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
563 lines
20 KiB
C++
563 lines
20 KiB
C++
/******************************************************************************
|
|
* Copyright (c) Advanced Micro Devices, Inc. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to
|
|
* deal in the Software without restriction, including without limitation the
|
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
* sell copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
* IN THE SOFTWARE.
|
|
*****************************************************************************/
|
|
|
|
#include <mpi.h>
|
|
|
|
#include "LL_MoE_Data.hpp"
|
|
#include "LL_MoE_Buffers.hpp"
|
|
#include "LL_MoE_Kernels.hpp"
|
|
|
|
using namespace rocshmem;
|
|
|
|
template<typename T>
|
|
class LLMoE {
|
|
private:
|
|
int rank {0}, num_ranks {0};
|
|
int device_id {0};
|
|
|
|
// rocSHMEM buffer
|
|
int64_t num_rdma_bytes {0};
|
|
void* rdma_buffer_ptr {nullptr};
|
|
|
|
// Workspace (32 MiB)
|
|
void* workspace {nullptr};
|
|
|
|
// LL_DeepEP parameters
|
|
const int num_tokens {0};
|
|
const int hidden {0};
|
|
const int num_topk {0};
|
|
const int num_experts {0};
|
|
|
|
// LL_DeepEP data
|
|
LLMoEData<T> ll_moe_data;
|
|
|
|
// LL Buffer index
|
|
int ll_buffer_idx {0};
|
|
|
|
// Dispatch buffers
|
|
T* packed_recv_x {nullptr};
|
|
int* packed_recv_src_info {nullptr};
|
|
int64_t* packed_recv_layout_range {nullptr};
|
|
int* packed_recv_count {nullptr};
|
|
int* global_atomic_counter {nullptr};
|
|
|
|
// Combine buffers
|
|
T* combined_x {nullptr};
|
|
|
|
// HIP stream to launch kernels
|
|
hipStream_t stream;
|
|
|
|
// init mode
|
|
InitMode init_mode {InitMode::Deterministic};
|
|
|
|
|
|
public:
|
|
LLMoE(int num_tokens_, int hidden_, int num_topk_, int num_experts_,
|
|
InitMode init_mode_ = InitMode::Deterministic)
|
|
: num_tokens(num_tokens_), hidden(hidden_), num_topk(num_topk_),
|
|
num_experts(num_experts_),
|
|
ll_moe_data(num_tokens_, hidden_, num_topk_, num_experts_,init_mode_),
|
|
init_mode(init_mode_) {
|
|
|
|
// Initialize rocSHMEM
|
|
comm_init();
|
|
|
|
// print rank and gpu id
|
|
std::cout << "Rank " << rank << " using GPU " << device_id << std::endl;
|
|
|
|
// Create HIP stream
|
|
CHECK_HIP(hipStreamCreate(&stream));
|
|
|
|
// num_experts must be divisible by num_ranks
|
|
ASSERT(num_experts % num_ranks == 0);
|
|
|
|
/**
|
|
* Generate input data after COMM init, because it sets different device
|
|
* IDs for different ranks.
|
|
*/
|
|
ll_moe_data.generate_data();
|
|
|
|
CHECK_HIP(hipExtMallocWithFlags(&workspace, NUM_WORKSPACE_BYTES,
|
|
hipDeviceMallocUncached));
|
|
// Mmemset workspace to zero
|
|
CHECK_HIP(hipMemsetAsync(workspace, 0, NUM_WORKSPACE_BYTES, stream));
|
|
|
|
// Allocate rocSHMEM buffer
|
|
num_rdma_bytes = get_rdma_size_hint<T>(
|
|
num_tokens, hidden, num_ranks, num_experts);
|
|
rdma_buffer_ptr = rocshmem_malloc(num_rdma_bytes);
|
|
if (rdma_buffer_ptr == nullptr) {
|
|
std::cerr << "Rank " << rank
|
|
<< ": Error in rocshmem_malloc. Aborting." << std::endl;
|
|
comm_finalize();
|
|
// Clean up other resources and exit
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// Mmemset rdma_buffer_ptr to zero
|
|
CHECK_HIP(hipMemsetAsync(rdma_buffer_ptr, 0, num_rdma_bytes, stream));
|
|
|
|
// Allocate dispatch buffers
|
|
allocate_dispatch_buffers();
|
|
|
|
// Synchronize to ensure all allocations are done
|
|
CHECK_HIP(hipStreamSynchronize(stream));
|
|
}
|
|
|
|
~LLMoE() {
|
|
CHECK_HIP(hipFree(workspace));
|
|
|
|
// Free dispatch buffers
|
|
CHECK_HIP(hipFree(packed_recv_x));
|
|
CHECK_HIP(hipFree(packed_recv_src_info));
|
|
CHECK_HIP(hipFree(packed_recv_layout_range));
|
|
CHECK_HIP(hipFree(packed_recv_count));
|
|
|
|
// Free combine buffers
|
|
CHECK_HIP(hipFree(combined_x));
|
|
|
|
// Destroy HIP stream
|
|
CHECK_HIP(hipStreamDestroy(stream));
|
|
|
|
// Free rocSHMEM buffer
|
|
rocshmem_free(rdma_buffer_ptr);
|
|
comm_finalize();
|
|
}
|
|
|
|
int get_rank() const {
|
|
return rank;
|
|
}
|
|
|
|
int get_num_ranks() const {
|
|
return num_ranks;
|
|
}
|
|
|
|
void ll_dispatch() {
|
|
// Buffer control
|
|
LLMoEBufferLayout<T> ll_layout(rdma_buffer_ptr, num_tokens,
|
|
hidden, num_ranks, num_experts);
|
|
LLMoEBuffer& buffer = ll_layout.buffers[ll_buffer_idx];
|
|
LLMoEBuffer& next_buffer = ll_layout.buffers[ll_buffer_idx ^= 1];
|
|
|
|
// Hip memset global_atomic_counter to zero
|
|
CHECK_HIP(hipMemsetAsync(global_atomic_counter, 0, sizeof(int), stream));
|
|
|
|
// Launch dispatch kernel
|
|
ll_kernels::dispatch<T>(packed_recv_x, packed_recv_src_info,
|
|
packed_recv_layout_range, packed_recv_count, global_atomic_counter,
|
|
buffer.dispatch_recv_buffer, buffer.dispatch_recv_count_buffer,
|
|
buffer.dispatch_send_buffer, ll_moe_data.X, ll_moe_data.topk_idx,
|
|
next_buffer.clean_meta().first, next_buffer.clean_meta().second,
|
|
num_tokens, hidden, num_topk, num_experts, rank, num_ranks, workspace,
|
|
stream);
|
|
|
|
// hipStreamSynchronize
|
|
CHECK_HIP(hipStreamSynchronize(stream));
|
|
|
|
//--- DEBUG FUNCTIONS ---
|
|
// int num_local_experts {num_experts / num_ranks};
|
|
// Print rdma_x (buffer.dispatch_send_buffer) for debugging
|
|
// print_rdma_x(buffer.dispatch_send_buffer);
|
|
|
|
// Print rdma_recv_x (buffer.dispatch_recv_buffer) for debugging
|
|
// print_rdma_recv_x(buffer.dispatch_recv_buffer, num_experts / num_ranks);
|
|
|
|
// print atomic counters for debugging
|
|
// print_atomic_counters();
|
|
|
|
// Print dispatch recv counts
|
|
// print_dispatch_recv_counts(num_local_experts,
|
|
// buffer.dispatch_recv_count_buffer);
|
|
|
|
// Print packed recv buffers
|
|
// print_packed_recv_buffers(num_local_experts);
|
|
}
|
|
|
|
void ll_combine() { // hipStream_t stream : TODO: pass stream
|
|
|
|
// Buffer control
|
|
LLMoEBufferLayout<T> ll_layout(rdma_buffer_ptr, num_tokens,
|
|
hidden, num_ranks, num_experts);
|
|
LLMoEBuffer& buffer = ll_layout.buffers[ll_buffer_idx];
|
|
LLMoEBuffer& next_buffer = ll_layout.buffers[ll_buffer_idx ^= 1];
|
|
|
|
// Hip memset global_atomic_counter to zero
|
|
CHECK_HIP(hipMemsetAsync(global_atomic_counter, 0,
|
|
sizeof(int), stream));
|
|
|
|
// Hip memset combined_x to zero
|
|
CHECK_HIP(hipMemsetAsync(combined_x, 0,
|
|
num_tokens * hidden * sizeof(T), stream));
|
|
|
|
// Launch combine kernel
|
|
ll_kernels::combine<T>(combined_x, buffer.combine_recv_buffer,
|
|
buffer.combine_recv_flag_buffer, buffer.combine_send_buffer,
|
|
packed_recv_x, ll_moe_data.topk_idx, packed_recv_src_info,
|
|
packed_recv_layout_range, global_atomic_counter,
|
|
next_buffer.clean_meta().first, next_buffer.clean_meta().second,
|
|
num_tokens, num_topk, hidden, num_experts, rank, num_ranks,
|
|
workspace, stream);
|
|
|
|
// hipStreamSynchronize
|
|
CHECK_HIP(hipStreamSynchronize(stream));
|
|
|
|
//--- DEBUG FUNCTIONS ---
|
|
// Print combine send buffer for debugging
|
|
// print_combine_send_buffer(buffer.combine_send_buffer);
|
|
|
|
// Print combined_x for debugging
|
|
// print_combined_x(combined_x);
|
|
|
|
// Verify combined_x data based on the experts it is routed to
|
|
// verify_combined_x(combined_x);
|
|
|
|
// Verify if init mode is Deterministic
|
|
if (init_mode == InitMode::Deterministic) {
|
|
verify_combined_x(combined_x);
|
|
}
|
|
}
|
|
|
|
private:
|
|
// Initialize rocSHMEM
|
|
void comm_init() {
|
|
|
|
// Initialize MPI
|
|
int mpi_rank {0}, mpi_size {0};
|
|
int ret {0};
|
|
int provided {0};
|
|
MPI_Init_thread (nullptr, nullptr, MPI_THREAD_MULTIPLE, &provided);
|
|
if (provided != MPI_THREAD_MULTIPLE) {
|
|
std::cerr << "MPI_THREAD_MULTIPLE support disabled.\n";
|
|
}
|
|
MPI_Comm_rank (MPI_COMM_WORLD, &mpi_rank);
|
|
MPI_Comm_size (MPI_COMM_WORLD, &mpi_size);
|
|
|
|
// Set GPU id
|
|
int device_count {0};
|
|
CHECK_HIP(hipGetDeviceCount(&device_count));
|
|
CHECK_HIP(hipSetDevice(mpi_rank % device_count));
|
|
|
|
// Get GPU id
|
|
CHECK_HIP(hipGetDevice(&device_id));
|
|
|
|
// Initialize rocSHMEM with unique ID
|
|
rocshmem_uniqueid_t uid;
|
|
rocshmem_init_attr_t attr;
|
|
if (mpi_rank == 0) {
|
|
ret = rocshmem_get_uniqueid (&uid);
|
|
if (ret != ROCSHMEM_SUCCESS) {
|
|
std::cout << mpi_rank
|
|
<< ": Error in rocshmem_get_uniqueid. Aborting." << std::endl;
|
|
MPI_Abort (MPI_COMM_WORLD, ret);
|
|
}
|
|
}
|
|
|
|
// Broadcast the unique ID to all ranks
|
|
MPI_Bcast (&uid, sizeof(rocshmem_uniqueid_t), MPI_BYTE, 0, MPI_COMM_WORLD);
|
|
ret = rocshmem_set_attr_uniqueid_args(mpi_rank, mpi_size, &uid, &attr);
|
|
if (ret != ROCSHMEM_SUCCESS) {
|
|
std::cout << mpi_rank
|
|
<< ": Error in rocshmem_set_attr_uniqueid_args. Aborting"
|
|
<< std::endl;
|
|
MPI_Abort (MPI_COMM_WORLD, ret);
|
|
}
|
|
|
|
ret = rocshmem_init_attr(ROCSHMEM_INIT_WITH_UNIQUEID, &attr);
|
|
if (ret != ROCSHMEM_SUCCESS) {
|
|
std::cout << mpi_rank << ": Error in rocshmem_init_attr. Aborting."
|
|
<< std::endl;
|
|
MPI_Abort (MPI_COMM_WORLD, ret);
|
|
}
|
|
|
|
rank = rocshmem_my_pe();
|
|
num_ranks = rocshmem_n_pes();
|
|
}
|
|
|
|
void comm_finalize() {
|
|
rocshmem_finalize();
|
|
MPI_Finalize();
|
|
}
|
|
|
|
// Allocate GPU buffers/tensors for dispatch
|
|
void allocate_dispatch_buffers() {
|
|
int num_local_experts = num_experts / num_ranks;
|
|
size_t packed_recv_x_bytes =
|
|
num_local_experts * num_ranks * num_tokens * hidden * sizeof(T);
|
|
size_t packed_recv_src_info_bytes =
|
|
num_local_experts * num_ranks * num_tokens * sizeof(int);
|
|
size_t packed_recv_layout_range_bytes =
|
|
num_local_experts * num_ranks * sizeof(int64_t);
|
|
size_t packed_recv_count_bytes =
|
|
num_local_experts * sizeof(int);
|
|
|
|
size_t combined_x_bytes = num_tokens * hidden * sizeof(T);
|
|
|
|
// Dimensions: [num_local_experts][num_ranks][num_tokens][hidden]
|
|
CHECK_HIP(hipMalloc(&packed_recv_x, packed_recv_x_bytes));
|
|
// Dimensions: [num_local_experts][num_ranks][num_tokens]
|
|
CHECK_HIP(hipMalloc(&packed_recv_src_info, packed_recv_src_info_bytes));
|
|
// Dimensions: [num_local_experts][num_ranks]
|
|
CHECK_HIP(hipMalloc(&packed_recv_layout_range,
|
|
packed_recv_layout_range_bytes));
|
|
// Dimensions: [num_local_experts]
|
|
CHECK_HIP(hipMalloc(&packed_recv_count, packed_recv_count_bytes));
|
|
// Dimensions: [num_tokens][hidden]
|
|
CHECK_HIP(hipMalloc(&combined_x, combined_x_bytes));
|
|
CHECK_HIP(hipMalloc(&global_atomic_counter, sizeof(int)));
|
|
}
|
|
|
|
/**
|
|
* ------------ DEBUG FUNCTIONS ------------
|
|
*/
|
|
// Verify combined_x data based on the experts it is routed to
|
|
void verify_combined_x(void* combined_x) {
|
|
T* combined_x_t = reinterpret_cast<T*>(combined_x);
|
|
bool all_correct = true;
|
|
for (int i = 0; i < num_tokens; i++) {
|
|
for (int h = 0; h < hidden; h++) {
|
|
T expected_value = ll_moe_data.X[i * hidden + h] * num_topk;
|
|
T actual_value = combined_x_t[i * hidden + h];
|
|
if (actual_value != expected_value) {
|
|
std::cout << "Mismatch at Token " << i << ", Hidden " << h
|
|
<< ": Expected " << expected_value
|
|
<< ", Actual " << actual_value << std::endl;
|
|
all_correct = false;
|
|
}
|
|
}
|
|
}
|
|
if (! all_correct) {
|
|
std::cout << "Verification failed: combined_x has mismatches." << std::endl;
|
|
}
|
|
}
|
|
|
|
// Print combined_x of dimensions [num_tokens][hidden]
|
|
void print_combined_x(void* combined_x) {
|
|
T* combined_x_t = reinterpret_cast<T*>(combined_x);
|
|
for (int i = 0; i < num_tokens; i++) {
|
|
std::cout << "Token " << i << ": ";
|
|
for (int j = 0; j < hidden; j++) {
|
|
std::cout << combined_x_t[i * hidden + j] << " ";
|
|
}
|
|
std::cout << std::endl;
|
|
}
|
|
}
|
|
|
|
// Print combine send buffer for debugging
|
|
void print_combine_send_buffer(void* combine_send_buffer) {
|
|
T* combine_send_buffer_t =
|
|
reinterpret_cast<T*>(combine_send_buffer);
|
|
int* packed_send_src_info_t =
|
|
reinterpret_cast<int*>(packed_recv_src_info);
|
|
int num_local_experts = num_experts / num_ranks;
|
|
const size_t num_T_per_slot = hidden + (sizeof(int) / sizeof(T));
|
|
for (int e = 0; e < num_local_experts; e++) {
|
|
std::cout << "Expert " << (rank * num_local_experts + e)
|
|
<< "[local expert " << e << "]:\n";
|
|
for (int r = 0; r < num_ranks; r++) {
|
|
std::cout << " To Rank " << r << ":\n";
|
|
// Starting offset and number of tokens sent to rank r
|
|
int64_t *layout_range = reinterpret_cast<int64_t*>(
|
|
packed_recv_layout_range + (e * num_ranks + r));
|
|
int num_tokens_from_r = reinterpret_cast<int*>(
|
|
layout_range)[0];
|
|
int offset_for_r = reinterpret_cast<int*>(
|
|
layout_range)[1];
|
|
std::cout << " Num tokens: " << num_tokens_from_r
|
|
<< ", Offset: " << offset_for_r
|
|
<< ", packed: " << *layout_range
|
|
<< ", addr: " << layout_range <<"\n";
|
|
for (int t = 0; t < num_tokens_from_r; t++) {
|
|
// int offset = e * num_ranks * num_tokens * hidden +
|
|
// (offset_for_r + t) * hidden + sizeof(int)/sizeof(T);
|
|
int offset = e * num_ranks * num_tokens * num_T_per_slot +
|
|
(offset_for_r + t) * num_T_per_slot +
|
|
sizeof(int)/sizeof(T);
|
|
std::cout << " Token " << t << ": (Index: "
|
|
<< packed_send_src_info_t[e * num_ranks * num_tokens +
|
|
(offset_for_r + t)]
|
|
<< ") " << " Addr: " << &combine_send_buffer_t[offset] << " ";
|
|
for (int h = 0; h < hidden; h++) {
|
|
std::cout << combine_send_buffer_t[offset + h] << " ";
|
|
}
|
|
std::cout << std::endl;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Print Ranks and the experts assigned to them
|
|
void print_expert_assignment() {
|
|
int num_local_experts = num_experts / num_ranks;
|
|
for (int r = 0; r < num_ranks; r++) {
|
|
// if (r == rank) {
|
|
std::cout << "Rank [" << r << "]: Experts: ";
|
|
for (int e = 0; e < num_local_experts; e++) {
|
|
std::cout << (r * num_local_experts + e) << " ";
|
|
}
|
|
std::cout << std::endl;
|
|
// }
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Function to print Atomic counters per expert from workspace
|
|
*/
|
|
void print_atomic_counters() {
|
|
int* atomic_counter_per_expert = reinterpret_cast<int*>(workspace);
|
|
int* atomic_finish_counter_per_expert = atomic_counter_per_expert +
|
|
num_experts;
|
|
std::cout << "Atomic counters per expert:\n";
|
|
for (int i = 0; i < num_experts; i++) {
|
|
std::cout << "Expert " << i << ": "
|
|
<< atomic_counter_per_expert[i]
|
|
<< ", Finish: "
|
|
<< atomic_finish_counter_per_expert[i]
|
|
<< std::endl;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Function to print packed_recv_x and packed_recv_src_info
|
|
* Dimensions:
|
|
* packed_recv_x: [num_local_experts][num_ranks][num_tokens][hidden]
|
|
* packed_recv_src_info: [num_local_experts][num_ranks][num_tokens]
|
|
* packed_recv_layout_range: [num_local_experts][num_ranks]
|
|
*/
|
|
void print_packed_recv_buffers(int num_local_experts) {
|
|
T* packed_recv_x_t = reinterpret_cast<T*>(packed_recv_x);
|
|
int* packed_recv_src_info_t =
|
|
reinterpret_cast<int*>(packed_recv_src_info);
|
|
for (int e = 0; e < num_local_experts; e++) {
|
|
std::cout << "Expert " << (rank * num_local_experts + e)
|
|
<< "[local expert " << e << "]:\n";
|
|
for (int r = 0; r < num_ranks; r++) {
|
|
// Starting offset and number of tokens received from rank r
|
|
std::cout << " From Rank " << r << ":\n";
|
|
int64_t *layout_range = reinterpret_cast<int64_t*>(
|
|
packed_recv_layout_range + (e * num_ranks + r));
|
|
int num_tokens_from_r = reinterpret_cast<int*>(
|
|
layout_range)[0];
|
|
int offset_for_r = reinterpret_cast<int*>(
|
|
layout_range)[1];
|
|
std::cout << " Num tokens: " << num_tokens_from_r
|
|
<< ", Offset: " << offset_for_r
|
|
<< ", packed: " << *layout_range
|
|
<< ", addr: " << layout_range <<"\n";
|
|
for (int t = 0; t < num_tokens_from_r; t++) {
|
|
int offset = e * num_ranks * num_tokens * hidden +
|
|
(offset_for_r + t) * hidden;
|
|
std::cout << " Token " << t << ": (Index: "
|
|
<< packed_recv_src_info_t[e * num_ranks * num_tokens +
|
|
(offset_for_r + t)]
|
|
<< ") " << " Addr: " << &packed_recv_x_t[offset] << " ";
|
|
for (int h = 0; h < hidden; h++) {
|
|
std::cout << packed_recv_x_t[offset + h] << " ";
|
|
}
|
|
std::cout << std::endl;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Function to print number of tokens received by each expert
|
|
* Dimensions: [num_local_experts][num_ranks]
|
|
*/
|
|
void print_dispatch_recv_counts(int num_local_experts,
|
|
void* recv_count_buffer) {
|
|
int64_t* recv_count = reinterpret_cast<int64_t*>(recv_count_buffer);
|
|
for (int e = 0; e < num_local_experts; e++) {
|
|
std::cout << "Expert " << (rank * num_local_experts + e) << ":\n";
|
|
for (int r = 0; r < num_ranks; r++) {
|
|
std::cout << " From Rank " << r << ": "
|
|
<< -recv_count[e * num_ranks + r] - 1
|
|
<< std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Function to print rdma_x of dimensions [num_tokens][int + hidden]
|
|
* for debugging purposes.
|
|
*/
|
|
void print_rdma_x(void* rdma_x) {
|
|
T* rdma_x_t = reinterpret_cast<T*>(rdma_x);
|
|
for (int i = 0; i < num_tokens; i++) {
|
|
std::cout << "Token " << i << ": ";
|
|
int token_idx = *(reinterpret_cast<int*>(
|
|
reinterpret_cast<uint8_t*>(rdma_x) + i * (sizeof(int) +
|
|
hidden * sizeof(T))));
|
|
int *token_addr = reinterpret_cast<int*>(
|
|
reinterpret_cast<uint8_t*>(rdma_x) + i * (sizeof(int) +
|
|
hidden * sizeof(T)));
|
|
std::cout << "[Addr: " << token_addr << "] ";
|
|
std::cout << "(Index: " << token_idx << ") ";
|
|
for (int j = 0; j < hidden; j++) {
|
|
std::cout << rdma_x_t[i * (hidden + sizeof(int)/sizeof(T)) +
|
|
sizeof(int)/sizeof(T) + j] << " ";
|
|
}
|
|
std::cout << std::endl;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Function to print rdma_recv_x of dimensions
|
|
* [num_local_experts][num_ranks][num_tokens][int + hidden]
|
|
*/
|
|
void print_rdma_recv_x(void* rdma_recv_x, int num_local_experts) {
|
|
|
|
// Dimensions:
|
|
std::cout << "rdma_recv_x dimensions: ["
|
|
<< num_local_experts << "]["
|
|
<< num_ranks << "]["
|
|
<< num_tokens << "]["
|
|
<< sizeof(int) + hidden * sizeof(T) << "]\n";
|
|
|
|
T* rdma_recv_x_t = reinterpret_cast<T*>(rdma_recv_x);
|
|
const size_t msg_size = sizeof(int) + hidden * sizeof(T);
|
|
for (int expert = 0; expert < num_local_experts; expert++) {
|
|
for (int rank = 0; rank < num_ranks; rank++) {
|
|
std::cout << "Expert " << expert << ", Rank " << rank << ":\n";
|
|
for (int token = 0; token < num_tokens; token++) {
|
|
int offset = expert * num_ranks * num_tokens * msg_size +
|
|
rank * num_tokens * msg_size +
|
|
token * msg_size;
|
|
int token_idx = *(reinterpret_cast<int*>(
|
|
reinterpret_cast<uint8_t*>(rdma_recv_x) + offset));
|
|
// Print the address of the token index for debugging
|
|
int *token_addr = reinterpret_cast<int*>(
|
|
reinterpret_cast<uint8_t*>(rdma_recv_x) + offset);
|
|
std::cout << "[Addr: " << token_addr << "] ";
|
|
std::cout << " Token " << token << ": (Index: " << token_idx << ") ";
|
|
for (int j = 0; j < hidden; j++) {
|
|
std::cout << rdma_recv_x_t[offset / sizeof(T) +
|
|
sizeof(int)/sizeof(T) + j] << " ";
|
|
}
|
|
std::cout << std::endl;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|