distributed: NCCL tensor-parallel primitives (TpContext + AllReduce)
New xserv-distributed crate: hand-written NCCL FFI, TpContext (one rank per thread, bound to one GPU), and in-place BF16 AllReduce on the null stream so it orders naturally with the model's kernels. 2-GPU AllReduce test included. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
50
crates/xserv-distributed/tests/allreduce.rs
Normal file
50
crates/xserv-distributed/tests/allreduce.rs
Normal file
@@ -0,0 +1,50 @@
|
||||
//! 2-GPU AllReduce smoke test. Skips if fewer than 2 GPUs are present.
|
||||
|
||||
use half::bf16;
|
||||
use std::thread;
|
||||
use xserv_cuda::{device, GpuBuffer};
|
||||
use xserv_distributed::{get_unique_id, TpContext};
|
||||
|
||||
#[test]
|
||||
fn allreduce_two_gpu_sum() {
|
||||
let world = 2usize;
|
||||
if device::device_count().unwrap_or(0) < world as i32 {
|
||||
eprintln!("skip: need >= {world} GPUs");
|
||||
return;
|
||||
}
|
||||
|
||||
let id = get_unique_id();
|
||||
let n = 4096usize;
|
||||
|
||||
let handles: Vec<_> = (0..world)
|
||||
.map(|rank| {
|
||||
let id = id;
|
||||
thread::spawn(move || {
|
||||
let ctx = TpContext::init(rank, world, id, rank as u32);
|
||||
|
||||
// Rank r fills its buffer with (r + 1).
|
||||
let val = bf16::from_f32((rank + 1) as f32);
|
||||
let host = vec![val; n];
|
||||
let src = unsafe {
|
||||
std::slice::from_raw_parts(host.as_ptr() as *const u8, n * 2)
|
||||
};
|
||||
let mut buf = GpuBuffer::alloc(n * 2).unwrap();
|
||||
buf.copy_from_host(src).unwrap();
|
||||
|
||||
ctx.all_reduce_sum_bf16(&mut buf, n);
|
||||
|
||||
let mut out = vec![0u8; n * 2];
|
||||
buf.copy_to_host(&mut out).unwrap();
|
||||
let res = unsafe { std::slice::from_raw_parts(out.as_ptr() as *const bf16, n) };
|
||||
(res[0].to_f32(), res[n - 1].to_f32())
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
// sum over ranks of (r+1) = 1 + 2 = 3
|
||||
for h in handles {
|
||||
let (first, last) = h.join().unwrap();
|
||||
assert_eq!(first, 3.0, "AllReduce(sum) first element");
|
||||
assert_eq!(last, 3.0, "AllReduce(sum) last element");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user