Merge pull request #782 from ROCmSoftwarePlatform/2.18.3
Sync up with NCCL 2.18.3
Этот коммит содержится в:
@@ -6,10 +6,46 @@
|
||||
|
||||
#include "nccl.h"
|
||||
#include "debug.h"
|
||||
#include "param.h"
|
||||
#include "cudawrap.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
// This env var (NCCL_CUMEM_ENABLE) toggles cuMem API usage
|
||||
NCCL_PARAM(CuMemEnable, "CUMEM_ENABLE", 0);
|
||||
|
||||
static int ncclCuMemSupported = 0;
|
||||
|
||||
// Determine whether CUMEM & VMM RDMA is supported on this platform
|
||||
int ncclIsCuMemSupported() {
|
||||
#if CUDART_VERSION < 11030
|
||||
return 0;
|
||||
#else
|
||||
CUdevice currentDev;
|
||||
int cudaDev;
|
||||
int cudaDriverVersion;
|
||||
int flag = 0;
|
||||
ncclResult_t ret = ncclSuccess;
|
||||
CUDACHECKGOTO(cudaDriverGetVersion(&cudaDriverVersion), ret, error);
|
||||
if (cudaDriverVersion < 12000) return 0; // Need CUDA_VISIBLE_DEVICES support
|
||||
CUDACHECKGOTO(cudaGetDevice(&cudaDev), ret, error);
|
||||
if (CUPFN(cuMemCreate) == NULL) return 0;
|
||||
CUCHECKGOTO(cuDeviceGet(¤tDev, cudaDev), ret, error);
|
||||
// Query device to see if CUMEM VMM support is available
|
||||
CUCHECKGOTO(cuDeviceGetAttribute(&flag, CU_DEVICE_ATTRIBUTE_VIRTUAL_MEMORY_MANAGEMENT_SUPPORTED, currentDev), ret, error);
|
||||
if (!flag) return 0;
|
||||
// Query device to see if CUMEM RDMA support is available
|
||||
CUCHECKGOTO(cuDeviceGetAttribute(&flag, CU_DEVICE_ATTRIBUTE_GPU_DIRECT_RDMA_WITH_CUDA_VMM_SUPPORTED, currentDev), ret, error);
|
||||
if (!flag) return 0;
|
||||
error:
|
||||
return (ret == ncclSuccess);
|
||||
#endif
|
||||
}
|
||||
|
||||
int ncclCuMemEnable() {
|
||||
return ((ncclParamCuMemEnable() == -2 && ncclCuMemSupported) || ncclParamCuMemEnable());
|
||||
}
|
||||
|
||||
#define DECLARE_CUDA_PFN(symbol,version) PFN_##symbol##_v##version pfn_##symbol = nullptr
|
||||
|
||||
#if CUDART_VERSION >= 11030
|
||||
@@ -35,6 +71,7 @@ DECLARE_CUDA_PFN(cuMemExportToShareableHandle, 10020);
|
||||
DECLARE_CUDA_PFN(cuMemImportFromShareableHandle, 10020);
|
||||
DECLARE_CUDA_PFN(cuMemMap, 10020);
|
||||
DECLARE_CUDA_PFN(cuMemRelease, 10020);
|
||||
DECLARE_CUDA_PFN(cuMemRetainAllocationHandle, 11000);
|
||||
DECLARE_CUDA_PFN(cuMemSetAccess, 10020);
|
||||
DECLARE_CUDA_PFN(cuMemUnmap, 10020);
|
||||
#if CUDA_VERSION >= 11070
|
||||
@@ -89,7 +126,6 @@ static ncclResult_t cudaPfnFuncLoader(void) {
|
||||
LOAD_SYM(cuCtxSetCurrent, 4000, 1);
|
||||
LOAD_SYM(cuCtxGetDevice, 2000, 1);
|
||||
/* cuMem API support */
|
||||
#if CUDA_VERSION >= 11030
|
||||
LOAD_SYM(cuMemAddressReserve, 10020, 1);
|
||||
LOAD_SYM(cuMemAddressFree, 10020, 1);
|
||||
LOAD_SYM(cuMemCreate, 10020, 1);
|
||||
@@ -98,9 +134,9 @@ static ncclResult_t cudaPfnFuncLoader(void) {
|
||||
LOAD_SYM(cuMemImportFromShareableHandle, 10020, 1);
|
||||
LOAD_SYM(cuMemMap, 10020, 1);
|
||||
LOAD_SYM(cuMemRelease, 10020, 1);
|
||||
LOAD_SYM(cuMemRetainAllocationHandle, 11000, 1);
|
||||
LOAD_SYM(cuMemSetAccess, 10020, 1);
|
||||
LOAD_SYM(cuMemUnmap, 10020, 1);
|
||||
#endif
|
||||
#if CUDA_VERSION >= 11070
|
||||
LOAD_SYM(cuMemGetHandleForAddressRange, 11070, 1); // DMA-BUF support
|
||||
#endif
|
||||
@@ -135,7 +171,7 @@ static void initOnceFunc() {
|
||||
if (ncclCudaPath == NULL)
|
||||
snprintf(path, 1024, "%s", "libcuda.so");
|
||||
else
|
||||
snprintf(path, 1024, "%s%s", ncclCudaPath, "libcuda.so");
|
||||
snprintf(path, 1024, "%s/%s", ncclCudaPath, "libcuda.so");
|
||||
|
||||
(void) dlerror(); // Clear any previous errors
|
||||
cudaLib = dlopen(path, RTLD_LAZY);
|
||||
@@ -195,6 +231,9 @@ static void initOnceFunc() {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Determine whether we support the cuMem APIs or not
|
||||
ncclCuMemSupported = ncclIsCuMemSupported();
|
||||
|
||||
initResult = ncclSuccess;
|
||||
return;
|
||||
error:
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ibvsymbols.h"
|
||||
|
||||
#ifdef NCCL_BUILD_RDMA_CORE
|
||||
/* RDMA-core linking mode. Symbols are pointers to linked IB Verbs */
|
||||
|
||||
#define ASSIGN_SYM(container, symbol, name) container->name= &symbol;
|
||||
|
||||
// Passthrough function for ibv_reg_mr macro in verbs.h
|
||||
struct ibv_mr* ibv_internal_reg_mr(
|
||||
struct ibv_pd* pd,
|
||||
void* addr,
|
||||
size_t length,
|
||||
int access) {
|
||||
return ibv_reg_mr(pd, addr, length, access);
|
||||
}
|
||||
|
||||
// Passthrough function for ibv_internal_query_port macro in verbs.h
|
||||
int ibv_internal_query_port(
|
||||
struct ibv_context* context,
|
||||
uint8_t port_num,
|
||||
struct ibv_port_attr* port_attr) {
|
||||
return ibv_query_port(context, port_num, port_attr);
|
||||
}
|
||||
|
||||
ncclResult_t buildIbvSymbols(struct ncclIbvSymbols* ibvSymbols) {
|
||||
ASSIGN_SYM(ibvSymbols, ibv_get_device_list, ibv_internal_get_device_list);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_free_device_list, ibv_internal_free_device_list);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_get_device_name, ibv_internal_get_device_name);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_open_device, ibv_internal_open_device);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_close_device, ibv_internal_close_device);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_get_async_event, ibv_internal_get_async_event);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_ack_async_event, ibv_internal_ack_async_event);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_query_device, ibv_internal_query_device);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_query_gid, ibv_internal_query_gid);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_query_qp, ibv_internal_query_qp);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_alloc_pd, ibv_internal_alloc_pd);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_dealloc_pd, ibv_internal_dealloc_pd);
|
||||
|
||||
ASSIGN_SYM(ibvSymbols, ibv_reg_mr_iova2, ibv_internal_reg_mr_iova2);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_reg_dmabuf_mr, ibv_internal_reg_dmabuf_mr);
|
||||
|
||||
ASSIGN_SYM(ibvSymbols, ibv_dereg_mr, ibv_internal_dereg_mr);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_create_cq, ibv_internal_create_cq);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_destroy_cq, ibv_internal_destroy_cq);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_create_qp, ibv_internal_create_qp);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_modify_qp, ibv_internal_modify_qp);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_destroy_qp, ibv_internal_destroy_qp);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_fork_init, ibv_internal_fork_init);
|
||||
ASSIGN_SYM(ibvSymbols, ibv_event_type_str, ibv_internal_event_type_str);
|
||||
|
||||
ibvSymbols->ibv_internal_reg_mr = &ibv_internal_reg_mr;
|
||||
ibvSymbols->ibv_internal_query_port = &ibv_internal_query_port;
|
||||
|
||||
return ncclSuccess;
|
||||
}
|
||||
|
||||
#else
|
||||
/* RDMA-core dynamic loading mode. Symbols are loaded from shared objects. */
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include "core.h"
|
||||
|
||||
// IBVERBS Library versioning
|
||||
#define IBVERBS_VERSION "IBVERBS_1.1"
|
||||
|
||||
ncclResult_t buildIbvSymbols(struct ncclIbvSymbols* ibvSymbols) {
|
||||
static void* ibvhandle = NULL;
|
||||
void* tmp;
|
||||
void** cast;
|
||||
|
||||
ibvhandle=dlopen("libibverbs.so", RTLD_NOW);
|
||||
if (!ibvhandle) {
|
||||
ibvhandle=dlopen("libibverbs.so.1", RTLD_NOW);
|
||||
if (!ibvhandle) {
|
||||
INFO(NCCL_INIT, "Failed to open libibverbs.so[.1]");
|
||||
goto teardown;
|
||||
}
|
||||
}
|
||||
|
||||
#define LOAD_SYM(handle, symbol, funcptr) do { \
|
||||
cast = (void**)&funcptr; \
|
||||
tmp = dlvsym(handle, symbol, IBVERBS_VERSION); \
|
||||
if (tmp == NULL) { \
|
||||
WARN("dlvsym failed on %s - %s version %s", symbol, dlerror(), IBVERBS_VERSION); \
|
||||
goto teardown; \
|
||||
} \
|
||||
*cast = tmp; \
|
||||
} while (0)
|
||||
|
||||
// Attempt to load a specific symbol version - fail silently
|
||||
#define LOAD_SYM_VERSION(handle, symbol, funcptr, version) do { \
|
||||
cast = (void**)&funcptr; \
|
||||
*cast = dlvsym(handle, symbol, version); \
|
||||
} while (0)
|
||||
|
||||
LOAD_SYM(ibvhandle, "ibv_get_device_list", ibvSymbols->ibv_internal_get_device_list);
|
||||
LOAD_SYM(ibvhandle, "ibv_free_device_list", ibvSymbols->ibv_internal_free_device_list);
|
||||
LOAD_SYM(ibvhandle, "ibv_get_device_name", ibvSymbols->ibv_internal_get_device_name);
|
||||
LOAD_SYM(ibvhandle, "ibv_open_device", ibvSymbols->ibv_internal_open_device);
|
||||
LOAD_SYM(ibvhandle, "ibv_close_device", ibvSymbols->ibv_internal_close_device);
|
||||
LOAD_SYM(ibvhandle, "ibv_get_async_event", ibvSymbols->ibv_internal_get_async_event);
|
||||
LOAD_SYM(ibvhandle, "ibv_ack_async_event", ibvSymbols->ibv_internal_ack_async_event);
|
||||
LOAD_SYM(ibvhandle, "ibv_query_device", ibvSymbols->ibv_internal_query_device);
|
||||
LOAD_SYM(ibvhandle, "ibv_query_port", ibvSymbols->ibv_internal_query_port);
|
||||
LOAD_SYM(ibvhandle, "ibv_query_gid", ibvSymbols->ibv_internal_query_gid);
|
||||
LOAD_SYM(ibvhandle, "ibv_query_qp", ibvSymbols->ibv_internal_query_qp);
|
||||
LOAD_SYM(ibvhandle, "ibv_alloc_pd", ibvSymbols->ibv_internal_alloc_pd);
|
||||
LOAD_SYM(ibvhandle, "ibv_dealloc_pd", ibvSymbols->ibv_internal_dealloc_pd);
|
||||
LOAD_SYM(ibvhandle, "ibv_reg_mr", ibvSymbols->ibv_internal_reg_mr);
|
||||
// Cherry-pick the ibv_reg_mr_iova2 API from IBVERBS 1.8
|
||||
LOAD_SYM_VERSION(ibvhandle, "ibv_reg_mr_iova2", ibvSymbols->ibv_internal_reg_mr_iova2, "IBVERBS_1.8");
|
||||
// Cherry-pick the ibv_reg_dmabuf_mr API from IBVERBS 1.12
|
||||
LOAD_SYM_VERSION(ibvhandle, "ibv_reg_dmabuf_mr", ibvSymbols->ibv_internal_reg_dmabuf_mr, "IBVERBS_1.12");
|
||||
LOAD_SYM(ibvhandle, "ibv_dereg_mr", ibvSymbols->ibv_internal_dereg_mr);
|
||||
LOAD_SYM(ibvhandle, "ibv_create_cq", ibvSymbols->ibv_internal_create_cq);
|
||||
LOAD_SYM(ibvhandle, "ibv_destroy_cq", ibvSymbols->ibv_internal_destroy_cq);
|
||||
LOAD_SYM(ibvhandle, "ibv_create_qp", ibvSymbols->ibv_internal_create_qp);
|
||||
LOAD_SYM(ibvhandle, "ibv_modify_qp", ibvSymbols->ibv_internal_modify_qp);
|
||||
LOAD_SYM(ibvhandle, "ibv_destroy_qp", ibvSymbols->ibv_internal_destroy_qp);
|
||||
LOAD_SYM(ibvhandle, "ibv_fork_init", ibvSymbols->ibv_internal_fork_init);
|
||||
LOAD_SYM(ibvhandle, "ibv_event_type_str", ibvSymbols->ibv_internal_event_type_str);
|
||||
|
||||
return ncclSuccess;
|
||||
|
||||
teardown:
|
||||
ibvSymbols->ibv_internal_get_device_list = NULL;
|
||||
ibvSymbols->ibv_internal_free_device_list = NULL;
|
||||
ibvSymbols->ibv_internal_get_device_name = NULL;
|
||||
ibvSymbols->ibv_internal_open_device = NULL;
|
||||
ibvSymbols->ibv_internal_close_device = NULL;
|
||||
ibvSymbols->ibv_internal_get_async_event = NULL;
|
||||
ibvSymbols->ibv_internal_ack_async_event = NULL;
|
||||
ibvSymbols->ibv_internal_query_device = NULL;
|
||||
ibvSymbols->ibv_internal_query_port = NULL;
|
||||
ibvSymbols->ibv_internal_query_gid = NULL;
|
||||
ibvSymbols->ibv_internal_query_qp = NULL;
|
||||
ibvSymbols->ibv_internal_alloc_pd = NULL;
|
||||
ibvSymbols->ibv_internal_dealloc_pd = NULL;
|
||||
ibvSymbols->ibv_internal_reg_mr = NULL;
|
||||
ibvSymbols->ibv_internal_reg_mr_iova2 = NULL;
|
||||
ibvSymbols->ibv_internal_reg_dmabuf_mr = NULL;
|
||||
ibvSymbols->ibv_internal_dereg_mr = NULL;
|
||||
ibvSymbols->ibv_internal_create_cq = NULL;
|
||||
ibvSymbols->ibv_internal_destroy_cq = NULL;
|
||||
ibvSymbols->ibv_internal_create_qp = NULL;
|
||||
ibvSymbols->ibv_internal_modify_qp = NULL;
|
||||
ibvSymbols->ibv_internal_destroy_qp = NULL;
|
||||
ibvSymbols->ibv_internal_fork_init = NULL;
|
||||
ibvSymbols->ibv_internal_event_type_str = NULL;
|
||||
|
||||
if (ibvhandle != NULL) dlclose(ibvhandle);
|
||||
return ncclSystemError;
|
||||
}
|
||||
|
||||
#endif
|
||||
+54
-182
@@ -8,314 +8,186 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include "core.h"
|
||||
|
||||
/*Function Pointers*/
|
||||
int (*ibv_internal_fork_init)(void);
|
||||
struct ibv_device** (*ibv_internal_get_device_list)(int *num_devices);
|
||||
void (*ibv_internal_free_device_list)(struct ibv_device **list);
|
||||
const char * (*ibv_internal_get_device_name)(struct ibv_device *device);
|
||||
struct ibv_context* (*ibv_internal_open_device)(struct ibv_device* device);
|
||||
int (*ibv_internal_close_device)(struct ibv_context *context);
|
||||
int (*ibv_internal_get_async_event)(struct ibv_context *context, struct ibv_async_event *event);
|
||||
void (*ibv_internal_ack_async_event)(struct ibv_async_event *event);
|
||||
int (*ibv_internal_query_device)(struct ibv_context *context, struct ibv_device_attr *device_attr);
|
||||
int (*ibv_internal_query_port)(struct ibv_context *context, uint8_t port_num, struct ibv_port_attr *port_attr);
|
||||
int (*ibv_internal_query_gid)(struct ibv_context *context, uint8_t port_num, int index, union ibv_gid *gid);
|
||||
int (*ibv_internal_query_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask, struct ibv_qp_init_attr *init_attr);
|
||||
struct ibv_pd * (*ibv_internal_alloc_pd)(struct ibv_context *context);
|
||||
int (*ibv_internal_dealloc_pd)(struct ibv_pd *pd);
|
||||
struct ibv_mr * (*ibv_internal_reg_mr)(struct ibv_pd *pd, void *addr, size_t length, int access);
|
||||
struct ibv_mr * (*ibv_internal_reg_mr_iova2)(struct ibv_pd *pd, void *addr, size_t length, uint64_t iova, int access);
|
||||
/* DMA-BUF support */
|
||||
struct ibv_mr * (*ibv_internal_reg_dmabuf_mr)(struct ibv_pd *pd, uint64_t offset, size_t length, uint64_t iova, int fd, int access);
|
||||
int (*ibv_internal_dereg_mr)(struct ibv_mr *mr);
|
||||
struct ibv_cq * (*ibv_internal_create_cq)(struct ibv_context *context, int cqe, void *cq_context, struct ibv_comp_channel *channel, int comp_vector);
|
||||
int (*ibv_internal_destroy_cq)(struct ibv_cq *cq);
|
||||
struct ibv_qp * (*ibv_internal_create_qp)(struct ibv_pd *pd, struct ibv_qp_init_attr *qp_init_attr);
|
||||
int (*ibv_internal_modify_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask);
|
||||
int (*ibv_internal_destroy_qp)(struct ibv_qp *qp);
|
||||
const char * (*ibv_internal_event_type_str)(enum ibv_event_type event);
|
||||
|
||||
// IBVERBS Library versioning
|
||||
#define IBVERBS_VERSION "IBVERBS_1.1"
|
||||
#include "ibvsymbols.h"
|
||||
|
||||
static pthread_once_t initOnceControl = PTHREAD_ONCE_INIT;
|
||||
static ncclResult_t initResult;
|
||||
|
||||
static void initOnceFunc(void) {
|
||||
static void* ibvhandle = NULL;
|
||||
void* tmp;
|
||||
void** cast;
|
||||
|
||||
ibvhandle=dlopen("libibverbs.so", RTLD_NOW);
|
||||
if (!ibvhandle) {
|
||||
ibvhandle=dlopen("libibverbs.so.1", RTLD_NOW);
|
||||
if (!ibvhandle) {
|
||||
INFO(NCCL_INIT, "Failed to open libibverbs.so[.1]");
|
||||
goto teardown;
|
||||
}
|
||||
}
|
||||
|
||||
#define LOAD_SYM(handle, symbol, funcptr) do { \
|
||||
cast = (void**)&funcptr; \
|
||||
tmp = dlvsym(handle, symbol, IBVERBS_VERSION); \
|
||||
if (tmp == NULL) { \
|
||||
WARN("dlvsym failed on %s - %s version %s", symbol, dlerror(), IBVERBS_VERSION); \
|
||||
goto teardown; \
|
||||
} \
|
||||
*cast = tmp; \
|
||||
} while (0)
|
||||
|
||||
// Attempt to load a specific symbol version - fail silently
|
||||
#define LOAD_SYM_VERSION(handle, symbol, funcptr, version) do { \
|
||||
cast = (void**)&funcptr; \
|
||||
*cast = dlvsym(handle, symbol, version); \
|
||||
} while (0)
|
||||
|
||||
LOAD_SYM(ibvhandle, "ibv_get_device_list", ibv_internal_get_device_list);
|
||||
LOAD_SYM(ibvhandle, "ibv_free_device_list", ibv_internal_free_device_list);
|
||||
LOAD_SYM(ibvhandle, "ibv_get_device_name", ibv_internal_get_device_name);
|
||||
LOAD_SYM(ibvhandle, "ibv_open_device", ibv_internal_open_device);
|
||||
LOAD_SYM(ibvhandle, "ibv_close_device", ibv_internal_close_device);
|
||||
LOAD_SYM(ibvhandle, "ibv_get_async_event", ibv_internal_get_async_event);
|
||||
LOAD_SYM(ibvhandle, "ibv_ack_async_event", ibv_internal_ack_async_event);
|
||||
LOAD_SYM(ibvhandle, "ibv_query_device", ibv_internal_query_device);
|
||||
LOAD_SYM(ibvhandle, "ibv_query_port", ibv_internal_query_port);
|
||||
LOAD_SYM(ibvhandle, "ibv_query_gid", ibv_internal_query_gid);
|
||||
LOAD_SYM(ibvhandle, "ibv_query_qp", ibv_internal_query_qp);
|
||||
LOAD_SYM(ibvhandle, "ibv_alloc_pd", ibv_internal_alloc_pd);
|
||||
LOAD_SYM(ibvhandle, "ibv_dealloc_pd", ibv_internal_dealloc_pd);
|
||||
LOAD_SYM(ibvhandle, "ibv_reg_mr", ibv_internal_reg_mr);
|
||||
// Cherry-pick the ibv_reg_mr_iova2 API from IBVERBS 1.8
|
||||
LOAD_SYM_VERSION(ibvhandle, "ibv_reg_mr_iova2", ibv_internal_reg_mr_iova2, "IBVERBS_1.8");
|
||||
// Cherry-pick the ibv_reg_dmabuf_mr API from IBVERBS 1.12
|
||||
LOAD_SYM_VERSION(ibvhandle, "ibv_reg_dmabuf_mr", ibv_internal_reg_dmabuf_mr, "IBVERBS_1.12");
|
||||
LOAD_SYM(ibvhandle, "ibv_dereg_mr", ibv_internal_dereg_mr);
|
||||
LOAD_SYM(ibvhandle, "ibv_create_cq", ibv_internal_create_cq);
|
||||
LOAD_SYM(ibvhandle, "ibv_destroy_cq", ibv_internal_destroy_cq);
|
||||
LOAD_SYM(ibvhandle, "ibv_create_qp", ibv_internal_create_qp);
|
||||
LOAD_SYM(ibvhandle, "ibv_modify_qp", ibv_internal_modify_qp);
|
||||
LOAD_SYM(ibvhandle, "ibv_destroy_qp", ibv_internal_destroy_qp);
|
||||
LOAD_SYM(ibvhandle, "ibv_fork_init", ibv_internal_fork_init);
|
||||
LOAD_SYM(ibvhandle, "ibv_event_type_str", ibv_internal_event_type_str);
|
||||
|
||||
initResult = ncclSuccess;
|
||||
return;
|
||||
|
||||
teardown:
|
||||
ibv_internal_get_device_list = NULL;
|
||||
ibv_internal_free_device_list = NULL;
|
||||
ibv_internal_get_device_name = NULL;
|
||||
ibv_internal_open_device = NULL;
|
||||
ibv_internal_close_device = NULL;
|
||||
ibv_internal_get_async_event = NULL;
|
||||
ibv_internal_ack_async_event = NULL;
|
||||
ibv_internal_query_device = NULL;
|
||||
ibv_internal_query_port = NULL;
|
||||
ibv_internal_query_gid = NULL;
|
||||
ibv_internal_query_qp = NULL;
|
||||
ibv_internal_alloc_pd = NULL;
|
||||
ibv_internal_dealloc_pd = NULL;
|
||||
ibv_internal_reg_mr = NULL;
|
||||
ibv_internal_reg_mr_iova2 = NULL;
|
||||
ibv_internal_reg_dmabuf_mr = NULL;
|
||||
ibv_internal_dereg_mr = NULL;
|
||||
ibv_internal_create_cq = NULL;
|
||||
ibv_internal_destroy_cq = NULL;
|
||||
ibv_internal_create_qp = NULL;
|
||||
ibv_internal_modify_qp = NULL;
|
||||
ibv_internal_destroy_qp = NULL;
|
||||
ibv_internal_fork_init = NULL;
|
||||
ibv_internal_event_type_str = NULL;
|
||||
|
||||
if (ibvhandle != NULL) dlclose(ibvhandle);
|
||||
initResult = ncclSystemError;
|
||||
return;
|
||||
}
|
||||
struct ncclIbvSymbols ibvSymbols;
|
||||
|
||||
ncclResult_t wrap_ibv_symbols(void) {
|
||||
pthread_once(&initOnceControl, initOnceFunc);
|
||||
pthread_once(&initOnceControl,
|
||||
[](){ initResult = buildIbvSymbols(&ibvSymbols); });
|
||||
return initResult;
|
||||
}
|
||||
|
||||
#define IBV_PTR_CHECK_ERRNO(name_internal, call, retval, error_retval, name) \
|
||||
if (name_internal == NULL) { \
|
||||
/* CHECK_NOT_NULL: helper macro to check for NULL symbol */
|
||||
#define CHECK_NOT_NULL(container, internal_name) \
|
||||
if (container.internal_name == NULL) { \
|
||||
WARN("lib wrapper not initialized."); \
|
||||
return ncclInternalError; \
|
||||
} \
|
||||
retval = call; \
|
||||
}
|
||||
|
||||
#define IBV_PTR_CHECK_ERRNO(container, internal_name, call, retval, error_retval, name) \
|
||||
CHECK_NOT_NULL(container, internal_name); \
|
||||
retval = container.call; \
|
||||
if (retval == error_retval) { \
|
||||
WARN("Call to " name " failed with error %s", strerror(errno)); \
|
||||
return ncclSystemError; \
|
||||
} \
|
||||
return ncclSuccess;
|
||||
|
||||
#define IBV_PTR_CHECK(name_internal, call, retval, error_retval, name) \
|
||||
if (name_internal == NULL) { \
|
||||
WARN("lib wrapper not initialized."); \
|
||||
return ncclInternalError; \
|
||||
} \
|
||||
retval = call; \
|
||||
#define IBV_PTR_CHECK(container, internal_name, call, retval, error_retval, name) \
|
||||
CHECK_NOT_NULL(container, internal_name); \
|
||||
retval = container.call; \
|
||||
if (retval == error_retval) { \
|
||||
WARN("Call to " name " failed"); \
|
||||
return ncclSystemError; \
|
||||
} \
|
||||
return ncclSuccess;
|
||||
|
||||
#define IBV_INT_CHECK_RET_ERRNO(name_internal, call, success_retval, name) \
|
||||
if (name_internal == NULL) { \
|
||||
WARN("lib wrapper not initialized."); \
|
||||
return ncclInternalError; \
|
||||
} \
|
||||
int ret = call; \
|
||||
#define IBV_INT_CHECK_RET_ERRNO(container, internal_name, call, success_retval, name) \
|
||||
CHECK_NOT_NULL(container, internal_name); \
|
||||
int ret = container.call; \
|
||||
if (ret != success_retval) { \
|
||||
WARN("Call to " name " failed with error %s", strerror(ret)); \
|
||||
return ncclSystemError; \
|
||||
} \
|
||||
return ncclSuccess;
|
||||
|
||||
#define IBV_INT_CHECK(name_internal, call, error_retval, name) \
|
||||
if (name_internal == NULL) { \
|
||||
WARN("lib wrapper not initialized."); \
|
||||
return ncclInternalError; \
|
||||
} \
|
||||
int ret = call; \
|
||||
#define IBV_INT_CHECK(container, internal_name, call, error_retval, name) \
|
||||
CHECK_NOT_NULL(container, internal_name); \
|
||||
int ret = container.call; \
|
||||
if (ret == error_retval) { \
|
||||
WARN("Call to " name " failed"); \
|
||||
return ncclSystemError; \
|
||||
} \
|
||||
return ncclSuccess;
|
||||
|
||||
#define IBV_PASSTHRU(name_internal, call) \
|
||||
if (name_internal == NULL) { \
|
||||
WARN("lib wrapper not initialized."); \
|
||||
return ncclInternalError; \
|
||||
} \
|
||||
call; \
|
||||
#define IBV_PASSTHRU(container, internal_name, call) \
|
||||
CHECK_NOT_NULL(container, internal_name); \
|
||||
container.call; \
|
||||
return ncclSuccess;
|
||||
|
||||
ncclResult_t wrap_ibv_fork_init() {
|
||||
IBV_INT_CHECK(ibv_internal_fork_init, ibv_internal_fork_init(), -1, "ibv_fork_init");
|
||||
IBV_INT_CHECK(ibvSymbols, ibv_internal_fork_init, ibv_internal_fork_init(), -1, "ibv_fork_init");
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_get_device_list(struct ibv_device ***ret, int *num_devices) {
|
||||
*ret = ibv_internal_get_device_list(num_devices);
|
||||
*ret = ibvSymbols.ibv_internal_get_device_list(num_devices);
|
||||
if (*ret == NULL) *num_devices = 0;
|
||||
return ncclSuccess;
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_free_device_list(struct ibv_device **list) {
|
||||
IBV_PASSTHRU(ibv_internal_free_device_list, ibv_internal_free_device_list(list));
|
||||
IBV_PASSTHRU(ibvSymbols, ibv_internal_free_device_list, ibv_internal_free_device_list(list));
|
||||
}
|
||||
|
||||
const char *wrap_ibv_get_device_name(struct ibv_device *device) {
|
||||
if (ibv_internal_get_device_name == NULL) {
|
||||
if (ibvSymbols.ibv_internal_get_device_name == NULL) {
|
||||
WARN("lib wrapper not initialized.");
|
||||
exit(-1);
|
||||
}
|
||||
return ibv_internal_get_device_name(device);
|
||||
return ibvSymbols.ibv_internal_get_device_name(device);
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_open_device(struct ibv_context **ret, struct ibv_device *device) { /*returns 0 on success, -1 on failure*/
|
||||
IBV_PTR_CHECK(ibv_internal_open_device, ibv_internal_open_device(device), *ret, NULL, "ibv_open_device");
|
||||
IBV_PTR_CHECK(ibvSymbols, ibv_internal_open_device, ibv_internal_open_device(device), *ret, NULL, "ibv_open_device");
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_close_device(struct ibv_context *context) { /*returns 0 on success, -1 on failure*/
|
||||
IBV_INT_CHECK(ibv_internal_close_device, ibv_internal_close_device(context), -1, "ibv_close_device");
|
||||
IBV_INT_CHECK(ibvSymbols, ibv_internal_close_device, ibv_internal_close_device(context), -1, "ibv_close_device");
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_get_async_event(struct ibv_context *context, struct ibv_async_event *event) { /*returns 0 on success, and -1 on error*/
|
||||
IBV_INT_CHECK(ibv_internal_get_async_event, ibv_internal_get_async_event(context, event), -1, "ibv_get_async_event");
|
||||
IBV_INT_CHECK(ibvSymbols, ibv_internal_get_async_event, ibv_internal_get_async_event(context, event), -1, "ibv_get_async_event");
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_ack_async_event(struct ibv_async_event *event) {
|
||||
IBV_PASSTHRU(ibv_internal_ack_async_event, ibv_internal_ack_async_event(event));
|
||||
IBV_PASSTHRU(ibvSymbols, ibv_internal_ack_async_event, ibv_internal_ack_async_event(event));
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_query_device(struct ibv_context *context, struct ibv_device_attr *device_attr) { /*returns 0 on success, or the value of errno on failure (which indicates the failure reason)*/
|
||||
IBV_INT_CHECK_RET_ERRNO(ibv_internal_query_device, ibv_internal_query_device(context, device_attr), 0, "ibv_query_device");
|
||||
IBV_INT_CHECK_RET_ERRNO(ibvSymbols, ibv_internal_query_device, ibv_internal_query_device(context, device_attr), 0, "ibv_query_device");
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_query_port(struct ibv_context *context, uint8_t port_num, struct ibv_port_attr *port_attr) { /*returns 0 on success, or the value of errno on failure (which indicates the failure reason)*/
|
||||
IBV_INT_CHECK_RET_ERRNO(ibv_internal_query_port, ibv_internal_query_port(context, port_num, port_attr), 0, "ibv_query_port");
|
||||
IBV_INT_CHECK_RET_ERRNO(ibvSymbols, ibv_internal_query_port, ibv_internal_query_port(context, port_num, port_attr), 0, "ibv_query_port");
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_query_gid(struct ibv_context *context, uint8_t port_num, int index, union ibv_gid *gid) {
|
||||
IBV_INT_CHECK_RET_ERRNO(ibv_internal_query_gid, ibv_internal_query_gid(context, port_num, index, gid), 0, "ibv_query_gid");
|
||||
IBV_INT_CHECK_RET_ERRNO(ibvSymbols, ibv_internal_query_gid, ibv_internal_query_gid(context, port_num, index, gid), 0, "ibv_query_gid");
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask, struct ibv_qp_init_attr *init_attr) {
|
||||
IBV_INT_CHECK_RET_ERRNO(ibv_internal_query_qp, ibv_internal_query_qp(qp, attr, attr_mask, init_attr), 0, "ibv_query_qp");
|
||||
IBV_INT_CHECK_RET_ERRNO(ibvSymbols, ibv_internal_query_qp, ibv_internal_query_qp(qp, attr, attr_mask, init_attr), 0, "ibv_query_qp");
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_alloc_pd(struct ibv_pd **ret, struct ibv_context *context) {
|
||||
IBV_PTR_CHECK_ERRNO(ibv_internal_alloc_pd, ibv_internal_alloc_pd(context), *ret, NULL, "ibv_alloc_pd");
|
||||
IBV_PTR_CHECK_ERRNO(ibvSymbols, ibv_internal_alloc_pd, ibv_internal_alloc_pd(context), *ret, NULL, "ibv_alloc_pd");
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_dealloc_pd(struct ibv_pd *pd) { /*returns 0 on success, or the value of errno on failure (which indicates the failure reason)*/
|
||||
IBV_INT_CHECK_RET_ERRNO(ibv_internal_dealloc_pd, ibv_internal_dealloc_pd(pd), 0, "ibv_dealloc_pd");
|
||||
IBV_INT_CHECK_RET_ERRNO(ibvSymbols, ibv_internal_dealloc_pd, ibv_internal_dealloc_pd(pd), 0, "ibv_dealloc_pd");
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_reg_mr(struct ibv_mr **ret, struct ibv_pd *pd, void *addr, size_t length, int access) {
|
||||
IBV_PTR_CHECK_ERRNO(ibv_internal_reg_mr, ibv_internal_reg_mr(pd, addr, length, access), *ret, NULL, "ibv_reg_mr");
|
||||
IBV_PTR_CHECK_ERRNO(ibvSymbols, ibv_internal_reg_mr, ibv_internal_reg_mr(pd, addr, length, access), *ret, NULL, "ibv_reg_mr");
|
||||
}
|
||||
|
||||
struct ibv_mr * wrap_direct_ibv_reg_mr(struct ibv_pd *pd, void *addr, size_t length, int access) {
|
||||
if (ibv_internal_reg_mr == NULL) {
|
||||
if (ibvSymbols.ibv_internal_reg_mr == NULL) {
|
||||
WARN("lib wrapper not initialized.");
|
||||
return NULL;
|
||||
}
|
||||
return ibv_internal_reg_mr(pd, addr, length, access);
|
||||
return ibvSymbols.ibv_internal_reg_mr(pd, addr, length, access);
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_reg_mr_iova2(struct ibv_mr **ret, struct ibv_pd *pd, void *addr, size_t length, uint64_t iova, int access) {
|
||||
if (ibv_internal_reg_mr_iova2 == NULL) {
|
||||
if (ibvSymbols.ibv_internal_reg_mr_iova2 == NULL) {
|
||||
return ncclInternalError;
|
||||
}
|
||||
if (ret == NULL) { return ncclSuccess; } // Assume dummy call
|
||||
IBV_PTR_CHECK_ERRNO(ibv_internal_reg_mr_iova2, ibv_internal_reg_mr_iova2(pd, addr, length, iova, access), *ret, NULL, "ibv_reg_mr_iova2");
|
||||
IBV_PTR_CHECK_ERRNO(ibvSymbols, ibv_internal_reg_mr_iova2, ibv_internal_reg_mr_iova2(pd, addr, length, iova, access), *ret, NULL, "ibv_reg_mr_iova2");
|
||||
}
|
||||
|
||||
/* DMA-BUF support */
|
||||
ncclResult_t wrap_ibv_reg_dmabuf_mr(struct ibv_mr **ret, struct ibv_pd *pd, uint64_t offset, size_t length, uint64_t iova, int fd, int access) {
|
||||
IBV_PTR_CHECK_ERRNO(ibv_internal_reg_dmabuf_mr, ibv_internal_reg_dmabuf_mr(pd, offset, length, iova, fd, access), *ret, NULL, "ibv_reg_dmabuf_mr");
|
||||
IBV_PTR_CHECK_ERRNO(ibvSymbols, ibv_internal_reg_dmabuf_mr, ibv_internal_reg_dmabuf_mr(pd, offset, length, iova, fd, access), *ret, NULL, "ibv_reg_dmabuf_mr");
|
||||
}
|
||||
|
||||
struct ibv_mr * wrap_direct_ibv_reg_dmabuf_mr(struct ibv_pd *pd, uint64_t offset, size_t length, uint64_t iova, int fd, int access) {
|
||||
if (ibv_internal_reg_dmabuf_mr == NULL) {
|
||||
if (ibvSymbols.ibv_internal_reg_dmabuf_mr == NULL) {
|
||||
errno = EOPNOTSUPP; // ncclIbDmaBufSupport() requires this errno being set
|
||||
return NULL;
|
||||
}
|
||||
return ibv_internal_reg_dmabuf_mr(pd, offset, length, iova, fd, access);
|
||||
return ibvSymbols.ibv_internal_reg_dmabuf_mr(pd, offset, length, iova, fd, access);
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_dereg_mr(struct ibv_mr *mr) { /*returns 0 on success, or the value of errno on failure (which indicates the failure reason)*/
|
||||
IBV_INT_CHECK_RET_ERRNO(ibv_internal_dereg_mr, ibv_internal_dereg_mr(mr), 0, "ibv_dereg_mr");
|
||||
IBV_INT_CHECK_RET_ERRNO(ibvSymbols, ibv_internal_dereg_mr, ibv_internal_dereg_mr(mr), 0, "ibv_dereg_mr");
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_create_cq(struct ibv_cq **ret, struct ibv_context *context, int cqe, void *cq_context, struct ibv_comp_channel *channel, int comp_vector) {
|
||||
IBV_PTR_CHECK_ERRNO(ibv_internal_create_cq, ibv_internal_create_cq(context, cqe, cq_context, channel, comp_vector), *ret, NULL, "ibv_create_cq");
|
||||
IBV_PTR_CHECK_ERRNO(ibvSymbols, ibv_internal_create_cq, ibv_internal_create_cq(context, cqe, cq_context, channel, comp_vector), *ret, NULL, "ibv_create_cq");
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_destroy_cq(struct ibv_cq *cq) {
|
||||
IBV_INT_CHECK_RET_ERRNO(ibv_internal_destroy_cq, ibv_internal_destroy_cq(cq), 0, "ibv_destroy_cq");
|
||||
IBV_INT_CHECK_RET_ERRNO(ibvSymbols, ibv_internal_destroy_cq, ibv_internal_destroy_cq(cq), 0, "ibv_destroy_cq");
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_destroy_qp(struct ibv_qp *qp) {
|
||||
IBV_INT_CHECK_RET_ERRNO(ibv_internal_destroy_qp, ibv_internal_destroy_qp(qp), 0, "ibv_destroy_qp");
|
||||
IBV_INT_CHECK_RET_ERRNO(ibvSymbols, ibv_internal_destroy_qp, ibv_internal_destroy_qp(qp), 0, "ibv_destroy_qp");
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_create_qp(struct ibv_qp **ret, struct ibv_pd *pd, struct ibv_qp_init_attr *qp_init_attr) {
|
||||
IBV_PTR_CHECK_ERRNO(ibv_internal_create_qp, ibv_internal_create_qp(pd, qp_init_attr), *ret, NULL, "ibv_create_qp");
|
||||
IBV_PTR_CHECK_ERRNO(ibvSymbols, ibv_internal_create_qp, ibv_internal_create_qp(pd, qp_init_attr), *ret, NULL, "ibv_create_qp");
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask) { /*returns 0 on success, or the value of errno on failure (which indicates the failure reason)*/
|
||||
IBV_INT_CHECK_RET_ERRNO(ibv_internal_modify_qp, ibv_internal_modify_qp(qp, attr, attr_mask), 0, "ibv_modify_qp");
|
||||
IBV_INT_CHECK_RET_ERRNO(ibvSymbols, ibv_internal_modify_qp, ibv_internal_modify_qp(qp, attr, attr_mask), 0, "ibv_modify_qp");
|
||||
}
|
||||
|
||||
ncclResult_t wrap_ibv_event_type_str(char **ret, enum ibv_event_type event) {
|
||||
*ret = (char *) ibv_internal_event_type_str(event);
|
||||
*ret = (char *) ibvSymbols.ibv_internal_event_type_str(event);
|
||||
return ncclSuccess;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ ncclResult_t mscclSetupProxy(struct mscclAlgo* hostAlgo, ncclComm_t comm) {
|
||||
proxyOp.pattern = 0;
|
||||
proxyOp.root = 0;
|
||||
proxyOp.nbytes = status.stepSize*proxyOp.sliceSteps;
|
||||
proxyOp.opCount = comm->collOpCount;
|
||||
proxyOp.opCount = comm->sharedRes->collOpCount;
|
||||
int nLoops = (int)(DIVUP(status.nBytes, (size_t)((size_t)hostAlgo->nChunksPerLoop*(size_t)status.chunkEffectiveSize)));
|
||||
int nLoopsChunkSteps = nLoops * status.chunkSteps;
|
||||
for (int ch = 0; ch < hostAlgo->nChannels; ch++) {
|
||||
@@ -123,7 +123,7 @@ ncclResult_t mscclSetupProxy(struct mscclAlgo* hostAlgo, ncclComm_t comm) {
|
||||
}
|
||||
proxyOp.nsteps = nLoopsChunkSteps * nRecvs;
|
||||
if (proxyOp.nsteps > 0) {
|
||||
NCCLCHECK(mscclSaveProxy(ncclChannel, proxyRecv, recvPeer->peer, &proxyOp, 0));
|
||||
NCCLCHECK(mscclSaveProxy(comm, ncclChannel, proxyRecv, recvPeer->peer, &proxyOp, 0));
|
||||
}
|
||||
}
|
||||
for (int i=0; i<mscclChannel->nSendPeers; i++){
|
||||
@@ -136,12 +136,12 @@ ncclResult_t mscclSetupProxy(struct mscclAlgo* hostAlgo, ncclComm_t comm) {
|
||||
}
|
||||
proxyOp.nsteps = nLoopsChunkSteps * nSends;
|
||||
if (proxyOp.nsteps > 0) {
|
||||
NCCLCHECK(mscclSaveProxy(ncclChannel, proxySend, sendPeer->peer, &proxyOp, 0));
|
||||
NCCLCHECK(mscclSaveProxy(comm, ncclChannel, proxySend, sendPeer->peer, &proxyOp, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
NCCLCHECK(ncclProxyStart(comm));
|
||||
comm->collOpCount++;
|
||||
comm->sharedRes->collOpCount++;
|
||||
return ncclSuccess;
|
||||
}
|
||||
|
||||
|
||||
@@ -170,4 +170,6 @@ error:
|
||||
return ncclSystemError;
|
||||
}
|
||||
|
||||
|
||||
int ncclCuMemEnable() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <utils.h>
|
||||
|
||||
struct shmHandleInternal {
|
||||
int fd;
|
||||
@@ -31,7 +32,7 @@ static void shmHandleInit(int fd, char* shmPath, size_t shmSize, size_t realShmS
|
||||
handle->devShmPtr = dptr;
|
||||
handle->shmSize = shmSize;
|
||||
handle->realShmSize = realShmSize;
|
||||
handle->refcount = (int*)(hptr + shmSize);
|
||||
handle->refcount = (hptr != NULL) ? (int*)(hptr + shmSize) : NULL;
|
||||
if (create) {
|
||||
int slen = strlen(shmPath);
|
||||
handle->shmPath = (char*)malloc(slen + 1);
|
||||
@@ -80,23 +81,20 @@ ncclResult_t ncclShmOpen(char* shmPath, size_t shmSize, void** shmPtr, void** de
|
||||
if (hptr == MAP_FAILED) {
|
||||
WARN("Could not map %s size %zi, error: %s", shmPath, realShmSize, strerror(errno));
|
||||
ret = ncclSystemError;
|
||||
hptr = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (create) {
|
||||
*(int*)(hptr + shmSize) = refcount;
|
||||
} else {
|
||||
int remref = __atomic_sub_fetch((int*)(hptr + shmSize), 1, __ATOMIC_RELAXED);
|
||||
int remref = ncclAtomicRefCountDecrement((int*)(hptr + shmSize));
|
||||
if (remref == 0) {
|
||||
/* the last peer has completed attachment, it should unlink the shm mem file. */
|
||||
if (unlink(shmPath) != 0) {
|
||||
WARN("unlink shared memory %s failed, error: %s", shmPath, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
if (refcount != -1) {
|
||||
WARN("attaching memory should only reduce refcount by 1 but %d is passed", refcount);
|
||||
}
|
||||
}
|
||||
|
||||
if (devShmPtr) {
|
||||
@@ -128,13 +126,13 @@ ncclResult_t ncclShmClose(ncclShmHandle_t handle) {
|
||||
if (tmphandle) {
|
||||
if (tmphandle->fd >= 0) {
|
||||
close(tmphandle->fd);
|
||||
if (tmphandle->shmPath != NULL && *tmphandle->refcount > 0) {
|
||||
if (tmphandle->shmPath != NULL && tmphandle->refcount != NULL && *tmphandle->refcount > 0) {
|
||||
if (unlink(tmphandle->shmPath) != 0) {
|
||||
WARN("unlink shared memory %s failed, error: %s", tmphandle->shmPath, strerror(errno));
|
||||
ret = ncclSystemError;
|
||||
}
|
||||
free(tmphandle->shmPath);
|
||||
}
|
||||
free(tmphandle->shmPath);
|
||||
}
|
||||
|
||||
if (tmphandle->shmPtr) {
|
||||
|
||||
@@ -419,7 +419,7 @@ static ncclResult_t socketTryAccept(struct ncclSocket* sock) {
|
||||
if (sock->fd != -1) {
|
||||
sock->state = ncclSocketStateAccepted;
|
||||
} else if (errno != EAGAIN && errno != EWOULDBLOCK) {
|
||||
WARN("socketTryAccept: get errno %d that is not EAGAIN or EWOULDBLOCK", errno);
|
||||
WARN("socketTryAccept: Accept failed: %s", strerror(errno));
|
||||
return ncclSystemError;
|
||||
}
|
||||
return ncclSuccess;
|
||||
@@ -429,6 +429,9 @@ static ncclResult_t socketFinalizeAccept(struct ncclSocket* sock) {
|
||||
uint64_t magic;
|
||||
enum ncclSocketType type;
|
||||
int received = 0;
|
||||
const int one = 1;
|
||||
SYSCHECK(setsockopt(sock->fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(int)), "setsockopt");
|
||||
|
||||
NCCLCHECK(ncclSocketProgress(NCCL_SOCKET_RECV, sock, &magic, sizeof(magic), &received));
|
||||
if (received == 0) return ncclSuccess;
|
||||
NCCLCHECK(socketWait(NCCL_SOCKET_RECV, sock, &magic, sizeof(magic), &received));
|
||||
|
||||
Ссылка в новой задаче
Block a user