Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,7 @@ include(cmake/AddCUDSS.cmake)
include(cmake/BundleStaticDeps.cmake)

add_spdlog()
option(LOCAL_CUDSS_BUILD "Build cuDSS locally" ON)
set(CUDSS_BUILD_PATH "${PROJECT_SOURCE_DIR}/libs/cudss")

if(NOT LOCAL_CUDSS_BUILD)
set(CUDSS_BUILD_PATH "")
endif()
add_cudss(CUDSS_BUILD_PATH "${CUDSS_BUILD_PATH}")
add_cudss()

set(CUNLS_LIBS spdlog::spdlog CUDA::cusparse CUDA::cublas CUDA::cusolver cudss)

Expand Down Expand Up @@ -60,7 +54,7 @@ add_library(cunls
$<TARGET_OBJECTS:cunls_robustifier>
)

target_link_libraries(cunls
target_link_libraries(cunls
PUBLIC CUDA::cudart
PRIVATE ${CUNLS_LIBS}
)
Expand Down
97 changes: 33 additions & 64 deletions cmake/AddCUDSS.cmake
Original file line number Diff line number Diff line change
@@ -1,78 +1,47 @@
# Function to add cuDSS library to the project
#
# Usage:
# add_cudss(CUDSS_BUILD_PATH "/path/to/cudss/build")
# add_cudss()
#
# This function will:
# - Check if a local cuDSS build exists at CUDSS_BUILD_PATH
# - If found, use the local build (sets CUDSS_NEW_API compile definition)
# - If not found, download a prebuilt version using FetchContent
# - Create an imported target 'cudss' that can be linked against
#
# Parameters:
# CUDSS_BUILD_PATH - Path to the cuDSS build directory (optional, defaults to empty)
# This function downloads a prebuilt cuDSS release using FetchContent and
# creates an imported target 'cudss' that can be linked against. The cuDSS
# version and per-platform archive are selected automatically based on the
# CUDA compiler version and target architecture (x86_64 or aarch64/sbsa).
function(add_cudss)
# Parse arguments
set(options "")
set(oneValueArgs CUDSS_BUILD_PATH)
set(multiValueArgs "")
cmake_parse_arguments(CUDSS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
# cuDSS release version to download.
set(CUDSS_VERSION "0.8.0.10")
Comment thread
alexkorovko marked this conversation as resolved.

# Create imported target
add_library(cudss STATIC IMPORTED)

# Check if local build path was provided and exists
set(LOCAL_CUDSS_BUILD OFF)
if(CUDSS_CUDSS_BUILD_PATH)
set(CUDSS_LIB_PATH "${CUDSS_CUDSS_BUILD_PATH}/libcudss_static.a")
set(CUDSS_INCLUDE_PATH "${CUDSS_CUDSS_BUILD_PATH}/include")

if(EXISTS "${CUDSS_LIB_PATH}" AND EXISTS "${CUDSS_INCLUDE_PATH}")
set(LOCAL_CUDSS_BUILD ON)
message(STATUS "Using local cuDSS build from ${CUDSS_CUDSS_BUILD_PATH}")
set_target_properties(cudss PROPERTIES
IMPORTED_LOCATION "${CUDSS_LIB_PATH}"
INTERFACE_INCLUDE_DIRECTORIES "${CUDSS_INCLUDE_PATH}"
)
endif()
endif()

# If local build not found, use prebuilt version
if(NOT LOCAL_CUDSS_BUILD)
message(STATUS "Using prebuilt cuDSS")
set(CUDSS_URL_PREFIX "https://developer.download.nvidia.com/compute/cudss/redist/libcudss/")
message(STATUS "CUDA Compiler Version: ${CMAKE_CUDA_COMPILER_VERSION}")

if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 13.0)
set(CUDSS_URL_AARCH64 ${CUDSS_URL_PREFIX}linux-aarch64/libcudss-linux-aarch64-0.7.1.4_cuda13-archive.tar.xz)
set(CUDSS_URL_X86_64 ${CUDSS_URL_PREFIX}linux-x86_64/libcudss-linux-x86_64-0.7.1.4_cuda13-archive.tar.xz)
message(STATUS "Using CUDA 13.0 or newer")
else()
set(CUDSS_URL_AARCH64 ${CUDSS_URL_PREFIX}linux-aarch64/libcudss-linux-aarch64-0.7.1.4_cuda12-archive.tar.xz)
set(CUDSS_URL_X86_64 ${CUDSS_URL_PREFIX}linux-x86_64/libcudss-linux-x86_64-0.7.1.4_cuda12-archive.tar.xz)
message(STATUS "Using CUDA 12.0 or older")
endif()
message(STATUS "Using prebuilt cuDSS ${CUDSS_VERSION}")
set(CUDSS_URL_PREFIX "https://developer.download.nvidia.com/compute/cudss/redist/libcudss/")
message(STATUS "CUDA Compiler Version: ${CMAKE_CUDA_COMPILER_VERSION}")

if(CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch64)|(AARCH64)")
set(CUDSS_URL ${CUDSS_URL_AARCH64})
else()
set(CUDSS_URL ${CUDSS_URL_X86_64})
endif()

include(FetchContent)
FetchContent_Declare(
cudss
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
URL ${CUDSS_URL}
)
FetchContent_Populate(cudss)
if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 13.0)
set(CUDSS_CUDA_TAG "cuda13")
message(STATUS "Using CUDA 13.0 or newer")
else()
set(CUDSS_CUDA_TAG "cuda12")
message(STATUS "Using CUDA 12.0 or older")
endif()

set_target_properties(cudss PROPERTIES
IMPORTED_LOCATION "${cudss_SOURCE_DIR}/lib/libcudss_static.a"
INTERFACE_INCLUDE_DIRECTORIES "${cudss_SOURCE_DIR}/include"
)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch64)|(AARCH64)")
set(CUDSS_URL "${CUDSS_URL_PREFIX}linux-sbsa/libcudss-linux-sbsa-${CUDSS_VERSION}_${CUDSS_CUDA_TAG}-archive.tar.xz")
else()
set(CUDSS_URL "${CUDSS_URL_PREFIX}linux-x86_64/libcudss-linux-x86_64-${CUDSS_VERSION}_${CUDSS_CUDA_TAG}-archive.tar.xz")
endif()

# Set parent scope variable to indicate if local build is used
set(LOCAL_CUDSS_BUILD ${LOCAL_CUDSS_BUILD} PARENT_SCOPE)
include(FetchContent)
FetchContent_Declare(
cudss
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
URL ${CUDSS_URL}
)
FetchContent_Populate(cudss)
Comment thread
alexkorovko marked this conversation as resolved.

set_target_properties(cudss PROPERTIES
IMPORTED_LOCATION "${cudss_SOURCE_DIR}/lib/libcudss_static.a"
INTERFACE_INCLUDE_DIRECTORIES "${cudss_SOURCE_DIR}/include"
)
endfunction()
4 changes: 0 additions & 4 deletions cunls/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ add_library(cunls_common OBJECT

target_link_libraries(cunls_common PRIVATE spdlog::spdlog cudss)

if(LOCAL_CUDSS_BUILD)
target_compile_definitions(cunls_common PRIVATE CUDSS_NEW_API)
endif()

if(ENABLE_PROFILING)
target_link_libraries(cunls_common PRIVATE nvtx3-cpp)
target_compile_definitions(cunls_common PRIVATE ENABLE_PROFILING)
Expand Down
90 changes: 27 additions & 63 deletions cunls/common/cudss_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@

#include "cunls/common/cudss_helper.h"

#include <cudss.h>

#include <cassert>
#include <cstring>

#include "cunls/common/log.h"
#include <cudss.h>

namespace cunls {

Expand Down Expand Up @@ -128,25 +129,21 @@ int cuDSSDeviceMemPool::Dealloc(void *ptr, size_t size, cudaStream_t stream) {
return cudaErrorInvalidDevicePointer;
}

int cuDSSDeviceMemPoolAlloc(void *ctx, void **ptr, size_t size,
cudaStream_t stream) {
int cuDSSDeviceMemPoolAlloc(void *ctx, void **ptr, size_t size, cudaStream_t stream) {
if (ctx == nullptr) {
return cudaErrorInvalidResourceHandle;
}
return reinterpret_cast<cuDSSDeviceMemPool *>(ctx)->Alloc(ptr, size, stream);
}

int cuDSSDeviceMemPoolDealloc(void *ctx, void *ptr, size_t size,
cudaStream_t stream) {
int cuDSSDeviceMemPoolDealloc(void *ctx, void *ptr, size_t size, cudaStream_t stream) {
if (ctx == nullptr) {
return cudaErrorInvalidResourceHandle;
}
return reinterpret_cast<cuDSSDeviceMemPool *>(ctx)->Dealloc(ptr, size,
stream);
return reinterpret_cast<cuDSSDeviceMemPool *>(ctx)->Dealloc(ptr, size, stream);
}

void SetcuDSSDeviceMemHandler(void *handle, cuDSSDeviceMemPool &pool,
const char *handler_name) {
void SetcuDSSDeviceMemHandler(void *handle, cuDSSDeviceMemPool &pool, const char *handler_name) {
if (handle == nullptr) {
return;
}
Expand All @@ -155,25 +152,22 @@ void SetcuDSSDeviceMemHandler(void *handle, cuDSSDeviceMemPool &pool,
handler.ctx = reinterpret_cast<void *>(&pool);
handler.device_alloc = cuDSSDeviceMemPoolAlloc;
handler.device_free = cuDSSDeviceMemPoolDealloc;
std::strncpy(handler.name,
(handler_name == nullptr || handler_name[0] == '\0')
? "cunls device pool"
: handler_name,
CUDSS_ALLOCATOR_NAME_LEN);
std::strncpy(
handler.name,
(handler_name == nullptr || handler_name[0] == '\0') ? "cunls device pool" : handler_name,
CUDSS_ALLOCATOR_NAME_LEN);
handler.name[CUDSS_ALLOCATOR_NAME_LEN - 1] = '\0';

DetachcuDSSDeviceMemHandler(handle);

THROW_ON_CUDSS_ERROR(cudssSetDeviceMemHandler(
reinterpret_cast<cudssHandle_t>(handle), &handler));
THROW_ON_CUDSS_ERROR(cudssSetDeviceMemHandler(reinterpret_cast<cudssHandle_t>(handle), &handler));
}

void DetachcuDSSDeviceMemHandler(void *handle) {
if (handle == nullptr) {
return;
}
THROW_ON_CUDSS_ERROR(cudssSetDeviceMemHandler(
reinterpret_cast<cudssHandle_t>(handle), nullptr));
THROW_ON_CUDSS_ERROR(cudssSetDeviceMemHandler(reinterpret_cast<cudssHandle_t>(handle), nullptr));
}

/**
Expand Down Expand Up @@ -240,17 +234,10 @@ cuDSSDescription::cuDSSDescription(const CSRSparseMatrix &symmetric_matrix) {
cudssMatrix_t mat = nullptr;
// Create cuDSS CSR matrix descriptor
// Parameters: symmetric matrix, full view, zero-based indexing
#ifdef CUDSS_NEW_API
THROW_ON_CUDSS_ERROR(cudssMatrixCreateCsr(
&mat, matrix_size, matrix_size, num_nonzeros, rows_ptr, NULL, cols_ptr,
values_ptr, CUDSS_R_32I, CUDSS_R_32I, CUDSS_R_32F, CUDSS_MTYPE_SYMMETRIC,
CUDSS_MVIEW_FULL, CUDSS_BASE_ZERO));
#else
THROW_ON_CUDSS_ERROR(cudssMatrixCreateCsr(
&mat, matrix_size, matrix_size, num_nonzeros, rows_ptr, NULL, cols_ptr,
values_ptr, CUDA_R_32I, CUDA_R_32F, CUDSS_MTYPE_SYMMETRIC,
CUDSS_MVIEW_FULL, CUDSS_BASE_ZERO));
#endif
THROW_ON_CUDSS_ERROR(cudssMatrixCreateCsr(&mat, matrix_size, matrix_size, num_nonzeros, rows_ptr,
NULL, cols_ptr, values_ptr, CUDSS_R_32I, CUDSS_R_32I,
CUDSS_R_32F, CUDSS_MTYPE_SYMMETRIC, CUDSS_MVIEW_FULL,
CUDSS_BASE_ZERO));

matrix_ = reinterpret_cast<void *>(mat);
}
Expand All @@ -273,13 +260,8 @@ cuDSSDescription::cuDSSDescription(const dvector<float> &vector) {
// vector

cudssMatrix_t mat = nullptr;
#ifdef CUDSS_NEW_API
THROW_ON_CUDSS_ERROR(cudssMatrixCreateDn(&mat, size, 1, size, ptr, CUDSS_R_32F,
CUDSS_LAYOUT_COL_MAJOR));
#else
THROW_ON_CUDSS_ERROR(cudssMatrixCreateDn(&mat, size, 1, size, ptr, CUDA_R_32F,
CUDSS_LAYOUT_COL_MAJOR));
#endif
THROW_ON_CUDSS_ERROR(
cudssMatrixCreateDn(&mat, size, 1, size, ptr, CUDSS_R_32F, CUDSS_LAYOUT_COL_MAJOR));
matrix_ = reinterpret_cast<void *>(mat);
}

Expand All @@ -301,13 +283,13 @@ cuDSSDescription::~cuDSSDescription() {
* number of threads.
*
* @param reordering_algorithm The reordering algorithm to use (e.g.,
* CUDSS_ALG_DEFAULT, CUDSS_ALG_1). Defaults to 0.
* CUDSS_REORDERING_ALG_DEFAULT,
* CUDSS_REORDERING_ALG_BTF_COLAMD). Defaults to 0.
* @param nthreads The number of threads to use. Defaults to 1.
*/
cuDSSConfig::cuDSSConfig(int reordering_algorithm, int nthreads) {
cudssConfig_t cfg = nullptr;

#ifdef CUDSS_NEW_API
// Validate algorithm is within expected range
if (reordering_algorithm < static_cast<int>(CUDSS_REORDERING_ALG_DEFAULT) ||
reordering_algorithm > static_cast<int>(CUDSS_REORDERING_ALG_NONE)) {
Expand All @@ -318,38 +300,20 @@ cuDSSConfig::cuDSSConfig(int reordering_algorithm, int nthreads) {

auto alg = (cudssReorderingAlg_t)reordering_algorithm;

THROW_ON_CUDSS_ERROR(cudssConfigSet(cfg, CUDSS_CONFIG_REORDERING_ALG, &alg,
sizeof(cudssReorderingAlg_t)));
#else
// Validate algorithm is within expected range
if (reordering_algorithm < static_cast<int>(CUDSS_ALG_DEFAULT) ||
reordering_algorithm > static_cast<int>(CUDSS_ALG_5)) {
throw std::invalid_argument("Invalid reordering algorithm value");
}

THROW_ON_CUDSS_ERROR(cudssConfigCreate(&cfg));

auto alg = (cudssAlgType_t)reordering_algorithm;

THROW_ON_CUDSS_ERROR(cudssConfigSet(cfg, CUDSS_CONFIG_REORDERING_ALG, &alg,
sizeof(cudssAlgType_t)));
#endif

THROW_ON_CUDSS_ERROR(
cudssConfigSet(cfg, CUDSS_CONFIG_HOST_NTHREADS, &nthreads, sizeof(int)));
cudssConfigSet(cfg, CUDSS_CONFIG_REORDERING_ALG, &alg, sizeof(cudssReorderingAlg_t)));

THROW_ON_CUDSS_ERROR(cudssConfigSet(cfg, CUDSS_CONFIG_HOST_NTHREADS, &nthreads, sizeof(int)));

#ifdef CUDSS_NEW_API
// Hybrid execute mode is incompatible with the BTF_COLAMD/COLAMD reordering
// paths in cuDSS — those algorithms return CUDSS_STATUS_NOT_SUPPORTED during
// analysis when hybrid execution is on. Enable hybrid mode only for the
// remaining reordering algorithms.
if (alg != CUDSS_REORDERING_ALG_BTF_COLAMD &&
alg != CUDSS_REORDERING_ALG_COLAMD) {
if (alg != CUDSS_REORDERING_ALG_BTF_COLAMD && alg != CUDSS_REORDERING_ALG_COLAMD) {
int hybrid_execute_mode = 16;
THROW_ON_CUDSS_ERROR(cudssConfigSet(cfg, CUDSS_CONFIG_HYBRID_EXECUTE_MODE,
&hybrid_execute_mode, sizeof(int)));
THROW_ON_CUDSS_ERROR(
cudssConfigSet(cfg, CUDSS_CONFIG_HYBRID_EXECUTE_MODE, &hybrid_execute_mode, sizeof(int)));
}
#endif

config_ = reinterpret_cast<void *>(cfg);
}
Expand Down Expand Up @@ -401,4 +365,4 @@ cuDSSData::~cuDSSData() {
}
}

} // namespace cunls
} // namespace cunls
4 changes: 0 additions & 4 deletions cunls/linear_solver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,3 @@ add_library(cunls_linear_solver OBJECT
)

target_link_libraries(cunls_linear_solver PRIVATE cudss)

if(LOCAL_CUDSS_BUILD)
target_compile_definitions(cunls_linear_solver PRIVATE CUDSS_NEW_API)
endif()
Loading