RoCE ring: distant ranks have no fabric path — forward 2-hop transfers via flow label 16383 instead of the CPU relay
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 25/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Ambito
- backend, networking
Direzione di ricerca
Read helios/src/execution/roce_fabric.rs and helios/native/roce_proxy.c to trace route planning, queue pair setup, and the CPU relay; compare them with docs/roce-ring.md. The body gives a proposed flow label, opt-in flag, and reference implementation, but leaves scope and route-list behavior undecided. A useful completion criterion is an agreed design and validated forwarding behavior; the prototype reports no clean end-to-end run.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
--roce-ring supports ring-cabled clusters, but distant ranks (2 hops apart) always go through the native CPU relay. There is no code path for letting the fabric forward those transfers, even when the intermediate ConnectX device already has hardware forwarding rules installed. This issue describes the gap, the mechanism that makes 2-hop forwarding possible, a reference implementation, and a concrete proposal.
Where the gap is
helios/src/execution/roce_fabric.rs:374 — plan_ring_routes reduces the endpoint table to rank ± 1 before planning:
let peers: Vec<_> = (0..world)
.filter(|p| *p == rank || *p == (rank + 1) % world || *p == (rank + world - 1) % world)
.collect();
Every other peer then gets an empty route vector, which propagates to helios/native/roce_proxy.c:
:570and:591—if (p == c->rank || ring_relayed(c, p)) continue;— no queue pair is created for a distant rank:886—if (ring_relayed(c, p)) return ring_post(...)— the transfer is posted into the neighbor's relay mailbox instead:238—ring_relayedis the single predicate deciding all three
So the only supported path for a non-neighbor is the CPU relay, which the documentation describes as such (docs/roce-ring.md:4: "A native CPU proxy forwards transfers addressed to its non-neighbours", :56-57: rank 0 → rank 2 relays through rank 1).
That is a correct fallback. The gap is that it is the only option — the fabric is never given the chance, even when it is wired to do the job.
The mechanism that makes 2-hop forwarding possible
The switchless-ring deployments in the DGX Spark community do not relay in software. They let the sender's NIC tag the packets that must be forwarded and let the intermediate device rewrite and hairpin them in hardware. The tag is the RoCEv2 UDP source port, which mlx5 derives from the IPv6 flow label in the GRH:
flow_label 16383 → UDP source port 65535
Setting rtr.ah_attr.grh.flow_label per peer in connect_qp is the entire tagging step. The intermediate device then matches eth_type 0x88b5 + src_mac + dst_mac with an offloaded flower rule (skip_sw), rewrites the EtherType back to 0x0800 and the destination MAC to the far node's port, and mirred-redirects out the sibling port. No CPU touches the forwarded packets, and the kernel forwards nothing.
Both halves are already present in Flare's design:
- The sender's
flow_labelis set inconnect_qp— it is currently hardcoded to0, but the per-peer plumbing is there. - The CPU relay machinery (
ring_post, mailboxes,ring_complete) can stay exactly as it is, as the fallback when routes are absent.
Reference implementation
knapcio/DeepSeek-V4.1-Flash-4x-DGX-Spark-TP4 implements this end to end for its own runtime, which is a fork of the same ring proxy:
-
runtime/b12x/b12x/comm/roce_ring/_roce_proxy.c:512-524— the flow-label assignment, with the comment explaining that the forwarding rules match UDP source port 65535 and that neighbor queue pairs keep flow label 0 so they do not match:rtr.ah_attr.grh.flow_label = (c->world == 4 && ((p - c->rank + c->world) % c->world) == 2) ? 16383 : 0; -
docs/switchless-ring.md— the topology, the/32diagonal routes, theskip_swflower rules, the hairpin queue size, the warning that the marker rewrites every source-port-65535 packet on the device (hence neighbor QPs must use flow label 0), andib_write_lat -d <dev> -x 3 --flow_label=16383as an independent check.
The same convention is used by the sparkring tooling that ships the mesh units (mlx5-rdma-tx-rewrite-probe --source-port 65535 --replacement-ethertype 0x88b5).
Proposal
Three changes, none of which alter behavior for clusters that do not opt in:
-
Plan routes for distant ranks.
plan_ring_routesalready receives the full endpoint table, so it can derive the pair for a 2-hop peer without any configuration: the local device is this rank's device on the link to the carrying neighbor, and the remote device is the distant rank's device on its link to the same neighbor.same_link/interface_prefixalready answer that. The pair should be expressed in a way both ends read identically (ordering by the two device numbers alone), and the two rails must be disjoint. -
Tag those queue pairs. In
connect_qp, setflow_label = 16383when the peer is not a neighbor and forwarding is enabled. Neighbor queue pairs keep0. -
Opt in with a CLI flag.
--roce-ring-forward(or similar) alongside--roce-ring, threaded throughServingOptions::rank_optionsso Orbit passes it to every rank. It cannot default to on: it only works when the intermediate devices have forwarding rules installed and the sender NICs have the tagging agent running, which is operator-side setup.
What I prototyped, and where I stopped
I implemented the three changes above against e5bd6a6 to check whether the approach holds up:
plan_ring_routesderives 2-hop pairs with the constraint that the pair must be a hairpin on the intermediate device (the arriving port and the departing port belong to the same adapter, so the redirect stays inside one device), oriented symmetrically so both ends compute the same pairing from their own endpoint lists.ring_relayedsplit intoring_distant(the topology predicate) andring_relayed(ring_distant && !ring_hw), so the relay path and the forwarding path share one source of truth.flow_labelset per peer as described.cargo build --locked --releasesucceeds;cargo test --manifest-path helios/Cargo.toml --features runtime-package,serverpasses 885 tests, including the ring routing test rewritten to assert the new non-neighbor pairs.
On a 4-node ring the transport does come up with the new routes (Connect RoCE transport. 2 rails per neighbor (experimental forwarded ring)), which confirms the route derivation and the QP setup. I did not get a clean end-to-end run: the remaining blocker is deployment-specific — the tagging agent was only installed on a subset of the ports the plan selected, so the packets that needed forwarding were never tagged and the collective timed out waiting for the distant rank. That is configuration, not the design, but it means I cannot claim a validated result, and I would rather report the idea than submit a PR I cannot back with measurements.
Question
Is ring forwarding for distant ranks in scope for Flare, or is the CPU relay intended to be the permanent answer for ring cabling? If it is in scope, would a PR along the lines above be welcome, and would you want the flag to also accept an explicit route list for deployments whose tagging coverage does not match the automatically derived pairing?
- Lingua principale
- Rust
- Stelle
- 800
- Fork
- 106
- Merge medio
- 1g 3h
- PR unite (30g)
- 100
Preparare l'ambiente
- Include un Dockerfile o un file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di NVIDIA/hyperflare-inference
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
NVIDIA/hyperflare-inference#268 ·
I maintainer di solito rispondono entro 1 giorno
-
break out engram wait timeApertaarea:caching area:engram enhancement performance triage:design-review
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
NVIDIA/hyperflare-inference#230 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 15/100
NVIDIA/hyperflare-inference#278 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 25/100
NVIDIA/hyperflare-inference#276 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
NVIDIA/hyperflare-inference#271 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di NVIDIA/hyperflare-inference
Issue simili
-
bug UI
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
wardian-app/Wardian#1746 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
jlcodes99/cockpit-tools#3125 ·
I maintainer di solito rispondono entro 2 giorni
-
bug user-sprint
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
Vondor/KassenSturz#967 ·
I maintainer di solito rispondono entro 1 giorno
-
area/ci
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 62/100
I maintainer di solito rispondono entro 1 giorno
-
[BUG] Incremental sync warns "no stored highest_uid" on every round for folders with no new mailApertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
rustmailer/bichon#411 ·