diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9854a55..d463b41 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,6 +29,7 @@ jobs: - name: CUDA info run: | + cmake --version echo "Installed cuda version is: ${{ steps.cuda-toolkit.outputs.cuda }}" echo "Cuda install location: ${{ steps.cuda-toolkit.outputs.CUDA_PATH }}" nvcc -V @@ -89,15 +90,21 @@ jobs: - name: Install build deps run: | apt-get install -y --no-install-recommends \ - cmake ninja-build zlib1g-dev \ + ninja-build zlib1g-dev \ hipblas-dev hipsparse-dev hipcub-dev rocprim-dev rocthrust-dev + - name: Set up CMake + uses: jwlawson/actions-setup-cmake@v2 + with: + cmake-version: '3.24.4' + # The ROCm apt packages don't add /opt/rocm/bin to PATH for non-interactive shells. - name: Add ROCm to PATH run: echo "/opt/rocm/bin" >> "$GITHUB_PATH" - name: HIP info run: | + cmake --version hipcc --version - name: Configure diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c27288..93406bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ # ----------------------------------------------------------------------------- # ROOT CMakeLists.txt for cuPDLPx (Unified Build System) # ----------------------------------------------------------------------------- -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.24) # HIP/ROCm support option (must be set before project() to influence language detection) option(USE_HIP "Build with HIP for AMD GPUs" OFF) @@ -12,19 +12,9 @@ if(USE_HIP) else() 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() + set(CMAKE_CUDA_ARCHITECTURES all-major) endif() enable_language(CUDA) @@ -57,14 +47,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(USE_HIP) - # HIP architecture configuration - # Default to gfx90a if not specified; can override with -DCMAKE_HIP_ARCHITECTURES=gfx1100, etc. - if(NOT DEFINED CMAKE_HIP_ARCHITECTURES OR CMAKE_HIP_ARCHITECTURES STREQUAL "") - set(CMAKE_HIP_ARCHITECTURES "gfx90a") - endif() -endif() - # ----------------------------------------------------------------------------- # [ELEGANT DESIGN] Target-based Compile Flags # ----------------------------------------------------------------------------- @@ -73,15 +55,24 @@ add_library(cupdlpx_compile_flags INTERFACE) if(NOT USE_HIP) # reduce.h passes device lambdas to thrust::transform_iterator target_compile_options(cupdlpx_compile_flags INTERFACE $<$:--extended-lambda>) + # all-major includes Maxwell to Volta on CUDA 12, which nvcc warns are deprecated + target_compile_options(cupdlpx_compile_flags INTERFACE $<$:-Wno-deprecated-gpu-targets>) endif() if(MSVC) target_compile_options(cupdlpx_compile_flags INTERFACE - $<$,$>:/O2 /W4 /Zi> - $<$:-Xcompiler=/O2> + $<$,$>:/W4 /Zi> $<$:-Xcompiler=/W4> $<$:-Xcompiler=/Zi> ) + if(NOT USE_HIP AND CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA" + AND CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 13) + # Newer CUDA 13 CCCL headers require the conforming MSVC preprocessor. + # Keep CUDA 12 on its existing mode to avoid CUB/Thrust macro errors. + target_compile_options(cupdlpx_compile_flags INTERFACE + $<$:-Xcompiler=/Zc:preprocessor> + ) + endif() target_compile_definitions(cupdlpx_compile_flags INTERFACE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_DEPRECATE @@ -89,7 +80,7 @@ if(MSVC) strdup=_strdup ) else() - target_compile_options(cupdlpx_compile_flags INTERFACE -O3 -Wall -Wextra -g) + target_compile_options(cupdlpx_compile_flags INTERFACE -Wall -Wextra -g) if(NOT WIN32) target_compile_options(cupdlpx_compile_flags INTERFACE -fPIC) endif() @@ -108,6 +99,7 @@ endif() # CONTROL OPTIONS # ----------------------------------------------------------------------------- include(CMakeDependentOption) +include(GNUInstallDirs) option(CUPDLPX_BUILD_STATIC_LIB "Build the cuPDLPx static library" ON) option(CUPDLPX_BUILD_SHARED_LIB "Build the cuPDLPx shared library" ON) @@ -196,8 +188,18 @@ target_compile_definitions(cupdlpx_compile_flags INTERFACE PSLP_VERSION="${PSLP_ # ----------------------------------------------------------------------------- # TARGET DEFINITIONS # ----------------------------------------------------------------------------- -file(GLOB C_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.c") -file(GLOB CU_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cu") +if(UNIX) + if(APPLE) + set(CUPDLPX_RPATH_ORIGIN "@loader_path") + else() + set(CUPDLPX_RPATH_ORIGIN "$ORIGIN") + endif() + file(RELATIVE_PATH CUPDLPX_LIBDIR_FROM_BINDIR + "${CMAKE_INSTALL_FULL_BINDIR}" "${CMAKE_INSTALL_FULL_LIBDIR}") +endif() + +file(GLOB C_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.c") +file(GLOB CU_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cu") list(REMOVE_ITEM C_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/cli.c") set(CORE_INCLUDE_DIRS @@ -267,6 +269,9 @@ if(CUPDLPX_BUILD_SHARED_LIB) OUTPUT_NAME "cupdlpx" RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" ) + if(UNIX) + set_property(TARGET cupdlpx_shared APPEND PROPERTY INSTALL_RPATH "${CUPDLPX_RPATH_ORIGIN}") + endif() if(USE_HIP) set_target_properties(cupdlpx_shared PROPERTIES HIP_ARCHITECTURES "${CMAKE_HIP_ARCHITECTURES}" @@ -292,6 +297,10 @@ if(CUPDLPX_BUILD_CLI) OUTPUT_NAME "cupdlpx" RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" ) + if(UNIX) + set_property(TARGET cupdlpx_cli APPEND PROPERTY INSTALL_RPATH + "${CUPDLPX_RPATH_ORIGIN}/${CUPDLPX_LIBDIR_FROM_BINDIR}") + endif() if(NOT USE_HIP) set_target_properties(cupdlpx_cli PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON @@ -306,7 +315,8 @@ if(CUPDLPX_BUILD_TESTS) endif() enable_testing() - file(GLOB TEST_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/test/*.c" "${CMAKE_CURRENT_SOURCE_DIR}/test/*.cu") + file(GLOB TEST_SOURCES CONFIGURE_DEPENDS + "${CMAKE_CURRENT_SOURCE_DIR}/test/*.c" "${CMAKE_CURRENT_SOURCE_DIR}/test/*.cu") foreach(TEST_SRC ${TEST_SOURCES}) get_filename_component(TEST_NAME ${TEST_SRC} NAME_WE) add_executable(${TEST_NAME} ${TEST_SRC}) @@ -337,16 +347,19 @@ endif() # 6. Install Targets if (CUPDLPX_BUILD_PYTHON) - install(DIRECTORY include/ DESTINATION include/ FILES_MATCHING PATTERN "*.h") + install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.h") else() if(TARGET cupdlpx_core) - install(TARGETS cupdlpx_core ARCHIVE DESTINATION lib) + install(TARGETS cupdlpx_core ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() if(TARGET cupdlpx_shared) - install(TARGETS cupdlpx_shared LIBRARY DESTINATION lib RUNTIME DESTINATION bin) + install(TARGETS cupdlpx_shared + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() if(TARGET cupdlpx_cli) - install(TARGETS cupdlpx_cli RUNTIME DESTINATION bin) + install(TARGETS cupdlpx_cli RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() - install(DIRECTORY include/ DESTINATION include/ FILES_MATCHING PATTERN "*.h") + install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.h") endif() diff --git a/docs/guides/command-line.md b/docs/guides/command-line.md index 36e3a75..6958671 100644 --- a/docs/guides/command-line.md +++ b/docs/guides/command-line.md @@ -13,7 +13,7 @@ Build it from source with the C libraries. | Component | CUDA build | ROCm build | | --- | --- | --- | | Compiler | GCC and NVCC | GCC and `hipcc` | -| Build system | CMake 3.20+ | CMake 3.20+ | +| Build system | CMake 3.24+ | CMake 3.24+ | See [hardware requirements](../getting-started/index.md#hardware-requirements) for supported GPUs and required CUDA or ROCm versions. @@ -36,6 +36,14 @@ cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --clean-first --parallel ``` +The default builds for every supported major CUDA architecture (`all-major`), +so compiling takes a while. To compile faster for only the GPU in the build +machine, pass `native`: + +```bash +cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_CUDA_ARCHITECTURES=native +``` + The build selects the sparse matrix–vector backend from the cuSPARSE version: @@ -44,9 +52,6 @@ version: | CUDA 12.4–13.2 | `cusparseSpMV` | | CUDA 13.3+ | `cusparseSpMVOp` | -To target a specific CUDA architecture, pass -`-DCMAKE_CUDA_ARCHITECTURES=` when configuring. - ### ROCm Enable HIP and provide the architecture of the target AMD GPU: diff --git a/docs/guides/python.md b/docs/guides/python.md index 8f20bd0..e6abbe9 100644 --- a/docs/guides/python.md +++ b/docs/guides/python.md @@ -47,7 +47,7 @@ cd cuPDLPx python -m pip install . ``` -Building from source requires CMake 3.21+ and a +Building from source requires CMake 3.24+ and a [CUDA or ROCm toolchain](command-line.md#build-requirements). Pip may build the package locally if no compatible wheel is available. diff --git a/docs/implementation/gpu-backends.md b/docs/implementation/gpu-backends.md index 5e3d907..dd29142 100644 --- a/docs/implementation/gpu-backends.md +++ b/docs/implementation/gpu-backends.md @@ -25,21 +25,18 @@ backend selection, and workspace reuse. ### CUDA -CMake selects default architectures based on the CUDA version. To reduce -binary size, specify the target architecture: +By default CMake builds for every supported major CUDA architecture +(`all-major`). To build only for the GPU in the build machine, pass `native`: ```bash -cmake -B build -DCMAKE_CUDA_ARCHITECTURES=90 +cmake -B build -DCMAKE_CUDA_ARCHITECTURES=native cmake --build build --parallel ``` -Use an architecture supported by the installed CUDA toolkit and the deployment -GPU. - ### ROCm -HIP builds require a target architecture. The default is `gfx90a`; override it -for other devices: +HIP builds use CMake's GPU architecture detection by default. Set the target +architecture explicitly for headless builds or when targeting another device: ```bash cmake -B build \ diff --git a/include/cupdlpx_types.h b/include/cupdlpx_types.h index 044bcbf..de62c93 100644 --- a/include/cupdlpx_types.h +++ b/include/cupdlpx_types.h @@ -16,7 +16,6 @@ limitations under the License. #pragma once -#include "PSLP_stats.h" #include #include @@ -146,7 +145,6 @@ extern "C" double cumulative_time_sec; double presolve_time; int presolve_status; - // PresolveStats presolve_stats; double absolute_primal_residual; double relative_primal_residual; diff --git a/internal/presolve.h b/internal/presolve.h index 8937668..dd3275e 100644 --- a/internal/presolve.h +++ b/internal/presolve.h @@ -2,7 +2,6 @@ #define PRESOLVE_H #include "PSLP_API.h" -#include "PSLP_stats.h" #include "cupdlpx.h" #ifdef __cplusplus diff --git a/pyproject.toml b/pyproject.toml index f60c034..0b6d255 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,7 @@ dependencies = ["numpy>=1.21", "scipy>=1.8"] [tool.scikit-build] build-dir = "build/{wheel_tag}" -cmake.version = ">=3.21" +cmake.version = ">=3.24" cmake.build-type = "Release" wheel.packages = ["python/cupdlpx"] sdist.include = [ @@ -35,7 +35,6 @@ sdist.include = [ ] [tool.scikit-build.cmake.define] -CMAKE_CUDA_ARCHITECTURES = "all" CMAKE_CUDA_STANDARD = "17" CUPDLPX_BUILD_PYTHON = "ON" CUPDLPX_BUILD_STATIC_LIB = "ON" @@ -77,4 +76,4 @@ source = ["cupdlpx"] [tool.coverage.report] fail_under = 80 show_missing = true -skip_covered = true \ No newline at end of file +skip_covered = true diff --git a/python_bindings/CMakeLists.txt b/python_bindings/CMakeLists.txt index bdf56bf..638cb53 100644 --- a/python_bindings/CMakeLists.txt +++ b/python_bindings/CMakeLists.txt @@ -1,6 +1,6 @@ # python_bindings/CMakeLists.txt -cmake_minimum_required(VERSION 3.21) +cmake_minimum_required(VERSION 3.24) # sources set(PYBIND_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/_core_bindings.cpp) @@ -38,8 +38,8 @@ install(TARGETS _cupdlpx_core ) if(WIN32) - # Install runtime DLL dependencies next to the extension module so Python can - # resolve them without additional os.add_dll_directory(...) calls. + # Copy runtime DLLs known to CMake, such as PSLP. CUDA's imported targets are + # UNKNOWN libraries, so CUDA DLLs are provided by the user's toolkit/environment. install(FILES $ DESTINATION cupdlpx OPTIONAL diff --git a/src/presolve.c b/src/presolve.c index 67b7b20..7148155 100644 --- a/src/presolve.c +++ b/src/presolve.c @@ -167,7 +167,6 @@ cupdlpx_result_t *create_result_from_presolve(const cupdlpx_presolve_info_t *inf { result->termination_reason = TERMINATION_REASON_UNSPECIFIED; } - // result->presolve_stats = *(info->presolver->stats); if (result->num_variables > 0) { result->primal_solution = (double *)safe_calloc(result->num_variables, sizeof(double)); @@ -224,9 +223,6 @@ void pslp_postsolve(const cupdlpx_presolve_info_t *info, cupdlpx_result_t *resul result->primal_objective_value = obj; result->dual_objective_value = obj; } - // if (info->presolver->stats != NULL) { - // result->presolve_stats = *(info->presolver->stats); - // } return; }