JACCL coordinator-optional connection setup (mlx PR 3899)
Parent: Mac local LLMs: Clusters, RDMA, exo and ds4 · Published reference · snapshot 2026-10-05
↓ Facts as markdownall context files
PR 3899 turns the JACCL bootstrap all-gather into a pluggable "side channel". The TCP star coordinator at `JACCL_COORDINATOR` stays the default, and a caller may instead pass `all_gather_factory` to `mx.distributed.init(backend="jaccl", ...)`.
These notes link each claim to its source. A source may be a research report hosted on this site rather than the primary document. A published reference means the content is available; it does not certify independent review or accuracy.Read the editorial policy and follow the sources before relying on a claim.
Facts
- PR 3899 turns the JACCL bootstrap all-gather into a pluggable "side channel". The TCP star coordinator at `JACCL_COORDINATOR` stays the default, and a caller may instead pass `all_gather_factory` to `mx.distributed.init(backend="jaccl", ...)`. [source]
- During initialisation JACCL exchanges RDMA connection metadata between ranks over a byte-level all-gather; the default is "a simple TCP star all-gather". [source]
- The factory is called once per rank with `(rank, size)` and must return a callable `f(src: bytes, n_bytes: int) -> bytes` whose result has length `size * n_bytes` with all ranks' inputs concatenated in rank order. [source]
- In `jaccl.cpp`, `Config::set_all_gather_factory` and `Config::set_all_gather` store the user function, and `Config::get_side_channel` prefers the factory, then the plain function, and only then builds a `TCPAllGather` from the coordinator address. [source]
- `Config::is_valid` now accepts a config when the coordinator string is non-empty OR a factory OR an all-gather function is set, so a run with no coordinator is valid. [source]
- The strict-mode error text still names a coordinator ("a coordinator ip/port (JACCL_COORDINATOR/MLX_JACCL_COORDINATOR)") and does not mention the factory. [source]
- The Python binding was moved into `mlx/distributed/distributed.cpp` after review so the group registers with the backends map; the first version called `jaccl::init` directly from the binding and the group was not registered, which reviewer nastya236 flagged would break `mx.distributed.all_sum` without a group and `clear_backends()`. [source]
- PR 3899 was opened by angeloskath on 2026-07-23, approved by nastya236 on 2026-07-30 and merged the same day as commit `85e3fb3` with 28 checks passing; its follow-up PR 3900 (ring refactor with a thread per wire) was written on top of it. [source]
- Late commits before merge were "Add user-definable side-channel", "Make sure one all gather at a time only", "Add the ability to define side-channel from python" and "Fixes from comments". [source]
- The release notes list it as "Making JACCL coordinator optional" in v0.32.1. [source]
- The factory path still needs a working slow channel; the PR text names a shared filesystem, iCloud or any central service as examples, and its worked example uses ZeroMQ with rank 0 as a ROUTER socket, so that example still has a rank-0 listener. [source]
- A reviewer asked why the barrier is built from two all-gathers; no answer is visible in the cached page. [source]
- The PR description says the zmq example was written by Claude; it is an illustration inside the PR, not shipped code. [source]
- "Optional" is used for two different things in the sources: in the release note it means the coordinator environment variable is not required, while the documentation still says `MLX_JACCL_COORDINATOR` should hold the IP and port rank 0 can listen on for the default path. Both are true: it is optional only when a factory is supplied. [source]
- Whether `mlx.launch --backend jaccl` offers any flag to select a non-TCP side channel; the cached launch.py shows it only sets the coordinator. [source]
- How the side channel behaves for peer-death detection compared with the TCP star (PR 4530 relies on the TCP channel living as long as the group). [source]
- PR 3899 lets a user supply their own metadata all-gather ("side channel") for JACCL initialisation through the `all_gather_factory` argument. [source]
- The default side channel is a TCP star all-gather rooted at the rank-0 coordinator. [source]
- The factory receives `(rank, size)` and returns `f(src, n_bytes)` that must give back `size * n_bytes` bytes in rank order. [source]
- `Config::get_side_channel` picks factory, then function, then TCP coordinator in that order. [source]
- `Config::is_valid` accepts an empty coordinator when a factory or all-gather function is set. [source]
- The strict-mode error message still lists only a coordinator and does not mention the factory. [source]
- The PR author's stated purpose is apps that already have a slow connection between nodes, to avoid opening a port and listening for connections. [source]
- The reviewer's summary of the benefit: no second network is needed, and rank 0 needs neither a reachable IP nor an open listening port. [source]
- Registering the factory-built group through `mlx/distributed/distributed.cpp` was a review fix so that backend registration and `clear_backends()` work. [source]
- PR 3899 merged on 2026-07-30 as commit `85e3fb3` and is in v0.32.1. [source]
- PR 3900 was stacked on 3899 and says it would be rebased after 3899 merged. [source]
- Rank hosts without a reachable listener can only skip the coordinator if their own side channel does not need one. [source]
Children
- No children recorded.