4f7d5f85ec
* 2.9.6-1
Add support for CUDA graphs.
Fuse BCM Gen4 switches to avoid suboptimal performance on some platforms. Issue #439.
Fix bootstrap issue caused by connection reordering.
Fix CPU locking block.
Improve CollNet algorithm.
Improve performance on DGX A100 for communicators with only one GPU per node.
* Clique tuning upgrade (#352) (#19)
* Enabling clique for any XGMI-connected topology, adding tuning
* Updating CHANGELOG for clique tuning
* Re-working clique barrier system to work on multi-process / multi-gpu
Co-authored-by: Sylvain Jeaugey <sjeaugey@nvidia.com>
Co-authored-by: gilbertlee-amd <44450918+gilbertlee-amd@users.noreply.github.com>
[ROCm/rccl commit: 6021329af0]
79 lines
3.0 KiB
C++
79 lines
3.0 KiB
C++
/*************************************************************************
|
|
* Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
|
* Modifications Copyright (c) 2019-2021 Advanced Micro Devices, Inc. All rights reserved.
|
|
*
|
|
* See LICENSE.txt for license information
|
|
************************************************************************/
|
|
|
|
#include "argcheck.h"
|
|
#include "comm.h"
|
|
|
|
static ncclResult_t CudaPtrCheck(const void* pointer, struct ncclComm* comm, const char* ptrname, const char* opname) {
|
|
hipPointerAttribute_t attr;
|
|
hipError_t err = hipPointerGetAttributes(&attr, pointer);
|
|
if (err != hipSuccess || attr.devicePointer == NULL) {
|
|
WARN("%s : %s is not a valid pointer", opname, ptrname);
|
|
return ncclInvalidArgument;
|
|
}
|
|
#if CUDART_VERSION >= 10000
|
|
if (attr.type == hipMemoryTypeDevice && attr.device != comm->cudaDev) {
|
|
#else
|
|
if (attr.memoryType == hipMemoryTypeDevice && attr.device != comm->cudaDev) {
|
|
#endif
|
|
WARN("%s : %s allocated on device %d mismatchs with NCCL device %d", opname, ptrname, attr.device, comm->cudaDev);
|
|
return ncclInvalidArgument;
|
|
}
|
|
return ncclSuccess;
|
|
}
|
|
|
|
ncclResult_t PtrCheck(void* ptr, const char* opname, const char* ptrname) {
|
|
if (ptr == NULL) {
|
|
WARN("%s : %s argument is NULL", opname, ptrname);
|
|
return ncclInvalidArgument;
|
|
}
|
|
return ncclSuccess;
|
|
}
|
|
|
|
ncclResult_t ArgsCheck(struct ncclInfo* info) {
|
|
// First, the easy ones
|
|
if (info->root < 0 || info->root >= info->comm->nRanks) {
|
|
WARN("%s : invalid root %d (root should be in the 0..%d range)", info->opName, info->root, info->comm->nRanks);
|
|
return ncclInvalidArgument;
|
|
}
|
|
if (info->datatype < 0 || info->datatype >= ncclNumTypes) {
|
|
WARN("%s : invalid type %d", info->opName, info->datatype);
|
|
return ncclInvalidArgument;
|
|
}
|
|
// Type is OK, compute nbytes. Convert Allgather/Broadcast/P2P calls to chars.
|
|
info->nBytes = info->count * ncclTypeSize(info->datatype);
|
|
if (info->coll == ncclFuncAllGather || info->coll == ncclFuncBroadcast) {
|
|
info->count = info->nBytes;
|
|
info->datatype = ncclInt8;
|
|
}
|
|
if (info->coll == ncclFuncAllGather || info->coll == ncclFuncReduceScatter) info->nBytes *= info->comm->nRanks; // count is per rank
|
|
|
|
if (info->op < 0 || info->op >= ncclNumOps) {
|
|
WARN("%s : invalid reduction operation %d", info->opName, info->op);
|
|
return ncclInvalidArgument;
|
|
}
|
|
|
|
if (info->comm->checkPointers) {
|
|
if (info->coll == ncclFuncSendRecv) {
|
|
if (strcmp(info->opName, "Send") == 0) {
|
|
NCCLCHECK(CudaPtrCheck(info->sendbuff, info->comm, "sendbuff", "Send"));
|
|
} else {
|
|
NCCLCHECK(CudaPtrCheck(info->recvbuff, info->comm, "recvbuff", "Recv"));
|
|
}
|
|
} else {
|
|
// Check CUDA device pointers
|
|
if (info->coll != ncclFuncBroadcast || info->comm->rank == info->root) {
|
|
NCCLCHECK(CudaPtrCheck(info->sendbuff, info->comm, "sendbuff", info->opName));
|
|
}
|
|
if (info->coll != ncclFuncReduce || info->comm->rank == info->root) {
|
|
NCCLCHECK(CudaPtrCheck(info->recvbuff, info->comm, "recvbuff", info->opName));
|
|
}
|
|
}
|
|
}
|
|
return ncclSuccess;
|
|
}
|