silvic-net
The collectives distributed training runs on, over a TCP ring: TcpCollective implements the Collective of silvic-core. silvic.ray.train creates one per Ray actor; any other launcher can do the same.
let listener = TcpCollective::bind_advertised("0.0.0.0", &node_ip)?;
let address = listener.address(); // gather every rank's, in rank order
let mut ring = TcpCollective::connect(listener, rank, &addresses, job_token, Duration::from_secs(1800))?;
Public API
TcpCollective::bind(host),TcpCollective::bind_advertised(host, node_ip)- A listener on an ephemeral port.
bind_advertisedlistens onhost, such as0.0.0.0, and advertisesnode_ip;bind("0.0.0.0")is an error, since other nodes cannot reach that address. listener.address()- The
ip:portthe other ranks connect to. TcpCollective::connect(listener, rank, addresses, job_token, timeout)- Joins the ring.
timeoutbounds the rendezvous, then how long a collective waits on a silent peer;set_timeoutchanges it later. A world of one opens no sockets. allreduce_sum_f64,allreduce_sum_i64,allreduce_max_f64,allgather_bytes- The
Collectivemethods: every rank calls the same ones, in the same order, with buffers of the same length.
The ring
Each rank connects to the next and accepts from the previous. The handshake carries a version, the job token, the rank and the world size, and rejects stray or mismatched peers. An allreduce is a reduce-scatter and then an allgather around the ring; below 4 KiB it is a single allgather. Every chunk folds in a fixed rank order, so a result is the same on every run for a given world size, and exact in any order for the integer-valued histograms quantized training reduces. Sockets are non-blocking and polled, so a ring step sends and receives at once and large buffers cannot deadlock.
Failures
Every frame carries the operation, a sequence number and the length, so ranks that call different collectives fail with an out-of-step error instead of exchanging garbage. A socket error, a closed peer or a timeout fails the collective with a Collective error naming the peer rank; the rank then shuts its sockets, so the failure travels around the ring, and every later call fails the same way.