import%20marimo%0A%0A__generated_with%20%3D%20%220.19.9%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%0A%20%20%20%20return%20(mo%2C)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20%23%20Shared%20imports%20for%20the%20notebook%0A%20%20%20%20import%20time%0A%20%20%20%20import%20torch%0A%20%20%20%20from%20monarch.actor%20import%20Actor%2C%20endpoint%2C%20this_host%2C%20current_rank%0A%20%20%20%20from%20monarch.rdma%20import%20RDMABuffer%2C%20is_rdma_available%0A%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20Actor%2C%0A%20%20%20%20%20%20%20%20RDMABuffer%2C%0A%20%20%20%20%20%20%20%20current_rank%2C%0A%20%20%20%20%20%20%20%20endpoint%2C%0A%20%20%20%20%20%20%20%20is_rdma_available%2C%0A%20%20%20%20%20%20%20%20this_host%2C%0A%20%20%20%20%20%20%20%20torch%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20RDMA%20%26%20Weight%20Synchronization%0A%0A%20%20%20%20You've%20built%20your%20async%20RL%20system.%20Generators%20are%20humming%2C%20the%20trainer%20is%0A%20%20%20%20learning.%20Then%20you%20check%20GPU%20utilization%20and%20discover%20that%20most%20of%20your%0A%20%20%20%20%22training%22%20time%20is%20spent%20copying%20weights.%20Your%20async%20system%20has%20become%20a%0A%20%20%20%20weight-syncing%20system%20that%20occasionally%20does%20RL.%0A%0A%20%20%20%20This%20notebook%20is%20about%20making%20that%20problem%20disappear%20%E2%80%94%20using%20RDMA%20to%20move%0A%20%20%20%20weights%20from%20trainer%20to%20generators%20so%20fast%20it%20becomes%20invisible.%0A%0A%20%20%20%20**Want%20to%20go%20deeper%3F**%20Check%20out%20**07b_weight_sync_deep_dive.py**%20for%20ibverbs%20internals%0A%20%20%20%20and%20RDMA%20buffer%20patterns.%20This%20notebook%20focuses%20on%0A%20%20%20%20the%20concepts%20and%20patterns%20you%20need%20to%20know%20for%20async%20RL.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20Prerequisites%0A%0A%20%20%20%20This%20notebook%20assumes%20familiarity%20with%3A%0A%0A%20%20%20%20-%20**PyTorch%20basics**%20-%20tensors%2C%20dtypes%2C%20device%20placement%0A%20%20%20%20-%20**On-policy%20vs%20off-policy%20RL**%20-%20covered%20in%20%5BNB05%3A%20RL%20Intro%5D(.%2F05_rl_intro.html)%0A%20%20%20%20-%20**Monarch%20Actor%20model**%20-%20spawning%20actors%2C%20endpoints%2C%20%60call_one%60%2F%60call%60%20(from%20%5BNB01%5D(.%2F01_history_and_vision.py)%20and%20%5BNB02%5D(.%2F02_interactive_devx.py))%0A%20%20%20%20-%20**Basic%20networking%20concepts**%20-%20what%20bandwidth%20and%20latency%20mean%2C%20client-server%20vs%20peer-to-peer%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%201.%20Why%20Weight%20Sync%20Matters%0A%0A%20%20%20%20%23%23%23%20The%20On-Policy%20Problem%0A%0A%20%20%20%20Traditional%20RL%20algorithms%20want%20to%20be%20**on-policy**%3A%20generate%20experience%20using%20the%20current%0A%20%20%20%20policy%2C%20then%20immediately%20use%20that%20experience%20to%20update%20the%20policy.%20This%20creates%20a%20tight%20loop%3A%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20On-Policy%20RL%3A%0A%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%0A%20%20%20%20%E2%94%82%20%20generate(policy_v1)%20%E2%86%92%20train(samples)%20%E2%86%92%20policy_v2%20%E2%86%92%20repeat%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20Experience%20from%20v1%20is%20only%20valid%20for%20updating%20v1%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20**Async%20RL%20breaks%20this%20rule.**%20Generators%20run%20continuously%20while%20the%20trainer%20updates%20weights.%0A%20%20%20%20By%20the%20time%20a%20sample%20reaches%20the%20trainer%2C%20it%20was%20generated%20by%20an%20old%20policy%20version%3A%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20Async%20RL%20(off-policy)%3A%0A%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%0A%20%20%20%20%E2%94%82%20%20Generator%3A%20policy_v1%20%E2%86%92%20sample%E2%82%81%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20Trainer%3A%20%20%20train(sample%E2%82%81)%20%E2%86%92%20policy_v2%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20Generator%3A%20policy_v1%20%E2%86%92%20sample%E2%82%82%20%20%E2%86%90%20still%20using%20v1!%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20Trainer%3A%20%20%20train(sample%E2%82%82)%20%E2%86%92%20policy_v3%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20Samples%20are%20%22stale%22%20-%20generated%20by%20older%20policy%20versions%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20This%20**off-policy-ness**%20can%20work%20up%20to%20a%20degree%2C%20but%20must%20be%20limited.%20The%20generators%0A%20%20%20%20need%20fresh%20weights%20regularly%20to%20stay%20%22close%20enough%22%20to%20on-policy.%20Weight%20sync%20frequency%0A%20%20%20%20becomes%20a%20key%20hyperparameter%20trading%20off%3A%0A%0A%20%20%20%20-%20**Too%20slow**%3A%20Samples%20become%20too%20stale%2C%20training%20diverges%0A%20%20%20%20-%20**Too%20fast**%3A%20Weight%20sync%20overhead%20dominates%2C%20negating%20async%20benefits%0A%0A%20%20%20%20%23%23%23%20The%20Scale%20Problem%0A%0A%20%20%20%20For%20LLM-based%20RL%2C%20the%20weights%20are%20**massive**.%20Back-of-envelope%20math%0A%20%20%20%20(1%20parameter%20%E2%89%88%202%20bytes%20in%20bf16)%3A%0A%0A%20%20%20%20%7C%20Model%20%7C%20Weight%20Size%20%7C%0A%20%20%20%20%7C-------%7C-------------%7C%0A%20%20%20%20%7C%20Llama%203.1%2070B%20%7C%20~140%20GB%20%7C%0A%20%20%20%20%7C%20Llama%203.1%20405B%20%7C%20~810%20GB%20%7C%0A%20%20%20%20%7C%20DeepSeek%20V3%20671B%20%7C%20~1.3%20TB%20%7C%0A%0A%20%20%20%20These%20weights%20need%20to%20move%20from%20trainer%20%E2%86%92%20generators%20regularly.%20If%20we're%0A%20%20%20%20not%20careful%2C%20our%20%22async%20RL%20training%20workload%22%20just%20becomes%20a%20weight%20syncing%0A%20%20%20%20workload.%20Let's%20look%20at%20the%20bandwidth%20hierarchy%20to%20understand%20why%20this%20is%0A%20%20%20%20tricky%20and%20what%20we%20can%20do%20about%20it.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%202.%20The%20Bandwidth%20Hierarchy%0A%0A%20%20%20%20For%20weight%20sync%2C%20we%20care%20about%20one%20specific%20data%20path%20%E2%80%94%20trainer%20GPU%20to%20generator%0A%20%20%20%20GPU%2C%20across%20nodes.%20Here's%20the%20chain%20of%20interconnects%20a%20weight%20tensor%20traverses%3A%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20Trainer%20GPU%20%E2%94%80%E2%94%80PCIe%E2%94%80%E2%94%80%E2%96%BA%20CPU%20%E2%94%80%E2%94%80PCIe%E2%94%80%E2%94%80%E2%96%BA%20NIC%20%E2%95%90%E2%95%90RDMA%E2%95%90%E2%95%90%E2%96%BA%20NIC%20%E2%94%80%E2%94%80PCIe%E2%94%80%E2%94%80%E2%96%BA%20CPU%20%E2%94%80%E2%94%80PCIe%E2%94%80%E2%94%80%E2%96%BA%20Generator%20GPU%0A%20%20%20%20%20%20same%20node%20%20%20%20%20(64%20GB%2Fs)%20%20%20%20(50%20GB%2Fs)%20%20%20%20%20(64%20GB%2Fs)%20%20%20%20%20%20same%20node%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20The%20bottleneck%20is%20the%20cross-node%20RDMA%20link%20at%2050%20GB%2Fs%20per%20NIC.%20But%20modern%20nodes%0A%20%20%20%20have%20**8%20NICs**%20(one%20per%20GPU)%2C%20so%20aggregate%20cross-node%20bandwidth%20is%20400%20GB%2Fs.%0A%0A%20%20%20%20Here's%20how%20all%20these%20interconnects%20fit%20together%20in%20a%20full%20node%3A%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20NODE%20A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20NVSwitch%20%2F%20NVLink%20Fabric%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%82%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%82%20%20%E2%94%82GPU%200%20%E2%94%82%20%E2%94%82GPU%201%20%E2%94%82%20%E2%94%82GPU%202%20%E2%94%82%20%E2%94%82GPU%203%20%E2%94%82%20%E2%94%82GPU%204%20%E2%94%82%20%E2%94%82GPU%205%20%E2%94%82%20%E2%94%82GPU%206%20%E2%94%82%20%E2%94%82GPU%207%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%82%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%E2%94%94%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%E2%94%94%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%E2%94%94%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%E2%94%94%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%E2%94%94%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%E2%94%94%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%E2%94%94%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%82%20%20%20%20%20%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%20%20900%20GB%2Fs%20NVLink%20%E2%94%82%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%3D%3D%3D%3D%3D%20%2064%20GB%2Fs%20PCIe%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%B4%E2%94%80%E2%94%80%E2%94%90%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%20%20%20%20%20%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%82%20%20CPU%200%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20CPU%201%20%20%E2%94%82%20%3D%3D%3D%3D%3D%3D%2064%20GB%2Fs%20%E2%95%90%E2%95%90%E2%94%82%20NIC%200%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%E2%94%82%20NIC%201%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%20%20%20%20%20PCIe%20%20%20%20%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%20%20%20%20%20%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%2064%20GB%2Fs%20PCIe%20%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%AA%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%AA%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%BC%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%BC%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%3D%3D%3D%3D%3D%20%2050%20GB%2Fs%20%20%20%3D%3D%3D%3D%3D%3D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20RDMA%20(IB%2FRoCE)%20%20%20RDMA%20(IB%2FRoCE)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%B4%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%B4%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20InfiniBand%20Switch%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%3D%3D%3D%3D%3D%20%2050%20GB%2Fs%20%20%20%3D%3D%3D%3D%3D%3D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20RDMA%20(IB%2FRoCE)%20%20%20RDMA%20(IB%2FRoCE)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%BC%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%BC%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%2064%20GB%2Fs%20PCIe%20%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%AA%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%90%E2%95%AA%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%B4%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%B4%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%20%20%20%20%20PCIe%20%20%20%20%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%B4%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%20%20%20%20%20%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%B4%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%82%20%20CPU%200%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20CPU%201%20%20%E2%94%82%20%3D%3D%3D%3D%3D%3D%2064%20GB%2Fs%20%E2%95%90%E2%95%90%E2%94%82%20NIC%200%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%E2%94%82%20NIC%201%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%20%20%20%20%20%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%3D%3D%3D%3D%3D%20%2064%20GB%2Fs%20PCIe%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%B4%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%82%20%20%20%20%20%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%20%20900%20GB%2Fs%20NVLink%20%E2%94%82%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%82%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%B4%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%B4%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%B4%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%B4%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%B4%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%B4%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%B4%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%B4%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%82%20%20%E2%94%82GPU%200%20%E2%94%82%20%E2%94%82GPU%201%20%E2%94%82%20%E2%94%82GPU%202%20%E2%94%82%20%E2%94%82GPU%203%20%E2%94%82%20%E2%94%82GPU%204%20%E2%94%82%20%E2%94%82GPU%205%20%E2%94%82%20%E2%94%82GPU%206%20%E2%94%82%20%E2%94%82GPU%207%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%82%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20NVSwitch%20%2F%20NVLink%20Fabric%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20NODE%20B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%0A%0A%20%20%20%20Bandwidth%20encoding%20(line%20intensity)%3A%0A%20%20%20%20%20%20%23%23%23%23%23%23%23%23%20%20NVLink%2FNVSwitch%20%20%20900%20GB%2Fs%20bidirectional%20(GPU%20%E2%86%94%20GPU%2C%20same%20node)%0A%20%20%20%20%20%20%3D%3D%3D%3D%3D%3D%3D%3D%20%20PCIe%20Gen5%20%2F%20RDMA%20%2050-64%20GB%2Fs%20unidirectional%20(CPU%E2%86%94GPU%2C%20CPU%E2%86%94NIC%2C%20cross-node)%0A%20%20%20%20%20%20(Showing%202%20of%208%20NICs%20for%20clarity%20%E2%80%94%20each%20GPU%20has%20a%20dedicated%20NIC)%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20%23%23%23%20A%20Note%20on%20Bandwidth%20Numbers%0A%0A%20%20%20%20Bandwidth%20specs%20vary%20by%20hardware%20generation%2C%20cluster%20configuration%2C%20and%20vendor.%0A%20%20%20%20We'll%20use%20numbers%20from%20Meta's%20published%20Llama%203%20training%20infrastructure%0A%20%20%20%20(%5BBuilding%20Meta's%20GenAI%20Infrastructure%5D(https%3A%2F%2Fengineering.fb.com%2F2024%2F03%2F12%2Fdata-center-engineering%2Fbuilding-metas-genai-infrastructure%2F))%3A%0A%0A%20%20%20%20%3E%20%22Both%20of%20these%20solutions%20interconnect%20**400%20Gbps%20endpoints**...%20we%20have%20successfully%0A%20%20%20%20%3E%20used%20both%20RoCE%20and%20InfiniBand%20clusters%20for%20large%2C%20GenAI%20workloads%20(including%20our%0A%20%20%20%20%3E%20ongoing%20training%20of%20Llama%203%20on%20our%20RoCE%20cluster)%20without%20any%20network%20bottlenecks.%22%0A%0A%20%20%20%20**Important**%3A%20%22400%20Gbps%22%20in%20networking%20is%20**full-duplex**%20-%20meaning%20400%20Gbps%20transmit%0A%20%20%20%20AND%20400%20Gbps%20receive%20simultaneously.%20For%20weight%20sync%20(unidirectional%3A%20trainer%20%E2%86%92%20generator)%2C%0A%20%20%20%20we%20get%20the%20full%20400%20Gbps%20%3D%20**50%20GB%2Fs%20per%20NIC**.%0A%0A%20%20%20%20Meta's%20Grand%20Teton%20nodes%20have%20**8%20RDMA%20NICs**%20(one%20per%20GPU%2C%201%3A1%20mapping)%2C%20giving%0A%20%20%20%20400%20GB%2Fs%20aggregate%20unidirectional%20bandwidth%20per%20node.%20For%20more%20details%20on%20Grand%20Teton%0A%20%20%20%20and%20Monarch's%20RDMA%20architecture%2C%20see%20the%20SIGCOMM%202024%20paper%3A%0A%20%20%20%20%5BRDMA%20over%20Ethernet%20for%20Distributed%20AI%20Training%20at%20Meta%20Scale%5D(https%3A%2F%2Fcs.stanford.edu%2F~keithw%2Fsigcomm2024%2Fsigcomm24-final246-acmpaginated.pdf).%0A%0A%20%20%20%20%7C%20Interconnect%20%7C%20Bandwidth%20%7C%20Notes%20%7C%0A%20%20%20%20%7C--------------%7C-----------%7C-------%7C%0A%20%20%20%20%7C%20**NVLink%204.0**%20%7C%20900%20GB%2Fs%20bidirectional%20%7C%20~450%20GB%2Fs%20per%20direction%20%7C%0A%20%20%20%20%7C%20**RDMA%20(IB%2FRoCE)**%20%7C%20400%20Gbps%20%3D%2050%20GB%2Fs%20%7C%20Per%20NIC%2C%20full-duplex%20%7C%0A%20%20%20%20%7C%20**PCIe%20Gen5%20x16**%20%7C%2064%20GB%2Fs%20%7C%20Per%20direction%20%7C%0A%0A%20%20%20%20**Key%20observations%3A**%0A%0A%20%20%20%201.%20**NVLink%20is%20fast%20but%20same-node%20only**%20-%20450%20GB%2Fs%2C%20but%20can't%20cross%20the%20network%0A%20%20%20%202.%20**RDMA%20%3E%3E%20TCP**%20-%2050%20GB%2Fs%20with%20zero-copy%20beats%20TCP%20significantly%20for%20cross-node%0A%20%20%20%203.%20**Multi-NIC%20scales**%20-%208%20NICs%20%C3%97%2050%20GB%2Fs%20%3D%20400%20GB%2Fs%2C%20approaching%20NVLink%20speeds%0A%0A%20%20%20%20**Rule%20of%20thumb**%3A%20NVLink%20for%20same-node%20ops%20(gradients%2C%20activations).%0A%20%20%20%20RDMA%20for%20cross-node%20communication%20(weight%20sync)%20-%20it's%20the%20only%20practical%20option.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%202b.%20Back-of-Envelope%3A%20Syncing%20Large%20Models%0A%0A%20%20%20%20Let's%20do%20some%20quick%20math.%20DeepSeek%20V3%20has%20671B%20parameters%20(~1.34%20TB%20in%20bf16).%0A%0A%20%20%20%20The%20key%20insight%3A%20**you're%20not%20shoving%201.3%20TB%20through%20a%20single%20NIC**.%20The%20weights%0A%20%20%20%20are%20distributed%20across%20many%20GPUs%20(via%20some%20combination%20of%20PP%2C%20EP%2C%20TP%2C%20FSDP)%2C%0A%20%20%20%20and%20each%20GPU%20has%20its%20own%20NIC.%20You%20get%20**aggregate%20bandwidth**%20across%20all%20NICs.%0A%0A%20%20%20%20The%20actual%20sync%20time%20depends%20on%20**both%20sides**%3A%0A%20%20%20%20-%20**Trainer's%20aggregate%20upload%20bandwidth**%20(sending%20weights%20out)%0A%20%20%20%20-%20**Generator's%20aggregate%20download%20bandwidth**%20(receiving%20weights)%0A%0A%20%20%20%20The%20bottleneck%20is%20whichever%20is%20smaller.%20And%20if%20multiple%20generators%20pull%20from%0A%20%20%20%20the%20same%20trainer%20simultaneously%2C%20the%20trainer's%20bandwidth%20is%20divided%20among%20them.%0A%0A%20%20%20%20With%20Grand%20Teton's%208%20NICs%20per%20node%20at%2050%20GB%2Fs%20each%20(400%20GB%2Fs%20per%20node)%2C%0A%20%20%20%20the%20math%20is%20simple%3A%20**Time%20%3D%20Shard%20Size%20%2F%20Bandwidth**.%0A%0A%20%20%20%20The%20per-node%20shard%20size%20depends%20on%20how%20many%20nodes%20the%20model%20is%20spread%20across%3A%0A%20%20%20%20-%20DeepSeek%20V3%20(1.3%20TB)%20across%208%20nodes%20%E2%86%92%20~160%20GB%20per%20node%0A%20%20%20%20-%20DeepSeek%20V3%20(1.3%20TB)%20across%2016%20nodes%20%E2%86%92%20~80%20GB%20per%20node%0A%0A%20%20%20%20%7C%20Per-node%20shard%20%7C%20Time%20to%20sync%20%7C%0A%20%20%20%20%7C----------------%7C--------------%7C%0A%20%20%20%20%7C%20~160%20GB%20(8%20nodes)%20%7C%20160%20%2F%20400%20%3D%20**0.4%20seconds**%20%7C%0A%20%20%20%20%7C%20~80%20GB%20(16%20nodes)%20%7C%2080%20%2F%20400%20%3D%20**0.2%20seconds**%20%7C%0A%0A%20%20%20%20The%20exact%20per-node%20shard%20size%20depends%20on%20your%20parallelism%20strategy%20(PP%2C%20EP%2C%20TP%2C%20etc.)%2C%0A%20%20%20%20but%20the%20math%20works%20out%3A%20with%20modern%20RDMA%20hardware%2C%20you%20can%20sync%20even%20the%20largest%0A%20%20%20%20models%20in%20**sub-second%20time**.%0A%0A%20%20%20%20Compare%20this%20to%20naive%20TCP%3A%20kernel%20copies%2C%20socket%20overhead%2C%20no%20zero-copy...%0A%20%20%20%20easily%2010x%20slower.%20**RDMA%20is%20the%20only%20way%20to%20make%20async%20RL%20practical%20at%20scale.**%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%203.%20The%20Problem%3A%20Collectives%20Are%20Blocking%0A%0A%20%20%20%20Most%20people%20use%20RDMA%20via%20**collectives**%20through%20PyTorch%20distributed%3A%0A%0A%20%20%20%20%60%60%60python%0A%20%20%20%20import%20torch.distributed%20as%20dist%0A%0A%20%20%20%20dist.init_process_group(backend%3D%22nccl%22)%0A%20%20%20%20dist.all_reduce(gradients%2C%20op%3Ddist.ReduceOp.SUM)%0A%20%20%20%20dist.broadcast(weights%2C%20src%3D0)%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20This%20works%20great%20for%20training.%20But%20async%20RL%20has%20a%20different%20access%20pattern.%0A%0A%20%20%20%20%23%23%23%20High%20Variance%20in%20Generation%20Times%0A%0A%20%20%20%20Generators%20have%20wildly%20different%20completion%20times%3A%0A%20%20%20%20-%20Some%20prompts%20%E2%86%92%2010%20tokens%20(fast)%0A%20%20%20%20-%20Other%20prompts%20%E2%86%92%201000%20tokens%20(slow)%0A%0A%20%20%20%20With%20collectives%2C%20fast%20generators%20wait%20for%20slow%20ones%3A%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20Generator%200%3A%20%E2%94%9C%E2%94%80%E2%94%80%20gen%20(fast)%20%E2%94%80%E2%94%80%E2%94%A4%20%20%E2%9A%A0%EF%B8%8F%20WAITING...%0A%20%20%20%20Generator%201%3A%20%E2%94%9C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%20gen%20(slow)%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%A4%0A%20%20%20%20Generator%202%3A%20%E2%94%9C%E2%94%80%E2%94%80%20gen%20(fast)%20%E2%94%80%E2%94%80%E2%94%A4%20%20%E2%9A%A0%EF%B8%8F%20WAITING...%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%86%93%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20all_gather(weights)%20%20%23%20Everyone%20waits!%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20%23%23%23%20The%20One-Sided%20Solution%3A%20RDMA%0A%0A%20%20%20%20What%20if%20the%20sender%20could%20write%20directly%20to%20the%20receiver's%20memory%20without%20coordination%3F%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20Two-sided%20(send%2Frecv)%3A%0A%20%20%20%20%20%20Sender%3A%20%22I%20have%20data%22%20%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%96%BA%20%20Receiver%3A%20%22I'm%20ready%22%0A%20%20%20%20%20%20Sender%3A%20sends%20data%20%20%20%20%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%96%BA%20%20Receiver%3A%20receives%20data%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20messages%20required%0A%0A%20%20%20%20One-sided%20(RDMA)%3A%0A%20%20%20%20%20%20Sender%3A%20writes%20directly%20to%20receiver's%20memory%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20No%20coordination%20needed!%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20This%20is%20what%20RDMA%20enables%3A%20**one-sided%20memory%20operations**.%0A%20%20%20%20The%20trainer%20doesn't%20even%20know%20when%20generators%20pull%20weights%20-%20this%20is%20truly%20async!%0A%0A%20%20%20%20RDMA%20isn't%20just%20%22faster%20TCP%22%20%E2%80%94%20it%20bypasses%20the%20kernel%20entirely.%20No%20socket%20buffers%2C%0A%20%20%20%20no%20context%20switches%2C%20no%20serialization.%20The%20NIC%20reads%20directly%20from%20registered%20memory.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%204.%20The%20Magic%20Pointer%20Pattern%0A%0A%20%20%20%20One%20natural%20question%20that%20arises%20is%20along%20the%20lines%20of%2C%20%22How%20do%20we%20actually%20represent%20one-sided%20puts%2Fgets%20if%20not%20with%20NCCL%20collectives%3F%22%0A%0A%20%20%20%20Here's%20a%20key%20insight%3A%20to%20represent%20remote%20data%2C%20we%20only%20need%20a%20**tiny%20handle**%20-%0A%20%20%20%20an%20%60(addr%2C%20rkey%2C%20size)%60%20tuple%20that%20says%20%22here's%20where%20my%20data%20lives.%22%0A%0A%20%20%20%20Monarch%20wraps%20this%20in%20%60RDMABuffer%60.%20Let's%20see%20how%20small%20it%20actually%20is%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Actor%2C%20RDMABuffer%2C%20endpoint%2C%20is_rdma_available%2C%20this_host%2C%20torch)%3A%0A%20%20%20%20%23%20Measure%20actual%20size%20of%20RDMABuffer%20handles%0A%20%20%20%20import%20pickle%0A%0A%20%20%20%20def%20show_fallback_sizes()%3A%0A%20%20%20%20%20%20%20%20%22%22%22Fallback%3A%20show%20expected%20sizes%20based%20on%20RDMABuffer%20structure.%22%22%22%0A%20%20%20%20%20%20%20%20print(%22(RDMA%20not%20available%20-%20showing%20expected%20handle%20sizes)%5Cn%22)%0A%20%20%20%20%20%20%20%20print(%22RDMABuffer%20contains%3A%20addr%20(8B)%20%2B%20rkey%20(4B)%20%2B%20size%20(8B)%20%2B%20owner%20(~100B)%22)%0A%20%20%20%20%20%20%20%20print(%22Total%20serialized%20size%3A%20~150-200%20bytes%20regardless%20of%20tensor%20size%5Cn%22)%0A%0A%20%20%20%20%20%20%20%20sizes%20%3D%20%5B(%221%20KB%22%2C%201024)%2C%20(%221%20MB%22%2C%201024**2)%2C%20(%221%20GB%22%2C%201024**3)%5D%0A%20%20%20%20%20%20%20%20handle_bytes%20%3D%20150%20%20%23%20approximate%0A%0A%20%20%20%20%20%20%20%20for%20name%2C%20tensor_bytes%20in%20sizes%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20ratio%20%3D%20tensor_bytes%20%2F%20handle_bytes%0A%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%7Bname%3A%3C8%7D%20tensor%20%E2%86%92%20~150%20byte%20handle%20%E2%86%92%20%7Bratio%3A%2C.0f%7Dx%20compression%22)%0A%0A%20%20%20%20%20%20%20%20print(%22%5Cn%E2%86%92%20Handle%20size%20is%20O(1)%20regardless%20of%20tensor%20size!%22)%0A%0A%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20if%20not%20is_rdma_available()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20show_fallback_sizes()%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20class%20BufferSizeDemo(Actor)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Actor%20that%20creates%20RDMABuffers%20and%20measures%20their%20size.%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%40endpoint%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20def%20measure_buffer_sizes(self)%20-%3E%20list%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20import%20pickle%20as%20_pickle%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20results%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sizes%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(%221%20KB%22%2C%20256)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(%221%20MB%22%2C%20256%20*%201024)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(%2210%20MB%22%2C%20256%20*%201024%20*%2010)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20name%2C%20numel%20in%20sizes%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tensor%20%3D%20torch.randn(numel)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tensor_bytes%20%3D%20tensor.numel()%20*%20tensor.element_size()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20byte_tensor%20%3D%20tensor.view(torch.uint8).flatten()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20buffer%20%3D%20RDMABuffer(byte_tensor)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20handle_bytes%20%3D%20len(_pickle.dumps(buffer))%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20results.append((name%2C%20tensor_bytes%2C%20handle_bytes))%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20results%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20proc%20%3D%20this_host().spawn_procs(per_host%3D%7B%22procs%22%3A%201%7D)%0A%20%20%20%20%20%20%20%20%20%20%20%20demo%20%3D%20proc.spawn(%22buffer_demo%22%2C%20BufferSizeDemo)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20results%20%3D%20demo.measure_buffer_sizes.call_one().get()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22RDMABuffer%20handle%20size%20vs%20actual%20tensor%20size%3A%5Cn%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%7B'Tensor%20Size'%3A%3C12%7D%20%7B'Actual%20Bytes'%3A%3C15%7D%20%7B'Handle%20Size'%3A%3C15%7D%20%7B'Ratio'%3A%3C10%7D%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22-%22%20*%2055)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20name%2C%20tensor_bytes%2C%20handle_bytes%20in%20results%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ratio%20%3D%20tensor_bytes%20%2F%20handle_bytes%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%7Bname%3A%3C12%7D%20%7Btensor_bytes%3A%3E12%2C%7D%20B%20%20%20%7Bhandle_bytes%3A%3E6%7D%20B%20%20%20%20%20%20%20%20%7Bratio%3A%3E8%2C.0f%7Dx%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22%5Cn%E2%86%92%20Handle%20size%20is%20O(1)%20regardless%20of%20tensor%20size!%22)%0A%0A%20%20%20%20except%20Exception%20as%20e%3A%0A%20%20%20%20%20%20%20%20print(f%22(RDMA%20setup%20failed%3A%20%7Be%7D)%5Cn%22)%0A%20%20%20%20%20%20%20%20show_fallback_sizes()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20The%20Magic%20Pointer%0A%0A%20%20%20%20This%20is%20the%20core%20pattern%3A%20**separate%20control%20plane%20from%20data%20plane**.%0A%0A%20%20%20%20-%20**Control%20plane**%20(actor%20messages)%3A%20Send%20tiny%20handle%20(~100%20bytes)%0A%20%20%20%20-%20**Data%20plane**%20(RDMA)%3A%20Bulk%20transfer%20of%20actual%20data%20(~10%20GB)%0A%0A%20%20%20%20Think%20of%20%60RDMABuffer%60%20as%20a%20**magic%20pointer**%20-%20it's%20a%20pointer%20that%20works%20across%20machines%3A%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20Trainer%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Generator%0A%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%0A%20%20%20%20%E2%94%82%20weights%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20local%20copy%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20(10%20GB)%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20(empty)%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%0A%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%201.%20Create%20RDMABuffer%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20(register%20memory%2C%20get%20handle)%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%E2%94%9C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%202.%20Send%20handle%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%96%BA%E2%94%82%20%20(~100%20bytes%20via%20actor)%0A%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%E2%97%84%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%203.%20RDMA%20read%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%A4%20%20(~10%20GB%20via%20hardware)%0A%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20(no%20trainer%20involvement!)%20%20%E2%94%82%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20The%20trainer%20doesn't%20even%20know%20when%20generators%20pull%20weights.%20True%20one-sided.%0A%0A%20%20%20%20%23%23%23%20RDMABuffer%20in%20Action%0A%0A%20%20%20%20%60%60%60python%0A%20%20%20%20from%20monarch.rdma%20import%20RDMABuffer%0A%0A%20%20%20%20%23%20Trainer%20side%3A%20register%20weights%0A%20%20%20%20weights%20%3D%20torch.randn(1024%2C%201024%2C%20device%3D%22cuda%22)%0A%20%20%20%20buffer%20%3D%20RDMABuffer(weights.view(torch.uint8).flatten())%0A%0A%20%20%20%20%23%20Return%20buffer%20as%20part%20of%20an%20endpoint%20response%0A%20%20%20%20%40endpoint%0A%20%20%20%20def%20get_weight_handle(self)%20-%3E%20RDMABuffer%3A%0A%20%20%20%20%20%20%20%20return%20self.buffer%0A%0A%20%20%20%20%23%20Generator%20side%3A%20receive%20handle%2C%20pull%20directly%20into%20GPU%0A%20%20%20%20handle%20%3D%20trainer.get_weight_handle.call_one().get()%20%20%23%20Tiny%20message%0A%20%20%20%20gpu_weights%20%3D%20model.weights.view(torch.uint8).flatten()%0A%20%20%20%20handle.read_into(gpu_weights).get()%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20Bulk%20RDMA%20transfer%0A%0A%20%20%20%20%23%20Push%20model%3A%20caller%20writes%20local%20src_tensor%20into%20the%20remote%20RDMABuffer%0A%20%20%20%20buffer.write_from(src_tensor).get()%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20**Pull%20vs%20Push**%3A%20%60read_into%60%20is%20the%20**pull**%20model%20(generator%20reads%20remote%20data%20into%0A%20%20%20%20its%20local%20buffer)%2C%20while%20%60write_from%60%20is%20the%20**push**%20model%20(caller%20writes%20local%20data%0A%20%20%20%20into%20the%20remote%20buffer).%20Both%20are%20one-sided%20RDMA%20operations%20%E2%80%94%20the%20remote%20side%20is%20not%0A%20%20%20%20involved.%20In%20async%20RL%2C%20pull%20is%20more%20natural%20because%20each%20generator%20decides%20*when*%20it%0A%20%20%20%20needs%20fresh%20weights.%0A%0A%20%20%20%20**Want%20to%20understand%20how%20RDMA%20works%20under%20the%20hood%3F**%20Check%20out%20**07b_weight_sync_deep_dive.py**%0A%20%20%20%20for%20ibverbs%20internals%2C%20queue%20pair%20setup%2C%20and%20why%20Monarch's%20actor%20model%20is%20such%20a%20natural%20fit%0A%20%20%20%20for%20managing%20RDMA%20connections.%20It's%20actors%20all%20the%20way%20down!%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20Live%20Demo%3A%20Trainer%20%E2%86%92%20Generator%20Weight%20Sync%0A%0A%20%20%20%20Let's%20see%20this%20in%20action%20with%20a%20simple%20example.%20A%20trainer%20holds%20weights%2C%0A%20%20%20%20a%20generator%20pulls%20them%20via%20RDMA.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Actor%2C%20RDMABuffer%2C%20endpoint%2C%20is_rdma_available%2C%20this_host%2C%20torch)%3A%0A%20%20%20%20%23%20Simple%20trainer%20%E2%86%92%20generator%20weight%20sync%20demo%0A%0A%20%20%20%20def%20show_fallback_demo()%3A%0A%20%20%20%20%20%20%20%20%22%22%22Show%20what%20would%20happen%20with%20RDMA.%22%22%22%0A%20%20%20%20%20%20%20%20print(%22(RDMA%20not%20available%20-%20showing%20conceptual%20flow)%5Cn%22)%0A%20%20%20%20%20%20%20%20print(%221.%20Trainer%20creates%20weights%20(e.g.%2C%204%20MB%20tensor)%22)%0A%20%20%20%20%20%20%20%20print(%222.%20Trainer%20wraps%20weights%20in%20RDMABuffer%20%E2%86%92%20tiny%20handle%20(~150%20bytes)%22)%0A%20%20%20%20%20%20%20%20print(%223.%20Trainer%20sends%20handle%20to%20Generator%20via%20actor%20message%22)%0A%20%20%20%20%20%20%20%20print(%224.%20Generator%20calls%20handle.read_into(local_buffer)%22)%0A%20%20%20%20%20%20%20%20print(%225.%20RDMA%20hardware%20transfers%204%20MB%20directly%2C%20trainer%20not%20involved!%22)%0A%20%20%20%20%20%20%20%20print(%22%5Cn%E2%86%92%20Zero-copy%2C%20one-sided%2C%20no%20serialization%20overhead%22)%0A%0A%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20if%20not%20is_rdma_available()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20show_fallback_demo()%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20class%20Sender(Actor)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Sender%20that%20holds%20data%20and%20exposes%20an%20RDMA%20handle.%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20def%20__init__(self%2C%20size%3A%20int)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20Create%20some%20data%20to%20send%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.data%20%3D%20torch.randn(size%2C%20dtype%3Dtorch.float32)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20Register%20with%20RDMA%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.data_bytes%20%3D%20self.data.view(torch.uint8).flatten()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.buffer%20%3D%20RDMABuffer(self.data_bytes)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%5BSender%5D%20Created%20data%3A%20%7Bself.data.numel()%20*%204%20%2F%201e6%3A.1f%7D%20MB%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%40endpoint%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20def%20get_handle(self)%20-%3E%20RDMABuffer%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Return%20tiny%20handle%20(not%20the%20data%20itself!)%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20self.buffer%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%40endpoint%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20def%20get_checksum(self)%20-%3E%20float%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22For%20verification%3A%20sum%20of%20data%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20float(self.data.sum())%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20class%20Receiver(Actor)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Receiver%20that%20pulls%20data%20from%20sender%20via%20RDMA.%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20def%20__init__(self%2C%20size%3A%20int)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20Pre-allocate%20space%20for%20data%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.data%20%3D%20torch.zeros(size%2C%20dtype%3Dtorch.float32)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.data_bytes%20%3D%20self.data.view(torch.uint8).flatten()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%5BReceiver%5D%20Allocated%20buffer%3A%20%7Bself.data.numel()%20*%204%20%2F%201e6%3A.1f%7D%20MB%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%40endpoint%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20def%20pull_data(self%2C%20handle%3A%20RDMABuffer)%20-%3E%20float%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Pull%20data%20via%20RDMA%20read%2C%20return%20checksum%20for%20verification.%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20This%20is%20the%20magic%3A%20RDMA%20read%20directly%20into%20our%20buffer%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20handle.read_into(self.data_bytes).get()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20float(self.data.sum())%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Spawn%20sender%20and%20receiver%0A%20%20%20%20%20%20%20%20%20%20%20%20procs%20%3D%20this_host().spawn_procs(per_host%3D%7B%22procs%22%3A%202%7D)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20sender%20%3D%20procs.slice(procs%3D0).spawn(%22sender%22%2C%20Sender%2C%201024%20*%201024)%20%20%23%204%20MB%0A%20%20%20%20%20%20%20%20%20%20%20%20receiver%20%3D%20procs.slice(procs%3D1).spawn(%22receiver%22%2C%20Receiver%2C%201024%20*%201024)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Step%201%3A%20Get%20handle%20from%20sender%20(tiny%20message!)%0A%20%20%20%20%20%20%20%20%20%20%20%20handle%20%3D%20sender.get_handle.call_one().get()%0A%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%5Cn%5BOrchestrator%5D%20Got%20handle%20from%20sender%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Step%202%3A%20Send%20handle%20to%20receiver%2C%20have%20it%20pull%20data%0A%20%20%20%20%20%20%20%20%20%20%20%20receiver_checksum%20%3D%20receiver.pull_data.call_one(handle).get()%0A%20%20%20%20%20%20%20%20%20%20%20%20sender_checksum%20%3D%20sender.get_checksum.call_one().get()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%5BOrchestrator%5D%20Sender%20checksum%3A%20%7Bsender_checksum%3A.2f%7D%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%5BOrchestrator%5D%20Receiver%20checksum%3A%20%7Breceiver_checksum%3A.2f%7D%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%5BOrchestrator%5D%20Match%3A%20%7Babs(sender_checksum%20-%20receiver_checksum)%20%3C%200.01%7D%22)%0A%0A%20%20%20%20except%20Exception%20as%20e%3A%0A%20%20%20%20%20%20%20%20print(f%22(Demo%20failed%3A%20%7Be%7D)%5Cn%22)%0A%20%20%20%20%20%20%20%20show_fallback_demo()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%205.%20CPU%20Staging%20Pattern%0A%0A%20%20%20%20%23%23%23%20GPU-Native%20RDMA%20Exists%20(and%20Monarch%20Supports%20It)%0A%0A%20%20%20%20GPU-native%20RDMA%20(GPUDirect)%20is%20real%20and%20works%20well%20-%20the%20NIC%20reads%20directly%20from%20GPU%0A%20%20%20%20memory%20with%20no%20CPU%20copy.%20Monarch%20supports%20this%20at%20the%20Rust%20level.%20For%20synchronous%0A%20%20%20%20bulk%20transfers%2C%20it's%20excellent.%0A%0A%20%20%20%20%23%23%23%20CPU%20Staging%3A%20A%20Deliberate%20Architectural%20Choice%0A%0A%20%20%20%20For%20async%20RL%2C%20CPU%20staging%20isn't%20a%20workaround%20for%20missing%20GPUDirect%20-%20it's%20the%0A%20%20%20%20**preferred%20production%20pattern**.%20The%20reason%20is%20**temporal%20decoupling**%3A%20trainers%0A%20%20%20%20and%20generators%20operate%20on%20completely%20independent%20timelines%2C%20and%20we%20need%20a%20buffer%0A%20%20%20%20between%20them.%0A%0A%20%20%20%20The%20issue%20isn't%20bandwidth%20-%20it's%20**timing**%3A%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20Direct%20GPU%E2%86%92GPU%20RDMA%3A%0A%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%0A%20%20%20%20%E2%94%82%20Generator%20GPU%20is%20mid-inference%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%E2%94%9C%E2%94%80%E2%94%80%20layer%201%20%E2%94%80%E2%94%80%E2%94%A4%20%5BRDMA%20arrives%2C%20needs%20sync!%5D%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%86%93%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20cudaDeviceSynchronize()%20%20%E2%86%90%20Blocks%20inference!%20%E2%94%82%0A%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20With%20CPU%20staging%2C%20nothing%20on%20the%20critical%20path%20blocks%3A%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20Trainer%20GPU%20%E2%94%80%E2%94%80%E2%96%BA%20CPU%20staging%20buffer%20(RDMA%20registered)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%5BSits%20here%2C%20ready%20anytime%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%96%BC%0A%20%20%20%20Generator%20grabs%20when%20ready%20%E2%94%80%E2%94%80%E2%96%BA%20Generator%20GPU%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20The%20CPU%20buffer%20is%20a%20**temporal%20decoupling%20point**.%0A%0A%20%20%20%20Note%3A%20the%20CPU%20staging%20path%20does%20involve%20GPU%E2%86%94CPU%20copies%20on%20each%20end.%20When%20we%20say%0A%20%20%20%20RDMA%20is%20%22zero-copy%2C%22%20we%20mean%20across%20the%20network%20%E2%80%94%20the%20NIC%20reads%2Fwrites%20directly%0A%20%20%20%20from%2Fto%20registered%20CPU%20memory%20with%20no%20kernel%20involvement.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%206.%20Circular%20Weight%20Buffers%0A%0A%20%20%20%20%23%23%23%20One-Sided%20Isn't%20Free%0A%0A%20%20%20%20One-sided%20RDMA%20is%20powerful%20-%20trainers%20and%20generators%20can%20operate%20independently%20without%0A%20%20%20%20explicit%20send%2Frecv%20coordination.%20But%20%22no%20coordination%22%20isn't%20quite%20right.%20There's%20still%0A%20%20%20%20a%20fundamental%20race%20condition%20lurking%3A%20**what%20if%20the%20trainer%20overwrites%20a%20buffer%20while%20a%0A%20%20%20%20generator%20is%20reading%20from%20it%3F**%0A%0A%20%20%20%20With%20a%20single%20buffer%2C%20this%20is%20a%20real%20problem%3A%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20Trainer%3A%20write%20v3%20to%20buffer%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%96%BA%20%20%5Bbuffer%3A%20v3...v2...v3%5D%20%20%E2%86%90%20corrupted!%0A%20%20%20%20Generator%3A%20reading%20v2%20from%20buffer%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%96%BA%20%20read%20gets%20mix%20of%20v2%20and%20v3%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20We%20need%20*some*%20form%20of%20coordination.%20The%20question%20is%3A%20do%20we%20go%20back%20to%20message-passing%0A%20%20%20%20(explicit%20locks%2C%20barriers%2C%20acknowledgments)%20and%20lose%20the%20async%20benefits%3F%20Or%20can%20we%20get%0A%20%20%20%20coordination%20from%20the%20**structure%20itself**%3F%0A%0A%20%20%20%20%23%23%23%20Solution%3A%20Circular%20Buffer%20as%20Structural%20Coordination%0A%0A%20%20%20%20The%20key%20insight%3A%20GPU%20memory%20is%20scarce%2C%20but%20**CPU%20memory%20is%20abundant**.%20We%20can%20afford%20to%0A%20%20%20%20keep%20multiple%20versions%20of%20the%20weights%20in%20CPU%20staging%20buffers.%20By%20writing%20to%20slots%20in%20a%0A%20%20%20%20circular%20pattern%2C%20the%20trainer%20never%20overwrites%20a%20slot%20that%20a%20generator%20might%20still%20be%0A%20%20%20%20reading%20-%20as%20long%20as%20we%20have%20enough%20slots%20to%20cover%20the%20timing%20gap.%0A%0A%20%20%20%20This%20is%20**structural%20coordination**%3A%20the%20circular%20buffer's%20design%20eliminates%20the%20race%0A%20%20%20%20condition%20without%20any%20explicit%20synchronization%20messages%20between%20trainer%20and%20generator.%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20Trainer%20writes%3A%20%20%20%20%20v0%20%20%20%20%E2%86%92%20%20v1%20%20%E2%86%92%20%20v2%20%20%E2%86%92%20%20v3%20%20%E2%86%92%20%20v4%20%20%E2%86%92%20%20v5%20%20%E2%86%92%20...%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%86%93%20%20%20%20%20%20%20%20%E2%86%93%20%20%20%20%20%20%E2%86%93%0A%20%20%20%20Buffer%20slots%3A%20%20%20%20%20%20%5Bslot0%5D%20%5Bslot1%5D%20%5Bslot2%5D%20%20(circular%2C%20reused)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v3%20%20%20%20%20%20v4%20%20%20%20%20%20v5%0A%0A%20%20%20%20Generator%20reads%3A%20%22Give%20me%20latest%22%20%E2%86%92%20v5%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20Benefits%3A%0A%20%20%20%20-%20**No%20message-based%20coordination**%20-%20structure%20prevents%20races%2C%20not%20locks%0A%20%20%20%20-%20**Pre-registered%20RDMA%20buffers**%20-%20no%20memory%20registration%20on%20hot%20path%0A%20%20%20%20-%20**Lock-free%20reads**%20-%20generators%20always%20get%20a%20consistent%20snapshot%0A%20%20%20%20-%20**Bounded%20memory**%20-%20only%20N%20versions%20in%20flight%0A%0A%20%20%20%20**Memory%20cost%20is%20real**%3A%20for%20a%2070B%20model%20(140%20GB%20in%20bf16)%2C%205%20slots%20%3D%20700%20GB%20of%20CPU%20RAM.%0A%20%20%20%20This%20is%20feasible%20on%20HPC%20nodes%20(Grand%20Teton%20has%20~1.5%20TB%20RAM%20per%20node)%2C%20but%20%60n_slots%60%20is%0A%20%20%20%20bounded%20by%20available%20CPU%20memory%2C%20not%20just%20timing.%0A%0A%20%20%20%20The%20key%20design%20constraint%3A%20register%20all%20slots%20at%20init%20time%2C%20then%20just%20write%20to%20them.%0A%20%20%20%20No%20allocation%2C%20no%20registration%20on%20the%20critical%20path.%20Tune%20%60n_slots%60%20so%20that%20the%20trainer%0A%20%20%20%20can't%20lap%20the%20slowest%20generator%20%E2%80%94%20if%20it%20does%2C%20the%20generator%20reads%20a%20corrupted%20mix%20of%0A%20%20%20%20two%20versions%20(not%20a%20graceful%20error%2C%20just%20silent%20data%20corruption).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20circ_slots_slider%20%3D%20mo.ui.slider(1%2C%208%2C%20value%3D3%2C%20label%3D%22Buffer%20slots%20(n_slots)%22)%0A%20%20%20%20circ_writes_slider%20%3D%20mo.ui.slider(1%2C%2010%2C%20value%3D2%2C%20label%3D%22Trainer%20writes%20per%20generator%20sync%22)%0A%20%20%20%20mo.vstack(%5B%0A%20%20%20%20%20%20%20%20mo.md(%22**Try%20it**%3A%20adjust%20slots%20and%20write%20speed%20to%20see%20when%20lapping%20causes%20a%20race%20condition.%22)%2C%0A%20%20%20%20%20%20%20%20mo.hstack(%5Bcirc_slots_slider%2C%20circ_writes_slider%5D%2C%20justify%3D%22center%22%2C%20gap%3D1)%2C%0A%20%20%20%20%5D)%0A%20%20%20%20return%20circ_slots_slider%2C%20circ_writes_slider%0A%0A%0A%40app.cell%0Adef%20_(circ_slots_slider%2C%20circ_writes_slider%2C%20mo)%3A%0A%20%20%20%20_n%20%3D%20circ_slots_slider.value%0A%20%20%20%20_w%20%3D%20circ_writes_slider.value%0A%20%20%20%20_safe%20%3D%20_w%20%3C%20_n%0A%0A%20%20%20%20%23%20Build%20SVG%20showing%20circular%20buffer%20slots%20with%20write%20pointer%20and%20read%20pointer%0A%20%20%20%20_slot_w%2C%20_slot_h%20%3D%2064%2C%2048%0A%20%20%20%20_gap%20%3D%206%0A%20%20%20%20_pad%20%3D%2030%0A%20%20%20%20_total_w%20%3D%20max(_n%20*%20(_slot_w%20%2B%20_gap)%20-%20_gap%20%2B%202%20*%20_pad%2C%20300)%0A%20%20%20%20_total_h%20%3D%20130%0A%0A%20%20%20%20_parts%20%3D%20%5B%0A%20%20%20%20%20%20%20%20f'%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22%7B_total_w%7D%22%20height%3D%22%7B_total_h%7D%22%20'%0A%20%20%20%20%20%20%20%20f'style%3D%22font-family%3A%20-apple-system%2C%20sans-serif%3B%22%3E'%0A%20%20%20%20%5D%0A%0A%20%20%20%20%23%20Title%0A%20%20%20%20_parts.append(%0A%20%20%20%20%20%20%20%20f'%3Ctext%20x%3D%22%7B_total_w%20%2F%202%7D%22%20y%3D%2218%22%20text-anchor%3D%22middle%22%20'%0A%20%20%20%20%20%20%20%20f'font-size%3D%2212%22%20fill%3D%22%23666%22%3ETrainer%20writes%20%7B_w%7D%20version%7B%22s%22%20if%20_w%20!%3D%201%20else%20%22%22%7D%20'%0A%20%20%20%20%20%20%20%20f'while%20generator%20reads%20from%20slot%200%3C%2Ftext%3E'%0A%20%20%20%20)%0A%0A%20%20%20%20_slot_y%20%3D%2050%0A%20%20%20%20for%20_i%20in%20range(_n)%3A%0A%20%20%20%20%20%20%20%20_x%20%3D%20_pad%20%2B%20_i%20*%20(_slot_w%20%2B%20_gap)%0A%0A%20%20%20%20%20%20%20%20%23%20Which%20trainer%20write%20steps%20land%20on%20this%20slot%3F%0A%20%20%20%20%20%20%20%20%23%20Trainer%20writes%20to%20slots%201%2C%202%2C%20...%2C%20wrapping%20around%0A%20%20%20%20%20%20%20%20_write_steps%20%3D%20%5Bj%20%2B%201%20for%20j%20in%20range(_w)%20if%20(1%20%2B%20j)%20%25%20_n%20%3D%3D%20_i%5D%0A%20%20%20%20%20%20%20%20_is_gen_read%20%3D%20(_i%20%3D%3D%200)%0A%20%20%20%20%20%20%20%20_is_written%20%3D%20len(_write_steps)%20%3E%200%0A%20%20%20%20%20%20%20%20_collision%20%3D%20_is_gen_read%20and%20_is_written%0A%0A%20%20%20%20%20%20%20%20%23%20Colors%0A%20%20%20%20%20%20%20%20if%20_collision%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_fill%2C%20_stroke%20%3D%20%22%23fecaca%22%2C%20%22%23dc2626%22%0A%20%20%20%20%20%20%20%20elif%20_is_gen_read%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_fill%2C%20_stroke%20%3D%20%22%23dbeafe%22%2C%20%22%232563eb%22%0A%20%20%20%20%20%20%20%20elif%20_is_written%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_fill%2C%20_stroke%20%3D%20%22%23dcfce7%22%2C%20%22%2316a34a%22%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_fill%2C%20_stroke%20%3D%20%22%23f3f4f6%22%2C%20%22%239ca3af%22%0A%0A%20%20%20%20%20%20%20%20%23%20Slot%20rectangle%0A%20%20%20%20%20%20%20%20_parts.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20f'%3Crect%20x%3D%22%7B_x%7D%22%20y%3D%22%7B_slot_y%7D%22%20width%3D%22%7B_slot_w%7D%22%20height%3D%22%7B_slot_h%7D%22%20rx%3D%225%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20f'fill%3D%22%7B_fill%7D%22%20stroke%3D%22%7B_stroke%7D%22%20stroke-width%3D%222%22%2F%3E'%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%23%20Slot%20label%0A%20%20%20%20%20%20%20%20_parts.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20f'%3Ctext%20x%3D%22%7B_x%20%2B%20_slot_w%20%2F%202%7D%22%20y%3D%22%7B_slot_y%20%2B%20_slot_h%20%2F%202%7D%22%20text-anchor%3D%22middle%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20f'dominant-baseline%3D%22central%22%20font-size%3D%2213%22%20font-weight%3D%22bold%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20f'fill%3D%22%7B_stroke%7D%22%3Eslot%20%7B_i%7D%3C%2Ftext%3E'%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%23%20Write%20step%20markers%20above%20slot%0A%20%20%20%20%20%20%20%20if%20_write_steps%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_step_label%20%3D%20%22%2C%22.join(str(s)%20for%20s%20in%20_write_steps)%0A%20%20%20%20%20%20%20%20%20%20%20%20_marker_color%20%3D%20%22%23dc2626%22%20if%20_collision%20else%20%22%2316a34a%22%0A%20%20%20%20%20%20%20%20%20%20%20%20_parts.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Ctext%20x%3D%22%7B_x%20%2B%20_slot_w%20%2F%202%7D%22%20y%3D%22%7B_slot_y%20-%208%7D%22%20text-anchor%3D%22middle%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'font-size%3D%2210%22%20fill%3D%22%7B_marker_color%7D%22%3Ewrite%20%23%7B_step_label%7D%3C%2Ftext%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%23%20Generator%20reading%20label%20below%20slot%200%0A%20%20%20%20%20%20%20%20if%20_is_gen_read%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_gen_label%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%E2%96%B2%20gen%20reading%20%E2%80%94%20OVERWRITTEN!%22%20if%20_collision%20else%20%22%E2%96%B2%20gen%20reading%22%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20_gen_color%20%3D%20%22%23dc2626%22%20if%20_collision%20else%20%22%232563eb%22%0A%20%20%20%20%20%20%20%20%20%20%20%20_gen_weight%20%3D%20%22bold%22%20if%20_collision%20else%20%22normal%22%0A%20%20%20%20%20%20%20%20%20%20%20%20_parts.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Ctext%20x%3D%22%7B_x%20%2B%20_slot_w%20%2F%202%7D%22%20y%3D%22%7B_slot_y%20%2B%20_slot_h%20%2B%2016%7D%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'text-anchor%3D%22middle%22%20font-size%3D%2210%22%20font-weight%3D%22%7B_gen_weight%7D%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'fill%3D%22%7B_gen_color%7D%22%3E%7B_gen_label%7D%3C%2Ftext%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20_parts.append(%22%3C%2Fsvg%3E%22)%0A%20%20%20%20_svg%20%3D%20%22%5Cn%22.join(_parts)%0A%0A%20%20%20%20if%20_safe%3A%0A%20%20%20%20%20%20%20%20_callout%20%3D%20mo.callout(mo.md(%0A%20%20%20%20%20%20%20%20%20%20%20%20f%22**Safe**%20%E2%80%94%20%7B_n%7D%20slots%2C%20%7B_w%7D%20trainer%20writes%20between%20generator%20reads.%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20f%22Generator%20finishes%20reading%20slot%200%20before%20trainer%20wraps%20around%20to%20overwrite%20it.%22%0A%20%20%20%20%20%20%20%20)%2C%20kind%3D%22success%22)%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20_callout%20%3D%20mo.callout(mo.md(%0A%20%20%20%20%20%20%20%20%20%20%20%20f%22**RACE%20CONDITION**%20%E2%80%94%20%7B_n%7D%20slots%2C%20%7B_w%7D%20trainer%20writes%20per%20generator%20read.%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20f%22Trainer%20wraps%20around%20and%20overwrites%20slot%200%20on%20write%20%23%7B_n%7D%20while%20generator%20is%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20f%22still%20reading%20it!%20Result%3A%20corrupted%20weights%20(silent%20data%20corruption%2C%20not%20an%20error).%5Cn%5Cn%22%0A%20%20%20%20%20%20%20%20%20%20%20%20f%22**Fix**%3A%20increase%20to%20at%20least%20**%7B_w%20%2B%201%7D%20slots**.%22%0A%20%20%20%20%20%20%20%20)%2C%20kind%3D%22danger%22)%0A%0A%20%20%20%20mo.vstack(%5Bmo.Html(_svg)%2C%20_callout%5D)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%207.%20Weight%20Re-sharding%0A%0A%20%20%20%20%23%23%23%20The%20Sharding%20Mismatch%20Problem%0A%0A%20%20%20%20Trainer%20and%20Generator%20often%20have%20**different%20tensor%20layouts**.%20Consider%20an%20example%3A%0A%0A%20%20%20%20%7C%20Role%20%7C%20Parallelism%20%7C%20Sharding%20%7C%0A%20%20%20%20%7C------%7C-------------%7C----------%7C%0A%20%20%20%20%7C%20Trainer%20%7C%20FSDP%20(8%20GPUs)%20%7C%20%60Shard(0)%60%20-%20rows%20split%20across%208%20GPUs%20%7C%0A%20%20%20%20%7C%20Generator%20%7C%20TP%20(2%20GPUs)%20%7C%20%60Shard(1)%60%20-%20columns%20split%20across%202%20GPUs%20%7C%0A%0A%20%20%20%20Therefore%20we%20cannot%20always%20directly%20transfer%20weights%20-%20we%20need%20**re-sharding**.%0A%0A%20%20%20%20Consider%20a%20simple%20example%20where%20the%20trainer%20may%20be%20row-sharded%20and%20the%20generator%20may%20be%20column-sharded%3A%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20Trainer%20(row-sharded)%3A%20%20%20%20%20%20%20%20%20%20Generator%20(column-sharded)%3A%0A%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%0A%20%20%20%20%E2%94%82%20GPU%200%3A%20rows%200-127%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20GPU%200%20%20%20%E2%94%82%20GPU%201%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%9C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%A4%20%20%20%20%20%E2%86%92%20%20%20%20%20%20%E2%94%82%20cols%20%20%20%20%E2%94%82%20cols%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20GPU%201%3A%20rows%20128%2B%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%200-511%20%20%20%E2%94%82%20512%2B%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%B4%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20%23%23%23%20Two%20Approaches%0A%0A%20%20%20%20**Gather%20Then%20Slice**%20(simple%20but%20wasteful)%3A%0A%20%20%20%20One%20approach%20is%20to%20materialize%20the%20entire%20tensor%2C%20i.e.%20%60gather%60%2C%20transfer%20the%20full%20tensor%2C%20and%20then%20slice%20on%20the%20receiver%20side%3A%0A%20%20%20%201.%20Each%20receiver%20gathers%20ALL%20sender%20shards%20%E2%86%92%20full%20tensor%0A%20%20%20%202.%20Each%20receiver%20slices%20out%20its%20portion%0A%20%20%20%203.%20**Problem**%3A%202x%20redundant%20data%20transfer%0A%0A%20%20%20%20**Routed%20Transfer**%20(optimal)%3A%0A%20%20%20%20A%20more%20efficient%20approach%20is%20to%20only%20transfer%20the%20data%20that%20needs%20to%20be%20transferred%3A%0A%20%20%20%201.%20Pre-compute%20which%20sender%20chunks%20overlap%20with%20which%20receiver%20regions%0A%20%20%20%202.%20Send%20only%20the%20exact%20chunks%20needed%0A%20%20%20%203.%20**Benefit**%3A%20Minimal%20bandwidth%2C%20no%20redundancy%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20GATHER%3A%20G0%20receives%20T0%2CT1%2CT2%2CT3%20%E2%86%92%20discards%20T2%2CT3%20(50%25%20waste!)%0A%20%20%20%20ROUTED%3A%20G0%20receives%20T0%2CT1%20only%20%E2%86%92%20exactly%20what%20it%20needs%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20The%20routed%20approach%20batches%20all%20needed%20transfers%20into%20one%20plan.%0A%20%20%20%20Pre-compute%20the%20plan%20once%20at%20handshake%2C%20execute%20it%20on%20each%20sync.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20from%20dataclasses%20import%20dataclass%0A%20%20%20%20from%20typing%20import%20List%2C%20Tuple%0A%0A%20%20%20%20%40dataclass%0A%20%20%20%20class%20ShardMetadata%3A%0A%20%20%20%20%20%20%20%20%22%22%22Metadata%20describing%20a%20tensor%20shard.%22%22%22%0A%20%20%20%20%20%20%20%20rank%3A%20int%0A%20%20%20%20%20%20%20%20global_shape%3A%20Tuple%5Bint%2C%20...%5D%0A%20%20%20%20%20%20%20%20offset%3A%20Tuple%5Bint%2C%20...%5D%20%20%23%20Start%20position%20in%20global%20tensor%0A%20%20%20%20%20%20%20%20local_shape%3A%20Tuple%5Bint%2C%20...%5D%20%20%23%20Shape%20of%20this%20shard%0A%0A%20%20%20%20%40dataclass%0A%20%20%20%20class%20TransferChunk%3A%0A%20%20%20%20%20%20%20%20%22%22%22A%20chunk%20to%20transfer%20from%20sender%20to%20receiver.%22%22%22%0A%20%20%20%20%20%20%20%20sender_rank%3A%20int%0A%20%20%20%20%20%20%20%20receiver_rank%3A%20int%0A%20%20%20%20%20%20%20%20sender_offset%3A%20Tuple%5Bint%2C%20int%5D%20%20%23%20Where%20to%20read%20from%20sender%0A%20%20%20%20%20%20%20%20receiver_offset%3A%20Tuple%5Bint%2C%20int%5D%20%20%23%20Where%20to%20write%20in%20receiver%0A%20%20%20%20%20%20%20%20shape%3A%20Tuple%5Bint%2C%20int%5D%20%20%23%20Shape%20of%20the%20chunk%0A%0A%20%20%20%20def%20compute_shard_metadata(%0A%20%20%20%20%20%20%20%20global_shape%3A%20Tuple%5Bint%2C%20int%5D%2C%0A%20%20%20%20%20%20%20%20num_ranks%3A%20int%2C%0A%20%20%20%20%20%20%20%20shard_dim%3A%20int%2C%0A%20%20%20%20)%20-%3E%20List%5BShardMetadata%5D%3A%0A%20%20%20%20%20%20%20%20%22%22%22Compute%20shard%20metadata%20for%20a%20given%20sharding.%22%22%22%0A%20%20%20%20%20%20%20%20shards%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20dim_size%20%3D%20global_shape%5Bshard_dim%5D%0A%20%20%20%20%20%20%20%20shard_size%20%3D%20dim_size%20%2F%2F%20num_ranks%0A%0A%20%20%20%20%20%20%20%20for%20rank%20in%20range(num_ranks)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20offset%20%3D%20%5B0%2C%200%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20local_shape%20%3D%20list(global_shape)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20offset%5Bshard_dim%5D%20%3D%20rank%20*%20shard_size%0A%20%20%20%20%20%20%20%20%20%20%20%20local_shape%5Bshard_dim%5D%20%3D%20shard_size%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20shards.append(ShardMetadata(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20rank%3Drank%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20global_shape%3Dglobal_shape%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20offset%3Dtuple(offset)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20local_shape%3Dtuple(local_shape)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20))%0A%0A%20%20%20%20%20%20%20%20return%20shards%0A%0A%20%20%20%20def%20compute_overlap(%0A%20%20%20%20%20%20%20%20sender%3A%20ShardMetadata%2C%0A%20%20%20%20%20%20%20%20receiver%3A%20ShardMetadata%2C%0A%20%20%20%20)%20-%3E%20%22TransferChunk%20%7C%20None%22%3A%0A%20%20%20%20%20%20%20%20%22%22%22Compute%20overlap%20between%20sender%20and%20receiver%20shards.%22%22%22%0A%20%20%20%20%20%20%20%20s_start%20%3D%20sender.offset%0A%20%20%20%20%20%20%20%20s_end%20%3D%20(s_start%5B0%5D%20%2B%20sender.local_shape%5B0%5D%2C%20s_start%5B1%5D%20%2B%20sender.local_shape%5B1%5D)%0A%0A%20%20%20%20%20%20%20%20r_start%20%3D%20receiver.offset%0A%20%20%20%20%20%20%20%20r_end%20%3D%20(r_start%5B0%5D%20%2B%20receiver.local_shape%5B0%5D%2C%20r_start%5B1%5D%20%2B%20receiver.local_shape%5B1%5D)%0A%0A%20%20%20%20%20%20%20%20inter_start%20%3D%20(max(s_start%5B0%5D%2C%20r_start%5B0%5D)%2C%20max(s_start%5B1%5D%2C%20r_start%5B1%5D))%0A%20%20%20%20%20%20%20%20inter_end%20%3D%20(min(s_end%5B0%5D%2C%20r_end%5B0%5D)%2C%20min(s_end%5B1%5D%2C%20r_end%5B1%5D))%0A%0A%20%20%20%20%20%20%20%20if%20inter_start%5B0%5D%20%3E%3D%20inter_end%5B0%5D%20or%20inter_start%5B1%5D%20%3E%3D%20inter_end%5B1%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20None%0A%0A%20%20%20%20%20%20%20%20shape%20%3D%20(inter_end%5B0%5D%20-%20inter_start%5B0%5D%2C%20inter_end%5B1%5D%20-%20inter_start%5B1%5D)%0A%0A%20%20%20%20%20%20%20%20sender_local%20%3D%20(inter_start%5B0%5D%20-%20s_start%5B0%5D%2C%20inter_start%5B1%5D%20-%20s_start%5B1%5D)%0A%20%20%20%20%20%20%20%20receiver_local%20%3D%20(inter_start%5B0%5D%20-%20r_start%5B0%5D%2C%20inter_start%5B1%5D%20-%20r_start%5B1%5D)%0A%0A%20%20%20%20%20%20%20%20return%20TransferChunk(%0A%20%20%20%20%20%20%20%20%20%20%20%20sender_rank%3Dsender.rank%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20receiver_rank%3Dreceiver.rank%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20sender_offset%3Dsender_local%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20receiver_offset%3Dreceiver_local%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20shape%3Dshape%2C%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20def%20compute_transfer_plan(%0A%20%20%20%20%20%20%20%20sender_shards%3A%20List%5BShardMetadata%5D%2C%0A%20%20%20%20%20%20%20%20receiver_shards%3A%20List%5BShardMetadata%5D%2C%0A%20%20%20%20)%20-%3E%20List%5BTransferChunk%5D%3A%0A%20%20%20%20%20%20%20%20%22%22%22Compute%20all%20transfers%20needed%20for%20re-sharding.%22%22%22%0A%20%20%20%20%20%20%20%20transfers%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20for%20sender%20in%20sender_shards%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20receiver%20in%20receiver_shards%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20chunk%20%3D%20compute_overlap(sender%2C%20receiver)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20chunk%20is%20not%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20transfers.append(chunk)%0A%20%20%20%20%20%20%20%20return%20transfers%0A%0A%20%20%20%20def%20render_resharding_svg(trainer_shards%2C%20gen_shards%2C%20transfer_plan%2C%20global_shape)%3A%0A%20%20%20%20%20%20%20%20%22%22%22Render%20a%20color-matched%20visualization%20of%20the%20re-sharding%20transfer%20plan.%0A%0A%20%20%20%20%20%20%20%20Returns%20HTML%20string%20with%3A%0A%20%20%20%20%20%20%20%20-%20Two%20grids%20(trainer%20left%2C%20generator%20right)%20where%20each%20transfer%20chunk%0A%20%20%20%20%20%20%20%20%20%20is%20colored%20the%20same%20on%20both%20sides%20so%20you%20can%20visually%20match%20them.%0A%20%20%20%20%20%20%20%20-%20A%20transfer%20matrix%20table%20below%20showing%20which%20chunks%20move%20where.%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20%20%20%20%20%23%20Layout%20constants%0A%20%20%20%20%20%20%20%20grid_w%2C%20grid_h%20%3D%20280%2C%20240%0A%20%20%20%20%20%20%20%20left_x%2C%20right_x%20%3D%2080%2C%20520%0A%20%20%20%20%20%20%20%20top_y%20%3D%2050%0A%20%20%20%20%20%20%20%20svg_w%20%3D%20880%0A%20%20%20%20%20%20%20%20rows%2C%20cols%20%3D%20global_shape%0A%0A%20%20%20%20%20%20%20%20%23%20Generate%20distinct%20colors%20for%20each%20transfer%0A%20%20%20%20%20%20%20%20%23%20Use%20HSL%20with%20evenly%20spaced%20hues%20for%20maximum%20distinction%0A%20%20%20%20%20%20%20%20n_transfers%20%3D%20len(transfer_plan)%0A%20%20%20%20%20%20%20%20transfer_colors%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20for%20i%20in%20range(max(n_transfers%2C%201))%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20hue%20%3D%20(i%20*%20360%20%2F%2F%20max(n_transfers%2C%201)%20%2B%2010)%20%25%20360%0A%20%20%20%20%20%20%20%20%20%20%20%20transfer_colors.append(f%22hsl(%7Bhue%7D%2C%2070%25%2C%2055%25)%22)%0A%0A%20%20%20%20%20%20%20%20%23%20Also%20need%20light%20shard%20background%20colors%20(just%20for%20shard%20boundaries)%0A%20%20%20%20%20%20%20%20shard_border_color%20%3D%20%22%23444%22%0A%0A%20%20%20%20%20%20%20%20parts%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20svg_h%20%3D%20top_y%20%2B%20grid_h%20%2B%2050%0A%20%20%20%20%20%20%20%20parts.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20f'%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22%7Bsvg_w%7D%22%20height%3D%22%7Bsvg_h%7D%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20f'viewBox%3D%220%200%20%7Bsvg_w%7D%20%7Bsvg_h%7D%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20f'style%3D%22font-family%3A%20-apple-system%2C%20sans-serif%3B%20font-size%3A%2012px%3B%22%3E'%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%23%20Title%20labels%0A%20%20%20%20%20%20%20%20parts.append(f'%3Ctext%20x%3D%22%7Bleft_x%20%2B%20grid_w%20%2F%2F%202%7D%22%20y%3D%2222%22%20text-anchor%3D%22middle%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'font-weight%3D%22bold%22%20font-size%3D%2215%22%3ETrainer%20shards%3C%2Ftext%3E')%0A%20%20%20%20%20%20%20%20parts.append(f'%3Ctext%20x%3D%22%7Bright_x%20%2B%20grid_w%20%2F%2F%202%7D%22%20y%3D%2222%22%20text-anchor%3D%22middle%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'font-weight%3D%22bold%22%20font-size%3D%2215%22%3EGenerator%20shards%3C%2Ftext%3E')%0A%0A%20%20%20%20%20%20%20%20%23%20Subtitle%20showing%20shard%20dim%0A%20%20%20%20%20%20%20%20t_dim%20%3D%20%22row%22%20if%20(trainer_shards%20and%20trainer_shards%5B0%5D.offset%20%3D%3D%20(0%2C%200)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20and%20len(trainer_shards)%20%3E%201%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20and%20trainer_shards%5B1%5D.offset%5B0%5D%20%3E%200)%20else%20%22col%22%0A%20%20%20%20%20%20%20%20g_dim%20%3D%20%22row%22%20if%20(gen_shards%20and%20gen_shards%5B0%5D.offset%20%3D%3D%20(0%2C%200)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20and%20len(gen_shards)%20%3E%201%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20and%20gen_shards%5B1%5D.offset%5B0%5D%20%3E%200)%20else%20%22col%22%0A%20%20%20%20%20%20%20%20parts.append(f'%3Ctext%20x%3D%22%7Bleft_x%20%2B%20grid_w%20%2F%2F%202%7D%22%20y%3D%2238%22%20text-anchor%3D%22middle%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'font-size%3D%2211%22%20fill%3D%22%23666%22%3E%7Blen(trainer_shards)%7D%20GPUs%2C%20%7Bt_dim%7D-sharded%3C%2Ftext%3E')%0A%20%20%20%20%20%20%20%20parts.append(f'%3Ctext%20x%3D%22%7Bright_x%20%2B%20grid_w%20%2F%2F%202%7D%22%20y%3D%2238%22%20text-anchor%3D%22middle%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'font-size%3D%2211%22%20fill%3D%22%23666%22%3E%7Blen(gen_shards)%7D%20GPUs%2C%20%7Bg_dim%7D-sharded%3C%2Ftext%3E')%0A%0A%20%20%20%20%20%20%20%20%23%20Helper%3A%20map%20global%20(row%2C%20col%2C%20h%2C%20w)%20to%20pixel%20rect%0A%20%20%20%20%20%20%20%20def%20to_px(base_x%2C%20r%2C%20c%2C%20h%2C%20w)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20px%20%3D%20base_x%20%2B%20(c%20%2F%20cols)%20*%20grid_w%0A%20%20%20%20%20%20%20%20%20%20%20%20py%20%3D%20top_y%20%2B%20(r%20%2F%20rows)%20*%20grid_h%0A%20%20%20%20%20%20%20%20%20%20%20%20pw%20%3D%20(w%20%2F%20cols)%20*%20grid_w%0A%20%20%20%20%20%20%20%20%20%20%20%20ph%20%3D%20(h%20%2F%20rows)%20*%20grid_h%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20px%2C%20py%2C%20pw%2C%20ph%0A%0A%20%20%20%20%20%20%20%20%23%20Draw%20transfer%20chunks%20as%20colored%20rectangles%20on%20BOTH%20grids%0A%20%20%20%20%20%20%20%20for%20i%2C%20t%20in%20enumerate(transfer_plan)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20color%20%3D%20transfer_colors%5Bi%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Find%20sender%2Freceiver%20shard%20global%20offsets%0A%20%20%20%20%20%20%20%20%20%20%20%20s_shard%20%3D%20next(s%20for%20s%20in%20trainer_shards%20if%20s.rank%20%3D%3D%20t.sender_rank)%0A%20%20%20%20%20%20%20%20%20%20%20%20r_shard%20%3D%20next(s%20for%20s%20in%20gen_shards%20if%20s.rank%20%3D%3D%20t.receiver_rank)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Trainer%20side%3A%20chunk%20in%20global%20coords%0A%20%20%20%20%20%20%20%20%20%20%20%20s_row%20%3D%20s_shard.offset%5B0%5D%20%2B%20t.sender_offset%5B0%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20s_col%20%3D%20s_shard.offset%5B1%5D%20%2B%20t.sender_offset%5B1%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20px%2C%20py%2C%20pw%2C%20ph%20%3D%20to_px(left_x%2C%20s_row%2C%20s_col%2C%20t.shape%5B0%5D%2C%20t.shape%5B1%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20parts.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Crect%20x%3D%22%7Bpx%3A.1f%7D%22%20y%3D%22%7Bpy%3A.1f%7D%22%20width%3D%22%7Bpw%3A.1f%7D%22%20height%3D%22%7Bph%3A.1f%7D%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'fill%3D%22%7Bcolor%7D%22%20fill-opacity%3D%220.55%22%20stroke%3D%22%7Bcolor%7D%22%20stroke-width%3D%220.5%22%2F%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Generator%20side%3A%20chunk%20in%20global%20coords%0A%20%20%20%20%20%20%20%20%20%20%20%20r_row%20%3D%20r_shard.offset%5B0%5D%20%2B%20t.receiver_offset%5B0%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20r_col%20%3D%20r_shard.offset%5B1%5D%20%2B%20t.receiver_offset%5B1%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20px%2C%20py%2C%20pw%2C%20ph%20%3D%20to_px(right_x%2C%20r_row%2C%20r_col%2C%20t.shape%5B0%5D%2C%20t.shape%5B1%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20parts.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Crect%20x%3D%22%7Bpx%3A.1f%7D%22%20y%3D%22%7Bpy%3A.1f%7D%22%20width%3D%22%7Bpw%3A.1f%7D%22%20height%3D%22%7Bph%3A.1f%7D%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'fill%3D%22%7Bcolor%7D%22%20fill-opacity%3D%220.55%22%20stroke%3D%22%7Bcolor%7D%22%20stroke-width%3D%220.5%22%2F%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%23%20Draw%20shard%20boundary%20outlines%20and%20rank%20labels%20on%20top%0A%20%20%20%20%20%20%20%20def%20draw_shard_outlines(shards%2C%20base_x%2C%20prefix)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20s%20in%20shards%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%20%3D%20base_x%20%2B%20(s.offset%5B1%5D%20%2F%20cols)%20*%20grid_w%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20y%20%3D%20top_y%20%2B%20(s.offset%5B0%5D%20%2F%20rows)%20*%20grid_h%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20w%20%3D%20(s.local_shape%5B1%5D%20%2F%20cols)%20*%20grid_w%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20h%20%3D%20(s.local_shape%5B0%5D%20%2F%20rows)%20*%20grid_h%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20parts.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Crect%20x%3D%22%7Bx%3A.1f%7D%22%20y%3D%22%7By%3A.1f%7D%22%20width%3D%22%7Bw%3A.1f%7D%22%20height%3D%22%7Bh%3A.1f%7D%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'fill%3D%22none%22%20stroke%3D%22%7Bshard_border_color%7D%22%20stroke-width%3D%222%22%2F%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20Rank%20label%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cx%2C%20cy%20%3D%20x%20%2B%20w%20%2F%202%2C%20y%20%2B%20h%20%2F%202%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20parts.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Ctext%20x%3D%22%7Bcx%3A.1f%7D%22%20y%3D%22%7Bcy%3A.1f%7D%22%20text-anchor%3D%22middle%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'dominant-baseline%3D%22central%22%20font-weight%3D%22bold%22%20font-size%3D%2213%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'fill%3D%22%23222%22%3E%7Bprefix%7D%7Bs.rank%7D%3C%2Ftext%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20draw_shard_outlines(trainer_shards%2C%20left_x%2C%20%22T%22)%0A%20%20%20%20%20%20%20%20draw_shard_outlines(gen_shards%2C%20right_x%2C%20%22G%22)%0A%0A%20%20%20%20%20%20%20%20%23%20Outer%20boxes%0A%20%20%20%20%20%20%20%20parts.append(f'%3Crect%20x%3D%22%7Bleft_x%7D%22%20y%3D%22%7Btop_y%7D%22%20width%3D%22%7Bgrid_w%7D%22%20height%3D%22%7Bgrid_h%7D%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'fill%3D%22none%22%20stroke%3D%22%23222%22%20stroke-width%3D%222.5%22%2F%3E')%0A%20%20%20%20%20%20%20%20parts.append(f'%3Crect%20x%3D%22%7Bright_x%7D%22%20y%3D%22%7Btop_y%7D%22%20width%3D%22%7Bgrid_w%7D%22%20height%3D%22%7Bgrid_h%7D%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'fill%3D%22none%22%20stroke%3D%22%23222%22%20stroke-width%3D%222.5%22%2F%3E')%0A%0A%20%20%20%20%20%20%20%20%23%20%22%3D%22%20sign%20between%20grids%20to%20show%20equivalence%0A%20%20%20%20%20%20%20%20mid_x%20%3D%20(left_x%20%2B%20grid_w%20%2B%20right_x)%20%2F%2F%202%0A%20%20%20%20%20%20%20%20mid_y%20%3D%20top_y%20%2B%20grid_h%20%2F%2F%202%0A%20%20%20%20%20%20%20%20parts.append(f'%3Ctext%20x%3D%22%7Bmid_x%7D%22%20y%3D%22%7Bmid_y%7D%22%20text-anchor%3D%22middle%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'dominant-baseline%3D%22central%22%20font-size%3D%2228%22%20fill%3D%22%23888%22%3E%3D%3C%2Ftext%3E')%0A%20%20%20%20%20%20%20%20parts.append(f'%3Ctext%20x%3D%22%7Bmid_x%7D%22%20y%3D%22%7Bmid_y%20%2B%2022%7D%22%20text-anchor%3D%22middle%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'font-size%3D%2210%22%20fill%3D%22%23888%22%3Esame%20data%3C%2Ftext%3E')%0A%0A%20%20%20%20%20%20%20%20%23%20Global%20shape%20label%0A%20%20%20%20%20%20%20%20parts.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20f'%3Ctext%20x%3D%22%7Bsvg_w%20%2F%2F%202%7D%22%20y%3D%22%7Bsvg_h%20-%208%7D%22%20text-anchor%3D%22middle%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20f'font-size%3D%2211%22%20fill%3D%22%23888%22%3EGlobal%20tensor%3A%20%7Brows%7D%20x%20%7Bcols%7D%3C%2Ftext%3E'%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20parts.append(%22%3C%2Fsvg%3E%22)%0A%20%20%20%20%20%20%20%20svg_str%20%3D%20%22%5Cn%22.join(parts)%0A%0A%20%20%20%20%20%20%20%20%23%20Build%20transfer%20matrix%20HTML%20table%0A%20%20%20%20%20%20%20%20n_trainers%20%3D%20len(trainer_shards)%0A%20%20%20%20%20%20%20%20n_gens%20%3D%20len(gen_shards)%0A%0A%20%20%20%20%20%20%20%20%23%20Build%20lookup%3A%20(sender_rank%2C%20receiver_rank)%20-%3E%20(transfer_index%2C%20chunk)%0A%20%20%20%20%20%20%20%20transfer_lookup%20%3D%20%7B%7D%0A%20%20%20%20%20%20%20%20for%20i%2C%20t%20in%20enumerate(transfer_plan)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20transfer_lookup%5B(t.sender_rank%2C%20t.receiver_rank)%5D%20%3D%20(i%2C%20t)%0A%0A%20%20%20%20%20%20%20%20table_parts%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20'%3Ctable%20style%3D%22border-collapse%3A%20collapse%3B%20margin-top%3A%2012px%3B%20font-family%3A%20monospace%3B%20font-size%3A%2012px%3B%22%3E'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20'%3Ctr%3E%3Cth%20style%3D%22border%3A%201px%20solid%20%23ccc%3B%20padding%3A%206px%2010px%3B%20background%3A%20%23f5f5f5%3B%22%3E%3C%2Fth%3E'%2C%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20for%20g%20in%20range(n_gens)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20table_parts.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Cth%20style%3D%22border%3A%201px%20solid%20%23ccc%3B%20padding%3A%206px%2010px%3B%20background%3A%20%23f5f5f5%3B%22%3EG%7Bg%7D%3C%2Fth%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20table_parts.append('%3C%2Ftr%3E')%0A%0A%20%20%20%20%20%20%20%20for%20t_rank%20in%20range(n_trainers)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20table_parts.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Ctr%3E%3Ctd%20style%3D%22border%3A%201px%20solid%20%23ccc%3B%20padding%3A%206px%2010px%3B%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'background%3A%20%23f5f5f5%3B%20font-weight%3A%20bold%3B%22%3ET%7Bt_rank%7D%3C%2Ftd%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20g_rank%20in%20range(n_gens)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20key%20%3D%20(t_rank%2C%20g_rank)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20key%20in%20transfer_lookup%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20idx%2C%20chunk%20%3D%20transfer_lookup%5Bkey%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color%20%3D%20transfer_colors%5Bidx%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20table_parts.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Ctd%20style%3D%22border%3A%201px%20solid%20%23ccc%3B%20padding%3A%206px%2010px%3B%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'background%3A%20%7Bcolor%7D%3B%20color%3A%20white%3B%20text-align%3A%20center%3B%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'font-weight%3A%20bold%3B%20text-shadow%3A%200%201px%202px%20rgba(0%2C0%2C0%2C0.4)%3B%22%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%7Bchunk.shape%5B0%5D%7Dx%7Bchunk.shape%5B1%5D%7D%3C%2Ftd%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20table_parts.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'%3Ctd%20style%3D%22border%3A%201px%20solid%20%23ccc%3B%20padding%3A%206px%2010px%3B%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'text-align%3A%20center%3B%20color%3A%20%23ccc%3B%22%3E%26mdash%3B%3C%2Ftd%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20table_parts.append('%3C%2Ftr%3E')%0A%0A%20%20%20%20%20%20%20%20table_parts.append('%3C%2Ftable%3E')%0A%20%20%20%20%20%20%20%20table_str%20%3D%20%22%5Cn%22.join(table_parts)%0A%0A%20%20%20%20%20%20%20%20%23%20Combine%20SVG%20%2B%20table%0A%20%20%20%20%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20f'%3Cdiv%20style%3D%22display%3A%20flex%3B%20flex-direction%3A%20column%3B%20align-items%3A%20center%3B%22%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20f'%7Bsvg_str%7D'%0A%20%20%20%20%20%20%20%20%20%20%20%20f'%3Cdiv%20style%3D%22margin-top%3A%204px%3B%20font-size%3A%2012px%3B%20color%3A%20%23666%3B%22%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20f'Matching%20colors%20%3D%20same%20data%20chunk.%20Matrix%20shows%20chunk%20shapes%20transferred.%3C%2Fdiv%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20f'%7Btable_str%7D'%0A%20%20%20%20%20%20%20%20%20%20%20%20f'%3C%2Fdiv%3E'%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20return%20compute_shard_metadata%2C%20compute_transfer_plan%2C%20render_resharding_svg%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20%23%20Interactive%20controls%20for%20re-sharding%20visualization%0A%20%20%20%20trainer_gpu_slider%20%3D%20mo.ui.slider(1%2C%208%2C%20value%3D4%2C%20label%3D%22Trainer%20GPUs%22)%0A%20%20%20%20gen_gpu_slider%20%3D%20mo.ui.slider(1%2C%208%2C%20value%3D2%2C%20label%3D%22Generator%20GPUs%22)%0A%20%20%20%20trainer_dim_dropdown%20%3D%20mo.ui.dropdown(%0A%20%20%20%20%20%20%20%20options%3D%7B%22Row%20(dim%200)%22%3A%200%2C%20%22Col%20(dim%201)%22%3A%201%7D%2C%0A%20%20%20%20%20%20%20%20value%3D%22Row%20(dim%200)%22%2C%0A%20%20%20%20%20%20%20%20label%3D%22Trainer%20shard%20dim%22%2C%0A%20%20%20%20)%0A%20%20%20%20gen_dim_dropdown%20%3D%20mo.ui.dropdown(%0A%20%20%20%20%20%20%20%20options%3D%7B%22Row%20(dim%200)%22%3A%200%2C%20%22Col%20(dim%201)%22%3A%201%7D%2C%0A%20%20%20%20%20%20%20%20value%3D%22Col%20(dim%201)%22%2C%0A%20%20%20%20%20%20%20%20label%3D%22Generator%20shard%20dim%22%2C%0A%20%20%20%20)%0A%0A%20%20%20%20mo.hstack(%0A%20%20%20%20%20%20%20%20%5Btrainer_gpu_slider%2C%20trainer_dim_dropdown%2C%20gen_gpu_slider%2C%20gen_dim_dropdown%5D%2C%0A%20%20%20%20%20%20%20%20justify%3D%22center%22%2C%0A%20%20%20%20%20%20%20%20gap%3D1%2C%0A%20%20%20%20)%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20gen_dim_dropdown%2C%0A%20%20%20%20%20%20%20%20gen_gpu_slider%2C%0A%20%20%20%20%20%20%20%20trainer_dim_dropdown%2C%0A%20%20%20%20%20%20%20%20trainer_gpu_slider%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20compute_shard_metadata%2C%0A%20%20%20%20compute_transfer_plan%2C%0A%20%20%20%20gen_dim_dropdown%2C%0A%20%20%20%20gen_gpu_slider%2C%0A%20%20%20%20mo%2C%0A%20%20%20%20render_resharding_svg%2C%0A%20%20%20%20trainer_dim_dropdown%2C%0A%20%20%20%20trainer_gpu_slider%2C%0A)%3A%0A%20%20%20%20%23%20Compute%20shards%20and%20transfer%20plan%20based%20on%20widget%20values%0A%20%20%20%20_global_shape%20%3D%20(512%2C%20512)%0A%20%20%20%20_t_shards%20%3D%20compute_shard_metadata(_global_shape%2C%20trainer_gpu_slider.value%2C%20trainer_dim_dropdown.value)%0A%20%20%20%20_g_shards%20%3D%20compute_shard_metadata(_global_shape%2C%20gen_gpu_slider.value%2C%20gen_dim_dropdown.value)%0A%20%20%20%20_plan%20%3D%20compute_transfer_plan(_t_shards%2C%20_g_shards)%0A%0A%20%20%20%20_svg%20%3D%20render_resharding_svg(_t_shards%2C%20_g_shards%2C%20_plan%2C%20_global_shape)%0A%0A%20%20%20%20%23%20Compute%20stats%20for%20the%20callout%0A%20%20%20%20_routed_bytes%20%3D%20sum(t.shape%5B0%5D%20*%20t.shape%5B1%5D%20*%202%20for%20t%20in%20_plan)%20%20%23%20bf16%20%3D%202%20bytes%0A%20%20%20%20_gather_bytes%20%3D%20_global_shape%5B0%5D%20*%20_global_shape%5B1%5D%20*%202%20*%20gen_gpu_slider.value%0A%20%20%20%20_waste_pct%20%3D%20(1%20-%20_routed_bytes%20%2F%20_gather_bytes)%20*%20100%20if%20_gather_bytes%20%3E%200%20else%200%0A%0A%20%20%20%20resharding_stats%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%22transfers%22%3A%20len(_plan)%2C%0A%20%20%20%20%20%20%20%20%22routed_bytes%22%3A%20_routed_bytes%2C%0A%20%20%20%20%20%20%20%20%22gather_bytes%22%3A%20_gather_bytes%2C%0A%20%20%20%20%20%20%20%20%22waste_pct%22%3A%20_waste_pct%2C%0A%20%20%20%20%7D%0A%0A%20%20%20%20_stats_md%20%3D%20mo.md(f%22%22%22%0A%20%20%20%20**Transfer%20Plan%20Stats**%20%7C%20**Transfers**%3A%20%7Blen(_plan)%7D%20chunks%20%7C%20**Routed**%3A%20%7B_routed_bytes%20%2F%201024%3A.1f%7D%20KB%20%7C%20**Gather**%3A%20%7B_gather_bytes%20%2F%201024%3A.1f%7D%20KB%20%7C%20**Saved**%3A%20%7B_waste_pct%3A.0f%7D%25%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20mo.vstack(%5Bmo.Html(_svg)%2C%20mo.callout(_stats_md%2C%20kind%3D%22info%22)%5D)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%208.%20Putting%20It%20All%20Together%0A%0A%20%20%20%20The%20full%20async%20RL%20weight%20sync%20pattern%3A%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20TRAINER%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%201.%20Train%20step%20completes%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%202.%20Copy%20weights%20to%20CPU%20staging%20buffer%20(non-blocking%20D2H)%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%203.%20Publish%20to%20circular%20buffer%20with%20version%20tag%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%204.%20Continue%20training%20(no%20blocking!)%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%96%BC%0A%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20CIRCULAR%20BUFFER%20(CPU%2C%20RDMA-registered)%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%5Bslot%200%3A%20v3%5D%20%5Bslot%201%3A%20v4%5D%20%5Bslot%202%3A%20v5%5D%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%86%91%20latest%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%BC%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%96%BC%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%96%BC%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%96%BC%0A%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%0A%20%20%20%20%E2%94%82%20%20%20GENERATOR%200%20%20%20%E2%94%82%20%20%20%E2%94%82%20%20%20GENERATOR%201%20%20%20%E2%94%82%20%20%20%E2%94%82%20%20%20GENERATOR%202%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20After%20gen%20done%3A%20%E2%94%82%20%20%20%E2%94%82%20After%20gen%20done%3A%20%E2%94%82%20%20%20%E2%94%82%20After%20gen%20done%3A%20%E2%94%82%0A%20%20%20%20%E2%94%82%201.%20Get%20latest%20%20%20%E2%94%82%20%20%20%E2%94%82%201.%20Get%20latest%20%20%20%E2%94%82%20%20%20%E2%94%82%201.%20Get%20latest%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20version%20%20%20%20%20%20%E2%94%82%20%20%20%E2%94%82%20%20%20%20version%20%20%20%20%20%20%E2%94%82%20%20%20%E2%94%82%20%20%20%20version%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%202.%20RDMA%20read%20%20%20%20%E2%94%82%20%20%20%E2%94%82%202.%20RDMA%20read%20%20%20%20%E2%94%82%20%20%20%E2%94%82%202.%20RDMA%20read%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20%E2%86%92%20GPU%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%E2%94%82%20%20%20%20%E2%86%92%20GPU%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%E2%94%82%20%20%20%20%E2%86%92%20GPU%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%203.%20Re-shard%20if%20%20%E2%94%82%20%20%20%E2%94%82%203.%20Re-shard%20if%20%20%E2%94%82%20%20%20%E2%94%82%203.%20Re-shard%20if%20%20%E2%94%82%0A%20%20%20%20%E2%94%82%20%20%20%20needed%20%20%20%20%20%20%20%E2%94%82%20%20%20%E2%94%82%20%20%20%20needed%20%20%20%20%20%20%20%E2%94%82%20%20%20%E2%94%82%20%20%20%20needed%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20**Key%20properties%3A**%0A%20%20%20%20-%20Trainer%20never%20blocks%20waiting%20for%20generators%0A%20%20%20%20-%20Generators%20pull%20directly%20to%20GPU%20when%20*they're*%20ready%0A%20%20%20%20-%20Re-sharding%20happens%20locally%20on%20each%20generator%0A%20%20%20%20-%20Circular%20buffer%20bounds%20memory%2C%20reuses%20RDMA%20registrations%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20Live%20Demo%3A%20Async%20Weight%20Sync%0A%0A%20%20%20%20Let's%20see%20this%20in%20action!%20We'll%20simulate%20the%20core%20async%20RL%20pattern%3A%0A%0A%20%20%20%20-%20**1%20Trainer**%3A%20Runs%20training%20steps%2C%20publishes%20new%20weights%20to%20a%203-slot%20circular%20buffer%0A%20%20%20%20-%20**4%20Generators**%3A%20Each%20independently%20syncs%20to%20latest%20weights%2C%20then%20generates%0A%0A%20%20%20%20All%205%20actors%20run%20**concurrently%20and%20independently**.%20The%20trainer%20never%20waits%20for%20generators%2C%0A%20%20%20%20and%20each%20generator%20grabs%20weights%20whenever%20it's%20ready%20(at%20slightly%20different%20rates%20to%20show%0A%20%20%20%20the%20async%20behavior).%20To%20verify%20correctness%2C%20we%20set%20weights%20to%20%60version%60%20and%20check%20on%20read.%0A%0A%20%20%20%20**Race%20condition%20safety**%3A%20The%20circular%20buffer's%20slot%20count%20is%20tuned%20so%20that%0A%20%20%20%20%60buffer_size%20%C3%97%20update_interval%20%3E%3E%20sync_time%60.%20This%20ensures%20a%20slot%20isn't%20overwritten%0A%20%20%20%20while%20a%20generator%20is%20reading%20it.%20In%20this%20demo%3A%205%20slots%2C%20~1s%20between%20trainer%20updates%2C%0A%20%20%20%20RDMA%20sync%20takes%20~ms%2C%20so%20a%20race%20is%20effectively%20impossible.%20In%20production%2C%20tune%0A%20%20%20%20%60buffer_size%60%20based%20on%20actual%20sync%20time%20and%20update%20frequency.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20Actor%2C%0A%20%20%20%20RDMABuffer%2C%0A%20%20%20%20current_rank%2C%0A%20%20%20%20endpoint%2C%0A%20%20%20%20is_rdma_available%2C%0A%20%20%20%20this_host%2C%0A%20%20%20%20torch%2C%0A)%3A%0A%20%20%20%20import%20threading%0A%0A%20%20%20%20def%20show_fallback()%3A%0A%20%20%20%20%20%20%20%20print(%22(RDMA%20not%20available%20-%20showing%20conceptual%20flow)%5Cn%22)%0A%20%20%20%20%20%20%20%20print(%22What%20would%20happen%20with%20RDMA%3A%22)%0A%20%20%20%20%20%20%20%20print(%22%20%20%5BTrainer%5D%20Publishes%20v0%2C%20v1%2C%20v2...%20to%20circular%20buffer%22)%0A%20%20%20%20%20%20%20%20print(%22%20%20%5BGenerator%5D%20Syncs%20when%20ready%2C%20verifies%20weights%20match%20version%22)%0A%20%20%20%20%20%20%20%20print(%22%20%20Both%20run%20independently%2C%20no%20blocking!%22)%0A%0A%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20if%20not%20is_rdma_available()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20show_fallback()%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20class%20Trainer(Actor)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Trainer%20with%20circular%20buffer%20for%20weight%20versioning.%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20def%20__init__(self%2C%20weight_size%3A%20int)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.n_slots%20%3D%205%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.version%20%3D%200%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.slots%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.handles%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20_%20in%20range(self.n_slots)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20slot%20%3D%20torch.zeros(weight_size%2C%20dtype%3Dtorch.float32)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.slots.append(slot)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.handles.append(RDMABuffer(slot.view(torch.uint8).flatten()))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%5BTrainer%5D%20Initialized%20%7Bself.n_slots%7D-slot%20circular%20buffer%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%40endpoint%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20def%20get_latest(self)%20-%3E%20tuple%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20self.version%20%3D%3D%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20None%2C%20-1%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v%20%3D%20self.version%20-%201%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20self.handles%5Bv%20%25%20self.n_slots%5D%2C%20v%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%40endpoint%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20def%20train_step(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Single%20training%20step%3A%20publish%20new%20weights.%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20import%20sys%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20slot_idx%20%3D%20self.version%20%25%20self.n_slots%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.slots%5Bslot_idx%5D.fill_(float(self.version))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.version%20%2B%3D%201%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%5BTrainer%5D%20Published%20v%7Bself.version%20-%201%7D%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sys.stdout.flush()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20self.version%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20class%20Generator(Actor)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Generator%20that%20syncs%20weights%20and%20generates.%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20def%20__init__(self%2C%20weight_size%3A%20int%2C%20trainer)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.gen_id%20%3D%20current_rank().rank%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.trainer%20%3D%20trainer%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.weights%20%3D%20torch.zeros(weight_size%2C%20dtype%3Dtorch.float32)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.weight_bytes%20%3D%20self.weights.view(torch.uint8).flatten()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.current_version%20%3D%20-1%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%5BGen%20%7Bself.gen_id%7D%5D%20Initialized%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%40endpoint%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20def%20generate_step(self)%20-%3E%20int%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Single%20generate%20step%3A%20sync%20if%20needed%2C%20then%20generate.%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20import%20sys%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20Try%20to%20sync%20weights%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20handle%2C%20version%20%3D%20self.trainer.get_latest.call_one().get()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20handle%20is%20not%20None%20and%20version%20%3E%20self.current_version%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20handle.read_into(self.weight_bytes).get()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20actual%20%3D%20int(self.weights%5B0%5D.item())%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20actual%20%3E%3D%20version%3A%20%20%23%20%3E%3D%20not%20%3D%3D%20%3A%20a%20later%20version%20may%20have%20written%20to%20same%20slot%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.current_version%20%3D%20actual%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%5BGen%20%7Bself.gen_id%7D%5D%20Synced%20to%20v%7Bactual%7D%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sys.stdout.flush()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20self.current_version%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Spawn%20trainer%20and%20generators%0A%20%20%20%20%20%20%20%20%20%20%20%20n_generators%20%3D%204%0A%20%20%20%20%20%20%20%20%20%20%20%20trainer_proc%20%3D%20this_host().spawn_procs(per_host%3D%7B%22procs%22%3A%201%7D)%0A%20%20%20%20%20%20%20%20%20%20%20%20generator_procs%20%3D%20this_host().spawn_procs(per_host%3D%7B%22procs%22%3A%20n_generators%7D)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20trainer%20%3D%20trainer_proc.spawn(%22trainer%22%2C%20Trainer%2C%20weight_size%3D1024)%0A%20%20%20%20%20%20%20%20%20%20%20%20generators%20%3D%20generator_procs.spawn(%22generators%22%2C%20Generator%2C%20weight_size%3D1024%2C%20trainer%3Dtrainer)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22%5Cn---%20Running%20async%20RL%20simulation%20---%5Cn%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Results%20storage%0A%20%20%20%20%20%20%20%20%20%20%20%20_results%20%3D%20%7B%22trainer%22%3A%20None%2C%20%22generators%22%3A%20%5BNone%5D%20*%20n_generators%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20def%20run_trainer(n_steps%2C%20step_time)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20import%20time%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20_%20in%20range(n_steps)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20time.sleep(step_time)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20_results%5B%22trainer%22%5D%20%3D%20trainer.train_step.call_one().get()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20def%20run_generator(gen_actor%2C%20gen_idx%2C%20n_iters%2C%20gen_time)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20import%20time%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20_%20in%20range(n_iters)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20version%20%3D%20gen_actor.generate_step.call_one().get()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20version%20%3E%3D%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20time.sleep(gen_time)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%5BGen%20%7Bgen_idx%7D%5D%20Generated%20(v%7Bversion%7D)%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20time.sleep(0.05)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20_results%5B%22generators%22%5D%5Bgen_idx%5D%20%3D%20version%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Create%20threads%20for%20trainer%20and%20each%20generator%0A%20%20%20%20%20%20%20%20%20%20%20%20threads%20%3D%20%5B%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Trainer%20thread%0A%20%20%20%20%20%20%20%20%20%20%20%20t%20%3D%20threading.Thread(target%3Drun_trainer%2C%20args%3D(6%2C%201.0))%20%20%23%201%20second%20per%20step%0A%20%20%20%20%20%20%20%20%20%20%20%20threads.append(t)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Generator%20threads%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20i%20in%20range(n_generators)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20gen_actor%20%3D%20generators.slice(procs%3Di)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20t%20%3D%20threading.Thread(target%3Drun_generator%2C%20args%3D(gen_actor%2C%20i%2C%205%2C%200.25))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20threads.append(t)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Start%20all%20threads%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20t%20in%20threads%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20t.start()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Wait%20for%20all%20to%20complete%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20t%20in%20threads%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20t.join()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%5Cn---%20Done!%20Trainer%20published%20%7B_results%5B'trainer'%5D%7D%20versions%20---%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20print(f%22Generators%20ended%20on%20versions%3A%20%7B_results%5B'generators'%5D%7D%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22All%20pulled%20independently%20via%20RDMA%2C%20weights%20verified!%22)%0A%0A%20%20%20%20except%20Exception%20as%20e%3A%0A%20%20%20%20%20%20%20%20import%20traceback%0A%20%20%20%20%20%20%20%20traceback.print_exc()%0A%20%20%20%20%20%20%20%20print(f%22(Demo%20failed%3A%20%7Be%7D)%22)%0A%20%20%20%20%20%20%20%20show_fallback()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%209.%20Going%20Further%3A%20TorchStore%0A%0A%20%20%20%20All%20the%20patterns%20we've%20covered%20-%20RDMA%20memory%20registration%2C%20magic%20pointers%2C%20circular%20buffers%2C%0A%20%20%20%20pre-computed%20transfer%20plans%20-%20are%20building%20blocks.%20If%20you%20need%20a%20**production-ready%20solution**%2C%0A%20%20%20%20check%20out%20%5BTorchStore%5D(https%3A%2F%2Fgithub.com%2Fmeta-pytorch%2Ftorchstore).%0A%0A%20%20%20%20%23%23%23%20What%20is%20TorchStore%3F%0A%0A%20%20%20%20TorchStore%20is%20a%20**distributed%2C%20asynchronous%20key-value%20store%20for%20PyTorch%20tensors**%20built%20on%0A%20%20%20%20Monarch's%20actor%20framework.%20It%20abstracts%20away%20the%20RDMA%20complexity%20while%20giving%20you%3A%0A%0A%20%20%20%20%60%60%60python%0A%20%20%20%20from%20torchstore%20import%20TorchStore%0A%0A%20%20%20%20%23%20Store%20tensors%20with%20async%20API%0A%20%20%20%20await%20ts.put(%22model%2Flayer1%2Fweights%22%2C%20tensor)%0A%0A%20%20%20%20%23%20Retrieve%20with%20optional%20in-place%20and%20slice%20semantics%0A%20%20%20%20await%20ts.get(%22model%2Flayer1%2Fweights%22%2C%20inplace_tensor%3Dbuffer)%0A%0A%20%20%20%20%23%20Native%20PyTorch%20checkpoint%20support%0A%20%20%20%20await%20ts.put_state_dict(model.state_dict())%0A%20%20%20%20loaded%20%3D%20await%20ts.get_state_dict()%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20%23%23%23%20When%20to%20Use%20What%0A%0A%20%20%20%20%7C%20Scenario%20%7C%20Solution%20%7C%0A%20%20%20%20%7C----------%7C----------%7C%0A%20%20%20%20%7C%20Learning%20RDMA%20patterns%20%7C%20This%20notebook%20%2B%2006b%20%7C%0A%20%20%20%20%7C%20Custom%20RL%20weight%20sync%20%7C%20See%2006b%20for%20%60RDMABuffer%60%20%2B%20%60RDMAAction%60%20patterns%20%7C%0A%20%20%20%20%7C%20General%20tensor%20storage%20%7C%20Use%20TorchStore%20%7C%0A%20%20%20%20%7C%20Checkpointing%20%7C%20Use%20TorchStore's%20%60put_state_dict%60%20%7C%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Summary%0A%0A%20%20%20%20%23%23%23%20Key%20Takeaways%0A%0A%20%20%20%201.%20**Bandwidth%20hierarchy%20matters**%3A%20NVLink%20(900%20GB%2Fs)%20%3E%3E%20InfiniBand%20(50%20GB%2Fs)%0A%20%20%20%20%20%20%20-%20Keep%20frequent%20operations%20on%20NVLink%2C%20use%20RDMA%20for%20cross-node%0A%0A%20%20%20%202.%20**Collectives%20block%2C%20RL%20needs%20async**%3A%20High%20variance%20in%20generation%20times%20makes%0A%20%20%20%20%20%20%20synchronous%20operations%20expensive%0A%0A%20%20%20%203.%20**Magic%20pointer%20pattern**%3A%20Tiny%20handle%20over%20control%20plane%2C%20bulk%20data%20over%20data%20plane%0A%20%20%20%20%20%20%20-%20~100%20bytes%20to%20describe%2010%20GB%20transfer%0A%0A%20%20%20%204.%20**CPU%20staging**%3A%20Temporal%20decoupling%20for%20async%20RL%0A%20%20%20%20%20%20%20-%20Nothing%20blocks%20on%20the%20critical%20path%0A%0A%20%20%20%205.%20**Circular%20buffers**%3A%20Version%20weights%20without%20memory%20churn%0A%20%20%20%20%20%20%20-%20Pre-register%20RDMA%20buffers%2C%20reuse%20slots%0A%0A%20%20%20%206.%20**Weight%20re-sharding**%3A%20Different%20layouts%20need%20overlap%20computation%0A%20%20%20%20%20%20%20-%20Routed%20approach%20avoids%20redundant%20transfers%0A%0A%20%20%20%20%23%23%23%20Want%20More%3F%0A%0A%20%20%20%20-%20**07b_weight_sync_deep_dive.py**%20-%20ibverbs%20internals%2C%20RDMA%20buffer%20patterns%0A%20%20%20%20-%20**08_rl_e2e.py**%20-%20Complete%20async%20RL%20system%20using%20these%20patterns%0A%0A%20%20%20%20---%0A%0A%20%20%20%20**Previous%3A**%20%5BNB06%20%E2%80%94%20Services%5D(.%2F06_services.html)%20%C2%B7%20**Next%3A**%20%5BNB07b%20%E2%80%94%20RDMA%20Deep%20Dive%5D(.%2F07b_weight_sync_deep_dive.html)%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
5ed062fd8bc0f29b859dd13072e87042