Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions projects/rccl/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Full documentation for RCCL is available at [https://rccl.readthedocs.io](https:
* `NCCL_HIER_CE_COLL_AG_RAIL_RING_ENABLE` (default `-1`): a positive value selects a ring for the inter-node rail phase of hierarchical Copy Engine `ncclAllGather`. The default keeps the direct path.
* `NCCL_IB_SORT_MERGE_NICS`: sorts the sub-devices of a merged IB device by plane ID. RCCL defaults it to `0` (NCCL defaults to `1`), so merged-device order and names are unchanged.
* nccl4py: per-call collective configuration (`NCCLCollConfig`, `VendorOption`) including the launch completion event, communicator properties (`NCCLCommProperties`), and the `GIN_ONLY` window flag. On ROCm, the HIP `Event` shim provides only an event handle; `record()`, `sync()` and `query` are not implemented.
* `RCCL_TUNER_EMBEDDED_CONFIG` (default `1`): the built-in CSV tuner configurations in `tuner/*.csv` are now compiled into `librccl.so` and used as the stock tuning defaults, so a cluster no longer has to stage the CSV on every node or on NFS. Set `0` to ignore the embedded configurations. `NCCL_TUNER_CONFIG_FILE` and the on-disk tuner directories still take precedence, and `NCCL_TUNER_PLUGIN=none` still disables the tuner entirely.

### Changed
* Host-side device API declarations (`ncclDevCommCreate`, `ncclDevCommDestroy`, `ncclCommQueryProperties`, `ncclGetPeerDevicePointer`, the `*CreateRequirement` helpers, the `ncclDevCommRequirements` and `ncclCommProperties` structs and their initializers) moved to `nccl_device/host.h`. `nccl_device.h` still includes it; code that includes individual `nccl_device/*.h` headers directly must also include `nccl_device/host.h`.
Expand All @@ -32,6 +33,7 @@ Full documentation for RCCL is available at [https://rccl.readthedocs.io](https:
* Communicator initialization at large scale is faster because the proxy no longer scans inactive poll descriptors.
* Network devices for each GPU are now chosen by rail and plane assignment, replacing the previous start-device scattering.
* `NCCL_MLOPART_RDMA_ENABLE` (default `0`) is kept. NCCL 2.32 removed it and treats buffers on partitioned GPUs as RDMA-capable on all non-ARM hosts; RCCL keeps network buffer registration for partitioned (CPX/DPX) GPUs opt-in.
* The CSV tuner configurations are no longer installed to `${ROCM_PATH}/share/rccl/tuner/` or copied into the build tree; they ship inside `librccl.so`. A CSV placed in that directory, or in `<librccl.so dir>/tuner/`, still overrides the built-in defaults. A copy left behind by an earlier build or by `cmake --install` over an existing prefix also still takes precedence, so delete it to pick up the embedded defaults; package upgrades remove it automatically.
* Retuned the symmetric AllReduce, ReduceScatter and AllGather kernels for gfx950. The block width is now selected per collective and message size instead of a fixed 256 threads, and the work partitioning and unroll factors in the load-direct kernels and the AllGather store kernel were refitted to the 64-lane wavefront. AllGather also switches from LL to the store kernel from 4 MB instead of 16 MB. The multi-node GIN kernels and all other architectures are unchanged. To fit the wider LL blocks, the shared LL scratch buffer on gfx950 grows from 4 MiB to 8 MiB per 8-rank communicator.

### Removed
Expand Down
29 changes: 26 additions & 3 deletions projects/rccl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,23 @@ file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/include/rccl")
configure_file(src/nccl.h.in ${PROJECT_BINARY_DIR}/include/rccl/rccl.h) # For external linking
configure_file(src/nccl.h.in ${PROJECT_BINARY_DIR}/include/nccl.h) # Used by some internal files

## Compile tuner/*.csv into librccl.so so the built-in CSV tuner works without
## the files being staged on every node. Disk locations remain as overrides.
set(RCCL_EMBEDDED_TUNER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/cmake/GenerateEmbeddedTunerConfigs.cmake)
set(RCCL_EMBEDDED_TUNER_HEADER ${PROJECT_BINARY_DIR}/include/rccl_tuner_embedded_configs.h)
# Always run, like update_git_version: an OUTPUT/DEPENDS command re-runs only
# when an input is newer than the output, so deleting a CSV would leave it
# embedded. The script rewrites the header only when the content changes, so
# running every build does not churn rebuilds.
add_custom_target(rccl_embedded_tuner_configs
ALL
COMMAND ${CMAKE_COMMAND} -DTUNER_DIR=${CMAKE_CURRENT_SOURCE_DIR}/tuner
-DOUT_FILE=${RCCL_EMBEDDED_TUNER_HEADER}
-P ${RCCL_EMBEDDED_TUNER_SCRIPT}
BYPRODUCTS ${RCCL_EMBEDDED_TUNER_HEADER}
COMMENT "Generating embedded RCCL tuner configs"
VERBATIM)

# Example plugins are C sources
if(BUILD_TESTS AND BUILD_PLUGIN_EXAMPLES)
enable_language(C)
Expand Down Expand Up @@ -881,9 +898,15 @@ if(EMIT_LLVM_IR)
rocm_install(DIRECTORY ${PROJECT_BINARY_DIR}/include/nccl_device
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/rccl)
endif()
## Install tuner config directory for CSV-based tuner
file(COPY tuner DESTINATION ${PROJECT_BINARY_DIR})
rocm_install(DIRECTORY ${PROJECT_BINARY_DIR}/tuner DESTINATION ${CMAKE_INSTALL_DATADIR}/rccl)
## tuner/*.csv is compiled into librccl.so (see rccl_embedded_tuner_configs above),
## so nothing is copied to the build tree or installed. A CSV placed in
## <libdir>/tuner/ or share/rccl/tuner/ still overrides the embedded defaults.
Comment thread
mustafabar marked this conversation as resolved.
Resolved
##
## Migration: dropping these rules does not delete copies an earlier build or
## install already wrote, and those still win over the embedded map. Package
## upgrades remove the installed copy, but `cmake --install` over an existing
## prefix does not, and an incremental build tree keeps <builddir>/tuner/ next
## to librccl.so. Delete those by hand to pick up the embedded defaults.
rocm_export_targets(
NAMESPACE roc::
TARGETS rccl
Expand Down
67 changes: 67 additions & 0 deletions projects/rccl/cmake/GenerateEmbeddedTunerConfigs.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#
# Copyright (c) 2026, Advanced Micro Devices, Inc. All rights reserved.
#
# See LICENSE.txt for license information
#
# Embeds tuner/*.csv into a header so librccl.so ships the built-in CSV tuner
# configs without the files being staged on disk.
#
# cmake -DTUNER_DIR=<dir> -DOUT_FILE=<header> -P GenerateEmbeddedTunerConfigs.cmake

if(NOT DEFINED TUNER_DIR OR NOT DEFINED OUT_FILE)
message(FATAL_ERROR "GenerateEmbeddedTunerConfigs.cmake requires -DTUNER_DIR and -DOUT_FILE")
endif()

set(RAW_DELIM "RCCLCSV")

# Match what the runtime accepts on disk (findTunerFileInDir): a stray
# tuner/notes.csv would otherwise be embedded and, sorting first, become what
# the arch-unknown lookup returns.
file(GLOB CSV_FILES "${TUNER_DIR}/rccl_tuner*.csv")
list(SORT CSV_FILES)

set(ENTRIES "")
foreach(CSV_FILE ${CSV_FILES})
get_filename_component(CSV_NAME ${CSV_FILE} NAME)
file(READ ${CSV_FILE} CSV_CONTENT)

# The name is spliced into a C++ string literal, the content into a raw one.
if(CSV_NAME MATCHES "[\"\\\\]")
message(FATAL_ERROR "${CSV_FILE} has a quote or backslash in its name and cannot be embedded")
endif()
string(FIND "${CSV_CONTENT}" ")${RAW_DELIM}\"" BAD_IDX)
if(NOT BAD_IDX EQUAL -1)
message(FATAL_ERROR "${CSV_FILE} contains the raw string terminator )${RAW_DELIM}\" and cannot be embedded")
endif()

string(APPEND ENTRIES " {\"${CSV_NAME}\", R\"${RAW_DELIM}(${CSV_CONTENT})${RAW_DELIM}\"},\n")
message(STATUS "Embedding tuner config: ${CSV_NAME}")
endforeach()

list(LENGTH CSV_FILES CSV_COUNT)

set(HEADER "/* Generated by cmake/GenerateEmbeddedTunerConfigs.cmake -- do not edit, do not commit. */
#ifndef RCCL_TUNER_EMBEDDED_CONFIGS_H_
#define RCCL_TUNER_EMBEDDED_CONFIGS_H_

/* ${CSV_COUNT} config(s) embedded from the source tree's tuner/ directory. */
struct RcclEmbeddedTunerConfig {
const char* name;
const char* content;
};

static const RcclEmbeddedTunerConfig kRcclEmbeddedTunerConfigs[] = {
${ENTRIES} {nullptr, nullptr}, /* sentinel: array is never zero-length */
};

#endif /* RCCL_TUNER_EMBEDDED_CONFIGS_H_ */
")

# Rewrite only on change so regeneration does not force a rebuild.
set(OLD_HEADER "")
if(EXISTS ${OUT_FILE})
file(READ ${OUT_FILE} OLD_HEADER)
endif()
if(NOT OLD_HEADER STREQUAL HEADER)
file(WRITE ${OUT_FILE} "${HEADER}")
endif()
15 changes: 15 additions & 0 deletions projects/rccl/docs/api-reference/env-variables.rst
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,21 @@ collected in the following table.
| Default: ``16``
| ``0``: No lower bound.

* - | ``RCCL_TUNER_EMBEDDED_CONFIG``
| Controls whether the built-in CSV tuner uses the tuning configurations
compiled into ``librccl.so`` from the source tree's ``tuner/*.csv``.
These are the stock defaults, so no file has to be staged on each node.
``NCCL_TUNER_CONFIG_FILE`` and a CSV in ``<librccl.so dir>/tuner/`` or
``${ROCM_PATH}/share/rccl/tuner/`` take precedence over them. When the
GPU architecture is known, only an architecture-specific
(``rccl_tuner_<arch>.csv``) or generic (``rccl_tuner.csv``)
configuration is used; another architecture's configuration is never
applied. When the architecture cannot be determined, any embedded
configuration may be used. To disable the tuner entirely, embedded
or not, use ``NCCL_TUNER_PLUGIN=none``.
- | ``1``: Use the embedded configurations when no file is found (default).
| ``0``: Ignore the embedded configurations. File-based tuning is unaffected.

Network and topology
====================

Expand Down
3 changes: 2 additions & 1 deletion projects/rccl/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,8 @@ add_library(rccl ${HIP_SOURCES})

## Set RCCL dependencies
## Ensure git version is updated before building rccl
add_dependencies(rccl update_git_version copy_nccl_device_headers net_ib_header_symlinks rma_header_symlinks)
add_dependencies(rccl update_git_version copy_nccl_device_headers net_ib_header_symlinks rma_header_symlinks
rccl_embedded_tuner_configs)

## Set RCCL include directories
target_include_directories(rccl PRIVATE ${PROJECT_BINARY_DIR}/include) # for generated rccl.h header
Expand Down
11 changes: 9 additions & 2 deletions projects/rccl/src/include/tuner.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#ifndef NCCL_INT_TUNER_H_
#define NCCL_INT_TUNER_H_

#include <map>
#include <string>

#include "nccl_tuner.h"
#include "comm.h"

Expand All @@ -17,11 +20,15 @@
// Built-in CSV tuner - compiled into librccl.so (follows rocmNetIb pattern)
extern ncclTuner_t rcclCsvTuner;

// Find CSV config file path. Returns path if found, nullptr if not.
// Find the CSV config source. Returns a file path, an "<embedded>/<name>" label
// for a config compiled into librccl.so, or nullptr if neither is available.
// gpuArch: GPU architecture string (e.g., "gfx950") for arch-specific config lookup
const char* rcclCsvTunerFindConfig(const char* gpuArch);

// Reset CSV tuner config path discovery (for testing)
// CSV configs compiled in from the source tree's tuner/ directory, keyed by file name.
const std::map<std::string, std::string>& rcclCsvTunerEmbeddedConfigs();

// Reset CSV tuner config source discovery (for testing)
void rcclCsvTunerResetConfigPath();

// Attempts to load NCCL tuner from environmental variable.
Expand Down
Loading
Loading