Add AMD OpenCL kernel, runtime-loaded CUDA, mixed backend, portability

AMD GPU backend:
- Add the GCN-tuned equihash192_7.cl kernel (clearCounter/blake/round1..7/
  combine pipeline) and its host driver src/gpu_amd.rs. GpuSolver now dispatches
  AMD-vendor OpenCL devices to it and other devices to the existing kernel
  (force with ZCL_OPENCL_KERNEL=amd|legacy). Validated on an RX 9060 XT: GPU
  solutions match the CPU reference 1/1.
- Expose BatchHasher::midstate() for the kernel's ulong8 hashState arg.

Runtime-loaded GPU drivers (minimum host deps):
- dlopen libcuda / libnvidia-ml via libloading instead of linking them
  (src/dylib.rs macro; cuda.rs, nvml.rs, gpu_probe.rs). The binary now builds
  and starts on hosts without an NVIDIA driver and reports no CUDA devices
  gracefully; remove build.rs (its only job was linking those libs).
- Add Dockerfile.portable + build-portable.sh: build against Debian bullseye's
  glibc 2.31 for a binary that runs on older distros and drives both AMD
  (OpenCL) and NVIDIA (CUDA) cards. Document the build matrix in the README.

Mixed backend (default):
- Add --backend mixed (now the default): each card on its native backend
  (NVIDIA->CUDA, AMD/Intel->OpenCL), deduped so no card is mined twice.
  --devices indexes the unified list shown by --list-devices.

Misc:
- Stale-work timeout (--job-timeout) default 300s -> 600s (10 minutes).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
jackpotincorporated
2026-06-06 01:15:41 -04:00
parent f3ca6a1ee4
commit 4b5f84959c
18 changed files with 2949 additions and 109 deletions
-53
View File
@@ -1,53 +0,0 @@
//! Build script for the CUDA backend.
//!
//! The `cuda` feature links the CUDA driver API (`cuda`) and NVML (for
//! clock/power control + readout). The backend drives miniZ's embedded fatbin
//! (`src/miniz/equihash192_7.fatbin`) via the driver API, so no nvcc / kernel
//! compilation is needed at build time. (The default OpenCL backend needs no
//! build-script support — `ocl` links `OpenCL` itself, cross-platform.)
//!
//! Linking is target-aware so the `cuda` feature builds on both Linux and
//! Windows:
//! - Linux: `libcuda.so` + `libnvidia-ml.so` from the system / toolkit dirs.
//! - Windows: `cuda.lib` + `nvml.lib` from `%CUDA_PATH%\lib\x64`.
use std::path::Path;
fn main() {
println!("cargo:rerun-if-changed=build.rs");
if std::env::var("CARGO_FEATURE_CUDA").is_ok() {
// Use the *target* OS (correct for cross-compilation too), not the host.
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();
link_cuda_driver(&target_os);
}
}
/// Link the CUDA driver library plus NVML. The backend loads the embedded miniZ
/// fatbin at runtime, so there is nothing to compile here.
fn link_cuda_driver(target_os: &str) {
if target_os == "windows" {
// CUDA Toolkit import libraries (cuda.lib, nvml.lib).
println!("cargo:rerun-if-env-changed=CUDA_PATH");
if let Ok(cuda_path) = std::env::var("CUDA_PATH") {
println!("cargo:rustc-link-search=native={cuda_path}\\lib\\x64");
}
// Driver API import lib is `cuda.lib`; NVML is `nvml.lib` (nvml.dll
// ships with the NVIDIA driver).
println!("cargo:rustc-link-lib=dylib=cuda");
println!("cargo:rustc-link-lib=dylib=nvml");
} else {
for dir in ["/usr/lib64", "/usr/lib", "/opt/cuda/lib64"] {
if Path::new(dir).exists() {
println!("cargo:rustc-link-search=native={dir}");
}
}
// GNU ld: embed an rpath so libcuda is found at runtime (Linux only —
// MSVC's linker rejects `-Wl,...`).
if target_os == "linux" {
println!("cargo:rustc-link-arg=-Wl,-rpath,/opt/cuda/lib64");
}
println!("cargo:rustc-link-lib=dylib=cuda");
println!("cargo:rustc-link-lib=dylib=nvidia-ml");
}
}