From d0ad001a3ac914c6ef7527ba25ac0835f6716c28 Mon Sep 17 00:00:00 2001 From: Chris Leonard Date: Thu, 11 Jun 2026 19:54:36 +0000 Subject: [PATCH 01/11] moved csrc/quantization/activation_kernels.cu to csrc/libtorch_stable/quantization/activation_kernels.cu Signed-off-by: Chris Leonard --- csrc/{ => libtorch_stable}/quantization/activation_kernels.cu | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename csrc/{ => libtorch_stable}/quantization/activation_kernels.cu (100%) diff --git a/csrc/quantization/activation_kernels.cu b/csrc/libtorch_stable/quantization/activation_kernels.cu similarity index 100% rename from csrc/quantization/activation_kernels.cu rename to csrc/libtorch_stable/quantization/activation_kernels.cu From c6dde94001736e1206795521b5cbc6806ef0cecc Mon Sep 17 00:00:00 2001 From: Chris Leonard Date: Fri, 12 Jun 2026 14:52:48 +0000 Subject: [PATCH 02/11] migrated csrc/libtorch_stable/quantization/activation_kernels.cu to be abi stable and removed the last cuda kernels from csrc/ops.h and csrc/torch_bindings.cpp and moved them to the libtorch_stable files Signed-off-by: Chris Leonard --- CMakeLists.txt | 155 ++++++++++-------- csrc/libtorch_stable/ops.h | 28 ++++ .../quantization/activation_kernels.cu | 117 ++++++------- csrc/libtorch_stable/torch_bindings.cpp | 27 +++ csrc/ops.h | 32 ---- csrc/torch_bindings.cpp | 39 ----- setup.py | 3 +- vllm/platforms/cuda.py | 1 - 8 files changed, 202 insertions(+), 200 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a2651ab344ca..8c88ba2b2675 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -319,82 +319,35 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") endif() # -# _C extension +# Legacy _C extension (ROCm only — CUDA ops migrated to _C_stable_libtorch) # -set(VLLM_EXT_SRC - "csrc/quantization/activation_kernels.cu" - "csrc/torch_bindings.cpp") - -if(VLLM_GPU_LANG STREQUAL "CUDA") - SET(CUTLASS_ENABLE_HEADERS_ONLY ON CACHE BOOL "Enable only the header library") - - # Set CUTLASS_REVISION. Used for FetchContent. Also fixes some bogus messages when building. - set(CUTLASS_REVISION "v4.4.2") - - # Use the specified CUTLASS source directory for compilation if VLLM_CUTLASS_SRC_DIR is provided - if (DEFINED ENV{VLLM_CUTLASS_SRC_DIR}) - set(VLLM_CUTLASS_SRC_DIR $ENV{VLLM_CUTLASS_SRC_DIR}) - endif() - - if(VLLM_CUTLASS_SRC_DIR) - if(NOT IS_ABSOLUTE VLLM_CUTLASS_SRC_DIR) - get_filename_component(VLLM_CUTLASS_SRC_DIR "${VLLM_CUTLASS_SRC_DIR}" ABSOLUTE) - endif() - message(STATUS "The VLLM_CUTLASS_SRC_DIR is set, using ${VLLM_CUTLASS_SRC_DIR} for compilation") - FetchContent_Declare(cutlass SOURCE_DIR ${VLLM_CUTLASS_SRC_DIR}) - else() - FetchContent_Declare( - cutlass - GIT_REPOSITORY https://github.com/nvidia/cutlass.git - # Please keep this in sync with CUTLASS_REVISION line above. - GIT_TAG ${CUTLASS_REVISION} - GIT_PROGRESS TRUE - - # Speed up CUTLASS download by retrieving only the specified GIT_TAG instead of the history. - # Important: If GIT_SHALLOW is enabled then GIT_TAG works only with branch names and tags. - # So if the GIT_TAG above is updated to a commit hash, GIT_SHALLOW must be set to FALSE - GIT_SHALLOW TRUE - ) - endif() - FetchContent_MakeAvailable(cutlass) - - set_gencode_flags_for_srcs( - SRCS "${VLLM_EXT_SRC}" - CUDA_ARCHS "${CUDA_ARCHS}") - -# if CUDA endif -endif() - -if (VLLM_GPU_LANG STREQUAL "HIP") - # Add QuickReduce kernels (ROCm-only; not part of stable ABI migration). - # TODO: Remove the cuda_view when ROCm upgrade to torch 2.11. - list(APPEND VLLM_EXT_SRC +if(VLLM_GPU_LANG STREQUAL "HIP") + set(VLLM_EXT_SRC + "csrc/torch_bindings.cpp" "csrc/custom_quickreduce.cu" "csrc/cuda_view.cu" - "csrc/libtorch_stable/cuda_utils_kernels.cu" - ) -# if ROCM endif -endif() + "csrc/libtorch_stable/cuda_utils_kernels.cu") -message(STATUS "Enabling C extension.") -define_extension_target( - _C - DESTINATION vllm - LANGUAGE ${VLLM_GPU_LANG} - SOURCES ${VLLM_EXT_SRC} - COMPILE_FLAGS ${VLLM_GPU_FLAGS} - ARCHITECTURES ${VLLM_GPU_ARCHES} - INCLUDE_DIRECTORIES ${CUTLASS_INCLUDE_DIR} - INCLUDE_DIRECTORIES ${CUTLASS_TOOLS_UTIL_INCLUDE_DIR} - USE_SABI 3 - WITH_SOABI) + message(STATUS "Enabling C extension.") + define_extension_target( + _C + DESTINATION vllm + LANGUAGE ${VLLM_GPU_LANG} + SOURCES ${VLLM_EXT_SRC} + COMPILE_FLAGS ${VLLM_GPU_FLAGS} + ARCHITECTURES ${VLLM_GPU_ARCHES} + INCLUDE_DIRECTORIES ${CUTLASS_INCLUDE_DIR} + INCLUDE_DIRECTORIES ${CUTLASS_TOOLS_UTIL_INCLUDE_DIR} + USE_SABI 3 + WITH_SOABI) -# If CUTLASS is compiled on NVCC >= 12.5, it by default uses -# cudaGetDriverEntryPointByVersion as a wrapper to avoid directly calling the -# driver API. This causes problems when linking with earlier versions of CUDA. -# Setting this variable sidesteps the issue by calling the driver directly. -target_compile_definitions(_C PRIVATE CUTLASS_ENABLE_DIRECT_CUDA_DRIVER_CALL=1) + # If CUTLASS is compiled on NVCC >= 12.5, it by default uses + # cudaGetDriverEntryPointByVersion as a wrapper to avoid directly calling the + # driver API. This causes problems when linking with earlier versions of CUDA. + # Setting this variable sidesteps the issue by calling the driver directly. + target_compile_definitions(_C PRIVATE CUTLASS_ENABLE_DIRECT_CUDA_DRIVER_CALL=1) +endif() if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") # @@ -403,6 +356,7 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") set(VLLM_STABLE_EXT_SRC "csrc/libtorch_stable/torch_bindings.cpp" "csrc/libtorch_stable/activation_kernels.cu" + "csrc/libtorch_stable/quantization/activation_kernels.cu" "csrc/libtorch_stable/quantization/w8a8/int8/scaled_quant.cu" "csrc/libtorch_stable/quantization/w8a8/fp8/common.cu" "csrc/libtorch_stable/quantization/w8a8/fp8/per_token_group_quant.cu" @@ -429,6 +383,65 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") "csrc/libtorch_stable/fused_deepseek_v4_qnorm_rope_kv_insert_kernel.cu") if(VLLM_GPU_LANG STREQUAL "CUDA") + SET(CUTLASS_ENABLE_HEADERS_ONLY ON CACHE BOOL "Enable only the header library") + + # Set CUTLASS_REVISION. Used for FetchContent. Also fixes some bogus messages when building. + set(CUTLASS_REVISION "v4.4.2") + + # Use the specified CUTLASS source directory for compilation if VLLM_CUTLASS_SRC_DIR is provided + if (DEFINED ENV{VLLM_CUTLASS_SRC_DIR}) + set(VLLM_CUTLASS_SRC_DIR $ENV{VLLM_CUTLASS_SRC_DIR}) + endif() + + if(VLLM_CUTLASS_SRC_DIR) + if(NOT IS_ABSOLUTE VLLM_CUTLASS_SRC_DIR) + get_filename_component(VLLM_CUTLASS_SRC_DIR "${VLLM_CUTLASS_SRC_DIR}" ABSOLUTE) + endif() + message(STATUS "The VLLM_CUTLASS_SRC_DIR is set, using ${VLLM_CUTLASS_SRC_DIR} for compilation") + FetchContent_Declare(cutlass SOURCE_DIR ${VLLM_CUTLASS_SRC_DIR}) + else() + FetchContent_Declare( + cutlass + GIT_REPOSITORY https://github.com/nvidia/cutlass.git + # Please keep this in sync with CUTLASS_REVISION line above. + GIT_TAG ${CUTLASS_REVISION} + GIT_PROGRESS TRUE + + # Speed up CUTLASS download by retrieving only the specified GIT_TAG instead of the history. + # Important: If GIT_SHALLOW is enabled then GIT_TAG works only with branch names and tags. + # So if the GIT_TAG above is updated to a commit hash, GIT_SHALLOW must be set to FALSE + GIT_SHALLOW TRUE + ) + endif() + FetchContent_MakeAvailable(cutlass) + + # Expert-specialization MXFP8 blockscaled grouped kernels (SM100+). + if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 13.0) + cuda_archs_loose_intersection(ES_MXFP8_GROUPED_MM_ARCHS "10.0f;11.0f" "${CUDA_ARCHS}") + else() + cuda_archs_loose_intersection(ES_MXFP8_GROUPED_MM_ARCHS "10.0a;10.1a;10.3a" "${CUDA_ARCHS}") + endif() + if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 AND ES_MXFP8_GROUPED_MM_ARCHS) + set(SRCS + "csrc/libtorch_stable/moe/mxfp8_moe/cutlass_mxfp8_grouped_mm.cu" + "csrc/libtorch_stable/moe/mxfp8_moe/mxfp8_experts_quant.cu") + set_gencode_flags_for_srcs( + SRCS "${SRCS}" + CUDA_ARCHS "${ES_MXFP8_GROUPED_MM_ARCHS}") + list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") + list(APPEND VLLM_GPU_FLAGS "-DENABLE_ES_MXFP8_GROUPED_MM_SM100=1") + message(STATUS "Building ES MXFP8 grouped kernels for archs: ${ES_MXFP8_GROUPED_MM_ARCHS}") + else() + if (NOT ${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 + AND ES_MXFP8_GROUPED_MM_ARCHS) + message(STATUS "Not building ES MXFP8 grouped kernels as CUDA Compiler version is " + "not >= 12.8.") + else() + message(STATUS "Not building ES MXFP8 grouped kernels as no compatible archs found " + "in CUDA target architectures.") + endif() + endif() + list(APPEND VLLM_STABLE_EXT_SRC "csrc/libtorch_stable/cuda_view.cu" "csrc/libtorch_stable/cuda_utils_kernels.cu" @@ -929,7 +942,6 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") SRCS "${FP4_SM120_SRCS}" CUDA_ARCHS "${FP4_SM120_ARCHS}") list(APPEND VLLM_STABLE_EXT_SRC "${FP4_SM120_SRCS}") - target_compile_definitions(_C PRIVATE ENABLE_NVFP4_SM120=1) list(APPEND VLLM_GPU_FLAGS "-DENABLE_NVFP4_SM120=1") list(APPEND VLLM_GPU_FLAGS "-DENABLE_CUTLASS_MOE_SM120=1") message(STATUS "Building SM12x NVFP4 for archs: ${FP4_SM120_ARCHS}") @@ -962,7 +974,6 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") SRCS "${FP4_SM100_SRCS}" CUDA_ARCHS "${FP4_SM100_ARCHS}") list(APPEND VLLM_STABLE_EXT_SRC "${FP4_SM100_SRCS}") - target_compile_definitions(_C PRIVATE ENABLE_NVFP4_SM100=1) list(APPEND VLLM_GPU_FLAGS "-DENABLE_NVFP4_SM100=1") list(APPEND VLLM_GPU_FLAGS "-DENABLE_CUTLASS_MOE_SM100=1") message(STATUS "Building SM10x/11x NVFP4/MXFP4 for archs: ${FP4_SM100_ARCHS}") diff --git a/csrc/libtorch_stable/ops.h b/csrc/libtorch_stable/ops.h index 9efc12e9f495..7d9cd02f72ac 100644 --- a/csrc/libtorch_stable/ops.h +++ b/csrc/libtorch_stable/ops.h @@ -1,10 +1,26 @@ #pragma once +#include "torch_utils.h" + #include #include #include #include +#include + +inline torch::stable::Tensor weak_ref_tensor(torch::stable::Tensor& tensor) { + // Ensure tensor is on CUDA + STD_TORCH_CHECK(tensor.device().is_cuda(), "Tensor must be on CUDA device"); + + // Get the raw data pointer + void* data_ptr = const_cast(tensor.mutable_data_ptr()); + + // Create a new tensor from the raw data pointer + return torch::stable::from_blob(data_ptr, tensor.sizes(), tensor.strides(), + tensor.device(), tensor.scalar_type(), + [base = tensor](void*) {}); +} void per_token_group_quant_fp8(const torch::stable::Tensor& input, torch::stable::Tensor& output_q, @@ -371,6 +387,18 @@ void silu_and_mul(torch::stable::Tensor& out, torch::stable::Tensor& input); void silu_and_mul_clamp(torch::stable::Tensor& out, torch::stable::Tensor& input, double limit, double alpha = 1.0, double beta = 0.0); + +void silu_and_mul_quant(torch::stable::Tensor& out, + torch::stable::Tensor& input, + torch::stable::Tensor& scale); + +void persistent_masked_m_silu_mul_quant( + const torch::stable::Tensor& input, // (E, T, 2*H) + const torch::stable::Tensor& tokens_per_expert, // (E) + torch::stable::Tensor& y_q, // (E, T, H) [OUT] + torch::stable::Tensor& y_s, // (E, T, H//group_size) [OUT] + bool cast_scale_ue8m0); + void mul_and_silu(torch::stable::Tensor& out, torch::stable::Tensor& input); void gelu_and_mul(torch::stable::Tensor& out, torch::stable::Tensor& input); void gelu_tanh_and_mul(torch::stable::Tensor& out, diff --git a/csrc/libtorch_stable/quantization/activation_kernels.cu b/csrc/libtorch_stable/quantization/activation_kernels.cu index 8cc645c33e2f..f8534dafa5b9 100644 --- a/csrc/libtorch_stable/quantization/activation_kernels.cu +++ b/csrc/libtorch_stable/quantization/activation_kernels.cu @@ -1,16 +1,12 @@ -#include -#include -#include +#include "libtorch_stable/torch_utils.h" #include -#include "core/math.hpp" -#include "../cuda_compat.h" -#include "dispatch_utils.h" +#include "core/math.hpp" +#include "cuda_compat.h" +#include "libtorch_stable/dispatch_utils.h" #include "quantization/w8a8/fp8/common.cuh" -#include - #ifndef USE_ROCM #include #include @@ -33,7 +29,6 @@ typedef __hip_fp8x4_e4m3_fnuz __nv_fp8x4_e4m3; #endif #endif -#include "core/registration.h" namespace vllm { template @@ -564,41 +559,47 @@ __global__ void silu_mul_fp8_quant_deep_gemm_kernel( } // namespace vllm // Launch activation, gating, and quantize kernel. -#define LAUNCH_ACTIVATION_GATE_KERNEL(KERNEL) \ - int d = input.size(-1) / 2; \ - int64_t num_tokens = input.numel() / input.size(-1); \ - dim3 grid(num_tokens, num_tokens > 16 ? num_tokens > 32 ? 1 : 2 : 4); \ - dim3 block(std::min(d, 512)); \ - const at::cuda::OptionalCUDAGuard device_guard(device_of(input)); \ - const cudaStream_t stream = at::cuda::getCurrentCUDAStream(); \ - VLLM_DISPATCH_FLOATING_TYPES( \ - input.scalar_type(), "act_and_mul_kernel", [&] { \ - VLLM_DISPATCH_FP8_TYPES( \ - out.scalar_type(), "fused_add_rms_norm_kernel_fp8_type", [&] { \ - vllm::act_and_mul_quant_kernel, \ - fp8_t> \ - <<>>(out.data_ptr(), \ - input.data_ptr(), \ - scale.data_ptr(), d); \ - }); \ +#define LAUNCH_ACTIVATION_GATE_KERNEL(KERNEL) \ + int d = input.size(-1) / 2; \ + int64_t num_tokens = input.numel() / input.size(-1); \ + dim3 grid(num_tokens, num_tokens > 16 ? num_tokens > 32 ? 1 : 2 : 4); \ + dim3 block(std::min(d, 512)); \ + const torch::stable::accelerator::DeviceGuard device_guard( \ + input.get_device_index()); \ + const cudaStream_t stream = \ + get_current_cuda_stream(input.get_device_index()); \ + VLLM_STABLE_DISPATCH_FLOATING_TYPES( \ + input.scalar_type(), "act_and_mul_kernel", [&] { \ + VLLM_STABLE_DISPATCH_FP8_TYPES( \ + out.scalar_type(), "act_and_mul_quant_kernel_fp8_type", [&] { \ + vllm::act_and_mul_quant_kernel, \ + fp8_t> \ + <<>>( \ + out.mutable_data_ptr(), \ + input.const_data_ptr(), \ + scale.const_data_ptr(), d); \ + }); \ }); -void silu_and_mul_quant(torch::Tensor& out, // [..., d] - torch::Tensor& input, // [..., 2 * d] - torch::Tensor& scale) { - TORCH_CHECK(out.dtype() == torch::kFloat8_e4m3fn || - out.dtype() == torch::kFloat8_e4m3fnuz); - TORCH_CHECK(input.dtype() == torch::kFloat16 || - input.dtype() == torch::kBFloat16); - TORCH_CHECK(input.size(-1) % 2 == 0); +void silu_and_mul_quant(torch::stable::Tensor& out, // [..., d] + torch::stable::Tensor& input, // [..., 2 * d] + torch::stable::Tensor& scale) { + STD_TORCH_CHECK( + out.scalar_type() == torch::headeronly::ScalarType::Float8_e4m3fn || + out.scalar_type() == torch::headeronly::ScalarType::Float8_e4m3fnuz); + STD_TORCH_CHECK( + input.scalar_type() == torch::headeronly::ScalarType::Half || + input.scalar_type() == torch::headeronly::ScalarType::BFloat16, + "Input must be FP16 or BF16"); + STD_TORCH_CHECK(input.size(-1) % 2 == 0); LAUNCH_ACTIVATION_GATE_KERNEL(vllm::silu_kernel); } void persistent_masked_m_silu_mul_quant( - const at::Tensor& input, // (E, T, 2*H) - const at::Tensor& tokens_per_expert, // (E) - at::Tensor& y_q, // (E, T, H) [OUT] - at::Tensor& y_s, // (E, T, H//group_size) [OUT] + const torch::stable::Tensor& input, // (E, T, 2*H) + const torch::stable::Tensor& tokens_per_expert, // (E) + torch::stable::Tensor& y_q, // (E, T, H) [OUT] + torch::stable::Tensor& y_s, // (E, T, H//group_size) [OUT] bool cast_scale_ue8m0) { #ifndef USE_ROCM @@ -606,14 +607,18 @@ void persistent_masked_m_silu_mul_quant( // fixed GROUP_SIZE of 128. static constexpr int GROUP_SIZE = 128; - TORCH_CHECK(input.dtype() == torch::kBFloat16); - TORCH_CHECK(y_q.dtype() == torch::kFloat8_e4m3fn || - y_q.dtype() == torch::kFloat8_e4m3fnuz); - TORCH_CHECK(input.size(-1) % (GROUP_SIZE * 2) == 0); + STD_TORCH_CHECK(input.scalar_type() == + torch::headeronly::ScalarType::BFloat16); + STD_TORCH_CHECK( + y_q.scalar_type() == torch::headeronly::ScalarType::Float8_e4m3fn || + y_q.scalar_type() == torch::headeronly::ScalarType::Float8_e4m3fnuz); + STD_TORCH_CHECK(input.size(-1) % (GROUP_SIZE * 2) == 0); bool const is_packed_ue8m0 = - (y_s.dtype() == torch::kInt32 && cast_scale_ue8m0); - TORCH_CHECK(y_s.dtype() == torch::kFloat32 || is_packed_ue8m0); + (y_s.scalar_type() == torch::headeronly::ScalarType::Int && + cast_scale_ue8m0); + STD_TORCH_CHECK(y_s.scalar_type() == torch::headeronly::ScalarType::Float || + is_packed_ue8m0); using Idx_t = int64_t; @@ -631,7 +636,7 @@ void persistent_masked_m_silu_mul_quant( int const NUM_GROUPS = H / GROUP_SIZE; - const cudaStream_t stream = at::cuda::getCurrentCUDAStream(); + const cudaStream_t stream = get_current_cuda_stream(input.get_device_index()); // TODO: Get this from cuda_arch ? static constexpr int SILU_V2_BLOCK_COUNT = 132 * 32; @@ -643,18 +648,20 @@ void persistent_masked_m_silu_mul_quant( static constexpr int max_shared_mem_bytes = \ GROUP_SIZE * 2 * STAGES * NUM_WARPS * 2; \ dim3 grid(sms), block(THREAD_COUNT); \ - const at::cuda::OptionalCUDAGuard device_guard(device_of(input)); \ - VLLM_DISPATCH_FP8_TYPES( \ + const torch::stable::accelerator::DeviceGuard device_guard( \ + input.get_device_index()); \ + VLLM_STABLE_DISPATCH_FP8_TYPES( \ y_q.scalar_type(), "silu_mul_fp8_quant_deep_gemm_kernel", [&] { \ vllm::silu_mul_fp8_quant_deep_gemm_kernel< \ BLOCK_COUNT, max_shared_mem_bytes, fp8_t, scale_t, THREAD_COUNT, \ Idx_t, CEIL_UE8M0, GROUP_SIZE, STAGES> \ <<>>( \ - reinterpret_cast<__nv_bfloat16*>(input.data_ptr()), \ - (fp8_t*)y_q.data_ptr(), \ - reinterpret_cast(y_s.data_ptr()), \ - reinterpret_cast(tokens_per_expert.data_ptr()), E, \ - T, H, stride_i_e, stride_i_t, stride_i_h, stride_yq_e, \ + reinterpret_cast<__nv_bfloat16*>(input.mutable_data_ptr()), \ + y_q.mutable_data_ptr(), \ + reinterpret_cast(y_s.mutable_data_ptr()), \ + reinterpret_cast( \ + tokens_per_expert.mutable_data_ptr()), \ + E, T, H, stride_i_e, stride_i_t, stride_i_h, stride_yq_e, \ stride_yq_t, stride_yq_h, STRIDE_YS_E, STRIDE_YS_T, \ STRIDE_YS_G, STRIDE_YS_P, stride_counts_e); \ }); @@ -679,7 +686,7 @@ void persistent_masked_m_silu_mul_quant( Idx_t stride_ys_g = y_s.stride(2); Idx_t stride_ys_p = 0; if (!cast_scale_ue8m0) { - TORCH_CHECK(!is_packed_ue8m0); + STD_TORCH_CHECK(!is_packed_ue8m0); LAUNCH_ON_H(float, stride_ys_e, stride_ys_t, stride_ys_g, stride_ys_p, false); return; @@ -692,8 +699,8 @@ void persistent_masked_m_silu_mul_quant( return; } - TORCH_CHECK(cast_scale_ue8m0 && is_packed_ue8m0); - TORCH_CHECK(y_s.dtype() == torch::kInt32); + STD_TORCH_CHECK(cast_scale_ue8m0 && is_packed_ue8m0); + STD_TORCH_CHECK(y_s.scalar_type() == torch::headeronly::ScalarType::Int); // Int32 packed ue8m0 scales tensor. // Let E, T, G be the number to experts, number of tokens and number of groups diff --git a/csrc/libtorch_stable/torch_bindings.cpp b/csrc/libtorch_stable/torch_bindings.cpp index c1d2d26fcd83..1b5929d6ccd9 100644 --- a/csrc/libtorch_stable/torch_bindings.cpp +++ b/csrc/libtorch_stable/torch_bindings.cpp @@ -34,6 +34,20 @@ STABLE_TORCH_LIBRARY_FRAGMENT(_C, ops) { // TODO: Remove this once ROCm upgrade to torch 2.11. ops.def("get_cuda_view_from_cpu_tensor(Tensor cpu_tensor) -> Tensor"); + // Note about marlin kernel 'workspace' arguments: + // Technically these should be mutable since they are modified by the kernel. + // But since they are set back to zero once the kernel is finished we can + // hand wave and say that they have no net effect. + // + // The reason to mark 'workspace' as immutable is so that they don't interfere + // with using ScalarType arguments in the ops. If they are marked as mutable, + // pytorch throws an assert in + // 'torch._higher_order_ops._register_effectful_op' that prevents these + // kernels from being torch.compile'd. + // See the following document for more info on custom types and ops that use + // custom types: + // https://docs.google.com/document/d/18fBMPuOJ0fY5ZQ6YyrHUppw9FA332CpNtgB6SOIgyuA + // Machete (Dense) Optimized Mixed Precision GEMM for Hopper. ops.def( "machete_supported_schedules(" @@ -480,6 +494,11 @@ STABLE_TORCH_LIBRARY_FRAGMENT(_C, ops) { "Tensor workspace, int k, int max_seq_len) -> ()"); // Activation ops + ops.def( + "persistent_masked_m_silu_mul_quant(Tensor input, Tensor counts, Tensor! " + "y_q, Tensor! y_s, bool use_ue8m0) -> ()"); + ops.def("weak_ref_tensor(Tensor input) -> Tensor"); + // Activation function used in SwiGLU. ops.def("silu_and_mul(Tensor! result, Tensor input) -> ()"); @@ -492,6 +511,10 @@ STABLE_TORCH_LIBRARY_FRAGMENT(_C, ops) { "silu_and_mul_with_clamp(Tensor! result, Tensor input, float limit, " "float alpha=1.0, float beta=0.0) -> ()"); + // SwiGLU activation with FP8 quantization. + ops.def( + "silu_and_mul_quant(Tensor! result, Tensor input, Tensor scale) -> ()"); + // Activation function used in GeGLU with `none` approximation. ops.def("gelu_and_mul(Tensor! out, Tensor input) -> ()"); @@ -690,6 +713,10 @@ STABLE_TORCH_LIBRARY_IMPL(_C, CUDA, ops) { ops.impl("persistent_topk", TORCH_BOX(&persistent_topk)); // Activation kernels (shared CUDA/ROCm) + ops.impl("persistent_masked_m_silu_mul_quant", + TORCH_BOX(&persistent_masked_m_silu_mul_quant)); + ops.impl("weak_ref_tensor", TORCH_BOX(&weak_ref_tensor)); + ops.impl("silu_and_mul_quant", TORCH_BOX(&silu_and_mul_quant)); ops.impl("silu_and_mul", TORCH_BOX(&silu_and_mul)); ops.impl("mul_and_silu", TORCH_BOX(&mul_and_silu)); ops.impl("gelu_and_mul", TORCH_BOX(&gelu_and_mul)); diff --git a/csrc/ops.h b/csrc/ops.h index ec3f5e187cc3..398ae1016f3a 100644 --- a/csrc/ops.h +++ b/csrc/ops.h @@ -9,28 +9,6 @@ #include -torch::Tensor weak_ref_tensor(torch::Tensor& tensor) { - // Ensure tensor is on CUDA - if (!tensor.is_cuda()) { - throw std::runtime_error("Tensor must be on CUDA device"); - } - - // Get the raw data pointer - void* data_ptr = tensor.data_ptr(); - - // Get tensor sizes and strides - std::vector sizes = tensor.sizes().vec(); - std::vector strides = tensor.strides().vec(); - - // Get tensor options (dtype, device) - auto options = tensor.options(); - - // Create a new tensor from the raw data pointer - auto new_tensor = torch::from_blob(data_ptr, sizes, strides, options); - - return new_tensor; -} - // rms_norm and fused_add_rms_norm declarations also exist in // csrc/libtorch_stable/ops.h (torch::stable ABI for CUDA). They remain here // because the CPU build still uses these torch::Tensor declarations. @@ -53,16 +31,6 @@ void silu_and_mul(torch::Tensor& out, torch::Tensor& input); void silu_and_mul_clamp(torch::Tensor& out, torch::Tensor& input, double limit, double alpha = 1.0, double beta = 0.0); -void silu_and_mul_quant(torch::Tensor& out, torch::Tensor& input, - torch::Tensor& scale); - -void persistent_masked_m_silu_mul_quant( - const at::Tensor& input, // (E, T, 2*H) - const at::Tensor& counts, // (E) - at::Tensor& y_q, // (E, T, H) [OUT] - at::Tensor& y_s, // (E, T, H//group_size) [OUT] - bool use_ue8m0); - void gelu_and_mul(torch::Tensor& out, torch::Tensor& input); void gelu_tanh_and_mul(torch::Tensor& out, torch::Tensor& input); diff --git a/csrc/torch_bindings.cpp b/csrc/torch_bindings.cpp index cfd185394a41..0a47729628e5 100644 --- a/csrc/torch_bindings.cpp +++ b/csrc/torch_bindings.cpp @@ -22,16 +22,6 @@ TORCH_LIBRARY_EXPAND(TORCH_EXTENSION_NAME, ops) { // vLLM custom ops // - ops.def( - "persistent_masked_m_silu_mul_quant(Tensor input, Tensor counts, Tensor! " - "y_q, Tensor! y_s," - "bool use_ue8m0) -> ()"); - ops.impl("persistent_masked_m_silu_mul_quant", torch::kCUDA, - &persistent_masked_m_silu_mul_quant); - - ops.def("weak_ref_tensor(Tensor input) -> Tensor"); - ops.impl("weak_ref_tensor", torch::kCUDA, &weak_ref_tensor); - #ifdef USE_ROCM // TODO: Remove this once we upgrade to torch 2.11. // ROCm still uses torch 2.10, @@ -39,35 +29,6 @@ TORCH_LIBRARY_EXPAND(TORCH_EXTENSION_NAME, ops) { ops.def("get_cuda_view_from_cpu_tensor(Tensor cpu_tensor) -> Tensor"); ops.impl("get_cuda_view_from_cpu_tensor", torch::kCPU, &get_cuda_view_from_cpu_tensor); -#endif - - // Activation ops (quantized only — basic ops moved to _C_stable_libtorch) - ops.def( - "silu_and_mul_quant(Tensor! result, Tensor input, Tensor scale) -> ()"); - ops.impl("silu_and_mul_quant", torch::kCUDA, &silu_and_mul_quant); - - // Horizontally-fused DeepseekV4-MLA: per-head RMSNorm + GPT-J RoPE for Q, and - // GPT-J RoPE + UE8M0 FP8 quant + paged cache insert for KV, all in one - // kernel launch. Registered in _C_stable_libtorch (incl. the FlashInfer V4 - // full-cache bf16/fp8 variants). - - // Quantization ops -#ifndef USE_ROCM - - // Note about marlin kernel 'workspace' arguments: - // Technically these should be mutable since they are modified by the kernel. - // But since they are set back to zero once the kernel is finished we can - // hand wave and say that they have no net effect. - // - // The reason to mark 'workspace' as immutable is so that they don't interfere - // with using ScalarType arguments in the ops. If they are marked as mutable, - // pytorch throws an assert in - // 'torch._higher_order_ops._register_effectful_op' that prevents these - // kernels from being torch.compile'd. - // See the following document for more info on custom types and ops that use - // custom types: - // https://docs.google.com/document/d/18fBMPuOJ0fY5ZQ6YyrHUppw9FA332CpNtgB6SOIgyuA - #endif } diff --git a/setup.py b/setup.py index 2aaa7dfc49c8..bdf6f76858bf 100644 --- a/setup.py +++ b/setup.py @@ -1149,7 +1149,8 @@ def _read_requirements(filename: str) -> list[str]: ext_modules.append(CMakeExtension(name="vllm._C")) if _build_custom_ops(): - ext_modules.append(CMakeExtension(name="vllm._C")) + if _is_hip(): + ext_modules.append(CMakeExtension(name="vllm._C")) if _is_cuda() or _is_hip(): ext_modules.append(CMakeExtension(name="vllm._C_stable_libtorch")) ext_modules.append(CMakeExtension(name="vllm._moe_C_stable_libtorch")) diff --git a/vllm/platforms/cuda.py b/vllm/platforms/cuda.py index 49181eaec6c9..1b04412c90e5 100644 --- a/vllm/platforms/cuda.py +++ b/vllm/platforms/cuda.py @@ -19,7 +19,6 @@ from typing_extensions import ParamSpec # import custom ops, trigger op registration -import vllm._C # noqa import vllm._C_stable_libtorch # noqa import vllm.envs as envs from vllm.logger import init_logger From e5aed52e462b0821b54c72d06871af9b022dcbfe Mon Sep 17 00:00:00 2001 From: Chris Leonard Date: Fri, 12 Jun 2026 15:57:14 +0000 Subject: [PATCH 03/11] small cosmetic changes to align with legacy code before migration and to clearly indicate where _C HIP ends in CMakeLists.txt Signed-off-by: Chris Leonard --- CMakeLists.txt | 2 +- csrc/libtorch_stable/ops.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c88ba2b2675..fc9e05aec053 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -347,7 +347,7 @@ if(VLLM_GPU_LANG STREQUAL "HIP") # driver API. This causes problems when linking with earlier versions of CUDA. # Setting this variable sidesteps the issue by calling the driver directly. target_compile_definitions(_C PRIVATE CUTLASS_ENABLE_DIRECT_CUDA_DRIVER_CALL=1) -endif() +endif() # _C HIP endif if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") # diff --git a/csrc/libtorch_stable/ops.h b/csrc/libtorch_stable/ops.h index 7d9cd02f72ac..64b2b8ee48b7 100644 --- a/csrc/libtorch_stable/ops.h +++ b/csrc/libtorch_stable/ops.h @@ -14,7 +14,7 @@ inline torch::stable::Tensor weak_ref_tensor(torch::stable::Tensor& tensor) { STD_TORCH_CHECK(tensor.device().is_cuda(), "Tensor must be on CUDA device"); // Get the raw data pointer - void* data_ptr = const_cast(tensor.mutable_data_ptr()); + void* data_ptr = tensor.mutable_data_ptr(); // Create a new tensor from the raw data pointer return torch::stable::from_blob(data_ptr, tensor.sizes(), tensor.strides(), @@ -397,7 +397,7 @@ void persistent_masked_m_silu_mul_quant( const torch::stable::Tensor& tokens_per_expert, // (E) torch::stable::Tensor& y_q, // (E, T, H) [OUT] torch::stable::Tensor& y_s, // (E, T, H//group_size) [OUT] - bool cast_scale_ue8m0); + bool use_ue8m0); void mul_and_silu(torch::stable::Tensor& out, torch::stable::Tensor& input); void gelu_and_mul(torch::stable::Tensor& out, torch::stable::Tensor& input); From c29e571dd6bf88ec0e55a94e72d7c41b04147c11 Mon Sep 17 00:00:00 2001 From: Chris Leonard Date: Sat, 13 Jun 2026 19:22:12 +0000 Subject: [PATCH 04/11] fix pre-commit issue Signed-off-by: Chris Leonard --- csrc/libtorch_stable/torch_bindings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csrc/libtorch_stable/torch_bindings.cpp b/csrc/libtorch_stable/torch_bindings.cpp index 1b5929d6ccd9..d55c12d382a9 100644 --- a/csrc/libtorch_stable/torch_bindings.cpp +++ b/csrc/libtorch_stable/torch_bindings.cpp @@ -47,7 +47,7 @@ STABLE_TORCH_LIBRARY_FRAGMENT(_C, ops) { // See the following document for more info on custom types and ops that use // custom types: // https://docs.google.com/document/d/18fBMPuOJ0fY5ZQ6YyrHUppw9FA332CpNtgB6SOIgyuA - + // Machete (Dense) Optimized Mixed Precision GEMM for Hopper. ops.def( "machete_supported_schedules(" From 957ecbccf1eae6b6c7b70d23c5966f7c05e47eca Mon Sep 17 00:00:00 2001 From: Chris Leonard Date: Mon, 15 Jun 2026 13:39:05 +0000 Subject: [PATCH 05/11] updated qutlass to attach to _C_stable_libtorch instead of _C which is no longer built with cuda. Also, the new stable version of weak_ref_tensor requires torch 2.11 but ROCm is still built with 2.10, so I added the old implementation back in csrc/ops.h which is no longer built on cuda. Signed-off-by: Chris Leonard --- cmake/external_projects/qutlass.cmake | 6 +++--- csrc/libtorch_stable/ops.h | 9 +++++++-- csrc/libtorch_stable/torch_bindings.cpp | 4 ++++ csrc/ops.h | 24 ++++++++++++++++++++++++ csrc/torch_bindings.cpp | 3 +++ 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/cmake/external_projects/qutlass.cmake b/cmake/external_projects/qutlass.cmake index 66c001919b03..193b7ecaf84d 100644 --- a/cmake/external_projects/qutlass.cmake +++ b/cmake/external_projects/qutlass.cmake @@ -91,9 +91,9 @@ if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 AND QUTLASS_ARCHS) CUDA_ARCHS "${QUTLASS_ARCHS}" ) - target_sources(_C PRIVATE ${QUTLASS_SOURCES}) - target_include_directories(_C PRIVATE ${QUTLASS_INCLUDES}) - target_compile_definitions(_C PRIVATE + target_sources(_C_stable_libtorch PRIVATE ${QUTLASS_SOURCES}) + target_include_directories(_C_stable_libtorch PRIVATE ${QUTLASS_INCLUDES}) + target_compile_definitions(_C_stable_libtorch PRIVATE QUTLASS_DISABLE_PYBIND=1 TARGET_CUDA_ARCH=${QUTLASS_TARGET_CC} ) diff --git a/csrc/libtorch_stable/ops.h b/csrc/libtorch_stable/ops.h index 64b2b8ee48b7..a146987b9848 100644 --- a/csrc/libtorch_stable/ops.h +++ b/csrc/libtorch_stable/ops.h @@ -1,14 +1,18 @@ #pragma once -#include "torch_utils.h" - #include #include +#include #include #include #include +#ifndef USE_ROCM + #include + +// Requires torch::stable::from_blob with a custom deleter (PyTorch >= 2.11). +// ROCm _C_stable_libtorch still targets 2.10; see legacy _C for ROCm. inline torch::stable::Tensor weak_ref_tensor(torch::stable::Tensor& tensor) { // Ensure tensor is on CUDA STD_TORCH_CHECK(tensor.device().is_cuda(), "Tensor must be on CUDA device"); @@ -21,6 +25,7 @@ inline torch::stable::Tensor weak_ref_tensor(torch::stable::Tensor& tensor) { tensor.device(), tensor.scalar_type(), [base = tensor](void*) {}); } +#endif void per_token_group_quant_fp8(const torch::stable::Tensor& input, torch::stable::Tensor& output_q, diff --git a/csrc/libtorch_stable/torch_bindings.cpp b/csrc/libtorch_stable/torch_bindings.cpp index d55c12d382a9..c4ea0c3df526 100644 --- a/csrc/libtorch_stable/torch_bindings.cpp +++ b/csrc/libtorch_stable/torch_bindings.cpp @@ -497,7 +497,9 @@ STABLE_TORCH_LIBRARY_FRAGMENT(_C, ops) { ops.def( "persistent_masked_m_silu_mul_quant(Tensor input, Tensor counts, Tensor! " "y_q, Tensor! y_s, bool use_ue8m0) -> ()"); +#ifndef USE_ROCM ops.def("weak_ref_tensor(Tensor input) -> Tensor"); +#endif // Activation function used in SwiGLU. ops.def("silu_and_mul(Tensor! result, Tensor input) -> ()"); @@ -715,7 +717,9 @@ STABLE_TORCH_LIBRARY_IMPL(_C, CUDA, ops) { // Activation kernels (shared CUDA/ROCm) ops.impl("persistent_masked_m_silu_mul_quant", TORCH_BOX(&persistent_masked_m_silu_mul_quant)); +#ifndef USE_ROCM ops.impl("weak_ref_tensor", TORCH_BOX(&weak_ref_tensor)); +#endif ops.impl("silu_and_mul_quant", TORCH_BOX(&silu_and_mul_quant)); ops.impl("silu_and_mul", TORCH_BOX(&silu_and_mul)); ops.impl("mul_and_silu", TORCH_BOX(&mul_and_silu)); diff --git a/csrc/ops.h b/csrc/ops.h index 398ae1016f3a..cb108a2daab0 100644 --- a/csrc/ops.h +++ b/csrc/ops.h @@ -9,6 +9,30 @@ #include +// This should be deleted when ROCm moves to torch >= 2.11 since a torch ABI +// stable version is defined in vllm/csrc/libtorch_stable/ops.h +torch::Tensor weak_ref_tensor(torch::Tensor& tensor) { + // Ensure tensor is on CUDA + if (!tensor.is_cuda()) { + throw std::runtime_error("Tensor must be on CUDA device"); + } + + // Get the raw data pointer + void* data_ptr = tensor.data_ptr(); + + // Get tensor sizes and strides + std::vector sizes = tensor.sizes().vec(); + std::vector strides = tensor.strides().vec(); + + // Get tensor options (dtype, device) + auto options = tensor.options(); + + // Create a new tensor from the raw data pointer + auto new_tensor = torch::from_blob(data_ptr, sizes, strides, options); + + return new_tensor; +} + // rms_norm and fused_add_rms_norm declarations also exist in // csrc/libtorch_stable/ops.h (torch::stable ABI for CUDA). They remain here // because the CPU build still uses these torch::Tensor declarations. diff --git a/csrc/torch_bindings.cpp b/csrc/torch_bindings.cpp index 0a47729628e5..ecd15a20fae9 100644 --- a/csrc/torch_bindings.cpp +++ b/csrc/torch_bindings.cpp @@ -22,6 +22,9 @@ TORCH_LIBRARY_EXPAND(TORCH_EXTENSION_NAME, ops) { // vLLM custom ops // + ops.def("weak_ref_tensor(Tensor input) -> Tensor"); + ops.impl("weak_ref_tensor", torch::kCUDA, &weak_ref_tensor); + #ifdef USE_ROCM // TODO: Remove this once we upgrade to torch 2.11. // ROCm still uses torch 2.10, From 1215fa076eaf39b78bfe8f349ba796c836d679f8 Mon Sep 17 00:00:00 2001 From: Chris Leonard Date: Mon, 15 Jun 2026 14:50:55 +0000 Subject: [PATCH 06/11] moved Expert-specialization MXFP8 block in the CMakeLists.txt to be below the set_gencode_flags_for_srcs to avoid conflicting sm_100 and sm_100f flags Signed-off-by: Chris Leonard --- CMakeLists.txt | 56 ++++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fc9e05aec053..7153cc00d0c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -415,33 +415,6 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") endif() FetchContent_MakeAvailable(cutlass) - # Expert-specialization MXFP8 blockscaled grouped kernels (SM100+). - if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 13.0) - cuda_archs_loose_intersection(ES_MXFP8_GROUPED_MM_ARCHS "10.0f;11.0f" "${CUDA_ARCHS}") - else() - cuda_archs_loose_intersection(ES_MXFP8_GROUPED_MM_ARCHS "10.0a;10.1a;10.3a" "${CUDA_ARCHS}") - endif() - if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 AND ES_MXFP8_GROUPED_MM_ARCHS) - set(SRCS - "csrc/libtorch_stable/moe/mxfp8_moe/cutlass_mxfp8_grouped_mm.cu" - "csrc/libtorch_stable/moe/mxfp8_moe/mxfp8_experts_quant.cu") - set_gencode_flags_for_srcs( - SRCS "${SRCS}" - CUDA_ARCHS "${ES_MXFP8_GROUPED_MM_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") - list(APPEND VLLM_GPU_FLAGS "-DENABLE_ES_MXFP8_GROUPED_MM_SM100=1") - message(STATUS "Building ES MXFP8 grouped kernels for archs: ${ES_MXFP8_GROUPED_MM_ARCHS}") - else() - if (NOT ${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 - AND ES_MXFP8_GROUPED_MM_ARCHS) - message(STATUS "Not building ES MXFP8 grouped kernels as CUDA Compiler version is " - "not >= 12.8.") - else() - message(STATUS "Not building ES MXFP8 grouped kernels as no compatible archs found " - "in CUDA target architectures.") - endif() - endif() - list(APPEND VLLM_STABLE_EXT_SRC "csrc/libtorch_stable/cuda_view.cu" "csrc/libtorch_stable/cuda_utils_kernels.cu" @@ -525,6 +498,35 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") SRCS "${VLLM_STABLE_EXT_SRC}" CUDA_ARCHS "${CUDA_ARCHS}") + # Expert-specialization MXFP8 blockscaled grouped kernels (SM100+). + # Must be registered after the blanket gencode pass above: these use + # family-specific arches (10.0f/11.0f) and cannot also get sm_100/sm_110. + if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 13.0) + cuda_archs_loose_intersection(ES_MXFP8_GROUPED_MM_ARCHS "10.0f;11.0f" "${CUDA_ARCHS}") + else() + cuda_archs_loose_intersection(ES_MXFP8_GROUPED_MM_ARCHS "10.0a;10.1a;10.3a" "${CUDA_ARCHS}") + endif() + if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 AND ES_MXFP8_GROUPED_MM_ARCHS) + set(SRCS + "csrc/libtorch_stable/moe/mxfp8_moe/cutlass_mxfp8_grouped_mm.cu" + "csrc/libtorch_stable/moe/mxfp8_moe/mxfp8_experts_quant.cu") + set_gencode_flags_for_srcs( + SRCS "${SRCS}" + CUDA_ARCHS "${ES_MXFP8_GROUPED_MM_ARCHS}") + list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") + list(APPEND VLLM_GPU_FLAGS "-DENABLE_ES_MXFP8_GROUPED_MM_SM100=1") + message(STATUS "Building ES MXFP8 grouped kernels for archs: ${ES_MXFP8_GROUPED_MM_ARCHS}") + else() + if (NOT ${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 + AND ES_MXFP8_GROUPED_MM_ARCHS) + message(STATUS "Not building ES MXFP8 grouped kernels as CUDA Compiler version is " + "not >= 12.8.") + else() + message(STATUS "Not building ES MXFP8 grouped kernels as no compatible archs found " + "in CUDA target architectures.") + endif() + endif() + # Only build Marlin kernels if we are building for at least some compatible archs. # Keep building Marlin for 9.0 as there are some group sizes and shapes that # are not supported by Machete yet. From 2c27bada54890acd0de4f1bed30bf39f405bcf36 Mon Sep 17 00:00:00 2001 From: Chris Leonard Date: Tue, 16 Jun 2026 12:37:22 +0000 Subject: [PATCH 07/11] Build QuTLASS as standalone vllm._qutlass_C extension with PyInit registration. Signed-off-by: Chris Leonard --- cmake/external_projects/qutlass.cmake | 34 +++++++++++++++++++++++---- csrc/qutlass_registration.cpp | 5 ++++ setup.py | 1 + vllm/platforms/cuda.py | 4 ++++ 4 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 csrc/qutlass_registration.cpp diff --git a/cmake/external_projects/qutlass.cmake b/cmake/external_projects/qutlass.cmake index 193b7ecaf84d..b653bbfce7b4 100644 --- a/cmake/external_projects/qutlass.cmake +++ b/cmake/external_projects/qutlass.cmake @@ -60,6 +60,7 @@ endif() if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 AND QUTLASS_ARCHS) set(QUTLASS_SOURCES + csrc/qutlass_registration.cpp ${qutlass_SOURCE_DIR}/qutlass/csrc/bindings.cpp ${qutlass_SOURCE_DIR}/qutlass/csrc/gemm.cu ${qutlass_SOURCE_DIR}/qutlass/csrc/gemm_ada.cu @@ -78,8 +79,19 @@ if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 AND QUTLASS_ARCHS) if(CUTLASS_INCLUDE_DIR AND EXISTS "${CUTLASS_INCLUDE_DIR}/cutlass/cutlass.h") list(APPEND QUTLASS_INCLUDES "${CUTLASS_INCLUDE_DIR}") + if(CUTLASS_TOOLS_UTIL_INCLUDE_DIR AND + EXISTS "${CUTLASS_TOOLS_UTIL_INCLUDE_DIR}/cutlass/util/packed_stride.hpp") + list(APPEND QUTLASS_INCLUDES "${CUTLASS_TOOLS_UTIL_INCLUDE_DIR}") + else() + get_filename_component(_qutlass_cutlass_root "${CUTLASS_INCLUDE_DIR}" DIRECTORY) + if(EXISTS "${_qutlass_cutlass_root}/tools/util/include/cutlass/util/packed_stride.hpp") + list(APPEND QUTLASS_INCLUDES "${_qutlass_cutlass_root}/tools/util/include") + endif() + endif() elseif(EXISTS "${qutlass_SOURCE_DIR}/qutlass/third_party/cutlass/include/cutlass/cutlass.h") - list(APPEND QUTLASS_INCLUDES "${qutlass_SOURCE_DIR}/qutlass/third_party/cutlass/include") + list(APPEND QUTLASS_INCLUDES + "${qutlass_SOURCE_DIR}/qutlass/third_party/cutlass/include" + "${qutlass_SOURCE_DIR}/qutlass/third_party/cutlass/tools/util/include") message(STATUS "[QUTLASS] Using QuTLASS vendored CUTLASS headers (no vLLM CUTLASS detected).") else() message(FATAL_ERROR "[QUTLASS] CUTLASS headers not found. " @@ -91,12 +103,23 @@ if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 AND QUTLASS_ARCHS) CUDA_ARCHS "${QUTLASS_ARCHS}" ) - target_sources(_C_stable_libtorch PRIVATE ${QUTLASS_SOURCES}) - target_include_directories(_C_stable_libtorch PRIVATE ${QUTLASS_INCLUDES}) - target_compile_definitions(_C_stable_libtorch PRIVATE + # QuTLASS uses legacy ATen headers and cannot be built with TORCH_TARGET_VERSION. + # Keep it as its own extension (registers torch.ops._qutlass_C). + define_extension_target( + _qutlass_C + DESTINATION vllm + LANGUAGE ${VLLM_GPU_LANG} + SOURCES ${QUTLASS_SOURCES} + COMPILE_FLAGS ${VLLM_GPU_FLAGS} + ARCHITECTURES ${VLLM_GPU_ARCHES} + INCLUDE_DIRECTORIES ${QUTLASS_INCLUDES} + USE_SABI 3 + WITH_SOABI) + + target_compile_definitions(_qutlass_C PRIVATE QUTLASS_DISABLE_PYBIND=1 TARGET_CUDA_ARCH=${QUTLASS_TARGET_CC} - ) + CUTLASS_ENABLE_DIRECT_CUDA_DRIVER_CALL=1) set_property(SOURCE ${QUTLASS_SOURCES} APPEND PROPERTY COMPILE_OPTIONS $<$:--expt-relaxed-constexpr --use_fast_math -O3> @@ -111,4 +134,5 @@ else() "[QUTLASS] Skipping build: no supported arch (12.0f / 10.0f) found in " "CUDA_ARCHS='${CUDA_ARCHS}'.") endif() + add_custom_target(_qutlass_C) endif() diff --git a/csrc/qutlass_registration.cpp b/csrc/qutlass_registration.cpp new file mode 100644 index 000000000000..effb44041350 --- /dev/null +++ b/csrc/qutlass_registration.cpp @@ -0,0 +1,5 @@ +#include "core/registration.h" + +// QuTLASS registers torch.ops._qutlass_C via TORCH_LIBRARY in bindings.cpp. +// This stub lets Python import vllm._qutlass_C to trigger op registration. +REGISTER_EXTENSION(_qutlass_C) diff --git a/setup.py b/setup.py index bdf6f76858bf..360ee99f93ee 100644 --- a/setup.py +++ b/setup.py @@ -1135,6 +1135,7 @@ def _read_requirements(filename: str) -> list[str]: # DeepGEMM requires CUDA 12.3+ (SM90/SM100) # Optional since it won't build on unsupported architectures ext_modules.append(CMakeExtension(name="vllm._deep_gemm_C", optional=True)) + ext_modules.append(CMakeExtension(name="vllm._qutlass_C", optional=True)) # fmha_sm100 is a Python/CuTe-DSL package installed into vllm.third_party. ext_modules.append(CMakeExtension(name="vllm.fmha_sm100", optional=True)) diff --git a/vllm/platforms/cuda.py b/vllm/platforms/cuda.py index 1b04412c90e5..1c249319771c 100644 --- a/vllm/platforms/cuda.py +++ b/vllm/platforms/cuda.py @@ -6,6 +6,7 @@ from __future__ import annotations +import contextlib import os import platform from collections.abc import Callable @@ -20,6 +21,9 @@ # import custom ops, trigger op registration import vllm._C_stable_libtorch # noqa + +with contextlib.suppress(ImportError): + import vllm._qutlass_C # noqa: F401 import vllm.envs as envs from vllm.logger import init_logger from vllm.utils.import_utils import import_pynvml From 9e539bc0ab5722f50af3d6fb43ca60f0ff383b17 Mon Sep 17 00:00:00 2001 From: Chris Leonard Date: Tue, 16 Jun 2026 20:01:42 +0000 Subject: [PATCH 08/11] Include _qutlass_C in precompiled wheels and register CUDA kernel extensions via import_kernels. Signed-off-by: Chris Leonard --- setup.py | 1 + vllm/platforms/cuda.py | 25 +++++++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 360ee99f93ee..b807b2215dbe 100644 --- a/setup.py +++ b/setup.py @@ -769,6 +769,7 @@ def extract_precompiled_and_patch_package( "vllm/_C.abi3.so", "vllm/_C_stable_libtorch.abi3.so", "vllm/_moe_C_stable_libtorch.abi3.so", + "vllm/_qutlass_C.abi3.so", "vllm/_flashmla_C.abi3.so", "vllm/_flashmla_extension_C.abi3.so", "vllm/_sparse_flashmla_C.abi3.so", diff --git a/vllm/platforms/cuda.py b/vllm/platforms/cuda.py index 1c249319771c..30a16e27469c 100644 --- a/vllm/platforms/cuda.py +++ b/vllm/platforms/cuda.py @@ -6,7 +6,6 @@ from __future__ import annotations -import contextlib import os import platform from collections.abc import Callable @@ -21,9 +20,6 @@ # import custom ops, trigger op registration import vllm._C_stable_libtorch # noqa - -with contextlib.suppress(ImportError): - import vllm._qutlass_C # noqa: F401 import vllm.envs as envs from vllm.logger import init_logger from vllm.utils.import_utils import import_pynvml @@ -43,6 +39,11 @@ logger = init_logger(__name__) +try: + import vllm._qutlass_C # noqa: F401 +except ImportError as e: + logger.warning("Failed to import from vllm._qutlass_C: %r", e) + _P = ParamSpec("_P") _R = TypeVar("_R") @@ -190,6 +191,22 @@ class CudaPlatformBase(Platform): "RAY_EXPERIMENTAL_NOSET_CUDA_VISIBLE_DEVICES", ] + @classmethod + def import_kernels(cls) -> None: + """Import CUDA kernel extensions (_C_stable_libtorch, optional _qutlass_C).""" + try: + import vllm._C_stable_libtorch # noqa: F401 + except ImportError as e: + logger.warning("Failed to import from vllm._C_stable_libtorch: %r", e) + try: + import vllm._moe_C_stable_libtorch # noqa: F401 + except ImportError as e: + logger.warning("Failed to import from vllm._moe_C_stable_libtorch: %r", e) + try: + import vllm._qutlass_C # noqa: F401 + except ImportError as e: + logger.warning("Failed to import from vllm._qutlass_C: %r", e) + @property def supported_dtypes(self) -> list[torch.dtype]: if self.has_device_capability(80): From 549bae41e6fc7d0e2302b48866f1fd4d7b571e9c Mon Sep 17 00:00:00 2001 From: Chris Leonard Date: Wed, 17 Jun 2026 13:57:40 +0000 Subject: [PATCH 09/11] Moved core/math.hpp to the libtorch_stable directory. Fixed data_ptr that should of been const_data_ptr. Signed-off-by: Chris Leonard --- csrc/{ => libtorch_stable}/core/math.hpp | 0 csrc/libtorch_stable/moe/moe_align_sum_kernels.cu | 2 +- csrc/libtorch_stable/ops.h | 3 ++- csrc/libtorch_stable/quantization/activation_kernels.cu | 9 +++++---- .../quantization/fp4/nvfp4_scaled_mm_kernels.cu | 2 +- .../quantization/fp4/nvfp4_scaled_mm_sm120_kernels.cu | 2 +- .../w8a8/cutlass/c3x/cutlass_gemm_caller.cuh | 2 +- .../quantization/w8a8/cutlass/c3x/scaled_mm.cuh | 2 +- .../quantization/w8a8/cutlass/scaled_mm_c2x.cuh | 2 +- 9 files changed, 13 insertions(+), 11 deletions(-) rename csrc/{ => libtorch_stable}/core/math.hpp (100%) diff --git a/csrc/core/math.hpp b/csrc/libtorch_stable/core/math.hpp similarity index 100% rename from csrc/core/math.hpp rename to csrc/libtorch_stable/core/math.hpp diff --git a/csrc/libtorch_stable/moe/moe_align_sum_kernels.cu b/csrc/libtorch_stable/moe/moe_align_sum_kernels.cu index d7c68ff25a63..1e842381349b 100644 --- a/csrc/libtorch_stable/moe/moe_align_sum_kernels.cu +++ b/csrc/libtorch_stable/moe/moe_align_sum_kernels.cu @@ -9,7 +9,7 @@ #include #include "../../cuda_compat.h" -#include "core/math.hpp" +#include "libtorch_stable/core/math.hpp" #include "libtorch_stable/dispatch_utils.h" #include "libtorch_stable/torch_utils.h" diff --git a/csrc/libtorch_stable/ops.h b/csrc/libtorch_stable/ops.h index a146987b9848..f8b5637c4a69 100644 --- a/csrc/libtorch_stable/ops.h +++ b/csrc/libtorch_stable/ops.h @@ -12,7 +12,8 @@ #include // Requires torch::stable::from_blob with a custom deleter (PyTorch >= 2.11). -// ROCm _C_stable_libtorch still targets 2.10; see legacy _C for ROCm. +// ROCm _C_stable_libtorch still targets 2.10; see the legacy declaration in +// csrc/ops.h (ROCm _C). inline torch::stable::Tensor weak_ref_tensor(torch::stable::Tensor& tensor) { // Ensure tensor is on CUDA STD_TORCH_CHECK(tensor.device().is_cuda(), "Tensor must be on CUDA device"); diff --git a/csrc/libtorch_stable/quantization/activation_kernels.cu b/csrc/libtorch_stable/quantization/activation_kernels.cu index f8534dafa5b9..822a41969e7e 100644 --- a/csrc/libtorch_stable/quantization/activation_kernels.cu +++ b/csrc/libtorch_stable/quantization/activation_kernels.cu @@ -2,7 +2,7 @@ #include -#include "core/math.hpp" +#include "libtorch_stable/core/math.hpp" #include "cuda_compat.h" #include "libtorch_stable/dispatch_utils.h" #include "quantization/w8a8/fp8/common.cuh" @@ -656,11 +656,12 @@ void persistent_masked_m_silu_mul_quant( BLOCK_COUNT, max_shared_mem_bytes, fp8_t, scale_t, THREAD_COUNT, \ Idx_t, CEIL_UE8M0, GROUP_SIZE, STAGES> \ <<>>( \ - reinterpret_cast<__nv_bfloat16*>(input.mutable_data_ptr()), \ + reinterpret_cast( \ + input.const_data_ptr()), \ y_q.mutable_data_ptr(), \ reinterpret_cast(y_s.mutable_data_ptr()), \ - reinterpret_cast( \ - tokens_per_expert.mutable_data_ptr()), \ + reinterpret_cast( \ + tokens_per_expert.const_data_ptr()), \ E, T, H, stride_i_e, stride_i_t, stride_i_h, stride_yq_e, \ stride_yq_t, stride_yq_h, STRIDE_YS_E, STRIDE_YS_T, \ STRIDE_YS_G, STRIDE_YS_P, stride_counts_e); \ diff --git a/csrc/libtorch_stable/quantization/fp4/nvfp4_scaled_mm_kernels.cu b/csrc/libtorch_stable/quantization/fp4/nvfp4_scaled_mm_kernels.cu index 86355bf70606..af9f24a70e0b 100644 --- a/csrc/libtorch_stable/quantization/fp4/nvfp4_scaled_mm_kernels.cu +++ b/csrc/libtorch_stable/quantization/fp4/nvfp4_scaled_mm_kernels.cu @@ -31,7 +31,7 @@ #include "cutlass/util/packed_stride.hpp" -#include "core/math.hpp" +#include "libtorch_stable/core/math.hpp" #include "core/batch_invariant.hpp" using namespace cute; diff --git a/csrc/libtorch_stable/quantization/fp4/nvfp4_scaled_mm_sm120_kernels.cu b/csrc/libtorch_stable/quantization/fp4/nvfp4_scaled_mm_sm120_kernels.cu index 7adba6308fa9..3a45ede8dfd5 100644 --- a/csrc/libtorch_stable/quantization/fp4/nvfp4_scaled_mm_sm120_kernels.cu +++ b/csrc/libtorch_stable/quantization/fp4/nvfp4_scaled_mm_sm120_kernels.cu @@ -31,7 +31,7 @@ #include "cutlass/util/packed_stride.hpp" -#include "core/math.hpp" +#include "libtorch_stable/core/math.hpp" #include "core/batch_invariant.hpp" using namespace cute; diff --git a/csrc/libtorch_stable/quantization/w8a8/cutlass/c3x/cutlass_gemm_caller.cuh b/csrc/libtorch_stable/quantization/w8a8/cutlass/c3x/cutlass_gemm_caller.cuh index 1eed75799248..1d9023484faf 100644 --- a/csrc/libtorch_stable/quantization/w8a8/cutlass/c3x/cutlass_gemm_caller.cuh +++ b/csrc/libtorch_stable/quantization/w8a8/cutlass/c3x/cutlass_gemm_caller.cuh @@ -19,7 +19,7 @@ #include "cutlass/gemm/collective/collective_builder.hpp" #include "cutlass/util/packed_stride.hpp" -#include "core/math.hpp" +#include "libtorch_stable/core/math.hpp" #include "libtorch_stable/cutlass_extensions/common.hpp" // clang-format on diff --git a/csrc/libtorch_stable/quantization/w8a8/cutlass/c3x/scaled_mm.cuh b/csrc/libtorch_stable/quantization/w8a8/cutlass/c3x/scaled_mm.cuh index 4cb591be0560..7b7d4d714731 100644 --- a/csrc/libtorch_stable/quantization/w8a8/cutlass/c3x/scaled_mm.cuh +++ b/csrc/libtorch_stable/quantization/w8a8/cutlass/c3x/scaled_mm.cuh @@ -14,7 +14,7 @@ #include "cutlass/epilogue/collective/collective_builder.hpp" #include "cutlass/gemm/collective/collective_builder.hpp" -#include "core/math.hpp" +#include "libtorch_stable/core/math.hpp" #include "libtorch_stable/cutlass_extensions/common.hpp" // clang-format on diff --git a/csrc/libtorch_stable/quantization/w8a8/cutlass/scaled_mm_c2x.cuh b/csrc/libtorch_stable/quantization/w8a8/cutlass/scaled_mm_c2x.cuh index 7846e609fe7d..d2b54cb911ba 100644 --- a/csrc/libtorch_stable/quantization/w8a8/cutlass/scaled_mm_c2x.cuh +++ b/csrc/libtorch_stable/quantization/w8a8/cutlass/scaled_mm_c2x.cuh @@ -22,7 +22,7 @@ #include "cutlass/epilogue/threadblock/fusion/visitors.hpp" #include "cutlass/gemm/kernel/default_gemm_universal_with_visitor.h" -#include "core/math.hpp" +#include "libtorch_stable/core/math.hpp" #include "libtorch_stable/cutlass_extensions/common.hpp" // clang-format on From 9b5532f514590658360a2aea17ffa2033666703a Mon Sep 17 00:00:00 2001 From: Chris Leonard Date: Thu, 18 Jun 2026 14:10:01 +0000 Subject: [PATCH 10/11] MXFP8 was accidentally added back to CMakeLists.txt after resolving merge conflict, removing it again Signed-off-by: Chris Leonard --- CMakeLists.txt | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7153cc00d0c2..e95fe38d3299 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -498,35 +498,6 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") SRCS "${VLLM_STABLE_EXT_SRC}" CUDA_ARCHS "${CUDA_ARCHS}") - # Expert-specialization MXFP8 blockscaled grouped kernels (SM100+). - # Must be registered after the blanket gencode pass above: these use - # family-specific arches (10.0f/11.0f) and cannot also get sm_100/sm_110. - if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 13.0) - cuda_archs_loose_intersection(ES_MXFP8_GROUPED_MM_ARCHS "10.0f;11.0f" "${CUDA_ARCHS}") - else() - cuda_archs_loose_intersection(ES_MXFP8_GROUPED_MM_ARCHS "10.0a;10.1a;10.3a" "${CUDA_ARCHS}") - endif() - if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 AND ES_MXFP8_GROUPED_MM_ARCHS) - set(SRCS - "csrc/libtorch_stable/moe/mxfp8_moe/cutlass_mxfp8_grouped_mm.cu" - "csrc/libtorch_stable/moe/mxfp8_moe/mxfp8_experts_quant.cu") - set_gencode_flags_for_srcs( - SRCS "${SRCS}" - CUDA_ARCHS "${ES_MXFP8_GROUPED_MM_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") - list(APPEND VLLM_GPU_FLAGS "-DENABLE_ES_MXFP8_GROUPED_MM_SM100=1") - message(STATUS "Building ES MXFP8 grouped kernels for archs: ${ES_MXFP8_GROUPED_MM_ARCHS}") - else() - if (NOT ${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 - AND ES_MXFP8_GROUPED_MM_ARCHS) - message(STATUS "Not building ES MXFP8 grouped kernels as CUDA Compiler version is " - "not >= 12.8.") - else() - message(STATUS "Not building ES MXFP8 grouped kernels as no compatible archs found " - "in CUDA target architectures.") - endif() - endif() - # Only build Marlin kernels if we are building for at least some compatible archs. # Keep building Marlin for 9.0 as there are some group sizes and shapes that # are not supported by Machete yet. From 94782971fc52b135ddaf2faa22d1502f4d35adc9 Mon Sep 17 00:00:00 2001 From: Chris Leonard Date: Thu, 18 Jun 2026 15:54:41 +0000 Subject: [PATCH 11/11] Removed the custom deleter from the stable::from_blob method. The deleter was saving the tensor data, causing the memory buildup to cascade until we reached OOM errors. This should fix that. Also, Since from_blob was replaced with an overload that is on torch 2.10, we no longer need the ifndef ROCM flag or the legacy weak_ref_tensor method in the non-stable ops.h file. Signed-off-by: Chris Leonard --- csrc/libtorch_stable/ops.h | 12 +++--------- csrc/libtorch_stable/torch_bindings.cpp | 4 ---- csrc/ops.h | 24 ------------------------ csrc/torch_bindings.cpp | 4 ---- 4 files changed, 3 insertions(+), 41 deletions(-) diff --git a/csrc/libtorch_stable/ops.h b/csrc/libtorch_stable/ops.h index f8b5637c4a69..1cc8e8167a62 100644 --- a/csrc/libtorch_stable/ops.h +++ b/csrc/libtorch_stable/ops.h @@ -8,12 +8,8 @@ #include #include -#ifndef USE_ROCM - #include +#include -// Requires torch::stable::from_blob with a custom deleter (PyTorch >= 2.11). -// ROCm _C_stable_libtorch still targets 2.10; see the legacy declaration in -// csrc/ops.h (ROCm _C). inline torch::stable::Tensor weak_ref_tensor(torch::stable::Tensor& tensor) { // Ensure tensor is on CUDA STD_TORCH_CHECK(tensor.device().is_cuda(), "Tensor must be on CUDA device"); @@ -21,12 +17,10 @@ inline torch::stable::Tensor weak_ref_tensor(torch::stable::Tensor& tensor) { // Get the raw data pointer void* data_ptr = tensor.mutable_data_ptr(); - // Create a new tensor from the raw data pointer + /// Create a new tensor from the raw data pointer return torch::stable::from_blob(data_ptr, tensor.sizes(), tensor.strides(), - tensor.device(), tensor.scalar_type(), - [base = tensor](void*) {}); + tensor.device(), tensor.scalar_type()); } -#endif void per_token_group_quant_fp8(const torch::stable::Tensor& input, torch::stable::Tensor& output_q, diff --git a/csrc/libtorch_stable/torch_bindings.cpp b/csrc/libtorch_stable/torch_bindings.cpp index c4ea0c3df526..d55c12d382a9 100644 --- a/csrc/libtorch_stable/torch_bindings.cpp +++ b/csrc/libtorch_stable/torch_bindings.cpp @@ -497,9 +497,7 @@ STABLE_TORCH_LIBRARY_FRAGMENT(_C, ops) { ops.def( "persistent_masked_m_silu_mul_quant(Tensor input, Tensor counts, Tensor! " "y_q, Tensor! y_s, bool use_ue8m0) -> ()"); -#ifndef USE_ROCM ops.def("weak_ref_tensor(Tensor input) -> Tensor"); -#endif // Activation function used in SwiGLU. ops.def("silu_and_mul(Tensor! result, Tensor input) -> ()"); @@ -717,9 +715,7 @@ STABLE_TORCH_LIBRARY_IMPL(_C, CUDA, ops) { // Activation kernels (shared CUDA/ROCm) ops.impl("persistent_masked_m_silu_mul_quant", TORCH_BOX(&persistent_masked_m_silu_mul_quant)); -#ifndef USE_ROCM ops.impl("weak_ref_tensor", TORCH_BOX(&weak_ref_tensor)); -#endif ops.impl("silu_and_mul_quant", TORCH_BOX(&silu_and_mul_quant)); ops.impl("silu_and_mul", TORCH_BOX(&silu_and_mul)); ops.impl("mul_and_silu", TORCH_BOX(&mul_and_silu)); diff --git a/csrc/ops.h b/csrc/ops.h index cb108a2daab0..398ae1016f3a 100644 --- a/csrc/ops.h +++ b/csrc/ops.h @@ -9,30 +9,6 @@ #include -// This should be deleted when ROCm moves to torch >= 2.11 since a torch ABI -// stable version is defined in vllm/csrc/libtorch_stable/ops.h -torch::Tensor weak_ref_tensor(torch::Tensor& tensor) { - // Ensure tensor is on CUDA - if (!tensor.is_cuda()) { - throw std::runtime_error("Tensor must be on CUDA device"); - } - - // Get the raw data pointer - void* data_ptr = tensor.data_ptr(); - - // Get tensor sizes and strides - std::vector sizes = tensor.sizes().vec(); - std::vector strides = tensor.strides().vec(); - - // Get tensor options (dtype, device) - auto options = tensor.options(); - - // Create a new tensor from the raw data pointer - auto new_tensor = torch::from_blob(data_ptr, sizes, strides, options); - - return new_tensor; -} - // rms_norm and fused_add_rms_norm declarations also exist in // csrc/libtorch_stable/ops.h (torch::stable ABI for CUDA). They remain here // because the CPU build still uses these torch::Tensor declarations. diff --git a/csrc/torch_bindings.cpp b/csrc/torch_bindings.cpp index ecd15a20fae9..e1430c08d3a3 100644 --- a/csrc/torch_bindings.cpp +++ b/csrc/torch_bindings.cpp @@ -20,10 +20,6 @@ TORCH_LIBRARY_EXPAND(TORCH_EXTENSION_NAME, ops) { // vLLM custom ops - // - - ops.def("weak_ref_tensor(Tensor input) -> Tensor"); - ops.impl("weak_ref_tensor", torch::kCUDA, &weak_ref_tensor); #ifdef USE_ROCM // TODO: Remove this once we upgrade to torch 2.11.