From b84b3302ad324553342f957757c245a54fa87631 Mon Sep 17 00:00:00 2001 From: Cody Balos Date: Thu, 26 Oct 2023 17:46:04 -0700 Subject: [PATCH] Bugfix: CMake FindMAGMA (#356) Always append hipblas and hipsparse CMake targets with HIP backend as these libraries are not reliably included in the pkgconfig file. Replace cublas and cusparse with the CMake targets because the library path in the pkgconfig file is not reliable. Specifically, the path is wrong on systems using the NVIDIA HPC SDK. --------- Co-authored-by: David Gardner --- CHANGELOG.md | 3 + cmake/tpl/FindMAGMA.cmake | 42 ++++++++---- doc/arkode/guide/source/Introduction.rst | 3 + doc/cvode/guide/source/Introduction.rst | 3 + doc/cvodes/guide/source/Introduction.rst | 3 + doc/ida/guide/source/Introduction.rst | 3 + doc/idas/guide/source/Introduction.rst | 3 + doc/kinsol/guide/source/Introduction.rst | 3 + scripts/shared | 2 + src/sundials/sundials_cuda.h | 39 +---------- src/sundials/sundials_cusolver.h | 68 +++++++++++++++++++ src/sundials/sundials_cusparse.h | 66 ++++++++++++++++++ .../sunlinsol_cusolversp_batchqr.cu | 1 + src/sunlinsol/magmadense/CMakeLists.txt | 2 +- src/sunmatrix/cusparse/CMakeLists.txt | 3 +- src/sunmatrix/cusparse/sunmatrix_cusparse.cu | 1 + src/sunmatrix/magmadense/CMakeLists.txt | 2 +- 17 files changed, 193 insertions(+), 54 deletions(-) create mode 100644 src/sundials/sundials_cusolver.h create mode 100644 src/sundials/sundials_cusparse.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b1c49a4a2..cf25b99bf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,9 @@ Fixed scaling bug in `SUNMatScaleAddI_Sparse` for non-square matrices. Fixed missing soversions in some `SUNLinearSolver` and `SUNNonlinearSolver` CMake targets. +Fixed the build system support for MAGMA when using a NVIDIA HPC SDK installation of CUDA +and fixed the targets used for rocBLAS and rocSPARSE. + Added the fourth order ERK method `ARKODE_SOFRONIOU_SPALETTA_5_3_4`. ## Changes to SUNDIALS in release 6.6.1 diff --git a/cmake/tpl/FindMAGMA.cmake b/cmake/tpl/FindMAGMA.cmake index d244c504b4..258d7106e3 100644 --- a/cmake/tpl/FindMAGMA.cmake +++ b/cmake/tpl/FindMAGMA.cmake @@ -66,24 +66,42 @@ if(MAGMA_LIBRARY AND MAGMA_INCLUDE_DIR) list(SUBLIST _libraries_list 1 -1 _libraries_list) # remove 'Libs:' part set(_interface_libraires ) + + if(SUNDIALS_MAGMA_BACKENDS MATCHES "HIP") + if(NOT TARGET roc::hipblas) + find_package(hipblas REQUIRED) + endif() + if(NOT TARGET roc::hipsparse) + find_package(hipsparse REQUIRED) + endif() + # MAGMA does not reliably include these in the pkgconfig file + list(APPEND _interface_libraires "roc::hipblas;roc::hipsparse") + endif() + + if(SUNDIALS_MAGMA_BACKENDS MATCHES "CUDA") + if (NOT TARGET CUDA::cudart) + find_package(CUDAToolkit REQUIRED) + endif() + endif() + foreach(lib ${_libraries_list}) if(NOT (lib STREQUAL "-lmagma" OR lib STREQUAL "-lmagma_sparse" OR lib STREQUAL "-L\${libdir}" OR lib STREQUAL "") ) - - # Remove -l only from the beginning of the string - string(REPLACE "^-l" "" lib ${lib}) - list(APPEND _interface_libraires ${lib}) - - # Check if we need to find roc::hipblas or roc::hipsparse - if(SUNDIALS_MAGMA_BACKENDS MATCHES "HIP") - if((lib STREQUAL "roc::hipblas") AND (NOT TARGET roc::hipblas)) - find_package(hipblas REQUIRED) + + # Check if we need to find cusparse or cublas + if(SUNDIALS_MAGMA_BACKENDS MATCHES "CUDA") + # Replace cublas, cusparse with the CMake targets because the library path in + # the magma pkgconfig is not reliable. Sepcifically, the path is wrong on systems + # like Perlmutter where the NVIDIA HPC SDK is used. + if(lib STREQUAL "-lcublas") + set(lib CUDA::cublas) endif() - if((lib STREQUAL "roc::hipsparse") AND (NOT TARGET roc::hipsparse)) - find_package(hipsparse REQUIRED) + if(lib STREQUAL "-lcusparse") + set(lib CUDA::cusparse) endif() endif() - + + list(APPEND _interface_libraires ${lib}) endif() endforeach() diff --git a/doc/arkode/guide/source/Introduction.rst b/doc/arkode/guide/source/Introduction.rst index 4fafa4d0bb..7fbe137950 100644 --- a/doc/arkode/guide/source/Introduction.rst +++ b/doc/arkode/guide/source/Introduction.rst @@ -133,6 +133,9 @@ Changes from previous versions Changes in vX.X.X ----------------- +Fixed the build system support for MAGMA when using a NVIDIA HPC SDK installation of CUDA +and fixed the targets used for rocBLAS and rocSPARSE. + Fixed a regression introduced by the stop time bug fix in v6.6.1 where ARKODE steppers would return at the stop time rather than the requested output time if the stop time was reached in the same step in which the output time was passed. diff --git a/doc/cvode/guide/source/Introduction.rst b/doc/cvode/guide/source/Introduction.rst index 085aae8f34..b28e54a07a 100644 --- a/doc/cvode/guide/source/Introduction.rst +++ b/doc/cvode/guide/source/Introduction.rst @@ -114,6 +114,9 @@ Changes from previous versions Changes in vX.X.X ----------------- +Fixed the build system support for MAGMA when using a NVIDIA HPC SDK installation of CUDA +and fixed the targets used for rocBLAS and rocSPARSE. + Fixed a regression introduced by the stop time bug fix in v6.6.1 where CVODE would return at the stop time rather than the requested output time if the stop time was reached in the same step in which the output time was passed. diff --git a/doc/cvodes/guide/source/Introduction.rst b/doc/cvodes/guide/source/Introduction.rst index 4382d3c2cb..567c0b0284 100644 --- a/doc/cvodes/guide/source/Introduction.rst +++ b/doc/cvodes/guide/source/Introduction.rst @@ -114,6 +114,9 @@ Changes from previous versions Changes in vX.X.X ----------------- +Fixed the build system support for MAGMA when using a NVIDIA HPC SDK installation of CUDA +and fixed the targets used for rocBLAS and rocSPARSE. + Fixed a regression introduced by the stop time bug fix in v6.6.1 where CVODES would return at the stop time rather than the requested output time if the stop time was reached in the same step in which the output time was passed. diff --git a/doc/ida/guide/source/Introduction.rst b/doc/ida/guide/source/Introduction.rst index 1fa001bde2..5fae985f15 100644 --- a/doc/ida/guide/source/Introduction.rst +++ b/doc/ida/guide/source/Introduction.rst @@ -75,6 +75,9 @@ Changes from previous versions Changes in vX.X.X ----------------- +Fixed the build system support for MAGMA when using a NVIDIA HPC SDK installation of CUDA +and fixed the targets used for rocBLAS and rocSPARSE. + Fixed a regression introduced by the stop time bug fix in v6.6.1 where IDA would return at the stop time rather than the requested output time if the stop time was reached in the same step in which the output time was passed. diff --git a/doc/idas/guide/source/Introduction.rst b/doc/idas/guide/source/Introduction.rst index 16db98882a..4d1d3b3c4c 100644 --- a/doc/idas/guide/source/Introduction.rst +++ b/doc/idas/guide/source/Introduction.rst @@ -89,6 +89,9 @@ Changes from previous versions Changes in vX.X.X ----------------- +Fixed the build system support for MAGMA when using a NVIDIA HPC SDK installation of CUDA +and fixed the targets used for rocBLAS and rocSPARSE. + Fixed a regression introduced by the stop time bug fix in v6.6.1 where IDAS would return at the stop time rather than the requested output time if the stop time was reached in the same step in which the output time was passed. diff --git a/doc/kinsol/guide/source/Introduction.rst b/doc/kinsol/guide/source/Introduction.rst index 0500e6d0df..d91d300fbb 100644 --- a/doc/kinsol/guide/source/Introduction.rst +++ b/doc/kinsol/guide/source/Introduction.rst @@ -91,6 +91,9 @@ Changes from previous versions Changes in vX.X.X ----------------- +Fixed the build system support for MAGMA when using a NVIDIA HPC SDK installation of CUDA +and fixed the targets used for rocBLAS and rocSPARSE. + Improved computational complexity of ``SUNMatScaleAddI_Sparse`` from ``O(M*N)`` to ``O(NNZ)``. diff --git a/scripts/shared b/scripts/shared index 9e42969552..7304bc5df8 100755 --- a/scripts/shared +++ b/scripts/shared @@ -246,6 +246,8 @@ $tar $tarfile $distrobase/src/sundials/sundials_band.c $tar $tarfile $distrobase/src/sundials/sundials_context_impl.h $tar $tarfile $distrobase/src/sundials/sundials_context.c $tar $tarfile $distrobase/src/sundials/sundials_cuda.h +$tar $tarfile $distrobase/src/sundials/sundials_cusolver.h +$tar $tarfile $distrobase/src/sundials/sundials_cusparse.h $tar $tarfile $distrobase/src/sundials/sundials_cuda_kernels.cuh $tar $tarfile $distrobase/src/sundials/sundials_debug.h $tar $tarfile $distrobase/src/sundials/sundials_dense.c diff --git a/src/sundials/sundials_cuda.h b/src/sundials/sundials_cuda.h index 244e6e76ef..75c0749da4 100644 --- a/src/sundials/sundials_cuda.h +++ b/src/sundials/sundials_cuda.h @@ -21,8 +21,6 @@ #include #include -#include -#include #include @@ -38,8 +36,6 @@ extern "C" { * ---------------------------------------------------------------------------*/ #define SUNDIALS_CUDA_VERIFY(cuerr) SUNDIALS_CUDA_Assert(cuerr, __FILE__, __LINE__) -#define SUNDIALS_CUSPARSE_VERIFY(cuerr) SUNDIALS_CUSPARSE_Assert(cuerr, __FILE__, __LINE__) -#define SUNDIALS_CUSOLVER_VERIFY(cuerr) SUNDIALS_CUSOLVER_Assert(cuerr, __FILE__, __LINE__) #define SUNDIALS_KERNEL_NAME(...) __VA_ARGS__ #ifndef SUNDIALS_DEBUG_CUDA_LASTERROR @@ -75,42 +71,9 @@ inline booleantype SUNDIALS_CUDA_Assert(cudaError_t cuerr, const char *file, int return SUNTRUE; /* Assert OK */ } -inline booleantype SUNDIALS_CUSPARSE_Assert(cusparseStatus_t status, const char *file, int line) -{ - if (status != CUSPARSE_STATUS_SUCCESS) - { -#ifdef SUNDIALS_DEBUG - fprintf(stderr, - "ERROR in cuSPARSE runtime operation: cusparseStatus_t = %d %s:%d\n", - status, file, line); -#ifdef SUNDIALS_DEBUG_ASSERT - assert(false); -#endif -#endif - return SUNFALSE; /* Assert failed */ - } - return SUNTRUE; /* Assert OK */ -} - -inline booleantype SUNDIALS_CUSOLVER_Assert(cusolverStatus_t status, const char *file, int line) -{ - if (status != CUSOLVER_STATUS_SUCCESS) - { -#ifdef SUNDIALS_DEBUG - fprintf(stderr, - "ERROR in cuSOLVER runtime operation: cusolverStatus_t = %d %s:%d\n", - status, file, line); -#ifdef SUNDIALS_DEBUG_ASSERT - assert(false); -#endif -#endif - return SUNFALSE; /* Assert failed */ - } - return SUNTRUE; /* Assert OK */ -} #ifdef __cplusplus /* wrapper to enable C++ usage */ } #endif -#endif /* _SUNDIALS_CUDA_H */ \ No newline at end of file +#endif /* _SUNDIALS_CUDA_H */ diff --git a/src/sundials/sundials_cusolver.h b/src/sundials/sundials_cusolver.h new file mode 100644 index 0000000000..b1aee9b266 --- /dev/null +++ b/src/sundials/sundials_cusolver.h @@ -0,0 +1,68 @@ +/* + * ----------------------------------------------------------------- + * Programmer(s): Cody J. Balos @ LLNL + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2023, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------- + * This header files defines internal utility functions and macros + * for working with CUDA. + * ----------------------------------------------------------------- + */ + +#include +#include + +#include +#include +#include + +#include + +#ifndef _SUNDIALS_CUSOLVER_H +#define _SUNDIALS_CUSOLVER_H + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +/* --------------------------------------------------------------------------- + * Utility macros + * ---------------------------------------------------------------------------*/ + +#define SUNDIALS_CUSOLVER_VERIFY(cuerr) SUNDIALS_CUSOLVER_Assert(cuerr, __FILE__, __LINE__) + + +/* --------------------------------------------------------------------------- + * Utility functions + * ---------------------------------------------------------------------------*/ + +inline booleantype SUNDIALS_CUSOLVER_Assert(cusolverStatus_t status, const char *file, int line) +{ + if (status != CUSOLVER_STATUS_SUCCESS) + { +#ifdef SUNDIALS_DEBUG + fprintf(stderr, + "ERROR in cuSOLVER runtime operation: cusolverStatus_t = %d %s:%d\n", + status, file, line); +#ifdef SUNDIALS_DEBUG_ASSERT + assert(false); +#endif +#endif + return SUNFALSE; /* Assert failed */ + } + return SUNTRUE; /* Assert OK */ +} + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +} +#endif + +#endif /* _SUNDIALS_CUSOLVER_H */ diff --git a/src/sundials/sundials_cusparse.h b/src/sundials/sundials_cusparse.h new file mode 100644 index 0000000000..3f9c3ae493 --- /dev/null +++ b/src/sundials/sundials_cusparse.h @@ -0,0 +1,66 @@ +/* + * ----------------------------------------------------------------- + * Programmer(s): Cody J. Balos @ LLNL + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2023, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------- + * This header files defines internal utility functions and macros + * for working with CUDA. + * ----------------------------------------------------------------- + */ + +#include +#include + +#include +#include + +#include + +#ifndef _SUNDIALS_CUSPARSE_H +#define _SUNDIALS_CUSPARSE_H + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +/* --------------------------------------------------------------------------- + * Utility macros + * ---------------------------------------------------------------------------*/ + +#define SUNDIALS_CUSPARSE_VERIFY(cuerr) SUNDIALS_CUSPARSE_Assert(cuerr, __FILE__, __LINE__) + +/* --------------------------------------------------------------------------- + * Utility functions + * ---------------------------------------------------------------------------*/ + +inline booleantype SUNDIALS_CUSPARSE_Assert(cusparseStatus_t status, const char *file, int line) +{ + if (status != CUSPARSE_STATUS_SUCCESS) + { +#ifdef SUNDIALS_DEBUG + fprintf(stderr, + "ERROR in cuSPARSE runtime operation: cusparseStatus_t = %d %s:%d\n", + status, file, line); +#ifdef SUNDIALS_DEBUG_ASSERT + assert(false); +#endif +#endif + return SUNFALSE; /* Assert failed */ + } + return SUNTRUE; /* Assert OK */ +} + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +} +#endif + +#endif /* _SUNDIALS_CUSPARSE_H */ diff --git a/src/sunlinsol/cusolversp/sunlinsol_cusolversp_batchqr.cu b/src/sunlinsol/cusolversp/sunlinsol_cusolversp_batchqr.cu index d7a351f974..915f6163e9 100644 --- a/src/sunlinsol/cusolversp/sunlinsol_cusolversp_batchqr.cu +++ b/src/sunlinsol/cusolversp/sunlinsol_cusolversp_batchqr.cu @@ -23,6 +23,7 @@ #include #include "sundials_cuda.h" +#include "sundials_cusolver.h" #include "sundials_debug.h" #define ZERO RCONST(0.0) diff --git a/src/sunlinsol/magmadense/CMakeLists.txt b/src/sunlinsol/magmadense/CMakeLists.txt index 116dc2d425..ed186d064d 100644 --- a/src/sunlinsol/magmadense/CMakeLists.txt +++ b/src/sunlinsol/magmadense/CMakeLists.txt @@ -19,7 +19,7 @@ if(SUNDIALS_MAGMA_BACKENDS MATCHES "CUDA") set(_libs_needed sundials_sunmatrixmagmadense sundials_nveccuda) elseif(SUNDIALS_MAGMA_BACKENDS MATCHES "HIP") set_source_files_properties(sunlinsol_magmadense.cpp PROPERTIES LANGUAGE CXX) - set(_libs_needed sundials_sunmatrixmagmadense sundials_nvechip) + set(_libs_needed sundials_sunmatrixmagmadense sundials_nvechip hip::device) endif() # Add the sunlinsol_magmadense library diff --git a/src/sunmatrix/cusparse/CMakeLists.txt b/src/sunmatrix/cusparse/CMakeLists.txt index 21ee8a88f5..2efa8a8f7a 100644 --- a/src/sunmatrix/cusparse/CMakeLists.txt +++ b/src/sunmatrix/cusparse/CMakeLists.txt @@ -28,8 +28,7 @@ sundials_add_library(sundials_sunmatrixcusparse sundials_generic_obj sundials_sunmemcuda_obj LINK_LIBRARIES - PUBLIC CUDA::cusparse - PRIVATE CUDA::cusolver + PUBLIC CUDA::cusparse CUDA::cusolver OUTPUT_NAME sundials_sunmatrixcusparse VERSION diff --git a/src/sunmatrix/cusparse/sunmatrix_cusparse.cu b/src/sunmatrix/cusparse/sunmatrix_cusparse.cu index a986fe7041..70fbc47da9 100644 --- a/src/sunmatrix/cusparse/sunmatrix_cusparse.cu +++ b/src/sunmatrix/cusparse/sunmatrix_cusparse.cu @@ -24,6 +24,7 @@ #include #include "sundials_cuda.h" +#include "sundials_cusparse.h" #include "sundials_debug.h" #include "cusparse_kernels.cuh" diff --git a/src/sunmatrix/magmadense/CMakeLists.txt b/src/sunmatrix/magmadense/CMakeLists.txt index 40612e4ae8..91968550fb 100644 --- a/src/sunmatrix/magmadense/CMakeLists.txt +++ b/src/sunmatrix/magmadense/CMakeLists.txt @@ -16,7 +16,7 @@ install(CODE "MESSAGE(\"\nInstall SUNMATRIX_MAGMADENSE with ${SUNDIALS_MAGMA_BAC if(SUNDIALS_MAGMA_BACKENDS MATCHES "CUDA") set_source_files_properties(sunmatrix_magmadense.cpp PROPERTIES LANGUAGE CUDA) - set(_libs_needed sundials_nveccuda ${CUDA_CUBLAS_LIBRARIES}) + set(_libs_needed sundials_nveccuda) elseif(SUNDIALS_MAGMA_BACKENDS MATCHES "HIP") set_source_files_properties(sunmatrix_magmadense.cpp PROPERTIES LANGUAGE CXX) set(_libs_needed sundials_nvechip hip::device)