60240fec77
Add scalable init API
* Add new ncclCommInitRankScalable to allow for passing multiple
unique IDs to the init function.
* Spreads the load onto multiple bootstrap roots, allowing for
constant bootstrap time.
* Requires multiple ranks to create a unique ID, and the CPU-side
ID exchange code to call allgather[v] instead of broadcast.
Accelerate init bootstrap operations
* Reduce the number of calls to allgather.
* Allow roots to reply early to ranks when information is already
available.
* Add an option to use ncclNet instead of sockets to perform
bootstrap allgather operations.
Add PAT algorithms for Allgather and ReduceScatter
* Parallel Aggregated Trees, variation of Bruck algorithm.
* Logarithmic number of network steps for small sizes at scale.
* Only supports one rank per node at the moment.
Add support for registered buffers for intra-node communication.
* Allow registered user buffers to be accessed directly intra-node
* Avoids extra copies in algorithms which permit it, saving
memory bandwidth and helping with compute overlap.
Add profiler plugin API
* New plugin API for profiling
* Supports various levels of profiling, with a hierarchy.
Asynchronous graph allocation
* Make calls to cudaMalloc and cudaMemcpy during graph allocation
asynchronous.
* Significantly speeds up graph capture.
Use fatal IB asynchronous events to stop network operation
* Avoids many other error messages
* Only fatal errors are affected; potentially transient errors
(e.g. port down) do not cause an immediate stop.
Set P2P level to PXB on AMD CPUs when using more than 2 GPUs per node
* P2P would cause a significant performance degradation when using
many GPUs, and therefore many interleaved data flows.
* Disable P2P through the CPU when we have 3+ GPUs per node; keep it
enabled when we only have 2 GPUs.
Improve the init logs to report the real NCCL function.
* Make the log report ncclCommInitRank or ncclCommSplit, rather than
the generic ncclCommInitRankFunc.
Add a parameter to set the location of the user configuration file.
* Add NCCL_CONF_FILE environment variable to set where the user's
configuration file resides.
Increase default IB timeout
* Increase IB timeout value from 18 to 20.
* Should help avoid fatal errors on large RoCE systems.
Add new check for nvidia peermem
* On linux kernels 6.6+, /sys/kernel/mm/memory_peers is no longer
present; check for /sys/module/nvidia_peermem/version instead.
Fix old performance regression when mixing small and large operations.
* Improves distribution of work on channels.
Fix crash when NUMA IDs are equal to -1.
* Can happen when a NIC is a virtual NIC, or when linux doesn't
know which NUMA node a device is attached to
* Issue NVIDIA/nccl-tests#233
Fix tree graph search when NCCL_CROSS_NIC is set to 1.
* Would force NCCL to use the balanced_tree pattern, thereby
disabling LL128 on platforms with 1 GPU+1 NIC per PCI switch.
* Would also try to use alternate rings even though it was not
needed.
Compiler tweaks and fixes
* PR #1177
* PR #1228
Fix stack smash
* PR #1325
Fixes for multi-node NVLink + IB operation
Coverity fixes and comments.
[ROCm/rccl commit: 68b542363f]
168 lines
5.8 KiB
C
168 lines
5.8 KiB
C
/*************************************************************************
|
|
* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
|
|
*
|
|
* See LICENSE.txt for license information
|
|
************************************************************************/
|
|
|
|
#ifndef EVENT_H_
|
|
#define EVENT_H_
|
|
|
|
#include <sys/types.h>
|
|
#include <stdint.h>
|
|
#include <unistd.h>
|
|
#include "profiler.h"
|
|
|
|
#define MAX_CHANNELS 32
|
|
#define MAX_STEPS 16
|
|
|
|
#define PROXY_OP_SEND_STATE_OFFSET (ncclProfilerProxyOpSendPosted)
|
|
#define PROXY_OP_RECV_STATE_OFFSET (ncclProfilerProxyOpRecvPosted)
|
|
#define PROXY_STEP_SEND_STATE_OFFSET (ncclProfilerProxyStepSendGPUWait)
|
|
#define PROXY_STEP_RECV_STATE_OFFSET (ncclProfilerProxyStepRecvWait)
|
|
|
|
#define NUM_PROXY_OP_SEND_STATES (ncclProfilerProxyOpSendDone - ncclProfilerProxyOpSendPosted + 1)
|
|
#define NUM_PROXY_OP_RECV_STATES (ncclProfilerProxyOpRecvDone - ncclProfilerProxyOpRecvPosted + 1)
|
|
#define NUM_PROXY_STEP_SEND_STATES (ncclProfilerProxyStepSendWait - ncclProfilerProxyStepSendGPUWait + 1)
|
|
#define NUM_PROXY_STEP_RECV_STATES (ncclProfilerProxyStepRecvGPUWait - ncclProfilerProxyStepRecvWait + 1)
|
|
|
|
#define PROXY_OP_SEND_STATE_IDX(state) (state - PROXY_OP_SEND_STATE_OFFSET)
|
|
#define PROXY_OP_RECV_STATE_IDX(state) (state - PROXY_OP_RECV_STATE_OFFSET)
|
|
#define PROXY_STEP_SEND_STATE_IDX(state) (state - PROXY_STEP_SEND_STATE_OFFSET)
|
|
#define PROXY_STEP_RECV_STATE_IDX(state) (state - PROXY_STEP_RECV_STATE_OFFSET)
|
|
|
|
#define MAX_PROXY_OP_STATES ((NUM_PROXY_OP_SEND_STATES > NUM_PROXY_OP_RECV_STATES ) ? NUM_PROXY_OP_SEND_STATES : NUM_PROXY_OP_RECV_STATES)
|
|
#define MAX_PROXY_STEP_STATES ((NUM_PROXY_STEP_SEND_STATES > NUM_PROXY_STEP_RECV_STATES) ? NUM_PROXY_STEP_SEND_STATES : NUM_PROXY_STEP_RECV_STATES)
|
|
|
|
#define MAX_COMM_CLIQUES (32 * 8)
|
|
|
|
struct proxyOp;
|
|
|
|
struct proxyStep {
|
|
uint8_t type; // type of event: network transfer
|
|
int step; // network transfer id in given channel
|
|
int isSend; // send/recv channel operation
|
|
double timestamp[MAX_PROXY_STEP_STATES];
|
|
double startTs;
|
|
double stopTs;
|
|
struct proxyOp* parent;
|
|
};
|
|
|
|
struct proxyOp {
|
|
uint8_t type; // type of event: proxy operation
|
|
uint8_t channelId; // channel id for this proxy operation
|
|
pid_t pid;
|
|
int rank;
|
|
int peer; // peer rank for this proxy operation
|
|
int nSteps; // total number of network transfers for this proxy operation
|
|
int chunkSize; // chunk size for this proxy operation
|
|
int isSend; // send/recv channel operation
|
|
size_t transSize; // transfer data size for this proxy operation
|
|
struct {
|
|
int steps; // completed steps for this proxy operation state
|
|
double timestamp;
|
|
} states[MAX_PROXY_OP_STATES];
|
|
double startTs;
|
|
double stopTs;
|
|
int stepCount; // last processed network operation for this proxy operation
|
|
struct proxyStep step[MAX_STEPS]; // array of network transfer events
|
|
struct taskEventBase* parent; // parent event p2p/collective
|
|
};
|
|
|
|
struct group;
|
|
struct context;
|
|
|
|
struct proxyCtrl {
|
|
uint8_t type;
|
|
struct context* ctx; // profiler context
|
|
double startTs;
|
|
double stopTs;
|
|
int state;
|
|
int appended; // appended proxy operations
|
|
};
|
|
|
|
// task level event base structure
|
|
struct taskEventBase {
|
|
uint8_t type; // event type: collective/p2p
|
|
int rank; // rank of the operation in NCCL communicator
|
|
const char* name; // FIXME: unused
|
|
uint64_t commHash; // communicator identifier
|
|
uint8_t func; // ncclFunc*
|
|
int refCount; // number of references for this operation
|
|
struct group* parent; // parent event group
|
|
struct taskEventBase* next; // next top level event in group
|
|
double startTs;
|
|
double stopTs;
|
|
};
|
|
|
|
struct collective {
|
|
struct taskEventBase base; // base structure for this event
|
|
uint64_t seqNumber; // sequence number for this collective in communicator
|
|
void const* sendBuff;
|
|
void* recvBuff;
|
|
size_t count;
|
|
size_t trafficBytes;
|
|
int root;
|
|
uint8_t datatype;
|
|
uint8_t nMaxChannels;
|
|
uint8_t algo;
|
|
uint8_t proto;
|
|
int op;
|
|
int nWarps;
|
|
int isCollnet;
|
|
int isNvls;
|
|
struct proxyOp send[MAX_CHANNELS];// array of send proxy operation events
|
|
struct proxyOp recv[MAX_CHANNELS];// array of recv proxy operation events
|
|
};
|
|
|
|
struct p2p {
|
|
struct taskEventBase base; // base structure for this event
|
|
uint8_t func;
|
|
void const* buff;
|
|
size_t count;
|
|
uint8_t datatype;
|
|
int peer;
|
|
struct proxyOp op;
|
|
};
|
|
|
|
struct group {
|
|
uint8_t type;
|
|
struct context* ctx; // profiler context
|
|
int groupId;
|
|
int refCount;
|
|
struct taskEventBase* eventHead; // queue head for task events
|
|
struct taskEventBase* eventTail; // queue tail for task events
|
|
double startTs;
|
|
double stopTs;
|
|
struct group* next; // next group event in queue
|
|
};
|
|
|
|
// arrays for different event objects
|
|
struct context {
|
|
int groupPoolSize;
|
|
int groupPoolBase;
|
|
int groupPoolIndex;
|
|
struct group* groupPool;
|
|
|
|
int collPoolSize;
|
|
int collPoolBase;
|
|
int collPoolIndex;
|
|
struct collective* collPool;
|
|
|
|
int p2pPoolSize;
|
|
int p2pPoolBase;
|
|
int p2pPoolIndex;
|
|
struct p2p* p2pPool;
|
|
|
|
int proxyCtrlPoolSize;
|
|
int proxyCtrlPoolBase;
|
|
int proxyCtrlPoolIndex;
|
|
struct proxyCtrl* proxyCtrlPool;
|
|
};
|
|
|
|
int taskEventQueueEmpty(struct group* g);
|
|
void taskEventQueueEnqueue(struct group* g, struct taskEventBase* event);
|
|
struct taskEventBase* taskEventQueueHead(struct group* g);
|
|
struct taskEventBase* taskEventQueueDequeue(struct group* g);
|
|
|
|
#endif
|