Skip to content
Merged
Show file tree
Hide file tree
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
54 changes: 54 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,60 @@ jobs:
pixi r pytest
rm -rf build/

build_gpu:
# Build-only: linking against cuBLAS/cuSPARSE needs the CUDA toolkit but
# not a physical GPU, so this validates the use_gpu build/link path without
# running the solver (running would require GPU hardware).
runs-on: ubuntu-latest
defaults:
run:
shell: bash -l {0}
strategy:
fail-fast: false
matrix:
python-version: [ "3.12" ]

steps:
- uses: actions/checkout@v7
with:
submodules: recursive
- uses: prefix-dev/setup-pixi@v0.10.0
with:
cache: false
pixi-version: v0.46.0
- name: Add .pixi/envs/default to the $PATH
run: echo "$(pwd)/.pixi/envs/default/bin" >> $GITHUB_PATH
shell: bash
- name: Install dependencies
run: |
pixi add --platform linux-64 scipy numpy pip pytest meson meson-python \
openblas python==${{ matrix.python-version }} \
cuda-version=12.* cuda-nvcc cuda-cudart-dev libcublas-dev libcusparse-dev
- name: Build (use_gpu=true)
run: |
export CUDA_PATH="$(pwd)/.pixi/envs/default"
export CUDA_HOME="$CUDA_PATH"
pixi r python -m pip install -v . --no-build-isolation \
-Csetup-args=-Duse_gpu=true -Csetup-args=-Dint32=true
- name: Check _scs_gpu is linked against cuBLAS and cuSPARSE
# A shared library links successfully even with undefined symbols, so the
# real regression test is that libcublas/libcusparse are recorded as
# NEEDED entries (the bug fixed in #221 was a missing link, seen only at
# import time as `undefined symbol: cusparseDestroySpMat`).
run: |
# Locate the installed extension in the pixi env's site-packages.
so=$(find "$(pwd)/.pixi/envs/default/lib" -name '_scs_gpu*.so' | head -1)
if [ -z "$so" ]; then
echo "ERROR: _scs_gpu*.so not found in the pixi environment"
find "$(pwd)/.pixi/envs/default/lib" -name '_scs_*.so' || true
exit 1
fi
echo "Inspecting $so"
readelf -d "$so"
readelf -d "$so" | grep -q 'libcublas' || { echo "ERROR: _scs_gpu not linked against cuBLAS"; exit 1; }
readelf -d "$so" | grep -q 'libcusparse' || { echo "ERROR: _scs_gpu not linked against cuSPARSE"; exit 1; }
echo "OK: _scs_gpu links cuBLAS and cuSPARSE"

build_native_arch:
runs-on: ubuntu-latest
defaults:
Expand Down
18 changes: 11 additions & 7 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -287,17 +287,18 @@ endif

if get_option('use_gpu')
gpu_c_args = common_c_args + ['-DPY_GPU=1', '-DINDIRECT=1']
_deps += cuda_dep
cublas_dep = cc.find_library('cublas', required: false)
if not cublas_dep.found()
cublas_dep = dependency('cublas', required: true)
endif
_deps += cublas_dep
cusparse_dep = cc.find_library('cusparse', required: false)
if not cusparse_dep.found()
cusparse_dep = dependency('cusparse', required: true)
endif
_deps += cusparse_dep
# Scope the CUDA libraries to this target rather than mutating the shared
# `_deps`, so they don't leak into _scs_mkl / _scs_accelerate / _scs_cudss
# when use_gpu is combined with those backends.
gpu_deps = _deps + [cuda_dep, cublas_dep, cusparse_dep]
if get_option('gpu_atrans')
gpu_c_args += '-DGPU_TRANSPOSE_MAT=1'
endif
Expand All @@ -310,10 +311,12 @@ if get_option('use_gpu')
# In Meson, sources with a `.cu` extension are compiled with nvcc by default.
# To compile `.c` files with nvcc, they must be explicitly targeted.
# It is strongly recommended to rename CUDA-C files to `.cu`.
# Meson's fs module has no glob(), so these are listed explicitly; keep in
# sync with the .c files under scs_source/linsys/gpu{,/indirect}.
'scs_source/linsys/gpu/gpu.c',
'scs_source/linsys/gpu/indirect/private.c',
c_args: gpu_c_args,
dependencies: _deps,
dependencies: gpu_deps,
include_directories: [
common_includes, 'scs_source/linsys/gpu/', 'scs_source/linsys/gpu/indirect'
],
Expand Down Expand Up @@ -382,9 +385,10 @@ if host_machine.system() == 'darwin'
endif

if get_option('link_cudss')
_deps += cuda_dep
cudss_dep = dependency('cudss', required: true)
_deps += cudss_dep
# Scope the CUDA libraries to this target rather than mutating the shared
# `_deps` (see the use_gpu block above).
cudss_deps = _deps + [cuda_dep, cudss_dep]
py.extension_module(
'_scs_cudss',
'scs/scspy.c',
Expand All @@ -394,7 +398,7 @@ if get_option('link_cudss')
spectral_cone_sources,
c_args: common_c_args + ['-DPY_CUDSS'],
include_directories: common_includes + ['scs_source/linsys/cudss/direct'],
dependencies: _deps,
dependencies: cudss_deps,
install_dir: scs_dir,
install: true,
)
Expand Down