Collectives across cards with rbln-ccl¶
On Rebel100™, one card is one logical device, and work that spans several cards runs as several processes that exchange tensors through torch.distributed. RBLN PyTorch provides the rbln-ccl backend for that: the collectives run on the NPUs and the script is the same one you would write for any other accelerator. This tutorial launches two processes on two cards and assembles a table with all_gather.
How a card is partitioned internally is not part of this picture. A Rebel100™ card is a fixed group of four chiplets that the RBLN Compiler uses for every program on its own; see the RBLN Compiler documentation. The device-mapping variables that group ATOM™ cards into one logical device are not used on Rebel100™; see Environment Variables › Device mapping.
Prerequisites¶
- A host with at least two RBLN NPUs and the RBLN Driver installed. The output below was recorded on two Rebel100™ (
RBLN-CR13) cards. - Python: 3.10–3.14
torch,torch-rbln, andrebel-compilerinstalled as described in Installation.torchrunships withtorch.
Step 1: Gather one row from every card¶
ccl_allgather.py is a standard torch.distributed script with one RBLN-specific line: each rank picks its own card from the RBLN_VISIBLE_DEVICES list before the first device use, because torchrun gives every rank the same environment. Each rank then fills a small tensor with its rank number and all_gather assembles the full table on every rank.
$ RBLN_VISIBLE_DEVICES=0,1 torchrun --nproc_per_node 2 ccl_allgather.py
rank 0 sees (2, 4): [0.0, 1.0]
rank 1 sees (2, 4): [0.0, 1.0]
torchrun prints its usual note about setting OMP_NUM_THREADS first, and the two lines may arrive in either order.
How to read it:
- Every rank ends with the same table. Row 0 came from rank 0 and row 1 from rank 1; after
all_gather, both processes hold both rows. The gather ran on the NPUs because the tensors arefloat16; Execution Semantics › Distributed lists how other dtypes are handled. - One process, one card.
RBLN_VISIBLE_DEVICES=0,1names the two cards fortorchrun, and the first lines of the script narrow it to one card per rank. The mapping is committed at the first device use, so this has to happen before any tensor is created onrbln. torchrunprovides the rank information.init_process_groupreads the rendezvous variablestorchrunsets. The runtime's own control plane defaults to127.0.0.1, which is enough for one host.- The call returns when the collective is complete.
rbln-cclcollectives are synchronous by default;TORCH_RBLN_C10D_ASYNC=1returns work handles to wait on instead.
Step 2: Go beyond one host¶
The same script runs across hosts once two things change. Launch it with torchrun --nnodes and a rendezvous endpoint, as for any backend, and set the RBLN control plane on every rank before init_process_group: RBLN_ROOT_IP to rank 0's address, RBLN_LOCAL_IP to the rank's own address, and RBLN_RDMA_HCA (or RBLN_RDMA_IP) when a host has more than one RDMA interface. The variables and their defaults are in Environment Variables › Distributed.
The supported collectives (broadcast, scatter, all_gather, all_reduce, reduce_scatter, send, recv, barrier), the reduce operators, and the dtype rules are listed in Execution Semantics › Distributed.
Next steps¶
- Execution Semantics › Distributed - The collectives, reduce operators, and dtypes the backend supports.
- Execution Semantics › Rebel100™ and ATOM™ - What differs between the two families from PyTorch's point of view.
- Environment Variables › Distributed - Control-plane and data-plane variables for multi-host runs.