Skip to content

Commit f332d93

Browse files
ZedongPengLhongpei
authored andcommitted
Core Refactoring: Headers Decoupling and CMake Migration (MIT-Lu-Lab#26)
* Refactor: Separate Public/Internal Headers * update readme * remove Makefile and update test.sh * add support for all CUDA ARCH * CI: add clang format check * update clang-format-check.yml * remove clang_format_check.yml * update readme
1 parent 518e623 commit f332d93

23 files changed

+2024
-1574
lines changed

CMakeLists.txt

Lines changed: 141 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# -----------------------------------------------------------------------------
2+
# ROOT CMakeLists.txt for cuPDLPx (Unified Build System)
3+
# -----------------------------------------------------------------------------
14
cmake_minimum_required(VERSION 3.20)
25

36
# Project config
@@ -8,43 +11,56 @@ set(CMAKE_C_STANDARD 99)
811
set(CMAKE_CXX_STANDARD 17)
912
set(CMAKE_CXX_STANDARD_REQUIRED ON)
1013
set(CMAKE_CXX_EXTENSIONS OFF)
14+
# Set default build type to Release if not specified (Optimized builds)
15+
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
16+
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
17+
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
18+
endif()
19+
20+
# Increase compatibility by compiling for all supported real and virtual architectures.
21+
set(CMAKE_CUDA_ARCHITECTURES all)
1122

12-
# On Windows, map strtok_r to strtok_s for compatibility
23+
# Global Compile flags (corresponding to CFLAGS/NVCCFLAGS)
24+
add_compile_options(-fPIC -O3 -Wall -Wextra -g)
25+
26+
# Windows compatibility
1327
if (WIN32)
1428
add_definitions(-Dstrtok_r=strtok_s)
1529
endif()
1630

17-
# Optional: be explicit about CUDA standard and separable compilation
31+
# CUDA standards and RDC (Relocatable Device Code) for shared/static linking
1832
set(CMAKE_CUDA_STANDARD 17)
1933
set(CMAKE_CUDA_STANDARD_REQUIRED ON)
2034

21-
set(CMAKE_CUDA_ARCHITECTURES "all")
22-
35+
# -----------------------------------------------------------------------------
36+
# FIND DEPENDENCIES
37+
# -----------------------------------------------------------------------------
2338
set(PYBIND11_FINDPYTHON ON)
2439
find_package(pybind11 CONFIG REQUIRED)
2540
find_package(CUDAToolkit REQUIRED)
2641
find_package(ZLIB REQUIRED)
42+
find_package(Python3 COMPONENTS Interpreter REQUIRED) # For versioning script
2743

2844
# -----------------------------------------------------------------------------
29-
# Version header generation
45+
# VERSION HEADER GENERATION (Build/generated/version.h)
3046
# -----------------------------------------------------------------------------
31-
# Get python for versioning script
32-
find_package(Python3 COMPONENTS Interpreter REQUIRED)
33-
3447
# Extract version from pyproject.toml
3548
execute_process(
3649
COMMAND ${Python3_EXECUTABLE} -c
3750
[=[
3851
import sys
39-
# Use stdlib tomllib if available, otherwise fall back to tomli (both accept .load on a binary file)
4052
try:
41-
import tomllib as toml # Python 3.11+
53+
import tomllib as toml
4254
except ModuleNotFoundError:
4355
import tomli as toml
56+
import os
57+
58+
if not os.path.exists("pyproject.toml"):
59+
sys.stderr.write("Error: pyproject.toml not found in the root directory.\n")
60+
sys.exit(1)
4461

4562
with open("pyproject.toml", "rb") as f:
4663
data = toml.load(f)
47-
4864
ver = data["project"]["version"]
4965
print(ver)
5066
]=]
@@ -53,56 +69,147 @@ print(ver)
5369
OUTPUT_STRIP_TRAILING_WHITESPACE
5470
)
5571

56-
# Print the version to CMake output
5772
message(STATUS "cuPDLPx version from pyproject.toml = ${CUPDLPX_VERSION}")
5873

5974
# Generate version.h from version.h.in
6075
configure_file(
61-
${CMAKE_CURRENT_SOURCE_DIR}/cupdlpx/version.h.in
76+
${CMAKE_CURRENT_SOURCE_DIR}/version.h.in
6277
${CMAKE_CURRENT_BINARY_DIR}/generated/version.h
6378
@ONLY
6479
)
6580

6681
# Make the generated files available for inclusion
6782
include_directories(${CMAKE_CURRENT_BINARY_DIR}/generated)
6883

84+
6985
# -----------------------------------------------------------------------------
70-
# Build the core native library that the Python extension links against
86+
# SOURCE DISCOVERY & TARGET DEFINITION
7187
# -----------------------------------------------------------------------------
72-
add_library(cupdlpx_core STATIC
73-
cupdlpx/interface.c
74-
cupdlpx/preconditioner.c
75-
cupdlpx/solver.cu
76-
cupdlpx/utils.cu
88+
# Discover sources (Assuming src/ directory based on Makefile)
89+
file(GLOB C_SOURCES
90+
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.c"
91+
)
92+
file(GLOB CU_SOURCES
93+
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.cu"
94+
)
95+
# Exclude cli.c from library builds
96+
list(REMOVE_ITEM C_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/cli.c")
97+
98+
# Set common include directories for the core libraries
99+
set(CORE_INCLUDE_DIRS
100+
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include # Public API headers
101+
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/internal # Internal implementation headers
102+
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/generated # Generated headers (version.h)
77103
)
78104

79-
# Public headers for dependents (e.g., the pybind11 module)
80-
target_include_directories(cupdlpx_core
81-
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/cupdlpx
82-
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/generated
105+
# Set common link libraries
106+
set(CORE_LINK_LIBS PUBLIC
107+
CUDA::cudart
108+
CUDA::cublas
109+
CUDA::cusparse
110+
ZLIB::ZLIB
83111
)
84112

85-
# Ensure position-independent code so it can be linked into a Python extension
86-
set_target_properties(cupdlpx_core PROPERTIES
87-
POSITION_INDEPENDENT_CODE ON
113+
# -----------------------------------------------------------------------------
114+
# 1. Core STATIC Library (cupdlpx_core)
115+
# -----------------------------------------------------------------------------
116+
add_library(cupdlpx_core STATIC
117+
${C_SOURCES}
118+
${CU_SOURCES}
88119
)
120+
target_include_directories(cupdlpx_core ${CORE_INCLUDE_DIRS})
121+
target_link_libraries(cupdlpx_core ${CORE_LINK_LIBS})
89122

90-
# If you compile CUDA sources in this target, enable separable compilation
91123
set_target_properties(cupdlpx_core PROPERTIES
124+
POSITION_INDEPENDENT_CODE ON
92125
CUDA_SEPARABLE_COMPILATION ON
93126
CUDA_RESOLVE_DEVICE_SYMBOLS ON
94127
)
95128

96-
# Link against CUDA runtime and libraries you use
97-
target_link_libraries(cupdlpx_core PUBLIC
98-
CUDA::cudart
99-
CUDA::cublas
100-
CUDA::cusparse
101-
ZLIB::ZLIB
129+
# -----------------------------------------------------------------------------
130+
# 2. Shared Library (libcupdlpx.so)
131+
# -----------------------------------------------------------------------------
132+
add_library(cupdlpx_shared SHARED
133+
${C_SOURCES}
134+
${CU_SOURCES}
135+
)
136+
target_include_directories(cupdlpx_shared ${CORE_INCLUDE_DIRS})
137+
target_link_libraries(cupdlpx_shared ${CORE_LINK_LIBS})
138+
139+
set_target_properties(cupdlpx_shared PROPERTIES
140+
OUTPUT_NAME "cupdlpx"
141+
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" # Output to ./build/
142+
CUDA_SEPARABLE_COMPILATION ON
143+
CUDA_RESOLVE_DEVICE_SYMBOLS ON
144+
)
145+
146+
# -----------------------------------------------------------------------------
147+
# 3. CLI Executable (cupdlpx)
148+
# -----------------------------------------------------------------------------
149+
add_executable(cupdlpx_cli src/cli.c)
150+
151+
target_include_directories(cupdlpx_cli PRIVATE
152+
${CMAKE_CURRENT_SOURCE_DIR}/include # For public headers
153+
${CMAKE_CURRENT_SOURCE_DIR}/internal # For internal headers
154+
${CMAKE_CURRENT_BINARY_DIR}/generated # For version.h
102155
)
103156

157+
# Link CLI to the static core library
158+
target_link_libraries(cupdlpx_cli PRIVATE cupdlpx_core)
159+
160+
set_target_properties(cupdlpx_cli PROPERTIES
161+
OUTPUT_NAME "cupdlpx"
162+
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" # Output to ./build/
163+
)
164+
165+
# -----------------------------------------------------------------------------
166+
# 4. Tests (CTest Integration)
167+
# -----------------------------------------------------------------------------
168+
enable_testing()
169+
file(GLOB TEST_SOURCES
170+
"${CMAKE_CURRENT_SOURCE_DIR}/test/*.c"
171+
"${CMAKE_CURRENT_SOURCE_DIR}/test/*.cu"
172+
)
173+
174+
foreach(TEST_SRC ${TEST_SOURCES})
175+
get_filename_component(TEST_NAME ${TEST_SRC} NAME_WE)
176+
177+
add_executable(${TEST_NAME} ${TEST_SRC})
178+
179+
# Link tests to the core static library
180+
target_link_libraries(${TEST_NAME} PRIVATE cupdlpx_core)
181+
182+
# Set up test includes
183+
target_include_directories(${TEST_NAME}
184+
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
185+
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/internal
186+
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/generated
187+
)
188+
189+
# Register with CTest
190+
add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
191+
192+
# Output to ./build/tests/
193+
set_target_properties(${TEST_NAME} PROPERTIES
194+
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/tests"
195+
)
196+
endforeach()
197+
104198
# -----------------------------------------------------------------------------
105-
# Add the pybind11 module (lives in subdir)
199+
# 5. Python Bindings
106200
# -----------------------------------------------------------------------------
107201
add_subdirectory(python_bindings)
108202

203+
# -----------------------------------------------------------------------------
204+
# 6. Install Targets
205+
# -----------------------------------------------------------------------------
206+
install(TARGETS cupdlpx_core cupdlpx_shared
207+
ARCHIVE DESTINATION lib
208+
LIBRARY DESTINATION lib
209+
)
210+
211+
# Install headers (only public headers)
212+
install(DIRECTORY include/
213+
DESTINATION include/
214+
FILES_MATCHING PATTERN "*.h"
215+
)

0 commit comments

Comments
 (0)