Skip to content

Commit 9f241a1

Browse files
authored
Barrier method for LPs with cuDSS sparse Cholesky / LDLT on the GPU (#272)
This PR adds a barrier (interior-point) method for solving linear programs. cuDSS is used to GPU-accelerate the sparse Cholesky and sparse LDLT solves, cuSparse is used to GPU-accelerate spMv and spMM. This PR also includes routines for the color refinement algorithm (generalized to weighted graphs) and folding a linear program. Crossover is also updated to use hypersparse solves. Barrier is enabled by default (along with PDLP and dual simplex) in concurrent mode. You may also use barrier by itself. The following new settings are supported: * `--method=3` to invoke the new barrier solver * `--folding` to control whether to fold the LP: (-1) automatic, (0) folding off, (1) folding in * `--dualize` to control whether to dualize the LP in presolve: (-1) automatic, (0) don't dualize, (1) force dualize * `--ordering` to control whether the ordering for cuDSS: (-1) automatic, (0) cuDSS default (1) AMD * `--augmented` to control what linear system to solve: (-1) automatic, (0) solve ADAT, (1) solve the augmented system * `--eliminate-dense-columns`, true to eliminate dense columns, false to not * `--cudss-deterministic`, true to use cuDSS deterministic mode, false to use nondeterministic mode Closes #204 Authors: - Chris Maes (https://github.com/chris-maes) - Nicolas Blin (https://github.com/Kh4ster) - Hugo Linsenmaier (https://github.com/hlinsen) - Ramakrishnap (https://github.com/rgsl888prabhu) - Ishika Roy (https://github.com/Iroy30) - Rajesh Gandham (https://github.com/rg20) Approvers: - Trevor McKay (https://github.com/tmckayus) - Hugo Linsenmaier (https://github.com/hlinsen) - Bradley Dice (https://github.com/bdice) URL: #272
1 parent 1e208da commit 9f241a1

File tree

81 files changed

+10324
-375
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+10324
-375
lines changed

benchmarks/linear_programming/cuopt/run_pdlp.cu

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,10 @@ static void parse_arguments(argparse::ArgumentParser& program)
6363
program.add_argument("--method")
6464
.help(
6565
"Method to solve the linear programming problem. 0: Concurrent (default), 1: PDLP, 2: "
66-
"DualSimplex")
66+
"DualSimplex, 3: Barrier")
6767
.default_value(0)
6868
.scan<'i', int>()
69-
.choices(0, 1, 2);
69+
.choices(0, 1, 2, 3);
7070

7171
program.add_argument("--crossover")
7272
.help("Enable crossover. 0: disabled (default), 1: enabled")
@@ -79,6 +79,12 @@ static void parse_arguments(argparse::ArgumentParser& program)
7979
"Path to PDLP hyper-params file to configure PDLP solver. Has priority over PDLP solver "
8080
"modes.");
8181

82+
program.add_argument("--presolve")
83+
.help("enable/disable presolve (default: true for MIP problems, false for LP problems)")
84+
.default_value(0)
85+
.scan<'i', int>()
86+
.choices(0, 1);
87+
8288
program.add_argument("--solution-path").help("Path where solution file will be generated");
8389
}
8490

@@ -109,6 +115,7 @@ static cuopt::linear_programming::pdlp_solver_settings_t<int, double> create_sol
109115
string_to_pdlp_solver_mode(program.get<std::string>("--pdlp-solver-mode"));
110116
settings.method = static_cast<cuopt::linear_programming::method_t>(program.get<int>("--method"));
111117
settings.crossover = program.get<int>("--crossover");
118+
settings.presolve = program.get<int>("--presolve");
112119

113120
return settings;
114121
}

ci/build_wheel_cuopt.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ set -euo pipefail
2020

2121
source rapids-init-pip
2222

23+
# Install rockylinux repo
24+
if command -v dnf &> /dev/null; then
25+
bash ci/utils/update_rockylinux_repo.sh
26+
fi
27+
28+
# Install cudss
29+
bash ci/utils/install_cudss.sh
30+
2331
package_dir="python/cuopt"
2432
export SKBUILD_CMAKE_ARGS="-DCUOPT_BUILD_WHEELS=ON;-DDISABLE_DEPRECATION_WARNINGS=ON";
2533

@@ -41,6 +49,8 @@ EXCLUDE_ARGS=(
4149
--exclude "libraft.so"
4250
--exclude "libcublas.so.*"
4351
--exclude "libcublasLt.so.*"
52+
--exclude "libcuda.so.1"
53+
--exclude "libcudss.so.*"
4454
--exclude "libcurand.so.*"
4555
--exclude "libcusolver.so.*"
4656
--exclude "libcusparse.so.*"

ci/build_wheel_libcuopt.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ source rapids-init-pip
2121
package_name="libcuopt"
2222
package_dir="python/libcuopt"
2323

24+
# Install rockylinux repo
25+
if command -v dnf &> /dev/null; then
26+
bash ci/utils/update_rockylinux_repo.sh
27+
fi
28+
2429
# Install Boost and TBB
2530
bash ci/utils/install_boost_tbb.sh
2631

@@ -34,6 +39,9 @@ else
3439
echo "Building in release mode"
3540
fi
3641

42+
# Install cudss
43+
bash ci/utils/install_cudss.sh
44+
3745
rapids-logger "Generating build requirements"
3846

3947
CUOPT_MPS_PARSER_WHEELHOUSE=$(RAPIDS_PY_WHEEL_NAME="cuopt_mps_parser" rapids-download-wheels-from-github python)
@@ -62,6 +70,8 @@ EXCLUDE_ARGS=(
6270
--exclude "libraft.so"
6371
--exclude "libcublas.so.*"
6472
--exclude "libcublasLt.so.*"
73+
--exclude "libcuda.so.1"
74+
--exclude "libcudss.so.*"
6575
--exclude "libcurand.so.*"
6676
--exclude "libcusolver.so.*"
6777
--exclude "libcusparse.so.*"

ci/utils/install_boost_tbb.sh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ if [ -f /etc/os-release ]; then
2222
. /etc/os-release
2323
if [[ "$ID" == "rocky" ]]; then
2424
echo "Detected Rocky Linux. Installing Boost and TBB via dnf..."
25-
dnf clean all
26-
dnf -y update
2725
dnf install -y epel-release
2826
dnf install -y boost1.78-devel tbb-devel
2927
if [[ "$(uname -m)" == "x86_64" ]]; then

ci/utils/install_cudss.sh

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/bin/bash
2+
3+
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
18+
set -euo pipefail
19+
20+
# Clean metadata & install cudss
21+
if command -v dnf &> /dev/null; then
22+
# Adding static library just to please CMAKE requirements
23+
if [ "$(echo "$CUDA_VERSION" | cut -d. -f1)" -ge 13 ] && [ "$(echo "$CUDA_VERSION" | cut -d. -f1)" -lt 14 ]; then
24+
dnf -y install libcudss0-static-cuda-13 libcudss0-devel-cuda-13 libcudss0-cuda-13
25+
else
26+
dnf -y install libcudss0-static-cuda-12 libcudss0-devel-cuda-12 libcudss0-cuda-12
27+
fi
28+
elif command -v apt-get &> /dev/null; then
29+
apt-get update
30+
apt-get install -y libcudss-devel
31+
else
32+
echo "Neither dnf nor apt-get found. Cannot install cudss dependencies."
33+
exit 1
34+
fi

ci/utils/update_rockylinux_repo.sh

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#!/bin/bash
2+
3+
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
18+
set -euo pipefail
19+
20+
REPO_DIR="/etc/yum.repos.d"
21+
22+
# Disable all existing Rocky repos to prevent mirror issues
23+
for repo_file in ${REPO_DIR}/Rocky-*.repo; do
24+
if [ -f "$repo_file" ]; then
25+
sed -i 's/^enabled=1/enabled=0/g' "$repo_file"
26+
fi
27+
done
28+
29+
# Overwrite the main Rocky repos with stable URLs
30+
# Using ONLY direct dl.rockylinux.org URLs (no mirrorlist) to avoid mirror sync issues
31+
# This prevents DNF from trying unreliable/out-of-sync mirrors
32+
cat <<'EOF' > ${REPO_DIR}/Rocky-BaseOS.repo
33+
[baseos]
34+
name=Rocky Linux 8.10 - BaseOS
35+
baseurl=https://dl.rockylinux.org/pub/rocky/8.10/BaseOS/$basearch/os/
36+
enabled=1
37+
gpgcheck=1
38+
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial
39+
retries=10
40+
timeout=30
41+
skip_if_unavailable=False
42+
metadata_expire=1h
43+
EOF
44+
45+
cat <<'EOF' > ${REPO_DIR}/Rocky-AppStream.repo
46+
[appstream]
47+
name=Rocky Linux 8.10 - AppStream
48+
baseurl=https://dl.rockylinux.org/pub/rocky/8.10/AppStream/$basearch/os/
49+
enabled=1
50+
gpgcheck=1
51+
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial
52+
retries=10
53+
timeout=30
54+
skip_if_unavailable=False
55+
metadata_expire=1h
56+
EOF
57+
58+
cat <<'EOF' > ${REPO_DIR}/Rocky-Extras.repo
59+
[extras]
60+
name=Rocky Linux 8.10 - Extras
61+
baseurl=https://dl.rockylinux.org/pub/rocky/8.10/extras/$basearch/os/
62+
enabled=1
63+
gpgcheck=1
64+
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial
65+
retries=10
66+
timeout=30
67+
skip_if_unavailable=False
68+
metadata_expire=1h
69+
EOF
70+
71+
# Clean DNF cache and refresh repository metadata with retry logic
72+
dnf clean all
73+
74+
max_attempts=3
75+
attempt=1
76+
while [ $attempt -le $max_attempts ]; do
77+
if dnf makecache --refresh; then
78+
break
79+
else
80+
if [ $attempt -lt $max_attempts ]; then
81+
sleep $((2 ** attempt))
82+
else
83+
echo "ERROR: Failed to refresh repository metadata after $max_attempts attempts"
84+
exit 1
85+
fi
86+
fi
87+
attempt=$((attempt + 1))
88+
done

conda/environments/all_cuda-129_arch-aarch64.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ dependencies:
3232
- gtest
3333
- ipython
3434
- jsonref==1.1.0
35+
- libcudss-dev >=0.7
3536
- libcurand-dev
3637
- libcusolver-dev
3738
- libcusparse-dev

conda/environments/all_cuda-129_arch-x86_64.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ dependencies:
3232
- gtest
3333
- ipython
3434
- jsonref==1.1.0
35+
- libcudss-dev >=0.7
3536
- libcurand-dev
3637
- libcusolver-dev
3738
- libcusparse-dev

conda/environments/all_cuda-130_arch-aarch64.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ dependencies:
3232
- gtest
3333
- ipython
3434
- jsonref==1.1.0
35+
- libcudss-dev >=0.7
3536
- libcurand-dev
3637
- libcusolver-dev
3738
- libcusparse-dev

conda/environments/all_cuda-130_arch-x86_64.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ dependencies:
3232
- gtest
3333
- ipython
3434
- jsonref==1.1.0
35+
- libcudss-dev >=0.7
3536
- libcurand-dev
3637
- libcusolver-dev
3738
- libcusparse-dev

0 commit comments

Comments
 (0)