Files
rocm-systems/projects/rccl/src/misc/cudawrap.cc
T

156 строки
4.5 KiB
C++
Исходник Обычный вид История

2022-05-24 02:02:31 -07:00
/*************************************************************************
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
*
* See LICENSE.txt for license information
************************************************************************/
#include "nccl.h"
#include "debug.h"
#include "cudawrap.h"
#include <dlfcn.h>
2022-08-18 02:53:17 -07:00
#define DECLARE_CUDA_PFN(symbol,version) PFN_##symbol##_v##version pfn_##symbol = nullptr
2022-05-24 02:02:31 -07:00
#if CUDART_VERSION >= 11030
/* CUDA Driver functions loaded with cuGetProcAddress for versioning */
2022-08-18 02:53:17 -07:00
DECLARE_CUDA_PFN(cuDeviceGet, 2000);
DECLARE_CUDA_PFN(cuDeviceGetAttribute, 2000);
DECLARE_CUDA_PFN(cuGetErrorString, 6000);
DECLARE_CUDA_PFN(cuGetErrorName, 6000);
2022-05-24 02:02:31 -07:00
/* enqueue.cc */
2022-08-18 02:53:17 -07:00
DECLARE_CUDA_PFN(cuMemGetAddressRange, 3020);
2022-05-24 02:02:31 -07:00
/* proxy.cc */
2022-08-18 02:53:17 -07:00
DECLARE_CUDA_PFN(cuCtxCreate, 3020);
DECLARE_CUDA_PFN(cuCtxDestroy, 4000);
DECLARE_CUDA_PFN(cuCtxSetCurrent, 4000);
2022-05-24 02:02:31 -07:00
#if CUDA_VERSION >= 11070
/* transport/collNet.cc/net.cc*/
2022-08-18 02:53:17 -07:00
DECLARE_CUDA_PFN(cuMemGetHandleForAddressRange, 11070); // DMA-BUF support
2022-05-24 02:02:31 -07:00
#endif
#endif
/* CUDA Driver functions loaded with dlsym() */
2022-08-18 02:53:17 -07:00
DECLARE_CUDA_PFN(cuInit, 2000);
DECLARE_CUDA_PFN(cuDriverGetVersion, 2020);
DECLARE_CUDA_PFN(cuGetProcAddress, 11030);
2022-05-24 02:02:31 -07:00
#define CUDA_DRIVER_MIN_VERSION 11030
static void *cudaLib;
2022-09-27 02:31:13 -07:00
int ncclCudaDriverVersionCache = -1;
2022-05-24 02:02:31 -07:00
#if CUDART_VERSION >= 11030
/*
Load the CUDA symbols
*/
2022-08-18 02:53:17 -07:00
static ncclResult_t cudaPfnFuncLoader(void) {
2022-05-24 02:02:31 -07:00
CUresult res;
2022-08-18 02:53:17 -07:00
#define LOAD_SYM(symbol, version, ignore) do { \
res = pfn_cuGetProcAddress(#symbol, (void **) (&pfn_##symbol), version, 0); \
2022-05-24 02:02:31 -07:00
if (res != 0) { \
if (!ignore) { \
2022-08-18 02:53:17 -07:00
WARN("Retrieve %s version %d failed with %d", #symbol, version, res); \
2022-05-24 02:02:31 -07:00
return ncclSystemError; } \
} } while(0)
2022-08-18 02:53:17 -07:00
LOAD_SYM(cuGetErrorString, 6000, 0);
LOAD_SYM(cuGetErrorName, 6000, 0);
LOAD_SYM(cuDeviceGet, 2000, 0);
LOAD_SYM(cuDeviceGetAttribute, 2000, 0);
LOAD_SYM(cuMemGetAddressRange, 3020, 1);
LOAD_SYM(cuCtxCreate, 3020, 1);
LOAD_SYM(cuCtxDestroy, 4000, 1);
LOAD_SYM(cuCtxSetCurrent, 4000, 1);
2022-05-24 02:02:31 -07:00
#if CUDA_VERSION >= 11070
2022-08-18 02:53:17 -07:00
LOAD_SYM(cuMemGetHandleForAddressRange, 11070, 1); // DMA-BUF support
2022-05-24 02:02:31 -07:00
#endif
return ncclSuccess;
}
#endif
2022-08-18 02:53:17 -07:00
static pthread_once_t initOnceControl = PTHREAD_ONCE_INIT;
static ncclResult_t initResult;
2022-05-24 02:02:31 -07:00
2022-08-18 02:53:17 -07:00
static void initOnceFunc() {
CUresult res;
2022-05-24 02:02:31 -07:00
/*
* Load CUDA driver library
*/
char path[1024];
char *ncclCudaPath = getenv("NCCL_CUDA_PATH");
if (ncclCudaPath == NULL)
snprintf(path, 1024, "%s", "libcuda.so");
else
snprintf(path, 1024, "%s%s", ncclCudaPath, "libcuda.so");
cudaLib = dlopen(path, RTLD_LAZY);
if (cudaLib == NULL) {
WARN("Failed to find CUDA library in %s (NCCL_CUDA_PATH=%s)", ncclCudaPath, ncclCudaPath);
goto error;
}
/*
* Load initial CUDA functions
*/
2022-08-18 02:53:17 -07:00
pfn_cuInit = (PFN_cuInit_v2000) dlsym(cudaLib, "cuInit");
2022-05-24 02:02:31 -07:00
if (pfn_cuInit == NULL) {
WARN("Failed to load CUDA missing symbol cuInit");
goto error;
}
2022-08-18 02:53:17 -07:00
pfn_cuDriverGetVersion = (PFN_cuDriverGetVersion_v2020) dlsym(cudaLib, "cuDriverGetVersion");
2022-05-24 02:02:31 -07:00
if (pfn_cuDriverGetVersion == NULL) {
WARN("Failed to load CUDA missing symbol cuDriverGetVersion");
goto error;
}
2022-09-27 02:31:13 -07:00
int driverVersion;
res = pfn_cuDriverGetVersion(&driverVersion);
2022-05-24 02:02:31 -07:00
if (res != 0) {
WARN("cuDriverGetVersion failed with %d", res);
goto error;
}
2022-09-27 02:31:13 -07:00
INFO(NCCL_INIT, "cudaDriverVersion %d", driverVersion);
2022-05-24 02:02:31 -07:00
2022-09-27 02:31:13 -07:00
if (driverVersion < CUDA_DRIVER_MIN_VERSION) {
// WARN("CUDA Driver version found is %d. Minimum requirement is %d", driverVersion, CUDA_DRIVER_MIN_VERSION);
2022-05-24 02:02:31 -07:00
// Silently ignore version check mismatch for backwards compatibility
goto error;
}
2022-08-18 02:53:17 -07:00
pfn_cuGetProcAddress = (PFN_cuGetProcAddress_v11030) dlsym(cudaLib, "cuGetProcAddress");
2022-05-24 02:02:31 -07:00
if (pfn_cuGetProcAddress == NULL) {
WARN("Failed to load CUDA missing symbol cuGetProcAddress");
goto error;
}
/*
* Required to initialize the CUDA Driver.
* Multiple calls of cuInit() will return immediately
* without making any relevant change
*/
pfn_cuInit(0);
2022-08-18 02:53:17 -07:00
#if CUDART_VERSION >= 11030
2022-05-24 02:02:31 -07:00
if (cudaPfnFuncLoader()) {
WARN("CUDA some PFN functions not found in the library");
goto error;
}
2022-08-18 02:53:17 -07:00
#endif
2022-05-24 02:02:31 -07:00
2022-08-18 02:53:17 -07:00
initResult = ncclSuccess;
return;
2022-05-24 02:02:31 -07:00
error:
2022-08-18 02:53:17 -07:00
initResult = ncclSystemError;
return;
2022-05-24 02:02:31 -07:00
}
2022-09-27 02:31:13 -07:00
ncclResult_t ncclCudaLibraryInit() {
2022-08-18 02:53:17 -07:00
pthread_once(&initOnceControl, initOnceFunc);
return initResult;
}