diff --git a/cmake/FindCompiler.cmake b/cmake/FindCompiler.cmake index 98358339f..a6298619a 100644 --- a/cmake/FindCompiler.cmake +++ b/cmake/FindCompiler.cmake @@ -44,32 +44,52 @@ if(is_dpcpp) # Check if the Nvidia target is supported. PortFFT uses this for choosing default configuration. check_cxx_compiler_flag("-fsycl -fsycl-targets=nvptx64-nvidia-cuda" dpcpp_supports_nvptx64) - if(ENABLE_CURAND_BACKEND OR ENABLE_CUSOLVER_BACKEND OR ENABLE_CUSPARSE_BACKEND) - list(APPEND UNIX_INTERFACE_COMPILE_OPTIONS - -fsycl-targets=nvptx64-nvidia-cuda -fsycl-unnamed-lambda) - list(APPEND UNIX_INTERFACE_LINK_OPTIONS - -fsycl-targets=nvptx64-nvidia-cuda) - elseif(ENABLE_ROCBLAS_BACKEND OR ENABLE_ROCRAND_BACKEND - OR ENABLE_ROCSOLVER_BACKEND OR ENABLE_ROCSPARSE_BACKEND) + # Assemble the SYCL offload target triples for every enabled GPU backend. + # DPC++ only honors the *last* -fsycl-targets flag on the command line, so + # all target triples must be passed together as a single comma-separated + # list. Previously each vendor backend appended its own -fsycl-targets flag + # (here and in the individual backend CMake files); in a multi-vendor build + # all but the last triple were then silently dropped, so the SYCL device + # kernels of the other vendor(s) were missing at runtime (see issue #708). + set(ONEMATH_SYCL_TARGET_TRIPLES "") + set(ONEMATH_SYCL_TARGET_ARCH_OPTIONS "") + + if(ENABLE_CUBLAS_BACKEND OR ENABLE_CURAND_BACKEND OR ENABLE_CUSOLVER_BACKEND + OR ENABLE_CUFFT_BACKEND OR ENABLE_CUSPARSE_BACKEND) + list(APPEND ONEMATH_SYCL_TARGET_TRIPLES "nvptx64-nvidia-cuda") + if(DEFINED CUDA_TARGETS AND NOT "${CUDA_TARGETS}" STREQUAL "") + list(APPEND ONEMATH_SYCL_TARGET_ARCH_OPTIONS + -Xsycl-target-backend=nvptx64-nvidia-cuda --cuda-gpu-arch=${CUDA_TARGETS}) + endif() + endif() + + if(ENABLE_ROCBLAS_BACKEND OR ENABLE_ROCRAND_BACKEND OR ENABLE_ROCSOLVER_BACKEND + OR ENABLE_ROCFFT_BACKEND OR ENABLE_ROCSPARSE_BACKEND) + list(APPEND ONEMATH_SYCL_TARGET_TRIPLES "amdgcn-amd-amdhsa") + list(APPEND ONEMATH_SYCL_TARGET_ARCH_OPTIONS + -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=${HIP_TARGETS}) + endif() + + if(ONEMATH_SYCL_TARGET_TRIPLES) + # Preserve the Intel GPU (spir64) device image when an Intel oneMKL GPU + # backend is enabled alongside a CUDA/HIP backend; otherwise it would be + # dropped from the combined -fsycl-targets list. + if(ENABLE_MKLGPU_BACKEND) + list(APPEND ONEMATH_SYCL_TARGET_TRIPLES "spir64") + endif() + list(JOIN ONEMATH_SYCL_TARGET_TRIPLES "," ONEMATH_SYCL_TARGETS_ARG) list(APPEND UNIX_INTERFACE_COMPILE_OPTIONS - -fsycl-targets=amdgcn-amd-amdhsa -fsycl-unnamed-lambda - -Xsycl-target-backend --offload-arch=${HIP_TARGETS}) + -fsycl-targets=${ONEMATH_SYCL_TARGETS_ARG} -fsycl-unnamed-lambda + ${ONEMATH_SYCL_TARGET_ARCH_OPTIONS}) list(APPEND UNIX_INTERFACE_LINK_OPTIONS - -fsycl-targets=amdgcn-amd-amdhsa -Xsycl-target-backend - --offload-arch=${HIP_TARGETS}) - endif() - if(ENABLE_CURAND_BACKEND OR ENABLE_CUSOLVER_BACKEND OR ENABLE_CUSPARSE_BACKEND OR ENABLE_ROCBLAS_BACKEND - OR ENABLE_ROCRAND_BACKEND OR ENABLE_ROCSOLVER_BACKEND OR ENABLE_ROCSPARSE_BACKEND) - set_target_properties(ONEMATH::SYCL::SYCL PROPERTIES - INTERFACE_COMPILE_OPTIONS "${UNIX_INTERFACE_COMPILE_OPTIONS}" - INTERFACE_LINK_OPTIONS "${UNIX_INTERFACE_LINK_OPTIONS}" - INTERFACE_LINK_LIBRARIES ${SYCL_LIBRARY}) - else() - set_target_properties(ONEMATH::SYCL::SYCL PROPERTIES - INTERFACE_COMPILE_OPTIONS "-fsycl" - INTERFACE_LINK_OPTIONS "-fsycl" - INTERFACE_LINK_LIBRARIES ${SYCL_LIBRARY}) + -fsycl-targets=${ONEMATH_SYCL_TARGETS_ARG} + ${ONEMATH_SYCL_TARGET_ARCH_OPTIONS}) endif() + + set_target_properties(ONEMATH::SYCL::SYCL PROPERTIES + INTERFACE_COMPILE_OPTIONS "${UNIX_INTERFACE_COMPILE_OPTIONS}" + INTERFACE_LINK_OPTIONS "${UNIX_INTERFACE_LINK_OPTIONS}" + INTERFACE_LINK_LIBRARIES ${SYCL_LIBRARY}) else() set_target_properties(ONEMATH::SYCL::SYCL PROPERTIES INTERFACE_COMPILE_OPTIONS "-fsycl" diff --git a/src/blas/backends/cublas/CMakeLists.txt b/src/blas/backends/cublas/CMakeLists.txt index 485af0b09..f4283ab3e 100644 --- a/src/blas/backends/cublas/CMakeLists.txt +++ b/src/blas/backends/cublas/CMakeLists.txt @@ -41,23 +41,9 @@ target_include_directories(${LIB_OBJ} ) target_compile_options(${LIB_OBJ} PRIVATE ${ONEMATH_BUILD_COPT}) -if (NOT "${ONEMATH_SYCL_IMPLEMENTATION}" STREQUAL "adaptivecpp") - target_compile_options(ONEMATH::SYCL::SYCL INTERFACE - -fsycl-targets=nvptx64-nvidia-cuda -fsycl-unnamed-lambda - ) - target_link_options(ONEMATH::SYCL::SYCL INTERFACE - -fsycl-targets=nvptx64-nvidia-cuda - ) - - if (DEFINED CUDA_TARGETS AND NOT "${CUDA_TARGETS}" STREQUAL "") - target_compile_options(ONEMATH::SYCL::SYCL INTERFACE - -Xsycl-target-backend --cuda-gpu-arch=${CUDA_TARGETS} - ) - target_link_options(ONEMATH::SYCL::SYCL INTERFACE - -Xsycl-target-backend --cuda-gpu-arch=${CUDA_TARGETS} - ) - endif() -endif() +# The SYCL offload targets (-fsycl-targets) for all enabled GPU backends are +# assembled once in cmake/FindCompiler.cmake so that multi-vendor builds keep +# every vendor's device image. See issue #708. target_link_libraries(${LIB_OBJ} PUBLIC ONEMATH::SYCL::SYCL ONEMATH::cuBLAS::cuBLAS) target_compile_features(${LIB_OBJ} PUBLIC cxx_std_11) diff --git a/src/blas/backends/rocblas/CMakeLists.txt b/src/blas/backends/rocblas/CMakeLists.txt index 13f96d6c4..f913a824a 100644 --- a/src/blas/backends/rocblas/CMakeLists.txt +++ b/src/blas/backends/rocblas/CMakeLists.txt @@ -46,19 +46,10 @@ target_include_directories(${LIB_OBJ} ${ONEMATH_GENERATED_INCLUDE_PATH} ) -if(NOT ${ONEMATH_SYCL_IMPLEMENTATION} STREQUAL "adaptivecpp") - target_compile_options(${LIB_OBJ} PRIVATE ${ONEMATH_BUILD_COPT}) - target_compile_options(ONEMATH::SYCL::SYCL INTERFACE - -fsycl-targets=amdgcn-amd-amdhsa -fsycl-unnamed-lambda - -Xsycl-target-backend --offload-arch=${HIP_TARGETS}) - target_link_options(ONEMATH::SYCL::SYCL INTERFACE - -fsycl-targets=amdgcn-amd-amdhsa -Xsycl-target-backend - --offload-arch=${HIP_TARGETS}) -else() - target_compile_options(${LIB_OBJ} PRIVATE ${ONEMATH_BUILD_COPT}) - target_compile_options(ONEMATH::SYCL::SYCL INTERFACE) - target_link_options(ONEMATH::SYCL::SYCL INTERFACE) -endif() +# The SYCL offload targets (-fsycl-targets) for all enabled GPU backends are +# assembled once in cmake/FindCompiler.cmake so that multi-vendor builds keep +# every vendor's device image. See issue #708. +target_compile_options(${LIB_OBJ} PRIVATE ${ONEMATH_BUILD_COPT}) target_link_libraries(${LIB_OBJ} PRIVATE roc::rocblas hip::host Threads::Threads) target_link_libraries(${LIB_OBJ} PUBLIC ONEMATH::SYCL::SYCL) diff --git a/src/sparse_blas/backends/cusparse/CMakeLists.txt b/src/sparse_blas/backends/cusparse/CMakeLists.txt index 517a2b9ca..ab2d1efcf 100644 --- a/src/sparse_blas/backends/cusparse/CMakeLists.txt +++ b/src/sparse_blas/backends/cusparse/CMakeLists.txt @@ -43,23 +43,9 @@ target_include_directories(${LIB_OBJ} target_compile_options(${LIB_OBJ} PRIVATE ${ONEMATH_BUILD_COPT}) -if (NOT "${ONEMATH_SYCL_IMPLEMENTATION}" STREQUAL "adaptivecpp") - target_compile_options(ONEMATH::SYCL::SYCL INTERFACE - -fsycl-targets=nvptx64-nvidia-cuda -fsycl-unnamed-lambda - ) - target_link_options(ONEMATH::SYCL::SYCL INTERFACE - -fsycl-targets=nvptx64-nvidia-cuda - ) - - if (DEFINED CUDA_TARGETS AND NOT "${CUDA_TARGETS}" STREQUAL "") - target_compile_options(ONEMATH::SYCL::SYCL INTERFACE - -Xsycl-target-backend --cuda-gpu-arch=${CUDA_TARGETS} - ) - target_link_options(ONEMATH::SYCL::SYCL INTERFACE - -Xsycl-target-backend --cuda-gpu-arch=${CUDA_TARGETS} - ) - endif() -endif() +# The SYCL offload targets (-fsycl-targets) for all enabled GPU backends are +# assembled once in cmake/FindCompiler.cmake so that multi-vendor builds keep +# every vendor's device image. See issue #708. if (${CMAKE_VERSION} VERSION_LESS "3.17.0") find_package(CUDA 12.2 REQUIRED)