futuremls-lab/oscar/add-jit-kernel
Claude Code and agent skill by futuremls-lab/oscar
- community
Checking that the SKILL.md file is still in the repository.
Step-by-step tutorial for adding a new lightweight JIT CUDA kernel to sglang's jit_kernel module
Install
npx vskill@latest install futuremls-lab/oscar/add-jit-kernelSKILL.md
Tutorial: Adding a New JIT Kernel to SGLang
This tutorial walks through adding a simple element-wise scale operation as a JIT kernel. We'll implement scale(x, factor) = x * factor to demonstrate the complete workflow.
Goal
Add a new operation that scales each element of a tensor by a scalar factor:
- Input: tensor
x(CUDA) and scalarfactor(float, passed at runtime) - Output:
x * factor(element-wise), allocated internally - Supported dtypes: FP16 (`torch.float16`), BF16 (`torch.bfloat16`), FP32 (`torch.float32`)
When to use JIT vs AOT (sgl-kernel)
- JIT (`jit_kernel`): prefer this first for kernels that do not depend on CUTLASS or another large C++ project. It is the default choice for lightweight kernels that benefit from rapid iteration and first-use compilation.
- AOT (`sgl-kernel`): prefer this when the kernel does depend on CUTLASS or another large C++ project, or when it should live in
sgl-kernel/and participate in the wheel build / torch op registration flow. - Exception: kernels that depend on
flashinfer, or on CUTLASS that is already provided throughflashinfer, can still be implemented asjit_kernel.
Common Abstractions in python/sglang/jit_kernel/include/sgl_kernel/
Always prefer these abstractions over raw CUDA primitives. They provide safety, readability, and consistency with the rest of the codebase.
Important include rule: for every #include <sgl_kernel/...> line, add a short trailing comment explaining why that header is included (for example // For TensorMatcher, SymbolicSize, SymbolicDevice). This matches the current JIT kernel style and keeps include usage self-documenting.
utils.h — Host-side utilities
- `host::RuntimeCheck(cond, args...)` — Assert a condition at runtime; throws
PanicErrorwith file/line info on failure. Prefer this over bareassert. - `host::Panic(args...)` — Unconditionally throw a
PanicErrorwith a descriptive message. - `host::div_ceil(a, b)` — Integer ceiling division
(a + b - 1) / b. - `host::irange(n)` / `host::irange(start, end)` — Range views for cleaner loops.
- `host::pointer::offset(ptr, offsets...)` — Byte-safe pointer arithmetic on
void*. Use this instead of raw casts.
utils.cuh — Device-side utilities + LaunchKernel
- Type aliases:
fp16_t,bf16_t,fp32_t,fp8_e4m3_t,fp8_e5m2_tand their packed variantsfp16x2_t,bf16x2_t,fp32x2_t, etc. - `SGL_DEVICE` — Expands to
__forceinline__ __device__. Use on all device functions. - `device::kWarpThreads` — Constant
32. - `device::load_as<T>(ptr, offset)` / `device::store_as<T>(ptr, val, offset)` — Type-safe loads/stores from
void*. - `device::pointer::offset(ptr, offsets...)` — Pointer arithmetic on device.
- `host::LaunchKernel(grid, block, device_or_stream [, smem])` — RAII kernel launcher that:
- Resolves the CUDA stream from a
DLDevicevia TVM-FFI automatically. - Checks the CUDA error with file/line info after launch via
operator()(kernel, args...). - Supports
.enable_pdl(bool)for PDL (Programmatic Dependent Launch, SM90+). - `host::RuntimeDeviceCheck(cudaError_t)` — Check a CUDA error; throw on failure.
tensor.h — Tensor validation (TensorMatcher, Symbolic types)
This is the primary validation API for all kernel launchers. Use it to validate every tvm::ffi::TensorView argument.
- `host::SymbolicSize{"name"}` — A named symbolic dimension. Call
.set_value(n)to pin it,.unwrap()to extract after verification. - `host::SymbolicDType` — Symbolic dtype. Use
.set_options<Ts...>()to restrict allowed types. - `host::SymbolicDevice` — Symbolic device. Use
.set_options<kDLCUDA>()to restrict to CUDA. - `host::TensorMatcher({dims...})` — Fluent builder for tensor validation:
.with_dtype<T>()— require a specific C++ type (e.g.fp16_t).with_dtype<T1, T2, ...>()— allow a set of types.with_device<kDLCUDA>(device_sym)— require CUDA and bind the checked device to aSymbolicDevice.with_strides({strides...})— validate strides (omit to require contiguous).verify(tensor_view)— execute the check; throwsPanicErrorwith full context on failure; chainable (verify(a).verify(b)to check multiple tensors with the same shape)
Typical pattern:
type.cuh — dtype_trait<T> and packed_t<T>
- `dtype_trait<T>` — Static trait struct for each scalar type. Provides:
dtype_trait<T>::from(value)— convert from another type (e.g.fp32_t→fp16_t)dtype_trait<T>::abs/sqrt/rsqrt/exp/sin/cos(x)— type-dispatched unary math (primarily forfp32_t)dtype_trait<T>::max/min(x, y)— type-dispatched binary math (primarily forfp32_t)- `packed_t<T>` — Two-element packed alias:
packed_t<fp16_t>=fp16x2_t,packed_t<bf16_t>=bf16x2_t,packed_t<fp32_t>=fp32x2_t. Use for vectorized loads/stores. - `device::cast<To, From>(value)` — Type-safe cast using
dtype_trait, e.g.cast<fp32x2_t, fp16x2_t>(v).
vec.cuh — Vectorized memory access (AlignedVector)
- `device::AlignedVector<T, N>` — Aligned storage for N elements of type T. N must be a power of two,
sizeof(T)*N <= 32. Enables vectorized loads/stores for bandwidth efficiency. In terms of API/codegen constraints, the upper bound is 256-bit; in practice, 128-bit is the portable default, while 256-bit vectorization is typically only viable onSM100+and should be gated by an architecture check when needed. .load(ptr, offset)— vectorized load fromptr[offset].store(ptr, offset)— vectorized store toptr[offset].fill(value)— fill all lanesoperator[](i)— element access
tile.cuh — tile::Memory (strided memory access pattern)
tile::Memory<T>is fundamentally a 1D cooperative accessor over a contiguous region.- `device::tile::Memory<T>::cta(blockDim.x)` — Creates a tile accessor where each thread handles
tid = threadIdx.xwith stridetsize(forcta(blockDim.x), this isblockDim.x). Common for loops over a 1D array. - `.load(ptr, offset)` — loads
ptr[tid + offset * tsize] - `.store(ptr, val, offset)` — stores to
ptr[tid + offset * tsize] - `.in_bound(n, offset)` — boundary check
For a 2D tile, either flatten (row, col) into a linear tile index first, or compute the address manually with ptr[row * stride + col] using your thread/block coordinates.
math.cuh — Device math (device::math::)
device::math::max/min<T>(a, b)— type-dispatched binary math viadtype_traitdevice::math::abs/sqrt/rsqrt/exp/sin/cos<T>(x)— type-dispatched unary math viadtype_trait
warp.cuh — Warp-level primitives
device::warp::reduce_sum<T>(value)— warp-level sum reduction via__shfl_xor_syncdevice::warp::reduce_max<T>(value)— warp-level max reduction
cta.cuh — CTA-level primitives
device::cta::reduce_max<T>(value, smem, min_value)— CTA-wide max using shared memory + warp reduction. Caller is responsible for a__syncthreads()after if the result insmem[0]is needed.
atomic.cuh — Atomic operations
device::atomic::max(float* addr, float value)— float atomic max (handles negative values correctly via bit tricks).
runtime.cuh — Occupancy and device info
host::runtime::get_blocks_per_sm(kernel, block_dim)— max active blocks per SM (occupancy)host::runtime::get_sm_count(device_id)— number of SMs on the devicehost::runtime::get_cc_major(device_id)— compute capability major version
Persistent kernel pattern (cap blocks to SM count × occupancy):
Step 0 (optional): Generate a .clangd config for better IDE support
Step 1: Implement the CUDA kernel in jit_kernel/csrc/
Create python/sglang/jit_kernel/csrc/elementwise/scale.cuh.
The implementation fully uses the project abstractions described above:
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingsglang-research/.claude/skills/add-jit-kernel/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/futuremls-lab/oscar/add-jit-kernel)