Reference files in this skill directory
When executing this skill, priority should be given to using materials under this directory :
| File / Directory | Purpose |
|---|---|
SKILL.md(this file) |
Process, directory conventions,complete JSONL test case specification, report structure,fixed schedule |
references/REFERENCE_JSON_CASE_FORMAT.md |
and "Performance Test Case JSONL Specification" belowsame text |
references/REFERENCE_PROFILER_AND_METRICS.md |
torch_npu.profiler、op_statistic.csv、*_ascend_pt path |
examples/sample_perf_cases.jsonl |
Minimal LayerNorm-style JSONL, can be copied and renamed |
examples/layer_norm_profiler_reference/ |
Layer Norm reference implementation(layer_norm_profiler_common.py、benchmark_layer_norm_torch_npu_profiler.py, test case JSONL, description); for a new operator, copy this directory to csrc/ops/<op>/test/ then replace the forward and file names |
Role
In ascend-kernel , for csrc/ops/<算子名>/ establish a reusable profiler performance test case and custom operator vs baseline Markdown report process. Collection must go through torch_npu.profiler, and warmup and active are fixed at 5(see next section). For details see references/REFERENCE_PROFILER_AND_METRICS.md。
Core principles (two mandatory constraints):
- Comparison report must always be presented: regardless of whether the baseline path is a baseline API or small-operator composition, the final report must include a custom operator vs baseline dual-path comparison table,single-path reports are prohibited as substitutes,The baseline must run on NPU。
- Test case generation must first read
design.md: before generating any JSONL test case, you must read thecsrc/ops/<op>/design.mdin the operator directory, extract parameter constraints, typical shapes, supported dtypes and key attribute values from it; test cases must cover all execution modes described in the design document.
Test case source: load from testcase-gen test case document (MANDATORY)
Before generating or modifying any JSONL test case,MUST first read the test case document produced by testcase-gen:
Step 0: Read the testcase-gen test case document
READ csrc/ops/<op>/test/<op>-test-cases.md
Extract from it:
| Extraction item | Location in the test case document | Purpose |
|---|---|---|
| SUPPORTED_DTYPES | §Test configuration | dtype coverage of JSONL test cases |
| TEST_SHAPES | §Test configuration | Basis for selecting small/medium/large-scale shapes |
| GENERAL_SHAPES | §Test configuration | Generalized shapes, may be supplemented for performance scenarios |
| NPU invocation method | §Operator baseline | Forward invocation of the custom operator |
| CPU reference implementation | §Operator baseline | Reference implementation of the baseline path |
testcase-gen output → JSONL test case conversion rules
- Select from TEST_SHAPES + GENERAL_SHAPESrepresentative shapes(covering small/medium/large scale), avoiding duplicates
- For each shape, iterate over all dtypes in SUPPORTED_DTYPES
- Populate the JSONL's
inputsfield using the attribute values in design.md (such as block_size, eps, etc.) - Total number of JSONL cases ≥ 8
- The NPU invocation method and CPU reference implementation in the operator benchmark are used to build the custom operator path and the benchmark path
If
<op>-test-cases.mddoes not exist: fall back to designing cases entirely from design.md on your own (following the process below), but you must note in the report that "the cases are self-designed and not produced by testcase-gen".
Case generation: design.md must be read first (mandatory)
Before generating or modifying any JSONL case(regardless of whether the testcase-gen case document has been loaded), the following steps must be performed:
Step 1: Read the design document
READ csrc/ops/<op>/design.md
Extract from it:
| Extraction item | Location in design.md | Purpose |
|---|---|---|
| Supported data types | §1 "Supported data types" | dtype coverage of the cases |
| Parameter constraints and value ranges | §1 "Parameter description" constraints column | Valid range of attribute values (such as block_size ≤ 128) |
| Typical shape / input scale | §2 "Computation logic" / §3 "Tiling strategy" | Shape baseline for small/medium/large-scale cases |
| Mode combinations of key attributes | §2 "Pseudocode" / §1 "Parameter description" | Execution paths that need to be covered separately (such as do_transpose=True/False, is_input_split=True/False) |
| Performance-critical points | §6 "Performance optimization" / §3 "Tiling strategy" | Branches that affect performance (such as transpose vs non-transpose taking different DMA paths) |
Step 2: Case design rules
| Rule | Description |
|---|---|
| Cover all execution modes | When design.md describes multiple execution paths (such as transpose/non-transpose, input_split mode), each mode must have at least one case |
| Cover all supported dtypes | Each supported data type must have at least one set of cases, typically a medium-scale shape |
| One set each for small/medium/large-scale shapes | Small-scale (dominated by kernel launch overhead), medium-scale (typical production scenario), and large-scale (dominated by memory access bandwidth) must each be covered |
| Parameter values come from the constraint range | Attribute values (such as block_size) must be selected from the constraints in design.md and must not be set arbitrarily |
| Integer/index tensor values must be semantically valid | The specific values of tensors such as win_lengths and offsets must satisfy the operator semantics (such as offsets must be valid window start offsets) |
Step 3: Validate the cases
After generating the cases, check:
- All dtypes are covered
- All execution modes (as defined by design.md) have corresponding cases
- Parameter values (including attribute values and integer tensor values) are within the constraints of design.md
- Include at least one "small shape" case and one "large shape" case
Reference path decision tree (mandatory)
Performance evaluationAlwaysA dual-path comparison is required (custom operator vs. benchmark), and the benchmark path is determined in the following order:
算子是否有标杆等价 API?
├─ 是(如 torch.nn.functional.*、torch_npu 内置算子)
│ └─ 使用标杆 API 作为标杆路径
└─ 否(无标杆等价接口)
└─ 必须实现「小算子拼接」标杆路径 ← 本技能的强制要求
└─ 用设计文档 §「参考实现」或「伪代码」中的 PyTorch 基础算子组合实现
Requirements for the benchmark path of small-operator stitching
When there is no benchmark-equivalent interface,you must:
- Read the reference implementation from design.md: the design document usually contains a PyTorch reference implementation (pseudocode or Python function); build the benchmark path based on that implementation.
- Use combinations of basic PyTorch operators:
torch.zeros, slice assignment,.permute()、torch.cat, etc. Do not use loops + Python scalar assignment (otherwise the profiler collects CPU operators rather than NPU operators, making a fair comparison impossible); the entire benchmark implementation must be based primarily on tensor operations and be executable on the NPU. - Clearly state in the report: the report header must state "No benchmark-equivalent interface; the benchmark path is small-operator stitching" and list the basic operators used.
- The comparison table must present: do not degrade to a single-path report on the grounds of "no benchmark interface"; you must retain the three columns "custom operator per-step", "benchmark per-step", and "ratio".
NEVER: output a single-path report or skip the comparison table on the grounds of "no benchmark-equivalent interface".
Fixed profiler step count (mandatory)
| Parameter | Value | Description |
|---|---|---|
warmup |
5 | Scripts or the CLI are not allowed to change it to other values |
active |
5 | Scripts or the CLI are not allowed to change it to other values |
wait |
Default 0 |
CLI or constant may be retained, as needed |
repeat |
Default 1 |
For simple scenarios, fix it at 1; if repeat>1, the CSV selection semantics must be explained in the documentation |
At the end of each step, you must prof.step(); total number of loop steps = repeat * (wait + warmup + active)。
File placement (uniformly in the operator's test/ subdirectory)
Place all of the following artifacts in ascend-kernel/csrc/ops/<op>/test/:
| Category | Naming convention (<op> such as layer_norm) |
|---|---|
| Use case JSONL only | <op>_perf_cases.jsonl(one JSON object per line);do not maintain, do not generate <op>_perf_cases.json |
| Markdown report | <op>_torch_npu_profiler_report.md(the only structured result written to disk;do not generate <op>_torch_npu_profiler_results.json) |
| Profiler export root directory | test/profiler_trace/(or --trace-root override) |
Performance scripts, common modules, and the above files in the same place test/。
Complete specification of the performance use case JSONL
The following is the complete field and type description for the use case file;use only .jsonl as the use case carrier.
1. File format
| Format | Description |
|---|---|
| JSONL | Each line one JSON object, with a newline at the end of the line; blank lines are ignored. Extension .jsonl。 |
ProhibitedIn this process, generate or maintain in sync with the use cases .json array files.
2. Top-level structure of a single use case
Each use case object must contain the key "inputs", whose value is a array。
Layer Norm example(if the operator differs, replace build_inputs convention; the structure must still contain the inputs array):
{
"inputs": [
{ "name": "x", "type": "tensor", "required": true, "dtype": "float16", "shape": [8, 128] },
{ "name": "normalized_shape", "type": "attr", "required": true, "dtype": "int", "value": [128] },
{ "name": "use_affine", "type": "attr", "required": false, "dtype": "bool", "value": true },
{ "name": "eps", "type": "attr", "required": false, "dtype": "float", "value": 1e-05 }
]
}
inputselements withinnameare unique within the same use case。- Other operators: tensor /
tensor_list/attr/ integer tensorrangeand other rules seereferences/REFERENCE_JSON_CASE_FORMAT.md。
3. Complete JSONL example (two lines, Layer Norm)
{"inputs":[{"name":"x","type":"tensor","required":true,"dtype":"float16","shape":[2,128]},{"name":"normalized_shape","type":"attr","required":true,"dtype":"int","value":[128]},{"name":"use_affine","type":"attr","required":false,"dtype":"bool","value":true},{"name":"eps","type":"attr","required":false,"dtype":"float","value":1e-05}]}
{"inputs":[{"name":"x","type":"tensor","required":true,"dtype":"float16","shape":[4,256]},{"name":"normalized_shape","type":"attr","required":true,"dtype":"int","value":[256]},{"name":"use_affine","type":"attr","required":false,"dtype":"bool","value":false},{"name":"eps","type":"attr","required":false,"dtype":"float","value":1e-05}]}
More complete field descriptions (tensor_list、int tensor range etc.) see references/REFERENCE_JSON_CASE_FORMAT.md。
Profiler and directory semantics (summary)
- Each time
with torch_npu.profiler.profile(...), under the handler directory generate with_ascend_ptas the suffix export directory; CSV path…/*_ascend_pt/ASCEND_PROFILER_OUTPUT/op_statistic.csv。 - Each use case, each implementation(e.g.
custom/baseline)one independentwith; sub-path recommended{trace_root}/{op_trace_tag}/{custom|baseline}/case_XXX/, clear before runningcase_XXX。
See references/REFERENCE_PROFILER_AND_METRICS.md。
Metrics (summary)
- For a single
withcorresponding CSV:sum of Total Time(us) for each operator row。 - divided by
active×repeat(divisor_mode=active_stepswhen) or onlyactive(active_only). This skill fixesactive=5; ifrepeat=1, thendivisor = 5。
Performance comparison report (Markdown) required structure
The report format strictly follows examples/sample_report.md, the structure is as follows:
1. Title
# 性能评估结果
2. Comparison table (unified single table, mandatory dual path)
All use cases are shown inthe same table, with the header fixed as Case | Shape | DType | 自定义算子(us) | 标杆(us) | 加速比。
Example:
## 性能对比
| Case | Shape | DType | 自定义算子(us) | 标杆(us) | 加速比 |
| ---- | ----- | ----- | ------------- | -------- | -------------- |
| 0 | [128, 4096] | float16 | 9.75 | 10.10 | 1.036 |
| 1 | [128, 5120] | float16 | 10.52 | 9.39 | 0.893 |
| 2 | [128, 6144] | float16 | 10.99 | 14.36 | 1.307 |
| 3 | [64, 6400] | float16 | 9.13 | 9.49 | 1.040 |
| 4 | [2, 1024, 4096] | float16 | 57.01 | 84.92 | 1.490 |
| 5 | [2, 1024, 6144] | float16 | 73.80 | 139.56 | 1.891 |
| 6 | [1, 2048, 6400] | float16 | 75.60 | 143.09 | 1.893 |
| 7 | [64, 4096] | float32 | 8.45 | 7.14 | 0.846 |
3. Full summary
Use ## 全量汇总 second-level heading, containing akey-value pair table:
## 全量汇总
| 指标 | 值 |
| ---- | -- |
| 用例数 | N |
| 平均 加速比(>1 表示自定义算子更快) | X.XXX |
| 自定义算子更优(比值>1) | M |
| 标杆更优(比值<1) | K |
Immediately below, use ### 按数据类型汇总 third-level heading, showing the summary table by dtype:
### 按数据类型汇总
| DType | 用例数 | 平均 加速比 | 自定义算子更优 | 标杆更优 |
| ----- | ------ | ------------------- | ------------- | -------- |
| float16 | 7 | 1.364 | 6 | 1 |
| float32 | 1 | 0.846 | 0 | 1 |
4. Brief analysis
Use ## 简短分析 second-level heading, list ≥3 brief conclusions in unordered list form, covering: overall trends, differences across dtype / shape scales, memory access and compute characteristics, etc.
## 简短分析
- 平均 加速比 大于 1,自定义算子整体略有优势。
- 大 shape 下自定义算子优势更明显,向量路径利用更充分。
- float32 小 shape 场景自定义算子略逊于标杆,可能与 kernel launch 开销占比较高有关。
Other conventions
- Do not writecontent that duplicates the report
*_profiler_results.json; intermediate statistics exist only in script memory and are written to Markdown.
Show results in the conversation (MANDATORY)
After generating csrc/ops/<op>/test/<op>_torch_npu_profiler_report.md(or if it already exists and has been updated in this run), the assistant inthe current conversation's reply MUST simultaneously completes the following,must notoutput only "report generated" and the path without showing the data:
- Paste the main performance content(the user can read the conclusions without opening the file, and the displayed content is consistent with the report structure):
- Unified comparison table: header
Case | Shape | DType | 自定义算子(us) | 标杆(us) | 加速比, all dtypes are shown in the same table. When there are many cases, it may be truncated with a note "see report for the rest". - Full summary: summary metrics in key-value pair form (number of use cases, average ratio, number of cases where the custom operator/baseline is better) and a summary table by data type.
- Brief analysis:≥3 unordered list conclusions, covering overall trends, differences across dtype / shape scales, memory access and compute characteristics, etc.
- Unified comparison table: header
NEVER: reply only with the report path; NEVER replace showing the core numbers and conclusions in the conversation with "please open the Markdown yourself".
Common pitfalls
warmup/activewas changed to a value other than 5, which is inconsistent with the skill convention.- Did not use
torch_npu.profilerorprof.step(), which is inconsistent with schedule. repeat>1Possibly multiple*_ascend_ptexports; when selecting CSV by mtime, the semantics need to be explained.- When the CSV header BOM / column names change, it must be compatible with Total Time(us)。
- When a custom operator is not registered, only follow the benchmark path; the custom library must be loaded before comparison.
- Did not read
<op>-test-cases.mdand directly designed test cases on your own: testcase-gen has already generated a unified test case document, and shapes and dtypes should be extracted from it first to avoid duplicate design. - Generated test cases directly without reading design.md: This caused shapes to not meet the constraints and missing coverage of key execution modes (such as missing the transpose=True path).
- Output a single-path report on the grounds of "no equivalent benchmark interface": A small-operator concatenated benchmark path must be implemented, and a dual-path comparison table must always be output.
- Small-operator concatenation used a Python loop with scalar-by-scalar assignment: What the profiler collects is CPU logic rather than NPU operators, causing the benchmark path timing to be distorted; the benchmark implementation should be based mainly on tensor operations.
- The assistant only output the report path and did not display the main tables and summary conclusions in the current conversation(violating "display results within the conversation").
Reference implementation (examples/layer_norm_profiler_reference/)
and ascend-kernel/csrc/ops/layer_norm/test/ The profiler-related files remain isomorphic, including:
layer_norm_profiler_common.py、benchmark_layer_norm_torch_npu_profiler.pylayer_norm_perf_cases.jsonl(JSONL only, no.json)LAYER_NORM_PROFILER_PERF_GUIDE.md、README.md
For a new operator, from this directory copy the whole thing to csrc/ops/<op>/test/, then replace the operator name, forward call,build_inputs and trace subdirectory name. If the repository's layer_norm/test/ has updates, they should be synchronized back to examples/layer_norm_profiler_reference/。
Checklist (assistant self-check)
- Has read
csrc/ops/<op>/test/<op>-test-cases.md(if it exists), and extracted SUPPORTED_DTYPES, TEST_SHAPES, GENERAL_SHAPES, and operator benchmarks from it - Has read
csrc/ops/<op>/design.md, and extracted dtype, parameter constraints, typical shapes, and execution modes from it - Test cases cover the design.md-describedall execution modes(such as transpose/non-transpose, input_split mode, etc.)
- The parameter values (attribute values and integer tensor values) in the test cases are all within the constraints of design.md
- Has confirmed the benchmark path type (benchmark API or small-operator concatenation), and clearly marked it at the top of the report
- If there is no equivalent benchmark interface, has implemented asmall-operator concatenatedbenchmark path, and the benchmark implementation is based mainly on tensor operations (not a Python scalar loop)
- Has used
torch_npu.profiler, andwarmup=5、active=5has not been rewritten - Has generated or updated
<op>_torch_npu_profiler_report.md, with a format consistent withexamples/sample_report.md: a unified comparison table including a DType column + full summary + summary by data type + brief analysis - has been displayed in the current conversationa unified comparison table including a DType column, full summary, summary by data type, and ≥3 itemsbrief analysis conclusions, not just the path
- Has explained the fixed-step convention and metric definitions