- Fork cudarc locally (vendor/cudarc): add CudaContext::load_cubin() that calls cuModuleLoadData directly — zero nvrtc dependency - Remove "nvrtc" feature from ml-core, ml-dqn, ml-ppo Cargo.toml - Replace all 89 Ptx::from_binary + load_module calls with load_cubin - ml-core cuda_autograd: wire 9 stub constructors to precompiled cubins (activation, elementwise, linear, loss, reduction, dropout, layer_norm, optimizer) - ml-core build.rs: compile 8 BF16-native CUDA kernels via nvcc - cubin_loader.rs: thin wrapper around CudaContext::load_cubin() - Fix size_of::<f32> in gpu_tensor.rs, stream_ops.rs, layer_norm.rs - Fix test data: Vec<f32> → Vec<half::bf16> for memcpy_htod - Stub ml-ppo/ml-dqn runtime compile_ptx calls (dead code) - backtest_metrics_kernel.cu: full native BF16 rewrite (no float) - backtest_env_kernel.cu: shared memory → __nv_bfloat16 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
72 lines
2.0 KiB
Rust
72 lines
2.0 KiB
Rust
use cudarc::{
|
|
driver::{CudaContext, DriverError},
|
|
nvrtc::Ptx,
|
|
};
|
|
|
|
fn main() -> Result<(), DriverError> {
|
|
let ctx = CudaContext::new(0)?;
|
|
|
|
println!("Device: {}", ctx.name()?);
|
|
println!();
|
|
|
|
// Load the module with the sin_kernel
|
|
let module = ctx.load_module(Ptx::from_file("./examples/sin.ptx"))?;
|
|
let sin_kernel = module.load_function("sin_kernel")?;
|
|
|
|
// Query function attributes
|
|
println!("=== Function Attributes for 'sin_kernel' ===");
|
|
println!();
|
|
|
|
println!("Resource Usage:");
|
|
println!(" Registers per thread: {}", sin_kernel.num_regs()?);
|
|
println!(
|
|
" Static shared memory: {} bytes",
|
|
sin_kernel.shared_size_bytes()?
|
|
);
|
|
println!(
|
|
" Constant memory: {} bytes",
|
|
sin_kernel.const_size_bytes()?
|
|
);
|
|
println!(
|
|
" Local memory per thread: {} bytes",
|
|
sin_kernel.local_size_bytes()?
|
|
);
|
|
println!();
|
|
|
|
println!("Limits:");
|
|
println!(
|
|
" Max threads per block: {}",
|
|
sin_kernel.max_threads_per_block()?
|
|
);
|
|
println!();
|
|
|
|
println!("Compilation Info:");
|
|
let ptx_ver = sin_kernel.ptx_version()?;
|
|
let bin_ver = sin_kernel.binary_version()?;
|
|
println!(
|
|
" PTX version: {}.{}",
|
|
ptx_ver / 10,
|
|
ptx_ver % 10
|
|
);
|
|
println!(
|
|
" Binary version: {}.{}",
|
|
bin_ver / 10,
|
|
bin_ver % 10
|
|
);
|
|
println!();
|
|
|
|
// Use occupancy API to get optimal launch configuration
|
|
extern "C" fn no_dynamic_smem(_block_size: std::ffi::c_int) -> usize {
|
|
0
|
|
}
|
|
let (min_grid_size, block_size) =
|
|
sin_kernel.occupancy_max_potential_block_size(no_dynamic_smem, 0, 0, None)?;
|
|
|
|
println!("=== Optimal Launch Configuration (sin_kernel) ===");
|
|
println!(" Suggested block size: {}", block_size);
|
|
println!(" Min grid size: {}", min_grid_size);
|
|
println!(" Total threads per grid: {}", min_grid_size * block_size);
|
|
|
|
Ok(())
|
|
}
|