Instructions to use aabbdev/RWKV7-1.5B-SMI-20260822 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use aabbdev/RWKV7-1.5B-SMI-20260822 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="aabbdev/RWKV7-1.5B-SMI-20260822", trust_remote_code=True) messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("aabbdev/RWKV7-1.5B-SMI-20260822", trust_remote_code=True, device_map="auto") - RWKV
How to use aabbdev/RWKV7-1.5B-SMI-20260822 with RWKV:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use aabbdev/RWKV7-1.5B-SMI-20260822 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "aabbdev/RWKV7-1.5B-SMI-20260822" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "aabbdev/RWKV7-1.5B-SMI-20260822", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/aabbdev/RWKV7-1.5B-SMI-20260822
- SGLang
How to use aabbdev/RWKV7-1.5B-SMI-20260822 with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "aabbdev/RWKV7-1.5B-SMI-20260822" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "aabbdev/RWKV7-1.5B-SMI-20260822", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "aabbdev/RWKV7-1.5B-SMI-20260822" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "aabbdev/RWKV7-1.5B-SMI-20260822", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use aabbdev/RWKV7-1.5B-SMI-20260822 with Docker Model Runner:
docker model run hf.co/aabbdev/RWKV7-1.5B-SMI-20260822
File size: 165,253 Bytes
6d93aeb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | """Generated TileLang kernel export. Do not edit; regenerate it."""
import linecache
from types import SimpleNamespace
EXPORT_FORMAT_VERSION = 3
SOURCE_SHA256 = {'kernel_tilelang_state.py': 'a3597160cb8d7317151200d05b241af7edcad2928c3731687764d914c28bf21a', 'kernel_tilelang_decode.py': 'b582151a6d2bd345cc5f87415543370e027c8f943a4dfe57a18300f08560bd73'}
def _build_state_namespace():
source = '# pyright: reportInvalidTypeForm=false\nfrom functools import lru_cache\nfrom typing import Any\n\nimport torch\n\nFLOAT16 = torch.float16 # type: ignore[attr-defined]\nBFLOAT16 = torch.bfloat16 # type: ignore[attr-defined]\nFLOAT32 = torch.float32 # type: ignore[attr-defined]\nTORCH_WHERE = torch.where # type: ignore[attr-defined]\nTORCH_ZEROS_LIKE = torch.zeros_like # type: ignore[attr-defined]\nTORCH_STACK = torch.stack # type: ignore[attr-defined]\nCUDA_GET_DEVICE_CAPABILITY = torch.cuda.get_device_capability\nIS_GRAD_ENABLED = torch.is_grad_enabled # type: ignore[attr-defined]\n\n\ndef cuda_arch_key(device: Any | None = None) -> str:\n major, minor = CUDA_GET_DEVICE_CAPABILITY(device)\n return f"sm_{major}{minor}"\n\n\nEXACT_FUSED_STATE_PROJECTION_CAPABILITIES = frozenset({(8, 9)})\n\n\ndef exact_fused_state_projection_supported(device: Any | None = None) -> bool:\n """Return whether padded narrow projection is bit-exact on this GPU."""\n return (\n tuple(CUDA_GET_DEVICE_CAPABILITY(device))\n in EXACT_FUSED_STATE_PROJECTION_CAPABILITIES\n )\n\n\ndef _require_exact_fused_state_projection(device: Any | None = None) -> None:\n if not exact_fused_state_projection_supported(device):\n capability = CUDA_GET_DEVICE_CAPABILITY(device)\n raise RuntimeError(\n "Exact fused state projection is not validated for CUDA capability "\n f"{capability}; use tilelang_state_update for exact fallback"\n )\n\n\ndef build_state_program(\n batch_size: int,\n num_heads: int,\n head_size: int,\n input_dtype: str,\n):\n """Build exact pointwise RWKV state finalization as a TileLang PrimFunc."""\n import tilelang.language as T # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n state: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size, head_size), "float32"\n ),\n decay: T.Tensor((batch_size, num_heads, head_size), input_dtype), # type: ignore[reportInvalidTypeForm]\n anti_update: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size, head_size), "float32"\n ),\n value_key: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size, head_size), "float32"\n ),\n next_state: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size, head_size), "float32"\n ),\n ):\n with T.Kernel(batch_size, num_heads, threads=256) as (batch, head):\n # Preserve eager PyTorch\'s FP32 rounding boundaries exactly:\n # multiply -> store, add anti update -> store, add value/key -> store.\n for row, column in T.Parallel(head_size, head_size):\n next_state[batch, head, row, column] = state[\n batch, head, row, column\n ] * T.cast(decay[batch, head, column], "float32")\n T.sync_threads()\n for row, column in T.Parallel(head_size, head_size):\n next_state[batch, head, row, column] = (\n next_state[batch, head, row, column]\n + anti_update[batch, head, row, column]\n )\n T.sync_threads()\n for row, column in T.Parallel(head_size, head_size):\n next_state[batch, head, row, column] = (\n next_state[batch, head, row, column]\n + value_key[batch, head, row, column]\n )\n\n return kernel\n\n\ndef build_state_backward_program(\n batch_size: int,\n num_heads: int,\n head_size: int,\n input_dtype: str,\n):\n """Build first-order gradients for exact pointwise state finalization."""\n import tilelang.language as T # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n grad_output: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size, head_size), "float32"\n ),\n decay: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size), input_dtype\n ),\n grad_state: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size, head_size), "float32"\n ),\n ):\n with T.Kernel(batch_size, num_heads, threads=256) as (batch, head):\n for row, column in T.Parallel(head_size, head_size):\n grad_state[batch, head, row, column] = grad_output[\n batch, head, row, column\n ] * T.cast(decay[batch, head, column], "float32")\n\n return kernel\n\n\ndef build_low_precision_state_program(\n batch_size: int,\n num_heads: int,\n head_size: int,\n input_dtype: str,\n):\n """Build FP32-compute finalization with FP16 or BF16 storage."""\n import tilelang.language as T # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n state: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size, head_size), input_dtype\n ),\n decay: T.Tensor((batch_size, num_heads, head_size), input_dtype), # type: ignore[reportInvalidTypeForm]\n anti_update: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size, head_size), "float32"\n ),\n value_key: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size, head_size), "float32"\n ),\n next_state: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size, head_size), input_dtype\n ),\n ):\n with T.Kernel(batch_size, num_heads, threads=256) as (batch, head):\n workspace = T.alloc_shared((head_size, head_size), "float32")\n for row, column in T.Parallel(head_size, head_size):\n workspace[row, column] = T.cast(\n state[batch, head, row, column], "float32"\n ) * T.cast(decay[batch, head, column], "float32")\n T.sync_threads()\n for row, column in T.Parallel(head_size, head_size):\n workspace[row, column] = (\n workspace[row, column]\n + anti_update[batch, head, row, column]\n )\n T.sync_threads()\n for row, column in T.Parallel(head_size, head_size):\n workspace[row, column] = (\n workspace[row, column]\n + value_key[batch, head, row, column]\n )\n T.sync_threads()\n for row, column in T.Parallel(head_size, head_size):\n next_state[batch, head, row, column] = T.cast(\n workspace[row, column], input_dtype\n )\n\n return kernel\n\n\ndef build_state_projection_program(\n batch_size: int,\n num_heads: int,\n head_size: int,\n input_dtype: str,\n):\n """Build padded Tensor Core state-by-receptance projection."""\n import tilelang.language as T # type: ignore[import-not-found]\n\n padded_columns = 16\n\n @T.prim_func\n def kernel(\n state: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size, head_size), input_dtype\n ),\n receptance: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size), input_dtype\n ),\n mixed: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size), input_dtype\n ),\n ):\n with T.Kernel(batch_size, num_heads, threads=128) as (batch, head):\n state_shared = T.alloc_shared(\n (head_size, head_size), input_dtype\n )\n receptance_shared = T.alloc_shared(\n (head_size, padded_columns), input_dtype\n )\n mixed_fragment = T.alloc_fragment(\n (head_size, padded_columns), "float32"\n )\n mixed_shared = T.alloc_shared(\n (head_size, padded_columns), input_dtype\n )\n T.copy(state[batch, head, :, :], state_shared)\n for row, column in T.Parallel(head_size, padded_columns):\n receptance_shared[row, column] = receptance[batch, head, row]\n T.clear(mixed_fragment)\n T.gemm(state_shared, receptance_shared, mixed_fragment)\n T.copy(mixed_fragment, mixed_shared)\n T.sync_threads()\n for row in T.Parallel(head_size):\n mixed[batch, head, row] = mixed_shared[row, 0]\n\n return kernel\n\n\ndef build_fused_state_update_program(\n batch_size: int,\n num_heads: int,\n head_size: int,\n input_dtype: str,\n):\n """Build exact finalization plus padded Tensor Core projection."""\n import tilelang.language as T # type: ignore[import-not-found]\n\n padded_columns = 16\n\n @T.prim_func\n def kernel(\n state: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size, head_size), "float32"\n ),\n decay: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size), input_dtype\n ),\n anti_update: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size, head_size), "float32"\n ),\n value_key: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size, head_size), "float32"\n ),\n receptance: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size), input_dtype\n ),\n next_state: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size, head_size), "float32"\n ),\n mixed: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size), input_dtype\n ),\n ):\n with T.Kernel(batch_size, num_heads, threads=256) as (batch, head):\n state_shared = T.alloc_shared(\n (head_size, head_size), input_dtype\n )\n receptance_shared = T.alloc_shared(\n (head_size, padded_columns), input_dtype\n )\n mixed_fragment = T.alloc_fragment(\n (head_size, padded_columns), "float32"\n )\n mixed_shared = T.alloc_shared(\n (head_size, padded_columns), input_dtype\n )\n\n # Preserve eager FP32 stores between multiply and both additions.\n for row, column in T.Parallel(head_size, head_size):\n next_state[batch, head, row, column] = state[\n batch, head, row, column\n ] * T.cast(decay[batch, head, column], "float32")\n T.sync_threads()\n for row, column in T.Parallel(head_size, head_size):\n next_state[batch, head, row, column] = (\n next_state[batch, head, row, column]\n + anti_update[batch, head, row, column]\n )\n T.sync_threads()\n for row, column in T.Parallel(head_size, head_size):\n next_state[batch, head, row, column] = (\n next_state[batch, head, row, column]\n + value_key[batch, head, row, column]\n )\n T.sync_threads()\n\n for row, column in T.Parallel(head_size, head_size):\n state_shared[row, column] = T.cast(\n next_state[batch, head, row, column], input_dtype\n )\n for row, column in T.Parallel(head_size, padded_columns):\n receptance_shared[row, column] = receptance[batch, head, row]\n T.clear(mixed_fragment)\n T.gemm(state_shared, receptance_shared, mixed_fragment)\n T.copy(mixed_fragment, mixed_shared)\n T.sync_threads()\n for row in T.Parallel(head_size):\n mixed[batch, head, row] = mixed_shared[row, 0]\n\n return kernel\n\n\n\n\n\n\n\n\ndef build_x_mix_program(\n batch_size: int,\n hidden_size: int,\n input_dtype: str,\n):\n """Build exact six-way decode x-mix without temporary stacking."""\n import tilelang.language as T # type: ignore[import-not-found]\n\n block_size = 256\n\n @T.prim_func\n def kernel(\n x: T.Tensor((batch_size, hidden_size), input_dtype), # type: ignore[reportInvalidTypeForm]\n previous: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, hidden_size), input_dtype\n ),\n mix_r: T.Tensor((hidden_size,), input_dtype), # type: ignore[reportInvalidTypeForm]\n mix_w: T.Tensor((hidden_size,), input_dtype), # type: ignore[reportInvalidTypeForm]\n mix_k: T.Tensor((hidden_size,), input_dtype), # type: ignore[reportInvalidTypeForm]\n mix_v: T.Tensor((hidden_size,), input_dtype), # type: ignore[reportInvalidTypeForm]\n mix_a: T.Tensor((hidden_size,), input_dtype), # type: ignore[reportInvalidTypeForm]\n mix_g: T.Tensor((hidden_size,), input_dtype), # type: ignore[reportInvalidTypeForm]\n mixed: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, 6, hidden_size), input_dtype\n ),\n ):\n with T.Kernel(\n T.ceildiv(hidden_size, block_size), batch_size, threads=block_size\n ) as (block, batch):\n delta_shared = T.alloc_shared((block_size,), input_dtype)\n products_shared = T.alloc_shared((6, block_size), input_dtype)\n\n for lane in T.Parallel(block_size):\n column = block * block_size + lane\n if column < hidden_size:\n delta_shared[lane] = T.cast(\n previous[batch, column] - x[batch, column], input_dtype\n )\n T.sync_threads()\n\n for lane in T.Parallel(block_size):\n column = block * block_size + lane\n if column < hidden_size:\n products_shared[0, lane] = T.cast(\n delta_shared[lane] * mix_r[column], input_dtype\n )\n products_shared[1, lane] = T.cast(\n delta_shared[lane] * mix_w[column], input_dtype\n )\n products_shared[2, lane] = T.cast(\n delta_shared[lane] * mix_k[column], input_dtype\n )\n products_shared[3, lane] = T.cast(\n delta_shared[lane] * mix_v[column], input_dtype\n )\n products_shared[4, lane] = T.cast(\n delta_shared[lane] * mix_a[column], input_dtype\n )\n products_shared[5, lane] = T.cast(\n delta_shared[lane] * mix_g[column], input_dtype\n )\n T.sync_threads()\n\n for lane in T.Parallel(block_size):\n column = block * block_size + lane\n if column < hidden_size:\n for mix_index in T.Serial(6):\n mixed[batch, mix_index, column] = T.cast(\n x[batch, column]\n + products_shared[mix_index, lane],\n input_dtype,\n )\n\n return kernel\n\n\ndef build_post_state_program(\n batch_size: int,\n num_heads: int,\n head_size: int,\n input_dtype: str,\n):\n """Build exact fused RKV correction and gating after native GroupNorm."""\n import tilelang.language as T # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n normalized: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size), input_dtype\n ),\n receptance: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size), input_dtype\n ),\n key: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size), input_dtype\n ),\n value: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size), input_dtype\n ),\n r_k: T.Tensor((num_heads, head_size), input_dtype), # type: ignore[reportInvalidTypeForm]\n gate: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size), input_dtype\n ),\n output: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size), input_dtype\n ),\n ):\n with T.Kernel(batch_size, num_heads, threads=32) as (batch, head):\n product_stage = T.alloc_shared((head_size,), input_dtype)\n correction = T.alloc_shared((head_size,), input_dtype)\n corrected = T.alloc_shared((head_size,), input_dtype)\n rkv_sum = T.alloc_shared((1,), input_dtype)\n\n for column in T.Parallel(head_size):\n product_stage[column] = T.cast(\n receptance[batch, head, column]\n * key[batch, head, column],\n input_dtype,\n )\n T.sync_threads()\n\n for column in T.Parallel(head_size):\n product_stage[column] = T.cast(\n product_stage[column] * r_k[head, column], input_dtype\n )\n T.sync_threads()\n\n for worker in T.Parallel(1):\n total = T.alloc_local((1,), "float32")\n total[0] = 0.0\n for column in T.serial(head_size):\n total[0] += T.cast(product_stage[column], "float32")\n rkv_sum[0] = T.cast(total[0], input_dtype)\n T.sync_threads()\n\n for column in T.Parallel(head_size):\n correction[column] = T.cast(\n rkv_sum[0] * value[batch, head, column], input_dtype\n )\n T.sync_threads()\n\n for column in T.Parallel(head_size):\n corrected[column] = T.cast(\n normalized[batch, head, column] + correction[column],\n input_dtype,\n )\n T.sync_threads()\n\n for column in T.Parallel(head_size):\n output[batch, head, column] = T.cast(\n corrected[column] * gate[batch, head, column], input_dtype\n )\n\n return kernel\n\n\ndef _dtype_name(dtype) -> str:\n if dtype == FLOAT16:\n return "float16"\n if dtype == BFLOAT16:\n return "bfloat16"\n if dtype == FLOAT32:\n return "float32"\n raise TypeError(f"TileLang RWKV kernel does not support dtype {dtype}")\n\n\n@lru_cache(maxsize=32)\ndef _compiled_kernel(\n batch_size: int,\n num_heads: int,\n head_size: int,\n input_dtype: str,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n program = build_state_program(\n batch_size,\n num_heads,\n head_size,\n input_dtype,\n )\n return tilelang.compile(\n program,\n out_idx=-1,\n execution_backend="auto",\n )\n\n\n@lru_cache(maxsize=32)\ndef _compiled_backward_kernel(\n batch_size: int,\n num_heads: int,\n head_size: int,\n input_dtype: str,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n build_state_backward_program(\n batch_size, num_heads, head_size, input_dtype\n ),\n out_idx=-1,\n execution_backend="auto",\n )\n\n@lru_cache(maxsize=32)\ndef _compiled_low_precision_state_kernel(\n batch_size: int,\n num_heads: int,\n head_size: int,\n input_dtype: str,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n build_low_precision_state_program(\n batch_size, num_heads, head_size, input_dtype\n ),\n out_idx=-1,\n execution_backend="auto",\n )\n\n\ndef torch_state_update(\n state: torch.Tensor,\n decay: torch.Tensor,\n normalized_key: torch.Tensor,\n gate_a: torch.Tensor,\n value: torch.Tensor,\n key: torch.Tensor,\n receptance: torch.Tensor,\n) -> tuple[torch.Tensor, torch.Tensor]:\n anti_matrix = (-normalized_key).unsqueeze(-1) @ (normalized_key * gate_a).unsqueeze(\n -2\n )\n value_key = value.unsqueeze(-1) @ key.unsqueeze(-2)\n state_f32 = state.float()\n next_state = state_f32 * decay.float().unsqueeze(-2)\n next_state = next_state + state_f32 @ anti_matrix.float()\n next_state = next_state + value_key.float()\n if state.dtype == BFLOAT16:\n next_state = next_state.to(BFLOAT16)\n mixed = (next_state.to(receptance.dtype) @ receptance.unsqueeze(-1)).squeeze(-1)\n return next_state, mixed\n\n\n@lru_cache(maxsize=32)\ndef _compiled_x_mix(\n batch_size: int,\n hidden_size: int,\n input_dtype: str,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n build_x_mix_program(batch_size, hidden_size, input_dtype),\n out_idx=-1,\n execution_backend="auto",\n )\n\n\ndef tilelang_x_mix(\n x: torch.Tensor,\n previous: torch.Tensor,\n mix_r: torch.Tensor,\n mix_w: torch.Tensor,\n mix_k: torch.Tensor,\n mix_v: torch.Tensor,\n mix_a: torch.Tensor,\n mix_g: torch.Tensor,\n) -> torch.Tensor:\n """Fuse exact six-way BF16/FP16 decode x-mix."""\n if x.device.type != "cuda" or any(\n tensor.device != x.device\n for tensor in (previous, mix_r, mix_w, mix_k, mix_v, mix_a, mix_g)\n ):\n raise RuntimeError("TileLang x-mix requires one CUDA device")\n if x.dtype != BFLOAT16 or any(\n tensor.dtype != x.dtype\n for tensor in (previous, mix_r, mix_w, mix_k, mix_v, mix_a, mix_g)\n ):\n raise TypeError("TileLang x-mix requires matching bfloat16 tensors")\n if x.ndim != 2 or previous.shape != x.shape:\n raise ValueError("x and previous must have shape [batch, hidden]")\n batch_size, hidden_size = x.shape\n if any(\n tensor.shape != (hidden_size,)\n for tensor in (mix_r, mix_w, mix_k, mix_v, mix_a, mix_g)\n ):\n raise ValueError("x-mix weights must have shape [hidden]")\n kernel: Any = _compiled_x_mix(\n batch_size,\n hidden_size,\n _dtype_name(x.dtype),\n cuda_arch_key(x.device),\n )\n return kernel(\n x.contiguous(),\n previous.contiguous(),\n mix_r.contiguous(),\n mix_w.contiguous(),\n mix_k.contiguous(),\n mix_v.contiguous(),\n mix_a.contiguous(),\n mix_g.contiguous(),\n )\n\n\n@lru_cache(maxsize=32)\ndef _compiled_post_state(\n batch_size: int,\n num_heads: int,\n head_size: int,\n input_dtype: str,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n build_post_state_program(batch_size, num_heads, head_size, input_dtype),\n out_idx=-1,\n execution_backend="auto",\n )\n\n\ndef tilelang_post_state(\n normalized: torch.Tensor,\n receptance: torch.Tensor,\n key: torch.Tensor,\n value: torch.Tensor,\n r_k: torch.Tensor,\n gate: torch.Tensor,\n) -> torch.Tensor:\n """Fuse exact BF16 RKV correction and gating after native GroupNorm."""\n inputs = (receptance, key, value, gate)\n if normalized.device.type != "cuda" or any(\n tensor.device != normalized.device for tensor in (*inputs, r_k)\n ):\n raise RuntimeError("TileLang post-state fusion requires one CUDA device")\n if normalized.dtype != BFLOAT16 or any(\n tensor.dtype != normalized.dtype for tensor in (*inputs, r_k)\n ):\n raise TypeError("TileLang post-state fusion requires matching bfloat16")\n if normalized.ndim != 3:\n raise ValueError("normalized must have shape [batch, heads, head]")\n batch_size, num_heads, head_size = normalized.shape\n expected = (batch_size, num_heads, head_size)\n if any(tensor.shape != expected for tensor in inputs):\n raise ValueError("post-state vector shapes are incompatible")\n if r_k.shape != (num_heads, head_size):\n raise ValueError("r_k must have shape [heads, head]")\n kernel: Any = _compiled_post_state(\n batch_size,\n num_heads,\n head_size,\n _dtype_name(normalized.dtype),\n cuda_arch_key(normalized.device),\n )\n return kernel(\n normalized.contiguous(),\n receptance.contiguous(),\n key.contiguous(),\n value.contiguous(),\n r_k.contiguous(),\n gate.contiguous(),\n )\n\n\n@lru_cache(maxsize=32)\ndef _compiled_fused_state_update(\n batch_size: int,\n num_heads: int,\n head_size: int,\n input_dtype: str,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n build_fused_state_update_program(\n batch_size, num_heads, head_size, input_dtype\n ),\n out_idx=[-2, -1],\n execution_backend="auto",\n )\n\n\n\n\ndef tilelang_fused_state_update(\n state: torch.Tensor,\n decay: torch.Tensor,\n anti_update: torch.Tensor,\n value_key: torch.Tensor,\n receptance: torch.Tensor,\n) -> tuple[torch.Tensor, torch.Tensor]:\n """Fuse exact FP32 state finalization and validated narrow projection."""\n batch_size, num_heads, head_size, columns = state.shape\n if columns != head_size or head_size % 16:\n raise ValueError("fused state update requires square 16-aligned heads")\n if state.device.type != "cuda" or any(\n tensor.device != state.device\n for tensor in (decay, anti_update, value_key, receptance)\n ):\n raise RuntimeError("fused state update requires one CUDA device")\n _require_exact_fused_state_projection(state.device)\n if state.dtype != FLOAT32 or anti_update.dtype != FLOAT32 or value_key.dtype != FLOAT32:\n raise TypeError("fused state update requires FP32 state updates")\n if decay.dtype != receptance.dtype or decay.dtype not in {FLOAT16, BFLOAT16}:\n raise TypeError("fused state update requires matching float16/bfloat16 vectors")\n kernel: Any = _compiled_fused_state_update(\n batch_size,\n num_heads,\n head_size,\n _dtype_name(decay.dtype),\n cuda_arch_key(state.device),\n )\n return kernel(\n state.contiguous(),\n decay.contiguous(),\n anti_update.contiguous(),\n value_key.contiguous(),\n receptance.contiguous(),\n )\n\n\n\n\n\n\n\n\n@lru_cache(maxsize=32)\ndef _compiled_state_projection(\n batch_size: int,\n num_heads: int,\n head_size: int,\n input_dtype: str,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n build_state_projection_program(\n batch_size, num_heads, head_size, input_dtype\n ),\n out_idx=-1,\n execution_backend="auto",\n )\n\n\ndef tilelang_state_projection(\n state: torch.Tensor, receptance: torch.Tensor\n) -> torch.Tensor:\n """Project head state on GPUs with validated exact padded MMA behavior."""\n if state.device.type != "cuda" or receptance.device != state.device:\n raise RuntimeError("TileLang state projection requires one CUDA device")\n _require_exact_fused_state_projection(state.device)\n if state.dtype != receptance.dtype or state.dtype not in {FLOAT16, BFLOAT16}:\n raise TypeError("TileLang state projection requires matching float16/bfloat16")\n if state.ndim != 4 or receptance.ndim != 3:\n raise ValueError("state/receptance ranks must be 4 and 3")\n batch_size, num_heads, head_size, columns = state.shape\n if columns != head_size or receptance.shape != (batch_size, num_heads, head_size):\n raise ValueError("state/receptance shapes are incompatible")\n if head_size % 16:\n raise ValueError("TileLang state projection requires head size divisible by 16")\n kernel: Any = _compiled_state_projection(\n batch_size,\n num_heads,\n head_size,\n _dtype_name(state.dtype),\n cuda_arch_key(state.device),\n )\n return kernel(state.contiguous(), receptance.contiguous())\n\n\ndef tilelang_state_finalize(\n state: torch.Tensor,\n decay: torch.Tensor,\n anti_update: torch.Tensor,\n value_key: torch.Tensor,\n) -> torch.Tensor:\n """Run compiled pointwise state finalization without PyTorch dispatch."""\n batch_size, num_heads, head_size, _ = state.shape\n kernel: Any = _compiled_kernel(\n batch_size,\n num_heads,\n head_size,\n _dtype_name(decay.dtype),\n cuda_arch_key(state.device),\n )\n return kernel(\n state.contiguous(),\n decay.contiguous(),\n anti_update.contiguous(),\n value_key.contiguous(),\n )\n\n\ndef tilelang_state_finalize_backward(\n grad_output: torch.Tensor, decay: torch.Tensor\n) -> torch.Tensor:\n """Run the compiled first-order state-gradient kernel."""\n batch_size, num_heads, head_size, _ = grad_output.shape\n kernel: Any = _compiled_backward_kernel(\n batch_size,\n num_heads,\n head_size,\n _dtype_name(decay.dtype),\n cuda_arch_key(grad_output.device),\n )\n return kernel(grad_output.contiguous(), decay.contiguous())\n\n\ndef tilelang_low_precision_state_finalize(\n state: torch.Tensor,\n decay: torch.Tensor,\n anti_update: torch.Tensor,\n value_key: torch.Tensor,\n) -> torch.Tensor:\n """Finalize recurrent state with FP32 compute and low-precision storage."""\n if state.dtype not in {FLOAT16, BFLOAT16} or decay.dtype != state.dtype:\n raise TypeError(\n "Low-precision state finalization requires matching FP16/BF16 state and decay"\n )\n if anti_update.dtype != FLOAT32 or value_key.dtype != FLOAT32:\n raise TypeError("Low-precision state finalization requires FP32 updates")\n batch_size, num_heads, head_size, columns = state.shape\n if columns != head_size:\n raise ValueError("Low-precision recurrent state must be square per head")\n kernel: Any = _compiled_low_precision_state_kernel(\n batch_size,\n num_heads,\n head_size,\n _dtype_name(decay.dtype),\n cuda_arch_key(state.device),\n )\n return kernel(\n state.contiguous(),\n decay.contiguous(),\n anti_update.contiguous(),\n value_key.contiguous(),\n )\n\n\n\n\ndef tilelang_state_update(\n state: torch.Tensor,\n decay: torch.Tensor,\n normalized_key: torch.Tensor,\n gate_a: torch.Tensor,\n value: torch.Tensor,\n key: torch.Tensor,\n receptance: torch.Tensor,\n *,\n state_finalize_op: Any | None = None,\n) -> tuple[torch.Tensor, torch.Tensor]:\n if state.device.type != "cuda":\n raise RuntimeError("TileLang RWKV kernel requires CUDA tensors")\n\n state = state.contiguous()\n decay = decay.contiguous()\n normalized_key = normalized_key.contiguous()\n gate_a = gate_a.contiguous()\n value = value.contiguous()\n key = key.contiguous()\n receptance = receptance.contiguous()\n\n # Keep BF16/FP16 outer products and FP32 batched GEMM in PyTorch. Their\n # accumulation order is observable after long recurrent sequences.\n anti_matrix = (-normalized_key).unsqueeze(-1) @ (normalized_key * gate_a).unsqueeze(\n -2\n )\n state_f32 = state.float()\n anti_update = state_f32 @ anti_matrix.float()\n value_key = (value.unsqueeze(-1) @ key.unsqueeze(-2)).float()\n if state.dtype in {FLOAT16, BFLOAT16}:\n next_state = tilelang_low_precision_state_finalize(\n state, decay, anti_update, value_key\n )\n mixed = (next_state @ receptance.unsqueeze(-1)).squeeze(-1)\n return next_state, mixed\n if state.dtype != FLOAT32:\n raise TypeError(\n "TileLang recurrent state must be float32, float16, or bfloat16"\n )\n\n differentiable = IS_GRAD_ENABLED() and any(\n tensor.requires_grad for tensor in (state, decay, anti_update, value_key)\n )\n if (\n not differentiable\n and receptance.dtype in {FLOAT16, BFLOAT16}\n and state.shape[-1] % 16 == 0\n and exact_fused_state_projection_supported(state.device)\n ):\n return tilelang_fused_state_update(\n state, decay, anti_update, value_key, receptance\n )\n if differentiable:\n if state_finalize_op is None:\n raise RuntimeError(\n "differentiable TileLang state update requires the registered custom op"\n )\n next_state = state_finalize_op(state, decay, anti_update, value_key)\n else:\n next_state = tilelang_state_finalize(state, decay, anti_update, value_key)\n mixed = (next_state.to(receptance.dtype) @ receptance.unsqueeze(-1)).squeeze(-1)\n return next_state, mixed\n\n\ndef torch_state_scan(\n state: torch.Tensor,\n decay: torch.Tensor,\n normalized_key: torch.Tensor,\n gate_a: torch.Tensor,\n value: torch.Tensor,\n key: torch.Tensor,\n receptance: torch.Tensor,\n *,\n active: torch.Tensor | None = None,\n reset: torch.Tensor | None = None,\n output_mode: str = "full",\n chunk_size: int = 0,\n) -> tuple[torch.Tensor, torch.Tensor]:\n """Exact executable specification for recurrent sequence state updates."""\n if output_mode not in {"full", "final"}:\n raise ValueError("output_mode must be full or final")\n if chunk_size < 0:\n raise ValueError("chunk_size must be non-negative")\n if decay.ndim != 4:\n raise ValueError("Sequence tensors must have shape [batch, time, heads, head]")\n sequence_length = decay.shape[1]\n if sequence_length == 0:\n raise ValueError("State scan requires at least one token")\n step = chunk_size or sequence_length\n matrix = state\n mixed_steps: list[torch.Tensor] = []\n final_mixed: torch.Tensor | None = None\n for chunk_start in range(0, sequence_length, step):\n chunk_stop = min(chunk_start + step, sequence_length)\n for token_index in range(chunk_start, chunk_stop):\n if reset is not None:\n reset_token = reset[:, token_index].bool().reshape(-1, 1, 1, 1)\n matrix = TORCH_WHERE(reset_token, TORCH_ZEROS_LIKE(matrix), matrix)\n matrix_candidate, mixed_candidate = torch_state_update(\n matrix,\n decay[:, token_index],\n normalized_key[:, token_index],\n gate_a[:, token_index],\n value[:, token_index],\n key[:, token_index],\n receptance[:, token_index],\n )\n if active is None:\n matrix = matrix_candidate\n mixed = mixed_candidate\n else:\n active_token = active[:, token_index].bool().reshape(-1, 1, 1, 1)\n matrix = TORCH_WHERE(active_token, matrix_candidate, matrix)\n mixed = (\n matrix.to(receptance.dtype)\n @ receptance[:, token_index].unsqueeze(-1)\n ).squeeze(-1)\n if output_mode == "full":\n mixed_steps.append(mixed)\n final_mixed = mixed\n if output_mode == "full":\n return matrix, TORCH_STACK(mixed_steps, dim=1)\n if final_mixed is None:\n raise RuntimeError("State scan produced no output")\n return matrix, final_mixed.unsqueeze(1)\n\n\ndef tilelang_state_scan(\n state: torch.Tensor,\n decay: torch.Tensor,\n normalized_key: torch.Tensor,\n gate_a: torch.Tensor,\n value: torch.Tensor,\n key: torch.Tensor,\n receptance: torch.Tensor,\n *,\n active: torch.Tensor | None = None,\n reset: torch.Tensor | None = None,\n output_mode: str = "full",\n chunk_size: int = 0,\n) -> tuple[torch.Tensor, torch.Tensor]:\n """Exact TileLang-assisted sequence scan using the validated state kernel."""\n if state.device.type != "cuda":\n raise RuntimeError("TileLang RWKV sequence scan requires CUDA tensors")\n if output_mode not in {"full", "final"}:\n raise ValueError("output_mode must be full or final")\n if chunk_size < 0:\n raise ValueError("chunk_size must be non-negative")\n sequence_length = decay.shape[1]\n if sequence_length == 0:\n raise ValueError("State scan requires at least one token")\n step = chunk_size or sequence_length\n matrix = state\n mixed_steps: list[torch.Tensor] = []\n final_mixed: torch.Tensor | None = None\n for chunk_start in range(0, sequence_length, step):\n chunk_stop = min(chunk_start + step, sequence_length)\n for token_index in range(chunk_start, chunk_stop):\n if reset is not None:\n reset_token = reset[:, token_index].bool().reshape(-1, 1, 1, 1)\n matrix = TORCH_WHERE(reset_token, TORCH_ZEROS_LIKE(matrix), matrix)\n candidate, candidate_mixed = tilelang_state_update(\n matrix,\n decay[:, token_index],\n normalized_key[:, token_index],\n gate_a[:, token_index],\n value[:, token_index],\n key[:, token_index],\n receptance[:, token_index],\n )\n if active is None:\n matrix = candidate\n mixed = candidate_mixed\n else:\n active_token = active[:, token_index].bool().reshape(-1, 1, 1, 1)\n matrix = TORCH_WHERE(active_token, candidate, matrix)\n mixed = (\n matrix.to(receptance.dtype)\n @ receptance[:, token_index].unsqueeze(-1)\n ).squeeze(-1)\n if output_mode == "full":\n mixed_steps.append(mixed)\n final_mixed = mixed\n if output_mode == "full":\n return matrix, TORCH_STACK(mixed_steps, dim=1)\n if final_mixed is None:\n raise RuntimeError("State scan produced no output")\n return matrix, final_mixed.unsqueeze(1)\n\n\ndef build_fast_state_scan_program(\n batch_size: int,\n sequence_length: int,\n num_heads: int,\n head_size: int,\n input_dtype: str,\n):\n """Build experimental persistent recurrent scan with one block per head."""\n import tilelang.language as T # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n state: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size, head_size), "float32"\n ),\n decay: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, sequence_length, num_heads, head_size), input_dtype\n ),\n normalized_key: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, sequence_length, num_heads, head_size), input_dtype\n ),\n gate_a: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, sequence_length, num_heads, head_size), input_dtype\n ),\n value: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, sequence_length, num_heads, head_size), input_dtype\n ),\n key: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, sequence_length, num_heads, head_size), input_dtype\n ),\n receptance: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, sequence_length, num_heads, head_size), input_dtype\n ),\n next_state: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size, head_size), "float32"\n ),\n mixed: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, sequence_length, num_heads, head_size), input_dtype\n ),\n ):\n with T.Kernel(batch_size, num_heads, threads=256) as (batch, head):\n current = T.alloc_shared((head_size, head_size), "float32")\n following = T.alloc_shared((head_size, head_size), "float32")\n for row, column in T.Parallel(head_size, head_size):\n current[row, column] = state[batch, head, row, column]\n T.sync_threads()\n\n for token in T.serial(sequence_length):\n for row, column in T.Parallel(head_size, head_size):\n anti_projection = T.alloc_local((1,), "float32")\n anti_projection[0] = 0.0\n for inner in T.serial(head_size):\n left = T.cast(\n -normalized_key[batch, token, head, inner], input_dtype\n )\n right = T.cast(\n normalized_key[batch, token, head, column]\n * gate_a[batch, token, head, column],\n input_dtype,\n )\n anti_element = T.cast(left * right, input_dtype)\n anti_projection[0] += current[row, inner] * T.cast(\n anti_element, "float32"\n )\n value_key = T.cast(\n T.cast(\n value[batch, token, head, row]\n * key[batch, token, head, column],\n input_dtype,\n ),\n "float32",\n )\n following[row, column] = (\n current[row, column]\n * T.cast(decay[batch, token, head, column], "float32")\n + anti_projection[0]\n + value_key\n )\n T.sync_threads()\n for row, column in T.Parallel(head_size, head_size):\n current[row, column] = following[row, column]\n T.sync_threads()\n\n for row in T.Parallel(head_size):\n projection = T.alloc_local((1,), "float32")\n projection[0] = 0.0\n for column in T.serial(head_size):\n projection[0] += (\n T.cast(current[row, column], input_dtype)\n * receptance[batch, token, head, column]\n )\n mixed[batch, token, head, row] = T.cast(projection[0], input_dtype)\n T.sync_threads()\n\n for row, column in T.Parallel(head_size, head_size):\n next_state[batch, head, row, column] = current[row, column]\n\n return kernel\n\n\n@lru_cache(maxsize=32)\ndef _compiled_fast_state_scan(\n batch_size: int,\n sequence_length: int,\n num_heads: int,\n head_size: int,\n input_dtype: str,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n build_fast_state_scan_program(\n batch_size,\n sequence_length,\n num_heads,\n head_size,\n input_dtype,\n ),\n out_idx=[-2, -1],\n execution_backend="auto",\n )\n\n\ndef tilelang_fast_state_scan(\n state: torch.Tensor,\n decay: torch.Tensor,\n normalized_key: torch.Tensor,\n gate_a: torch.Tensor,\n value: torch.Tensor,\n key: torch.Tensor,\n receptance: torch.Tensor,\n) -> tuple[torch.Tensor, torch.Tensor]:\n """Run experimental approximate persistent sequence scan."""\n if state.device.type != "cuda":\n raise RuntimeError("TileLang fast state scan requires CUDA tensors")\n batch_size, sequence_length, num_heads, head_size = decay.shape\n kernel: Any = _compiled_fast_state_scan(\n batch_size,\n sequence_length,\n num_heads,\n head_size,\n _dtype_name(receptance.dtype),\n cuda_arch_key(state.device),\n )\n return kernel(\n state.contiguous(),\n decay.contiguous(),\n normalized_key.contiguous(),\n gate_a.contiguous(),\n value.contiguous(),\n key.contiguous(),\n receptance.contiguous(),\n )\n\n\ndef clear_tilelang_state_kernel_caches() -> None:\n """Drop bounded Python references to compiled recurrent-state kernels."""\n for compiler in (\n _compiled_kernel,\n _compiled_backward_kernel,\n _compiled_low_precision_state_kernel,\n _compiled_x_mix,\n _compiled_post_state,\n _compiled_fused_state_update,\n _compiled_state_projection,\n _compiled_fast_state_scan,\n ):\n compiler.cache_clear()\n'
filename = '<rwkv7_state_a3597160cb8d7317151200d05b241af7edcad2928c3731687764d914c28bf21a>'
linecache.cache[filename] = (
len(source), None, source.splitlines(keepends=True), filename
)
namespace = {'__name__': 'inference.kernel.state'}
exec(compile(source, filename, 'exec'), namespace, namespace) # noqa: S102
return SimpleNamespace(
Any=namespace['Any'],
BFLOAT16=namespace['BFLOAT16'],
CUDA_GET_DEVICE_CAPABILITY=namespace['CUDA_GET_DEVICE_CAPABILITY'],
EXACT_FUSED_STATE_PROJECTION_CAPABILITIES=namespace['EXACT_FUSED_STATE_PROJECTION_CAPABILITIES'],
FLOAT16=namespace['FLOAT16'],
FLOAT32=namespace['FLOAT32'],
IS_GRAD_ENABLED=namespace['IS_GRAD_ENABLED'],
TORCH_STACK=namespace['TORCH_STACK'],
TORCH_WHERE=namespace['TORCH_WHERE'],
TORCH_ZEROS_LIKE=namespace['TORCH_ZEROS_LIKE'],
_compiled_backward_kernel=namespace['_compiled_backward_kernel'],
_compiled_fast_state_scan=namespace['_compiled_fast_state_scan'],
_compiled_fused_state_update=namespace['_compiled_fused_state_update'],
_compiled_kernel=namespace['_compiled_kernel'],
_compiled_low_precision_state_kernel=namespace['_compiled_low_precision_state_kernel'],
_compiled_post_state=namespace['_compiled_post_state'],
_compiled_state_projection=namespace['_compiled_state_projection'],
_compiled_x_mix=namespace['_compiled_x_mix'],
_dtype_name=namespace['_dtype_name'],
_require_exact_fused_state_projection=namespace['_require_exact_fused_state_projection'],
build_fast_state_scan_program=namespace['build_fast_state_scan_program'],
build_fused_state_update_program=namespace['build_fused_state_update_program'],
build_low_precision_state_program=namespace['build_low_precision_state_program'],
build_post_state_program=namespace['build_post_state_program'],
build_state_backward_program=namespace['build_state_backward_program'],
build_state_program=namespace['build_state_program'],
build_state_projection_program=namespace['build_state_projection_program'],
build_x_mix_program=namespace['build_x_mix_program'],
clear_tilelang_state_kernel_caches=namespace['clear_tilelang_state_kernel_caches'],
cuda_arch_key=namespace['cuda_arch_key'],
exact_fused_state_projection_supported=namespace['exact_fused_state_projection_supported'],
lru_cache=namespace['lru_cache'],
tilelang_fast_state_scan=namespace['tilelang_fast_state_scan'],
tilelang_fused_state_update=namespace['tilelang_fused_state_update'],
tilelang_low_precision_state_finalize=namespace['tilelang_low_precision_state_finalize'],
tilelang_post_state=namespace['tilelang_post_state'],
tilelang_state_finalize=namespace['tilelang_state_finalize'],
tilelang_state_finalize_backward=namespace['tilelang_state_finalize_backward'],
tilelang_state_projection=namespace['tilelang_state_projection'],
tilelang_state_scan=namespace['tilelang_state_scan'],
tilelang_state_update=namespace['tilelang_state_update'],
tilelang_x_mix=namespace['tilelang_x_mix'],
torch=namespace['torch'],
torch_state_scan=namespace['torch_state_scan'],
torch_state_update=namespace['torch_state_update'],
)
def _build_decode_namespace(state_cuda_arch_key):
source = 'from __future__ import annotations\n\n\nfrom functools import lru_cache\nfrom typing import Any\n\nimport torch\n\n\n\n_HEAD_SIZE = 64\n_TWO_NEG_41 = 4.547473508864641e-13\n_NEXP_HALF_LOG2_E = -0.8750387749145276\n_NLOG2_E = -1.4426950408889634\n_ROTATOR1_SIGNED = -1640531527\n\n\ndef _build_wkv_program(\n batch_size: int,\n sequence_length: int,\n num_heads: int,\n precise: bool = False,\n):\n """Build a fixed-shape FP16 WKV scan with selectable recurrence precision."""\n import tilelang.language as T # type: ignore[import-not-found]\n\n head_size = _HEAD_SIZE\n current_dtype = "float32" if precise else "float16"\n\n @T.prim_func\n def kernel(\n state: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, num_heads, head_size, head_size), "float16"\n ),\n receptance: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, sequence_length, num_heads, head_size), "float16"\n ),\n decay_raw: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, sequence_length, num_heads, head_size), "float16"\n ),\n key: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, sequence_length, num_heads, head_size), "float16"\n ),\n value: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, sequence_length, num_heads, head_size), "float16"\n ),\n gate_a: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, sequence_length, num_heads, head_size), "float16"\n ),\n gate_b: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, sequence_length, num_heads, head_size), "float16"\n ),\n elapsed: T.Tensor((batch_size,), "int32"), # type: ignore[reportInvalidTypeForm]\n output: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (batch_size, sequence_length, num_heads, head_size), "float16"\n ),\n ):\n with T.Kernel(batch_size, num_heads, threads=head_size) as (batch, head):\n current = T.alloc_local((head_size,), current_dtype)\n r_shared = T.alloc_shared((2, head_size), "float16")\n w_shared = T.alloc_shared((2, head_size), "float16")\n k_shared = T.alloc_shared((2, head_size), "float16")\n v_shared = T.alloc_shared((2, head_size), "float16")\n a_shared = T.alloc_shared((2, head_size), "float16")\n b_shared = T.alloc_shared((2, head_size), "float16")\n\n row = T.get_thread_binding()\n for column in T.serial(head_size):\n current[column] = T.cast(\n state[batch, head, row, column], current_dtype\n )\n\n T.async_copy(\n receptance[batch, 0, head, 0:head_size],\n r_shared[0, 0:head_size],\n coalesced_width=8,\n )\n T.async_copy(\n decay_raw[batch, 0, head, 0:head_size],\n w_shared[0, 0:head_size],\n coalesced_width=8,\n )\n T.async_copy(\n key[batch, 0, head, 0:head_size],\n k_shared[0, 0:head_size],\n coalesced_width=8,\n )\n T.async_copy(\n value[batch, 0, head, 0:head_size],\n v_shared[0, 0:head_size],\n coalesced_width=8,\n )\n T.async_copy(\n gate_a[batch, 0, head, 0:head_size],\n a_shared[0, 0:head_size],\n coalesced_width=8,\n )\n T.async_copy(\n gate_b[batch, 0, head, 0:head_size],\n b_shared[0, 0:head_size],\n coalesced_width=8,\n )\n\n for token in T.serial(sequence_length):\n current_buffer = token % 2\n T.ptx_wait_group(0)\n T.sync_threads()\n if not precise:\n for column in T.Parallel(head_size):\n raw = T.cast(\n w_shared[current_buffer, column], "float32"\n )\n phase = T.cast(\n elapsed[batch] + head * head_size + column + token,\n "int32",\n )\n rotation = T.cast(\n phase * T.cast(_ROTATOR1_SIGNED, "int32"), "float32"\n ) * _TWO_NEG_41\n transformed = T.exp2(\n _NEXP_HALF_LOG2_E\n / (1.0 + T.exp2(_NLOG2_E * raw))\n ) - 1.0 + rotation\n w_shared[current_buffer, column] = T.cast(\n transformed, "float16"\n )\n T.sync_threads()\n\n if token + 1 < sequence_length:\n next_buffer = (token + 1) % 2\n T.async_copy(\n receptance[batch, token + 1, head, 0:head_size],\n r_shared[next_buffer, 0:head_size],\n coalesced_width=8,\n )\n T.async_copy(\n decay_raw[batch, token + 1, head, 0:head_size],\n w_shared[next_buffer, 0:head_size],\n coalesced_width=8,\n )\n T.async_copy(\n key[batch, token + 1, head, 0:head_size],\n k_shared[next_buffer, 0:head_size],\n coalesced_width=8,\n )\n T.async_copy(\n value[batch, token + 1, head, 0:head_size],\n v_shared[next_buffer, 0:head_size],\n coalesced_width=8,\n )\n T.async_copy(\n gate_a[batch, token + 1, head, 0:head_size],\n a_shared[next_buffer, 0:head_size],\n coalesced_width=8,\n )\n T.async_copy(\n gate_b[batch, token + 1, head, 0:head_size],\n b_shared[next_buffer, 0:head_size],\n coalesced_width=8,\n )\n\n if precise:\n # Match the PyTorch recurrent store boundary: accumulate the\n # factored rank-one update in FP32, then round state once.\n state_projection_f32 = T.alloc_local((1,), "float32")\n state_projection_f32[0] = T.cast(0.0, "float32")\n for column in T.serial(head_size):\n state_projection_f32[0] += current[column] * T.cast(\n a_shared[current_buffer, column], "float32"\n )\n rounded_state = T.alloc_local((head_size,), "float16")\n for column in T.serial(head_size):\n updated_f32 = T.alloc_local((1,), "float32")\n updated_f32[0] = current[column] * T.cast(\n w_shared[current_buffer, column], "float32"\n )\n updated_f32[0] = (\n updated_f32[0]\n + state_projection_f32[0]\n * T.cast(b_shared[current_buffer, column], "float32")\n )\n value_key = T.cast(\n k_shared[current_buffer, column]\n * v_shared[current_buffer, row],\n "float16",\n )\n updated_f32[0] = updated_f32[0] + T.cast(\n value_key, "float32"\n )\n rounded = T.cast(updated_f32[0], "float16")\n current[column] = T.cast(rounded, "float32")\n rounded_state[column] = rounded\n # Fixed two-lane FP16 projection preserves recurrent output\n # order while avoiding a second long FP32 dependency chain.\n output_pair = T.alloc_local((2,), "float16")\n for lane in T.vectorized(2):\n output_pair[lane] = T.cast(0.0, "float16")\n for pair in T.serial(head_size // 2):\n for lane in T.vectorized(2):\n column = pair * 2 + lane\n output_pair[lane] = T.cast(\n rounded_state[column]\n * r_shared[current_buffer, column]\n + output_pair[lane],\n "float16",\n )\n output[batch, token, head, row] = T.cast(\n output_pair[0] + output_pair[1], "float16"\n )\n else:\n projection_pair = T.alloc_local((2,), "float16")\n for lane in T.vectorized(2):\n projection_pair[lane] = T.cast(0.0, "float16")\n for pair in T.serial(head_size // 2):\n for lane in T.vectorized(2):\n column = pair * 2 + lane\n projection_pair[lane] = T.cast(\n a_shared[current_buffer, column] * current[column]\n + projection_pair[lane],\n "float16",\n )\n state_projection = T.cast(\n projection_pair[0] + projection_pair[1], "float16"\n )\n output_pair = T.alloc_local((2,), "float16")\n for lane in T.vectorized(2):\n output_pair[lane] = T.cast(0.0, "float16")\n for pair in T.serial(head_size // 2):\n for lane in T.vectorized(2):\n column = pair * 2 + lane\n updated = T.cast(\n current[column]\n * w_shared[current_buffer, column]\n + T.cast(\n k_shared[current_buffer, column]\n * v_shared[current_buffer, row]\n + T.cast(\n state_projection\n * b_shared[current_buffer, column]\n + current[column],\n "float16",\n ),\n "float16",\n ),\n "float16",\n )\n current[column] = updated\n output_pair[lane] = T.cast(\n updated * r_shared[current_buffer, column]\n + output_pair[lane],\n "float16",\n )\n output[batch, token, head, row] = T.cast(\n output_pair[0] + output_pair[1], "float16"\n )\n # Precise mode synchronizes at the next wait/barrier before a\n # double buffer is reused; the legacy transform needs this barrier.\n if not precise:\n T.sync_threads()\n\n for column in T.serial(head_size):\n state[batch, head, row, column] = current[column]\n\n return kernel\n\n\n\n\n@lru_cache(maxsize=16)\ndef _compiled_wkv(\n batch_size: int,\n sequence_length: int,\n num_heads: int,\n device_arch: str,\n precise: bool = False,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n _build_wkv_program(\n batch_size,\n sequence_length,\n num_heads,\n precise,\n ),\n out_idx=[],\n execution_backend="auto",\n )\n\n\ndef _build_wkv_w0_t1_program(num_heads: int):\n """Build specialized B1T1 FP16 WKV with fused decay bias."""\n import tilelang.language as T # type: ignore[import-not-found]\n\n head_size = _HEAD_SIZE\n\n @T.prim_func\n def kernel(\n state: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (1, num_heads, head_size, head_size), "float16"\n ),\n receptance: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (1, 1, num_heads, head_size), "float16"\n ),\n decay: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (1, 1, num_heads, head_size), "float16"\n ),\n decay_bias: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (num_heads, head_size), "float16"\n ),\n key: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (1, 1, num_heads, head_size), "float16"\n ),\n value: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (1, 1, num_heads, head_size), "float16"\n ),\n gate_a: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (1, 1, num_heads, head_size), "float16"\n ),\n gate_b: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (1, 1, num_heads, head_size), "float16"\n ),\n elapsed: T.Tensor((1,), "int32"), # type: ignore[reportInvalidTypeForm]\n output: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (1, 1, num_heads, head_size), "float16"\n ),\n ):\n with T.Kernel(num_heads, threads=head_size) as head:\n row = T.get_thread_binding(0)\n current = T.alloc_local((head_size,), "float16")\n state_vector = T.alloc_local((8,), "float16")\n state_shared = T.alloc_shared(\n (head_size, head_size), "float16"\n )\n r_shared = T.alloc_shared((head_size,), "float16")\n w_shared = T.alloc_shared((head_size,), "float16")\n k_shared = T.alloc_shared((head_size,), "float16")\n v_shared = T.alloc_shared((head_size,), "float16")\n a_shared = T.alloc_shared((head_size,), "float16")\n b_shared = T.alloc_shared((head_size,), "float16")\n for chunk in T.serial(head_size // 8):\n linear_start = (chunk * head_size + row) * 8\n for vector_lane in T.vectorized(8):\n linear = linear_start + vector_lane\n source_row = linear // head_size\n source_column = linear % head_size\n state_vector[vector_lane] = state[\n 0, head, source_row, source_column\n ]\n for vector_lane in T.serial(8):\n linear = linear_start + vector_lane\n source_row = linear // head_size\n source_column = linear % head_size\n swizzled_column = (\n ((source_row % 32) ^ (source_column // 2)) * 2\n + source_column % 2\n )\n state_shared[source_row, swizzled_column] = (\n state_vector[vector_lane]\n )\n T.sync_threads()\n for column in T.serial(head_size):\n swizzled_column = (\n ((row % 32) ^ (column // 2)) * 2 + column % 2\n )\n current[column] = state_shared[row, swizzled_column]\n r_shared[row] = receptance[0, 0, head, row]\n k_shared[row] = key[0, 0, head, row]\n v_shared[row] = value[0, 0, head, row]\n a_shared[row] = gate_a[0, 0, head, row]\n b_shared[row] = gate_b[0, 0, head, row]\n raw = T.cast(\n decay[0, 0, head, row] + decay_bias[head, row],\n "float32",\n )\n phase = T.cast(\n elapsed[0] + head * head_size + row, "int32"\n )\n rotation = T.cast(\n phase * T.cast(_ROTATOR1_SIGNED, "int32"), "float32"\n ) * _TWO_NEG_41\n transformed = T.exp2(\n _NEXP_HALF_LOG2_E\n / (1.0 + T.exp2(_NLOG2_E * raw))\n ) - 1.0 + rotation\n w_shared[row] = T.cast(transformed, "float16")\n T.sync_threads()\n projection_pair = T.alloc_local((2,), "float16")\n for pair_lane in T.vectorized(2):\n projection_pair[pair_lane] = T.cast(0.0, "float16")\n for pair in T.serial(head_size // 2):\n for pair_lane in T.vectorized(2):\n column = pair * 2 + pair_lane\n projection_pair[pair_lane] = T.cast(\n a_shared[column] * current[column]\n + projection_pair[pair_lane],\n "float16",\n )\n state_projection = T.cast(\n projection_pair[0] + projection_pair[1], "float16"\n )\n output_pair = T.alloc_local((2,), "float16")\n for pair_lane in T.vectorized(2):\n output_pair[pair_lane] = T.cast(0.0, "float16")\n for pair in T.serial(head_size // 2):\n for pair_lane in T.vectorized(2):\n column = pair * 2 + pair_lane\n updated = T.cast(\n current[column] * w_shared[column]\n + T.cast(\n k_shared[column] * v_shared[row]\n + T.cast(\n state_projection * b_shared[column]\n + current[column],\n "float16",\n ),\n "float16",\n ),\n "float16",\n )\n current[column] = updated\n output_pair[pair_lane] = T.cast(\n updated * r_shared[column]\n + output_pair[pair_lane],\n "float16",\n )\n output[0, 0, head, row] = T.cast(\n output_pair[0] + output_pair[1], "float16"\n )\n for column in T.serial(head_size):\n swizzled_column = (\n ((row % 32) ^ (column // 2)) * 2 + column % 2\n )\n state_shared[row, swizzled_column] = current[column]\n T.sync_threads()\n for chunk in T.serial(head_size // 8):\n linear_start = (chunk * head_size + row) * 8\n for vector_lane in T.serial(8):\n linear = linear_start + vector_lane\n target_row = linear // head_size\n target_column = linear % head_size\n swizzled_column = (\n ((target_row % 32) ^ (target_column // 2)) * 2\n + target_column % 2\n )\n state_vector[vector_lane] = state_shared[\n target_row, swizzled_column\n ]\n for vector_lane in T.vectorized(8):\n linear = linear_start + vector_lane\n target_row = linear // head_size\n target_column = linear % head_size\n state[0, head, target_row, target_column] = (\n state_vector[vector_lane]\n )\n\n return kernel\n\n\n@lru_cache(maxsize=8)\ndef _compiled_wkv_w0_t1(num_heads: int, device_arch: str):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n _build_wkv_w0_t1_program(num_heads),\n out_idx=[],\n execution_backend="auto",\n )\n\n\ndef _wkv_w0_t1_out(\n state: torch.Tensor,\n receptance: torch.Tensor,\n decay: torch.Tensor,\n decay_bias: torch.Tensor,\n key: torch.Tensor,\n value: torch.Tensor,\n gate_a: torch.Tensor,\n gate_b: torch.Tensor,\n elapsed: torch.Tensor,\n output: torch.Tensor,\n) -> None:\n """Run specialized B1T1 WKV with fused decay bias."""\n batch, sequence, heads, head_size = receptance.shape\n if (batch, sequence, head_size) != (1, 1, _HEAD_SIZE):\n raise ValueError("fused-bias WKV requires B1T1 with head size 64")\n tensors = (\n state,\n receptance,\n decay,\n decay_bias,\n key,\n value,\n gate_a,\n gate_b,\n output,\n )\n if any(tensor.device.type != "cuda" for tensor in tensors):\n raise RuntimeError("fused-bias WKV requires CUDA")\n if any(tensor.dtype != torch.float16 for tensor in tensors):\n raise TypeError("fused-bias WKV requires FP16")\n if any(not tensor.is_contiguous() for tensor in tensors):\n raise ValueError("fused-bias WKV requires contiguous tensors")\n if tuple(state.shape) != (1, heads, head_size, head_size):\n raise ValueError("fused-bias WKV state shape mismatch")\n if tuple(decay_bias.shape) != (heads, head_size):\n raise ValueError("fused-bias WKV decay-bias shape mismatch")\n if any(\n tuple(tensor.shape) != tuple(receptance.shape)\n for tensor in (decay, key, value, gate_a, gate_b, output)\n ):\n raise ValueError("fused-bias WKV vector shape mismatch")\n if elapsed.dtype != torch.int32 or tuple(elapsed.shape) != (1,):\n raise TypeError("elapsed must be int32 [1]")\n kernel: Any = _compiled_wkv_w0_t1(\n heads, cuda_arch_key(state.device)\n )\n kernel(\n state,\n receptance,\n decay,\n decay_bias,\n key,\n value,\n gate_a,\n gate_b,\n elapsed,\n output,\n )\n\n\ndef _wkv_kernel_out(\n state: torch.Tensor,\n receptance: torch.Tensor,\n decay: torch.Tensor,\n key: torch.Tensor,\n value: torch.Tensor,\n gate_a: torch.Tensor,\n gate_b: torch.Tensor,\n elapsed: torch.Tensor,\n output: torch.Tensor,\n *,\n precise: bool,\n) -> None:\n if state.device.type != "cuda" or output.device.type != "cuda":\n raise RuntimeError("TileLang FP16 WKV requires CUDA tensors")\n batch_size, sequence_length, num_heads, head_size = receptance.shape\n expected_state = (batch_size, num_heads, head_size, head_size)\n if head_size != _HEAD_SIZE or tuple(state.shape) != expected_state:\n raise ValueError("TileLang WKV requires [B,H,64,64] state")\n if not state.is_contiguous() or not output.is_contiguous():\n raise ValueError("TileLang WKV state/output must be contiguous")\n vectors = (receptance, decay, key, value, gate_a, gate_b)\n if any(vector.shape != receptance.shape for vector in vectors):\n raise ValueError("All WKV vectors must have the same [B,T,H,N] shape")\n if output.shape != receptance.shape:\n raise ValueError("WKV output must match receptance shape")\n if any(vector.dtype != torch.float16 for vector in (*vectors, state, output)):\n raise TypeError("TileLang WKV tensors must use float16")\n if (\n elapsed.dtype != torch.int32\n or tuple(elapsed.shape) != (batch_size,)\n or not elapsed.is_contiguous()\n ):\n raise TypeError("elapsed must be contiguous int32 [B]")\n kernel: Any = _compiled_wkv(\n batch_size,\n sequence_length,\n num_heads,\n cuda_arch_key(state.device),\n precise,\n )\n kernel(\n state,\n receptance.contiguous(),\n decay.contiguous(),\n key.contiguous(),\n value.contiguous(),\n gate_a.contiguous(),\n gate_b.contiguous(),\n elapsed,\n output,\n )\n\n\ndef _wkv_out(\n state: torch.Tensor,\n receptance: torch.Tensor,\n decay_raw: torch.Tensor,\n key: torch.Tensor,\n value: torch.Tensor,\n gate_a: torch.Tensor,\n gate_b: torch.Tensor,\n elapsed: torch.Tensor,\n output: torch.Tensor,\n) -> None:\n """Run Albatross-compatible WKV into caller-owned state/output."""\n _wkv_kernel_out(\n state,\n receptance,\n decay_raw,\n key,\n value,\n gate_a,\n gate_b,\n elapsed,\n output,\n precise=False,\n )\n\n\ndef _wkv_precise_out(\n state: torch.Tensor,\n receptance: torch.Tensor,\n decay: torch.Tensor,\n key: torch.Tensor,\n value: torch.Tensor,\n gate_a: torch.Tensor,\n gate_b: torch.Tensor,\n elapsed: torch.Tensor,\n output: torch.Tensor,\n) -> None:\n """Run FP32-accumulating WKV with FP16 recurrent storage."""\n _wkv_kernel_out(\n state,\n receptance,\n decay,\n key,\n value,\n gate_a,\n gate_b,\n elapsed,\n output,\n precise=True,\n )\n\n\n\n\n\ndef _build_gemv_program(\n input_rows: int,\n output_rows: int,\n input_dtype: str = "float16",\n out_tile: int = 2,\n reduce_threads: int = 128,\n clear_input_sized_output: bool = False,\n):\n """Build output-tiled FP32-accumulating inference GEMV."""\n if input_rows <= 0 or output_rows <= 0 or output_rows % out_tile:\n raise ValueError("GEMV dimensions must be positive and output tiled")\n if input_dtype not in {"float16", "bfloat16"}:\n raise ValueError("GEMV dtype must be float16 or bfloat16")\n vector_width = 8\n block_k = reduce_threads * vector_width\n if input_rows % block_k:\n raise ValueError("GEMV input must divide reduction tile")\n\n import tilelang.language as T # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n value: T.Tensor((input_rows,), input_dtype), # type: ignore[reportInvalidTypeForm]\n weight: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (output_rows, input_rows), input_dtype\n ),\n output: T.Tensor((output_rows,), input_dtype), # type: ignore[reportInvalidTypeForm]\n clear_output: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (input_rows,), input_dtype\n ),\n ):\n with T.Kernel(\n output_rows // out_tile, threads=reduce_threads\n ) as block:\n thread = T.get_thread_binding(0)\n row = block * out_tile\n value_local = T.alloc_local((vector_width,), input_dtype)\n weight_local = T.alloc_local(\n (out_tile, vector_width), input_dtype\n )\n accumulator0 = T.alloc_local((1,), "float32")\n accumulator1 = T.alloc_local((1,), "float32")\n reduced0 = T.alloc_local((1,), "float32")\n reduced1 = T.alloc_local((1,), "float32")\n T.clear(accumulator0)\n T.clear(accumulator1)\n for chunk in T.serial(input_rows // block_k):\n for lane in T.vectorized(vector_width):\n column = (\n chunk * block_k + thread * vector_width + lane\n )\n value_local[lane] = value[column]\n weight_local[0, lane] = weight[row, column]\n weight_local[1, lane] = weight[row + 1, column]\n for lane in T.serial(vector_width):\n current = T.cast(value_local[lane], "float32")\n accumulator0[0] += current * T.cast(\n weight_local[0, lane], "float32"\n )\n accumulator1[0] += current * T.cast(\n weight_local[1, lane], "float32"\n )\n with T.attr(\n T.comm_reducer(\n lambda left, right: left + right,\n [T.cast(0, "float32")],\n ),\n "reduce_scope",\n T.reinterpret(T.uint64(0), dtype="handle"),\n ):\n T.evaluate(\n T.tvm_thread_allreduce(\n T.uint32(1),\n accumulator0[0],\n True,\n reduced0[0],\n thread,\n dtype="handle",\n )\n )\n with T.attr(\n T.comm_reducer(\n lambda left, right: left + right,\n [T.cast(0, "float32")],\n ),\n "reduce_scope",\n T.reinterpret(T.uint64(0), dtype="handle"),\n ):\n T.evaluate(\n T.tvm_thread_allreduce(\n T.uint32(1),\n accumulator1[0],\n True,\n reduced1[0],\n thread,\n dtype="handle",\n )\n )\n if thread == 0:\n output[row] = T.cast(reduced0[0], input_dtype)\n output[row + 1] = T.cast(reduced1[0], input_dtype)\n if clear_input_sized_output and row < input_rows:\n clear_output[row] = T.cast(0.0, input_dtype)\n clear_output[row + 1] = T.cast(0.0, input_dtype)\n\n return kernel\n\n\n@lru_cache(maxsize=32)\ndef _compiled_gemv(\n input_rows: int,\n output_rows: int,\n input_dtype: str,\n out_tile: int,\n reduce_threads: int,\n clear_input_sized_output: bool,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n _build_gemv_program(\n input_rows,\n output_rows,\n input_dtype,\n out_tile,\n reduce_threads,\n clear_input_sized_output,\n ),\n out_idx=[],\n execution_backend="auto",\n )\n\ndef _build_ffn_program(\n channels: int,\n ffn_rows: int,\n block_rows: int = 2,\n reduce_threads: int = 64,\n input_dtype: str = "float16",\n):\n """Build B1T1 FFN key GEMV fused with ReLU-square."""\n if channels <= 0 or ffn_rows <= 0 or ffn_rows % block_rows:\n raise ValueError("dimensions must be positive and rows divisible by block_rows")\n if input_dtype not in {"float16", "bfloat16"}:\n raise ValueError("FFN dtype must be float16 or bfloat16")\n vector_width = 8\n block_k = reduce_threads * vector_width\n if channels % block_k:\n raise ValueError("channels must be divisible by reduce_threads * 8")\n\n import tilelang.language as T # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n mixed: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n weight: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (ffn_rows, channels), input_dtype\n ),\n output: T.Tensor((ffn_rows,), input_dtype), # type: ignore[reportInvalidTypeForm]\n ):\n with T.Kernel(\n ffn_rows // block_rows,\n threads=(block_rows, reduce_threads),\n ) as block:\n row_lane = T.get_thread_binding(0)\n reduce_lane = T.get_thread_binding(1)\n row = block * block_rows + row_lane\n mixed_local = T.alloc_local((vector_width,), input_dtype)\n weight_local = T.alloc_local((vector_width,), input_dtype)\n accumulator = T.alloc_local((1,), "float32")\n reduced = T.alloc_local((1,), "float32")\n T.clear(accumulator)\n for chunk in T.serial(channels // block_k):\n for lane in T.vectorized(vector_width):\n column = (\n chunk * block_k\n + reduce_lane * vector_width\n + lane\n )\n mixed_local[lane] = mixed[column]\n weight_local[lane] = weight[row, column]\n for lane in T.serial(vector_width):\n accumulator[0] += T.cast(\n mixed_local[lane], "float32"\n ) * T.cast(weight_local[lane], "float32")\n with T.attr(\n T.comm_reducer(\n lambda left, right: left + right,\n [T.cast(0, "float32")],\n ),\n "reduce_scope",\n T.reinterpret(T.uint64(0), dtype="handle"),\n ):\n T.evaluate(\n T.tvm_thread_allreduce(\n T.uint32(1),\n accumulator[0],\n True,\n reduced[0],\n reduce_lane,\n dtype="handle",\n )\n )\n if reduce_lane == 0:\n projected = T.cast(reduced[0], input_dtype)\n activated = T.max(projected, T.cast(0, input_dtype))\n output[row] = T.cast(activated * activated, input_dtype)\n\n return kernel\n\n\n@lru_cache(maxsize=32)\ndef _compiled_ffn(\n channels: int,\n ffn_rows: int,\n block_rows: int,\n reduce_threads: int,\n input_dtype: str,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n _build_ffn_program(\n channels, ffn_rows, block_rows, reduce_threads, input_dtype\n ),\n out_idx=[],\n execution_backend="auto",\n )\n\n\ndef _build_tmix_layernorm_mix6_program(\n channels: int,\n input_dtype: str = "float16",\n epsilon: float = 1e-5,\n threads: int = 256,\n):\n """Build fused LayerNorm and six shifted time-mix vectors."""\n if channels <= 0 or channels % threads:\n raise ValueError("channels must be divisible by LayerNorm threads")\n if input_dtype not in {"float16", "bfloat16"}:\n raise ValueError("time-mix dtype must be float16 or bfloat16")\n\n import tilelang.language as T # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n residual: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n previous: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n norm_weight: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n norm_bias: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n mix_weights: T.Tensor((6, channels), input_dtype), # type: ignore[reportInvalidTypeForm]\n normalized: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n mixed: T.Tensor((6, channels), input_dtype), # type: ignore[reportInvalidTypeForm]\n ):\n with T.Kernel(1, threads=threads):\n thread = T.get_thread_binding(0)\n local_sum = T.alloc_local((1,), "float32")\n local_square = T.alloc_local((1,), "float32")\n reduced_sum = T.alloc_local((1,), "float32")\n reduced_square = T.alloc_local((1,), "float32")\n T.clear(local_sum)\n T.clear(local_square)\n for chunk in T.serial(channels // threads):\n channel = chunk * threads + thread\n value = T.cast(residual[channel], "float32")\n local_sum[0] += value\n local_square[0] += value * value\n with T.attr(\n T.comm_reducer(\n lambda left, right: left + right,\n [T.cast(0, "float32")],\n ),\n "reduce_scope",\n T.reinterpret(T.uint64(0), dtype="handle"),\n ):\n T.evaluate(\n T.tvm_thread_allreduce(\n T.uint32(1),\n local_sum[0],\n True,\n reduced_sum[0],\n thread,\n dtype="handle",\n )\n )\n with T.attr(\n T.comm_reducer(\n lambda left, right: left + right,\n [T.cast(0, "float32")],\n ),\n "reduce_scope",\n T.reinterpret(T.uint64(0), dtype="handle"),\n ):\n T.evaluate(\n T.tvm_thread_allreduce(\n T.uint32(1),\n local_square[0],\n True,\n reduced_square[0],\n thread,\n dtype="handle",\n )\n )\n mean = reduced_sum[0] / channels\n variance = T.max(\n reduced_square[0] / channels - mean * mean, 0.0\n )\n inverse_std = 1.0 / T.sqrt(variance + epsilon)\n for chunk in T.serial(channels // threads):\n channel = chunk * threads + thread\n current = T.cast(\n (\n (T.cast(residual[channel], "float32") - mean)\n * inverse_std\n * T.cast(norm_weight[channel], "float32")\n + T.cast(norm_bias[channel], "float32")\n ),\n input_dtype,\n )\n previous_value = previous[channel]\n normalized[channel] = current\n delta = T.cast(previous_value - current, input_dtype)\n for stream in T.serial(6):\n mixed[stream, channel] = T.cast(\n current + delta * mix_weights[stream, channel],\n input_dtype,\n )\n\n return kernel\n\n\n@lru_cache(maxsize=32)\ndef _compiled_tmix_layernorm_mix6(\n channels: int,\n input_dtype: str,\n epsilon: float,\n threads: int,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n _build_tmix_layernorm_mix6_program(\n channels, input_dtype, epsilon, threads\n ),\n out_idx=[],\n execution_backend="auto",\n )\n\ndef _build_cmix_layernorm_mix_program(\n channels: int,\n input_dtype: str = "float16",\n epsilon: float = 1e-5,\n threads: int = 256,\n):\n """Build fused final residual LayerNorm and channel-mix input."""\n if channels <= 0 or channels % threads:\n raise ValueError("channels must be divisible by LayerNorm threads")\n if input_dtype not in {"float16", "bfloat16"}:\n raise ValueError("channel-mix dtype must be float16 or bfloat16")\n\n import tilelang.language as T # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n residual: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n previous: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n norm_weight: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n norm_bias: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n mix_weight: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n normalized: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n mixed: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n ):\n with T.Kernel(1, threads=threads):\n thread = T.get_thread_binding(0)\n local_sum = T.alloc_local((1,), "float32")\n local_square = T.alloc_local((1,), "float32")\n reduced_sum = T.alloc_local((1,), "float32")\n reduced_square = T.alloc_local((1,), "float32")\n T.clear(local_sum)\n T.clear(local_square)\n for chunk in T.serial(channels // threads):\n channel = chunk * threads + thread\n value = T.cast(residual[channel], "float32")\n local_sum[0] += value\n local_square[0] += value * value\n with T.attr(\n T.comm_reducer(\n lambda left, right: left + right,\n [T.cast(0, "float32")],\n ),\n "reduce_scope",\n T.reinterpret(T.uint64(0), dtype="handle"),\n ):\n T.evaluate(\n T.tvm_thread_allreduce(\n T.uint32(1),\n local_sum[0],\n True,\n reduced_sum[0],\n thread,\n dtype="handle",\n )\n )\n with T.attr(\n T.comm_reducer(\n lambda left, right: left + right,\n [T.cast(0, "float32")],\n ),\n "reduce_scope",\n T.reinterpret(T.uint64(0), dtype="handle"),\n ):\n T.evaluate(\n T.tvm_thread_allreduce(\n T.uint32(1),\n local_square[0],\n True,\n reduced_square[0],\n thread,\n dtype="handle",\n )\n )\n mean = reduced_sum[0] / channels\n variance = T.max(\n reduced_square[0] / channels - mean * mean, 0.0\n )\n inverse_std = 1.0 / T.sqrt(variance + epsilon)\n for chunk in T.serial(channels // threads):\n channel = chunk * threads + thread\n current = T.cast(\n (\n (T.cast(residual[channel], "float32") - mean)\n * inverse_std\n * T.cast(norm_weight[channel], "float32")\n + T.cast(norm_bias[channel], "float32")\n ),\n input_dtype,\n )\n normalized[channel] = current\n delta = T.cast(previous[channel] - current, input_dtype)\n mixed[channel] = T.cast(\n current + delta * mix_weight[channel], input_dtype\n )\n\n return kernel\n\n\ndef _build_cmix_add_layernorm_mix_program(\n channels: int,\n input_dtype: str = "float16",\n epsilon: float = 1e-5,\n threads: int = 256,\n):\n """Build fused residual add, LayerNorm, and channel-mix input."""\n if channels <= 0 or channels % threads:\n raise ValueError("channels must be divisible by LayerNorm threads")\n if input_dtype not in {"float16", "bfloat16"}:\n raise ValueError("channel-mix dtype must be float16 or bfloat16")\n\n import tilelang.language as T # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n residual: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n update: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n previous: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n norm_weight: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n norm_bias: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n mix_weight: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n combined: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n normalized: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n mixed: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n ):\n with T.Kernel(1, threads=threads):\n thread = T.get_thread_binding(0)\n local_sum = T.alloc_local((1,), "float32")\n local_square = T.alloc_local((1,), "float32")\n reduced_sum = T.alloc_local((1,), "float32")\n reduced_square = T.alloc_local((1,), "float32")\n T.clear(local_sum)\n T.clear(local_square)\n for chunk in T.serial(channels // threads):\n channel = chunk * threads + thread\n value_f16 = T.cast(\n residual[channel] + update[channel], input_dtype\n )\n combined[channel] = value_f16\n value = T.cast(value_f16, "float32")\n local_sum[0] += value\n local_square[0] += value * value\n with T.attr(\n T.comm_reducer(\n lambda left, right: left + right,\n [T.cast(0, "float32")],\n ),\n "reduce_scope",\n T.reinterpret(T.uint64(0), dtype="handle"),\n ):\n T.evaluate(\n T.tvm_thread_allreduce(\n T.uint32(1),\n local_sum[0],\n True,\n reduced_sum[0],\n thread,\n dtype="handle",\n )\n )\n with T.attr(\n T.comm_reducer(\n lambda left, right: left + right,\n [T.cast(0, "float32")],\n ),\n "reduce_scope",\n T.reinterpret(T.uint64(0), dtype="handle"),\n ):\n T.evaluate(\n T.tvm_thread_allreduce(\n T.uint32(1),\n local_square[0],\n True,\n reduced_square[0],\n thread,\n dtype="handle",\n )\n )\n mean = reduced_sum[0] / channels\n variance = T.max(\n reduced_square[0] / channels - mean * mean, 0.0\n )\n inverse_std = 1.0 / T.sqrt(variance + epsilon)\n for chunk in T.serial(channels // threads):\n channel = chunk * threads + thread\n current = T.cast(\n (\n (T.cast(combined[channel], "float32") - mean)\n * inverse_std\n * T.cast(norm_weight[channel], "float32")\n + T.cast(norm_bias[channel], "float32")\n ),\n input_dtype,\n )\n previous_value = previous[channel]\n normalized[channel] = current\n delta = T.cast(previous_value - current, input_dtype)\n mixed[channel] = T.cast(\n current + delta * mix_weight[channel], input_dtype\n )\n\n return kernel\n\n\n@lru_cache(maxsize=32)\ndef _compiled_cmix_add_layernorm_mix(\n channels: int,\n input_dtype: str,\n epsilon: float,\n threads: int,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n _build_cmix_add_layernorm_mix_program(\n channels, input_dtype, epsilon, threads\n ),\n out_idx=[],\n execution_backend="auto",\n )\n\n\n@lru_cache(maxsize=32)\ndef _compiled_cmix_layernorm_mix(\n channels: int,\n input_dtype: str,\n epsilon: float,\n threads: int,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n _build_cmix_layernorm_mix_program(\n channels, input_dtype, epsilon, threads\n ),\n out_idx=[],\n execution_backend="auto",\n )\n\n\ndef _dtype_name(dtype: torch.dtype) -> str:\n if dtype == torch.float16:\n return "float16"\n if dtype == torch.bfloat16:\n return "bfloat16"\n raise TypeError("TileLang decode tensors must use float16 or bfloat16")\n\n\ndef _require_contiguous_cuda(\n tensors: tuple[torch.Tensor, ...], name: str\n) -> str:\n if torch.is_grad_enabled() and any(\n tensor.requires_grad for tensor in tensors\n ):\n raise RuntimeError(f"TileLang {name} is inference-only")\n if any(tensor.device.type != "cuda" for tensor in tensors):\n raise RuntimeError(f"TileLang {name} requires CUDA tensors")\n dtype = tensors[0].dtype\n input_dtype = _dtype_name(dtype)\n if any(tensor.dtype != dtype for tensor in tensors):\n raise TypeError(f"TileLang {name} tensors must share one dtype")\n if any(not tensor.is_contiguous() for tensor in tensors):\n raise ValueError(f"TileLang {name} requires contiguous tensors")\n if len({tensor.device for tensor in tensors}) != 1:\n raise ValueError(f"TileLang {name} tensors must share a device")\n return input_dtype\n\n\ndef _ffn_out(\n mixed: torch.Tensor,\n weight: torch.Tensor,\n output: torch.Tensor,\n *,\n block_rows: int = 1,\n reduce_threads: int = 128,\n) -> None:\n """Run FFN key projection and ReLU-square into caller-owned output."""\n input_dtype = _require_contiguous_cuda(\n (mixed, weight, output), "FFN key"\n )\n if mixed.dim() != 1 or weight.dim() != 2:\n raise ValueError("FFN key expects mixed [C] and weight [F,C]")\n channels = mixed.numel()\n ffn_rows = weight.size(0)\n if weight.size(1) != channels or tuple(output.shape) != (ffn_rows,):\n raise ValueError("FFN key weight/output shape mismatch")\n kernel: Any = _compiled_ffn(\n channels,\n ffn_rows,\n block_rows,\n reduce_threads,\n input_dtype,\n cuda_arch_key(mixed.device),\n )\n kernel(mixed, weight, output)\n\n\ndef _build_cmix_value_program(\n channels: int,\n ffn_rows: int,\n input_dtype: str = "float16",\n block_rows: int = 64,\n reduce_threads: int = 8,\n):\n """Build sparse FFN value projection over transposed packed weights."""\n if channels <= 0 or ffn_rows <= 0:\n raise ValueError("dimensions must be positive")\n if channels % block_rows or ffn_rows % reduce_threads:\n raise ValueError("dimensions must divide block and reduction sizes")\n if input_dtype not in {"float16", "bfloat16"}:\n raise ValueError("FFN dtype must be float16 or bfloat16")\n\n import tilelang.language as T # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n hidden: T.Tensor((ffn_rows,), input_dtype), # type: ignore[reportInvalidTypeForm]\n weight: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (ffn_rows, channels), input_dtype\n ),\n output: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n ):\n with T.Kernel(\n channels // block_rows,\n threads=(reduce_threads, block_rows),\n ) as block:\n reduce_lane = T.get_thread_binding(0)\n output_lane = T.get_thread_binding(1)\n row = block * block_rows + output_lane\n accumulator = T.alloc_local((1,), "float32")\n reduced = T.alloc_local((1,), "float32")\n T.clear(accumulator)\n for chunk in T.serial(ffn_rows // reduce_threads):\n hidden_row = chunk * reduce_threads + reduce_lane\n activation = hidden[hidden_row]\n if activation != T.cast(0, input_dtype):\n accumulator[0] += T.cast(\n activation, "float32"\n ) * T.cast(weight[hidden_row, row], "float32")\n with T.attr(\n T.comm_reducer(\n lambda left, right: left + right,\n [T.cast(0, "float32")],\n ),\n "reduce_scope",\n T.reinterpret(T.uint64(0), dtype="handle"),\n ):\n T.evaluate(\n T.tvm_thread_allreduce(\n T.uint32(1),\n accumulator[0],\n True,\n reduced[0],\n reduce_lane,\n dtype="handle",\n )\n )\n if reduce_lane == 0:\n output[row] = T.cast(reduced[0], input_dtype)\n\n return kernel\n\n\n@lru_cache(maxsize=32)\ndef _compiled_cmix_value(\n channels: int,\n ffn_rows: int,\n input_dtype: str,\n block_rows: int,\n reduce_threads: int,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n _build_cmix_value_program(\n channels, ffn_rows, input_dtype, block_rows, reduce_threads\n ),\n out_idx=[],\n execution_backend="auto",\n )\n\n\ndef _build_cmix_sparse_atomic_program(\n channels: int,\n ffn_rows: int,\n input_dtype: str = "float16",\n ffn_tile: int = 128,\n threads: int = 128,\n):\n """Build tiled exact-zero FFN down projection with FP16 atomics."""\n output_tile = threads * 2\n if (\n channels <= 0\n or ffn_rows <= 0\n or ffn_rows % ffn_tile\n or channels % output_tile\n ):\n raise ValueError("FFN dimensions must divide sparse tiles")\n if input_dtype != "float16":\n raise ValueError("atomic sparse FFN currently requires float16")\n\n import tilelang.language as T # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n hidden: T.Tensor((ffn_rows,), input_dtype), # type: ignore[reportInvalidTypeForm]\n weight: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (ffn_rows, channels), input_dtype\n ),\n output: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n ):\n with T.Kernel(\n ffn_rows // ffn_tile,\n channels // output_tile,\n threads=threads,\n ) as (ffn_block, channel_block):\n thread = T.get_thread_binding(0)\n activation_shared = T.alloc_shared((ffn_tile,), input_dtype)\n nonzero_ids = T.alloc_shared((ffn_tile,), "int32")\n nonzero_count = T.alloc_shared((1,), "int32")\n warp_counts = T.alloc_shared((ffn_tile // 32,), "int32")\n warp_prefix = T.alloc_shared((ffn_tile // 32,), "int32")\n accumulators = T.alloc_local((2,), input_dtype)\n ffn_row = ffn_block * ffn_tile + thread\n preactivation = T.cast(hidden[ffn_row], "float32")\n activated = T.max(preactivation, 0.0)\n activation_shared[thread] = T.cast(\n activated * activated, input_dtype\n )\n if thread == 0:\n nonzero_count[0] = 0\n T.sync_threads()\n lane = thread % 32\n warp = thread // 32\n nonzero = activation_shared[thread] != T.cast(0, input_dtype)\n mask = T.ballot_sync(nonzero)\n local_position = T.popcount(\n mask & ((T.uint32(1) << lane) - T.uint32(1))\n )\n if lane == 0:\n warp_counts[warp] = T.popcount(mask)\n T.sync_threads()\n if thread == 0:\n for warp_index in T.serial(ffn_tile // 32):\n warp_prefix[warp_index] = nonzero_count[0]\n nonzero_count[0] += warp_counts[warp_index]\n T.sync_threads()\n if nonzero:\n nonzero_ids[warp_prefix[warp] + local_position] = thread\n T.sync_threads()\n T.clear(accumulators)\n for index in T.serial(ffn_tile):\n if index < nonzero_count[0]:\n local_row = nonzero_ids[index]\n actual_row = ffn_block * ffn_tile + local_row\n activation = activation_shared[local_row]\n for pair_lane in T.serial(2):\n channel = (\n channel_block * output_tile\n + thread * 2\n + pair_lane\n )\n accumulators[pair_lane] = T.cast(\n activation * weight[actual_row, channel]\n + accumulators[pair_lane],\n input_dtype,\n )\n channel = channel_block * output_tile + thread * 2\n T.atomic_addx2(\n output[channel : channel + 2], accumulators[0:2]\n )\n\n return kernel\n\n\n@lru_cache(maxsize=16)\ndef _compiled_cmix_sparse_atomic(\n channels: int,\n ffn_rows: int,\n input_dtype: str,\n ffn_tile: int,\n threads: int,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n _build_cmix_sparse_atomic_program(\n channels,\n ffn_rows,\n input_dtype,\n ffn_tile,\n threads,\n ),\n out_idx=[],\n execution_backend="auto",\n )\n\n\ndef _build_cmix_sparse_binned_program(\n channels: int,\n ffn_rows: int,\n input_dtype: str = "float16",\n ffn_tile: int = 128,\n threads: int = 128,\n exponent_bins: int = 6,\n):\n """Build deterministic exponent-binned exact-zero FFN accumulation."""\n output_tile = threads * 4\n if (\n channels <= 0\n or ffn_rows <= 0\n or ffn_rows % ffn_tile\n or channels % output_tile\n or exponent_bins != 6\n ):\n raise ValueError("binned FFN dimensions must divide sparse tiles")\n if input_dtype != "float16":\n raise ValueError("binned sparse FFN currently requires float16")\n\n import tilelang.language as T # type: ignore[import-not-found]\n from tvm.tirx import op as tirx_op # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n hidden: T.Tensor((ffn_rows,), input_dtype), # type: ignore[reportInvalidTypeForm]\n weight: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (ffn_rows, channels), input_dtype\n ),\n output: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (exponent_bins, channels), "float32"\n ),\n ):\n with T.Kernel(\n ffn_rows // ffn_tile,\n channels // output_tile,\n threads=threads,\n ) as (ffn_block, channel_block):\n thread = T.get_thread_binding(0)\n activation_shared = T.alloc_shared((ffn_tile,), input_dtype)\n nonzero_ids = T.alloc_shared((ffn_tile,), "int32")\n nonzero_count = T.alloc_shared((1,), "int32")\n warp_counts = T.alloc_shared((ffn_tile // 32,), "int32")\n warp_prefix = T.alloc_shared((ffn_tile // 32,), "int32")\n accumulators = T.alloc_local((4,), input_dtype)\n accumulator_bins = T.alloc_local((4,), "int32")\n remaining_bins = T.alloc_local((4,), "int32")\n vector_values = T.alloc_local((4,), "float32")\n ffn_row = ffn_block * ffn_tile + thread\n preactivation = T.cast(hidden[ffn_row], "float32")\n activated = T.max(preactivation, 0.0)\n activation_shared[thread] = T.cast(\n activated * activated, input_dtype\n )\n if thread == 0:\n nonzero_count[0] = 0\n T.sync_threads()\n lane = thread % 32\n warp = thread // 32\n nonzero = activation_shared[thread] != T.cast(0, input_dtype)\n mask = T.ballot_sync(nonzero)\n local_position = T.popcount(\n mask & ((T.uint32(1) << lane) - T.uint32(1))\n )\n if lane == 0:\n warp_counts[warp] = T.popcount(mask)\n T.sync_threads()\n if thread == 0:\n for warp_index in T.serial(ffn_tile // 32):\n warp_prefix[warp_index] = nonzero_count[0]\n nonzero_count[0] += warp_counts[warp_index]\n T.sync_threads()\n if nonzero:\n nonzero_ids[warp_prefix[warp] + local_position] = thread\n T.sync_threads()\n T.clear(accumulators)\n for index in T.serial(ffn_tile):\n if index < nonzero_count[0]:\n local_row = nonzero_ids[index]\n actual_row = ffn_block * ffn_tile + local_row\n activation = activation_shared[local_row]\n for output_lane in T.serial(4):\n channel = (\n channel_block * output_tile\n + thread * 4\n + output_lane\n )\n accumulators[output_lane] = T.cast(\n activation * weight[actual_row, channel]\n + accumulators[output_lane],\n input_dtype,\n )\n channel = channel_block * output_tile + thread * 4\n for output_lane in T.serial(4):\n value = accumulators[output_lane]\n bits = T.reinterpret(value, "uint16")\n exponent = T.cast(\n T.bitwise_and(T.shift_right(bits, 10), 31),\n "int32",\n )\n accumulator_bins[output_lane] = T.if_then_else(\n exponent == 0,\n 0,\n T.min(1 + (exponent - 1) // 6, exponent_bins - 1),\n )\n common_bin = T.max(\n T.max(accumulator_bins[0], accumulator_bins[1]),\n T.max(accumulator_bins[2], accumulator_bins[3]),\n )\n for output_lane in T.serial(4):\n vector_values[output_lane] = T.if_then_else(\n accumulator_bins[output_lane] == common_bin,\n T.cast(accumulators[output_lane], "float32"),\n 0.0,\n )\n T.call_intrin(\n "float4",\n tirx_op.Op.get("tl.atomic_addx4_elem_op"),\n T.access_ptr(\n output[common_bin, channel : channel + 4], "rw"\n ),\n T.access_ptr(vector_values[0:4], "r"),\n )\n for output_lane in T.serial(4):\n remaining_bins[output_lane] = T.if_then_else(\n accumulator_bins[output_lane] != common_bin\n and accumulators[output_lane] != T.cast(0, input_dtype),\n accumulator_bins[output_lane],\n -1,\n )\n second_bin = T.max(\n T.max(remaining_bins[0], remaining_bins[1]),\n T.max(remaining_bins[2], remaining_bins[3]),\n )\n if second_bin >= 0:\n for output_lane in T.serial(4):\n vector_values[output_lane] = T.if_then_else(\n accumulator_bins[output_lane] == second_bin,\n T.cast(accumulators[output_lane], "float32"),\n 0.0,\n )\n T.call_intrin(\n "float4",\n tirx_op.Op.get("tl.atomic_addx4_elem_op"),\n T.access_ptr(\n output[second_bin, channel : channel + 4], "rw"\n ),\n T.access_ptr(vector_values[0:4], "r"),\n )\n for output_lane in T.serial(4):\n if (\n accumulator_bins[output_lane] != common_bin\n and accumulator_bins[output_lane] != second_bin\n and accumulators[output_lane] != T.cast(0, input_dtype)\n ):\n T.atomic_add(\n output[accumulator_bins[output_lane], channel + output_lane],\n T.cast(accumulators[output_lane], "float32"),\n )\n return kernel\n\n\n@lru_cache(maxsize=16)\ndef _compiled_cmix_sparse_binned(\n channels: int,\n ffn_rows: int,\n input_dtype: str,\n ffn_tile: int,\n threads: int,\n exponent_bins: int,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n _build_cmix_sparse_binned_program(\n channels,\n ffn_rows,\n input_dtype,\n ffn_tile,\n threads,\n exponent_bins,\n ),\n out_idx=[],\n execution_backend="auto",\n )\n\n\ndef _build_cmix_binned_finalize_program(\n channels: int,\n exponent_bins: int = 6,\n input_dtype: str = "float16",\n threads: int = 256,\n):\n """Build fixed-order bin reduction plus FP16 residual finalization."""\n if channels <= 0 or channels % threads or exponent_bins != 6:\n raise ValueError("binned finalization dimensions are unsupported")\n if input_dtype != "float16":\n raise ValueError("binned finalization currently requires float16")\n\n import tilelang.language as T # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n bins: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (exponent_bins, channels), "float32"\n ),\n residual: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n output: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n ):\n with T.Kernel(channels // threads, threads=threads) as block:\n channel = block * threads + T.get_thread_binding(0)\n total = T.alloc_local((1,), input_dtype)\n total[0] = T.cast(bins[0, channel], input_dtype)\n bins[0, channel] = 0.0\n for exponent in T.serial(1, exponent_bins):\n total[0] = T.cast(\n total[0] + T.cast(bins[exponent, channel], input_dtype),\n input_dtype,\n )\n bins[exponent, channel] = 0.0\n contribution = total[0]\n output[channel] = T.cast(\n residual[channel] + contribution, input_dtype\n )\n\n return kernel\n\n\n@lru_cache(maxsize=16)\ndef _compiled_cmix_binned_finalize(\n channels: int,\n exponent_bins: int,\n input_dtype: str,\n threads: int,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n _build_cmix_binned_finalize_program(\n channels, exponent_bins, input_dtype, threads\n ),\n out_idx=[],\n execution_backend="auto",\n )\n\ndef _build_cmix_sparse_split_program(\n channels: int,\n ffn_rows: int,\n input_dtype: str = "float16",\n ffn_tile: int = 128,\n threads: int = 128,\n splits: int = 8,\n):\n """Build split exact-zero FFN down projection without global atomics."""\n output_tile = threads * 2\n if (\n channels <= 0\n or ffn_rows <= 0\n or ffn_rows % (ffn_tile * splits)\n or channels % output_tile\n or input_dtype != "float16"\n ):\n raise ValueError("FP16 sparse split dimensions must divide tiles")\n\n import tilelang.language as T # type: ignore[import-not-found]\n\n\n @T.prim_func\n def kernel(\n hidden: T.Tensor((ffn_rows,), input_dtype), # type: ignore[reportInvalidTypeForm]\n weight: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (ffn_rows, channels), input_dtype\n ),\n partials: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (splits, channels), input_dtype\n ),\n ):\n with T.Kernel(\n splits,\n channels // output_tile,\n threads=threads,\n ) as (split, channel_block):\n thread = T.get_thread_binding(0)\n activation_shared = T.alloc_shared((ffn_tile,), input_dtype)\n nonzero_ids = T.alloc_shared((ffn_tile,), "int32")\n nonzero_count = T.alloc_shared((1,), "int32")\n warp_counts = T.alloc_shared((ffn_tile // 32,), "int32")\n warp_prefix = T.alloc_shared((ffn_tile // 32,), "int32")\n accumulators = T.alloc_local((2,), input_dtype)\n tile_accumulators = T.alloc_local((2,), input_dtype)\n T.clear(accumulators)\n\n for local_tile in T.serial(\n ffn_rows // (ffn_tile * splits)\n ):\n ffn_block = (\n split * (ffn_rows // (ffn_tile * splits)) + local_tile\n )\n ffn_row = ffn_block * ffn_tile + thread\n preactivation = T.cast(hidden[ffn_row], "float32")\n activated = T.max(preactivation, 0.0)\n activation_shared[thread] = T.cast(\n activated * activated, input_dtype\n )\n if thread == 0:\n nonzero_count[0] = 0\n T.sync_threads()\n lane = thread % 32\n warp = thread // 32\n nonzero = activation_shared[thread] != T.cast(0, input_dtype)\n mask = T.ballot_sync(nonzero)\n local_position = T.popcount(\n mask & ((T.uint32(1) << lane) - T.uint32(1))\n )\n if lane == 0:\n warp_counts[warp] = T.popcount(mask)\n T.sync_threads()\n if thread == 0:\n for warp_index in T.serial(ffn_tile // 32):\n warp_prefix[warp_index] = nonzero_count[0]\n nonzero_count[0] += warp_counts[warp_index]\n T.sync_threads()\n if nonzero:\n nonzero_ids[warp_prefix[warp] + local_position] = thread\n T.sync_threads()\n T.clear(tile_accumulators)\n for index in T.serial(ffn_tile):\n if index < nonzero_count[0]:\n local_row = nonzero_ids[index]\n actual_row = ffn_block * ffn_tile + local_row\n activation = activation_shared[local_row]\n for pair_lane in T.serial(2):\n channel = (\n channel_block * output_tile\n + thread * 2\n + pair_lane\n )\n tile_accumulators[pair_lane] = T.cast(\n activation * weight[actual_row, channel]\n + tile_accumulators[pair_lane],\n input_dtype,\n )\n for pair_lane in T.serial(2):\n accumulators[pair_lane] = T.cast(\n accumulators[pair_lane]\n + tile_accumulators[pair_lane],\n input_dtype,\n )\n T.sync_threads()\n\n channel = channel_block * output_tile + thread * 2\n partials[split, channel] = accumulators[0]\n partials[split, channel + 1] = accumulators[1]\n\n return kernel\n\n\n@lru_cache(maxsize=16)\ndef _compiled_cmix_sparse_split(\n channels: int,\n ffn_rows: int,\n input_dtype: str,\n ffn_tile: int,\n threads: int,\n splits: int,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n _build_cmix_sparse_split_program(\n channels,\n ffn_rows,\n input_dtype,\n ffn_tile,\n threads,\n splits,\n ),\n out_idx=[],\n execution_backend="auto",\n )\n\ndef _build_cmix_finalize_program(\n channels: int, splits: int, input_dtype: str = "float16"\n):\n """Build deterministic split-output finalization."""\n if channels <= 0 or channels % 256 or splits <= 0:\n raise ValueError("channels must be positive and divisible by 256")\n if input_dtype not in {"float16", "bfloat16"}:\n raise ValueError("FFN dtype must be float16 or bfloat16")\n\n import tilelang.language as T # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n partials: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (splits, channels), input_dtype\n ),\n output: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n ):\n with T.Kernel(channels // 256, threads=256) as block:\n row = block * 256 + T.get_thread_binding(0)\n value = T.alloc_local((1,), input_dtype)\n value[0] = partials[0, row]\n for split in T.serial(1, splits):\n value[0] = T.cast(\n value[0] + partials[split, row], input_dtype\n )\n output[row] = value[0]\n\n return kernel\n\n\n@lru_cache(maxsize=16)\ndef _compiled_cmix_finalize(\n channels: int, splits: int, input_dtype: str, device_arch: str\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n _build_cmix_finalize_program(channels, splits, input_dtype),\n out_idx=[],\n execution_backend="auto",\n )\n\n\ndef _cmix_value_out(\n hidden: torch.Tensor,\n weight: torch.Tensor,\n partials: torch.Tensor,\n output: torch.Tensor,\n *,\n splits: int = 4,\n block_rows: int = 64,\n reduce_threads: int = 8,\n) -> None:\n """Run sparse split FFN value projection with fixed graph workspaces."""\n input_dtype = _require_contiguous_cuda(\n (hidden, weight, partials, output), "FFN value"\n )\n if hidden.dim() != 1 or weight.dim() != 2:\n raise ValueError("FFN value expects hidden [F] and weight [F,C]")\n ffn_rows, channels = weight.shape\n if (\n hidden.numel() != ffn_rows\n or ffn_rows % splits\n or tuple(partials.shape) != (splits, channels)\n or tuple(output.shape) != (channels,)\n ):\n raise ValueError("FFN value split/workspace shape mismatch")\n split_rows = ffn_rows // splits\n kernel: Any = _compiled_cmix_value(\n channels,\n split_rows,\n input_dtype,\n block_rows,\n reduce_threads,\n cuda_arch_key(hidden.device),\n )\n for split in range(splits):\n start = split * split_rows\n stop = start + split_rows\n kernel(\n hidden[start:stop],\n weight[start:stop],\n partials[split],\n )\n finalize: Any = _compiled_cmix_finalize(\n channels, splits, input_dtype, cuda_arch_key(hidden.device)\n )\n finalize(partials, output)\n\n\ndef _build_rankout_program(\n channels: int,\n rank_w: int,\n rank_a: int,\n rank_g: int,\n rank_v: int,\n use_value_mix: bool,\n input_dtype: str = "float16",\n):\n """Build fused W/A/G/V rank-out with raw decay and pointwise gates."""\n if channels <= 0 or min(rank_w, rank_a, rank_g, rank_v) < 0:\n raise ValueError("rank-out dimensions must be non-negative")\n if channels % 256:\n raise ValueError("rank-out channels must be divisible by 256")\n if input_dtype not in {"float16", "bfloat16"}:\n raise ValueError("rank-out dtype must be float16 or bfloat16")\n\n import tilelang.language as T # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n decay_rank: T.Tensor((rank_w,), input_dtype), # type: ignore[reportInvalidTypeForm]\n a_rank: T.Tensor((rank_a,), input_dtype), # type: ignore[reportInvalidTypeForm]\n g_rank: T.Tensor((rank_g,), input_dtype), # type: ignore[reportInvalidTypeForm]\n value_rank: T.Tensor((rank_v,), input_dtype), # type: ignore[reportInvalidTypeForm]\n w2: T.Tensor((rank_w, channels), input_dtype), # type: ignore[reportInvalidTypeForm]\n a2: T.Tensor((rank_a, channels), input_dtype), # type: ignore[reportInvalidTypeForm]\n g2: T.Tensor((rank_g, channels), input_dtype), # type: ignore[reportInvalidTypeForm]\n v2: T.Tensor((rank_v, channels), input_dtype), # type: ignore[reportInvalidTypeForm]\n w0: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n a0: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n v0: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n value_base: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n first_value: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n decay: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n gate_a: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n gate_g: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n value: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n ):\n with T.Kernel(channels // 256, threads=256) as block:\n channel = block * 256 + T.get_thread_binding(0)\n decay_acc = T.alloc_local((1,), "float32")\n a_acc = T.alloc_local((1,), "float32")\n g_acc = T.alloc_local((1,), "float32")\n v_acc = T.alloc_local((1,), "float32")\n T.clear(decay_acc)\n T.clear(a_acc)\n T.clear(g_acc)\n T.clear(v_acc)\n for rank in T.serial(rank_w):\n transformed = T.cast(\n T.tanh(T.cast(decay_rank[rank], "float32")),\n input_dtype,\n )\n decay_acc[0] += T.cast(\n transformed, "float32"\n ) * T.cast(w2[rank, channel], "float32")\n for rank in T.serial(rank_a):\n a_acc[0] += T.cast(\n a_rank[rank], "float32"\n ) * T.cast(a2[rank, channel], "float32")\n for rank in T.serial(rank_g):\n transformed = T.cast(\n 1.0\n / (\n 1.0\n + T.exp(-T.cast(g_rank[rank], "float32"))\n ),\n input_dtype,\n )\n g_acc[0] += T.cast(\n transformed, "float32"\n ) * T.cast(g2[rank, channel], "float32")\n if use_value_mix:\n for rank in T.serial(rank_v):\n v_acc[0] += T.cast(\n value_rank[rank], "float32"\n ) * T.cast(v2[rank, channel], "float32")\n\n decay[channel] = T.cast(decay_acc[0], input_dtype)\n\n a_raw = T.cast(\n a0[channel] + T.cast(a_acc[0], input_dtype),\n input_dtype,\n )\n gate_a[channel] = T.cast(\n 1.0 / (1.0 + T.exp(-T.cast(a_raw, "float32"))),\n input_dtype,\n )\n gate_g[channel] = T.cast(g_acc[0], input_dtype)\n if use_value_mix:\n v_raw = T.cast(\n v0[channel] + T.cast(v_acc[0], input_dtype),\n input_dtype,\n )\n v_gate = T.cast(\n 1.0 / (1.0 + T.exp(-T.cast(v_raw, "float32"))),\n input_dtype,\n )\n delta = T.cast(\n first_value[channel] - value_base[channel],\n input_dtype,\n )\n value[channel] = T.cast(\n value_base[channel]\n + T.cast(delta * v_gate, input_dtype),\n input_dtype,\n )\n else:\n value[channel] = value_base[channel]\n\n return kernel\n\n\ndef _build_rankout_reduced_program(\n channels: int,\n rank_w: int,\n rank_a: int,\n rank_g: int,\n rank_v: int,\n use_value_mix: bool,\n input_dtype: str = "float16",\n out_tile: int = 4,\n reduce_threads: int = 128,\n):\n """Build rank-parallel W/A/G/V rank-out from transposed weights."""\n if channels <= 0 or channels % out_tile:\n raise ValueError("rank-out channels must be divisible by output tile")\n if min(rank_w, rank_a, rank_g, rank_v) < 0:\n raise ValueError("rank-out dimensions must be non-negative")\n if input_dtype not in {"float16", "bfloat16"}:\n raise ValueError("rank-out dtype must be float16 or bfloat16")\n if reduce_threads & (reduce_threads - 1):\n raise ValueError("rank-out reduction threads must be a power of two")\n\n import tilelang.language as T # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n decay_rank: T.Tensor((rank_w,), input_dtype), # type: ignore[reportInvalidTypeForm]\n a_rank: T.Tensor((rank_a,), input_dtype), # type: ignore[reportInvalidTypeForm]\n g_rank: T.Tensor((rank_g,), input_dtype), # type: ignore[reportInvalidTypeForm]\n value_rank: T.Tensor((rank_v,), input_dtype), # type: ignore[reportInvalidTypeForm]\n w2: T.Tensor((channels, rank_w), input_dtype), # type: ignore[reportInvalidTypeForm]\n a2: T.Tensor((channels, rank_a), input_dtype), # type: ignore[reportInvalidTypeForm]\n g2: T.Tensor((channels, rank_g), input_dtype), # type: ignore[reportInvalidTypeForm]\n v2: T.Tensor((channels, rank_v), input_dtype), # type: ignore[reportInvalidTypeForm]\n a0: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n v0: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n value_base: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n first_value: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n decay: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n gate_a: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n gate_g: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n value: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n ):\n with T.Kernel(\n channels // out_tile, threads=reduce_threads\n ) as block:\n thread = T.get_thread_binding(0)\n channel_start = block * out_tile\n accumulator = T.alloc_local((4, out_tile), "float32")\n partial = T.alloc_shared(\n (4, out_tile, reduce_threads), "float32"\n )\n T.clear(accumulator)\n\n for chunk in T.serial((rank_w + reduce_threads - 1) // reduce_threads):\n rank = chunk * reduce_threads + thread\n if rank < rank_w:\n rank_value = T.tanh(T.cast(decay_rank[rank], "float32"))\n for output_lane in T.serial(out_tile):\n accumulator[0, output_lane] += rank_value * T.cast(\n w2[channel_start + output_lane, rank], "float32"\n )\n for chunk in T.serial((rank_a + reduce_threads - 1) // reduce_threads):\n rank = chunk * reduce_threads + thread\n if rank < rank_a:\n rank_value = T.cast(a_rank[rank], "float32")\n for output_lane in T.serial(out_tile):\n accumulator[1, output_lane] += rank_value * T.cast(\n a2[channel_start + output_lane, rank], "float32"\n )\n for chunk in T.serial((rank_g + reduce_threads - 1) // reduce_threads):\n rank = chunk * reduce_threads + thread\n if rank < rank_g:\n rank_value = 1.0 / (\n 1.0 + T.exp(-T.cast(g_rank[rank], "float32"))\n )\n for output_lane in T.serial(out_tile):\n accumulator[2, output_lane] += rank_value * T.cast(\n g2[channel_start + output_lane, rank], "float32"\n )\n if use_value_mix:\n for chunk in T.serial(\n (rank_v + reduce_threads - 1) // reduce_threads\n ):\n rank = chunk * reduce_threads + thread\n if rank < rank_v:\n rank_value = T.cast(value_rank[rank], "float32")\n for output_lane in T.serial(out_tile):\n accumulator[3, output_lane] += rank_value * T.cast(\n v2[channel_start + output_lane, rank], "float32"\n )\n\n for role in T.serial(4):\n for output_lane in T.serial(out_tile):\n partial[role, output_lane, thread] = accumulator[\n role, output_lane\n ]\n T.sync_threads()\n for reduction_step in T.serial(7):\n stride = reduce_threads >> (reduction_step + 1)\n if thread < stride:\n for role in T.serial(4):\n for output_lane in T.serial(out_tile):\n partial[role, output_lane, thread] += partial[\n role, output_lane, thread + stride\n ]\n T.sync_threads()\n\n if thread == 0:\n for output_lane in T.serial(out_tile):\n channel = channel_start + output_lane\n decay[channel] = T.cast(\n partial[0, output_lane, 0], input_dtype\n )\n a_raw = T.cast(\n a0[channel]\n + T.cast(partial[1, output_lane, 0], input_dtype),\n input_dtype,\n )\n gate_a[channel] = T.cast(\n 1.0 / (1.0 + T.exp(-T.cast(a_raw, "float32"))),\n input_dtype,\n )\n gate_g[channel] = T.cast(\n partial[2, output_lane, 0], input_dtype\n )\n if use_value_mix:\n v_raw = T.cast(\n v0[channel]\n + T.cast(partial[3, output_lane, 0], input_dtype),\n input_dtype,\n )\n v_gate = T.cast(\n 1.0 / (1.0 + T.exp(-T.cast(v_raw, "float32"))),\n input_dtype,\n )\n delta = T.cast(\n first_value[channel] - value_base[channel],\n input_dtype,\n )\n value[channel] = T.cast(\n value_base[channel]\n + T.cast(delta * v_gate, input_dtype),\n input_dtype,\n )\n else:\n value[channel] = value_base[channel]\n\n return kernel\n\n\n@lru_cache(maxsize=32)\ndef _compiled_rankout_reduced(\n channels: int,\n rank_w: int,\n rank_a: int,\n rank_g: int,\n rank_v: int,\n use_value_mix: bool,\n input_dtype: str,\n out_tile: int,\n reduce_threads: int,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n _build_rankout_reduced_program(\n channels,\n rank_w,\n rank_a,\n rank_g,\n rank_v,\n use_value_mix,\n input_dtype,\n out_tile,\n reduce_threads,\n ),\n out_idx=[],\n execution_backend="auto",\n )\n\n@lru_cache(maxsize=32)\ndef _compiled_rankout(\n channels: int,\n rank_w: int,\n rank_a: int,\n rank_g: int,\n rank_v: int,\n use_value_mix: bool,\n input_dtype: str,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n _build_rankout_program(\n channels,\n rank_w,\n rank_a,\n rank_g,\n rank_v,\n use_value_mix,\n input_dtype,\n ),\n out_idx=[],\n execution_backend="auto",\n )\n\n\ndef _rankout_out(\n ranks: tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor],\n weights: tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor],\n vectors: tuple[torch.Tensor, torch.Tensor, torch.Tensor],\n value_base: torch.Tensor,\n first_value: torch.Tensor,\n outputs: tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor],\n *,\n use_value_mix: bool,\n) -> None:\n """Run fused rank-out and pointwise finalization into fixed outputs."""\n tensors = (*ranks, *weights, *vectors, value_base, first_value, *outputs)\n input_dtype = _require_contiguous_cuda(tensors, "rank-out")\n channels = value_base.numel()\n rank_sizes = tuple(rank.numel() for rank in ranks)\n if any(tuple(rank.shape) != (size,) for rank, size in zip(ranks, rank_sizes)):\n raise ValueError("rank-out inputs must be one-dimensional")\n for weight, size in zip(weights, rank_sizes, strict=True):\n if tuple(weight.shape) != (size, channels):\n raise ValueError("rank-out weight shape mismatch")\n if any(tuple(vector.shape) != (channels,) for vector in vectors):\n raise ValueError("rank-out vectors must have shape [C]")\n if tuple(first_value.shape) != (channels,) or any(\n tuple(output.shape) != (channels,) for output in outputs\n ):\n raise ValueError("rank-out value/output shape mismatch")\n kernel: Any = _compiled_rankout(\n channels,\n *rank_sizes,\n use_value_mix,\n input_dtype,\n cuda_arch_key(value_base.device),\n )\n kernel(*ranks, *weights, *vectors, value_base, first_value, *outputs)\n\n\ndef _build_key_gate_program(\n num_heads: int,\n head_size: int = 64,\n input_dtype: str = "float16",\n):\n """Build fused per-head key normalization and recurrent gate vectors."""\n if num_heads <= 0 or head_size != 64:\n raise ValueError("key gate requires positive heads of size 64")\n if input_dtype not in {"float16", "bfloat16"}:\n raise ValueError("key gate dtype must be float16 or bfloat16")\n\n import tilelang.language as T # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n key: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (num_heads * head_size,), input_dtype\n ),\n key_scale: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (num_heads * head_size,), input_dtype\n ),\n gate_a: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (num_heads * head_size,), input_dtype\n ),\n gate_scale: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (num_heads * head_size,), input_dtype\n ),\n normalized: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (num_heads * head_size,), input_dtype\n ),\n modified: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (num_heads * head_size,), input_dtype\n ),\n anti_key: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (num_heads * head_size,), input_dtype\n ),\n anti_gate: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (num_heads * head_size,), input_dtype\n ),\n ):\n with T.Kernel(num_heads, threads=head_size) as head:\n lane = T.get_thread_binding(0)\n channel = head * head_size + lane\n local_square = T.alloc_local((1,), "float32")\n reduced_square = T.alloc_local((1,), "float32")\n scaled = T.cast(key[channel] * key_scale[channel], input_dtype)\n local_square[0] = T.cast(scaled, "float32") * T.cast(\n scaled, "float32"\n )\n with T.attr(\n T.comm_reducer(\n lambda left, right: left + right,\n [T.cast(0, "float32")],\n ),\n "reduce_scope",\n T.reinterpret(T.uint64(0), dtype="handle"),\n ):\n T.evaluate(\n T.tvm_thread_allreduce(\n T.uint32(1),\n local_square[0],\n True,\n reduced_square[0],\n lane,\n dtype="handle",\n )\n )\n norm = T.max(T.sqrt(reduced_square[0]), 1.0e-12)\n normalized_value = T.cast(\n T.cast(scaled, "float32") / norm, input_dtype\n )\n gate_delta = T.cast(gate_a[channel] - 1.0, input_dtype)\n gate_factor = T.cast(\n 1.0\n + T.cast(gate_delta * gate_scale[channel], input_dtype),\n input_dtype,\n )\n modified_value = T.cast(\n key[channel] * gate_factor, input_dtype\n )\n normalized[channel] = normalized_value\n modified[channel] = modified_value\n anti_key[channel] = T.cast(-normalized_value, input_dtype)\n anti_gate[channel] = T.cast(\n normalized_value * gate_a[channel], input_dtype\n )\n\n return kernel\n\n\n@lru_cache(maxsize=32)\ndef _compiled_key_gate(\n num_heads: int,\n head_size: int,\n input_dtype: str,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n _build_key_gate_program(num_heads, head_size, input_dtype),\n out_idx=[],\n execution_backend="auto",\n )\n\ndef _build_post_state_program(\n num_heads: int,\n head_size: int,\n input_dtype: str = "float16",\n epsilon: float = 6.4e-4,\n):\n """Build fused GroupNorm, RKV residual, and gate finalization."""\n if num_heads <= 0 or head_size <= 0 or head_size > 1024:\n raise ValueError("invalid post-state dimensions")\n if input_dtype not in {"float16", "bfloat16"}:\n raise ValueError("post-state dtype must be float16 or bfloat16")\n channels = num_heads * head_size\n\n import tilelang.language as T # type: ignore[import-not-found]\n\n @T.prim_func\n def kernel(\n projected: T.Tensor((num_heads, head_size), input_dtype), # type: ignore[reportInvalidTypeForm]\n receptance: T.Tensor((num_heads, head_size), input_dtype), # type: ignore[reportInvalidTypeForm]\n key: T.Tensor((num_heads, head_size), input_dtype), # type: ignore[reportInvalidTypeForm]\n value: T.Tensor((num_heads, head_size), input_dtype), # type: ignore[reportInvalidTypeForm]\n r_k: T.Tensor((num_heads, head_size), input_dtype), # type: ignore[reportInvalidTypeForm]\n gate: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n norm_weight: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n norm_bias: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n output: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n ):\n with T.Kernel(\n num_heads, threads=channels // num_heads\n ) as head:\n lane = T.get_thread_binding(0)\n channel = head * head_size + lane\n sample = T.cast(projected[head, lane], "float32")\n sample_sum = T.alloc_local((1,), "float32")\n square_sum = T.alloc_local((1,), "float32")\n rkv_sum = T.alloc_local((1,), "float32")\n reduced_sum = T.alloc_local((1,), "float32")\n reduced_square = T.alloc_local((1,), "float32")\n reduced_rkv = T.alloc_local((1,), "float32")\n sample_sum[0] = sample\n square_sum[0] = sample * sample\n rkv_sum[0] = (\n T.cast(receptance[head, lane], "float32")\n * T.cast(key[head, lane], "float32")\n * T.cast(r_k[head, lane], "float32")\n )\n with T.attr(\n T.comm_reducer(\n lambda left, right: left + right,\n [T.cast(0, "float32")],\n ),\n "reduce_scope",\n T.reinterpret(T.uint64(0), dtype="handle"),\n ):\n T.evaluate(\n T.tvm_thread_allreduce(\n T.uint32(1),\n sample_sum[0],\n True,\n reduced_sum[0],\n lane,\n dtype="handle",\n )\n )\n with T.attr(\n T.comm_reducer(\n lambda left, right: left + right,\n [T.cast(0, "float32")],\n ),\n "reduce_scope",\n T.reinterpret(T.uint64(0), dtype="handle"),\n ):\n T.evaluate(\n T.tvm_thread_allreduce(\n T.uint32(1),\n square_sum[0],\n True,\n reduced_square[0],\n lane,\n dtype="handle",\n )\n )\n with T.attr(\n T.comm_reducer(\n lambda left, right: left + right,\n [T.cast(0, "float32")],\n ),\n "reduce_scope",\n T.reinterpret(T.uint64(0), dtype="handle"),\n ):\n T.evaluate(\n T.tvm_thread_allreduce(\n T.uint32(1),\n rkv_sum[0],\n True,\n reduced_rkv[0],\n lane,\n dtype="handle",\n )\n )\n mean = reduced_sum[0] / head_size\n variance = T.max(\n reduced_square[0] / head_size - mean * mean, 0.0\n )\n normalized = (sample - mean) / T.sqrt(variance + epsilon)\n affine = (\n normalized * T.cast(norm_weight[channel], "float32")\n + T.cast(norm_bias[channel], "float32")\n )\n residual = reduced_rkv[0] * T.cast(\n value[head, lane], "float32"\n )\n output[channel] = T.cast(\n (affine + residual) * T.cast(gate[channel], "float32"),\n input_dtype,\n )\n\n return kernel\n\n\n@lru_cache(maxsize=32)\ndef _compiled_post_state(\n num_heads: int,\n head_size: int,\n input_dtype: str,\n epsilon: float,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n _build_post_state_program(\n num_heads, head_size, input_dtype, epsilon\n ),\n out_idx=[],\n execution_backend="auto",\n )\n\n\ndef _post_state_out(\n projected: torch.Tensor,\n receptance: torch.Tensor,\n key: torch.Tensor,\n value: torch.Tensor,\n r_k: torch.Tensor,\n gate: torch.Tensor,\n norm_weight: torch.Tensor,\n norm_bias: torch.Tensor,\n output: torch.Tensor,\n *,\n epsilon: float,\n) -> None:\n """Run fused post-state normalization and residual finalization."""\n tensors = (\n projected,\n receptance,\n key,\n value,\n r_k,\n gate,\n norm_weight,\n norm_bias,\n output,\n )\n input_dtype = _require_contiguous_cuda(tensors, "post-state")\n if projected.dim() != 2:\n raise ValueError("post-state projected input must have shape [H,N]")\n num_heads, head_size = projected.shape\n channels = num_heads * head_size\n if any(\n tuple(tensor.shape) != (num_heads, head_size)\n for tensor in (receptance, key, value, r_k)\n ):\n raise ValueError("post-state head tensor shape mismatch")\n if any(\n tuple(tensor.shape) != (channels,)\n for tensor in (gate, norm_weight, norm_bias, output)\n ):\n raise ValueError("post-state channel tensor shape mismatch")\n kernel: Any = _compiled_post_state(\n num_heads,\n head_size,\n input_dtype,\n epsilon,\n cuda_arch_key(projected.device),\n )\n kernel(*tensors)\n\n\ndef _build_rkv_program(\n channels: int,\n rank_w: int,\n rank_a: int,\n rank_g: int,\n rank_v: int,\n block_rows: int = 2,\n reduce_threads: int = 128,\n input_dtype: str = "float16",\n):\n """Build output-tiled direct R/K/V plus W/A/G/V rank-input GEMV."""\n ranks = (rank_w, rank_a, rank_g, rank_v)\n if channels <= 0 or any(rank < 0 for rank in ranks):\n raise ValueError("channels must be positive and ranks non-negative")\n if input_dtype not in {"float16", "bfloat16"}:\n raise ValueError("RKV dtype must be float16 or bfloat16")\n if block_rows not in {1, 2}:\n raise ValueError("RKV output tile must contain one or two rows")\n total_rows = 3 * channels + sum(ranks)\n if any(size % block_rows for size in (channels, *ranks)):\n raise ValueError("every RKV segment must be divisible by block_rows")\n vector_width = 8\n block_k = reduce_threads * vector_width\n if channels % block_k:\n raise ValueError("channels must be divisible by reduce_threads * 8")\n\n import tilelang.language as T # type: ignore[import-not-found]\n\n r_end = channels\n k_end = 2 * channels\n v_end = 3 * channels\n w_end = v_end + rank_w\n a_end = w_end + rank_a\n g_end = a_end + rank_g\n\n @T.prim_func\n def kernel(\n xr: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n xk: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n xv: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n xw: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n xa: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n xg: T.Tensor((channels,), input_dtype), # type: ignore[reportInvalidTypeForm]\n weight: T.Tensor( # type: ignore[reportInvalidTypeForm]\n (total_rows, channels), input_dtype\n ),\n output: T.Tensor((total_rows,), input_dtype), # type: ignore[reportInvalidTypeForm]\n ):\n with T.Kernel(\n total_rows // block_rows, threads=reduce_threads\n ) as block:\n reduce_lane = T.get_thread_binding(0)\n row = block * block_rows\n mixed_local = T.alloc_local((vector_width,), input_dtype)\n weight_local = T.alloc_local(\n (block_rows, vector_width), input_dtype\n )\n accumulator0 = T.alloc_local((1,), "float32")\n accumulator1 = T.alloc_local((1,), "float32")\n reduced0 = T.alloc_local((1,), "float32")\n reduced1 = T.alloc_local((1,), "float32")\n T.clear(accumulator0)\n T.clear(accumulator1)\n for chunk in T.serial(channels // block_k):\n for lane in T.vectorized(vector_width):\n column = (\n chunk * block_k\n + reduce_lane * vector_width\n + lane\n )\n mixed_local[lane] = T.if_then_else(\n row < r_end,\n xr[column],\n T.if_then_else(\n row < k_end,\n xk[column],\n T.if_then_else(\n row < v_end,\n xv[column],\n T.if_then_else(\n row < w_end,\n xw[column],\n T.if_then_else(\n row < a_end,\n xa[column],\n T.if_then_else(\n row < g_end, xg[column], xv[column]\n ),\n ),\n ),\n ),\n ),\n )\n weight_local[0, lane] = weight[row, column]\n if block_rows == 2:\n weight_local[1, lane] = weight[row + 1, column]\n for lane in T.serial(vector_width):\n mixed_value = T.cast(mixed_local[lane], "float32")\n accumulator0[0] += mixed_value * T.cast(\n weight_local[0, lane], "float32"\n )\n if block_rows == 2:\n accumulator1[0] += mixed_value * T.cast(\n weight_local[1, lane], "float32"\n )\n with T.attr(\n T.comm_reducer(\n lambda left, right: left + right,\n [T.cast(0, "float32")],\n ),\n "reduce_scope",\n T.reinterpret(T.uint64(0), dtype="handle"),\n ):\n T.evaluate(\n T.tvm_thread_allreduce(\n T.uint32(1),\n accumulator0[0],\n True,\n reduced0[0],\n reduce_lane,\n dtype="handle",\n )\n )\n if block_rows == 2:\n with T.attr(\n T.comm_reducer(\n lambda left, right: left + right,\n [T.cast(0, "float32")],\n ),\n "reduce_scope",\n T.reinterpret(T.uint64(0), dtype="handle"),\n ):\n T.evaluate(\n T.tvm_thread_allreduce(\n T.uint32(1),\n accumulator1[0],\n True,\n reduced1[0],\n reduce_lane,\n dtype="handle",\n )\n )\n if reduce_lane == 0:\n output[row] = T.cast(reduced0[0], input_dtype)\n if block_rows == 2:\n output[row + 1] = T.cast(reduced1[0], input_dtype)\n\n return kernel\n\n\n@lru_cache(maxsize=32)\ndef _compiled_rkv(\n channels: int,\n rank_w: int,\n rank_a: int,\n rank_g: int,\n rank_v: int,\n block_rows: int,\n reduce_threads: int,\n input_dtype: str,\n device_arch: str,\n):\n del device_arch\n import tilelang # type: ignore[import-not-found]\n\n return tilelang.compile(\n _build_rkv_program(\n channels,\n rank_w,\n rank_a,\n rank_g,\n rank_v,\n block_rows,\n reduce_threads,\n input_dtype,\n ),\n out_idx=[],\n execution_backend="auto",\n )\n\n\ndef _rkv_out(\n inputs: tuple[torch.Tensor, ...],\n weight: torch.Tensor,\n output: torch.Tensor,\n ranks: tuple[int, int, int, int],\n *,\n block_rows: int = 1,\n reduce_threads: int = 128,\n) -> None:\n """Run direct-input packed RKV and rank-input projections."""\n if len(inputs) != 6:\n raise ValueError("RKV expects xr, xk, xv, xw, xa, and xg")\n input_dtype = _require_contiguous_cuda(\n (*inputs, weight, output), "RKV"\n )\n if len(ranks) != 4 or any(rank < 0 for rank in ranks):\n raise ValueError("ranks must contain four non-negative values")\n channels = inputs[0].numel()\n if any(tuple(value.shape) != (channels,) for value in inputs):\n raise ValueError("every RKV input must have shape [C]")\n total_rows = 3 * channels + sum(ranks)\n if tuple(weight.shape) != (total_rows, channels):\n raise ValueError("packed RKV low-rank weight shape mismatch")\n if tuple(output.shape) != (total_rows,):\n raise ValueError("packed RKV low-rank output shape mismatch")\n kernel: Any = _compiled_rkv(\n channels,\n *ranks,\n block_rows,\n reduce_threads,\n input_dtype,\n cuda_arch_key(inputs[0].device),\n )\n kernel(*inputs, weight, output)\n\n\ndef clear_tilelang_kernel_caches() -> None:\n """Drop bounded Python references to compiled decode kernels."""\n for compiler in (\n _compiled_wkv,\n _compiled_wkv_w0_t1,\n _compiled_gemv,\n _compiled_ffn,\n _compiled_tmix_layernorm_mix6,\n _compiled_cmix_add_layernorm_mix,\n _compiled_cmix_layernorm_mix,\n _compiled_cmix_value,\n _compiled_cmix_sparse_atomic,\n _compiled_cmix_sparse_binned,\n _compiled_cmix_binned_finalize,\n _compiled_cmix_sparse_split,\n _compiled_cmix_finalize,\n _compiled_rankout_reduced,\n _compiled_rankout,\n _compiled_key_gate,\n _compiled_post_state,\n _compiled_rkv,\n ):\n compiler.cache_clear()\n'
filename = '<rwkv7_decode_b582151a6d2bd345cc5f87415543370e027c8f943a4dfe57a18300f08560bd73>'
linecache.cache[filename] = (
len(source), None, source.splitlines(keepends=True), filename
)
namespace = {'__name__': 'inference.kernel.decode'}
namespace['cuda_arch_key'] = state_cuda_arch_key
exec(compile(source, filename, 'exec'), namespace, namespace) # noqa: S102
return SimpleNamespace(
Any=namespace['Any'],
_HEAD_SIZE=namespace['_HEAD_SIZE'],
_NEXP_HALF_LOG2_E=namespace['_NEXP_HALF_LOG2_E'],
_NLOG2_E=namespace['_NLOG2_E'],
_ROTATOR1_SIGNED=namespace['_ROTATOR1_SIGNED'],
_TWO_NEG_41=namespace['_TWO_NEG_41'],
_build_cmix_add_layernorm_mix_program=namespace['_build_cmix_add_layernorm_mix_program'],
_build_cmix_binned_finalize_program=namespace['_build_cmix_binned_finalize_program'],
_build_cmix_finalize_program=namespace['_build_cmix_finalize_program'],
_build_cmix_layernorm_mix_program=namespace['_build_cmix_layernorm_mix_program'],
_build_cmix_sparse_atomic_program=namespace['_build_cmix_sparse_atomic_program'],
_build_cmix_sparse_binned_program=namespace['_build_cmix_sparse_binned_program'],
_build_cmix_sparse_split_program=namespace['_build_cmix_sparse_split_program'],
_build_cmix_value_program=namespace['_build_cmix_value_program'],
_build_ffn_program=namespace['_build_ffn_program'],
_build_gemv_program=namespace['_build_gemv_program'],
_build_key_gate_program=namespace['_build_key_gate_program'],
_build_post_state_program=namespace['_build_post_state_program'],
_build_rankout_program=namespace['_build_rankout_program'],
_build_rankout_reduced_program=namespace['_build_rankout_reduced_program'],
_build_rkv_program=namespace['_build_rkv_program'],
_build_tmix_layernorm_mix6_program=namespace['_build_tmix_layernorm_mix6_program'],
_build_wkv_program=namespace['_build_wkv_program'],
_build_wkv_w0_t1_program=namespace['_build_wkv_w0_t1_program'],
_cmix_value_out=namespace['_cmix_value_out'],
_compiled_cmix_add_layernorm_mix=namespace['_compiled_cmix_add_layernorm_mix'],
_compiled_cmix_binned_finalize=namespace['_compiled_cmix_binned_finalize'],
_compiled_cmix_finalize=namespace['_compiled_cmix_finalize'],
_compiled_cmix_layernorm_mix=namespace['_compiled_cmix_layernorm_mix'],
_compiled_cmix_sparse_atomic=namespace['_compiled_cmix_sparse_atomic'],
_compiled_cmix_sparse_binned=namespace['_compiled_cmix_sparse_binned'],
_compiled_cmix_sparse_split=namespace['_compiled_cmix_sparse_split'],
_compiled_cmix_value=namespace['_compiled_cmix_value'],
_compiled_ffn=namespace['_compiled_ffn'],
_compiled_gemv=namespace['_compiled_gemv'],
_compiled_key_gate=namespace['_compiled_key_gate'],
_compiled_post_state=namespace['_compiled_post_state'],
_compiled_rankout=namespace['_compiled_rankout'],
_compiled_rankout_reduced=namespace['_compiled_rankout_reduced'],
_compiled_rkv=namespace['_compiled_rkv'],
_compiled_tmix_layernorm_mix6=namespace['_compiled_tmix_layernorm_mix6'],
_compiled_wkv=namespace['_compiled_wkv'],
_compiled_wkv_w0_t1=namespace['_compiled_wkv_w0_t1'],
_dtype_name=namespace['_dtype_name'],
_ffn_out=namespace['_ffn_out'],
_post_state_out=namespace['_post_state_out'],
_rankout_out=namespace['_rankout_out'],
_require_contiguous_cuda=namespace['_require_contiguous_cuda'],
_rkv_out=namespace['_rkv_out'],
_wkv_kernel_out=namespace['_wkv_kernel_out'],
_wkv_out=namespace['_wkv_out'],
_wkv_precise_out=namespace['_wkv_precise_out'],
_wkv_w0_t1_out=namespace['_wkv_w0_t1_out'],
clear_tilelang_kernel_caches=namespace['clear_tilelang_kernel_caches'],
cuda_arch_key=namespace['cuda_arch_key'],
lru_cache=namespace['lru_cache'],
torch=namespace['torch'],
)
state = _build_state_namespace()
decode = _build_decode_namespace(state.cuda_arch_key)
__all__ = ["state", "decode"]
|