Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
114 commits
Select commit Hold shift + click to select a range
a29119e
vendor: conv1d packages
averyhNV Nov 5, 2026
220e42b
vendor: moe_grouped_gemm packages
averyhNV Nov 5, 2026
06bcb00
vendor: gqa packages
averyhNV Nov 5, 2026
2edabb2
moe_grouped_gemm: the ragged BF16 MoE grouped GEMM on the cake runtime
averyhNV Nov 5, 2026
7a62dde
vendor: mhc packages
averyhNV Nov 5, 2026
03e59f5
mhc: the four-stream hyper-connection kernels as a cake op
averyhNV Nov 5, 2026
438cc96
gqa: packed causal GQA attention, head dim 256, on the cake runtime
averyhNV Nov 5, 2026
188f379
tests: gqa
averyhNV Nov 5, 2026
94a7989
tests: mhc
averyhNV Nov 5, 2026
9b9bb4f
conv1d: the short-conv op on the cake runtime
averyhNV Nov 5, 2026
1ecdec7
tests: conv1d
averyhNV Nov 5, 2026
701c627
tests: moe_grouped_gemm
averyhNV Nov 5, 2026
67577b5
vendor: kda packages
averyhNV Nov 5, 2026
5628db4
vendor: gated_rmsnorm packages
averyhNV Nov 5, 2026
e22f32d
vendor: rmsnorm packages
averyhNV Nov 5, 2026
ad8df6a
vendor: dsa packages
averyhNV Nov 5, 2026
1faa47a
kda: packed KDA chunked training, single rank and context parallel
averyhNV Nov 5, 2026
bc12602
gated_rmsnorm: the SiLU-gated RMSNorm op on the cake runtime
averyhNV Nov 5, 2026
4210da3
rmsnorm: the zero-centred input RMSNorm on the cake runtime
averyhNV Nov 5, 2026
8eff403
dsa: sparse attention and lightning indexer on the cake runtime
averyhNV Nov 5, 2026
03b86da
tests: kda
averyhNV Nov 5, 2026
f746c65
tests: gated_rmsnorm
averyhNV Nov 5, 2026
0177e7b
tests: rmsnorm
averyhNV Nov 5, 2026
eefde4b
tests: dsa
averyhNV Nov 5, 2026
ef381a0
vendor: dense_gemm packages
averyhNV Nov 5, 2026
e9dd400
vendor: gdn packages
averyhNV Nov 5, 2026
2fda20d
cake: one runtime for every op: variants, arguments, loader, prebuild
averyhNV Nov 5, 2026
621f82b
tools/vendor_cake.py: one manifest for FlashInfer and miles PR sources
averyhNV Nov 5, 2026
e048232
Packaging, CI and README for the cake layout
averyhNV Nov 5, 2026
631ab4b
gdn: chunked gated delta rule on the cake runtime
averyhNV Nov 5, 2026
ad8eeef
tests: gdn
averyhNV Nov 5, 2026
20ccf43
dense_gemm: batched projection and FP32 router GEMMs on the cake runtime
averyhNV Nov 5, 2026
9eead0b
tests: dense_gemm
averyhNV Nov 5, 2026
eaaeaf0
Tighten the README and keep version 0.0.1
Zhichenzzz Nov 5, 2026
1ebe1d5
README: keep only what a user needs
Zhichenzzz Nov 5, 2026
d67ad25
Simplify the cake runtime: public CUDA APIs, no lookup memos
Zhichenzzz Nov 5, 2026
47e436c
Merge cake-stack/00-layout into cake-stack/01-gdn
Zhichenzzz Nov 5, 2026
af06868
Merge main (squash of #12) into cake-stack/01-gdn
Zhichenzzz Nov 5, 2026
ce45d9b
Merge cake-stack/01-gdn into cake-stack/02-kda
Zhichenzzz Nov 5, 2026
a7b6a79
Merge cake-stack/02-kda into cake-stack/03-conv1d
Zhichenzzz Nov 5, 2026
d67a161
Merge cake-stack/03-conv1d into cake-stack/04-gated-rmsnorm
Zhichenzzz Nov 5, 2026
6fe0cf5
Merge cake-stack/04-gated-rmsnorm into cake-stack/05-rmsnorm
Zhichenzzz Nov 5, 2026
f1e97a1
Merge cake-stack/05-rmsnorm into cake-stack/06-dsa
Zhichenzzz Nov 5, 2026
704dffb
Merge cake-stack/06-dsa into cake-stack/07-mhc
Zhichenzzz Nov 5, 2026
3ca55be
Merge cake-stack/07-mhc into cake-stack/08-gqa
Zhichenzzz Nov 5, 2026
1e23377
Merge cake-stack/08-gqa into cake-stack/09-dense-gemm
Zhichenzzz Nov 5, 2026
46cc60f
Merge cake-stack/09-dense-gemm into cake-stack/10-moe-grouped-gemm
Zhichenzzz Nov 5, 2026
67466e4
Merge the README tidy (ops described in their modules) into cake-stac…
Zhichenzzz Nov 5, 2026
7e26304
Merge cake-stack/01-gdn into cake-stack/02-kda
Zhichenzzz Nov 5, 2026
a6353e3
Merge cake-stack/02-kda into cake-stack/03-conv1d
Zhichenzzz Nov 5, 2026
1ae0bfc
Merge cake-stack/03-conv1d into cake-stack/04-gated-rmsnorm
Zhichenzzz Nov 5, 2026
2625a05
Merge cake-stack/04-gated-rmsnorm into cake-stack/05-rmsnorm
Zhichenzzz Nov 5, 2026
3e3bf8b
Merge cake-stack/05-rmsnorm into cake-stack/06-dsa
Zhichenzzz Nov 5, 2026
326c651
Merge cake-stack/06-dsa into cake-stack/07-mhc
Zhichenzzz Nov 5, 2026
1ab49fe
Merge cake-stack/07-mhc into cake-stack/08-gqa
Zhichenzzz Nov 5, 2026
34306b3
Merge cake-stack/08-gqa into cake-stack/09-dense-gemm
Zhichenzzz Nov 5, 2026
a8db080
Merge cake-stack/09-dense-gemm into cake-stack/10-moe-grouped-gemm
Zhichenzzz Nov 5, 2026
c974662
Merge main into cake-stack/01-gdn
Zhichenzzz Nov 5, 2026
d9e40a2
Merge cake-stack/01-gdn into cake-stack/02-kda
Zhichenzzz Nov 5, 2026
235259c
Merge cake-stack/02-kda into cake-stack/03-conv1d
Zhichenzzz Nov 5, 2026
f2b01d9
Merge cake-stack/03-conv1d into cake-stack/04-gated-rmsnorm
Zhichenzzz Nov 5, 2026
b8eb4a3
Merge cake-stack/04-gated-rmsnorm into cake-stack/05-rmsnorm
Zhichenzzz Nov 5, 2026
388f92f
Merge cake-stack/05-rmsnorm into cake-stack/06-dsa
Zhichenzzz Nov 5, 2026
555e6a2
Merge cake-stack/06-dsa into cake-stack/07-mhc
Zhichenzzz Nov 5, 2026
9e2dea2
Merge cake-stack/07-mhc into cake-stack/08-gqa
Zhichenzzz Nov 5, 2026
0319a7a
Merge cake-stack/08-gqa into cake-stack/09-dense-gemm
Zhichenzzz Nov 5, 2026
fecc0fb
Merge cake-stack/09-dense-gemm into cake-stack/10-moe-grouped-gemm
Zhichenzzz Nov 5, 2026
4fc5125
Merge main (squash of cake-stack/01-gdn) into cake-stack/02-kda
Zhichenzzz Nov 5, 2026
bba5b43
Merge cake-stack/02-kda into cake-stack/03-conv1d
Zhichenzzz Nov 5, 2026
ef2c15d
Merge cake-stack/03-conv1d into cake-stack/04-gated-rmsnorm
Zhichenzzz Nov 5, 2026
df6a61d
Merge cake-stack/04-gated-rmsnorm into cake-stack/05-rmsnorm
Zhichenzzz Nov 5, 2026
1d54f65
Merge cake-stack/05-rmsnorm into cake-stack/06-dsa
Zhichenzzz Nov 5, 2026
0962ff7
Merge cake-stack/06-dsa into cake-stack/07-mhc
Zhichenzzz Nov 5, 2026
765de7e
Merge cake-stack/07-mhc into cake-stack/08-gqa
Zhichenzzz Nov 5, 2026
f377f1b
Merge cake-stack/08-gqa into cake-stack/09-dense-gemm
Zhichenzzz Nov 5, 2026
3517116
Merge cake-stack/09-dense-gemm into cake-stack/10-moe-grouped-gemm
Zhichenzzz Nov 5, 2026
da3d325
Merge main (squash of cake-stack/02-kda) into cake-stack/03-conv1d
Zhichenzzz Nov 5, 2026
55d3c37
Merge cake-stack/03-conv1d into cake-stack/04-gated-rmsnorm
Zhichenzzz Nov 5, 2026
0a76c88
Merge cake-stack/04-gated-rmsnorm into cake-stack/05-rmsnorm
Zhichenzzz Nov 5, 2026
01cc138
Merge cake-stack/05-rmsnorm into cake-stack/06-dsa
Zhichenzzz Nov 5, 2026
2e3e6ed
Merge cake-stack/06-dsa into cake-stack/07-mhc
Zhichenzzz Nov 5, 2026
a9d4fd0
Merge cake-stack/07-mhc into cake-stack/08-gqa
Zhichenzzz Nov 5, 2026
c587c75
Merge cake-stack/08-gqa into cake-stack/09-dense-gemm
Zhichenzzz Nov 5, 2026
202bb3c
Merge cake-stack/09-dense-gemm into cake-stack/10-moe-grouped-gemm
Zhichenzzz Nov 5, 2026
865e16a
Merge main (squash of cake-stack/03-conv1d) into cake-stack/04-gated-…
Zhichenzzz Nov 5, 2026
5a6c3f9
Merge cake-stack/04-gated-rmsnorm into cake-stack/05-rmsnorm
Zhichenzzz Nov 5, 2026
5a0073c
Merge cake-stack/05-rmsnorm into cake-stack/06-dsa
Zhichenzzz Nov 5, 2026
ac91a51
Merge cake-stack/06-dsa into cake-stack/07-mhc
Zhichenzzz Nov 5, 2026
cc4489b
Merge cake-stack/07-mhc into cake-stack/08-gqa
Zhichenzzz Nov 5, 2026
ad1fd6a
Merge cake-stack/08-gqa into cake-stack/09-dense-gemm
Zhichenzzz Nov 5, 2026
0ece6d0
Merge cake-stack/09-dense-gemm into cake-stack/10-moe-grouped-gemm
Zhichenzzz Nov 5, 2026
23f835d
Merge main (squash of cake-stack/04-gated-rmsnorm) into cake-stack/05…
Zhichenzzz Nov 5, 2026
32700ee
Merge cake-stack/05-rmsnorm into cake-stack/06-dsa
Zhichenzzz Nov 5, 2026
2d22240
Merge cake-stack/06-dsa into cake-stack/07-mhc
Zhichenzzz Nov 5, 2026
a400322
Merge cake-stack/07-mhc into cake-stack/08-gqa
Zhichenzzz Nov 5, 2026
fc30ec8
Merge cake-stack/08-gqa into cake-stack/09-dense-gemm
Zhichenzzz Nov 5, 2026
05c0fb7
Merge cake-stack/09-dense-gemm into cake-stack/10-moe-grouped-gemm
Zhichenzzz Nov 5, 2026
7297d6a
Merge main (squash of cake-stack/05-rmsnorm) into cake-stack/06-dsa
Zhichenzzz Nov 5, 2026
c019f95
Merge cake-stack/06-dsa into cake-stack/07-mhc
Zhichenzzz Nov 5, 2026
83901b0
Merge cake-stack/07-mhc into cake-stack/08-gqa
Zhichenzzz Nov 5, 2026
81fa670
Merge cake-stack/08-gqa into cake-stack/09-dense-gemm
Zhichenzzz Nov 5, 2026
ecb3216
Merge cake-stack/09-dense-gemm into cake-stack/10-moe-grouped-gemm
Zhichenzzz Nov 5, 2026
7107f60
Merge main (squash of cake-stack/06-dsa) into cake-stack/07-mhc
Zhichenzzz Nov 5, 2026
c153391
Merge cake-stack/07-mhc into cake-stack/08-gqa
Zhichenzzz Nov 5, 2026
603e9d8
Merge cake-stack/08-gqa into cake-stack/09-dense-gemm
Zhichenzzz Nov 5, 2026
45bc5ff
Merge cake-stack/09-dense-gemm into cake-stack/10-moe-grouped-gemm
Zhichenzzz Nov 5, 2026
a0c20dc
Merge main (squash of cake-stack/07-mhc) into cake-stack/08-gqa
Zhichenzzz Nov 5, 2026
de8bca3
Merge cake-stack/08-gqa into cake-stack/09-dense-gemm
Zhichenzzz Nov 5, 2026
d47c425
Merge cake-stack/09-dense-gemm into cake-stack/10-moe-grouped-gemm
Zhichenzzz Nov 5, 2026
601078c
Merge main (squash of cake-stack/08-gqa) into cake-stack/09-dense-gemm
Zhichenzzz Nov 5, 2026
a05f2c5
Merge cake-stack/09-dense-gemm into cake-stack/10-moe-grouped-gemm
Zhichenzzz Nov 5, 2026
79f55da
tests: dense_gemm checks the batch-invariance note in its docstrings,…
Zhichenzzz Nov 5, 2026
974ab92
Merge cake-stack/09-dense-gemm into cake-stack/10-moe-grouped-gemm
Zhichenzzz Nov 5, 2026
b2c247f
Merge main (squash of cake-stack/09-dense-gemm) into cake-stack/10-mo…
Zhichenzzz Nov 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions miles_ext_kernels/cake/_impl/moe_grouped_gemm/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""
Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved.
Licensed under the Apache License, Version 2.0.
https://www.apache.org/licenses/LICENSE-2.0

The implementation of ``miles_ext_kernels.cake.moe_grouped_gemm`` (:mod:`.ops`).
"""

from miles_ext_kernels.cake._runtime import loader

loader.install_op("moe_grouped_gemm")

from .ops import check_grouped_dims, grouped_mm, max_grouped_rows, prebuild, release # noqa: E402

__all__ = ["check_grouped_dims", "grouped_mm", "max_grouped_rows", "prebuild", "release"]
215 changes: 215 additions & 0 deletions miles_ext_kernels/cake/_impl/moe_grouped_gemm/ops.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
"""
Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved.
Licensed under the Apache License, Version 2.0.
https://www.apache.org/licenses/LICENSE-2.0

The ragged BF16 MoE grouped GEMM miles calls (SM100a / SM103a / SM107a), on two vendored FlashInfer packages whose
libraries the runtime's loader builds and loads (SM107a with a CUDA 13.4 or newer toolkit):
``_vendor/cake_moe_grouped_det_gemm`` (``det``) and ``_vendor/cake_moe_grouped_gemm`` (``fast``).

:func:`grouped_mm` is ``torch._grouped_mm(x, w.transpose(-2, -1), offs=offs)`` for ``x [sum_m, K]``, ``w [E, N, K]``
and the int32 cumulative row ends ``offs [E]`` of the groups, differentiable in ``x`` and ``w``. The kernels read
``offs`` on the device (no host synchronisation); groups may be empty, one row long or of any size, and rows past
``offs[-1]`` are left alone. Every product is an FP32 accumulation of exact BF16 products rounded once to BF16 (the
cuBLAS / CUTLASS numerics, not their bits).

Variants. ``det`` reduces every output in a fixed order: the output and both gradients repeat bit for bit. ``fast``
gives the same output and input-gradient bits; its weight gradient, where it picks the 512-wide k tile (``K`` a multiple
of 512 and at least 4096 rows per group on average), adds the split tail of its last wave with unordered FP32 atomics
instead of a second, ordered reduction launch, so those tiles may differ in the last bit run to run. Every forward reads
the configured variant (``config.variant``); its backward runs the package of its forward. Under
``torch.use_deterministic_algorithms(True)`` a ``fast`` call runs ``det`` and logs it once (``config.warn_runs_det``):
the ``fast`` weight gradient raises torch's non-determinism alert there.

32-bit addressing. The kernels address each output with 32-bit element offsets: ``sum_m * N`` (the output),
``sum_m * K`` (the input gradient) and ``E * N * K`` (the weight gradient) must stay at most ``2**31 - 1``.
:func:`check_grouped_dims` checks a weight ``[E, N, K]`` and the most rows a call may get where the model is built;
:func:`max_grouped_rows` is that bound. :func:`grouped_mm` checks every limit of the three products before its forward
launches anything, so a call the backward could not serve fails at its forward.

Workspaces. The packages keep small workspaces per device and CUDA stream (scheduler words, wave counters and the FP32
tail sums of the ``fast`` weight gradient) that every launch leaves at their rest state for the next one on its stream;
calls on two streams never share them, and a launch captured into a CUDA graph takes its own. They stay outside the
runtime's workspace pool, whose buffers do not keep their content. :func:`release` drops them.

Prebuild. :func:`prebuild` builds every program both variants may launch on the device's architecture (forward, input
gradient, both weight-gradient k tiles, every stage of each), and on SM100a / SM103a the probe of the memory domains the
input gradient compiles once per compute capability (``tvm_ffi.cpp.load_inline``, an nvcc build), so that no call
compiles afterwards.
"""

from __future__ import annotations

import functools
import logging
import sys
from importlib import import_module
from pathlib import Path
from types import ModuleType
from typing import Any

import torch

from miles_ext_kernels.cake._runtime import config, loader

__all__ = ["check_grouped_dims", "grouped_mm", "max_grouped_rows", "prebuild", "release"]

logger = logging.getLogger(__name__)

_OP = "moe_grouped_gemm"
# the vendored package of each variant
_PACKAGES = {"det": "cake_moe_grouped_det_gemm", "fast": "cake_moe_grouped_gemm"}
# miles_ext_kernels.cake._vendor
_VENDOR = f"{__name__.rsplit('._impl.', 1)[0]}._vendor"
_WHAT = "the Cake MoE grouped GEMM"
# The routes of one forward and backward with BF16 weights: (op, record_name keywords).
_ROUTES = (
("fwd", {}),
("dgrad", {}),
("wgrad", {"out_dtype": "bfloat16", "tile_k": 256}),
("wgrad", {"out_dtype": "bfloat16", "tile_k": 512}),
)
_DETERMINISTIC_ALGORITHMS = "calls under torch.use_deterministic_algorithms(True)"


def _module(variant: str, name: str) -> ModuleType:
"""The submodule ``name`` (``cake_autograd``, ``cake_backend``, ``cake_jit``) of ``variant``'s package."""
return import_module(f"{_VENDOR}.{_PACKAGES[variant]}.{name}")


@functools.cache
def _int32_elems() -> int:
"""The largest element offset the programs of both packages address."""
return min(int(_module(variant, "cake_jit").HOST_PLAN_CONSTANTS["int32_elems"]) for variant in _PACKAGES)


def max_grouped_rows(n: int, k: int) -> int:
"""The most rows (``sum_m``, padding rows included) a call with expert weights ``[E, N, K]`` serves: the output
``[sum_m, N]`` and the input gradient ``[sum_m, K]`` are addressed with 32-bit element offsets."""
return _int32_elems() // max(int(n), int(k), 1)


def check_grouped_dims(n: int, k: int, *, num_groups: int | None = None, max_rows: int | None = None) -> None:
"""Raise ``ValueError`` unless the programs serve the expert weight ``[E, N, K]`` in all three products.

The forward and the weight gradient need ``N`` a multiple of 256, the input and weight gradients ``K`` a multiple
of 256. With ``num_groups`` (``E``), the weight gradient ``[E, N, K]`` must fit 32-bit element offsets; with
``max_rows``, the most rows a call may get (``sum_m``, padding rows included), so must the output and the input
gradient (:func:`max_grouped_rows`). Call it where the model is built, with the bound of the configured run.
"""
for name, dim in (("output features N", n), ("input features K", k)):
if dim < 256 or dim % 256:
raise ValueError(f"{_WHAT} needs expert {name} that are a multiple of 256, got {dim}")
limit = _int32_elems()
if num_groups is not None and num_groups * n * k > limit:
raise ValueError(
f"{_WHAT} addresses its weight gradient with 32-bit element offsets: {num_groups} experts of [{n}, {k}] "
f"are {num_groups * n * k} elements, more than {limit}"
)
if max_rows is not None and max_rows > max_grouped_rows(n, k):
raise ValueError(
f"{_WHAT} addresses its output and input gradient with 32-bit element offsets: {max_rows} rows of "
f"{max(n, k)} columns are more than {limit} elements; experts of [{n}, {k}] serve at most "
f"{max_grouped_rows(n, k)} rows"
)


def _device_index(device: Any) -> int:
device = torch.device("cuda") if device is None else torch.device(device)
if device.type != "cuda":
raise ValueError(f"{_WHAT} runs on CUDA devices, got {device}")
return torch.cuda.current_device() if device.index is None else device.index


@functools.cache
def _arch(index: int) -> str:
"""The architecture of device ``index``, checked to be supported and its programs to build with the toolkit."""
arch = loader.device_arch(index)
loader.check_toolkit(arch, _WHAT)
return arch


def grouped_mm(x: torch.Tensor, w: torch.Tensor, offs: torch.Tensor) -> torch.Tensor:
"""The ragged grouped GEMM ``Y[offs[e-1]:offs[e]] = X[offs[e-1]:offs[e]] @ W[e].T``: ``[sum_m, N]`` BF16.

``x [sum_m, K]`` and ``w [E, N, K]`` are BF16 with unit stride on their last axis, ``offs`` the int32 cumulative
row ends ``[E]`` on ``x``'s device (``torch._grouped_mm``'s ``offs``). The backward returns ``x.grad`` in BF16 and
``w.grad`` in ``w``'s dtype; an empty group gets an exactly zero weight gradient. The call runs the configured
variant (``det`` unless configured); its backward runs the same package.
"""
if x.dim() != 2 or w.dim() != 3 or x.shape[1] != w.shape[2]:
raise ValueError(f"grouped_mm takes x [sum_m, K] and w [E, N, K], got {tuple(x.shape)} and {tuple(w.shape)}")
if x.dtype != torch.bfloat16 or w.dtype != torch.bfloat16:
raise ValueError(f"grouped_mm takes BF16 x and w, got {x.dtype} and {w.dtype}")
if offs.dtype != torch.int32 or offs.dim() != 1 or offs.numel() != w.shape[0]:
raise ValueError(
f"offs must be the int32 cumulative row ends [E] of the {w.shape[0]} groups, got {offs.dtype} "
f"{tuple(offs.shape)}"
)
if w.device != x.device or offs.device != x.device:
raise ValueError(f"x, w and offs must be on one device, got {x.device}, {w.device} and {offs.device}")
num_groups, n, k = (int(size) for size in w.shape)
check_grouped_dims(n, k, num_groups=num_groups, max_rows=int(x.shape[0]))
_arch(_device_index(x.device))
variant = config.variant(_OP)
if variant == "fast" and torch.are_deterministic_algorithms_enabled():
config.warn_runs_det(_OP, _DETERMINISTIC_ALGORITHMS)
variant = "det"
if variant == "det":
return _module("det", "cake_autograd").cake_grouped_det_mm(x, w, offs)
return _module("fast", "cake_autograd").cake_grouped_mm(x, w, offs, deterministic=False)


def _library_names(variant: str, arch: str) -> list[str]:
"""Every library of ``variant``'s package the routes of one forward and backward bind on ``arch``."""
jit = _module(variant, "cake_jit")
names = []
for op, keys in _ROUTES:
if not jit.program_registered(op, arch, **keys):
continue
for stage in jit.ROUTES[jit.record_name(op, **keys)]["stages"]:
if arch in jit.PROGRAMS[stage["program"]]["arches"]:
names.append(jit.library_name(stage["program"], arch, stage["specializations"]))
return names


def prebuild(*, device: Any = None, max_workers: int | None = None) -> list[Path]:
"""Build, ahead of the first call, every program :func:`grouped_mm` of either variant can launch on ``device``
(default: the current device) with BF16 weights, whatever the group sizes: the forward, input-gradient and both
weight-gradient routes, every stage built for its architecture (about a dozen libraries per variant), and the
queue probe of the input gradient on SM100a / SM103a. No model parameter: one build serves every expert shape.
Returns the cache paths of the libraries.

``NotImplementedError`` for a device other than SM100a / SM103a / SM107a; ``RuntimeError`` for a toolkit too old
for its architecture.
"""
index = _device_index(device)
arch = _arch(index)
paths = []
for variant, package in _PACKAGES.items():
paths += loader.prebuild_libraries(package, _library_names(variant, arch), max_workers)
capability = torch.cuda.get_device_capability(index)
for variant in _PACKAGES:
backend = _module(variant, "cake_backend")
if arch in backend.host_plan_constants()["domain_split_archs"]:
# the probe the first probed launch on a stream would compile; the even split serves without it
if backend._queue_probe_module(capability) is None:
logger.warning(
"%s: the queue probe does not build on %s here; the input gradient splits its work queues evenly "
"(the same bits)",
_WHAT,
arch,
)
return paths


def release() -> None:
"""Drop the workspaces both packages keep per device and stream, with the queue splits probed on them."""
for package in _PACKAGES.values():
backend = sys.modules.get(f"{_VENDOR}.{package}.cake_backend")
if backend is None:
continue
with backend._STREAM_WORKSPACES_LOCK:
# a probed split is keyed by its workspace's address, which a later workspace may reuse
backend._stream_workspaces.clear()
backend._queue_splits.clear()
1 change: 1 addition & 0 deletions miles_ext_kernels/cake/_runtime/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"mhc",
"gqa",
"dense_gemm",
"moe_grouped_gemm",
)

# miles_ext_kernels.cake: op modules are its submodules, implementations those of its _impl package
Expand Down
Loading
Loading