Skip to content

Drop CUDA::cuda_driver link so mbpt.exe launches on CPU-only nodes - #18

Merged
egull merged 2 commits into
mainfrom
fix/drop-cuda-driver-cpu-nodes
Jul 21, 2026
Merged

Drop CUDA::cuda_driver link so mbpt.exe launches on CPU-only nodes#18
egull merged 2 commits into
mainfrom
fix/drop-cuda-driver-cpu-nodes

Conversation

@gauravharsha

Copy link
Copy Markdown
Contributor

Problem

When green-mbpt's mbpt.exe is built with green-gpu as a CUSTOM_KERNEL, the resulting binary fails to even launch on CPU-only nodes with:

libcuda.so.1: cannot open shared object file: No such file or directory

This happens even for pure-CPU runs that never touch the GPU, which prevents shipping a single binary usable on both CPU-only and GPU nodes.

Root cause

src/CMakeLists.txt links CUDA::cuda_driver (i.e. libcuda.so.1, the NVIDIA driver library, which only exists on nodes with the GPU driver installed). But green-gpu makes no CUDA driver API calls — the only cu* symbols anywhere in the source are the inline cuComplex.h helpers (cuCadd/cuCmul/cuCreal/…), which come from a header, not from libcuda. Everything else is CUDA runtime API + cuBLAS + cuSolver.

Because accel-lib/gpu are static libraries absorbed into mbpt.exe, that spurious link put a hard DT_NEEDED on libcuda.so.1 into the final executable, so the dynamic loader demanded the driver at startup.

Fix

Remove CUDA::cuda_driver from both link lines. The shared CUDA runtime loads the driver lazily on the first CUDA call, so the binary starts on CPU-only nodes and only needs the driver if GPU code actually runs.

Verification

readelf -d ./mbpt.exe | grep -i libcuda.so.1   # now empty

Confirmed by the reporter that a CUDA-enabled mbpt.exe built against this change launches on CPU-only nodes.

Note: if future code adds real driver-API calls (cuInit/cuCtxCreate/cuLaunchKernel/…), the link should be restored — or better, the kernel loaded as a dlopen plugin — rather than reintroducing a hard startup dependency.

🤖 Generated with Claude Code

gauravharsha and others added 2 commits July 20, 2026 16:34
green-gpu makes no CUDA driver API calls: the only cu* symbols in the
source are the inline cuComplex.h helpers (cuCadd/cuCmul/cuCreal/...),
which come from a header, not libcuda. Everything else uses the CUDA
runtime API, cuBLAS, and cuSolver.

Linking CUDA::cuda_driver (libcuda.so.1) therefore added a spurious hard
DT_NEEDED on the NVIDIA driver library. Since accel-lib/gpu are static and
get absorbed into mbpt.exe when green-gpu is used as a CUSTOM_KERNEL, the
resulting mbpt.exe failed to even launch on CPU-only nodes with
"libcuda.so.1: cannot open shared object file" -- including for pure CPU
runs that never touch the GPU.

Dropping the link removes the startup dependency; the shared CUDA runtime
loads the driver lazily on the first CUDA call, so one binary starts on
both CPU-only and GPU nodes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The only remaining CUDA driver-API call was cuDeviceGetAttribute with
CU_DEVICE_ATTRIBUTE_MEMORY_CLOCK_RATE (added for CUDA 13 compatibility
after cudaDeviceProp::memoryClockRate was removed). That single call is
what forced accel-lib/gpu to link libcuda, defeating the point of dropping
CUDA::cuda_driver.

NVIDIA's documented CUDA 13 replacement for the removed memoryClockRate
field is the runtime API cudaDeviceGetAttribute(cudaDevAttrMemoryClockRate),
which returns the same kHz value, is available across CUDA versions, and
links only against libcudart. Switch to it so no driver-API symbols remain
and the binary needs no libcuda at startup.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gauravharsha

Copy link
Copy Markdown
Contributor Author

Good catch on cuDeviceGetAttribute — that driver-API call (added in 2a4bc34 for CUDA 13, after cudaDeviceProp::memoryClockRate was removed) was the one remaining thing forcing a libcuda link, which would have defeated this PR.

Fixed in 27b64b3 by switching to the runtime-API equivalent cudaDeviceGetAttribute(&memClockKHz, cudaDevAttrMemoryClockRate, i). This is NVIDIA's documented CUDA 13 replacement for the removed memoryClockRate field (see the cuda-samples CHANGELOG), returns the same kHz value, is available across CUDA versions, and links only against libcudart. No driver-API symbols remain, so mbpt.exe needs no libcuda at startup.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.71%. Comparing base (23c530c) to head (27b64b3).

Additional details and impacted files
@@           Coverage Diff           @@
##             main      #18   +/-   ##
=======================================
  Coverage   96.71%   96.71%           
=======================================
  Files          13       13           
  Lines         852      852           
=======================================
  Hits          824      824           
  Misses         28       28           
Flag Coverage Δ
unittests 96.71% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes an unnecessary hard link dependency on the CUDA driver library (libcuda.so.1) so CUDA-enabled binaries that embed green-gpu can still launch on CPU-only nodes (and only require the NVIDIA driver if GPU code actually executes).

Changes:

  • Drop CUDA::cuda_driver from accel-lib and gpu link lines to avoid a DT_NEEDED entry for libcuda.so.1 at program start.
  • Replace the one CUDA driver API usage (cuDeviceGetAttribute) with the CUDA runtime API equivalent (cudaDeviceGetAttribute) in device-info printing code.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/cuda_check.cpp Removes the lone CUDA driver API call by switching to the runtime attribute query API.
src/CMakeLists.txt Removes CUDA::cuda_driver from library linkage to prevent startup-time dependency on libcuda.so.1.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@egull egull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good and is actually quite a useful convenience feature. I'm approving and merging.

@egull
egull merged commit 52df6a1 into main Jul 21, 2026
2 checks passed
@egull
egull deleted the fix/drop-cuda-driver-cpu-nodes branch July 21, 2026 07:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants