Blackwell Brings NUMA Back, Inside One GPU DeepSeek addressed the dual-die memory locality of Nvidia's Blackwell (SM100) B200 and B300 GPUs in a pull request to its DeepGEMM library (deepseek-ai/DeepGEMM#462), splitting MoE weights along the N dimension so each of the two dies joined by NV-HBI stores its own half in local HBM. Because CUDA exposes no API identifying which SM sits on which die, DeepGEMM measures it at startup with a pointer-chasing probe timed via clock64, accepting the result only if the far die is at least 1.25x slower and both SMs in every TPC agree, retrying up to 5 times before falling back to an even split. The code allocates die-local memory through MLOPart, an MPS mode, using cuMemAddressReserve and cuMemMap, pending direct per-die allocation that the post says should arrive in CUDA 13.4. On Blackwell SM100 we are back to solving NUMA problems, inside a single GPU package. To software, a B200 or B300 looks like one big GPU. CUDA shows one device with a flat address space and a unified L2, and you launch kernels across all the SMs just like you did on Hopper. Physically, though, it is two separate silicon dies joined by NV-HBI. The link is fast, but HBM attached to your own die is still noticeably closer than HBM attached to the other one. If you ignore this, memory-heavy kernels like MoE layers pull half their weights across the link, which costs latency and power. DeepSeek recently handled this in DeepGEMM for their MegaMoE kernel deepseek-ai/DeepGEMM 462 https://github.com/deepseek-ai/DeepGEMM/pull/462 . All the code below comes from that implementation. Two locality domains two-locality-domains Each die is a locality domain with its own SMs and its own HBM stacks. CUDA has no API that tells you which SM sits on which die, so DeepGEMM measures it at startup. It puts one buffer on each die and has every SM chase a chain of pointers through both, timing the hops with clock64 : template