178b6b7590
Rework core for NVIDIA Trusted Computing * Compress work structs so that they are shared between channels * Utilize the full amount of kernel argument space permitted (4k) before resorting to work fifo. * Rework the task preprocessing phase. * Use a separate abortDevFlag which is kept in sync with abortFlag using cudaMemcpy operations. * Rename src/include/align.h to src/include/bitops.h Add lazy connection establishment for collective operations * Move buffer allocation and connection establishment to the first collective operation using that algorithm. * Accelerate init time and reduce memory usage. * Avoid allocating NVLS buffers if all calls are registered. * Compute algo/proto in ncclLaunchCollTasksInfo early on. * Connect peers in ncclCollPreconnectFunc if not connected already. * Also move shared buffer creation to the first send/recv call. Accelerate intra-node NVLink detection * Make each rank only detect NVLinks attached to its GPU. * Fuse XMLs to reconstruct the full NVLink topology Add init profiling to report time spend in different init phases. * Report timings of bootstrap, allgather, search, connect, etc. * Add new "PROFILE" category for NCCL_DEBUG_SUBSYS. Add support for PCI p2p on split PCI switches * Detect split PCI switches through a kernel module exposing switch information. * Update the topology XML and graph to add those inter-switch connections. Add cost estimation API * Add a new ncclGroupEndSimulate primitive to return the estimated time a group would take. Net/IB: Add separate traffic class for fifo messages * Add NCCL_IB_FIFO_TC to control the traffic class of fifo messages independently from NCCL_IB_TC. Merges PR #1194 Net/IB: Add support for IB router * Use flid instead of lid if subnets do not match * Warn if flid is 0 Optimizations and fixes for device network offload (unpack) * Double the default number of channels * Cache netDeviceType * Fix save/increment head logic to enable Tree support. Support ncclGroupStart/End for ncclCommAbort/Destroy * Allow Abort/Destroy to be called within a group when managing multiple GPUs with a single process. Improve Tuner API * Provide to the plugin the original cost table so that the plugin can leave unknown or disabled algo/proto combinations untouched. * Remove nvlsSupport and collnetSupport. Do not print version to stdout when using a debug file * Also print version from all processes with INFO debug level. Fixes issue #1271 Fix clang warnings in NVTX headers * Update NVTX headers to the latest version Fixes issue #1270 Disable port fusion in heterogeneous systems * Do not fuse ports if a mix of multi-port and single port are detected. Fix NVLS graphs search for dual NICs. * Fix NVLS graph search when we have more than one NIC per GPU. Fix crash with collnetDirect * Add separate graph search for collnetDirect, testing alltoall paths and working similarly to the NVLS search. Fix hang when nodes have different CPU types * Add the CPU type to the rank peer info. * Align all ranks on the CPU type after the first allgather. * Only use the aligned CPU type for all tuning operations. Fixes issue #1136 Fixes issue #1184 Fix performance of registered send/recv operations * Allow for single full size operations * Add INFO to confirm the registration of send/recv buffers. Move all sync ops to finalize stage * Ensure ncclCommDestroy is non-blocking if ncclCommFinalize has been called. Improve error reporting during SHM segment creation Improve support of various compilers Merges PR #1177 Merges PR #1228 Allow net and tuner plugins to be statically linked * Search for ncclNet or ncclTuner symbols in the main binary. Merges PR #979 Plugin examples includes cleanup * Harmonize err.h and common.h usage. * Add mixed plugin with both net and tuner.
242 lines
8.2 KiB
C++
242 lines
8.2 KiB
C++
/*************************************************************************
|
|
* Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved.
|
|
*
|
|
* See LICENSE.txt for license information
|
|
************************************************************************/
|
|
|
|
#include "gdrwrap.h"
|
|
|
|
#ifndef GDR_DIRECT
|
|
#include "core.h"
|
|
|
|
/* Function pointers assigned from dlopen() */
|
|
static gdr_t (*gdr_internal_open)(void);
|
|
static int (*gdr_internal_close)(gdr_t g);
|
|
static int (*gdr_internal_pin_buffer)(gdr_t g, unsigned long addr, size_t size, uint64_t p2p_token, uint32_t va_space, gdr_mh_t *handle);
|
|
static int (*gdr_internal_unpin_buffer)(gdr_t g, gdr_mh_t handle);
|
|
static int (*gdr_internal_get_info)(gdr_t g, gdr_mh_t handle, gdr_info_t *info);
|
|
static int (*gdr_internal_map)(gdr_t g, gdr_mh_t handle, void **va, size_t size);
|
|
static int (*gdr_internal_unmap)(gdr_t g, gdr_mh_t handle, void *va, size_t size);
|
|
static void (*gdr_internal_runtime_get_version)(int *major, int *minor);
|
|
static void (*gdr_internal_driver_get_version)(gdr_t g, int *major, int *minor);
|
|
static int (*gdr_internal_copy_to_mapping)(gdr_mh_t handle, void *map_d_ptr, const void *h_ptr, size_t size);
|
|
static int (*gdr_internal_copy_from_mapping)(gdr_mh_t handle, void *h_ptr, const void *map_d_ptr, size_t size);
|
|
|
|
|
|
// Used to make the GDR library calls thread safe
|
|
pthread_mutex_t gdrLock = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
#define GDRAPI_LIBNAME "libgdrapi.so"
|
|
|
|
#define LOAD_SYM(handle, symbol, funcptr) do { \
|
|
cast = (void**)&funcptr; \
|
|
tmp = dlsym(handle, symbol); \
|
|
if (tmp == NULL) { \
|
|
WARN("dlsym failed on %s - %s", symbol, dlerror());\
|
|
goto teardown; \
|
|
} \
|
|
*cast = tmp; \
|
|
} while (0)
|
|
|
|
#define LOAD_SYM_OPTIONAL(handle, symbol, funcptr) do {\
|
|
cast = (void**)&funcptr; \
|
|
tmp = dlsym(handle, symbol); \
|
|
if (tmp == NULL) { \
|
|
INFO(NCCL_INIT,"dlsym failed on %s, ignoring", symbol); \
|
|
} \
|
|
*cast = tmp; \
|
|
} while (0)
|
|
|
|
static pthread_once_t initOnceControl = PTHREAD_ONCE_INIT;
|
|
static ncclResult_t initResult;
|
|
|
|
static void initOnceFunc(void) {
|
|
static void* gdrhandle = NULL;
|
|
void* tmp;
|
|
void** cast;
|
|
|
|
gdrhandle=dlopen(GDRAPI_LIBNAME, RTLD_NOW);
|
|
if (!gdrhandle) {
|
|
WARN("Failed to open %s", GDRAPI_LIBNAME);
|
|
goto teardown;
|
|
}
|
|
|
|
/* Load the function pointers from the DL library image */
|
|
LOAD_SYM(gdrhandle, "gdr_open", gdr_internal_open);
|
|
LOAD_SYM(gdrhandle, "gdr_close", gdr_internal_close);
|
|
LOAD_SYM(gdrhandle, "gdr_pin_buffer", gdr_internal_pin_buffer);
|
|
LOAD_SYM(gdrhandle, "gdr_unpin_buffer", gdr_internal_unpin_buffer);
|
|
LOAD_SYM(gdrhandle, "gdr_get_info", gdr_internal_get_info);
|
|
LOAD_SYM(gdrhandle, "gdr_map", gdr_internal_map);
|
|
LOAD_SYM(gdrhandle, "gdr_unmap", gdr_internal_unmap);
|
|
LOAD_SYM(gdrhandle, "gdr_runtime_get_version", gdr_internal_runtime_get_version);
|
|
LOAD_SYM(gdrhandle, "gdr_driver_get_version", gdr_internal_driver_get_version);
|
|
LOAD_SYM(gdrhandle, "gdr_copy_to_mapping", gdr_internal_copy_to_mapping);
|
|
LOAD_SYM(gdrhandle, "gdr_copy_from_mapping", gdr_internal_copy_from_mapping);
|
|
|
|
initResult = ncclSuccess;
|
|
return;
|
|
|
|
teardown:
|
|
gdr_internal_open = NULL;
|
|
gdr_internal_close = NULL;
|
|
gdr_internal_pin_buffer = NULL;
|
|
gdr_internal_unpin_buffer = NULL;
|
|
gdr_internal_get_info = NULL;
|
|
gdr_internal_map = NULL;
|
|
gdr_internal_unmap = NULL;
|
|
gdr_internal_runtime_get_version = NULL;
|
|
gdr_internal_driver_get_version = NULL;
|
|
gdr_internal_copy_to_mapping = NULL;
|
|
gdr_internal_copy_from_mapping = NULL;
|
|
|
|
if (gdrhandle != NULL) dlclose(gdrhandle);
|
|
initResult = ncclSystemError;
|
|
return;
|
|
}
|
|
|
|
|
|
ncclResult_t wrap_gdr_symbols(void) {
|
|
pthread_once(&initOnceControl, initOnceFunc);
|
|
return initResult;
|
|
}
|
|
|
|
gdr_t wrap_gdr_open(void) {
|
|
if (gdr_internal_open == NULL) {
|
|
WARN("GDRCOPY lib wrapper not initialized.");
|
|
return NULL;
|
|
}
|
|
return gdr_internal_open();
|
|
}
|
|
|
|
ncclResult_t wrap_gdr_close(gdr_t g) {
|
|
if (gdr_internal_close == NULL) {
|
|
WARN("GDRCOPY lib wrapper not initialized.");
|
|
return ncclInternalError;
|
|
}
|
|
int ret = gdr_internal_close(g);
|
|
if (ret != 0) {
|
|
WARN("gdr_close() failed: %d", ret);
|
|
return ncclSystemError;
|
|
}
|
|
return ncclSuccess;
|
|
}
|
|
|
|
ncclResult_t wrap_gdr_pin_buffer(gdr_t g, unsigned long addr, size_t size, uint64_t p2p_token, uint32_t va_space, gdr_mh_t *handle) {
|
|
if (gdr_internal_pin_buffer == NULL) {
|
|
WARN("GDRCOPY lib wrapper not initialized.");
|
|
return ncclInternalError;
|
|
}
|
|
int ret;
|
|
GDRLOCKCALL(gdr_internal_pin_buffer(g, addr, size, p2p_token, va_space, handle), ret);
|
|
if (ret != 0) {
|
|
WARN("gdr_pin_buffer(addr %lx, size %zu) failed: %d", addr, size, ret);
|
|
return ncclSystemError;
|
|
}
|
|
return ncclSuccess;
|
|
}
|
|
|
|
ncclResult_t wrap_gdr_unpin_buffer(gdr_t g, gdr_mh_t handle) {
|
|
if (gdr_internal_unpin_buffer == NULL) {
|
|
WARN("GDRCOPY lib wrapper not initialized.");
|
|
return ncclInternalError;
|
|
}
|
|
int ret;
|
|
GDRLOCKCALL(gdr_internal_unpin_buffer(g, handle), ret);
|
|
if (ret != 0) {
|
|
WARN("gdr_unpin_buffer(handle %lx) failed: %d", handle.h, ret);
|
|
return ncclSystemError;
|
|
}
|
|
return ncclSuccess;
|
|
}
|
|
|
|
ncclResult_t wrap_gdr_get_info(gdr_t g, gdr_mh_t handle, gdr_info_t *info) {
|
|
if (gdr_internal_get_info == NULL) {
|
|
WARN("GDRCOPY lib wrapper not initialized.");
|
|
return ncclInternalError;
|
|
}
|
|
int ret;
|
|
GDRLOCKCALL(gdr_internal_get_info(g, handle, info), ret);
|
|
if (ret != 0) {
|
|
WARN("gdr_get_info(handle %lx) failed: %d", handle.h, ret);
|
|
return ncclSystemError;
|
|
}
|
|
return ncclSuccess;
|
|
}
|
|
|
|
ncclResult_t wrap_gdr_map(gdr_t g, gdr_mh_t handle, void **va, size_t size) {
|
|
if (gdr_internal_map == NULL) {
|
|
WARN("GDRCOPY lib wrapper not initialized.");
|
|
return ncclInternalError;
|
|
}
|
|
int ret;
|
|
GDRLOCKCALL(gdr_internal_map(g, handle, va, size), ret);
|
|
if (ret != 0) {
|
|
WARN("gdr_map(handle %lx, size %zu) failed: %d", handle.h, size, ret);
|
|
return ncclSystemError;
|
|
}
|
|
return ncclSuccess;
|
|
}
|
|
|
|
ncclResult_t wrap_gdr_unmap(gdr_t g, gdr_mh_t handle, void *va, size_t size) {
|
|
if (gdr_internal_unmap == NULL) {
|
|
WARN("GDRCOPY lib wrapper not initialized.");
|
|
return ncclInternalError;
|
|
}
|
|
int ret;
|
|
GDRLOCKCALL(gdr_internal_unmap(g, handle, va, size), ret);
|
|
if (ret != 0) {
|
|
WARN("gdr_unmap(handle %lx, va %p, size %zu) failed: %d", handle.h, va, size, ret);
|
|
return ncclSystemError;
|
|
}
|
|
return ncclSuccess;
|
|
}
|
|
|
|
ncclResult_t wrap_gdr_runtime_get_version(int *major, int *minor) {
|
|
if (gdr_internal_runtime_get_version == NULL) {
|
|
WARN("GDRCOPY lib wrapper not initialized.");
|
|
return ncclInternalError;
|
|
}
|
|
gdr_internal_runtime_get_version(major, minor);
|
|
return ncclSuccess;
|
|
}
|
|
|
|
ncclResult_t wrap_gdr_driver_get_version(gdr_t g, int *major, int *minor) {
|
|
if (gdr_internal_driver_get_version == NULL) {
|
|
WARN("GDRCOPY lib wrapper not initialized.");
|
|
return ncclInternalError;
|
|
}
|
|
gdr_internal_driver_get_version(g, major, minor);
|
|
return ncclSuccess;
|
|
}
|
|
|
|
ncclResult_t wrap_gdr_copy_to_mapping(gdr_mh_t handle, void *map_d_ptr, const void *h_ptr, size_t size) {
|
|
if (gdr_internal_copy_to_mapping == NULL) {
|
|
WARN("GDRCOPY lib wrapper not initialized.");
|
|
return ncclInternalError;
|
|
}
|
|
int ret;
|
|
GDRLOCKCALL(gdr_internal_copy_to_mapping(handle, map_d_ptr, h_ptr, size), ret);
|
|
if (ret != 0) {
|
|
WARN("gdr_copy_to_mapping(handle %lx, map_d_ptr %p, h_ptr %p, size %zu) failed: %d", handle.h, map_d_ptr, h_ptr, size, ret);
|
|
return ncclSystemError;
|
|
}
|
|
return ncclSuccess;
|
|
}
|
|
|
|
ncclResult_t wrap_gdr_copy_from_mapping(gdr_mh_t handle, void *h_ptr, const void *map_d_ptr, size_t size) {
|
|
if (gdr_internal_copy_from_mapping == NULL) {
|
|
WARN("GDRCOPY lib wrapper not initialized.");
|
|
return ncclInternalError;
|
|
}
|
|
int ret;
|
|
GDRLOCKCALL(gdr_internal_copy_from_mapping(handle, h_ptr, map_d_ptr, size), ret);
|
|
if (ret != 0) {
|
|
WARN("gdr_copy_from_mapping(handle %lx, h_ptr %p, map_d_ptr %p, size %zu) failed: %d", handle.h, h_ptr, map_d_ptr, size, ret);
|
|
return ncclSystemError;
|
|
}
|
|
return ncclSuccess;
|
|
}
|
|
|
|
#endif /* !GDR_DIRECT */
|