Skip to content

Commit e65c501

Browse files
committed
update release v0.2.0
1 parent 99bbf1f commit e65c501

172 files changed

Lines changed: 101410 additions & 5313 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ dist/
2323

2424
# temporary files
2525
mate/jit/aot-levels.json
26-
aot-lib/
26+
aot-ops/
2727
temp/
28-
mate/jit/aot-levels.json
28+
*.so

.gitmodules

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[submodule "3rdparty/mutlass"]
22
path = 3rdparty/mutlass
33
url = https://github.com/MooreThreads/mutlass.git
4+
branch = main

AGENTS.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Agent Instructions for MATE
2+
3+
This file provides guidance to AI-assisted contributions to MATE.
4+
5+
6+
## Quick Reference
7+
8+
| Task | Command |
9+
|------|---------|
10+
| Install for development | `pip install --no-build-isolation -e . -v` |
11+
| Initialize submodules | `git submodule update --init --recursive` |
12+
| Run all tests | `pytest tests/` |
13+
| Run specific test | `pytest tests/path/test_file.py::test_function` |
14+
| Run multi-GPU test | `mpirun -np 4 pytest tests/comm/test_allreduce_unified_api.py` |
15+
| Run linting | `pre-commit run -a` |
16+
| Install pre-commit hooks | `pre-commit install` |
17+
| Clear JIT cache | `rm -rf ~/.cache/mate/` |
18+
| Enable API logging (basic) | `export MATE_LOGLEVEL=1` |
19+
| Enable API logging (detailed) | `export MATE_LOGLEVEL=3` |
20+
| Enable API logging (with stats) | `export MATE_LOGLEVEL=5` |
21+
| Set API log destination | `export MATE_LOGDEST=mylog.txt` |
22+
| Enable verbose JIT logging | `export MATE_JIT_VERBOSE=1` |
23+
| Set target architectures | `export MATE_MUSA_ARCH_LIST="3.1"` |
24+
25+
26+
## Quick Start for Development
27+
28+
### Installation
29+
30+
```bash
31+
git clone https://github.com/MooreThreads/mate.git --recursive
32+
cd mate
33+
pip install --no-build-isolation -e . -v
34+
```
35+
36+
**Important**: The `--recursive` flag is required to initialize submodules in `3rdparty/` (mutlass...).
37+
38+
If you forgot `--recursive` when cloning:
39+
```bash
40+
git submodule update --init --recursive
41+
```
42+
43+
The `--no-build-isolation` flag prevents pip from pulling incompatible PyTorch versions from PyPI.
44+
45+
46+
## External Integrations
47+
48+
### TVM-FFI: Cross-Language Unified ABI
49+
50+
MATE uses **TVM-FFI** (Apache TVM's Foreign Function Interface) for bindings, which provides a **cross-language unified ABI**. This means:
51+
52+
- **Not limited to PyTorch**: The same compiled kernels can be used from multiple frameworks
53+
- **Language agnostic**: Bindings can be created for Python, C++, Rust, etc.
54+
- **Type-safe marshaling**: Automatic tensor/array conversion between languages
55+
- **Export syntax**: Use `TVM_FFI_DLL_EXPORT_TYPED_FUNC(name, func)` to expose C++ functions
56+
57+
### TVM-FFI Kernel Binding Rules
58+
59+
When exporting MATE kernels through TVM-FFI, follow these rules:
60+
61+
- TVM-FFI functions do **not** need to be `void` by default. Return values are allowed when they represent real metadata or status produced by C++.
62+
- For kernel-style bindings, if an output tensor's shape, dtype, and device are already known on the Python side, allocate it in Python and pass it into C++ as a tensor/tensor view.
63+
- Do **not** use `alloc_tensor()` inside C++ FFI bindings for ordinary kernel outputs that can be preallocated by the caller.
64+
- Exception: if an output tensor's padding, row stride, or storage layout is tightly coupled to the kernel implementation and easy to misuse from Python, allocate it inside C++ and return the logical tensor/view from FFI.
65+
- Keep non-`void` returns only for values that are not ordinary output tensors, such as dispatch metadata that must be surfaced from C++.
66+
- When updating FFI bindings, prefer the kernel-library guidance from TVM-FFI over generic PyTorch extension patterns.
67+
68+
69+
## External Documentation Resources
70+
71+
When working with MATE's dependencies and tools, refer to these official documentation sources:
72+
73+
### Core Dependencies
74+
75+
- **TVM-FFI**: Apache TVM's Foreign Function Interface
76+
- Documentation: <https://tvm.apache.org/ffi/>
77+
- Package: `apache-tvm-ffi` (<https://pypi.org/project/apache-tvm-ffi/>)
78+
- Use for: Understanding FFI export syntax, cross-language bindings
79+
- MUSA Fork: https://github.com/MooreThreads/tvm-ffi/
80+
- When working on MUSA-related features, always refer to the musa-specific fork and its tags (e.g., v0.1.9.post2+musa.1) instead of upstream TVM-FFI.
81+
82+
83+
### When to Consult These Docs
84+
85+
- **Working on FFI bindings** → Check TVM-FFI docs for export patterns and type marshaling
86+
- **Working on kernel bindings** → Check the TVM-FFI kernel library guide for output-allocation patterns and `TensorView` usage
87+
88+
89+
## Behavior Rules
90+
91+
- Always read relevant files before modifying code
92+
- For non-trivial tasks, create a plan first
93+
- Validate changes by running tests
94+
- Prefer minimal, localized changes

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
AGENTS.md

README.md

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@ MATE (**M**USA **A**I **T**ensor **E**ngine) is a centralized library for Genera
55
## Highlights
66

77
- High-performance attention and GEMM operators for MUSA
8-
- Compatibility wrappers for `flash_attn` and `deep_gemm`
8+
- Compatibility wrappers for `flash_attn_3`, `sageattention`, `flash_mla`, and `deep_gemm`
99
- CLI tools for environment checks, configuration inspection, and replay
1010

1111
## Quick Links
1212

1313
- CLI documentation: [docs/mate_cli.md](docs/mate_cli.md)
14-
- FlashAttention compatibility summary: [docs/flash_attention.md](docs/flash_attention.md)
15-
- FlashAttention wrapper: [wrappers/flash-attention/README.md](wrappers/flash-attention/README.md)
16-
- DeepGEMM wrapper: [wrappers/deep_gemm/README.md](wrappers/deep_gemm/README.md)
14+
- FlashAttention-3 compatibility summary: [docs/flash_attention.md](docs/flash_attention.md)
15+
- FlashAttention-3 wrapper: [wrappers/flash-attention/README.md](wrappers/flash-attention/README.md)
16+
- SageAttention wrapper: [wrappers/SageAttention/README.md](wrappers/SageAttention/README.md)
17+
- FlashMLA wrapper: [wrappers/FlashMLA/README.md](wrappers/FlashMLA/README.md)
18+
- DeepGEMM wrapper: [wrappers/DeepGEMM/README.md](wrappers/DeepGEMM/README.md)
1719

1820
## Requirements
1921

@@ -28,7 +30,37 @@ MATE (**M**USA **A**I **T**ensor **E**ngine) is a centralized library for Genera
2830
```bash
2931
git clone https://github.com/MooreThreads/mate.git --recursive
3032
cd mate
31-
bash build.sh
33+
python -m build --wheel --no-isolation
34+
```
35+
36+
For local development, install MATE in editable mode:
37+
38+
```bash
39+
git clone https://github.com/MooreThreads/mate.git --recursive
40+
cd mate
41+
pip install --no-build-isolation -e . -v
42+
```
43+
44+
If you forgot `--recursive` when cloning, initialize submodules before building or
45+
installing:
46+
47+
```bash
48+
git submodule update --init --recursive
49+
```
50+
51+
Pre-build AOT kernels before packaging the wheel:
52+
53+
```bash
54+
git clone https://github.com/MooreThreads/mate.git --recursive
55+
cd mate
56+
MATE_MUSA_ARCH_LIST=3.1 python -m mate.aot
57+
python -m build --wheel --no-isolation
58+
```
59+
60+
Customize AOT coverage by operator family when needed:
61+
62+
```bash
63+
python -m mate.aot --attention-aot-level 0 --add-gemm true --add-moe false
3264
```
3365

3466
## Repository Layout
@@ -71,8 +103,10 @@ MATE uses the packages under `wrappers/` as a compatibility layer for CUDA-orien
71103

72104
| Wrapper | Package | Import Path | Purpose | Documentation |
73105
| --- | --- | --- | --- | --- |
74-
| `wrappers/flash-attention` | `mate-flash-attention` | `flash_attn` | FlashAttention-compatible APIs on top of MATE attention operators on MUSA | [wrapper README](wrappers/flash-attention/README.md), [compatibility summary](docs/flash_attention.md) |
75-
| `wrappers/deep_gemm` | `mate-deep_gemm` | `deep_gemm` | DeepGEMM-compatible APIs on top of MATE GEMM operators on MUSA | [wrapper README](wrappers/deep_gemm/README.md) |
106+
| `wrappers/flash-attention` | `flash_attn_3` | `flash_attn_interface` | FlashAttention-3-compatible APIs on top of MATE attention operators on MUSA | [wrapper README](wrappers/flash-attention/README.md), [compatibility summary](docs/flash_attention.md) |
107+
| `wrappers/SageAttention` | `sageattention` | `sageattention` | SageAttention-compatible dense quantized attention wrapper on top of MATE on MUSA | [wrapper README](wrappers/SageAttention/README.md) |
108+
| `wrappers/FlashMLA` | `flash_mla` | `flash_mla` | FlashMLA-compatible MLA dense/sparse decode and sparse prefill APIs on top of MATE MLA operators on MUSA | [wrapper README](wrappers/FlashMLA/README.md) |
109+
| `wrappers/DeepGEMM` | `deep-gemm` | `deep_gemm` | DeepGEMM-compatible APIs on top of MATE GEMM operators on MUSA | [wrapper README](wrappers/DeepGEMM/README.md) |
76110

77111
## Build Documentation
78112

benchmarks/bench_flash_attn.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,6 @@ def fn():
251251
pack_gqa=cfg.is_packgqa,
252252
deterministic=False,
253253
sm_margin=0,
254-
return_attn_probs=False,
255254
return_softmax_lse=False,
256255
backend=backend,
257256
)

benchmarks/bench_gdn_prefill.py

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
import argparse
2+
3+
import numpy as np
4+
import torch
5+
import torch.nn.functional as F
6+
7+
from mate.gdn_prefill import chunk_gated_delta_rule
8+
from mate.testing.utils import bench_kineto
9+
10+
11+
HEAD_CONFIGS = [
12+
# (h_qk, h_v, d, label)
13+
# Qwen3.5-397B and 122B (h_k=16, h_v=64, d=128) under different TP
14+
(2, 8, 128, "397B/122B TP8"),
15+
(4, 16, 128, "397B/122B TP4"),
16+
(8, 32, 128, "397B/122B TP2"),
17+
(16, 64, 128, "397B/122B TP1"),
18+
# Qwen3.5-35B, 9B and 4B (h_k=16, h_v=32, d=128)
19+
(16, 32, 128, "35B/9B/4B TP1"),
20+
# Qwen3.5-27B (h_k=16, h_v=48, d=128)
21+
(16, 48, 128, "27B TP1"),
22+
# Qwen3.5-2B and 0.8B (h_k=16, h_v=16, d=128)
23+
(16, 16, 128, "2B/0.8B TP1"),
24+
# Symmetric heads
25+
(32, 32, 128, "Sym h32"),
26+
]
27+
28+
SEQ_CONFIGS = [
29+
# (cu_seqlen_endpoints, label)
30+
# endpoints are cumulative positions (leading 0 added automatically)
31+
((8192,), "1x8192"),
32+
((4096,), "1x4096"),
33+
((2048,), "1x2048"),
34+
((1024 * 6, 8192), "6144+2048"),
35+
((1024 * 4, 8192), "4096+4096"),
36+
((1024 * 2, 8192), "2048+6144"),
37+
((1024 * 1, 8192), "1024+7168"),
38+
((2048, 2048 * 2, 2048 * 3, 8192), "2048x4"),
39+
(tuple(1024 * (i + 1) for i in range(8)), "1024x8"),
40+
]
41+
42+
43+
def _gdn_tflops(total_tokens: int, h_o: int, d: int, time_ms: float) -> float:
44+
# 2 GEMMs (kv outer product + q@state), MAC counted as 2 FLOPs.
45+
flops = 2 * 2 * total_tokens * h_o * d * d
46+
return flops / time_ms / 1e9
47+
48+
49+
def bench_mate(
50+
endpoints: tuple[int, ...],
51+
h_qk: int,
52+
h_v: int,
53+
d: int,
54+
chunk_size: int,
55+
dtype: torch.dtype,
56+
num_tests: int,
57+
) -> float:
58+
device = "musa"
59+
num_seqs = len(endpoints)
60+
total_tokens = endpoints[-1]
61+
head_o = max(h_qk, h_v)
62+
63+
cu_seqlens = torch.tensor([0] + list(endpoints), dtype=torch.int32, device=device)
64+
65+
q = torch.randn((total_tokens, h_qk, d), dtype=dtype, device=device)
66+
k = F.normalize(
67+
torch.randn((total_tokens, h_qk, d), dtype=torch.float32, device=device),
68+
p=2,
69+
dim=-1,
70+
).to(dtype)
71+
v = torch.randn((total_tokens, h_v, d), dtype=dtype, device=device)
72+
alpha = torch.exp(
73+
-torch.rand(total_tokens, head_o, dtype=torch.float32, device=device)
74+
)
75+
beta = torch.sigmoid(
76+
torch.randn(total_tokens, head_o, dtype=torch.float32, device=device)
77+
)
78+
h0 = torch.randn((num_seqs, head_o, d, d), dtype=torch.float32, device=device)
79+
out = torch.empty((total_tokens, head_o, d), dtype=dtype, device=device)
80+
state_out = torch.empty_like(h0)
81+
82+
kernel_times = bench_kineto(
83+
lambda: chunk_gated_delta_rule(
84+
q=q,
85+
k=k,
86+
v=v,
87+
g=alpha,
88+
beta=beta,
89+
scale=None,
90+
initial_state=h0,
91+
output_final_state=True,
92+
cu_seqlens=cu_seqlens,
93+
use_qk_l2norm_in_kernel=False,
94+
chunk_size=chunk_size,
95+
output=out,
96+
output_state=state_out,
97+
),
98+
kernel_names=(
99+
"fused_prepare_compute_w_u_kernel",
100+
"h_recurrence_kernel",
101+
"output_o_kernel",
102+
),
103+
num_tests=num_tests,
104+
suppress_kineto_output=True,
105+
flush_l2=True,
106+
with_multiple_kernels=True,
107+
)
108+
return float(np.sum(np.asarray(kernel_times, dtype=np.float64)))
109+
110+
111+
def main():
112+
parser = argparse.ArgumentParser(description="Benchmark mate.gdn_prefill")
113+
parser.add_argument("--chunk-size", type=int, default=64)
114+
parser.add_argument(
115+
"--num-tests",
116+
type=int,
117+
default=10,
118+
help="Number of profiling iterations for bench_kineto",
119+
)
120+
parser.add_argument(
121+
"--dtype",
122+
type=str,
123+
default="fp16",
124+
choices=["fp16", "bf16"],
125+
help="Input dtype for q/k/v",
126+
)
127+
args = parser.parse_args()
128+
129+
if not (hasattr(torch, "musa") and torch.musa.is_available()):
130+
raise RuntimeError("MUSA device is not available.")
131+
132+
dtype = torch.float16 if args.dtype == "fp16" else torch.bfloat16
133+
134+
print(f"\nMUSA: {torch.musa.get_device_name(0)}")
135+
print("Kernel: mate.gdn_prefill.chunk_gated_delta_rule")
136+
print(f"chunk_size={args.chunk_size}, dtype={args.dtype}")
137+
print()
138+
139+
header = (
140+
f"{'Heads':<15s} {'Seqlens':<16s} {'h_qk':>4s} {'h_v':>4s}"
141+
f" {'MATE (MUSA)':>12s} {'TFLOPS':>7s}"
142+
)
143+
print(header)
144+
print("-" * len(header))
145+
146+
for h_qk, h_v, d, h_label in HEAD_CONFIGS:
147+
for endpoints, s_label in SEQ_CONFIGS:
148+
total_tokens = endpoints[-1]
149+
mate_ms = bench_mate(
150+
endpoints=endpoints,
151+
h_qk=h_qk,
152+
h_v=h_v,
153+
d=d,
154+
chunk_size=args.chunk_size,
155+
dtype=dtype,
156+
num_tests=args.num_tests,
157+
)
158+
tflops = _gdn_tflops(total_tokens, max(h_qk, h_v), d, mate_ms)
159+
print(
160+
f"{h_label:<15s} {s_label:<16s} {h_qk:>4d} {h_v:>4d}"
161+
f" {mate_ms:>11.3f}ms {tflops:>6.1f}"
162+
)
163+
print()
164+
165+
166+
if __name__ == "__main__":
167+
main()

0 commit comments

Comments
 (0)