// Copyright (c) Microsoft Corporation. // Licensed under the MIT license. #ifndef MSCCLPP_EXECUTION_KERNEL_HPP_ #define MSCCLPP_EXECUTION_KERNEL_HPP_ #include #if defined(ENABLE_NPKIT) #include #endif #include #include #include #include "execution_common.hpp" #if defined(MSCCLPP_DEVICE_COMPILE) #include "gpu_data_types.hpp" namespace { template MSCCLPP_DEVICE_INLINE To bit_cast(const From& src) { static_assert(sizeof(To) == sizeof(From), "Size mismatch for bit_cast"); union { From f; To t; } u; u.f = src; return u.t; } template MSCCLPP_DEVICE_INLINE T add_elements(T a, T b) { return a + b; } template <> MSCCLPP_DEVICE_INLINE __half2 add_elements(__half2 a, __half2 b) { return __hadd2(a, b); } template <> MSCCLPP_DEVICE_INLINE __bfloat16 add_elements(__bfloat16 a, __bfloat16 b) { return __hadd(a, b); } template <> MSCCLPP_DEVICE_INLINE __bfloat162 add_elements(__bfloat162 a, __bfloat162 b) { return __hadd2(a, b); } template MSCCLPP_DEVICE_INLINE int4 add_vectors_helper(int4 a, int4 b) { int4 ret; ret.w = bit_cast(add_elements(bit_cast(a.w), bit_cast(b.w))); ret.x = bit_cast(add_elements(bit_cast(a.x), bit_cast(b.x))); ret.y = bit_cast(add_elements(bit_cast(a.y), bit_cast(b.y))); ret.z = bit_cast(add_elements(bit_cast(a.z), bit_cast(b.z))); return ret; } template MSCCLPP_DEVICE_INLINE int4 add_vectors(int4 a, int4 b) { return add_vectors_helper(a, b); } template <> MSCCLPP_DEVICE_INLINE int4 add_vectors<__half>(int4 a, int4 b) { return add_vectors_helper<__half2>(a, b); } template <> MSCCLPP_DEVICE_INLINE int4 add_vectors<__bfloat16>(int4 a, int4 b) { return add_vectors_helper<__bfloat162>(a, b); } template MSCCLPP_DEVICE_INLINE uint2 add_vectors_helper(uint2 a, uint2 b) { uint2 ret; ret.x = bit_cast(add_elements(bit_cast(a.x), bit_cast(b.x))); ret.y = bit_cast(add_elements(bit_cast(a.y), bit_cast(b.y))); return ret; } template MSCCLPP_DEVICE_INLINE uint2 add_vectors(uint2 a, uint2 b) { return add_vectors_helper(a, b); } template <> MSCCLPP_DEVICE_INLINE __attribute__((unused)) uint2 add_vectors<__half>(uint2 a, uint2 b) { return add_vectors_helper<__half2>(a, b); } template <> MSCCLPP_DEVICE_INLINE __attribute__((unused)) uint2 add_vectors<__bfloat16>(uint2 a, uint2 b) { return add_vectors_helper<__bfloat162>(a, b); } template MSCCLPP_DEVICE_INLINE int add_vectors_helper(int a, int b) { return bit_cast(add_elements(bit_cast(a), bit_cast(b))); } template MSCCLPP_DEVICE_INLINE int add_vectors(int a, int b) { return add_vectors_helper(a, b); } template <> MSCCLPP_DEVICE_INLINE __attribute__((unused)) int add_vectors<__half>(int a, int b) { return add_vectors_helper<__half2>(a, b); } template <> MSCCLPP_DEVICE_INLINE __attribute__((unused)) int add_vectors<__bfloat16>(int a, int b) { return add_vectors_helper<__bfloat162>(a, b); } template MSCCLPP_DEVICE_INLINE uint32_t add_vectors_helper(uint32_t a, uint32_t b) { return bit_cast(add_elements(bit_cast(a), bit_cast(b))); } template MSCCLPP_DEVICE_INLINE uint32_t add_vectors(uint32_t a, uint32_t b) { return add_vectors_helper(a, b); } template <> MSCCLPP_DEVICE_INLINE uint32_t add_vectors<__half>(uint32_t a, uint32_t b) { return add_vectors_helper<__half2>(a, b); } template <> MSCCLPP_DEVICE_INLINE uint32_t add_vectors<__bfloat16>(uint32_t a, uint32_t b) { return add_vectors_helper<__bfloat162>(a, b); } } // namespace #endif // defined(MSCCLPP_DEVICE_COMPILE) namespace mscclpp { #if defined(MSCCLPP_DEVICE_COMPILE) template MSCCLPP_DEVICE_INLINE T* getBuffer(T* input, T* output, T* scratch, BufferType bufferType) { if (bufferType == BufferType::INPUT) { return input; } if (bufferType == BufferType::OUTPUT) { return output; } if (bufferType == BufferType::SCRATCH) { return scratch; } return nullptr; } MSCCLPP_DEVICE_INLINE void handleSignal(DeviceHandle* smChannels, DeviceHandle* proxyChannels, uint8_t* channelIndex, int nChannels, ChannelType chType) { int tid = threadIdx.x; if (tid < nChannels && chType == ChannelType::SM) { smChannels[channelIndex[tid]].signal(); return; } if (tid < nChannels && chType == ChannelType::PROXY) { proxyChannels[channelIndex[threadIdx.x]].signal(); } } MSCCLPP_DEVICE_INLINE void handleWait(DeviceHandle* smChannels, DeviceHandle* proxyChannels, uint8_t* channelIndexes, int nChannels, ChannelType chType) { int tid = threadIdx.x; if (tid < nChannels && chType == ChannelType::SM) { smChannels[channelIndexes[tid]].wait(); return; } if (tid < nChannels && chType == ChannelType::PROXY) { proxyChannels[channelIndexes[tid]].wait(); } } MSCCLPP_DEVICE_INLINE void handleFlush(DeviceHandle* proxyChannels, uint8_t* channelIndexes, int nChannels) { int tid = threadIdx.x; if (tid < nChannels) { proxyChannels[channelIndexes[tid]].flush(); } } MSCCLPP_DEVICE_INLINE void handleGet(DeviceHandle* smChannel, uint8_t* srcChannelIndexes, uint32_t* dstOffsets, uint32_t* srcOffsets, int count, uint32_t size) { for (int i = 0; i < count; i++) { uint32_t dstOffset = dstOffsets[i]; uint32_t srcOffset = srcOffsets[i]; smChannel[srcChannelIndexes[i]].get(dstOffset, srcOffset, size, threadIdx.x, blockDim.x); } } template MSCCLPP_DEVICE_INLINE void handlePut(DeviceHandle* smChannel, DeviceHandle* proxyChannels, uint8_t* dstChannelIndexes, uint32_t* dstOffsets, uint32_t* srcOffsets, int count, uint32_t size, ChannelType chType) { if (chType == ChannelType::SM) { for (int i = 0; i < count; i++) { uint32_t dstOffset = dstOffsets[i]; uint32_t srcOffset = srcOffsets[i]; smChannel[dstChannelIndexes[i]].put(dstOffset, srcOffset, size, threadIdx.x, blockDim.x); } return; } if (chType == ChannelType::PROXY) { int tid = threadIdx.x; if (tid < count) { if constexpr (PutWithSignal) { proxyChannels[dstChannelIndexes[tid]].putWithSignal(dstOffsets[tid], srcOffsets[tid], size); } else if constexpr (PutWithSignalAndFlush) { proxyChannels[dstChannelIndexes[tid]].putWithSignalAndFlush(dstOffsets[tid], srcOffsets[tid], size); } else { proxyChannels[dstChannelIndexes[tid]].put(dstOffsets[tid], srcOffsets[tid], size); } } } } template MSCCLPP_DEVICE_INLINE void handleReadReduceCopySend(T* output, uint32_t outputOffsetByBytes, T* input, uint32_t inputOffsetByBytes, DeviceHandle* smChannels, uint8_t* dstChannelIndexes, uint8_t* srcChannelIndexes, uint32_t* dstOffsets, uint32_t* srcOffsets, int nDstChannels, int nSrcChannels, uint32_t size, bool sendToRemote = true) { const size_t nInt4 = size / sizeof(int4); const size_t inputOffset4 = inputOffsetByBytes / sizeof(int4); const size_t outputOffset4 = outputOffsetByBytes / sizeof(int4); int4* input4 = (int4*)input; int4* output4 = (int4*)output; for (size_t idx = threadIdx.x; idx < nInt4; idx += blockDim.x) { int4 tmp = input4[inputOffset4 + idx]; for (int index = 0; index < nSrcChannels; ++index) { int4 val; size_t srcOffset = srcOffsets[index] / sizeof(int4); val = smChannels[srcChannelIndexes[index]].read(srcOffset + idx); tmp = add_vectors(tmp, val); } output4[outputOffset4 + idx] = tmp; if (sendToRemote) { for (int index = 0; index < nDstChannels; ++index) { size_t dstOffset = dstOffsets[index] / sizeof(int4); smChannels[dstChannelIndexes[index]].write(dstOffset + idx, tmp); } } } // handle rest of data size_t processed = nInt4 * sizeof(int4); const size_t startIdx = (inputOffsetByBytes + processed) / sizeof(T); const size_t endIdx = (inputOffsetByBytes + size) / sizeof(T); for (size_t idx = threadIdx.x + startIdx; idx < endIdx; idx += blockDim.x) { T tmp = input[idx]; for (int index = 0; index < nSrcChannels; ++index) { size_t srcOffset = srcOffsets[index] / sizeof(T); tmp = add_elements(tmp, smChannels[srcChannelIndexes[index]].read(srcOffset + idx)); } output[idx] = tmp; if (sendToRemote) { for (int index = 0; index < nDstChannels; ++index) { size_t dstOffset = dstOffsets[index] / sizeof(T); smChannels[dstChannelIndexes[index]].write(dstOffset + idx, tmp); } } } } template MSCCLPP_DEVICE_INLINE void handlePutPacket(size_t scratchSize, DeviceHandle* smChannels, DeviceHandle* proxyChannels, uint8_t* dstChannelIndexes, uint32_t* dstOffsets, uint32_t* srcOffsets, int nDstChannels, uint32_t size, ChannelType chType, uint32_t flag) { const size_t scratchBaseOffset = flag & 0x1 ? 0 : scratchSize >> 1; if (chType == ChannelType::SM) { for (int index = 0; index < nDstChannels; ++index) { smChannels[dstChannelIndexes[index]].putPackets( scratchBaseOffset + dstOffsets[index] * 2, srcOffsets[index], size, threadIdx.x, blockDim.x, flag); } } if (chType == ChannelType::PROXY) { int tid = threadIdx.x; if (tid >= nDstChannels) { return; } // For proxy channel, we assume src and dst are in packet format uint32_t dstOffset = (dstOffsets[tid] << 1) + scratchBaseOffset; uint32_t srcOffset = (srcOffsets[tid] << 1) + scratchBaseOffset; proxyChannels[dstChannelIndexes[tid]].put(dstOffset, srcOffset, size << 1); } } template MSCCLPP_DEVICE_INLINE void handleReduceSendPacket(T* dst, uint32_t dstOffsetByBytes, T* src, uint32_t srcOffsetByBytes, T* inputBuff, size_t inputBuffSize, uint32_t* inputOffsets, int nSrcs, DeviceHandle* smChannels, uint8_t* outputChannelIndexes, uint32_t* outputOffsets, int nDstChannels, size_t size, uint32_t flag) { size_t nPackets = size * 2 / sizeof(PacketType); const size_t intputBaseOffset = flag & 0x1 ? 0 : inputBuffSize >> 1; const uint32_t srcOffset = srcOffsetByBytes / sizeof(PacketPayload); const uint32_t dstOffset = dstOffsetByBytes / sizeof(PacketPayload); PacketPayload* srcPacketPayload = (PacketPayload*)src + srcOffset; PacketPayload* dstPacketPayload = (PacketPayload*)dst + dstOffset; for (size_t idx = threadIdx.x; idx < nPackets; idx += blockDim.x) { PacketPayload data = {}; for (int index = 0; index < nSrcs; ++index) { PacketType* pkt = (PacketType*)((char*)inputBuff + intputBaseOffset + 2 * inputOffsets[index]); PacketPayload val = pkt[idx].read(flag); data = add_vectors(data, val); } data = add_vectors(data, srcPacketPayload[idx]); dstPacketPayload[idx] = data; if (SendToRemote) { PacketType pkt(data, flag); for (int index = 0; index < nDstChannels; ++index) { size_t offset = (intputBaseOffset + outputOffsets[index] * 2) / sizeof(PacketType); smChannels[outputChannelIndexes[index]].write(offset + idx, pkt); } } } } template MSCCLPP_DEVICE_INLINE void handleCopyPacket(void* dst, void* src, size_t srcSize, uint32_t dstOffset, uint32_t srcOffset, size_t size, uint32_t flag) { const size_t inputScratchBaseOffset = flag & 0x1 ? 0 : srcSize >> 1; PacketType* srcPackets = (PacketType*)((char*)src + inputScratchBaseOffset + 2 * srcOffset); PacketPayload* result = (PacketPayload*)((char*)dst + dstOffset); size_t nPackets = size * 2 / sizeof(PacketType); for (size_t idx = threadIdx.x; idx < nPackets; idx += blockDim.x) { PacketPayload data = srcPackets[idx].read(flag); result[idx] = data; } } template MSCCLPP_DEVICE_INLINE void handleTransformToPacket(void* dst, void* src, size_t dstSize, uint32_t dstOffset, uint32_t srcOffset, size_t size, uint32_t flag) { const size_t outputScratchBaseOffset = flag & 0x1 ? 0 : dstSize >> 1; dstOffset = dstOffset * 2 + outputScratchBaseOffset; mscclpp::putPackets(dst, dstOffset, src, srcOffset, size, threadIdx.x, blockDim.x, flag); } template MSCCLPP_DEVICE_INLINE void handleReduceSend(T* dst, uint32_t dstOffsetByBytes, T* src, uint32_t srcOffsetByBytes, T* input, uint32_t* inputOffsets, DeviceHandle* smChannels, uint8_t* outputChannelIndexes, uint32_t* outputOffsets, int nOutChannels, uint32_t size) { const size_t nInt4 = size / sizeof(int4); const size_t srcOffset4 = srcOffsetByBytes / sizeof(int4); const size_t dstOffset4 = dstOffsetByBytes / sizeof(int4); int4* src4 = (int4*)src; int4* dst4 = (int4*)dst; int4* input4 = (int4*)input; for (size_t idx = threadIdx.x; idx < nInt4; idx += blockDim.x) { int4 tmp = src4[srcOffset4 + idx]; for (int index = 0; index < nOutChannels; ++index) { size_t offset = inputOffsets[index] / sizeof(int4); int4 val = input4[offset + idx]; tmp = add_vectors(tmp, val); } dst4[dstOffset4 + idx] = tmp; for (int index = 0; index < nOutChannels; ++index) { size_t offset = outputOffsets[index] / sizeof(int4); smChannels[outputChannelIndexes[index]].write(offset + idx, tmp); } } // handle rest of data size_t processed = nInt4 * sizeof(int4); const size_t startIdx = (srcOffsetByBytes + processed) / sizeof(T); const size_t endIdx = (srcOffsetByBytes + size) / sizeof(T); for (size_t idx = threadIdx.x + startIdx; idx < endIdx; idx += blockDim.x) { T tmp = src[idx]; for (int index = 0; index < nOutChannels; ++index) { size_t offset = inputOffsets[index] / sizeof(T); tmp = add_elements(tmp, input[offset + idx]); } dst[idx] = tmp; for (int index = 0; index < nOutChannels; ++index) { size_t offset = outputOffsets[index] / sizeof(T); smChannels[outputChannelIndexes[index]].write(offset + idx, tmp); } } } MSCCLPP_DEVICE_INLINE void handleCopy(void* dst, void* src, uint32_t dstOffset, uint32_t srcOffset, size_t size) { char* srcData = (char*)src + srcOffset; char* dstData = (char*)dst + dstOffset; Element::copy(dstData, srcData, size, threadIdx.x, blockDim.x); } template __global__ void executionKernel([[maybe_unused]] int rank /*for debug*/, T* input, T* output, T* scratch, size_t scratchSize, DeviceExecutionPlan* plan, uint32_t flag #if defined(ENABLE_NPKIT) , NpKitEventCollectContext* npKitEventCollectContexts, uint64_t* cpuTimestamp) { #else ) { #endif extern __shared__ int4 sharedMem[]; int bid = blockIdx.x; int tid = threadIdx.x; #if defined(ENABLE_NPKIT) NpKitEvent* event_buffer = (NpKitEvent*)((char*)sharedMem + sizeof(DeviceExecutionPlan)); uint64_t event_buffer_head = 0; #if defined(ENABLE_NPKIT_EVENT_EXECUTOR_INIT_ENTRY) && defined(ENABLE_NPKIT_EVENT_EXECUTOR_INIT_EXIT) uint64_t npkit_timestamp_entry = 0; if (tid == 0) { npkit_timestamp_entry = NPKIT_GET_GPU_TIMESTAMP(); } #endif #endif DeviceExecutionPlan* localPlan = plan + bid; for (size_t i = tid; i < sizeof(DeviceExecutionPlan) / sizeof(int4); i += blockDim.x) { sharedMem[i] = ((int4*)localPlan)[i]; } __syncshm(); localPlan = (DeviceExecutionPlan*)sharedMem; int nOperations = localPlan->nOperations; Operation* operations = localPlan->operations; DeviceHandle* smChannels = localPlan->channels.smChannels; DeviceHandle* proxyChannels = localPlan->channels.proxyChannels; #if defined(ENABLE_NPKIT) && defined(ENABLE_NPKIT_EVENT_TIME_SYNC_CPU) #if defined(MSCCLPP_DEVICE_HIP) NpKit::CollectGpuEventShm(NPKIT_EVENT_TIME_SYNC_CPU, 0, 0, NPKIT_LOAD_CPU_TIMESTAMP_PER_BLOCK(cpuTimestamp, bid), #else NpKit::CollectGpuEventShm(NPKIT_EVENT_TIME_SYNC_CPU, 0, 0, *cpuTimestamp, #endif event_buffer, &event_buffer_head); #endif #if defined(ENABLE_NPKIT) && defined(ENABLE_NPKIT_EVENT_TIME_SYNC_GPU) NpKit::CollectGpuEventShm(NPKIT_EVENT_TIME_SYNC_GPU, 0, 0, NPKIT_GET_GPU_TIMESTAMP(), event_buffer, &event_buffer_head); #endif #if defined(ENABLE_NPKIT) && defined(ENABLE_NPKIT_EVENT_EXECUTOR_INIT_ENTRY) && \ defined(ENABLE_NPKIT_EVENT_EXECUTOR_INIT_EXIT) NpKit::CollectGpuEventShm(NPKIT_EVENT_EXECUTOR_INIT_ENTRY, 0, 0, npkit_timestamp_entry, event_buffer, &event_buffer_head); NpKit::CollectGpuEventShm(NPKIT_EVENT_EXECUTOR_INIT_EXIT, 0, 0, NPKIT_GET_GPU_TIMESTAMP(), event_buffer, &event_buffer_head); #endif for (int i = 0; i < nOperations; i++) { Operation& op = operations[i]; #if defined(ENABLE_NPKIT) && defined(ENABLE_NPKIT_EVENT_EXECUTOR_OP_BASE_ENTRY) NpKit::CollectGpuEventShm(NPKIT_EVENT_EXECUTOR_OP_BASE_ENTRY + (int)op.type, op.size, 0, NPKIT_GET_GPU_TIMESTAMP(), event_buffer, &event_buffer_head); #endif if (op.type == OperationType::BARRIER) { __syncthreads(); } else if (op.type == OperationType::SIGNAL) { handleSignal(smChannels, proxyChannels, op.outputChannelIndexes, op.nOutputs, op.channelType); } else if (op.type == OperationType::WAIT) { handleWait(smChannels, proxyChannels, op.inputChannelIndexes, op.nInputs, op.channelType); } else if (op.type == OperationType::FLUSH) { handleFlush(proxyChannels, op.outputChannelIndexes, op.nOutputs); } else if (op.type == OperationType::PUT) { handlePut(smChannels, proxyChannels, op.outputChannelIndexes, op.outputOffsets, op.inputOffsets, op.nOutputs, op.size, op.channelType); } else if (op.type == OperationType::PUT_WITH_SIGNAL) { handlePut(smChannels, proxyChannels, op.outputChannelIndexes, op.outputOffsets, op.inputOffsets, op.nOutputs, op.size, op.channelType); } else if (op.type == OperationType::PUT_WITH_SIGNAL_AND_FLUSH) { handlePut(smChannels, proxyChannels, op.outputChannelIndexes, op.outputOffsets, op.inputOffsets, op.nOutputs, op.size, op.channelType); } else if (op.type == OperationType::GET) { handleGet(smChannels, op.inputChannelIndexes, op.outputOffsets, op.inputOffsets, op.nInputs, op.size); } else if (op.type == OperationType::COPY) { T* dst = getBuffer(input, output, scratch, op.dstBufferType); T* src = getBuffer(input, output, scratch, op.srcBufferType); handleCopy(dst, src, op.dstOffset, op.srcOffset, op.size); } else if (op.type == OperationType::READ_REDUCE_COPY_SEND) { T* dst = getBuffer(input, output, scratch, op.dstBufferType); T* src = getBuffer(input, output, scratch, op.srcBufferType); handleReadReduceCopySend(dst, op.dstOffset, src, op.srcOffset, smChannels, op.outputChannelIndexes, op.inputChannelIndexes, op.outputOffsets, op.inputOffsets, op.nOutputs, op.nInputs, op.size); } else if (op.type == OperationType::READ_REDUCE_COPY) { T* dst = getBuffer(input, output, scratch, op.dstBufferType); T* src = getBuffer(input, output, scratch, op.srcBufferType); handleReadReduceCopySend(dst, op.dstOffset, src, op.srcOffset, smChannels, op.outputChannelIndexes, op.inputChannelIndexes, op.outputOffsets, op.inputOffsets, op.nOutputs, op.nInputs, op.size, false); } else if (op.type == OperationType::PUT_PACKET) { handlePutPacket(scratchSize, smChannels, proxyChannels, op.outputChannelIndexes, op.outputOffsets, op.inputOffsets, op.nOutputs, op.size, op.channelType, flag); } else if (op.type == OperationType::REDUCE_SEND_PACKET) { T* dst = getBuffer(input, output, scratch, op.dstBufferType); T* src = getBuffer(input, output, scratch, op.srcBufferType); handleReduceSendPacket(dst, op.dstOffset, src, op.srcOffset, scratch, scratchSize, op.inputOffsets, op.nInputs, smChannels, op.outputChannelIndexes, op.outputOffsets, op.nOutputs, op.size, flag); } else if (op.type == OperationType::REDUCE_PACKET) { T* dst = getBuffer(input, output, scratch, op.dstBufferType); T* src = getBuffer(input, output, scratch, op.srcBufferType); handleReduceSendPacket(dst, op.dstOffset, src, op.srcOffset, scratch, scratchSize, op.inputOffsets, op.nInputs, smChannels, op.outputChannelIndexes, op.outputOffsets, op.nOutputs, op.size, flag); } else if (op.type == OperationType::COPY_PACKET) { T* dst = getBuffer(input, output, scratch, op.dstBufferType); T* src = getBuffer(input, output, scratch, op.srcBufferType); handleCopyPacket(dst, src, scratchSize, op.dstOffset, op.srcOffset, op.size, flag); } else if (op.type == OperationType::TRANSFORM_TO_PACKET) { T* dst = getBuffer(input, output, scratch, op.dstBufferType); T* src = getBuffer(input, output, scratch, op.srcBufferType); handleTransformToPacket(dst, src, scratchSize, op.dstOffset, op.srcOffset, op.size, flag); } else if (op.type == OperationType::REDUCE_SEND) { T* dst = getBuffer(input, output, scratch, op.dstBufferType); T* src = getBuffer(input, output, scratch, op.srcBufferType); T* tmp = getBuffer(input, output, scratch, op.inputBufferType); handleReduceSend(dst, op.dstOffset, src, op.srcOffset, tmp, op.inputOffsets, smChannels, op.outputChannelIndexes, op.outputOffsets, op.nOutputs, op.size); } #if defined(ENABLE_NPKIT) && defined(ENABLE_NPKIT_EVENT_EXECUTOR_OP_BASE_EXIT) NpKit::CollectGpuEventShm(NPKIT_EVENT_EXECUTOR_OP_BASE_EXIT + (int)op.type, op.size, 0, NPKIT_GET_GPU_TIMESTAMP(), event_buffer, &event_buffer_head); #endif } #if defined(ENABLE_NPKIT) NpKit::StoreGpuEventShm(npKitEventCollectContexts, event_buffer, event_buffer_head); #endif } #endif // defined(MSCCLPP_DEVICE_COMPILE) class ExecutionKernel { public: #if defined(MSCCLPP_DEVICE_HIP) template static void launchKernel(int rank, int nthreadblocks, int nthreads, void* src, void* dst, void* scratch, size_t scratchSize, DataType dataType, DeviceExecutionPlan* plan, size_t sharedMemSize, cudaStream_t stream, uint32_t flag = 0) { switch (dataType) { case DataType::INT32: executionKernel<<>>( rank, (int32_t*)src, (int32_t*)dst, (int32_t*)scratch, scratchSize, plan, flag #if defined(ENABLE_NPKIT) , NpKit::GetGpuEventCollectContexts(), NpKit::GetCpuTimestamp()); #else ); #endif break; case DataType::UINT32: executionKernel<<>>( rank, (uint32_t*)src, (uint32_t*)dst, (uint32_t*)scratch, scratchSize, plan, flag #if defined(ENABLE_NPKIT) , NpKit::GetGpuEventCollectContexts(), NpKit::GetCpuTimestamp()); #else ); #endif break; case DataType::FLOAT16: executionKernel<<>>( rank, (half*)src, (half*)dst, (half*)scratch, scratchSize, plan, flag #if defined(ENABLE_NPKIT) , NpKit::GetGpuEventCollectContexts(), NpKit::GetCpuTimestamp()); #else ); #endif break; case DataType::FLOAT32: executionKernel<<>>( rank, (float*)src, (float*)dst, (float*)scratch, scratchSize, plan, flag #if defined(ENABLE_NPKIT) , NpKit::GetGpuEventCollectContexts(), NpKit::GetCpuTimestamp()); #else ); #endif break; case DataType::BFLOAT16: executionKernel<__bfloat16, PacketType><<>>( rank, (__bfloat16*)src, (__bfloat16*)dst, (__bfloat16*)scratch, scratchSize, plan, flag #if defined(ENABLE_NPKIT) , NpKit::GetGpuEventCollectContexts(), NpKit::GetCpuTimestamp()); #else ); #endif break; } } #else // !defined(MSCCLPP_DEVICE_HIP) template static void launchKernel(int rank, int nthreadblocks, int nthreads, void* src, void* dst, void* scratch, size_t scratchSize, DataType dataType, DeviceExecutionPlan* plan, size_t sharedMemSize, cudaStream_t stream, uint32_t flag = 0); #endif // !defined(MSCCLPP_DEVICE_HIP) }; } // namespace mscclpp #endif // MSCCLPP_EXECUTION_KERNEL_HPP_