Based on the requirements specification, design plan, and reference implementation, complete the code implementation, verification, and README delivery.
Required Inputs
Requirements Specification Information
From SPEC.md , extract:
| Field | Purpose |
|---|---|
| Operator name | File naming, function naming |
| Mathematical formula | Understand the computation logic |
| Input/output specifications (shape, dtype) | Test data generation |
| Supported data types | Test coverage, impl type handling |
| Precision requirements | Test tolerance settings |
| Server type | Environment compatibility confirmation |
Design Plan Information
From DESIGN.md , extract:
| Field | Purpose |
|---|---|
| API mapping design | {op}_impl.py Core implementation |
| Data specification design | test_{op}.py Data generation + {op}_impl.py tensor description |
| Tiling strategy | {op}_impl.py tiling configuration |
| Loop structure design | {op}_impl.py kernel logic |
| Verification plan | test_{op}.py test case design |
| Performance metrics | README.md performance description |
Reference Implementation Information
From {op}_golden.py , extract:
| Information | Purpose |
|---|---|
golden function name {op}_golden() |
test_{op}.py import statement |
| Parameter signature | test_{op}.py data preparation |
| Output format | {op}_impl.py output tensor construction |
If the above information is insufficient, ask the user questions step by step to supplement it.
Reference Files
| File | Purpose | Loading Time |
|---|---|---|
| references/test-template.py | Fixed template for test files | Read when generating test_{op}.py |
| references/impl-template.py | Fixed template for impl files | Read when generating {op}_impl.py |
| references/execution-constraints.md | PyPTO development execution constraints checklist | Must-read before entering the implementation phase; refer to it repeatedly during coding and self-checks |
| references/error-code-troubleshooting.md | Error code troubleshooting process and common error code quick reference | Troubleshoot according to the process when verification fails |
| scripts/environment_prepare.sh | Environment initialization script | Execute as needed during the environment preparation phase |
| scripts/list_idle_chip_ids.sh | Output the list of currently available chip ids (compatible with 910B / 910C) | Set TILE_FWK_DEVICE_ID execute before |
Development Phase
Phase One: Environment Preparation
- Check whether CANN is installed
echo ${PATH} | grep cann-8.5.0
- Check whether the pto-isa source code has been obtained
echo ${PTO_TILE_LIB_CODE_PATH}
- If the path does not exist, execute
scripts/environment_prepare.shto perform environment initialization - If it is still unsuccessful, refer to
docs/install/prepare_environment.mdGet the pto-isa source code and set up environment variables
- Verify key documentation and example directories
ls docs/api/
ls examples/
- Set device_id
# 查找空闲 chip id
`bash scripts/list_idle_chip_ids.sh`
# 根据输出结果设置环境变量(例如输出为 "0 1 3 ..." 时,先选 chip 0)
export TILE_FWK_DEVICE_ID=$(bash scripts/list_idle_chip_ids.sh | awk '{print $1}')
export PTO_TILE_LIB_CODE_PATH=./pto_isa/pto-isa/
- If the script produces no output, it means all current chips are occupied by processes and cannot be set arbitrarily
TILE_FWK_DEVICE_ID
⚠️ Not setting TILE_FWK_DEVICE_ID will cause a runtime error: "If no NPU environment is available"
If the above checks do not pass, refer to the materials in docs/install to complete environment preparation.
Phase 2: Code generation
Output directory:custom/{op}/
Generation order:
- Based on the input information, first sort out the API mapping, tiling strategy, and loop structure, and proceed to implementation only after confirming feasibility
- Before entering implementation, read
references/execution-constraints.md, and apply the framework-level constraints, basic type constraints, control flow constraints, and high-frequency operation constraints to this implementation - Based on
references/impl-template.pygenerate{op}_impl.py - Based on
references/test-template.pygeneratetest_{op}.py(prerequisite:{op}_impl.pyalready generated) - Generate
README.md
⚠️ Implementation code and test code must be separated; mixing golden / impl / test into the same file is prohibited.
Generate {op}_impl.py
PyPTO kernel function implementation, generated based on the fixed template references/impl-template.py .
Before implementation, must check item by item references/execution-constraints.md, especially: output write-back, dynamic axis annotation, Element usage, TileShape, valid_shape, loop/cond, read-write loopback within the same graph.
| Specification | Description |
|---|---|
| Export function | {op}_wrapper(x: torch.Tensor) -> torch.Tensor |
| Kernel decorator | @pypto.frontend.jit |
| Tensor descriptor | pypto.Tensor() or pypto.Tensor([pypto.DYNAMIC, ...], pypto.DT_FP32) |
| Tiling configuration | Must call pypto.set_vec_tile_shapes(...) or pypto.set_cube_tile_shapes(...) |
| Output write-back | output[:] = result or pypto.assemble(result, offset, output) |
| Optional helper function | {op}_core() — split core computation logic for complex operators |
Generate test_{op}.py
torch golden function precision comparison test, generated based on the fixed template references/test-template.py .
Structure:
| Block | Content |
|---|---|
| Import | from {op}_golden import {op}_golden + from {op}_impl import {op}_wrapper |
| Environment tools | get_device_id() — read TILE_FWK_DEVICE_ID |
| Test function | test_{op}_levelN() — data generation → {op}_wrapper(x) → {op}_golden(x) → assert_allclose |
| CLI entry | argparse, supports example_id / --list / --run_mode |
Mandatory precision comparison specification:
| Specification | Description |
|---|---|
| Precision comparison | Must use assert_allclose, see "Three state marker conventions" |
| Tolerance | Simple operators rtol=1e-3, atol=1e-3; complex operators rtol=3e-3, atol=3e-3 |
| NPU conditional comparison | if run_mode == "npu": assert_allclose(...) |
| Manual comparison prohibited | assert max_diff < tolerance / np.allclose() are all prohibited |
Generate README.md
Must include:
- Chinese description
- Operator overview and formula
- Directory structure
- How to run
- Verification entry
- Known limitations
Mapping from Design to code files
| design section | test_{op}.py |
{op}_impl.py |
README.md |
|---|---|---|---|
| Overview | Indirect reference | No | Yes |
| API mapping design | No | Yes | Summarizable |
| Data specification design | Yes | Yes | Summarizable |
| Tiling strategy | No | Yes | Summarizable |
| Loop structure design | No | Yes | Summarizable |
| Verification plan | Yes | No | Yes |
| Performance metrics | Partial | Partial | Yes |
| Deliverables list | Yes | Yes | Yes |
Stage 3: Test verification
Prefer using NPU mode for verification.
Verification steps:
- Compile and install(if pypto is not installed):
python3 build_ci.py -f python3 --disable_auto_execute
If already installed, there is no need to repeatedly compile.
- Run operator verification:
When an NPU card is detected, directly use
run_mode=nputo run:
python3 custom/{op}/test_{op}.py
- Verification failure handling:
⚠️ First confirm whether there is an error code: if yes, the error code process must be followed; if no, skip it
Check method: search stderr or logs for
Errcode: F/ErrCode: F- Has an error code (e.g.
ErrCode: FC0000!) → the error code troubleshooting process must be followed: see references/error-code-troubleshooting.md - No error code → skip, and directly analyze the error message or logs to locate the problem
- Has an error code (e.g.
Recommended verification order:
- Small-scale functional verification: first confirm that the code can run and that the basic output shape is correct
- Typical-scale verification: use regular inputs from the target scenario for main-path verification
- Boundary and extreme value verification: check zero values, large values, special shapes, dynamic shapes, etc.
- Large-scale or performance-related verification: proceed only after functionality and precision are stable
Test type:
- Unit test: basic functionality verification
- Precision test: precision meets requirements
- Performance test: performance measurement has been completed, and whether it meets requirements is judged based on measured data
⚠️ When an NPU card is available, do not use run_mode=sim。
Implementation notes
- A PyPTO tensor is uninitialized random values after creation: initialize before use, or ensure write-before-read; do not treat
pypto.tensor(...)as an initialized tensor. - Do not invent ops: during implementation, only use APIs already supported by PyPTO; when a missing capability is encountered, fall back to the API exploration or design stage for reconfirmation.
- Prefer using
@pypto.frontend.jitstyle: choose the latest non-wrapper style, refer todocs/api/pypto-frontend-jit.md, and stay consistent with existing examples and documentation. - golden / impl / test must have separated responsibilities: do not mix golden logic, implementation logic, and test logic in the same file.
- Use valid_shape for dynamic data ranges: when the last block's data amount may be smaller than the fixed block size,
pypto.view/pypto.reshapemust specifyvalid_shape。 - Use unroll_list for dynamic loop bounds: When the loop count is a dynamic value, you need to use
unroll_list; When loops are nested in multiple levels, the innermost level usesunroll_list。 - matmul / cube scenario: Must confirm that
set_cube_tile_shapes(...)is correctly configured. - Output write-back must be done explicitly: Use
output[:] = ...、output.move(...)orpypto.assemble(..., output); do not writeoutput = ...。 - Dynamic axes must be explicitly annotated: All dynamic shape inputs and outputs must be marked as
pypto.DYNAMIC/pypto.DYN。 - Element is used to fix scalar dtype: When a scalar participates in computation and the dtype cannot rely on implicit mapping, explicitly use
pypto.Element(dtype, value)。 - Avoid read-write loops within the same graph: The same Tensor should not be both
viewreadassembleand written back in the same graph. - If the design already has tiling / loop constraints, prioritize following
DESIGN.mdduring coding, and do not rewrite them on a whim.
Common Issues and Solutions
7 Common Types of Errors
- BFloat16 to NumPy conversion failure: Must first
.float()and then.numpy() - Environment variable not set: First run
bash scripts/list_idle_chip_ids.shto confirm an available chip id, then setexport TILE_FWK_DEVICE_ID=<空闲 chip id> - Dynamic axis defined in the wrong location: Must be defined outside the jit function
- Tile Shape not set: Before matmul, must call
set_cube_tile_shapes; before vec operations,set_vec_tile_shapes - Unreasonable precision standard: bfloat16 uses
atol=0.0001, rtol=0.0078125 - Using PyTorch as Golden: When using NumPy to implement the golden function, bfloat16 data type conversion is not accurate enough; golden must independently be in
{op}_golden.py, implemented using pure torch - Error when SymbolicScalar is used as a list index:
TypeError: list indices must be integers or slices, not SymbolicScalar. Reason:pypto.loopreturns a compile-time symbolic value, not a Python runtime object. Solution: Use tensor slice orpypto.view/pypto.assembleto build the data flow.
Three Status Marker Conventions
Generated test_{op}.py must output the precision判定 marker using the following pattern:
import sys
import numpy as np
def run_test():
# ... setup inputs, call golden and impl ...
try:
np.testing.assert_allclose(impl_output, golden_output, rtol=rtol, atol=atol)
print("[PRECISION_PASS]")
except AssertionError as e:
print(f"[PRECISION_FAIL] {e}", file=sys.stderr)
sys.exit(1)
except Exception as e:
# 功能问题(无标记),exit code ≠ 0
print(f"Runtime error: {e}", file=sys.stderr)
sys.exit(2)
if __name__ == "__main__":
run_test()
Marker meanings:
[PRECISION_PASS]: Precision verification passed[PRECISION_FAIL]: Precision verification failed (numeric mismatch)- No marker + exit ≠ 0: Functional issue (code crash, logic error, etc.)
assert_allclose thrown AssertionError contains Not equal to tolerance keyword, and the caller uses this to distinguish between "run failure" and "precision failure".
Checklist
- 3 files (
test_{op}.py+{op}_impl.py+README.md) all exist test_{op}.pyexecutable (no syntax errors)- The test includes
[PRECISION_PASS]/[PRECISION_FAIL]marker logic, with no other functional issues - On verification failure, it has been confirmed whether there is an error code: if yes, follow the error code process; if no, skip
{op}_impl.pyhas been self-checked according toreferences/execution-constraints.md: output write-back, dynamic axis, TileShape, valid_shape, Element, loop/cond, and assemble loop have all been checked