Files
rustytorch/build.rs
T
builderandClaude Sonnet 4.6 301f223b91 refactor(rustytorch): full clean review 2026-04-30
- fix(workspace): exclude crates/training/rtx-distributed from workspace members
  — RNCCL path deps absent in standalone checkout blocked all cargo operations
- refactor(rtx-backend-webgpu): split compute.rs (1654 lines) into compute/mod.rs
  (1040) + compute/conv.rs (628) — both within 1250-line limit
- fix(rtx-bench): add missing src/bin/main.rs declared in [[bin]] Cargo.toml entry
- fix(gitignore): narrow `bin/` exclusion to /bin/ only; add !**/src/bin/ exception
  to allow Rust source binary directories
- style(rtx-eval): 67x "literal".to_string() → "literal".to_owned() in automation,
  validation, metrics, lib, core, error modules and build.rs

All tests pass (64 tests across rtx-eval + rtx-backend-webgpu, 0 failures).
Clippy clean (-D warnings) on all changed crates.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-30 08:27:50 -07:00

123 lines
4.3 KiB
Rust

//! Build script for RustyTorch++
//! Configures GPU compilation and links with rustg
use std::env;
use std::path::PathBuf;
use std::process::Command;
fn main() {
println!("cargo:rerun-if-changed=build.rs");
// Check for CUDA installation
check_cuda();
// Set up rustg paths
setup_rustg_paths();
// Configure GPU architecture
// Default to sm_86 (Ampere - RTX 30xx series) which is widely compatible
// Use GPU_ARCH env var to override for specific hardware:
// sm_75 = Turing (RTX 20xx)
// sm_80 = Ampere (A100)
// sm_86 = Ampere (RTX 30xx, RTX A-series)
// sm_89 = Ada Lovelace (RTX 40xx)
// sm_90 = Hopper (H100)
// sm_100/sm_120 = Blackwell (RTX 50xx) - requires CUDA 13+
let gpu_arch = env::var("GPU_ARCH").unwrap_or_else(|_| detect_gpu_arch());
println!("cargo:rustc-env=GPU_ARCH={}", gpu_arch);
// Set kernel cache directory
let kernel_cache = PathBuf::from("target/kernel_cache");
std::fs::create_dir_all(&kernel_cache).expect("Failed to create kernel cache directory");
println!("cargo:rustc-env=KERNEL_CACHE_DIR={}", kernel_cache.display());
}
fn check_cuda() {
// Source shell config and check nvcc
let output = Command::new("sh")
.arg("-c")
.arg("source ~/.zshrc 2>/dev/null || source ~/.bashrc 2>/dev/null; which nvcc")
.output();
if let Ok(output) = output {
if output.status.success() {
let nvcc_path = String::from_utf8_lossy(&output.stdout);
println!("cargo:warning=Found NVCC at: {}", nvcc_path.trim());
// Check CUDA version
let version_output = Command::new("nvcc")
.arg("--version")
.output();
if let Ok(version) = version_output {
let version_str = String::from_utf8_lossy(&version.stdout);
if version_str.contains("release 13.0") {
println!("cargo:warning=CUDA 13.0 detected - RTX 5090 support enabled");
}
}
}
} else {
println!("cargo:warning=NVCC not found - GPU compilation may be limited");
}
}
fn setup_rustg_paths() {
// Set up paths to rustg components
let rustg_path = PathBuf::from("../rust/rustg");
if rustg_path.exists() {
println!("cargo:rustc-env=RUSTG_PATH={}", rustg_path.display());
// Add cargo-g to PATH if available
let cargo_g_path = rustg_path.join("cargo-g");
if cargo_g_path.exists() {
println!("cargo:rustc-env=CARGO_G_PATH={}", cargo_g_path.display());
}
// Add gpu-dev-tools to PATH if available
let gpu_tools_path = rustg_path.join("gpu-dev-tools");
if gpu_tools_path.exists() {
println!("cargo:rustc-env=GPU_DEV_TOOLS_PATH={}", gpu_tools_path.display());
}
} else {
println!("cargo:warning=rustg not found at expected path - using fallback compilation");
}
}
/// Auto-detect GPU architecture from nvidia-smi
fn detect_gpu_arch() -> String {
// Try to detect GPU compute capability using nvidia-smi
let output = Command::new("nvidia-smi")
.args(["--query-gpu=compute_cap", "--format=csv,noheader"])
.output();
if let Ok(output) = output {
if output.status.success() {
let compute_cap = String::from_utf8_lossy(&output.stdout);
let compute_cap = compute_cap.trim();
// Convert compute capability (e.g., "8.6") to sm arch (e.g., "sm_86")
if let Some(arch) = compute_cap_to_sm(compute_cap) {
println!("cargo:warning=Auto-detected GPU architecture: {} (compute {})", arch, compute_cap);
return arch;
}
}
}
// Fallback to sm_86 (RTX 30xx series) - widely compatible
println!("cargo:warning=Could not detect GPU, defaulting to sm_86 (Ampere)");
"sm_86".to_owned()
}
/// Convert compute capability string to sm_XX format
fn compute_cap_to_sm(compute_cap: &str) -> Option<String> {
// Parse "X.Y" format
let parts: Vec<&str> = compute_cap.split('.').collect();
if parts.len() == 2 {
if let (Ok(major), Ok(minor)) = (parts[0].parse::<u32>(), parts[1].parse::<u32>()) {
return Some(format!("sm_{}{}", major, minor));
}
}
None
}