94057c3d3e
PR Test (NPU) / check-changes (push) Has been cancelled
PR Test (NPU) / pr-gate (push) Has been cancelled
PR Test (NPU) / set-image-config (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-4-npu-a3 (push) Has been cancelled
PR Test (NPU) / stage-b-test-16-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-1-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-2-npu-a3 (push) Has been cancelled
PR Test (Arm64) / pr-gate (push) Has been cancelled
PR Test (Arm64) / check-changes (push) Has been cancelled
PR Test (Arm64) / build-test (push) Has been cancelled
PR Test (sgl-router) / gate (push) Has been cancelled
PR Test (sgl-router) / tier-1 — lint (push) Has been cancelled
PR Test (sgl-router) / tier-2 — build + test (push) Has been cancelled
PR Test (sgl-router) / tier-3 — docker (placeholder) (push) Has been cancelled
PR Test (sgl-router) / tier-3 — k8s integration (push) Has been cancelled
PR Test (sgl-router) / tier-3 — e2e (push) Has been cancelled
PR Test (sgl-router) / finish (push) Has been cancelled
PR Test (NPU) / single-node-poc (map[name:qwen3_6_27b_w8a8_1p_in64k_out1k_50ms runner:linux-aarch64-a3-2 test_case:test/registered/ascend/performance/qwen3_6_27b/test_npu_qwen3_6_27b_w8a8_1p_in64k_out1k_50ms.py test_type:perf]) (push) Has been cancelled
PR Test (NPU) / pr-test-npu-finish (push) Has been cancelled
PR Test (Xeon) / pr-gate (push) Has been cancelled
PR Test (Xeon) / check-changes (push) Has been cancelled
PR Test (Xeon) / build-test (, xeon-gnr, base-b-test-cpu) (push) Has been cancelled
PR Test (XPU) / check-changes (push) Has been cancelled
PR Test (XPU) / pr-gate (push) Has been cancelled
PR Test (XPU) / stage-a-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / wait-for-stage-a (push) Has been cancelled
PR Test (XPU) / stage-b-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / finish (push) Has been cancelled
CI Model Inventory / build-inventory (push) Has been cancelled
Lint / lint (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Compilation Check (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Manual Policy (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Request Processing (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Summary (push) Has been cancelled
PR Test (SMG) / build-wheel (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on windows (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (x86_64 - auto) (push) Has been cancelled
PR Test (SMG) / python-unit-tests (push) Has been cancelled
PR Test (SMG) / unit-tests (push) Has been cancelled
PR Test (SMG) / benchmarks (push) Has been cancelled
PR Test (SMG) / chat-completions (push) Has been cancelled
PR Test (SMG) / chat-completions-4gpu (push) Has been cancelled
PR Test (SMG) / e2e (push) Has been cancelled
PR Test (SMG) / docker-build-test (push) Has been cancelled
PR Test (SMG) / k8s-integration (push) Has been cancelled
PR Test (SMG) / finish (push) Has been cancelled
PR Test (SMG) / summarize-benchmarks (push) Has been cancelled
Release SGLang Model Gateway Docker Image / publish (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Build SDist (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Upload to PyPI (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (aarch64, 12.9, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (x86_64, 12.9, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu129 (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (aarch64, 13.0, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (x86_64, 13.0, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu130 (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 700) (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 720) (push) Has been cancelled
Release SGLang Kernels / release-rocm700 (push) Has been cancelled
Release SGLang Kernels / release-rocm720 (push) Has been cancelled
Release SGLang Kernels / build-musa43 (43, 3.10) (push) Has been cancelled
Release SGLang Kernels / release-musa43 (push) Has been cancelled
238 lines
9.7 KiB
C++
238 lines
9.7 KiB
C++
#pragma once
|
|
|
|
#include <hip/hip_runtime.h>
|
|
|
|
#include <vector>
|
|
|
|
#include "quick_all_reduce.cuh"
|
|
|
|
#define HIP_CHECK(err) \
|
|
do { \
|
|
hipError_t err_ = (err); \
|
|
if (err_ != hipSuccess) { \
|
|
std::printf("HIP error %d at %s:%d. %s\n", err_, __FILE__, __LINE__, hipGetErrorString(err_)); \
|
|
throw std::runtime_error("HIP error"); \
|
|
} \
|
|
} while (0)
|
|
|
|
namespace quickreduce {
|
|
using fptr_t = int64_t;
|
|
static_assert(sizeof(void*) == sizeof(fptr_t));
|
|
|
|
template <typename AllReduceKernel, typename T>
|
|
__global__ __quickreduce_launch_bounds_two_shot__ static void allreduce_prototype_twoshot(
|
|
T const* A,
|
|
T* B,
|
|
uint32_t N,
|
|
uint32_t num_blocks,
|
|
int rank,
|
|
uint8_t** dbuffer_list,
|
|
uint32_t data_offset,
|
|
uint32_t flag_color,
|
|
int64_t data_size_per_phase) {
|
|
int block = blockIdx.x;
|
|
int grid = gridDim.x;
|
|
|
|
while (block < num_blocks) {
|
|
AllReduceKernel::run(A, B, N, block, rank, dbuffer_list, data_offset, flag_color, data_size_per_phase);
|
|
block += grid;
|
|
flag_color++;
|
|
}
|
|
}
|
|
|
|
#define TWOSHOT_DISPATCH(__codec) \
|
|
if (world_size == 2) { \
|
|
using LineCodec = __codec<T, 2>; \
|
|
using AllReduceKernel = AllReduceTwoshot<T, LineCodec, cast_bf2half>; \
|
|
hipLaunchKernelGGL( \
|
|
(allreduce_prototype_twoshot<AllReduceKernel, T>), \
|
|
dim3(grid), \
|
|
dim3(kBlockTwoShot), \
|
|
0, \
|
|
stream, \
|
|
A, \
|
|
B, \
|
|
N, \
|
|
num_blocks, \
|
|
rank, \
|
|
dbuffer_list, \
|
|
data_offset, \
|
|
flag_color, \
|
|
this->kMaxProblemSize); \
|
|
} else if (world_size == 4) { \
|
|
using LineCodec = __codec<T, 4>; \
|
|
using AllReduceKernel = AllReduceTwoshot<T, LineCodec, cast_bf2half>; \
|
|
hipLaunchKernelGGL( \
|
|
(allreduce_prototype_twoshot<AllReduceKernel, T>), \
|
|
dim3(grid), \
|
|
dim3(kBlockTwoShot), \
|
|
0, \
|
|
stream, \
|
|
A, \
|
|
B, \
|
|
N, \
|
|
num_blocks, \
|
|
rank, \
|
|
dbuffer_list, \
|
|
data_offset, \
|
|
flag_color, \
|
|
this->kMaxProblemSize); \
|
|
} else if (world_size == 8) { \
|
|
using LineCodec = __codec<T, 8>; \
|
|
using AllReduceKernel = AllReduceTwoshot<T, LineCodec, cast_bf2half>; \
|
|
hipLaunchKernelGGL( \
|
|
(allreduce_prototype_twoshot<AllReduceKernel, T>), \
|
|
dim3(grid), \
|
|
dim3(kBlockTwoShot), \
|
|
0, \
|
|
stream, \
|
|
A, \
|
|
B, \
|
|
N, \
|
|
num_blocks, \
|
|
rank, \
|
|
dbuffer_list, \
|
|
data_offset, \
|
|
flag_color, \
|
|
this->kMaxProblemSize); \
|
|
}
|
|
|
|
enum QuickReduceQuantLevel {
|
|
F16 = 0,
|
|
INT8 = 1,
|
|
INT6 = 2,
|
|
INT4 = 3,
|
|
};
|
|
|
|
struct DeviceComms {
|
|
// Max problem size is 2GB (in bytes) or half of uint32_t max value.
|
|
int64_t kMaxProblemSize = static_cast<int64_t>(std::numeric_limits<int32_t>::max()) + 1;
|
|
|
|
// Max TP-8
|
|
static int constexpr kMaxWorldSize = 8;
|
|
|
|
bool initialized = false;
|
|
uint32_t flag_color = 1;
|
|
int world_size;
|
|
int rank;
|
|
|
|
uint8_t* dbuffer;
|
|
uint8_t** dbuffer_list;
|
|
hipIpcMemHandle_t buffer_ipc_handle;
|
|
std::vector<hipIpcMemHandle_t> all_buffer_ipc_handles;
|
|
std::vector<uint8_t*> buffer_list;
|
|
uint32_t data_offset;
|
|
|
|
DeviceComms() : initialized(false), world_size(1), rank(0) {}
|
|
~DeviceComms() {
|
|
destroy();
|
|
}
|
|
|
|
void init(int world_size, int rank, std::optional<int64_t> max_problem_size = std::nullopt) {
|
|
destroy();
|
|
this->world_size = world_size;
|
|
this->rank = rank;
|
|
if (max_problem_size.has_value() && max_problem_size.value() > 0) {
|
|
this->kMaxProblemSize = max_problem_size.value();
|
|
}
|
|
// Allocate buffer size for worst case: F16 2-stage buffer.
|
|
uint32_t flags_buffer_size = 2 * world_size * kMaxNumBlocks * sizeof(uint32_t);
|
|
static int64_t data_buffer_size = 2 * this->kMaxProblemSize;
|
|
int64_t total_buffer_size = flags_buffer_size + data_buffer_size;
|
|
data_offset = flags_buffer_size;
|
|
HIP_CHECK(hipExtMallocWithFlags((void**)&dbuffer, total_buffer_size, hipDeviceMallocUncached));
|
|
|
|
// Clear the flags buffer.
|
|
HIP_CHECK(hipMemset(dbuffer, 0, flags_buffer_size));
|
|
|
|
// Device-side list of IPC buffers.
|
|
buffer_list.resize(world_size);
|
|
HIP_CHECK(hipMalloc(&dbuffer_list, world_size * sizeof(uint8_t*)));
|
|
|
|
// Create IPC handles for rank's communication buffer.
|
|
all_buffer_ipc_handles.resize(world_size);
|
|
HIP_CHECK(hipIpcGetMemHandle(&buffer_ipc_handle, dbuffer));
|
|
|
|
initialized = true;
|
|
}
|
|
int get_world_size() {
|
|
return world_size;
|
|
}
|
|
int get_rank() {
|
|
return rank;
|
|
}
|
|
bool status() {
|
|
return initialized;
|
|
}
|
|
hipIpcMemHandle_t const get_handle() {
|
|
return buffer_ipc_handle;
|
|
}
|
|
|
|
void destroy() {
|
|
if (initialized) {
|
|
for (int i = 0; i < world_size; i++) {
|
|
if (i != rank) {
|
|
HIP_CHECK(hipIpcCloseMemHandle(dbuffer_list[i]));
|
|
}
|
|
}
|
|
|
|
HIP_CHECK(hipFree(dbuffer));
|
|
HIP_CHECK(hipFree(dbuffer_list));
|
|
|
|
initialized = false;
|
|
}
|
|
}
|
|
|
|
void open_ipc_handles(std::vector<hipIpcMemHandle_t> const& ipc_handles) {
|
|
assert(ipc_handles.size() == all_buffer_ipc_handles.size());
|
|
for (int i = 0; i < world_size; i++) {
|
|
all_buffer_ipc_handles[i] = ipc_handles[i];
|
|
}
|
|
|
|
// Open device memory access to the IPC communication buffers.
|
|
// Note: For our own rank, we do not need to open a handle.
|
|
for (int i = 0; i < world_size; i++) {
|
|
if (i != rank) {
|
|
HIP_CHECK(
|
|
hipIpcOpenMemHandle((void**)&buffer_list[i], all_buffer_ipc_handles[i], hipIpcMemLazyEnablePeerAccess));
|
|
} else {
|
|
buffer_list[i] = dbuffer;
|
|
}
|
|
}
|
|
|
|
HIP_CHECK(hipMemcpy(dbuffer_list, buffer_list.data(), world_size * sizeof(uint8_t*), hipMemcpyHostToDevice));
|
|
}
|
|
|
|
template <typename T, bool cast_bf2half>
|
|
void allreduce(T const* A, T* B, uint32_t N, int quant_level, hipStream_t stream) {
|
|
if (world_size != 2 && world_size != 4 && world_size != 8) {
|
|
throw std::runtime_error("All Reduce not supported for world_size = " + std::to_string(world_size));
|
|
}
|
|
|
|
// Configuration.
|
|
uint32_t msg_size = N * sizeof(T);
|
|
uint32_t num_blocks = divceil(msg_size, kTileSize);
|
|
uint32_t grid = min(kMaxNumBlocks, num_blocks);
|
|
auto quant_level_ = static_cast<QuickReduceQuantLevel>(quant_level);
|
|
switch (quant_level_) {
|
|
case QuickReduceQuantLevel::INT8:
|
|
TWOSHOT_DISPATCH(CodecQ8)
|
|
break;
|
|
case QuickReduceQuantLevel::INT6:
|
|
TWOSHOT_DISPATCH(CodecQ6)
|
|
break;
|
|
case QuickReduceQuantLevel::INT4:
|
|
TWOSHOT_DISPATCH(CodecQ4)
|
|
break;
|
|
default:
|
|
TWOSHOT_DISPATCH(CodecFP)
|
|
break;
|
|
}
|
|
HIP_CHECK(cudaGetLastError());
|
|
// Rotate the flag color.
|
|
flag_color += divceil(N, grid);
|
|
}
|
|
};
|
|
|
|
} // namespace quickreduce
|