Skip to content
Merged
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
294 changes: 147 additions & 147 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -686,8 +686,7 @@ function(cuopt_configure_component target)
CXX_SCAN_FOR_MODULES OFF
BUILD_RPATH_USE_ORIGIN TRUE
INSTALL_RPATH "\$ORIGIN"
# Same hidden-by-default visibility that #1625 applies to cuopt_objs. The
# components are the shipped artifacts, so they need it too.
# Same hidden-by-default visibility that #1625 applies to the *_objs libraries.
CXX_VISIBILITY_PRESET hidden
CUDA_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN ON
Expand Down Expand Up @@ -747,14 +746,11 @@ get_filename_component(CUDSS_MT_LIB_FILE_NAME "${CUDSS_MT_LIB_FILE}" NAME)
# modules that never call the GPU can link this instead of libcuopt.so.
#
# LANGUAGES is deliberately not CUDA: adding a .cu file here should fail loudly rather than
# quietly reintroduce a CUDA dependency. Built as an OBJECT library first, mirroring
# cuopt_objs/cuopt, so cuopt_static can link the objects directly for tests that reach
# parser internals the shared library does not export.
# quietly reintroduce a CUDA dependency. Built as an OBJECT library first (mirrored below by
# cuopt_routing_objs / cuopt_mathopt_objs) so cuopt_static can link the objects directly.
add_library(cuopt_client_objs OBJECT ${CUOPT_CLIENT_SRC_FILES})
# Default visibility, deliberately unlike cuopt_objs: this library was carved out of the
# internals rather than designed as an export surface, so libcuopt resolves ~239 symbols
# from it. Hiding them would mean annotating essentially every host-side method with
# CUOPT_EXPORT.
# Default visibility, deliberately unlike the other *_objs: carved out of the internals rather
# than designed as an export surface, so libcuopt resolves ~239 symbols from it.
set_target_properties(cuopt_client_objs
PROPERTIES POSITION_INDEPENDENT_CODE ON
CXX_SCAN_FOR_MODULES OFF
Expand Down Expand Up @@ -863,9 +859,75 @@ target_link_libraries(cuopt_client
)


# ##################################################################################################
# - cuDSS threading layer --------------------------------------------------------------------------
message(STATUS "target include directories CUDSS_INCLUDES = ${CUDSS_INCLUDE}")

# Build our own cuDSS threading layer against our own libgomp instead of cuDSS's prebuilt one,
# which can resolve a different libgomp instance (#1219). Off by default; enabled for wheel
# builds (ci/build_wheel_libcuopt.sh).
option(CUOPT_BUILD_CUSTOM_CUDSS_MTLAYER "Build a cuDSS threading layer linked against our own libgomp" OFF)

if (CUOPT_BUILD_CUSTOM_CUDSS_MTLAYER)
add_library(cudss_mtlayer_cuopt SHARED src/barrier/cudss_mtlayer_cuopt.cpp)
target_include_directories(cudss_mtlayer_cuopt PRIVATE "${CUDSS_INCLUDE}")
target_link_libraries(cudss_mtlayer_cuopt PRIVATE OpenMP::OpenMP_CXX CUDA::cudart)
set_target_properties(cudss_mtlayer_cuopt
PROPERTIES BUILD_RPATH "\$ORIGIN"
INSTALL_RPATH "\$ORIGIN"
)
set(CUDSS_MT_LIB_FILE_NAME "libcudss_mtlayer_cuopt.so")
else ()
# Full path, not just the basename, so the runtime dlopen pin (sparse_cholesky.cuh) and
# cudssSetThreadingLayer() resolve the exact same file CMake found (#1883).
set(CUDSS_MT_LIB_FILE_NAME "${CUDSS_MT_LIB_FILE}")
endif ()

# cuopt_routing: VRP / routing engine (omitted when SKIP_ROUTING_BUILD=ON)
#
# OBJECT library first, mirroring cuopt_client_objs, so cuopt_static links the same compiled
# objects instead of recompiling routing a second time.
if(NOT SKIP_ROUTING_BUILD)
add_library(cuopt_routing SHARED ${CUOPT_ROUTING_SRC_FILES})
add_library(cuopt_routing_objs OBJECT ${CUOPT_ROUTING_SRC_FILES})
set_target_properties(cuopt_routing_objs
PROPERTIES POSITION_INDEPENDENT_CODE ON
CXX_SCAN_FOR_MODULES OFF
CXX_VISIBILITY_PRESET hidden
CUDA_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN ON
)
target_compile_options(cuopt_routing_objs
PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:${CUOPT_CXX_FLAGS}>"
"$<$<COMPILE_LANGUAGE:CUDA>:${CUOPT_CUDA_FLAGS}>"
)
target_compile_definitions(cuopt_routing_objs
PUBLIC "CUOPT_LOG_ACTIVE_LEVEL=RAPIDS_LOGGER_LOG_LEVEL_${LIBCUOPT_LOGGING_LEVEL}"
)
target_include_directories(cuopt_routing_objs
PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/src"
"${CMAKE_CURRENT_BINARY_DIR}"
PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>"
INTERFACE
"$<INSTALL_INTERFACE:include>"
)
# Repeated on cuopt_routing below: $<TARGET_OBJECTS:...> doesn't inherit an OBJECT
# library's PUBLIC link interface.
target_link_libraries(cuopt_routing_objs
PUBLIC
cuopt_client
rmm::rmm
rapids_logger::rapids_logger
CCCL::CCCL
raft::raft
CUDA::cublas
CUDA::cusparse
PRIVATE simde::simde OpenMP::OpenMP_CXX OpenMP::OpenMP_CUDA
)

add_library(cuopt_routing SHARED $<TARGET_OBJECTS:cuopt_routing_objs>)
cuopt_configure_component(cuopt_routing)
target_link_libraries(cuopt_routing
PUBLIC
Expand All @@ -886,37 +948,62 @@ if(NOT SKIP_ROUTING_BUILD)
endif()

# cuopt_mathopt: LP / MIP / numerical optimization engine
add_library(cuopt_mathopt SHARED ${CUOPT_MATHOPT_SRC_FILES})
cuopt_configure_component(cuopt_mathopt)
target_include_directories(cuopt_mathopt PRIVATE
#
# OBJECT library first, same reason as cuopt_routing_objs above.
add_library(cuopt_mathopt_objs OBJECT ${CUOPT_MATHOPT_SRC_FILES})
set_target_properties(cuopt_mathopt_objs
PROPERTIES POSITION_INDEPENDENT_CODE ON
CXX_SCAN_FOR_MODULES OFF
CXX_VISIBILITY_PRESET hidden
CUDA_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN ON
)
target_compile_options(cuopt_mathopt_objs
PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:${CUOPT_CXX_FLAGS}>"
"$<$<COMPILE_LANGUAGE:CUDA>:${CUOPT_CUDA_FLAGS}>"
)
target_compile_definitions(cuopt_mathopt_objs
PUBLIC "CUOPT_LOG_ACTIVE_LEVEL=RAPIDS_LOGGER_LOG_LEVEL_${LIBCUOPT_LOGGING_LEVEL}"
)
target_include_directories(cuopt_mathopt_objs
PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/src"
"${CMAKE_CURRENT_BINARY_DIR}"
PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>"
INTERFACE
"$<INSTALL_INTERFACE:include>"
)
target_include_directories(cuopt_mathopt_objs PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty"
"${CMAKE_CURRENT_SOURCE_DIR}/src/io"
"${CUDSS_INCLUDE}"
$<$<BOOL:${CUOPT_PARSER_WITH_BZIP2}>:${BZIP2_INCLUDE_DIRS}>
$<$<BOOL:${CUOPT_PARSER_WITH_ZLIB}>:${ZLIB_INCLUDE_DIRS}>
)
# Adding Papilo as a system include messes up clang's include resolution if papilo is already installed as a conda package
target_include_directories(cuopt_mathopt PRIVATE
target_include_directories(cuopt_mathopt_objs PRIVATE
"${papilo_SOURCE_DIR}/src"
"${papilo_BINARY_DIR}"
)
target_include_directories(cuopt_mathopt SYSTEM PRIVATE
target_include_directories(cuopt_mathopt_objs SYSTEM PRIVATE
"${pslp_SOURCE_DIR}/include"
"${dejavu_SOURCE_DIR}"
# utilities/version_info.cpp includes highway, and utilities builds into this
# component since cuopt_base was removed.
"${highway_SOURCE_DIR}"
)
target_compile_definitions(cuopt_mathopt
target_compile_definitions(cuopt_mathopt_objs
PUBLIC CUSPARSE_ENABLE_EXPERIMENTAL_API
# utilities/version_info.cpp reports these; it builds here now that cuopt_base is gone.
CUOPT_CUDA_ARCHITECTURES="${JOINED_CUDA_ARCHITECTURES}"
CUOPT_CPU_ARCHITECTURE="${CMAKE_SYSTEM_PROCESSOR}"
PRIVATE CUDSS_MT_LIB_FILE_NAME="${CUDSS_MT_LIB_FILE_NAME}"
)
target_link_libraries(cuopt_mathopt
# Repeated on cuopt_mathopt below -- see the note on cuopt_routing_objs above.
target_link_libraries(cuopt_mathopt_objs
PUBLIC
# The parsers and the host-side problem representation live in cuopt_client.
cuopt_client
rmm::rmm
rapids_logger::rapids_logger
Expand All @@ -932,153 +1019,61 @@ target_link_libraries(cuopt_mathopt
nccl_external
${CMAKE_DL_LIBS}
)
target_link_libraries(cuopt_mathopt PRIVATE $<TARGET_FILE:PSLP>)
add_dependencies(cuopt_mathopt PSLP)
target_link_libraries(cuopt_mathopt PRIVATE $<TARGET_FILE:hwy>)
add_dependencies(cuopt_mathopt hwy)
target_include_directories(cuopt_mathopt SYSTEM PRIVATE
# partitioner.cpp includes <kaminpar.h>; KaMinPar is linked by file below so its PUBLIC
# defines aren't inherited -- replicate the ones <kaminpar.h> needs. KAMINPAR_64BIT_EDGE_IDS
# must stay in sync with get_kaminpar.cmake or the prebuilt archive's ABI mismatches.
target_include_directories(cuopt_mathopt_objs SYSTEM PRIVATE
$<TARGET_PROPERTY:KaMinPar::KaMinPar,INTERFACE_INCLUDE_DIRECTORIES>)
target_compile_definitions(cuopt_mathopt PRIVATE TBB_PREVIEW_GLOBAL_CONTROL KAMINPAR_64BIT_EDGE_IDS)
target_link_libraries(cuopt_mathopt PRIVATE $<TARGET_FILE:KaMinPar::KaMinPar>)
target_compile_definitions(cuopt_mathopt_objs PRIVATE TBB_PREVIEW_GLOBAL_CONTROL KAMINPAR_64BIT_EDGE_IDS)
if (TARGET KaMinPar)
add_dependencies(cuopt_mathopt KaMinPar)
add_dependencies(cuopt_mathopt_objs KaMinPar)
endif ()
add_library(cuopt::mathopt ALIAS cuopt_mathopt)

# ##################################################################################################
# - cuopt_objs: OBJECT library used by cuopt_static for internal test builds ---------------------
add_library(cuopt_objs OBJECT
${CUOPT_SRC_FILES}
)
set_target_properties(cuopt_objs
PROPERTIES POSITION_INDEPENDENT_CODE ON
CXX_VISIBILITY_PRESET hidden
CUDA_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN ON
CXX_SCAN_FOR_MODULES OFF
)
target_compile_definitions(cuopt_objs
PUBLIC "CUOPT_LOG_ACTIVE_LEVEL=RAPIDS_LOGGER_LOG_LEVEL_${LIBCUOPT_LOGGING_LEVEL}"
PUBLIC CUSPARSE_ENABLE_EXPERIMENTAL_API
)
target_compile_options(cuopt_objs
PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:${CUOPT_CXX_FLAGS}>"
"$<$<COMPILE_LANGUAGE:CUDA>:${CUOPT_CUDA_FLAGS}>"
)

# ##################################################################################################
# - include paths ---------------------------------------------------------------------------------
message(STATUS "target include directories CUDSS_INCLUDES = ${CUDSS_INCLUDE}")

# Adding Papilo as a system include messes up clang's include resolution if papilo is already installed as a conda package
target_include_directories(cuopt_objs PRIVATE
"${papilo_SOURCE_DIR}/src"
"${papilo_BINARY_DIR}"
)

target_include_directories(cuopt_objs SYSTEM PRIVATE
"${pslp_SOURCE_DIR}/include"
"${dejavu_SOURCE_DIR}"
"${highway_SOURCE_DIR}"
)

target_include_directories(cuopt_objs
PRIVATE
add_library(cuopt_mathopt SHARED $<TARGET_OBJECTS:cuopt_mathopt_objs>)
cuopt_configure_component(cuopt_mathopt)
target_include_directories(cuopt_mathopt PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty"
"${CMAKE_CURRENT_SOURCE_DIR}/src"
"${CMAKE_CURRENT_SOURCE_DIR}/src/io"
"${CMAKE_CURRENT_SOURCE_DIR}/src/grpc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/grpc/client"
"${CMAKE_CURRENT_SOURCE_DIR}/src/grpc/codegen/generated"
"${CMAKE_CURRENT_BINARY_DIR}"
"${CUDSS_INCLUDE}"
$<$<BOOL:${CUOPT_PARSER_WITH_BZIP2}>:${BZIP2_INCLUDE_DIRS}>
$<$<BOOL:${CUOPT_PARSER_WITH_ZLIB}>:${ZLIB_INCLUDE_DIRS}>
PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>"
INTERFACE
"$<INSTALL_INTERFACE:include>"
)

# Link PSLP by file to avoid export dependency tracking
target_link_libraries(cuopt_objs PRIVATE $<TARGET_FILE:PSLP>)
add_dependencies(cuopt_objs PSLP)

target_link_libraries(cuopt_objs PRIVATE $<TARGET_FILE:hwy>)
add_dependencies(cuopt_objs hwy)

# Link KaMinPar by file to avoid export dependency tracking (mirrors PSLP above).
# KaMinPar is a from-source static library fully embedded into libcuopt.so; it is never
# installed (INSTALL_KAMINPAR OFF) and consumers of cuopt::cuopt never use it, so it must
# not leak into cuopt's exported link interface (otherwise rapids_export fails with
# "target KaMinPar is not in any export set"). libKaMinPar.a is self-contained (the
# kaminpar-common OBJECT lib is archived into it); we only need its public headers
# (<kaminpar.h>, which pulls in stdlib + TBB) at compile time.
target_include_directories(cuopt_objs SYSTEM PRIVATE
$<TARGET_PROPERTY:KaMinPar::KaMinPar,INTERFACE_INCLUDE_DIRECTORIES>)
# partitioner.cpp includes <kaminpar.h>. Because KaMinPar is linked by file, cuopt
# does NOT inherit KaMinPar's PUBLIC compile definitions, so we must replicate the ones that
# affect what <kaminpar.h> compiles to:
# * TBB_PREVIEW_GLOBAL_CONTROL - <kaminpar.h> includes <tbb/global_control.h>, which older
# TBB gates behind this macro.
# * KAMINPAR_64BIT_EDGE_IDS - selects EdgeID = uint64 in <kaminpar.h>. MUST stay in sync
# with the KAMINPAR_64BIT_* options in get_kaminpar.cmake;
# otherwise the public API types (e.g. copy_graph's span<>
# widths) mismatch the prebuilt archive => undefined refs.
target_compile_definitions(cuopt_objs PRIVATE TBB_PREVIEW_GLOBAL_CONTROL KAMINPAR_64BIT_EDGE_IDS)
# Real (non-imported) target only exists when KaMinPar is built from source via CPM;
# force it to build before the objects that include its headers since it is EXCLUDE_FROM_ALL.
if (TARGET KaMinPar)
add_dependencies(cuopt_objs KaMinPar)
endif ()

# Build our own cuDSS threading layer against cuopt_objs's own libgomp instead of cuDSS's
# prebuilt one, which can resolve a different libgomp instance (#1219). Off by default;
# enabled for wheel builds (ci/build_wheel_libcuopt.sh).
option(CUOPT_BUILD_CUSTOM_CUDSS_MTLAYER "Build a cuDSS threading layer linked against our own libgomp" OFF)

if (CUOPT_BUILD_CUSTOM_CUDSS_MTLAYER)
add_library(cudss_mtlayer_cuopt SHARED src/barrier/cudss_mtlayer_cuopt.cpp)
target_include_directories(cudss_mtlayer_cuopt PRIVATE "${CUDSS_INCLUDE}")
target_link_libraries(cudss_mtlayer_cuopt PRIVATE OpenMP::OpenMP_CXX CUDA::cudart)
set_target_properties(cudss_mtlayer_cuopt
PROPERTIES BUILD_RPATH "\$ORIGIN"
INSTALL_RPATH "\$ORIGIN"
)
set(CUDSS_MT_LIB_FILE_NAME "libcudss_mtlayer_cuopt.so")
else ()
# Full path, not just the basename, so the runtime dlopen pin (sparse_cholesky.cuh) and
# cudssSetThreadingLayer() resolve the exact same file CMake found (#1883).
set(CUDSS_MT_LIB_FILE_NAME "${CUDSS_MT_LIB_FILE}")
endif ()

target_compile_definitions(cuopt_objs
PRIVATE CUDSS_MT_LIB_FILE_NAME="${CUDSS_MT_LIB_FILE_NAME}"
PUBLIC
target_compile_definitions(cuopt_mathopt
PUBLIC CUSPARSE_ENABLE_EXPERIMENTAL_API
CUOPT_CUDA_ARCHITECTURES="${JOINED_CUDA_ARCHITECTURES}"
CUOPT_CPU_ARCHITECTURE="${CMAKE_SYSTEM_PROCESSOR}"
PRIVATE CUDSS_MT_LIB_FILE_NAME="${CUDSS_MT_LIB_FILE_NAME}"
)
target_include_directories(cuopt_objs PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/include)

target_link_libraries(cuopt_objs
target_link_libraries(cuopt_mathopt
PUBLIC
cuopt::cuopt_client
CUDA::cublas
CUDA::cusparse
# The parsers and the host-side problem representation live in cuopt_client.
cuopt_client
rmm::rmm
rapids_logger::rapids_logger
CCCL::CCCL
raft::raft
CUDA::cublas
CUDA::cusparse
${CUDSS_LIB_FILE}
PRIVATE
${CUOPT_PRIVATE_CUDA_LIBS}
simde::simde
OpenMP::OpenMP_CXX
OpenMP::OpenMP_CUDA
$<$<BOOL:${CUOPT_ENABLE_GRPC}>:protobuf::libprotobuf>
$<$<BOOL:${CUOPT_ENABLE_GRPC}>:gRPC::grpc++>
simde::simde
nccl_external
${CMAKE_DL_LIBS}
)
# Linked by file (not target_link_libraries(... KaMinPar)) so it doesn't leak into cuopt's
# exported link interface -- headers are already visible via cuopt_mathopt_objs above.
target_link_libraries(cuopt_mathopt PRIVATE $<TARGET_FILE:PSLP>)
add_dependencies(cuopt_mathopt PSLP)
target_link_libraries(cuopt_mathopt PRIVATE $<TARGET_FILE:hwy>)
add_dependencies(cuopt_mathopt hwy)
target_link_libraries(cuopt_mathopt PRIVATE $<TARGET_FILE:KaMinPar::KaMinPar>)
if (TARGET KaMinPar)
add_dependencies(cuopt_mathopt KaMinPar)
endif ()
add_library(cuopt::mathopt ALIAS cuopt_mathopt)


# ##################################################################################################
# - generate tests --------------------------------------------------------------------------------
Expand All @@ -1092,11 +1087,16 @@ endif ()
# single self-contained shared object rather than linking the shared libcuopt (see the Java
# classifier JARs).
if (BUILD_TESTS OR (BUILD_MIP_BENCHMARKS AND NOT BUILD_LP_ONLY) OR CUOPT_BUILD_STATIC_LIB)
# Embeds cuopt_client_objs directly rather than linking libcuopt_client.so: internal test
# binaries and the Java classifier JAR both reach parser/data-model internals that the
# shared library deliberately does not export. Do not also link cuopt::cuopt_client here --
# that would duplicate every symbol.
add_library(cuopt_static STATIC $<TARGET_OBJECTS:cuopt_objs> $<TARGET_OBJECTS:cuopt_client_objs>)
# Embeds the *_objs directly rather than linking the shared component libraries: internal
# tests and the Java classifier JAR reach internals the shared libraries don't export.
if(NOT SKIP_ROUTING_BUILD)
set(_cuopt_static_routing_objs $<TARGET_OBJECTS:cuopt_routing_objs>)
endif()
add_library(cuopt_static STATIC
$<TARGET_OBJECTS:cuopt_client_objs>
$<TARGET_OBJECTS:cuopt_mathopt_objs>
${_cuopt_static_routing_objs}
)
target_link_libraries(cuopt_static
PUBLIC
CUDA::cublas
Expand Down
Loading