Skip to content

Commit 9bbfdb0

Browse files
authored
Merge branch 'main' into move_datasets_to_s3
2 parents 1d99d85 + 787243b commit 9bbfdb0

File tree

29 files changed

+184
-85
lines changed

29 files changed

+184
-85
lines changed

.github/workflows/nightly.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION. All rights reserved.
22
# SPDX-License-Identifier: Apache-2.0
33

44
name: Trigger Nightly cuOpt Pipeline
@@ -17,7 +17,7 @@ jobs:
1717
matrix:
1818
cuopt_branch:
1919
- "main"
20-
- "release/25.12"
20+
- "release/26.02"
2121
steps:
2222
- uses: actions/checkout@v4
2323
- name: Trigger Pipeline

build.sh

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/bash
22

3-
# SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
# SPDX-FileCopyrightText: Copyright (c) 2021-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
44
# SPDX-License-Identifier: Apache-2.0
55

66

@@ -15,7 +15,7 @@ REPODIR=$(cd "$(dirname "$0")"; pwd)
1515
LIBCUOPT_BUILD_DIR=${LIBCUOPT_BUILD_DIR:=${REPODIR}/cpp/build}
1616
LIBMPS_PARSER_BUILD_DIR=${LIBMPS_PARSER_BUILD_DIR:=${REPODIR}/cpp/libmps_parser/build}
1717

18-
VALIDARGS="clean libcuopt libmps_parser cuopt_mps_parser cuopt cuopt_server cuopt_sh_client docs deb -a -b -g -fsanitize -v -l= --verbose-pdlp --build-lp-only --no-fetch-rapids --skip-c-python-adapters --skip-tests-build --skip-routing-build --skip-fatbin-write --host-lineinfo [--cmake-args=\\\"<args>\\\"] [--cache-tool=<tool>] -n --allgpuarch --ci-only-arch --show_depr_warn -h --help"
18+
VALIDARGS="clean libcuopt libmps_parser cuopt_mps_parser cuopt cuopt_server cuopt_sh_client docs deb -a -b -g -fsanitize -tsan -msan -v -l= --verbose-pdlp --build-lp-only --no-fetch-rapids --skip-c-python-adapters --skip-tests-build --skip-routing-build --skip-fatbin-write --host-lineinfo [--cmake-args=\\\"<args>\\\"] [--cache-tool=<tool>] -n --allgpuarch --ci-only-arch --show_depr_warn -h --help"
1919
HELP="$0 [<target> ...] [<flag> ...]
2020
where <target> is:
2121
clean - remove all existing build artifacts and configuration (start over)
@@ -32,7 +32,9 @@ HELP="$0 [<target> ...] [<flag> ...]
3232
-g - build for debug
3333
-a - Enable assertion (by default in debug mode)
3434
-b - Build with benchmark settings
35-
-fsanitize - Build with sanitizer
35+
-fsanitize - Build with AddressSanitizer and UndefinedBehaviorSanitizer
36+
-tsan - Build with ThreadSanitizer (cannot be used with -fsanitize or -msan)
37+
-msan - Build with MemorySanitizer (cannot be used with -fsanitize or -tsan)
3638
-n - no install step
3739
--no-fetch-rapids - don't fetch rapids dependencies
3840
-l= - log level. Options are: TRACE | DEBUG | INFO | WARN | ERROR | CRITICAL | OFF. Default=INFO
@@ -76,6 +78,8 @@ BUILD_ALL_GPU_ARCH=0
7678
BUILD_CI_ONLY=0
7779
BUILD_LP_ONLY=0
7880
BUILD_SANITIZER=0
81+
BUILD_TSAN=0
82+
BUILD_MSAN=0
7983
SKIP_C_PYTHON_ADAPTERS=0
8084
SKIP_TESTS_BUILD=0
8185
SKIP_ROUTING_BUILD=0
@@ -230,6 +234,12 @@ fi
230234
if hasArg -fsanitize; then
231235
BUILD_SANITIZER=1
232236
fi
237+
if hasArg -tsan; then
238+
BUILD_TSAN=1
239+
fi
240+
if hasArg -msan; then
241+
BUILD_MSAN=1
242+
fi
233243
if hasArg --skip-c-python-adapters; then
234244
SKIP_C_PYTHON_ADAPTERS=1
235245
fi
@@ -298,6 +308,24 @@ if [ ${BUILD_LP_ONLY} -eq 1 ] && [ ${SKIP_C_PYTHON_ADAPTERS} -eq 0 ]; then
298308
exit 1
299309
fi
300310

311+
if [ ${BUILD_SANITIZER} -eq 1 ] && [ ${BUILD_TSAN} -eq 1 ]; then
312+
echo "ERROR: -fsanitize and -tsan cannot be used together"
313+
echo "AddressSanitizer and ThreadSanitizer are mutually exclusive"
314+
exit 1
315+
fi
316+
317+
if [ ${BUILD_SANITIZER} -eq 1 ] && [ ${BUILD_MSAN} -eq 1 ]; then
318+
echo "ERROR: -fsanitize and -msan cannot be used together"
319+
echo "AddressSanitizer and MemorySanitizer are mutually exclusive"
320+
exit 1
321+
fi
322+
323+
if [ ${BUILD_TSAN} -eq 1 ] && [ ${BUILD_MSAN} -eq 1 ]; then
324+
echo "ERROR: -tsan and -msan cannot be used together"
325+
echo "ThreadSanitizer and MemorySanitizer are mutually exclusive"
326+
exit 1
327+
fi
328+
301329
if [ ${BUILD_ALL_GPU_ARCH} -eq 1 ]; then
302330
CUOPT_CMAKE_CUDA_ARCHITECTURES="RAPIDS"
303331
echo "Building for *ALL* supported GPU architectures..."
@@ -344,6 +372,8 @@ if buildAll || hasArg libcuopt; then
344372
-DFETCH_RAPIDS=${FETCH_RAPIDS} \
345373
-DBUILD_LP_ONLY=${BUILD_LP_ONLY} \
346374
-DBUILD_SANITIZER=${BUILD_SANITIZER} \
375+
-DBUILD_TSAN=${BUILD_TSAN} \
376+
-DBUILD_MSAN=${BUILD_MSAN} \
347377
-DSKIP_C_PYTHON_ADAPTERS=${SKIP_C_PYTHON_ADAPTERS} \
348378
-DBUILD_TESTS=$((1 - ${SKIP_TESTS_BUILD})) \
349379
-DSKIP_ROUTING_BUILD=${SKIP_ROUTING_BUILD} \

cpp/CMakeLists.txt

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,33 @@ endif(CMAKE_COMPILER_IS_GNUCXX)
7979
# 1. Run the binary with env var set: LD_PRELOAD="$(gcc -print-file-name=libasan.so)" ASAN_OPTIONS='protect_shadow_gap=0:replace_intrin=0'
8080
# 2. (Optional) To run with a debugger (gdb or cuda-gdb) use the additional ASAN option alloc_dealloc_mismatch=0
8181
if(BUILD_SANITIZER)
82-
list(APPEND CUOPT_CXX_FLAGS -fsanitize=address,undefined -fno-omit-frame-pointer -g -Wno-error=maybe-uninitialized)
82+
list(APPEND CUOPT_CXX_FLAGS -fsanitize=address,undefined -fno-omit-frame-pointer -g)
83+
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
84+
list(APPEND CUOPT_CXX_FLAGS -Wno-error=maybe-uninitialized)
85+
endif()
8386
add_link_options(-fsanitize=address,undefined)
8487
endif(BUILD_SANITIZER)
8588

89+
# To use ThreadSanitizer:
90+
# 1. Build with clang and the -tsan flag
91+
# 2. Run the binary with env var set: OMP_TOOL_LIBRARIES=/usr/lib/llvm-17/lib/libarcher.so ARCHER_OPTIONS='verbose=1' TSAN_OPTIONS='suppresions=cpp/utilities/tsan_suppressions.txt:ignore_noninstrumented_modules=1:halt_on_error=1'
92+
# Replace with local llvm install path. libarcher.so must be presetn
93+
if(BUILD_TSAN)
94+
message(STATUS "Building with ThreadSanitizer enabled")
95+
list(APPEND CUOPT_CXX_FLAGS -fsanitize=thread -fno-omit-frame-pointer -g)
96+
add_link_options(-fsanitize=thread)
97+
endif(BUILD_TSAN)
98+
99+
# To use MemorySanitizer:
100+
# 1. Build with clang and the -msan flag (MemorySanitizer requires clang)
101+
# 2. Run the binary with env var set: MSAN_OPTIONS='halt_on_error=1'
102+
# Note: MemorySanitizer requires all code (including libraries) to be instrumented for accurate results
103+
if(BUILD_MSAN)
104+
message(STATUS "Building with MemorySanitizer enabled")
105+
list(APPEND CUOPT_CXX_FLAGS -fsanitize=memory -fno-omit-frame-pointer -g -fsanitize-memory-track-origins=1)
106+
add_link_options(-fsanitize=memory)
107+
endif(BUILD_MSAN)
108+
86109
if(DEFINE_ASSERT)
87110
add_definitions(-DASSERT_MODE)
88111
endif(DEFINE_ASSERT)
@@ -116,7 +139,11 @@ if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.9)
116139
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -static-global-template-stub=false")
117140
endif()
118141
list(APPEND CUOPT_CUDA_FLAGS -Werror=cross-execution-space-call -Wno-deprecated-declarations -Xcompiler=-Werror --default-stream=per-thread)
119-
list(APPEND CUOPT_CUDA_FLAGS -Xcompiler=-Wall -Wno-error=non-template-friend)
142+
if("${CMAKE_CUDA_HOST_COMPILER}" MATCHES "clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
143+
list(APPEND CUOPT_CUDA_FLAGS -Xcompiler=-Wall)
144+
else()
145+
list(APPEND CUOPT_CUDA_FLAGS -Xcompiler=-Wall -Wno-error=non-template-friend)
146+
endif()
120147
list(APPEND CUOPT_CUDA_FLAGS -Xfatbin=-compress-all)
121148
if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 12.9 AND CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 13.0)
122149
list(APPEND CUOPT_CUDA_FLAGS -Xfatbin=--compress-level=3)

cpp/include/cuopt/error.hpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* clang-format off */
22
/*
3-
* SPDX-FileCopyrightText: Copyright (c) 2021-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
* SPDX-FileCopyrightText: Copyright (c) 2021-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66
/* clang-format on */
@@ -33,8 +33,6 @@ enum class error_type_t {
3333
*/
3434

3535
struct logic_error : public std::logic_error {
36-
explicit logic_error() = default;
37-
3836
logic_error(const logic_error& exception) = default;
3937

4038
// Move constructor

cpp/include/cuopt/linear_programming/utilities/internals.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* clang-format off */
22
/*
3-
* SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
* SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66
/* clang-format on */
@@ -62,6 +62,7 @@ namespace linear_programming {
6262

6363
class base_solution_t {
6464
public:
65+
virtual ~base_solution_t() = default;
6566
virtual bool is_mip() const = 0;
6667
};
6768

cpp/src/dual_simplex/barrier.cu

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* clang-format off */
22
/*
3-
* SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
* SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66
/* clang-format on */
@@ -44,6 +44,48 @@ namespace cuopt::linear_programming::dual_simplex {
4444

4545
auto constexpr use_gpu = true;
4646

47+
// non-template wrappers to work around clang compiler bug
48+
[[maybe_unused]] static void pairwise_multiply(
49+
float* a, float* b, float* out, int size, rmm::cuda_stream_view stream)
50+
{
51+
cub::DeviceTransform::Transform(
52+
cuda::std::make_tuple(a, b), out, size, cuda::std::multiplies<>{}, stream);
53+
}
54+
55+
[[maybe_unused]] static void pairwise_multiply(
56+
double* a, double* b, double* out, int size, rmm::cuda_stream_view stream)
57+
{
58+
cub::DeviceTransform::Transform(
59+
cuda::std::make_tuple(a, b), out, size, cuda::std::multiplies<>{}, stream);
60+
}
61+
62+
[[maybe_unused]] static void axpy(
63+
float alpha, float* x, float beta, float* y, float* out, int size, rmm::cuda_stream_view stream)
64+
{
65+
cub::DeviceTransform::Transform(
66+
cuda::std::make_tuple(x, y),
67+
out,
68+
size,
69+
[alpha, beta] __host__ __device__(float a, float b) { return alpha * a + beta * b; },
70+
stream);
71+
}
72+
73+
[[maybe_unused]] static void axpy(double alpha,
74+
double* x,
75+
double beta,
76+
double* y,
77+
double* out,
78+
int size,
79+
rmm::cuda_stream_view stream)
80+
{
81+
cub::DeviceTransform::Transform(
82+
cuda::std::make_tuple(x, y),
83+
out,
84+
size,
85+
[alpha, beta] __host__ __device__(double a, double b) { return alpha * a + beta * b; },
86+
stream);
87+
}
88+
4789
template <typename i_t, typename f_t>
4890
class iteration_data_t {
4991
public:
@@ -1404,12 +1446,7 @@ class iteration_data_t {
14041446

14051447
// diag.pairwise_product(x1, r1);
14061448
// r1 <- D * x_1
1407-
thrust::transform(handle_ptr->get_thrust_policy(),
1408-
d_x1.data(),
1409-
d_x1.data() + n,
1410-
d_diag_.data(),
1411-
d_r1.data(),
1412-
thrust::multiplies<f_t>());
1449+
pairwise_multiply(d_x1.data(), d_diag_.data(), d_r1.data(), n, stream_view_);
14131450

14141451
// r1 <- Q x1 + D x1
14151452
if (Q.n > 0) {
@@ -1419,12 +1456,7 @@ class iteration_data_t {
14191456

14201457
// y1 <- - alpha * r1 + beta * y1
14211458
// y1.axpy(-alpha, r1, beta);
1422-
thrust::transform(handle_ptr->get_thrust_policy(),
1423-
d_r1.data(),
1424-
d_r1.data() + n,
1425-
d_y1.data(),
1426-
d_y1.data(),
1427-
axpy_op<f_t>{-alpha, beta});
1459+
axpy(-alpha, d_r1.data(), beta, d_y1.data(), d_y1.data(), n, stream_view_);
14281460

14291461
// matrix_transpose_vector_multiply(A, alpha, x2, 1.0, y1);
14301462
cusparse_view_.transpose_spmv(alpha, d_x2, 1.0, d_y1);

cpp/src/linear_programming/pdlp.cu

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* clang-format off */
22
/*
3-
* SPDX-FileCopyrightText: Copyright (c) 2022-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
* SPDX-FileCopyrightText: Copyright (c) 2022-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66
/* clang-format on */
@@ -1511,7 +1511,7 @@ void pdlp_solver_t<i_t, f_t>::compute_initial_step_size()
15111511

15121512
const auto& cusparse_view_ = pdhg_solver_.get_cusparse_view();
15131513

1514-
int sing_iters = 0;
1514+
[[maybe_unused]] int sing_iters = 0;
15151515
for (int i = 0; i < max_iterations; ++i) {
15161516
++sing_iters;
15171517
// d_q = d_z

cpp/src/linear_programming/utilities/cython_solve.cu

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* clang-format off */
22
/*
3-
* SPDX-FileCopyrightText: Copyright (c) 2023-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
* SPDX-FileCopyrightText: Copyright (c) 2023-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66
/* clang-format on */
@@ -309,8 +309,7 @@ std::pair<std::vector<std::unique_ptr<solver_ret_t>>, double> call_batch_solve(
309309

310310
#pragma omp parallel for num_threads(max_thread)
311311
for (std::size_t i = 0; i < size; ++i)
312-
list[i] =
313-
std::move(call_solve(data_models[i], solver_settings, cudaStreamNonBlocking, is_batch_mode));
312+
list[i] = call_solve(data_models[i], solver_settings, cudaStreamNonBlocking, is_batch_mode);
314313

315314
auto end = std::chrono::high_resolution_clock::now();
316315
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start_solver);

cpp/src/linear_programming/utils.cuh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* clang-format off */
22
/*
3-
* SPDX-FileCopyrightText: Copyright (c) 2022-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
* SPDX-FileCopyrightText: Copyright (c) 2022-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66
/* clang-format on */
@@ -62,9 +62,9 @@ struct max_abs_value {
6262
template <typename i_t>
6363
i_t conditional_major(uint64_t total_pdlp_iterations)
6464
{
65-
uint64_t step = 10;
66-
uint64_t threshold = 1000;
67-
uint64_t iteration = 0;
65+
uint64_t step = 10;
66+
uint64_t threshold = 1000;
67+
[[maybe_unused]] uint64_t iteration = 0;
6868

6969
[[maybe_unused]] constexpr uint64_t max_u64 = std::numeric_limits<uint64_t>::max();
7070

cpp/src/mip/diversity/lns/rins.cu

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,8 @@ void rins_t<i_t, f_t>::run_rins()
262262
branch_and_bound_settings.num_diving_threads = 1;
263263
branch_and_bound_settings.log.log = false;
264264
branch_and_bound_settings.log.log_prefix = "[RINS] ";
265-
branch_and_bound_settings.solution_callback = [this, &rins_solution_queue](
266-
std::vector<f_t>& solution, f_t objective) {
265+
branch_and_bound_settings.solution_callback = [&rins_solution_queue](std::vector<f_t>& solution,
266+
f_t objective) {
267267
rins_solution_queue.push_back(solution);
268268
};
269269
dual_simplex::branch_and_bound_t<i_t, f_t> branch_and_bound(branch_and_bound_problem,

0 commit comments

Comments
 (0)