transport_bench/
transport_bench.rs1use rlx_distributed::{NetTransport, ProcessGroup, ReduceKind};
23use std::net::{Ipv4Addr, SocketAddr, TcpListener};
24use std::sync::Arc;
25use std::thread;
26use std::time::Instant;
27
28fn main() {
29 let world = 2u32;
30 let listeners: Vec<TcpListener> = (0..world)
31 .map(|_| TcpListener::bind((Ipv4Addr::LOCALHOST, 0)).unwrap())
32 .collect();
33 let addrs: Vec<SocketAddr> = listeners.iter().map(|l| l.local_addr().unwrap()).collect();
34
35 println!("transport: loopback TCP, world_size = {world}");
36 let handles: Vec<_> = listeners
37 .into_iter()
38 .enumerate()
39 .map(|(rank, listener)| {
40 let addrs = addrs.clone();
41 thread::spawn(move || {
42 let t = NetTransport::from_listener(rank as u32, world, listener, addrs, 64 << 20)
43 .unwrap();
44 bench(&ProcessGroup::new(Arc::new(t)));
45 })
46 })
47 .collect();
48 for h in handles {
49 h.join().unwrap();
50 }
51}
52
53fn bench(g: &ProcessGroup) {
54 let rank = g.rank();
55 g.barrier().unwrap();
56
57 let iters = 5000;
59 if rank == 0 {
60 let p = [1.0f32];
61 for _ in 0..200 {
62 g.send_f32(1, 0, &p).unwrap();
63 g.recv_f32(1, 0).unwrap();
64 }
65 let t0 = Instant::now();
66 for _ in 0..iters {
67 g.send_f32(1, 0, &p).unwrap();
68 g.recv_f32(1, 0).unwrap();
69 }
70 let us = t0.elapsed().as_secs_f64() * 1e6 / iters as f64;
71 println!(
72 "[latency] ping-pong: {us:6.2} µs RTT ({:.2} µs one-way) [{iters} iters]",
73 us / 2.0
74 );
75 } else {
76 for _ in 0..(200 + iters) {
77 let x = g.recv_f32(0, 0).unwrap();
78 g.send_f32(0, 0, &x).unwrap();
79 }
80 }
81 g.barrier().unwrap();
82
83 for &elems in &[256usize, 16_384, 262_144, 4_194_304] {
85 let bytes = elems * 4;
86 let reps = (512 * 1024 * 1024 / bytes).clamp(8, 200_000);
87 if rank == 0 {
88 let buf = vec![0.5f32; elems];
89 g.send_f32(1, 1, &[0.0]).unwrap(); let t0 = Instant::now();
91 for _ in 0..reps {
92 g.send_f32(1, 2, &buf).unwrap();
93 }
94 g.recv_f32(1, 3).unwrap(); let secs = t0.elapsed().as_secs_f64();
96 let gbps = (reps * bytes) as f64 / secs / 1e9;
97 println!(
98 "[bandwidth] {:>9} B × {:>6} = {:>5.1} GB -> {gbps:6.2} GB/s",
99 bytes,
100 reps,
101 (reps * bytes) as f64 / 1e9
102 );
103 } else {
104 g.recv_f32(0, 1).unwrap();
105 for _ in 0..reps {
106 g.recv_f32(0, 2).unwrap();
107 }
108 g.send_f32(0, 3, &[1.0]).unwrap();
109 }
110 g.barrier().unwrap();
111 }
112
113 for &elems in &[4096usize, 4096 * 8] {
117 let mut data = vec![1.0f32; elems];
118 let iters = 2000;
119 for _ in 0..50 {
120 g.all_reduce(&mut data, ReduceKind::Sum).unwrap();
121 }
122 g.barrier().unwrap();
123 let t0 = Instant::now();
124 for _ in 0..iters {
125 g.all_reduce(&mut data, ReduceKind::Sum).unwrap();
126 }
127 let us = t0.elapsed().as_secs_f64() * 1e6 / iters as f64;
128 if rank == 0 {
129 println!("[collective] all_reduce {:>6} f32: {us:6.2} µs/op", elems);
130 }
131 g.barrier().unwrap();
132 }
133
134 g.barrier().unwrap();
135}