Add HDP flush for gfx940 (#1434)
* Fix collective trace
* Use nontemporal for st_global
* Fix previous commit
* Add HDP flush to data receive path
* Fix previous commit
* Control flushing by NCCL_NET_FORCE_FLUSH and RCCL_NET_HDP_FLUSH
* Introduce RCCL_NET_HDP_FLUSH and RCCL_NET_GDR_FLUSH
Both are on by default. Turn both off will skip all flush will likely
result in data error.
* Enable GDR copy by default
* Remove GDR flush env var because it is disabled by GDC flush
* Output kernel collective trace at comm destroy by default
* Limit kernel timeout messages to 100
* Use system relaxed atomic for loadInt
* Refine timeout messages and use atomic for setting offset from CPU
* Add kernel trace for barrier timeout
* Add backup barrier to avoid race in atomicAdd
* Use different counters for different warps
* Rework barrier implementation
* Fix for other GFX
* Use __hip_atomic_store and __hip_atomic_load
* Fix bug in previous commit
* Don't reset barrier values in running kernel
* Update trace format
* Fix typo
* Switch back to hip_atomic_fetch_add
* Use same barrier implementation for all GFX
* Remove extra threadfence
* Turn off HDP flush by default
Please use RCCL_NET_HDP_FLUSH=1 to switch on HDP flush
* Remove unnecessary changes from alterative barrier implementation
* Added back __threadfence_block
* Revert back to threadfence for gfx other than gfx94x
[ROCm/rccl commit: caba0bc049]
This commit is contained in:
@@ -23,7 +23,7 @@ inline __device__ int min(int a, ssize_t b) { return (a < b) ? a : b; }
|
||||
|
||||
inline __device__ int loadInt(int* ptr) {
|
||||
int v;
|
||||
v = atomicAdd((unsigned long long *)ptr, 0);
|
||||
v = __atomic_load_n(ptr, __ATOMIC_RELAXED);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
@@ -199,8 +199,7 @@ template<> __device__ __forceinline__ void st_global<0>(uintptr_t addr, BytePack
|
||||
} \
|
||||
template<> \
|
||||
__device__ __forceinline__ void st_##space<bytes>(addr_cxx_ty addr, BytePack<bytes> value) { \
|
||||
data_cxx_ty tmp = value.native; \
|
||||
*((data_cxx_ty *)addr) = tmp; \
|
||||
__builtin_nontemporal_store(value.native, (data_cxx_ty *)addr); \
|
||||
}
|
||||
|
||||
// #if __CUDA_ARCH__ >= 700
|
||||
|
||||
@@ -16,37 +16,42 @@
|
||||
#define NCCL_SPINS_BEFORE_CHECK_ABORT 1000000
|
||||
|
||||
#if defined(__gfx940__) || defined(__gfx941__) || defined(__gfx942__)
|
||||
#define barrier_by_group() do { \
|
||||
if (nthreads == NCCL_MAX_NTHREADS) { \
|
||||
__builtin_amdgcn_s_barrier(); \
|
||||
} else { \
|
||||
const int w = threadIdx.x/WARP_SIZE; \
|
||||
const int wid = threadIdx.x%WARP_SIZE; \
|
||||
if (wid == 0) { \
|
||||
barrier_next[w] += nthreads/WARP_SIZE; \
|
||||
atomicAdd((unsigned long long *)barriers, 1); \
|
||||
while (atomicAdd((unsigned long long *)barriers, 0) < barrier_next[w]) __builtin_amdgcn_s_sleep(1); \
|
||||
__asm__ __volatile__("s_wakeup"); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#define __THREAD_FENCE __threadfence_block()
|
||||
#else
|
||||
#define __THREAD_FENCE __threadfence()
|
||||
#endif
|
||||
|
||||
#define barrier_by_group() do { \
|
||||
if (nthreads == NCCL_MAX_NTHREADS) { \
|
||||
__threadfence(); __builtin_amdgcn_s_barrier(); \
|
||||
__THREAD_FENCE; __builtin_amdgcn_s_barrier(); \
|
||||
} else { \
|
||||
const int w = threadIdx.x/WARP_SIZE; \
|
||||
const int wid = threadIdx.x%WARP_SIZE; \
|
||||
__threadfence(); \
|
||||
if (wid == 0) { \
|
||||
barrier_next[w] += nthreads/WARP_SIZE; \
|
||||
atomicAdd((unsigned long long *)barriers, 1); \
|
||||
while (atomicAdd((unsigned long long *)barriers, 0) < barrier_next[w]) __builtin_amdgcn_s_sleep(1); \
|
||||
__hip_atomic_fetch_add(barriers, 1, __ATOMIC_RELEASE, __HIP_MEMORY_SCOPE_WORKGROUP); \
|
||||
int spins = 0; \
|
||||
int rate_limit = 50; \
|
||||
__THREAD_FENCE; \
|
||||
while (__hip_atomic_load(barriers, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP) < barrier_next[w]) { \
|
||||
spins++; \
|
||||
if (spins == NCCL_SPINS_BEFORE_CHECK_ABORT) { \
|
||||
if (__atomic_load_n(ncclShmem.comm.abortFlag, __ATOMIC_SEQ_CST)) { \
|
||||
ncclShmem.aborted = 1; \
|
||||
break; \
|
||||
} \
|
||||
spins = 0; \
|
||||
} \
|
||||
if (spins == 0 && rate_limit > 0) { \
|
||||
rate_limit --; \
|
||||
traceData(__LINE__, threadIdx.x, __hip_atomic_load(barriers, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP), barrier_next[w]); \
|
||||
} \
|
||||
__builtin_amdgcn_s_sleep(1); \
|
||||
} \
|
||||
__asm__ __volatile__("s_wakeup"); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/* Protocol classes: ProtoSimple, ProtoLL, ProtoLL128
|
||||
* We use these as template args to the Primtiives class instead of integral
|
||||
|
||||
@@ -43,7 +43,7 @@ class Primitives<
|
||||
Fan fan;
|
||||
int index; // Peer index I'm responsible for
|
||||
int flags;
|
||||
int group;
|
||||
const int group;
|
||||
uint64_t step;
|
||||
struct ncclConnFifo* connFifo = NULL;
|
||||
T* connEltsFifo;
|
||||
@@ -55,6 +55,7 @@ class Primitives<
|
||||
uint32_t* next_hdp_reg;
|
||||
uint64_t* barriers;
|
||||
uint64_t* barrier_next;
|
||||
int repeat;
|
||||
|
||||
#if defined(ENABLE_NPKIT)
|
||||
public:
|
||||
@@ -113,12 +114,16 @@ private:
|
||||
if (((flags & (Recv*RoleWaitRecv)) && !noRecvWait) ||
|
||||
((flags & (Send*RoleWaitSend)) && !noSendWait)) {
|
||||
int spins = 0;
|
||||
repeat = 50;
|
||||
while (connStepCache + (isSendNotRecv ? NCCL_STEPS : 0) < step + StepPerSlice) {
|
||||
__builtin_amdgcn_s_sleep(1);
|
||||
connStepCache = loadStepValue(connStepPtr);
|
||||
if (checkAbort(spins)) break;
|
||||
//if (spins == 0) printf("r=%d b=%d t=%d SPUN OUT got=%d want=%d\n", ncclShmem.comm.rank, blockIdx.x, threadIdx.x, int(connStepCache + (isSendNotRecv ? NCCL_STEPS : 0)), int(step+StepPerSlice));
|
||||
if (spins == 0) traceData(__LINE__, threadIdx.x, int(connStepCache + (isSendNotRecv ? NCCL_STEPS : 0)), int(step+StepPerSlice));
|
||||
if (spins == 0 && repeat > 0) {
|
||||
repeat --;
|
||||
traceData(__LINE__, threadIdx.x, int(connStepCache + (isSendNotRecv ? NCCL_STEPS : 0)), int(step+StepPerSlice));
|
||||
}
|
||||
}
|
||||
__asm__ __volatile__("s_wakeup");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user