CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
258 lines
9.5 KiB
C++
258 lines
9.5 KiB
C++
/*
|
|
* Portions of this file are adapted from DeepEP (https://github.com/deepseek-ai/DeepEP).
|
|
* Copyright (c) 2025 DeepSeek. Licensed under the MIT License.
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
/*
|
|
* SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
* See LICENSE.txt for more license information.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
// ============================================================================
|
|
// Configuration constants
|
|
// ============================================================================
|
|
#define NUM_MAX_RDMA_PEERS 20
|
|
#define NUM_WORKSPACE_BYTES (32 * 1024 * 1024)
|
|
#define NUM_MAX_LOCAL_EXPERTS 1024
|
|
#define NUM_BUFFER_ALIGNMENT_BYTES 128
|
|
#define MAX_HIDDEN_DIM 16384
|
|
#define MAX_NCCL_GIN_CTX_PER_COMM 4
|
|
#define FINISHED_SUM_TAG 1024
|
|
#define NUM_WAIT_NANOSECONDS 500
|
|
#define MAX_SUPPORTED_TOKENS_PER_RANK 8192 // Must match kernel template in hybridep_adapter.cu
|
|
#define HT_OF_NUM_TOKENS_PER_CHUNK 64
|
|
|
|
#ifndef ENABLE_FAST_DEBUG
|
|
#define NUM_CPU_TIMEOUT_SECS 100
|
|
#define NUM_TIMEOUT_CYCLES 200000000000ull // 200G cycles ~= 100s
|
|
#else
|
|
#define NUM_CPU_TIMEOUT_SECS 10
|
|
#define NUM_TIMEOUT_CYCLES 20000000000ull // 20G cycles ~= 10s
|
|
#endif
|
|
|
|
#define LOW_LATENCY_SEND_PHASE 1
|
|
#define LOW_LATENCY_RECV_PHASE 2
|
|
|
|
// NCCL GIN Configuration
|
|
|
|
// Make CLion CUDA indexing work
|
|
#ifdef __CLION_IDE__
|
|
#define __CUDA_ARCH__ 900 // NOLINT(*-reserved-identifier)
|
|
#define __CUDACC_RDC__ // NOLINT(*-reserved-identifier)
|
|
#endif
|
|
|
|
// Remove Torch restrictions
|
|
#ifdef __CUDA_NO_HALF_CONVERSIONS__
|
|
#undef __CUDA_NO_HALF_CONVERSIONS__
|
|
#endif
|
|
#ifdef __CUDA_NO_HALF_OPERATORS__
|
|
#undef __CUDA_NO_HALF_OPERATORS__
|
|
#endif
|
|
#ifdef __CUDA_NO_HALF2_OPERATORS__
|
|
#undef __CUDA_NO_HALF2_OPERATORS__
|
|
#endif
|
|
#ifdef __CUDA_NO_BFLOAT16_CONVERSIONS__
|
|
#undef __CUDA_NO_BFLOAT16_CONVERSIONS__
|
|
#endif
|
|
#ifdef __CUDA_NO_BFLOAT162_OPERATORS__
|
|
#undef __CUDA_NO_BFLOAT162_OPERATORS__
|
|
#endif
|
|
|
|
// ============================================================================
|
|
// Standard includes
|
|
// ============================================================================
|
|
#include <cstdint>
|
|
#include <optional>
|
|
#include <stdexcept>
|
|
#include <vector>
|
|
#include <cuda_bf16.h>
|
|
#include <cuda_fp8.h>
|
|
#include <cuda_runtime.h>
|
|
#include "nccl.h"
|
|
#include "nccl_device.h"
|
|
#include "device/macros.cuh"
|
|
|
|
namespace nccl_ep {
|
|
|
|
// Internode low-latency kernels
|
|
namespace internode_ll {
|
|
|
|
void clean_low_latency_buffer(int* clean_0, int num_clean_int_0,
|
|
int* clean_1, int num_clean_int_1,
|
|
cudaStream_t stream);
|
|
|
|
void dispatch(const void* inData,
|
|
const int64_t* inTopkIdx,
|
|
void* outDataBuf,
|
|
void* outScalesBuf,
|
|
int* outSrcInfo,
|
|
int64_t* outLayout,
|
|
int* outCnt,
|
|
void* sendBuf,
|
|
void* recvBuf,
|
|
int* recvCntBuf,
|
|
size_t sendOff,
|
|
size_t recvOff,
|
|
size_t recvCntOff,
|
|
int* nextRecvCntBuf,
|
|
int nextRecvCntBufSize,
|
|
int* recvStats,
|
|
int64_t* waitStats,
|
|
int numTokens,
|
|
int hidden,
|
|
int maxTokensPerRank,
|
|
int numTopk,
|
|
int numExperts,
|
|
int currRank,
|
|
int numRanks,
|
|
bool use_fp8,
|
|
bool roundScale,
|
|
bool use_ue8m0,
|
|
int phases,
|
|
int numComms,
|
|
ncclDevComm* devComms,
|
|
const ncclWindow_t* windows,
|
|
unsigned signalsBase,
|
|
void* workspace,
|
|
int num_device_sms,
|
|
cudaStream_t stream);
|
|
|
|
void combine(const void* inData,
|
|
const int* srcInfo,
|
|
const int64_t* layoutRange,
|
|
const int64_t* inTopkIdx,
|
|
const float* topkWeights,
|
|
void* outData,
|
|
void* sendBuf,
|
|
void* recvBuf,
|
|
int* recvFlagBuf,
|
|
size_t sendOff,
|
|
size_t recvOff,
|
|
size_t recvFlagOff,
|
|
int* nextRecvCntBuf,
|
|
int nextRecvCntBufSize,
|
|
int64_t* waitStats,
|
|
int numCombinedTokens,
|
|
int hidden,
|
|
int maxTokensPerRank,
|
|
int numTopk,
|
|
int numExperts,
|
|
int currRank,
|
|
int numRanks,
|
|
bool useLogFmt,
|
|
int phases,
|
|
bool zeroCopy,
|
|
int numComms,
|
|
ncclDevComm* devComms,
|
|
const ncclWindow_t* windows,
|
|
unsigned signalsBase,
|
|
void* workspace,
|
|
int num_device_sms,
|
|
cudaStream_t stream);
|
|
|
|
} // namespace internode_ll
|
|
|
|
template <typename dtype_t>
|
|
__host__ __device__ constexpr dtype_t ceil_div(dtype_t a, dtype_t b) {
|
|
return (a + b - 1) / b;
|
|
}
|
|
|
|
template <typename dtype_t>
|
|
__host__ __device__ constexpr dtype_t align(dtype_t a, dtype_t b) {
|
|
return ceil_div<dtype_t>(a, b) * b;
|
|
}
|
|
|
|
struct LowLatencyBuffer {
|
|
int num_clean_int = 0;
|
|
|
|
void* dispatch_rdma_send_buffer = nullptr;
|
|
void* dispatch_rdma_recv_data_buffer = nullptr;
|
|
int* dispatch_rdma_recv_count_buffer = nullptr;
|
|
|
|
void* combine_rdma_send_buffer = nullptr;
|
|
void* combine_rdma_recv_data_buffer = nullptr;
|
|
int* combine_rdma_recv_flag_buffer = nullptr;
|
|
|
|
void* combine_rdma_send_buffer_data_start = nullptr;
|
|
size_t num_bytes_per_combine_msg = 0;
|
|
|
|
std::pair<int*, int> clean_meta() {
|
|
EP_HOST_ASSERT(dispatch_rdma_recv_count_buffer == combine_rdma_recv_flag_buffer);
|
|
return {dispatch_rdma_recv_count_buffer, num_clean_int};
|
|
}
|
|
};
|
|
|
|
struct LowLatencyLayout {
|
|
size_t total_bytes = 0;
|
|
LowLatencyBuffer buffers[2];
|
|
|
|
template <typename out_ptr_t = void*, typename count_ptr_t = uint8_t*, typename in_ptr_t = void*>
|
|
out_ptr_t advance(const in_ptr_t& ptr, size_t count) {
|
|
return reinterpret_cast<out_ptr_t>(reinterpret_cast<count_ptr_t>(ptr) + count);
|
|
}
|
|
|
|
LowLatencyLayout(void* rdma_buffer, int num_max_dispatch_tokens_per_rank, int hidden, int num_ranks, int num_experts) {
|
|
const int num_scales = hidden / 128;
|
|
|
|
// Dispatch and combine layout:
|
|
// - 2 symmetric odd/even send buffer
|
|
// - 2 symmetric odd/even receive buffers
|
|
// - 2 symmetric odd/even signaling buffers
|
|
|
|
// Message sizes
|
|
// NOTES: you should add a control `int4` for combine messages if you want to do data transformation
|
|
// NOTES: `num_scales * sizeof(nv_bfloat162)` means the per-128-channel min/max
|
|
EP_HOST_ASSERT(num_scales * sizeof(float) <= hidden);
|
|
size_t num_bytes_per_dispatch_msg = sizeof(int4) + std::max(hidden * sizeof(nv_bfloat16), hidden + num_scales * sizeof(float));
|
|
size_t num_bytes_per_combine_msg = num_scales * sizeof(nv_bfloat162) + hidden * sizeof(nv_bfloat16);
|
|
|
|
// Send buffer
|
|
size_t dispatch_send_buffer_bytes = num_max_dispatch_tokens_per_rank * num_bytes_per_dispatch_msg;
|
|
size_t combine_send_buffer_bytes = num_experts * num_max_dispatch_tokens_per_rank * num_bytes_per_combine_msg;
|
|
size_t send_buffer_bytes = std::max(dispatch_send_buffer_bytes, combine_send_buffer_bytes);
|
|
EP_HOST_ASSERT(send_buffer_bytes % sizeof(int4) == 0);
|
|
total_bytes += send_buffer_bytes * 2;
|
|
|
|
// Symmetric receive buffers
|
|
size_t dispatch_recv_data_buffer_bytes = num_experts * num_max_dispatch_tokens_per_rank * num_bytes_per_dispatch_msg;
|
|
size_t combine_recv_buffer_bytes = num_experts * num_max_dispatch_tokens_per_rank * num_bytes_per_combine_msg;
|
|
size_t recv_buffer_bytes = std::max(dispatch_recv_data_buffer_bytes, combine_recv_buffer_bytes);
|
|
EP_HOST_ASSERT(recv_buffer_bytes % sizeof(int4) == 0);
|
|
total_bytes += recv_buffer_bytes * 2;
|
|
|
|
// Symmetric signaling buffers
|
|
size_t dispatch_recv_count_buffer_bytes = num_experts * sizeof(int);
|
|
size_t combine_recv_flag_buffer_bytes = dispatch_recv_count_buffer_bytes;
|
|
size_t signaling_buffer_bytes = std::max(dispatch_recv_count_buffer_bytes, combine_recv_flag_buffer_bytes);
|
|
size_t signaling_buffer_bytes_aligned = align<size_t>(signaling_buffer_bytes, 128);
|
|
total_bytes += signaling_buffer_bytes_aligned * 2;
|
|
|
|
// Assign pointers
|
|
|
|
for (int i = 0; i < 2; ++ i) {
|
|
buffers[i] = {
|
|
static_cast<int>(signaling_buffer_bytes / sizeof(int)),
|
|
advance(rdma_buffer, signaling_buffer_bytes_aligned * 2 + send_buffer_bytes * i),
|
|
advance(rdma_buffer, signaling_buffer_bytes_aligned * 2 + send_buffer_bytes * 2 + recv_buffer_bytes * i),
|
|
advance<int*>(rdma_buffer, signaling_buffer_bytes_aligned * i),
|
|
advance(rdma_buffer, signaling_buffer_bytes_aligned * 2 + send_buffer_bytes * i),
|
|
advance(rdma_buffer, signaling_buffer_bytes_aligned * 2 + send_buffer_bytes * 2 + recv_buffer_bytes * i),
|
|
advance<int*>(rdma_buffer, signaling_buffer_bytes_aligned * i),
|
|
advance(rdma_buffer, signaling_buffer_bytes_aligned * 2 + send_buffer_bytes * i),
|
|
num_bytes_per_combine_msg
|
|
};
|
|
}
|
|
}
|
|
};
|
|
|
|
inline unsigned long int get_low_latency_rdma_size_hint(int num_max_dispatch_tokens_per_rank, int hidden, int num_ranks, int num_experts) {
|
|
auto num_bytes = LowLatencyLayout(nullptr, num_max_dispatch_tokens_per_rank, hidden, num_ranks, num_experts).total_bytes;
|
|
return ((num_bytes + NUM_BUFFER_ALIGNMENT_BYTES) / NUM_BUFFER_ALIGNMENT_BYTES) * NUM_BUFFER_ALIGNMENT_BYTES;
|
|
}
|
|
|
|
} // namespace nccl_ep
|
|
|