diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e7679f..0311658 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,25 @@ cmake_minimum_required(VERSION 3.20) # Project config -project(cupdlpx LANGUAGES C CXX CUDA) +project(cupdlpx LANGUAGES C CXX) + +# Default CUDA architectures: SASS for every current arch, PTX only for the newest one as a forward-compat fallback. +find_package(CUDAToolkit REQUIRED) +if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES AND NOT DEFINED ENV{CUDAARCHS}) + if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 13) + set(CMAKE_CUDA_ARCHITECTURES 75-real 80-real 86-real 89-real 90-real + 100-real 120-real 120-virtual) + elseif(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 12.8) + set(CMAKE_CUDA_ARCHITECTURES 60-real 70-real 75-real 80-real 86-real + 89-real 90-real 100-real 120-real 120-virtual) + else() + set(CMAKE_CUDA_ARCHITECTURES 60-real 70-real 75-real 80-real 86-real + 89-real 90-real 90-virtual) + endif() +endif() + +enable_language(CUDA) +message(STATUS "CUDA architectures: ${CMAKE_CUDA_ARCHITECTURES}") set(CUPDLPX_VERSION_MAJOR 0) set(CUPDLPX_VERSION_MINOR 2) @@ -32,10 +50,6 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() -if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES) - set(CMAKE_CUDA_ARCHITECTURES 60 70 75 80 86 89 90) -endif() - # ----------------------------------------------------------------------------- # [ELEGANT DESIGN] Target-based Compile Flags # ----------------------------------------------------------------------------- @@ -85,7 +99,6 @@ endif() # ----------------------------------------------------------------------------- # FIND DEPENDENCIES # ----------------------------------------------------------------------------- -find_package(CUDAToolkit REQUIRED) include(FetchContent) # 1. ZLIB Configuration diff --git a/README.md b/README.md index 919e8e0..4cd6a31 100644 --- a/README.md +++ b/README.md @@ -30,8 +30,8 @@ Our work is presented in two papers: * **Build Tools:** CMake (≥ 3.20), GCC, NVCC. > **SpMV backend** is selected automatically at compile time based on cuSPARSE version: -> - `cusparseSpMV` — CUDA 12.4 – 13.1 (cuSPARSE < 12.7.3) -> - `cusparseSpMVOp` — CUDA 13.1 Update 1+ (cuSPARSE ≥ 12.7.3) +> - `cusparseSpMV` — CUDA 12.4 – 13.2 (cuSPARSE < 12.8.1) +> - `cusparseSpMVOp` — CUDA 13.3+ (cuSPARSE ≥ 12.8.1) ### Build from Source Clone the repository and compile the project using CMake. diff --git a/internal/cusparse_compat.h b/internal/cusparse_compat.h index 9eaecb2..6d84034 100644 --- a/internal/cusparse_compat.h +++ b/internal/cusparse_compat.h @@ -3,19 +3,11 @@ #include // cusparseSpMVOp_bufferSize was introduced in cuSPARSE 12.7.3 (CUDA 13.1 Update 1). +// cuSPARSE 12.8.1 (CUDA 13.3.0) introduced the SpMVOp ALG1/ALG2 algorithms and +// added a cusparseSpMVOpAlg_t parameter to cusparseSpMVOp_bufferSize/createDescr. // CUSPARSE_VERSION encoding: major*1000 + minor*100 + patch. -#if defined(CUSPARSE_VERSION) && CUSPARSE_VERSION >= 12703 +#if defined(CUSPARSE_VERSION) && CUSPARSE_VERSION >= 12801 #define CUPDLPX_HAS_SPMVOP 1 #else #define CUPDLPX_HAS_SPMVOP 0 #endif - -#if !CUPDLPX_HAS_SPMVOP -// The SpMVOp types were added to cusparse.h before the functions -// (e.g. CUDA 13.1 base has the types but not the functions). -// Only provide fallback typedefs for cuSPARSE versions that lack them entirely. -#if !defined(CUSPARSE_VERSION) || CUSPARSE_VERSION < 12700 -typedef void *cusparseSpMVOpDescr_t; -typedef void *cusparseSpMVOpPlan_t; -#endif -#endif diff --git a/src/spmv_backend.cu b/src/spmv_backend.cu index 4b7618a..dd797ec 100644 --- a/src/spmv_backend.cu +++ b/src/spmv_backend.cu @@ -47,8 +47,15 @@ void cupdlpx_spmv_buffer_size(cusparseHandle_t sparse_handle, size_t *buffer_size) { #if CUPDLPX_HAS_SPMVOP - CUSPARSE_CHECK(cusparseSpMVOp_bufferSize( - sparse_handle, CUSPARSE_OPERATION_NON_TRANSPOSE, mat, vec_x, vec_y, vec_y, CUDA_R_64F, buffer_size)); + CUSPARSE_CHECK(cusparseSpMVOp_bufferSize(sparse_handle, + CUSPARSE_OPERATION_NON_TRANSPOSE, + mat, + vec_x, + vec_y, + vec_y, + CUDA_R_64F, + CUSPARSE_SPMVOP_ALG2, + buffer_size)); #else CUSPARSE_CHECK(cusparseSpMV_bufferSize(sparse_handle, CUSPARSE_OPERATION_NON_TRANSPOSE, @@ -74,8 +81,16 @@ void cupdlpx_spmv_prepare(cusparseHandle_t sparse_handle, #if CUPDLPX_HAS_SPMVOP cusparseSpMVOpDescr_t local_descr = NULL; cusparseSpMVOpPlan_t local_plan = NULL; - CUSPARSE_CHECK(cusparseSpMVOp_createDescr( - sparse_handle, &local_descr, CUSPARSE_OPERATION_NON_TRANSPOSE, mat, vec_x, vec_y, vec_y, CUDA_R_64F, buffer)); + CUSPARSE_CHECK(cusparseSpMVOp_createDescr(sparse_handle, + &local_descr, + CUSPARSE_OPERATION_NON_TRANSPOSE, + mat, + vec_x, + vec_y, + vec_y, + CUDA_R_64F, + CUSPARSE_SPMVOP_ALG2, + buffer)); CUSPARSE_CHECK(cusparseSpMVOp_createPlan(sparse_handle, local_descr, &local_plan, NULL, 0)); *descr = (void *)local_descr; *plan = (void *)local_plan;