ref(upstream): FULL TREE — Deep-Spark xllm (1470) + ds_vllm csrc/models (703)

Replaces cherry-picked upstream_ref with complete source trees.

xllm/ — Iluvatar official C++ inference engine (15MB, 1470 files)
  Complete: kernels → layers → models → runtime → scheduler → api
  Excluded: .git, binary images, third_party submodule checkouts

ds_vllm/ — Iluvatar official vllm fork (8MB, 703 files)
  Included: csrc/ (ALL CUDA kernels), fused_moe/, qwen3_5 model, _custom_ops
  Excluded: tests, benchmarks, docs, examples (not needed for reference)

Critical call chains now fully traceable:
  MoE: moe_topk_softmax_kernels.cuh → ixformer.h → fused_moe.cpp → layer
  GDN: qwen3_gated_delta_net_base.cpp → qwen3_5_gated_delta_net.cpp
  Attention: ixformer.h → xllm_paged_attention → attention.cpp
This commit is contained in:
EX Engine
2026-08-10 02:53:54 +00:00
parent 9e4fb3712f
commit 002f9879b2
2179 changed files with 494021 additions and 79 deletions

View File

@@ -0,0 +1,48 @@
---
name: add-unit-test
description: Add or update xLLM unit tests in the repository. Use when Codex needs to create a new C++/CUDA/NPU/MLU unit test, place a test under tests/, wire it into CMake with cc_test, update an existing test target, choose platform gates, or validate test naming and dependencies against current xLLM test conventions.
---
# Add Unit Test
## Workflow
1. Inspect the production code and the nearest existing tests before writing a new test.
- Match the production path under `xllm/` to `tests/` where possible.
- Prefer extending an existing nearby `*_test.cpp` and `cc_test` target when the behavior belongs to the same domain.
- Create a new test source only when it improves isolation, keeps platform setup separate, or follows an existing directory pattern.
2. Read the project style guide before editing production files under `xllm/`, and apply the same C++ style discipline to new test code:
`.agents/skills/code-review/references/custom-code-style.md`.
3. Follow the current test layout and CMake conventions.
- Read [xllm-test-patterns.md](references/xllm-test-patterns.md) when adding a new test file, new `cc_test`, platform-specific test, or test directory.
- Use `*_test.cpp` for C++ test files and `*_test.cu` for CUDA source tests.
- Do not create nested `test/` or `tests/` directories for new unit tests unless the surrounding tree already requires that structure.
4. Wire tests through CMake with `include(cc_test)` and `cc_test(...)`.
- Keep source names relative to the current test directory unless an existing target already uses an absolute source path for a production `.cpp`.
- Use target names ending in `_test`.
- Put platform-directory gates in the parent `CMakeLists.txt` when the whole child directory is platform-specific.
- Use target-level `if(USE_NPU)`, `if(USE_MLU)`, `if(USE_CUDA)`, or generator expressions only when a mixed directory contains both generic and platform-specific tests.
5. Write tests for observable behavior, not implementation trivia.
- Cover success, edge, and error paths touched by the change.
- Prefer deterministic inputs, fixed seeds, and small tensors/data structures.
- Keep helpers file-local in an anonymous namespace unless shared by multiple test files.
- Use `TEST`/`TEST_F` names that describe behavior clearly.
6. Validate narrowly before finishing.
- Always run `git diff --check` for the changed test paths.
- Search for stale filenames after moving or renaming tests.
- Run the narrowest build/test command available locally; if not feasible, state the exact reason and what was checked instead.
## Common Commands
```bash
rg --files tests/<area>
rg "old_test_name|old_file_name" tests xllm CMakeLists.txt
git diff --check -- tests/<area>
```
For full remote validation on the development machine, use the repository AGENTS instructions for SSH, container, build, and test commands.

View File

@@ -0,0 +1,124 @@
# xLLM Unit Test Patterns
Use this reference when creating or changing unit tests under `tests/`.
## Layout
- Mirror production structure where practical:
- `xllm/core/framework/tokenizer` -> `tests/core/framework/tokenizer`
- `xllm/core/layers/mlu` -> `tests/core/layers/mlu`
- `xllm/function_call/...` -> `tests/function_call/...`
- Keep tests directly in the relevant leaf directory.
- Avoid new nested `test/` or `tests/` directories. Recent cleanup moved those tests into their parent directories.
- Shared helpers may live beside tests, such as `tests/core/layers/mlu/tests_utils.cpp`.
## Naming
- Test source files use singular suffixes:
- C++: `thing_test.cpp`
- CUDA source: `thing_test.cu`
- Test CMake target names also end in `_test`.
- If a target aggregates several source files, keep the target name at the domain level, for example `layer_test`, `moe_layer_test`, or `sampler_test`.
- Keep helper files out of the `*_test.cpp` suffix unless they define tests.
## CMake Basics
Use `cc_test` for C++/CUDA unit test binaries:
```cmake
include(cc_test)
cc_test(
NAME
feature_test
SRCS
feature_test.cpp
DEPS
:feature
GTest::gtest_main
glog::glog
)
```
Rules:
- Add `include(cc_test)` in each CMake file that declares `cc_test`.
- Use dependencies that match nearby tests first.
- Prefer `GTest::gtest_main`; add `GTest::gtest` only when nearby tests need it or the target explicitly uses it.
- Add `target_link_libraries(...)` and `add_dependencies(...)` after `cc_test` when needed for `brpc`, `OpenSSL`, `protobuf`, platform runtime libraries, or link-group handling.
- Use `:target_name` for local production CMake targets where existing tests do so.
## Platform Gates
Gate entire platform-only directories in the parent `CMakeLists.txt`.
Current examples:
```cmake
if(USE_CUDA)
add_subdirectory(cuda)
endif()
if(USE_NPU)
add_subdirectory(npu)
endif()
```
```cmake
if(USE_CUDA)
add_subdirectory(cuda)
endif()
if(USE_MLU)
add_subdirectory(mlu)
endif()
```
Do not repeat the same platform `if(...)` inside every child CMake file when the parent already gates the directory.
Use target-level platform gates only for mixed directories where generic and platform-specific tests coexist, such as `tests/core/runtime` or framework directories with both generic and NPU-only targets.
Use generator expressions for platform-specific optional link libraries when the target exists across platforms:
```cmake
target_link_libraries(example_test
PUBLIC
Python::Python
$<$<BOOL:${USE_NPU}>:ascendcl>
$<$<BOOL:${USE_NPU}>:hccl>
$<$<BOOL:${USE_NPU}>:c_sec>)
```
## Source Style
- Add the xLLM copyright header to new files, using the current year.
- Include `<gtest/gtest.h>` in every test source.
- Use project-root-relative includes; avoid `../` includes.
- Put file-local helpers in an anonymous namespace.
- Prefer fixed-width integers (`int32_t`, `int64_t`) unless an API requires plain `int`.
- Use `static_cast`, `nullptr`, braces on all control statements, and concise comments only where they clarify test setup.
- Keep deterministic random or tensor tests seeded with stable labels or fixed seeds.
## Test Design
- Test behavior through public or stable internal interfaces used by nearby tests.
- Cover the regression or edge case that motivated the test.
- For parser and pure logic tests, keep inputs small and assert exact outputs/errors.
- For tensor/device tests, keep tensor shapes small, check dtype/device expectations, and compare against a simple reference implementation.
- For forked-process or device-init-sensitive tests, follow nearby standalone target patterns and leave a short CMake comment explaining why the target is isolated.
## Validation Checklist
Before finishing:
```bash
rg --files tests/<area>
rg "old_file_name|old_target_name" tests xllm CMakeLists.txt
git diff --check -- tests/<area>
```
Run the narrowest feasible validation:
- Local CMake/build target if available.
- `python setup.py test` in the project container when full validation is requested or risk is high.
- For development-machine validation, follow the repo AGENTS instructions for `ssh gpu-h800-195`, `/export/home/zhangxu709/xllm`, container `zx-xllm-cuda`, and the build/test commands.

View File

@@ -0,0 +1,115 @@
---
name: code-review
description: Review code changes for quality, security, performance, and correctness following project-specific standards. Use when reviewing pull requests, examining git diffs, or when the user asks for a code review. This skill should be used proactively — when the user asks for a review without specifying commits, automatically detect the current branch and diff against the main branch.
---
# Code Review
## Workflow
### Step 1: Determine the diff
If the user provides explicit SHAs or a PR link, use those. Otherwise, **auto-detect**:
```bash
# Fetch latest remote state
git fetch origin main --quiet
# Detect current branch
CURRENT_BRANCH=$(git branch --show-current)
# Find the merge base with origin/main
MERGE_BASE=$(git merge-base origin/main HEAD)
# Show what changed
git diff --stat $MERGE_BASE..HEAD
git diff $MERGE_BASE..HEAD
```
If `CURRENT_BRANCH` is `main`, warn the user and ask which commits to review.
### Step 2: Read project standards
Read [custom-code-style.md](references/custom-code-style.md) for project-specific coding style.
### Step 3: Review against the checklist
**Correctness:**
- Logic handles edge cases and boundary conditions
- Error handling is comprehensive (no silent failures)
- Type safety maintained (no unsafe casts, proper use of `std::optional`)
- Resource lifecycle correct (RAII, no leaks, proper cleanup order)
**Architecture:**
- Clean separation of concerns, no layer violations
- Dependencies flow in the correct direction
- Changes align with existing patterns in the codebase
- No unnecessary coupling introduced
**Performance & Concurrency:**
- No performance regressions on hot paths
- Thread safety: proper locking, no data races
- CUDA/NPU kernels: memory coalescing, occupancy, sync correctness
- No unnecessary copies of large objects (tensors, vectors)
**Testing:**
- Tests verify actual logic, not just mock wiring
- Edge cases and error paths covered
- Integration tests for cross-component changes
**Production Readiness:**
- Backward compatibility maintained (or breaking changes documented)
- Migration strategy for schema/config changes
- No hardcoded values that should be configurable
### Step 4: Output findings
Use the format below.
## Output Format
### Strengths
[Specific things done well, with file:line references]
### Issues
#### Critical (Must Fix)
[Bugs, security holes, data loss risks, broken functionality]
#### Important (Should Fix)
[Architecture problems, missing error handling, test gaps, performance issues]
#### Minor (Nice to Have)
[Style, optimization opportunities, documentation improvements]
**Each issue must include:**
- **File:line** reference
- **What** is wrong
- **Why** it matters
- **How** to fix (if not obvious)
### Recommendations
[Broader improvements for code quality, architecture, or process]
### Assessment
**Ready to merge?** [Yes / No / With fixes]
**Reasoning:** [1-2 sentence technical assessment]
## Rules
**DO:**
- Apply project-specific style from [custom-code-style.md](references/custom-code-style.md)
- Follow DDD (Domain Driven Design) principles, and keep the codebase clean and maintainable
- Categorize by actual severity (not everything is Critical)
- Be specific with file:line references
- Explain WHY issues matter
- Acknowledge strengths
- Give a clear verdict
**DON'T:**
- Approve without thorough review
- Mark nitpicks as Critical
- Give feedback on code not in the diff
- Be vague (e.g., "improve error handling" without specifics)

View File

@@ -0,0 +1,316 @@
# Custom Code Style
Project-specific coding style for xllm. The reviewer **MUST** enforce these style.
---
## 1. Naming Conventions
### C++
| Element | Style | Example |
|------------------|------------------------------------|--------------------------------------|
| Namespace | `snake_case` | `xllm`, `xllm::detail` |
| Class / Struct | `PascalCase` | `LlmModelImplBase`, `KVCache` |
| Function | `snake_case` | `get_input_embeddings`, `forward` |
| Member variable | `snake_case_` (trailing underscore)| `model_type_`, `embed_tokens_` |
| Local variable | `snake_case` | `inputs_embeds`, `kv_caches` |
| Constant | `k` + `PascalCase` | `kContentLength`, `kMaxBatchSize` |
| Enum type | `PascalCase` | `EngineType`, `DeviceType` |
| Enum value | `ALL_CAPS` | `LLM`, `VLM`, `INVALID` |
| Template param | `PascalCase` | `DecoderLayerType` |
| Macro | `ALL_CAPS` | `XLLM_CHECK`, `LOG_EVERY_N` |
| File name | `snake_case` | `llm_model_base.h`, `types.h` |
| Header guard | `#pragma once` | - |
### Python
| Element | Style | Example |
|------------------|------------------------|--------------------------------------|
| Module / file | `snake_case` | `model_loader.py` |
| Class | `PascalCase` | `TokenizerConfig` |
| Function | `snake_case` | `load_model` |
| Variable | `snake_case` | `batch_size` |
| Constant | `ALL_CAPS` | `MAX_SEQ_LEN` |
| Private member | `_leading_underscore` | `_internal_state` |
---
## 2. File & Header Rules
- **Copyright header required** on all new files. Use the correct year matching the file creation date.
```cpp
/* Copyright 2025 The xLLM Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
...
==============================================================================*/
```
- **No relative paths in `#include`**. Always use project-root-relative paths.
```cpp
// Good
#include "core/common/types.h"
// Bad
#include "../common/types.h"
#include "./types.h"
```
- **Remove redundant and duplicate includes**. Each header should be included exactly once, and unused includes must be cleaned up.
---
## 3. Type System & Declarations
- **Use fixed-width integers** (`int32_t`, `int64_t`) instead of plain `int`, unless the API you are calling explicitly requires `int`.
```cpp
// Good
int32_t batch_size = 16;
int64_t total_tokens = 0;
// Bad
int batch_size = 16;
```
- **Use `static_cast`** for all type conversions. Never use C-style casts.
```cpp
// Good
auto len = static_cast<int32_t>(vec.size());
// Bad
auto len = (int32_t)vec.size();
```
- **Do not use `auto` for simple/primitive types**. `auto` is acceptable for complex types (iterators, lambdas, template-deduced types) but not for `int32_t`, `float`, `bool`, `std::string`, etc.
```cpp
// Good
int32_t count = 0;
auto it = map.find(key); // complex iterator type, auto is fine
// Bad
auto count = 0;
auto name = std::string("model");
```
- **Use `using` instead of `typedef`** for type aliases. Prefer aliases for complex types to improve readability.
```cpp
// Good
using TensorVec = std::vector<torch::Tensor>;
using CallbackFn = std::function<void(int32_t)>;
// Bad
typedef std::vector<torch::Tensor> TensorVec;
```
- **Use `enum class`** instead of plain `enum` to provide type safety and prevent implicit conversions.
```cpp
// Good
enum class DeviceType : int8_t { CPU = 0, CUDA = 1, NPU = 2 };
// Bad
enum DeviceType { CPU = 0, CUDA = 1, NPU = 2 };
```
- **Use `nullptr`** instead of `NULL` or `0` for null pointers.
- **Choose the right container**: use `std::unordered_map` / `std::unordered_set` when key ordering is irrelevant (O(1) average lookup). Use `std::map` / `std::set` only when sorted iteration or key ordering is required.
---
## 4. Class Design
- **Mark classes `final`** if they are not designed to be inherited from.
```cpp
// Good
class TokenizerConfig final { ... };
// Bad class has no virtual functions and is not intended as a base
class TokenizerConfig { ... };
```
- **Use `explicit`** on any constructor that can be invoked with a single argument. This includes multi-parameter constructors where all parameters except the first have default values.
```cpp
// Good
explicit ModelArgs(const std::string& path, int32_t num_layers = 12);
// Bad allows implicit conversion from std::string
ModelArgs(const std::string& path, int32_t num_layers = 12);
```
- **Use `override`** when overriding virtual functions in derived classes. Never repeat the `virtual` keyword on overrides.
```cpp
// Good
ModelOutput forward(torch::Tensor tokens, ...) override;
// Bad
virtual ModelOutput forward(torch::Tensor tokens, ...);
```
- **Structs must not have member functions**. If you need methods, use a `class`. Structs are for plain data aggregation only.
---
## 5. Memory & Resource Management
- **Avoid raw pointers**. Prefer smart pointers (`std::unique_ptr`, `std::shared_ptr`) for ownership semantics.
- Use `std::unique_ptr` by default (sole ownership).
- Use `std::shared_ptr` only when shared ownership is genuinely needed.
- Raw pointers are acceptable only for non-owning references where the lifetime is clearly managed elsewhere.
---
## 6. Scoping & Visibility
### C++
- **File-local functions and variables** (used only within a single `.cpp` file) must be placed in an **anonymous namespace**.
```cpp
namespace {
int32_t compute_padding(int32_t seq_len, int32_t alignment) {
return (alignment - seq_len % alignment) % alignment;
}
} // namespace
```
### Python
- **File-local helper functions** (not part of the public API) must be prefixed with `_`.
- **Non-public member functions** of a class must be prefixed with `_`.
```python
def _validate_config(config: dict) -> bool:
...
class ModelLoader:
def load(self, path: str) -> Model:
self._check_path(path)
...
def _check_path(self, path: str) -> None:
...
```
---
## 7. Torch & Framework API Usage
- **Use `torch::` namespace** instead of `at::` or `c10::` wherever possible. Prefer the highest-level PyTorch C++ API.
```cpp
// Good
torch::Tensor output = torch::zeros({batch_size, hidden_dim});
// Bad
at::Tensor output = at::zeros({batch_size, hidden_dim});
c10::optional<torch::Tensor> mask = c10::nullopt; // use std::optional
```
- **Use `CHECK`** (glog) instead of `TORCH_CHECK` for assertions.
```cpp
// Good
CHECK(tensor.is_contiguous()) << "Input tensor must be contiguous";
// Bad
TORCH_CHECK(tensor.is_contiguous(), "Input tensor must be contiguous");
```
- **Use `LOG(FATAL)`** for unrecoverable errors instead of throwing `std::runtime_error`.
```cpp
// Good
LOG(FATAL) << "Unsupported model type: " << model_type;
// Bad
throw std::runtime_error("Unsupported model type: " + model_type);
```
---
## 8. Code Style & Control Flow
- **Always use braces `{}`** with `if`, `while`, `for`, even for single-line bodies.
```cpp
// Good
if (x > 0) {
return x;
}
// Bad
if (x > 0) return x;
```
- **Avoid `if` inside `for` loops** when possible. Prefer filtering the data beforehand or restructuring the logic (e.g., early `continue`, separate loops, `std::copy_if`).
- **Define variables close to first use**. Do not declare all variables at the top of a function.
- **Annotate constant arguments** with a comment indicating the parameter name when calling functions or constructors.
```cpp
// Good
auto layer = DecoderLayer(/*hidden_size=*/4096, /*num_heads=*/32);
// Bad
auto layer = DecoderLayer(4096, 32);
```
---
## 9. STL Best Practices
- **Always `reserve()` before filling a `std::vector`** when the size is known or can be estimated.
```cpp
// Good
std::vector<torch::Tensor> outputs;
outputs.reserve(num_layers);
for (int32_t i = 0; i < num_layers; ++i) {
outputs.emplace_back(compute_layer(i));
}
// Bad causes multiple reallocations
std::vector<torch::Tensor> outputs;
for (int32_t i = 0; i < num_layers; ++i) {
outputs.push_back(compute_layer(i));
}
```
- **Prefer `emplace_back`** over `push_back` to construct elements in-place and avoid unnecessary copies.
---
## 10. Global Flags
- **Do not overuse `FLAGS_` global variables**. Prefer passing configuration through constructor parameters or config structs. Only use global flags for top-level, process-wide settings.
- **Register new flags in `help_formatter.h`**. When adding a new global flag, always add a corresponding entry in `help_formatter.h` so it appears in `--help` output.
---
## 11. Python-Specific Rules
- **Type annotations are required** on all function signatures (parameters and return types). Use `typing` module types where needed.
```python
# Good
def load_model(path: str, device: str = "cuda") -> nn.Module:
...
# Bad
def load_model(path, device="cuda"):
...
```
- **Private helpers**: prefix with `_` (see Section 6).

View File

@@ -0,0 +1,49 @@
---
name: git-workflow
description: Use when the task involves Git operations for the public xLLM repository, including choosing branch or tag names, preparing commits and pull requests, backporting fixes, checking repo-specific review expectations, or drafting commit messages from actual diffs.
---
# Git Workflow
Use xLLM repo reality, not generic Git habits.
## Reference Map
Load only the file that matches the user's immediate Git task.
| File | What it is for | When to load it |
| --- | --- | --- |
| `references/source-of-truth.md` | Repo-specific source priority and canonical files to consult | Load first when repo docs, local state, and user wording may disagree |
| `references/branch-naming.md` | Branch naming patterns and default branch conventions | Load when the user asks how to name a branch or which branch to branch from |
| `references/development-flow.md` | Day-to-day fork, sync, branch, validate, and push flow | Load when the user asks for normal development steps from local change to push |
| `references/pr-review.md` | PR targeting, PR scope, and review expectations | Load when the task is about opening a PR, choosing the target branch, or deciding who should review |
| `references/release-layout.md` | Release branch and tag shapes used by xLLM | Load when the task mentions release branches, release tags, or patch version naming |
| `references/backport-flow.md` | Preferred backport and hotfix flow for released lines | Load when the task mentions cherry-picks, hotfixes, or fixing an already released branch |
| `references/commit-format.md` | Commit title/body conventions and xLLM-style examples | Load when the user asks for a commit message, commit style guidance, or message cleanup |
## Workflow
1. Decide which subtask the user actually needs.
2. Read `references/source-of-truth.md` when you need repo-specific confirmation.
3. Then load only the most relevant task file from the table above.
4. For commit message drafting, run `bash scripts/collect_git_context.sh [--staged|--all|--unstaged]` before writing the final message.
5. Draft commit messages from the actual diff, not from filenames alone.
6. If one diff mixes unrelated concerns, recommend splitting the commit instead of forcing one vague summary.
7. Default PR targets to `main` unless the task is clearly a release or backport flow.
8. For released lines, prefer landing on `main` first and then backporting unless the user explicitly wants a direct hotfix flow.
## Output
Return the smallest useful answer for the user's Git task:
- workflow questions: concrete branch, tag, PR, or backport steps
- commit message requests: `<type>: <subject>` plus an optional short bullet body
- repo-convention questions: current xLLM-specific guidance, not generic Git advice
## Quick Checks
- branch names match xLLM style such as `feat/<topic>`, `bugfix/<topic>`, or `release/vX.Y.Z`
- PR target is `main` unless this is a release or backport task
- commit title matches the dominant change in the diff
- release tags use semantic versions such as `v0.9.0` or `v0.9.1`
- owner-review expectations come from `.github/CODEOWNERS` when relevant

View File

@@ -0,0 +1,30 @@
# Backport Flow
When a released line needs a bugfix, prefer this flow:
1. land the fix on `main` first unless the user explicitly needs a direct hotfix flow
2. cherry-pick or backport the fix to the matching `release/vX.Y.Z` branch
3. update release content as needed on that release branch
4. create the next patch tag for that release line
Example shape:
```bash
# land on main first
git checkout main
git pull --rebase upstream main
git checkout -b bugfix/<topic>
git commit -m "bugfix: fix <summary>."
# then backport
git checkout release/v0.9.0
git pull --rebase upstream release/v0.9.0
git cherry-pick <bugfix_commit>
git tag v0.9.1
```
## Quick Checklist
- backport from a commit already landed on `main` when possible
- cherry-pick onto the matching `release/vX.Y.Z` branch
- use the next semantic patch tag for the release line

View File

@@ -0,0 +1,54 @@
# Branch Naming
Use one of these branch shapes:
```text
<type>/<topic>
<namespace>/<type>/<topic>
preview/<topic>
release/vX.Y.Z
```
Recommended lowercase branch types:
- `feat`: new user-visible capability or feature work
- `bugfix`: incorrect behavior, regressions, or hot fixes
- `refactor`: structural changes without intended behavior changes
- `docs`: documentation-only work when a dedicated branch is useful
- `test`: test-only work when separated from product changes
- `perf`: runtime or memory improvements
- `chore`: repo maintenance that does not fit the other categories
- `build`: dependency, CI, packaging, or release tooling changes
Topic guidelines:
- use lowercase letters, numbers, and hyphens by default
- keep the topic short, specific, and review-friendly
- prefer nouns or short noun phrases like `scheduler`, `lm-head-new`, `npu-template`
- avoid spaces, uppercase letters, and vague names like `misc`, `temp`, `test-branch`
- avoid repeating the type in the topic, such as `feat/feature-x`
- use slash-separated namespace prefixes only when the work clearly belongs to a scoped stream
Scoped branch guidelines:
- use `<namespace>/<type>/<topic>` for team-, model-, or project-scoped work such as `dsv4/feat/rope-dsv4`
- keep the namespace stable and meaningful, not personal or temporary
- use `preview/<topic>` only for preview-track work that intentionally aligns with preview branches upstream
- reserve `release/vX.Y.Z` for release preparation or release-only changes
- avoid direct development on `main` and `release/*` unless the user explicitly asks for it
Examples:
- `feat/skills`
- `feat/lm_head_new`
- `bugfix/scheduler`
- `refactor/npu_template`
- `preview/glm-5`
- `release/v0.9.0`
Notes for xLLM:
- `main` is the default development branch
- `feat/*`, `bugfix/*`, and `refactor/*` appear in current branch usage and are safe defaults
- `preview/*` and `release/*` are long-lived integration branches, not ordinary personal topic branches
- both hyphen and underscore appear in existing history, but prefer hyphens for new branch topics unless matching an established naming family

View File

@@ -0,0 +1,56 @@
# Commit Format
Use this exact first-line format:
```text
<type>: <subject>
```
Allowed lowercase types:
- `feat`: add user-visible behavior or a new capability
- `bugfix`: correct incorrect behavior or a regression
- `docs`: change documentation only
- `test`: add or update tests only
- `refactor`: improve structure without changing intended behavior
- `chore`: repository maintenance that does not fit the other types
- `style`: formatting or style-only changes without logic changes
- `revert`: revert an earlier commit
- `perf`: improve runtime or memory behavior
- `model`: change model definitions, checkpoints, prompts, or inference behavior
- `build`: change build, release, or dependency wiring
- `release`: change release versioning, release notes, or release-only metadata
Subject guidelines:
- use lowercase letters by default
- include at least 4 words
- end with a period
- start with a verb like `add`, `fix`, `remove`, `refactor`, `document`
- keep it specific enough that a reviewer understands the main change
- avoid filler like `update`, `misc`, `stuff`, `changes`
- describe the effect or intent, not a mechanical file list
Body guidelines:
- add a body only when the title alone is not enough
- use short bullets for secondary details or important context
- mention follow-up work, migration steps, or compatibility impact when relevant
- if confidence is low because the diff is partial or noisy, say that explicitly
Observed xLLM-style examples:
- `feat: add rope_in_place tilelang kernel for npu device. (#964)`
- `bugfix: align rec initialization flags with options. (#1142)`
- `docs: update the document to align them with the latest code. (#1113)`
- `refactor: extract multi-modal input processors to processors dir. (#1022)`
- `perf: reserve vector capacity before batch push_back. (#1089)`
- `release: update xllm release version to v0.9.0. (#1124)`
- `feat: support qwen3.5/qwen3.5-moe mtp draft model for speculative decoding[3/N]. (#1119)`
Notes for xLLM:
- `bugfix:` appears more often than `fix:` in current history and should be the default bug-repair prefix
- `fix:` exists in a few historical commits but is less consistent than `bugfix:`
- PR-number suffixes like `(#1142)` are common in merged history but are optional unless the user explicitly wants them
- staged series markers like `[1/N]` or `[3/N]` appear when a change is intentionally split across multiple commits

View File

@@ -0,0 +1,33 @@
# Development Flow
Follow this sequence unless the user asks for a different workflow:
1. fork the upstream repository
2. sync local `main` with `upstream/main`
3. create a focused topic branch from `main`
4. implement the change
5. run formatting and the narrowest relevant validation
6. commit in clear English
7. push to the fork
8. open a PR to upstream `main`
Example commands:
```bash
git fetch upstream
git checkout main
git pull --rebase upstream main
git checkout -b feat/<topic>
# after development
git add <files>
git commit -m "feat: add <change summary>."
git push origin feat/<topic>
```
## Quick Checklist
- branch from `main` unless this is a release or backport task
- keep the branch focused on one change
- run the narrowest relevant validation before commit
- push to your fork before opening the PR

View File

@@ -0,0 +1,28 @@
# PR And Review
## Pull Request Guidance
The public repo guidance is lightweight:
- `README.md` and `CONTRIBUTING.md` ask contributors to fork, create a branch, and send a pull request
- keep PRs focused and easy to review, even though the public docs do not publish a hard line-count limit
- write commit messages and PR descriptions in clear English
- avoid unnecessary merge noise in branch history; prefer a clean linear history when practical
## Target Branch
- use `main` unless this is explicitly a release or backport task
## Review Expectations
Use `.github/CODEOWNERS` as the visible review signal:
- changes under `/xllm/` have listed code owners
- expect owner review or owner attention for those paths
- if the user asks who should review a change under `/xllm/`, check `CODEOWNERS`
## Quick Checklist
- PR target is `main` unless this is a backport or release task
- PR is focused and clearly described
- review expectations are checked through `CODEOWNERS`

View File

@@ -0,0 +1,15 @@
# Release Layout
Observed public release layout:
- release branches use `release/vX.Y.Z`
- observed release branches include `release/v0.6.0`, `release/v0.7.0`, `release/v0.8.0`, and `release/v0.9.0`
- release notes are tracked in `RELEASE.md`
- public tags use semantic version tags such as `v0.9.0`
- patch tags use normal patch versions such as `v0.7.1` and `v0.7.2`, not `-rcN`
## Naming Guardrails
- do not switch to `release_0.1.0` branches unless the user explicitly wants an older internal workflow
- do not assume `v0.1.0-rc0` style tags unless the user explicitly asks for them
- prefer the next semantic patch tag for bugfix releases

View File

@@ -0,0 +1,29 @@
# Source Of Truth
Use these repo files first when the user asks for xLLM-specific Git guidance:
- `README.md`
- `CONTRIBUTING.md`
- `RELEASE.md`
- `.github/workflows/check_format.yml`
- `.pre-commit-config.yaml`
- `.github/CODEOWNERS`
Guidance priority:
1. direct user request
2. current repo files and branch reality
3. visible remote repo conventions
4. older internal notes or remembered habits
When repo docs, local repo state, and user wording disagree:
- say the conflict explicitly
- prefer the most concrete source available
- avoid inventing rules that are not visible in the public repo
Common examples of rules you should not assume without evidence:
- rebase-only or squash-only merge requirements
- mandatory reviewer counts beyond what `CODEOWNERS` implies
- old naming patterns such as `features/*`, `release_0.1.0`, or `v0.1.0-rc0`

View File

@@ -0,0 +1,104 @@
#!/usr/bin/env bash
set -euo pipefail
mode="auto"
if [[ $# -gt 1 ]]; then
echo "usage: $0 [--staged|--all|--unstaged]" >&2
exit 1
fi
if [[ $# -eq 1 ]]; then
case "$1" in
--staged)
mode="staged"
;;
--all)
mode="all"
;;
--unstaged)
mode="unstaged"
;;
*)
echo "unknown option: $1" >&2
echo "usage: $0 [--staged|--all|--unstaged]" >&2
exit 1
;;
esac
fi
if ! git rev-parse --show-toplevel >/dev/null 2>&1; then
echo "not inside a git repository" >&2
exit 1
fi
repo_root="$(git rev-parse --show-toplevel)"
cd "$repo_root"
staged_count="$(git diff --cached --name-only | wc -l | tr -d ' ')"
untracked_files="$(git ls-files --others --exclude-standard)"
if [[ "$mode" == "auto" ]]; then
if [[ "$staged_count" != "0" ]]; then
mode="staged"
else
mode="all"
fi
fi
case "$mode" in
staged)
status_cmd=(git diff --cached --name-status)
stat_cmd=(git diff --cached --stat)
patch_cmd=(git diff --cached --unified=1 --no-color)
headline="staged changes"
;;
unstaged)
status_cmd=(git diff --name-status)
stat_cmd=(git diff --stat)
patch_cmd=(git diff --unified=1 --no-color)
headline="unstaged changes"
;;
all)
headline="all local changes"
;;
*)
echo "invalid mode: $mode" >&2
exit 1
;;
esac
echo "repo: $repo_root"
echo "branch: $(git branch --show-current)"
echo "scope: $headline"
echo
echo "status:"
git status --short
echo
if [[ -n "$untracked_files" ]]; then
echo "untracked files:"
printf '%s\n' "$untracked_files"
echo
fi
if [[ "$mode" == "all" ]]; then
echo "changed files:"
git diff HEAD --name-status
echo
echo "diff stat:"
git diff HEAD --stat
echo
echo "patch excerpt:"
git diff HEAD --unified=1 --no-color | sed -n '1,400p'
else
echo "changed files:"
"${status_cmd[@]}"
echo
echo "diff stat:"
"${stat_cmd[@]}"
echo
echo "patch excerpt:"
"${patch_cmd[@]}" | sed -n '1,400p'
fi

View File

@@ -0,0 +1 @@
../../third_party/tilelang-ascend/.agents/skills/tilelang-custom-skill/tilelang-api-best-practices

View File

@@ -0,0 +1,140 @@
---
name: tilelang-ascend-kernel
description: Use when the user wants to add, modify, debug, or review an xLLM TileLang Ascend kernel or specialization, including Python kernel definitions, generated Ascend-C source, runtime wrapper dispatch, TileLang CMake wiring, and NPU tests.
---
# TileLang Ascend Kernel
## When to use
Use this skill when the task involves any of the following in the xLLM repo:
- `xllm/compiler/tilelang/targets/ascend/kernels/*.py`
- `xllm/core/kernels/npu/tilelang/*_wrapper.cpp`
- `xllm/core/kernels/npu/tilelang/CMakeLists.txt`
- generated TileLang artifacts such as `manifest.json`, `registry.inc`, or specialization `.cpp`
Run build and test commands inside the NPU container.
Run TileLang commands from the xLLM repo root, not from an installed-package environment.
## Entry points and TL_ROOT
- Prefer `python xllm/compiler/tilelang_launcher.py ...` for end-to-end TileLang compile flows.
- From the xLLM repo root, use `export TL_ROOT=$PWD/third_party/tilelang-ascend` for xLLM TileLang tooling and verify `test -f "$TL_ROOT/tilelang/__init__.py"`.
- Before any raw script does `import tilelang`, run `export TL_ROOT=$PWD/third_party/tilelang-ascend && source third_party/tilelang-ascend/set_env.sh`, then execute the script.
- Do not run kernel files directly with `python rope.py`; use module execution because these files rely on relative imports.
- For direct kernel-script debugging, run them as modules and pass required CLI args:
```bash
cd xllm
python -m compiler.tilelang.targets.ascend.kernels.rope \
--output ../.tmp/rope.cpp
# Expected: [INFO] RoPE output matches torch reference
```
- The same module-style rule applies to other kernel files under `xllm/compiler/tilelang/targets/ascend/kernels/`.
## Primary Reference And Mode Preference
Primary reference:
- `third_party/tilelang-ascend/docs/TileLang-Ascend Programming Guide.md`
Use `third_party/tilelang-ascend/.agents/skills/tilelang-custom-skill/tilelang-api-best-practices/references/api-tile-ops.md` when the task depends on `T.tile.xxx` semantics such as `compare`, `select`, `cast`, or other vector intrinsics.
Default to Expert mode for xLLM Ascend kernels:
- prefer `T.tile.xxx`, explicit UB/shared allocation, and explicit `T.copy`
- prefer explicit `T.serial` control for row/block traversal
- do not introduce Developer mode `T.Parallel` unless the kernel is a clearly tile-local element-wise expression and the change does not reduce control over UB usage, temporary buffers, or exact runtime semantics
- when translating Triton kernels, preserve the Triton runtime semantics first, then choose the smallest Expert-mode lowering that matches them
## Common Triton To TileLang-Ascend Semantics
Use this table as the quick semantic mapping when translating Triton kernels:
| Triton pattern | TileLang-Ascend pattern | Notes |
| --- | --- | --- |
| `x + y`, `x - y`, `x * y`, `x / y` | `T.tile.add/sub/mul/div` | Prefer tile ops in Expert-style vector code instead of hand-written scalar loops. |
| `tl.exp(x)`, `tl.log(x)`, `tl.abs(x)` | `T.tile.exp`, `T.tile.ln`, `T.tile.abs` | TileLang uses `ln`, not `log`. |
| `x.to(tl.float32)` or `tl.cast(...)` | `T.tile.cast(dst, src, "CAST_NONE", count)` | Pick a non-default cast mode only when rounding semantics are required. |
| `x <= y`, `x < y`, `x >= y`, `x == y` | `T.tile.compare(mask, x, y, "LE"/"LT"/"GE"/"EQ")` | `T.tile.compare` produces a bit mask, not a float tensor. |
| `tl.where(cond, a, b)` | `T.tile.select(dst, selMask, a, b, selMode)` | API-level match. If `cond` is a comparison expression such as `x <= y`, materialize `selMask` with `T.tile.compare(...)` first; use the matching `VSEL_*` mode for tensor-tensor or tensor-scalar selection. |
| `tl.full(shape, value, dtype)` | allocate buffer + `T.tile.fill(dst, value)` | Separate allocation from initialization. |
| `tl.arange(0, N)` | `T.tile.createvecindex(dst, 0)` or explicit loop indices | Prefer `createvecindex` only when the kernel truly needs a vector index tensor. |
Rules for semantic-preserving lowering:
- Preserve Triton control-flow, masking, and parameter semantics. Do not substitute a numerically similar formula unless the runtime-visible behavior is unchanged for the supported input domain.
- Keep the kernel ABI aligned with the lowering. Every runtime parameter must either participate in the TileLang implementation or be removed from the interface.
- Add targeted tests for branch, mask, and boundary behavior. Do not rely only on random inputs if some paths are hit only under specific values.
- Choose the correct `VSEL_*` mode based on the source operands. `VSEL_CMPMASK_SPR` is the natural match for a mask produced by `T.tile.compare`; `VSEL_TENSOR_SCALAR_MODE` and `VSEL_TENSOR_TENSOR_MODE` are for explicit tensor/scalar or tensor/tensor selection modes.
## New kernel
Follow this order:
1. Implement `build_<kernel>_kernel(...)`
2. Implement `generate_source(...)`
3. Declare `DISPATCH_SCHEMA` and `SPECIALIZATIONS`
4. Run TileLang compilation once and inspect `registry.inc`
5. Add or update `<kernel>_wrapper.cpp`
6. Register the kernel in `xllm/core/kernels/npu/tilelang/CMakeLists.txt` with:
- `tilelang_register_runtime_kernel(NAME <kernel> WRAPPER_SRCS <srcs...>)`
For wrapper work:
- do kernel precision alignment on the Python side first (`build_<kernel>_kernel(...)` / `generate_source(...)`), not in the C++ wrapper
- handwrite tensor checks, layout transforms, and `build_runtime_specialization(...)`
- use generated `make_<kernel>_specialization(...)` and `find_<kernel>_kernel_entry(...)`
- do not handwrite kernel-specific specialization structs or kernel fn typedefs
- **never use `permute`, `contiguous`, `transpose`, `reshape` (when non-trivial), `clone`, or any operation that triggers a device memory copy in the wrapper**. The wrapper must only pass pointers to existing tensors. If the kernel needs a different layout, handle it inside the kernel itself or require the caller to provide the correct layout.
## New specialization
Use this path when the kernel logic and wrapper ABI stay the same.
1. Update the existing kernel's `SPECIALIZATIONS`
2. Confirm every runtime dispatch field still matches `DISPATCH_SCHEMA`
3. Re-run TileLang compilation
4. Check that `registry.inc` contains the new entry
5. Check that the wrapper's `build_runtime_specialization(...)` still constructs matching values
## Debug generated Ascend-C
When the task is to inspect codegen or compare two kernel implementations, use an isolated output root:
```bash
python xllm/compiler/tilelang_launcher.py compile-kernels \
--target ascend \
--device a3 \
--output-root .tmp/tilelang_debug \
--kernels <kernel> \
--force
```
Then inspect:
- `.tmp/tilelang_debug/targets/ascend/<kernel>/<variant_key>/<kernel>_<variant_key>_kernel.cpp`
- `.tmp/tilelang_debug/targets/ascend/<kernel>/registry.inc`
- `.tmp/tilelang_debug/targets/ascend/<kernel>/manifest.json`
Use this path before changing wrapper code when you need to understand generated symbols, field order, or ABI.
## Validate
Prefer the narrowest command first:
- `python -m py_compile xllm/compiler/tilelang/targets/ascend/kernels/<kernel>.py`
- `cd xllm && python -m compiler.tilelang.targets.ascend.kernels.<kernel> --output ../.tmp/<kernel>.cpp`
- `python xllm/compiler/tilelang_launcher.py prepare-ascend`
- `python setup.py test --test-name <wrapper_test_target> --device npu`
## References
Read `docs/en/dev_guide/tilelang_ascend_kernel_dev.md` for mechanism details.
Use `rope` as the concrete template:
- `xllm/compiler/tilelang/targets/ascend/kernels/rope.py`
- `xllm/core/kernels/npu/tilelang/rope_wrapper.cpp`
- `xllm/core/kernels/npu/tilelang/CMakeLists.txt`

View File

@@ -0,0 +1 @@
../../third_party/tilelang-ascend/.agents/skills/tilelang-custom-skill/tilelang-debug-helper

View File

@@ -0,0 +1 @@
../../third_party/tilelang-ascend/.agents/skills/tilelang-custom-skill/tilelang-expert-to-developer