alpaka-group / alpaka

Abstraction Library for Parallel Kernel Acceleration :llama:
https://alpaka.readthedocs.io
Mozilla Public License 2.0
356 stars 74 forks source link

Use shared CUDA libraries by default #2348

Closed fwyzard closed 3 months ago

fwyzard commented 3 months ago

If CMAKE_CUDA_RUNTIME_LIBRARY is not set, set it to "Shared". This ensures that both the libraries implicitly linked by CMake match those explicitly linked by alpaka.

If CMAKE_CUDA_RUNTIME_LIBRARY is set to None, full CUDA applications are likely to build using the libcudart.so shared library, while host-only applications will likely fail to link. If CMAKE_CUDA_RUNTIME_LIBRARY is set to None, cuRAND is not supported.

fwyzard commented 3 months ago

This PR restores the behaviour we had before #2329, except that host-only applications like hostOnlyAPITest now build properly.

fwyzard commented 3 months ago

In particular, regular CUDA-based applications are still linked against both shared and static CUDA runtime libraries:

/usr/bin/g++-13 -g -Og CMakeFiles/axpyTest.dir/src/axpy.cpp.o -o axpyTest   -L/usr/local/cuda-12.6/targets/x86_64-linux/lib/stubs  -L/usr/local/cuda-12.6/targets/x86_64-linux/lib  -Wl,-rpath,/usr/local/cuda-12.6/lib64 /usr/local/cuda-12.6/targets/x86_64-linux/lib/stubs/libcuda.so /usr/lib/x86_64-linux-gnu/libboost_atomic.so.1.74.0 /usr/local/cuda-12.6/lib64/libcudart.so -ldl /usr/lib/x86_64-linux-gnu/librt.a /usr/local/cuda-12.6/lib64/libcurand.so ../../../thirdParty/catch2/src/libCatch2Maind.a ../../../thirdParty/catch2/src/libCatch2d.a -lcudadevrt -lcudart_static -lrt -lpthread -ldl

Would it make sense to use only the shared (or only the static) library ?

fwyzard commented 3 months ago

For example adding

diff --git a/cmake/alpakaCommon.cmake b/cmake/alpakaCommon.cmake
index 6661ad63031..28d7fd693bd 100644
--- a/cmake/alpakaCommon.cmake
+++ b/cmake/alpakaCommon.cmake
@@ -546,6 +546,7 @@ if(alpaka_ACC_GPU_CUDA_ENABLE)
         if(CMAKE_CUDA_RUNTIME_LIBRARY STREQUAL "Static")
             target_link_libraries(alpaka INTERFACE CUDA::cudart_static)
         else()
+            set(CMAKE_CUDA_RUNTIME_LIBRARY "Shared")
             target_link_libraries(alpaka INTERFACE CUDA::cudart)
         endif()

to inform CMake that we want to link libcudart.so by default ?

I really am not familiar with CMake best practices, so I will leave this PR as-is, unless told otherwise.

psychocoderHPC commented 3 months ago
set(CMAKE_CUDA_RUNTIME_LIBRARY "Shared")
set(CMAKE_CUDA_RUNTIME_LIBRARY "Shared")

should always be guarded and set only if not already set. It is allowed to set CMAKE_CUDA_RUNTIME_LIBRARY to None

https://cmake.org/cmake/help/latest/variable/CMAKE_CUDA_RUNTIME_LIBRARY.html

psychocoderHPC commented 3 months ago

This PR is solving my issues I saw here

fwyzard commented 3 months ago

It is allowed to set CMAKE_CUDA_RUNTIME_LIBRARY to None

Mhm, OK, but that will break all alpaka applications ?

Actually, the alpaka build rules will actually ignore it and link libcudart.so anyway.

fwyzard commented 3 months ago

All possible options are

        # Use the Shared CUDA Runtime library by default
        if(NOT DEFINED CMAKE_CUDA_RUNTIME_LIBRARY)
            set(CMAKE_CUDA_RUNTIME_LIBRARY "Shared")
        endif()

        # Link the CUDA Runtime library
        if(CMAKE_CUDA_RUNTIME_LIBRARY STREQUAL "Static")
            target_link_libraries(alpaka INTERFACE CUDA::cudart_static)
        elseif(CMAKE_CUDA_RUNTIME_LIBRARY STREQUAL "Shared")
            target_link_libraries(alpaka INTERFACE CUDA::cudart)
        elseif(CMAKE_CUDA_RUNTIME_LIBRARY STREQUAL "None")
            # Do not link any cudart library ?
        else()
            # ?
        endif()

        if(NOT alpaka_DISABLE_VENDOR_RNG)
            # Use cuRAND random number generators
            if(CMAKE_CUDA_RUNTIME_LIBRARY STREQUAL "Static")
                target_link_libraries(alpaka INTERFACE CUDA::curand_static)
            elseif(CMAKE_CUDA_RUNTIME_LIBRARY STREQUAL "Shared")
                target_link_libraries(alpaka INTERFACE CUDA::curand)
            else()
                # ?
            endif()
        endif()

But I don't know what we should do in the cases other than "Static" and "Shared".

fwyzard commented 3 months ago

OK, I think I covered all use cases in the latest update.