#include // For TensorMatcher, SymbolicSize, SymbolicDevice #include // For div_ceil #include // For LaunchKernel #include #include #include #include namespace { template __global__ void clamp_position_kernel(T* __restrict__ dst, const T* __restrict__ seq_lens, size_t n) { size_t idx = blockIdx.x * blockDim.x + threadIdx.x; if (idx < n) { T val = seq_lens[idx] - 1; dst[idx] = val < 0 ? 0 : val; } } constexpr size_t kBlockSize = 256; template struct ClampPosition { static void run(tvm::ffi::TensorView dst, tvm::ffi::TensorView seq_lens) { using namespace host; SymbolicSize N = {"num_elements"}; SymbolicDevice device_; device_.set_options(); TensorMatcher({N}) // .with_dtype() .with_device(device_) .verify(dst) .verify(seq_lens); const size_t num_elements = N.unwrap(); if (num_elements == 0) return; const size_t grid_size = div_ceil(num_elements, kBlockSize); const DLDevice device = device_.unwrap(); LaunchKernel(grid_size, kBlockSize, device)( clamp_position_kernel, static_cast(dst.data_ptr()), static_cast(seq_lens.data_ptr()), num_elements); } }; } // namespace