main
cuh 92 lines 2.81 KB
Raw
1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 #pragma once
5
6 #include <cuda_runtime.h>
7
8 #include <cstdint>
9 #include <string>
10
11 #include "../../torch_utils.h"
12
13 namespace vllm::direct_dcp {
14
15 constexpr uint64_t kSpinLimit = 100000000;
16
17 // Advance the invocation ID; its low bit selects one of two staging slots.
18 static __global__ void increment_epoch_kernel(int64_t* epoch) {
19 if (blockIdx.x == 0 && threadIdx.x == 0) {
20 epoch[0] += 1;
21 }
22 }
23
24 template <typename T>
25 __device__ __forceinline__ T* get_peer_ptr(const int64_t* peer_ptrs,
26 int64_t peer) {
27 return reinterpret_cast<T*>(static_cast<uintptr_t>(peer_ptrs[peer]));
28 }
29
30 // Replicate one 16-byte payload to every symmetric-buffer replica.
31 __device__ __forceinline__ void multimem_store_16(uint4* mc_ptr, uint4 value) {
32 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 900
33 asm volatile("multimem.st.relaxed.sys.global.v4.f32 [%0], {%1,%2,%3,%4};"
34 :
35 : "l"(mc_ptr), "r"(value.x), "r"(value.y), "r"(value.z),
36 "r"(value.w)
37 : "memory");
38 #else
39 asm volatile("trap;");
40 #endif
41 }
42
43 // Publish prior system-scope writes and signal every replica.
44 __device__ __forceinline__ void multimem_store_release_system(uint32_t* mc_ptr,
45 uint32_t value) {
46 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 900
47 asm volatile("multimem.st.release.sys.global.u32 [%0], %1;"
48 :
49 : "l"(mc_ptr), "r"(value)
50 : "memory");
51 #else
52 asm volatile("trap;");
53 #endif
54 }
55
56 __device__ __forceinline__ void store_release_system(uint32_t* ptr,
57 uint32_t value) {
58 uint64_t address = reinterpret_cast<uint64_t>(ptr);
59 asm volatile("st.global.release.sys.u32 [%0], %1;"
60 :
61 : "l"(address), "r"(value)
62 : "memory");
63 }
64
65 __device__ __forceinline__ uint32_t load_acquire_system(const uint32_t* ptr) {
66 uint32_t value;
67 uint64_t address = reinterpret_cast<uint64_t>(ptr);
68 asm volatile("ld.global.acquire.sys.u32 %0, [%1];"
69 : "=r"(value)
70 : "l"(address)
71 : "memory");
72 return value;
73 }
74
75 __device__ __forceinline__ bool wait_for_epoch(const uint32_t* ptr,
76 uint32_t epoch) {
77 for (uint64_t spins = 0; spins < kSpinLimit; ++spins) {
78 if (load_acquire_system(ptr) == epoch) {
79 return true;
80 }
81 }
82 return false;
83 }
84
85 inline void check_cuda_launch(const char* operation) {
86 cudaError_t error = cudaGetLastError();
87 STD_TORCH_CHECK(error == cudaSuccess,
88 std::string(operation) +
89 " kernel launch failed: " + cudaGetErrorString(error));
90 }
91
92 } // namespace vllm::direct_dcp