UCC: a collective API that sits above UCX, NCCL and SHARP
Unified Collective Communication Library
At a glance
- What is it?
- UCC (Unified Collective Communication) is a BSD-3-Clause C library that gives MPI, OpenSHMEM and other runtimes one collective API over several transports. It is worth adopting when you need nonblocking, repetitive collectives and hardware offload, and it is the wrong tool when you only need plain MPI collectives on one fabric.
- Who is it for?
- Adopt UCC if you are building or extending a programming model runtime and need one collective API that can target UCX/UCP, SHARP, CUDA, NCCL or RCCL, or if you run Open MPI and want to route coll and scoll through UCC with --mca coll_ucc_enable 1.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 7 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The gap UCC fills between a runtime and a fabric
A programming model runtime needs collectives. MPI has them, OpenSHMEM has them, and deep learning frameworks have their own. Each of those has historically been implemented against one transport, and the code that decides whether a broadcast goes over shared memory, InfiniBand, or an offload engine lives inside the runtime. UCC takes that decision out. The README describes it as a collective communication operations API and library that is flexible, complete, and feature-rich for current and emerging programming models and runtimes. The intended reader is not an application developer calling MPI_Bcast. It is the person maintaining the layer underneath, or the person wiring Open MPI or OpenSHMEM to a new network. The design goals list makes the target explicit: nonblocking collective operations that cover a variety of programming models, a flexible resource allocation model, relaxed ordering, a flexible synchronous model, and repetitive collective operations that are initialized once and invoked multiple times. Hardware collectives are listed as a first-class citizen, which is the part that distinguishes this from a portable reference implementation.
How the component architecture routes a collective
The README ships a component diagram (docs/images/ucc_components.png) rather than a prose description of the data flow, so the architecture has to be read from the goal list and the transport list together. The library presents one collective API upward. Below it, a component layer selects an implementation. The supported transports enumerated in the README are UCX/UCP (InfiniBand, ROCE, Cray Gemini and Aries, shared memory), SHARP, CUDA, NCCL, RCCL, and MLX5. That list tells you the selection is not a single code path. A broadcast on an InfiniBand cluster with a SHARP-capable switch can be handed to the switch; the same call with CUDA buffers on an NVIDIA node can go through NCCL or the CUDA path; a host-memory collective falls back to UCX/UCP. The repetitive-collective goal matters here: if a collective is initialized once and invoked many times, the transport selection and any setup work happen at init, not per call. That is the mechanism that makes the nonblocking and relaxed-ordering goals usable in a training loop or an iterative solver. UCX is a hard dependency, not an optional one. The README states that UCC uses utilities provided by UCX's UCS component, so the UCX install is required even if you never intend to run a UCP collective.
Building UCC against a specific UCX prefix
The developer build is autotools. The README gives three commands: ./autogen.sh, then ./configure --prefix=<ucc-install-path> --with-ucx=<ucx-install-path>, then make. The --with-ucx flag is the one that decides which UCX you link, and the README's Open MPI walkthrough builds UCX first from source with its own ./autogen.sh; ./configure --prefix=<ucx-install-path>; make -j install, then builds UCC against that prefix, then builds Open MPI with both --with-ucx=<ucx-install-path> and --with-ucc=<ucc-install-path>. Documentation generation is a separate configure path: ./configure --prefix=<ucc-install-path> --with-docs-only followed by make docs, which requires Doxygen. CUDA support is opt-in at compile time and the README specifies NVIDIA CUDA 11.0 or above; HIP support for AMD GPUs is also opt-in, with installation instructions pointed at AMD's ROCm documentation. Note what the README does not give: there is no list of configure flags for enabling or disabling individual transports, no guidance on which UCX version is compatible with which UCC release, and no note on whether a UCC built without CUDA can still be loaded by an MPI built with it. Those are the questions to answer before you pin a version.
Turning UCC on inside Open MPI and OpenSHMEM
UCC is not something an application links directly in the workflow the README shows. It is enabled through the runtime's MCA parameters. For MPI the command is mpirun -np 2 --mca coll_ucc_enable 1 --mca coll_ucc_priority 100 ./my_mpi_app, and for OpenSHMEM it is mpirun -np 2 --mca scoll_ucc_enable 1 --mca scoll_ucc_priority 100 ./my_openshmem_app. The two prefixes differ: coll_ for MPI collectives, scoll_ for OpenSHMEM collectives. The priority parameter is what makes this interesting operationally. Setting coll_ucc_priority to 100 pushes UCC ahead of the other coll components in Open MPI's selection order, which means the UCC path is chosen for collectives it claims to support. If a collective is not implemented for the active transport, the fallback behavior is determined by the component framework, and the README does not document what happens in that case. That is a real gap: a priority of 100 is a blunt instrument, and you should confirm per-collective coverage rather than assume the entire MPI collective set is served. The same caution applies to scoll_ucc_enable for OpenSHMEM, where the set of collectives is smaller but the interaction with the runtime's own implementations is equally undocumented here.
Where UCC is the wrong choice
The dependency chain is the first constraint. UCC requires UCX because it uses UCS utilities, so you cannot drop UCC into a system that has no UCX and expect a standalone library. If your cluster runs a single fabric with a working MPI collective implementation and no hardware offload, UCC adds a component layer, a second library to version, and a second prefix to keep in sync with your MPI build, in exchange for transport selection you do not need. The GPU story is also conditional. CUDA support requires a compile-time decision and CUDA 11.0 or above, and the README does not state which collective operations have CUDA implementations versus which fall back to host staging. If your workload is GPU-resident and you are choosing between UCC and going directly to NCCL, the README's transport list does not by itself tell you when UCC's NCCL path is preferable. The documentation is the weakest part overall: the API reference lives at openucx.github.io/ucc/ and the repository's own README defers to it, so an evaluation based on the README alone will leave the collective coverage matrix, the error model, and the memory-registration requirements unanswered.
How UCC differs from calling NCCL or MPI collectives directly
The obvious alternative for GPU collectives is NCCL directly, and for CPU collectives it is the MPI implementation's own coll modules. The difference is the layer at which the choice is made. NCCL is a GPU collective library with its own API and its own communicator model; an application or framework calls it and gets NCCL's algorithms. MPI's coll framework picks among its own modules. UCC sits one level up and treats NCCL as one of several backends, alongside RCCL, CUDA, SHARP, MLX5 and UCX/UCP. The practical consequence is that a runtime can expose one collective interface and let UCC decide, at init time for repetitive collectives, whether a given operation goes to an in-network reduction engine, a GPU library, or the host transport. That is a different trade-off from NCCL, which optimizes hard for the NVIDIA GPU path and does not attempt to serve CPU collectives over InfiniBand or Cray interconnects. If your entire workload is GPU collectives on NVIDIA hardware, the UCC layer is overhead unless you specifically need SHARP or a mixed CPU/GPU collective pattern. If you have a heterogeneous cluster, the single API is the reason to look at UCC at all.
Licence, maintenance and what a version bump costs
UCC is BSD-3-Clause, stated in the README and in the LICENSE file. That is a permissive licence and it is the same family as UCX, which matters if you are shipping a product that embeds the library. The README also points contributors at the UCF Consortium's Membership Voluntary Consensus Standard and Export Compliant Contribution Submissions policies, which is a governance constraint on contribution rather than on use. On maintenance, the release cadence visible in the repository is roughly quarterly: v1.8.0 in June 2026, v1.9.0-rc1 in August 2026, and v1.9.0 in September 2026. Each release is a source build, and the upgrade cost is not just rebuilding UCC. Because Open MPI is configured with --with-ucc=<ucc-install-path> and --with-ucx=<ucx-install-path>, moving UCC forward means confirming the new release still builds against your pinned UCX, then rebuilding or at least reconfiguring the MPI install that references the UCC prefix. On a large cluster that is a maintenance window, not a package upgrade. The README gives no compatibility matrix for UCC against UCX versions, so the safe practice is to pin both and test the pair before rolling out. This is a description of the licence terms as stated in the repository, not legal advice.
Editorial conclusion
Adopt UCC if you are building or extending a programming model runtime and need one collective API that can target UCX/UCP, SHARP, CUDA, NCCL or RCCL, or if you run Open MPI and want to route coll and scoll through UCC with --mca coll_ucc_enable 1. Do not adopt it as a drop-in replacement for your existing collectives if you are on a single fabric with no hardware offload and no GPU path, because the build still requires a matching UCX install and the operational surface grows. Before committing, verify three things against your own tree: that the UCC release you pin builds against your UCX version, that your MPI or OpenSHMEM build was configured with --with-ucc, and whether the transport you actually care about is listed as supported in the README rather than assumed.
Community notes