Files
rustytorch/crates/training/rtx-compress/build.rs
T
osobhandClaude Fable 5 1e3c604896 feat(meta,jepa): expose GPU features through meta-crates; wire JEPA cluster plan and real shard loading
Meta-crates (Phase 2):
- rtx-core / rtx-training / rtx-inference-stack gain cuda and metal
  features threading into their sub-crates; GPU was previously
  unreachable through the user-facing bundles.
- rtx-training restores rtx-distributed (the hpc-channels blocker is
  gone) so the advertised DistributedTransformerTrainer resolves; drops
  the unused rtx-runtime dep.
- rtx-transformers drops unused rtx-backend/rtx-backend-cpu deps
  (stale comment referenced a teacher that never used them).

Never-compiled CUDA paths fixed (surfaced by the new feature wiring,
verified on RTX 5060 Ti / CUDA 13.1):
- rtx-compress build.rs: missing Path/Command/fs imports.
- rtx-flash-attention flash_decode_forward: reborrow &mut kernel args.
- rtx-transformers: rope kernel include path, cudarc 0.18 Arc<CudaModule>,
  PushKernelArg imports in jepa_gpu, edition-2024 ref patterns.
- rtx-memory: full cudarc 0.18 port (CudaContext, stream-based alloc,
  DevicePtr accessors, error enum formatting) across gpu_pinning,
  gpu_transfer, gpu_real, gpu_allocator/arena, gpu_tests.

JEPA (Phase 3):
- JepaRunConfig::apply_cluster_plan consumes ClusterTrainingPlan
  (batch size, TP/DP, world size, total steps) so jepa_cluster is no
  longer standalone dead config; ViTSizeStr::approx_params_m feeds
  JepaParallelConfig::for_model_and_cluster.
- WebDatasetShard::load reads real .tar shards from disk via the
  existing parser (gzip rejected explicitly); to_in_memory documented
  as synthetic/test-only.
- New image-decode feature actually defines the dep for the previously
  unreachable cfg(feature = "image-decode") JPEG/PNG decode path.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-09 19:25:51 -07:00

191 lines
4.8 KiB
Rust

//! Build script for RTX-Compress CUDA kernels
//!
//! Compiles MX quantization CUDA kernels to PTX for GPU acceleration.
use std::env;
#[cfg(feature = "cuda")]
use std::fs;
#[cfg(feature = "cuda")]
use std::path::Path;
#[cfg(feature = "cuda")]
use std::process::Command;
fn main() {
// Only compile CUDA kernels if CUDA feature is enabled
#[cfg(feature = "cuda")]
compile_cuda_kernels();
// Avoid unused warnings when cuda feature is not enabled
#[cfg(not(feature = "cuda"))]
{
let _ = env::var("OUT_DIR");
}
}
#[cfg(feature = "cuda")]
fn compile_cuda_kernels() {
let out_dir = env::var("OUT_DIR").unwrap();
let cuda_kernels_dir = Path::new("src/quantization/cuda_kernels");
println!("cargo:rerun-if-changed=src/quantization/cuda_kernels/mx_kernels.cu");
// Check if NVCC is available
if !is_nvcc_available() {
println!("cargo:warning=NVCC not found - MX CUDA kernels will not be compiled");
println!("cargo:warning=MX GPU quantization will fall back to CPU");
create_dummy_ptx(&out_dir);
return;
}
println!("cargo:warning=Compiling MX quantization CUDA kernels");
// Compile MX kernels
match compile_kernel(
cuda_kernels_dir.join("mx_kernels.cu"),
Path::new(&out_dir).join("mx_kernels.ptx"),
) {
Ok(_) => {
println!("cargo:warning=MX CUDA kernels compiled successfully");
}
Err(e) => {
println!("cargo:warning=Failed to compile MX CUDA kernels: {e}");
println!("cargo:warning=MX GPU quantization will fall back to CPU");
create_dummy_ptx(&out_dir);
}
}
}
#[cfg(feature = "cuda")]
fn is_nvcc_available() -> bool {
Command::new("nvcc")
.arg("--version")
.output()
.map(|output| output.status.success())
.unwrap_or(false)
}
#[cfg(feature = "cuda")]
fn compile_kernel<P: AsRef<Path>>(
cu_file: P,
ptx_file: P,
) -> Result<(), Box<dyn std::error::Error>> {
let cu_path = cu_file.as_ref();
let ptx_path = ptx_file.as_ref();
// Ensure output directory exists
if let Some(parent) = ptx_path.parent() {
fs::create_dir_all(parent)?;
}
// Compile CUDA to PTX with RTX 3050/3090 (Ampere) optimizations
let output = Command::new("nvcc")
.arg("--ptx") // Generate PTX intermediate representation
.arg("--gpu-architecture=sm_86") // RTX 3050/3090 (Ampere) compute capability
.arg("--allow-unsupported-compiler") // Allow GCC 13+ (needed for Ubuntu 24.04)
.arg("--optimize=2") // Maximum optimization
.arg("--use_fast_math") // Fast math for performance
.arg("--maxrregcount=64") // Register optimization
.arg("-o")
.arg(ptx_path) // Output PTX file
.arg(cu_path) // Input CUDA source
.output()?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
eprintln!("NVCC compilation failed:");
eprintln!("{stderr}");
return Err(format!("NVCC failed with: {stderr}").into());
}
println!(
"cargo:warning=Compiled {} -> {}",
cu_path.display(),
ptx_path.display()
);
Ok(())
}
#[cfg(feature = "cuda")]
fn create_dummy_ptx(out_dir: &str) {
// Create dummy PTX file when NVCC is not available
// This allows the crate to compile but GPU kernels won't work
let dummy_ptx = r#"
.version 7.0
.target sm_86
.address_size 64
// Dummy kernel - real implementation requires NVCC compilation
.visible .entry mx_compute_exponents_kernel(
.param .u64 input,
.param .u64 exponents,
.param .u64 numel,
.param .u32 format
) {
ret;
}
.visible .entry mx_quantize_mantissas_8bit_kernel(
.param .u64 input,
.param .u64 exponents,
.param .u64 mantissas,
.param .u64 numel,
.param .u32 format
) {
ret;
}
.visible .entry mx_quantize_mantissas_4bit_kernel(
.param .u64 input,
.param .u64 exponents,
.param .u64 mantissas,
.param .u64 numel,
.param .u32 format
) {
ret;
}
.visible .entry mx_dequantize_8bit_kernel(
.param .u64 mantissas,
.param .u64 exponents,
.param .u64 output,
.param .u64 numel,
.param .u32 format
) {
ret;
}
.visible .entry mx_dequantize_4bit_kernel(
.param .u64 mantissas,
.param .u64 exponents,
.param .u64 output,
.param .u64 numel,
.param .u32 format
) {
ret;
}
.visible .entry mx_fused_quantize_8bit_kernel(
.param .u64 input,
.param .u64 exponents,
.param .u64 mantissas,
.param .u64 numel,
.param .u32 format
) {
ret;
}
.visible .entry mx_fused_quantize_4bit_kernel(
.param .u64 input,
.param .u64 exponents,
.param .u64 mantissas,
.param .u64 numel,
.param .u32 format
) {
ret;
}
"#;
fs::write(Path::new(out_dir).join("mx_kernels.ptx"), dummy_ptx)
.expect("Failed to create dummy PTX file");
}