5b471d77b2
Improvements for GB200 systems
* Optimize the network performance by alternating the direction of the
rings and the NIC to GPU assignment across communicators to limit
unnecessary sharing.
* Fix the detection of C2C links in case GPU Direct RDMA is disabled
between a GPU and a NIC.
* Fix PXN support on MNNVL systems, where NCCL would try (and fail) to
share regular host memory across multiple nodes.
* Fix P2C (PXN over C2C), which is now preferred over regular PXN. This
support is currently preliminary and is disabled by default; use
NCCL_PXN_C2C=1 to enable.
Further reduce the overheads of CUDA graph capturing, which increased in
NCCL 2.26.2 for large graphs.
Optimize the network performance on DGX B200 systems by adjusting the
bandwidths provided to the graph search algorithm.
Enable fp8 reductions in symmetric kernels on Blackwell with CUDA 12.8.
Restore the plugin name handling logic to make it possible to specify a
path to the plugin (Issue #1732).
Restore the ability to change NCCL_COLLNET_ENABLE during execution
(Issue #1741).
Add an example tuner plugin with CSV-based overrides.
Remove an x86 dependency from the example profiler.
[ROCm/rccl commit: 3ea7eedf3b]
142 строки
4.6 KiB
C++
142 строки
4.6 KiB
C++
/*************************************************************************
|
|
* Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved.
|
|
*
|
|
* See LICENSE.txt for license information
|
|
************************************************************************/
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <dlfcn.h>
|
|
|
|
#include "debug.h"
|
|
|
|
#define MAX_STR_LEN 255
|
|
|
|
enum ncclPluginType {
|
|
ncclPluginTypeNet,
|
|
ncclPluginTypeTuner,
|
|
ncclPluginTypeProfiler,
|
|
};
|
|
|
|
#define NUM_LIBS 3
|
|
static void *libHandles[NUM_LIBS];
|
|
static const char *pluginNames[NUM_LIBS] = { "NET", "TUNER", "PROFILER" };
|
|
static const char *pluginPrefix[NUM_LIBS] = { "libnccl-net", "libnccl-tuner", "libnccl-profiler" };
|
|
static const char *pluginFallback[NUM_LIBS] = { "", "Using internal tuner plugin.", "" };
|
|
static unsigned long subsys[NUM_LIBS] = { NCCL_INIT|NCCL_NET, NCCL_INIT|NCCL_TUNING, NCCL_INIT };
|
|
|
|
static void* tryOpenLib(char* name, int* err, char* errStr) {
|
|
*err = 0;
|
|
if (nullptr == name || strlen(name) == 0) {
|
|
return nullptr;
|
|
}
|
|
|
|
if (strncasecmp(name, "STATIC_PLUGIN", strlen(name)) == 0) {
|
|
name = nullptr;
|
|
}
|
|
|
|
void *handle = dlopen(name, RTLD_NOW | RTLD_LOCAL);
|
|
if (nullptr == handle) {
|
|
strncpy(errStr, dlerror(), MAX_STR_LEN);
|
|
errStr[MAX_STR_LEN] = '\0';
|
|
// "handle" and "name" won't be NULL at the same time.
|
|
// coverity[var_deref_model]
|
|
if (strstr(errStr, name) && strstr(errStr, "No such file or directory")) {
|
|
*err = ENOENT;
|
|
}
|
|
}
|
|
return handle;
|
|
}
|
|
|
|
static void appendNameToList(char* nameList, int *leftChars, char* name) {
|
|
snprintf(nameList + PATH_MAX - *leftChars, *leftChars, " %s", name);
|
|
*leftChars -= strlen(name) + 1;
|
|
}
|
|
|
|
static void* openPluginLib(enum ncclPluginType type, const char* libName) {
|
|
int openErr, len = PATH_MAX;
|
|
char libName_[MAX_STR_LEN] = { 0 };
|
|
char openErrStr[MAX_STR_LEN + 1] = { 0 };
|
|
char eNoEntNameList[PATH_MAX] = { 0 };
|
|
|
|
if (libName && strlen(libName)) {
|
|
snprintf(libName_, MAX_STR_LEN, "%s", libName);
|
|
libHandles[type] = tryOpenLib(libName_, &openErr, openErrStr);
|
|
if (libHandles[type]) {
|
|
INFO(subsys[type], "%s/Plugin: Plugin name set by env to %s", pluginNames[type], libName_);
|
|
return libHandles[type];
|
|
}
|
|
if (openErr == ENOENT) {
|
|
appendNameToList(eNoEntNameList, &len, libName_);
|
|
} else {
|
|
INFO(subsys[type], "%s/Plugin: %s", pluginNames[type], openErrStr);
|
|
}
|
|
|
|
// libName can't be a relative or absolute path (start with '.' or contain any '/'). It can't be a library name either (start with 'lib' or end with '.so')
|
|
if (strchr(libName, '/') == nullptr && (strncmp(libName, "lib", strlen("lib")) || strlen(libName) < strlen(".so") || strncmp(libName + strlen(libName) - strlen(".so"), ".so", strlen(".so")))) {
|
|
snprintf(libName_, MAX_STR_LEN, "%s-%s.so", pluginPrefix[type], libName);
|
|
libHandles[type] = tryOpenLib(libName_, &openErr, openErrStr);
|
|
if (libHandles[type]) {
|
|
INFO(subsys[type], "%s/Plugin: Plugin name set by env to %s", pluginNames[type], libName_);
|
|
return libHandles[type];
|
|
}
|
|
if (openErr == ENOENT) {
|
|
appendNameToList(eNoEntNameList, &len, libName_);
|
|
} else {
|
|
INFO(subsys[type], "%s/Plugin: %s", pluginNames[type], openErrStr);
|
|
}
|
|
}
|
|
} else {
|
|
snprintf(libName_, MAX_STR_LEN, "%s.so", pluginPrefix[type]);
|
|
libHandles[type] = tryOpenLib(libName_, &openErr, openErrStr);
|
|
if (libHandles[type]) {
|
|
return libHandles[type];
|
|
}
|
|
if (openErr == ENOENT) {
|
|
appendNameToList(eNoEntNameList, &len, libName_);
|
|
} else {
|
|
INFO(subsys[type], "%s/Plugin: %s", pluginNames[type], openErrStr);
|
|
}
|
|
}
|
|
|
|
if (strlen(eNoEntNameList)) {
|
|
INFO(subsys[type], "%s/Plugin: Could not find:%s. %s", pluginNames[type], eNoEntNameList, pluginFallback[type]);
|
|
} else if (strlen(pluginFallback[type])) {
|
|
INFO(subsys[type], "%s/Plugin: %s", pluginNames[type], pluginFallback[type]);
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void* ncclOpenNetPluginLib(const char* name) {
|
|
return openPluginLib(ncclPluginTypeNet, name);
|
|
}
|
|
|
|
void* ncclOpenTunerPluginLib(const char* name) {
|
|
return openPluginLib(ncclPluginTypeTuner, name);
|
|
}
|
|
|
|
void* ncclOpenProfilerPluginLib(const char* name) {
|
|
return openPluginLib(ncclPluginTypeProfiler, name);
|
|
}
|
|
|
|
void* ncclGetNetPluginLib(void) {
|
|
return libHandles[ncclPluginTypeNet];
|
|
}
|
|
|
|
ncclResult_t ncclClosePluginLib(void* handle) {
|
|
bool found = false;
|
|
for (int l=0; l<NUM_LIBS; l++) {
|
|
if (libHandles[l] == handle) {
|
|
libHandles[l] = nullptr;
|
|
if (!found) {
|
|
if (handle) {
|
|
dlclose(handle);
|
|
}
|
|
found = true;
|
|
}
|
|
}
|
|
}
|
|
return ncclSuccess;
|
|
}
|