已合并
fix check error #831
bxr创建于 4月23日
fix check error #831
已合并
共 154 个文件变更+5110-9428
| @@ -12,7 +12,7 @@ A ConvTile is defined by five families of attributes: | |||
| 12 | 12 | ||
| 13 | - **Location**: which logical tile storage class the tile belongs to (matrix/cube registers). | 13 | - **Location**: which logical tile storage class the tile belongs to (matrix/cube registers). |
| 14 | - **Element type**: scalar element type (`float`, `half`, `int8_t`, ...). | 14 | - **Element type**: scalar element type (`float`, `half`, `int8_t`, ...). |
| 15 | -- **Buffer size**: the number of elements in the convtile. | 15 | +- **Buffer size**: the static space of convtile. |
| 16 | - **Layout**: a layout (`NCHW`, `NHWC`, `NC1HWC0`, ...), used to guide lowering and target-specific fast paths. | 16 | - **Layout**: a layout (`NCHW`, `NHWC`, `NC1HWC0`, ...), used to guide lowering and target-specific fast paths. |
| 17 | - **Shape**: a `pto::ConvTileShape<...>` (up to 6 dimensions). | 17 | - **Shape**: a `pto::ConvTileShape<...>` (up to 6 dimensions). |
| 18 | 18 | ||
| @@ -42,7 +42,7 @@ Instruction pages in `docs/isa/` specify which locations are legal for each inst | |||
| 42 | 42 | ||
| 43 | ### Capacity (`BufferSize_`) | 43 | ### Capacity (`BufferSize_`) |
| 44 | 44 | ||
| 45 | -`BufferSize_` define the **static number of elements** of the tile object. Most instructions require static shapes so they can be specialized and optimized at compile time. | 45 | +`BufferSize_` define the **static capacity** of the tile object. Most instructions require static shapes so they can be specialized and optimized at compile time. |
| 46 | 46 | ||
| 47 | ### Layout (`pto::Layout`) | 47 | ### Layout (`pto::Layout`) |
| 48 | 48 | ||
| @@ -0,0 +1,96 @@ | |||
| 1 | +# ConvTile 编程模型 | ||
| 2 | + | ||
| 3 | +PTO Lib 程序可基于 **ConvTile** 编写卷积相关算子。`ConvTile` 是固定容量的 2D 到 6D 缓冲对象,也是 PTO 卷积类操作中的主要计算单元和数据搬运单元。 | ||
| 4 | + | ||
| 5 | +从概念上说,`ConvTile` 驻留在**片上 Tile 存储**中(类似寄存器文件或片上 SRAM),并通过 `TLOAD` / `TSTORE` 与全局内存(GM)之间搬运数据。 | ||
| 6 | + | ||
| 7 | +本文档说明 `include/pto/common/pto_tile.hpp` 中的 C++ `ConvTile` 类型及其布局和形状约束。 | ||
| 8 | + | ||
| 9 | +## ConvTile 表示什么 | ||
| 10 | + | ||
| 11 | +一个 `ConvTile` 主要由以下几类属性定义: | ||
| 12 | + | ||
| 13 | +- **位置(Location)**:该 Tile 所属的逻辑存储类别(如矩阵/立方寄存器等)。 | ||
| 14 | +- **元素类型(Element type)**:标量元素类型(如 `float`、`half`、`int8_t` 等)。 | ||
| 15 | +- **缓冲区大小(Buffer size)**:`ConvTile` 的静态缓冲容量。 | ||
| 16 | +- **布局(Layout)**:如 `NCHW`、`NHWC`、`NC1HWC0` 等,用于指导 lowering 和目标相关优化路径。 | ||
| 17 | +- **形状(Shape)**:`pto::ConvTileShape<...>`,支持最多 6 个维度。 | ||
| 18 | + | ||
| 19 | +## `pto::ConvTile` 类型 | ||
| 20 | + | ||
| 21 | +`ConvTile` 通过 C++ 模板类型声明: | ||
| 22 | + | ||
| 23 | +```cpp | ||
| 24 | +pto::ConvTile< | ||
| 25 | + pto::TileType Loc_, | ||
| 26 | + Element_, | ||
| 27 | + BufferSize_, | ||
| 28 | + pto::Layout_ layout, | ||
| 29 | + pto::ConvTileShape Shape_ | ||
| 30 | +>; | ||
| 31 | +``` | ||
| 32 | + | ||
| 33 | +### 位置(`TileType`) | ||
| 34 | + | ||
| 35 | +`TileType` 表示 Tile 的逻辑/物理存储类别,同时参与重载选择和编译期检查。 | ||
| 36 | + | ||
| 37 | +常见位置包括: | ||
| 38 | + | ||
| 39 | +- `TileType::Vec`:向量 Tile 存储(UB / 向量流水线)。 | ||
| 40 | +- `TileType::Mat`:通用矩阵 Tile 存储(矩阵 L1)。 | ||
| 41 | + | ||
| 42 | +每条指令允许使用哪些位置,应以 `docs/isa/` 下对应指令文档为准。 | ||
| 43 | + | ||
| 44 | +### 容量(`BufferSize_`) | ||
| 45 | + | ||
| 46 | +`BufferSize_` 定义了 Tile 对象的**静态容量**。多数指令要求 Tile 具备静态形状,以便在编译期进行特化和优化。 | ||
| 47 | + | ||
| 48 | +### 布局(`pto::Layout`) | ||
| 49 | + | ||
| 50 | +`ConvTile` 包含一个布局枚举,如: | ||
| 51 | + | ||
| 52 | +- `NCHW` | ||
| 53 | +- `NHWC` | ||
| 54 | +- `NC1HWC0` | ||
| 55 | +- `FRACTAL_Z` | ||
| 56 | +- `FRACTAL_Z_S16S8` | ||
| 57 | + | ||
| 58 | +布局信息会影响后端实现、lowering 路径以及特定目标上的快速路径选择。 | ||
| 59 | + | ||
| 60 | +### 形状(`pto::ConvTileShape`) | ||
| 61 | + | ||
| 62 | +`pto::ConvTileShape<...Shapes>` 支持 1 到 6 个整型模板参数。每个维度既可以是编译期常量,也可以是 `pto::DYNAMIC`(即 `-1`)。 | ||
| 63 | + | ||
| 64 | +- 静态维度保存在类型信息中,可通过 `ConvTileShape::staticShape[dim]` 获取。 | ||
| 65 | +- 动态维度保存在运行时对象 `ConvTileShape::shape[dim]` 中,并由 `ConvTileShape(...)` 构造函数赋值。 | ||
| 66 | + | ||
| 67 | +构造函数会通过 `static_assert` 检查“运行时传入参数个数是否与动态维度数量一致”,因此若构造参数不匹配,会在编译期报错。 | ||
| 68 | + | ||
| 69 | +## 地址绑定(`TASSIGN`) | ||
| 70 | + | ||
| 71 | +在手动放置流程中,`TASSIGN(tile, addr)` 用于把一个 `ConvTile` 对象绑定到实现定义的地址。 | ||
| 72 | + | ||
| 73 | +在自动模式中,`TASSIGN(tile, addr)` 可能根据构建配置被处理为 no-op。 | ||
| 74 | + | ||
| 75 | +具体约束请参考 `docs/isa/TASSIGN.md`。 | ||
| 76 | + | ||
| 77 | +## 最小示例 | ||
| 78 | + | ||
| 79 | +```cpp | ||
| 80 | +#include <pto/pto-inst.hpp> | ||
| 81 | +using namespace pto; | ||
| 82 | + | ||
| 83 | +void example(__gm__ half* in, __gm__ half* out) { | ||
| 84 | + using TileT = ConvTile<TileType::Mat, half, 4096, Layout::NC1HWC0, pto::ConvTileShape<1, 1, 16, 16, 16>>; | ||
| 85 | + using GShape = Shape<1, 1, 16, 16, 16>; | ||
| 86 | + using GStride = Stride<1 * 16* 16* 16, 16* 16* 16, 16 * 16, 16, 1>; | ||
| 87 | + using GT = GlobalTensor<half, GShape, GStride, Layout::NC1HWC0>; | ||
| 88 | + GT gin(in); | ||
| 89 | + | ||
| 90 | + TileT tile5d; | ||
| 91 | + TASSIGN(tile5d, 0x0); | ||
| 92 | + | ||
| 93 | + TLOAD(tile5d, gin); | ||
| 94 | +} | ||
| 95 | +``` | ||
| 96 | + | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | # Events and Synchronization | 1 | # Events and Synchronization |
| 2 | 2 | ||
| 3 | -PTO Tile Lib supports an explicit event model for expressing dependencies between operations without introducing a global barrier for every instruction. Note that in auto mode, the events turn into no-ops since auto mode inserts the synchronization during compilation. | 3 | +PTO Tile Lib supports an explicit event model for expressing dependencies between operations without introducing a global barrier for every instruction. |
| 4 | 4 | ||
| 5 | This document describes the C++ event types used by `include/pto/common/pto_instr.hpp` and `include/pto/common/event.hpp`. | 5 | This document describes the C++ event types used by `include/pto/common/pto_instr.hpp` and `include/pto/common/event.hpp`. |
| 6 | 6 | ||
| @@ -1,7 +1,6 @@ | |||
| 1 | # 事件与同步 | 1 | # 事件与同步 |
| 2 | 2 | ||
| 3 | PTO Tile Lib 支持显式事件(event)模型,用于表达操作之间的依赖关系,而不必为每条指令都引入全局屏障。 | 3 | PTO Tile Lib 支持显式事件(event)模型,用于表达操作之间的依赖关系,而不必为每条指令都引入全局屏障。 |
| 4 | -注意:在auto模式下,Events是no-op,因为auto模式下编译器会自动插入同步。 | ||
| 5 | 4 | ||
| 6 | 本文档描述 `include/pto/common/pto_instr.hpp` 与 `include/pto/common/event.hpp` 中使用的 C++ 事件类型。 | 5 | 本文档描述 `include/pto/common/pto_instr.hpp` 与 `include/pto/common/event.hpp` 中使用的 C++ 事件类型。 |
| 7 | 6 | ||
| @@ -92,3 +91,4 @@ void pipeline(__gm__ float* in0, __gm__ float* in1, __gm__ float* out) { | |||
| 92 | TSTORE(gout, c, e2); | 91 | TSTORE(gout, c, e2); |
| 93 | } | 92 | } |
| 94 | ``` | 93 | ``` |
| 94 | + | ||
| @@ -11,8 +11,10 @@ | |||
| 11 | - [更多教程示例](tutorials/README_zh.md) | 11 | - [更多教程示例](tutorials/README_zh.md) |
| 12 | - [调试与断言查找](debug_zh.md) | 12 | - [调试与断言查找](debug_zh.md) |
| 13 | - [Tile 抽象与布局/有效区域规则](Tile_zh.md) | 13 | - [Tile 抽象与布局/有效区域规则](Tile_zh.md) |
| 14 | +- [ConvTile 编程模型](ConvTile_zh.md) | ||
| 14 | - [全局内存张量(shape/stride/layout)](GlobalTensor_zh.md) | 15 | - [全局内存张量(shape/stride/layout)](GlobalTensor_zh.md) |
| 15 | - [事件与同步模型](Event_zh.md) | 16 | - [事件与同步模型](Event_zh.md) |
| 17 | +- [CPU_SIM 后端说明](cpu_sim_zh.md) | ||
| 16 | - [标量值、类型助记符与枚举](Scalar_zh.md) | 18 | - [标量值、类型助记符与枚举](Scalar_zh.md) |
| 17 | 19 | ||
| 18 | ## 相关文档 | 20 | ## 相关文档 |
| @@ -1,380 +1,158 @@ | |||
| 1 | -# Compilation Process | 1 | +# Compilation Process |
| 2 | - | 2 | + |
| 3 | -This document explains the PTO operator compilation process, helping developers understand the complete workflow from source code to executable files. | 3 | +This document describes the build and compilation flow for PTO Tile Lib from the perspective of source organization, public intrinsics, backend selection, and repository build entry points. |
| 4 | - | 4 | + |
| 5 | -## Contents | 5 | +It focuses on the developer-visible workflow and does not expand undocumented internal compiler stages into normative interface descriptions. |
| 6 | - | 6 | + |
| 7 | -- [1. Compilation Overview](#1-compilation-overview) | 7 | +## 1. Overview |
| 8 | -- [2. Build System Configuration](#2-build-system-configuration) | 8 | + |
| 9 | -- [3. Compilation Steps](#3-compilation-steps) | 9 | +PTO kernels are written in C++ using PTO intrinsics such as `TLOAD`, `TADD`, `TMATMUL`, `TSYNC`, and `TSTORE`. |
| 10 | -- [4. Compilation Options](#4-compilation-options) | 10 | + |
| 11 | -- [5. Cross Compilation](#5-cross-compilation) | 11 | +The common public entry is: |
| 12 | -- [6. Compilation Optimization](#6-compilation-optimization) | 12 | + |
| 13 | -- [7. Troubleshooting](#7-troubleshooting) | 13 | +```cpp |
| 14 | - | 14 | +#include <pto/pto-inst.hpp> |
| 15 | ---- | 15 | +``` |
| 16 | - | 16 | + |
| 17 | -## 1. Compilation Overview | 17 | +The intrinsic layer is implemented primarily through headers under [PTO Public Headers](../../include/pto/README.md), especially `../../include/pto/common/pto_instr.hpp`. |
| 18 | - | 18 | + |
| 19 | -### 1.1 Compilation Pipeline | 19 | +## 2. Build and compilation characteristics |
| 20 | - | 20 | + |
| 21 | -``` | 21 | +PTO Tile Lib uses a **C++ intrinsic interface**. |
| 22 | -PTO C++ Source (.cpp) | 22 | + |
| 23 | - ↓ | 23 | +From the public API perspective, the library is primarily **header-based / template-based**. |
| 24 | -Preprocessor (macro expansion, #include, #ifdef) | 24 | +The same PTO source can be built against different backends depending on build configuration. |
| 25 | - ↓ | 25 | +CPU simulation is the recommended first validation path, while NPU execution depends on an Ascend CANN environment. |
| 26 | -C++ Frontend (lexer, parser, semantic analysis, AST) | 26 | +The codebase requires **C++20 or later**. |
| 27 | - ↓ | 27 | + |
| 28 | -PTO Intrinsic Expansion (TLOAD/TSTORE/TADD → low-level instructions) | 28 | +For project-level build guidance, see [Project Overview](../../README.md) and [Getting Started](../getting-started.md). |
| 29 | - ↓ | 29 | + |
| 30 | -Middle-end (optimization passes, IR generation) | 30 | +## 3. Build flow |
| 31 | - ↓ | 31 | + |
| 32 | -Backend (instruction selection, register allocation, code generation) | 32 | +At a high level, the build flow is: |
| 33 | - ↓ | 33 | + |
| 34 | -Linker (symbol resolution, relocation) | 34 | +```text |
| 35 | - ↓ | 35 | +PTO C++ source |
| 36 | -Executable / Shared Library | 36 | + -> C++ preprocessing / compilation |
| 37 | -``` | 37 | + -> PTO intrinsic headers select backend-specific implementations |
| 38 | - | 38 | + -> build system compiles test cases / kernels / demos |
| 39 | -### 1.2 Required Tools | 39 | + -> binaries or test artifacts are produced |
| 40 | - | 40 | +``` |
| 41 | -**CMake** (>= 3.16): | 41 | + |
| 42 | -```bash | 42 | +This description is intentionally written from the developer’s point of view to summarize the main relationship between source code and build artifacts. |
| 43 | -# Ubuntu/Debian | 43 | + |
| 44 | -sudo apt install cmake | 44 | +This document does not define a complete proprietary compiler pipeline as a public contract, such as a fixed sequence of “frontend -> PTO intrinsic expansion -> middle-end IR -> backend lowering”. Such stages may exist in toolchains, but they are not presented here as normative interface definitions. |
| 45 | - | 45 | + |
| 46 | -# macOS | 46 | +## 4. Public intrinsic layer and backend selection |
| 47 | -brew install cmake | 47 | + |
| 48 | -``` | 48 | +The public intrinsic entry point is `../../include/pto/common/pto_instr.hpp`. |
| 49 | - | 49 | + |
| 50 | -**C++ Compiler** (C++20 support): | 50 | +That header exposes APIs such as: |
| 51 | -- GCC >= 13.0 | 51 | + |
| 52 | -- Clang >= 15.0 | 52 | +- `TASSIGN` |
| 53 | -- MSVC 2022 (Windows) | 53 | +- `TSYNC` |
| 54 | - | 54 | +- `TLOAD` |
| 55 | -**Python** (>= 3.8): | 55 | +- `TSTORE` |
| 56 | -```bash | 56 | +- vector instructions such as `TADD`, `TMUL`, `TEXP` |
| 57 | -sudo apt install python3 python3-pip | 57 | +- matrix instructions such as `TMATMUL` |
| 58 | -``` | 58 | + |
| 59 | - | 59 | +The header also includes backend-specific implementation headers based on build conditions. |
| 60 | -### 1.3 Optional Tools | 60 | + |
| 61 | - | 61 | +This means that, from a developer point of view, the compilation process is centered on: |
| 62 | -**Ninja** (faster builds): | 62 | + |
| 63 | -```bash | 63 | +1. writing C++ code against the PTO intrinsics |
| 64 | -sudo apt install ninja-build | 64 | +2. compiling it with the repository build configuration |
| 65 | -``` | 65 | +3. letting the selected backend provide the concrete implementation path |
| 66 | - | 66 | + |
| 67 | -**ccache** (compilation cache): | 67 | +## 5. Build tools used in this repository |
| 68 | -```bash | 68 | + |
| 69 | -sudo apt install ccache | 69 | +The repository clearly depends on: |
| 70 | -export CC="ccache gcc" | 70 | + |
| 71 | -export CXX="ccache g++" | 71 | +- **CMake** |
| 72 | -``` | 72 | +- **Python** for scripts and tests |
| 73 | - | 73 | +- a **C++20-capable compiler** |
| 74 | ---- | 74 | + |
| 75 | - | 75 | +Typical commands used in this repository include: |
| 76 | -## 2. Build System Configuration | 76 | + |
| 77 | - | 77 | +```bash |
| 78 | -### 2.1 Minimal CMake Configuration | 78 | +# CPU simulation |
| 79 | - | 79 | +python3 tests/run_cpu.py --clean --verbose |
| 80 | -```cmake | 80 | + |
| 81 | -cmake_minimum_required(VERSION 3.16) | 81 | +# Run a demo on CPU simulation |
| 82 | -project(MyPTOOperator LANGUAGES CXX) | 82 | +python3 tests/run_cpu.py --demo gemm --verbose |
| 83 | - | 83 | + |
| 84 | -set(CMAKE_CXX_STANDARD 20) | 84 | +# Run ST on simulator backend |
| 85 | -set(CMAKE_CXX_STANDARD_REQUIRED ON) | 85 | +python3 tests/script/run_st.py -r sim -v a3 -t tadd -g TADDTest.case_float_64x64_64x64 |
| 86 | - | 86 | +``` |
| 87 | -find_package(PTO REQUIRED) | 87 | + |
| 88 | - | 88 | +If you are building in this repository, prefer the existing scripts and documented commands over inventing a standalone build flow. |
| 89 | -add_executable(my_operator src/my_operator.cpp) | 89 | + |
| 90 | -target_link_libraries(my_operator PRIVATE PTO::pto) | 90 | +## 6. CPU simulation path vs NPU path |
| 91 | -``` | 91 | + |
| 92 | - | 92 | +### 6.1 CPU simulation |
| 93 | -### 2.2 Build Configuration | 93 | + |
| 94 | - | 94 | +The CPU simulation path is intended for functional development and validation. |
| 95 | -**Backend Selection**: | 95 | + |
| 96 | -```bash | 96 | +In this path: |
| 97 | -# CPU simulation | 97 | + |
| 98 | -cmake -B build -DPTO_BACKEND=CPU | 98 | +- PTO intrinsics remain visible at the C++ source level |
| 99 | - | 99 | +- backend behavior is modeled by the CPU simulation implementation |
| 100 | -# NPU (A2/A3) | 100 | +- some device-only synchronization details are simplified or become no-ops |
| 101 | -cmake -B build -DPTO_BACKEND=NPU -DSOC_VERSION=Ascend910B1 | 101 | + |
| 102 | - | 102 | +Relevant documents: |
| 103 | -# NPU (A5) | 103 | + |
| 104 | -cmake -B build -DPTO_BACKEND=NPU -DSOC_VERSION=Ascend910_9599 | 104 | +- [CPU Simulation](cpu_sim.md) |
| 105 | -``` | 105 | +- [Quickstart Tutorial](tutorial.md) |
| 106 | - | 106 | +- [Events and Synchronization](Event.md) |
| 107 | -**Build Types**: | 107 | + |
| 108 | -```bash | 108 | +### 6.2 NPU path |
| 109 | -# Debug (no optimization, debug symbols) | 109 | + |
| 110 | -cmake -B build -DCMAKE_BUILD_TYPE=Debug | 110 | +The NPU path targets Ascend hardware or simulator-side execution. |
| 111 | - | 111 | + |
| 112 | -# Release (full optimization) | 112 | +In this path: |
| 113 | -cmake -B build -DCMAKE_BUILD_TYPE=Release | 113 | + |
| 114 | - | 114 | +- backend-specific NPU implementations are used |
| 115 | -# RelWithDebInfo (optimization + debug symbols) | 115 | +- device-side constraints matter more directly |
| 116 | -cmake -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo | 116 | +- instruction availability must be checked against the backend support table |
| 117 | -``` | 117 | + |
| 118 | - | 118 | +Relevant references: |
| 119 | -### 2.3 Build Commands | 119 | + |
| 120 | - | 120 | +- [Backend Implementation Status](../../include/README.md) |
| 121 | -```bash | 121 | +- [PTO ISA Reference](../isa/README.md) |
| 122 | -# Configure | 122 | + |
| 123 | -cmake -B build -DCMAKE_BUILD_TYPE=Release | 123 | +## 7. Compilation-related checks |
| 124 | - | 124 | + |
| 125 | -# Build | 125 | +When a PTO kernel does not compile or run as expected, the most reliable checks are: |
| 126 | -cmake --build build -j$(nproc) | 126 | + |
| 127 | - | 127 | +1. **Header-level API usage** |
| 128 | -# Test | 128 | + - Is the intrinsic used according to `../../include/pto/common/pto_instr.hpp`? |
| 129 | -ctest --test-dir build --output-on-failure | 129 | + |
| 130 | - | 130 | +2. **ISA constraints** |
| 131 | -# Install | 131 | + - Does the instruction documentation under `docs/isa/` allow the tile type, layout, and operand combination? |
| 132 | -cmake --install build --prefix /path/to/install | 132 | + |
| 133 | -``` | 133 | +3. **Tile and GlobalTensor definitions** |
| 134 | - | 134 | + - Are tile shapes, valid regions, and layouts legal? |
| 135 | ---- | 135 | + - Are `GlobalTensor` shape/stride declarations correct? |
| 136 | - | 136 | + |
| 137 | -## 3. Compilation Steps | 137 | +4. **Backend support** |
| 138 | - | 138 | + - Is the target instruction implemented on the selected backend according to [Backend Implementation Status](../../include/README.md)? |
| 139 | -### 3.1 Preprocessing | 139 | + |
| 140 | - | 140 | +5. **Build environment** |
| 141 | -**Macro Expansion**: | 141 | + - Are the required compiler, Python environment, and CANN environment available? |
| 142 | -```cpp | 142 | + |
| 143 | -// Source | 143 | +## 8. Notes on build examples |
| 144 | -#define TILE_SIZE 256 | 144 | + |
| 145 | -using TileT = Tile<TileType::Vec, float, 16, TILE_SIZE>; | 145 | +Some commonly written build examples on the internet, such as generic `find_package(PTO REQUIRED)` snippets or imagined standalone `PTO::pto` link targets, are **not** established as the canonical integration model by this repository. |
| 146 | - | 146 | + |
| 147 | -// After preprocessing | 147 | +When documenting or extending PTO Tile Lib, use the repository build scripts, the top-level `CMakeLists.txt`, and existing test or demo build patterns as the primary reference. |
| 148 | -using TileT = Tile<TileType::Vec, float, 16, 256>; | 148 | + |
| 149 | -``` | 149 | +## 9. Notes |
| 150 | - | 150 | + |
| 151 | -**View Preprocessed Output**: | 151 | +The compilation flow of PTO Tile Lib can be summarized as follows: |
| 152 | -```bash | 152 | + |
| 153 | -g++ -E -P src/my_operator.cpp -o my_operator.i | 153 | +- PTO code is written in C++ with public intrinsics. |
| 154 | -``` | 154 | +- The build system selects the corresponding backend implementation according to configuration. |
| 155 | - | 155 | +- CPU simulation is the preferred first validation path. |
| 156 | -### 3.2 Compilation | 156 | +- Backend support and instruction legality are checked explicitly during development. |
| 157 | - | 157 | + |
| 158 | -**PTO Intrinsic Expansion**: | 158 | +The documentation describes the public programming surface and usage model, while internal compiler stages remain implementation details unless stated otherwise in dedicated toolchain documents. |
| 159 | -```cpp | ||
| 160 | -// Source | ||
| 161 | -TLOAD(tile, input); | ||
| 162 | - | ||
| 163 | -// Expanded to low-level instructions | ||
| 164 | -__builtin_pto_load(tile.data(), input.data(), tile.size(), tile.alignment()); | ||
| 165 | -``` | ||
| 166 | - | ||
| 167 | -**Generate Object File**: | ||
| 168 | -```bash | ||
| 169 | -g++ -std=c++20 -O3 -c src/my_operator.cpp -o build/my_operator.o | ||
| 170 | -``` | ||
| 171 | - | ||
| 172 | -### 3.3 Linking | ||
| 173 | - | ||
| 174 | -**Symbol Resolution**: | ||
| 175 | -``` | ||
| 176 | -my_operator.o: | ||
| 177 | - - Defines: main, my_kernel | ||
| 178 | - - References: TLOAD, TSTORE, TADD | ||
| 179 | - | ||
| 180 | -libpto.a: | ||
| 181 | - - Defines: TLOAD, TSTORE, TADD, ... | ||
| 182 | - | ||
| 183 | -Linker resolves: | ||
| 184 | - my_operator.o::TLOAD → libpto.a::TLOAD ✓ | ||
| 185 | -``` | ||
| 186 | - | ||
| 187 | -**Generate Executable**: | ||
| 188 | -```bash | ||
| 189 | -g++ build/my_operator.o -L/path/to/pto/lib -lpto -o build/my_operator | ||
| 190 | -``` | ||
| 191 | - | ||
| 192 | ---- | ||
| 193 | - | ||
| 194 | -## 4. Compilation Options | ||
| 195 | - | ||
| 196 | -### 4.1 Optimization Levels | ||
| 197 | - | ||
| 198 | -| Option | Use Case | Performance | | ||
| 199 | -|--------|----------|-------------| | ||
| 200 | -| `-O0` | Debugging | Slowest | | ||
| 201 | -| `-O1` | Basic optimization | Medium | | ||
| 202 | -| `-O2` | Production (recommended) | Fast | | ||
| 203 | -| `-O3` | Maximum optimization | Fastest | | ||
| 204 | -| `-Os` | Size optimization | Medium | | ||
| 205 | -| `-Ofast` | Aggressive (may violate standards) | Fastest | | ||
| 206 | - | ||
| 207 | -**Example**: | ||
| 208 | -```bash | ||
| 209 | -# Production build | ||
| 210 | -g++ -O3 -march=native src/my_operator.cpp | ||
| 211 | - | ||
| 212 | -# Debug build | ||
| 213 | -g++ -O0 -g src/my_operator.cpp | ||
| 214 | -``` | ||
| 215 | - | ||
| 216 | -### 4.2 Architecture-Specific Options | ||
| 217 | - | ||
| 218 | -**-march=native**: Optimize for current CPU | ||
| 219 | -```bash | ||
| 220 | -g++ -O3 -march=native src/my_operator.cpp | ||
| 221 | -``` | ||
| 222 | - | ||
| 223 | -**-march=x86-64**: Generic x86-64 code | ||
| 224 | -```bash | ||
| 225 | -g++ -O3 -march=x86-64 src/my_operator.cpp | ||
| 226 | -``` | ||
| 227 | - | ||
| 228 | -### 4.3 Debug Options | ||
| 229 | - | ||
| 230 | -**Debug Symbols**: | ||
| 231 | -```bash | ||
| 232 | -g++ -g src/my_operator.cpp | ||
| 233 | -gdb ./my_operator | ||
| 234 | -``` | ||
| 235 | - | ||
| 236 | -**Sanitizers**: | ||
| 237 | -```bash | ||
| 238 | -# Address sanitizer (memory errors) | ||
| 239 | -g++ -fsanitize=address src/my_operator.cpp | ||
| 240 | - | ||
| 241 | -# Undefined behavior sanitizer | ||
| 242 | -g++ -fsanitize=undefined src/my_operator.cpp | ||
| 243 | -``` | ||
| 244 | - | ||
| 245 | -### 4.4 Warning Options | ||
| 246 | - | ||
| 247 | -```bash | ||
| 248 | -g++ -Wall -Wextra -Wpedantic -Werror src/my_operator.cpp | ||
| 249 | -``` | ||
| 250 | - | ||
| 251 | ---- | ||
| 252 | - | ||
| 253 | -## 5. Cross Compilation | ||
| 254 | - | ||
| 255 | -### 5.1 x86 → ARM Cross Compilation | ||
| 256 | - | ||
| 257 | -**Install Toolchain**: | ||
| 258 | -```bash | ||
| 259 | -sudo apt install g++-aarch64-linux-gnu | ||
| 260 | -``` | ||
| 261 | - | ||
| 262 | -**CMake Toolchain File**: | ||
| 263 | -```cmake | ||
| 264 | -# toolchain-aarch64.cmake | ||
| 265 | -set(CMAKE_SYSTEM_NAME Linux) | ||
| 266 | -set(CMAKE_SYSTEM_PROCESSOR aarch64) | ||
| 267 | -set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc) | ||
| 268 | -set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++) | ||
| 269 | -``` | ||
| 270 | - | ||
| 271 | -**Build**: | ||
| 272 | -```bash | ||
| 273 | -cmake -B build -DCMAKE_TOOLCHAIN_FILE=toolchain-aarch64.cmake | ||
| 274 | -cmake --build build | ||
| 275 | -``` | ||
| 276 | - | ||
| 277 | ---- | ||
| 278 | - | ||
| 279 | -## 6. Compilation Optimization | ||
| 280 | - | ||
| 281 | -### 6.1 Speed Up Compilation | ||
| 282 | - | ||
| 283 | -**Use Ninja**: | ||
| 284 | -```bash | ||
| 285 | -cmake -B build -G Ninja | ||
| 286 | -ninja -C build | ||
| 287 | -``` | ||
| 288 | - | ||
| 289 | -**Use ccache**: | ||
| 290 | -```bash | ||
| 291 | -export CC="ccache gcc" | ||
| 292 | -export CXX="ccache g++" | ||
| 293 | -cmake -B build | ||
| 294 | -cmake --build build | ||
| 295 | -``` | ||
| 296 | - | ||
| 297 | -**Parallel Build**: | ||
| 298 | -```bash | ||
| 299 | -cmake --build build -j$(nproc) | ||
| 300 | -``` | ||
| 301 | - | ||
| 302 | -**Precompiled Headers**: | ||
| 303 | -```cmake | ||
| 304 | -target_precompile_headers(my_operator PRIVATE <pto/pto-inst.hpp>) | ||
| 305 | -``` | ||
| 306 | - | ||
| 307 | -### 6.2 Reduce Binary Size | ||
| 308 | - | ||
| 309 | -**Strip Debug Symbols**: | ||
| 310 | -```bash | ||
| 311 | -strip build/my_operator | ||
| 312 | -``` | ||
| 313 | - | ||
| 314 | -**Link-Time Optimization (LTO)**: | ||
| 315 | -```cmake | ||
| 316 | -set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) | ||
| 317 | -``` | ||
| 318 | - | ||
| 319 | ---- | ||
| 320 | - | ||
| 321 | -## 7. Troubleshooting | ||
| 322 | - | ||
| 323 | -### 7.1 Common Compilation Errors | ||
| 324 | - | ||
| 325 | -**Error: Header not found** | ||
| 326 | -``` | ||
| 327 | -error: pto/pto-inst.hpp: No such file or directory | ||
| 328 | -``` | ||
| 329 | - | ||
| 330 | -**Solution**: | ||
| 331 | -```bash | ||
| 332 | -export PTO_LIB_PATH=/path/to/pto-isa | ||
| 333 | -cmake -B build -DPTO_ROOT=/path/to/pto-isa | ||
| 334 | -``` | ||
| 335 | - | ||
| 336 | -**Error: Static assertion failed** | ||
| 337 | -``` | ||
| 338 | -static_assert failed: "Tile shape not aligned" | ||
| 339 | -``` | ||
| 340 | - | ||
| 341 | -**Solution**: | ||
| 342 | -```cpp | ||
| 343 | -// Wrong: width 250 is not multiple of 16 | ||
| 344 | -using TileT = Tile<TileType::Vec, float, 16, 250>; | ||
| 345 | - | ||
| 346 | -// Correct: width 256 is multiple of 16 | ||
| 347 | -using TileT = Tile<TileType::Vec, float, 16, 256>; | ||
| 348 | -``` | ||
| 349 | - | ||
| 350 | -**Error: Undefined reference** | ||
| 351 | -``` | ||
| 352 | -undefined reference to `pto::TLOAD(...)` | ||
| 353 | -``` | ||
| 354 | - | ||
| 355 | -**Solution**: | ||
| 356 | -```cmake | ||
| 357 | -target_link_libraries(my_operator PRIVATE PTO::pto) | ||
| 358 | -``` | ||
| 359 | - | ||
| 360 | -### 7.2 Runtime Errors | ||
| 361 | - | ||
| 362 | -**Error: Shared library not found** | ||
| 363 | -``` | ||
| 364 | -error while loading shared libraries: libpto.so | ||
| 365 | -``` | ||
| 366 | - | ||
| 367 | -**Solution**: | ||
| 368 | -```bash | ||
| 369 | -export LD_LIBRARY_PATH=/path/to/pto/lib:$LD_LIBRARY_PATH | ||
| 370 | -``` | ||
| 371 | - | ||
| 372 | ---- | ||
| 373 | - | ||
| 374 | -## References | ||
| 375 | - | ||
| 376 | -- [Getting Started](../getting-started.md) | ||
| 377 | -- [Debugging Guide](debug.md) | ||
| 378 | -- [Performance Optimization](opt.md) | ||
| 379 | -- [CMake Documentation](https://cmake.org/documentation/) | ||
| 380 | - | ||
| @@ -1,960 +1,158 @@ | |||
| 1 | -# 编译流程详解 | 1 | +# 编译流程说明 |
| 2 | 2 | ||
| 3 | -本文档详细介绍 PTO 算子的编译流程,帮助开发者理解从源代码到可执行文件的完整过程,掌握编译优化技巧。 | 3 | +本文档从源码组织、公共 intrinsics、backend 选择和仓库构建入口几个角度,说明 PTO Tile Lib 的构建与编译流程。 |
| 4 | 4 | ||
| 5 | -## 目录 | 5 | +本文档重点描述开发者可见的工作流,不将未公开定义的编译器内部阶段扩展为规范接口说明。 |
| 6 | 6 | ||
| 7 | -- [1. 编译流程概述](#1-编译流程概述) | 7 | +## 1. 概述 |
| 8 | -- [2. 构建系统配置](#2-构建系统配置) | ||
| 9 | -- [3. 编译步骤详解](#3-编译步骤详解) | ||
| 10 | -- [4. 编译选项说明](#4-编译选项说明) | ||
| 11 | -- [5. 交叉编译](#5-交叉编译) | ||
| 12 | -- [6. 编译优化](#6-编译优化) | ||
| 13 | -- [7. 常见问题排查](#7-常见问题排查) | ||
| 14 | -- [8. 高级主题](#8-高级主题) | ||
| 15 | 8 | ||
| 16 | ---- | 9 | +PTO kernel 以 C++ 形式编写,并通过 `TLOAD`、`TADD`、`TMATMUL`、`TSYNC`、`TSTORE` 等 PTO intrinsic 表达计算与数据移动。 |
| 17 | 10 | ||
| 18 | -## 1. 编译流程概述 | 11 | +常用的公共入口头文件是: |
| 19 | 12 | ||
| 20 | -### 1.1 完整编译流程图 | ||
| 21 | - | ||
| 22 | -``` | ||
| 23 | -┌─────────────────────────────────────────────────────────────┐ | ||
| 24 | -│ PTO C++ 源码 (.cpp) │ | ||
| 25 | -└────────────────────────┬────────────────────────────────────┘ | ||
| 26 | - │ | ||
| 27 | - ▼ | ||
| 28 | -┌─────────────────────────────────────────────────────────────┐ | ||
| 29 | -│ 预处理器 (Preprocessor) │ | ||
| 30 | -│ - 宏展开 (#define) │ | ||
| 31 | -│ - 头文件包含 (#include) │ | ||
| 32 | -│ - 条件编译 (#ifdef) │ | ||
| 33 | -└────────────────────────┬────────────────────────────────────┘ | ||
| 34 | - │ | ||
| 35 | - ▼ | ||
| 36 | -┌─────────────────────────────────────────────────────────────┐ | ||
| 37 | -│ C++ 编译器前端 (Frontend) │ | ||
| 38 | -│ - 词法分析 (Lexer) │ | ||
| 39 | -│ - 语法分析 (Parser) │ | ||
| 40 | -│ - 语义分析 (Semantic Analysis) │ | ||
| 41 | -│ - 生成 AST (Abstract Syntax Tree) │ | ||
| 42 | -└────────────────────────┬────────────────────────────────────┘ | ||
| 43 | - │ | ||
| 44 | - ▼ | ||
| 45 | -┌─────────────────────────────────────────────────────────────┐ | ||
| 46 | -│ PTO 内建函数展开 │ | ||
| 47 | -│ - TLOAD → 底层加载指令 │ | ||
| 48 | -│ - TSTORE → 底层存储指令 │ | ||
| 49 | -│ - TADD/TMUL → 底层计算指令 │ | ||
| 50 | -│ - 静态检查 (Tile 对齐、类型匹配) │ | ||
| 51 | -└────────────────────────┬────────────────────────────────────┘ | ||
| 52 | - │ | ||
| 53 | - ▼ | ||
| 54 | -┌─────────────────────────────────────────────────────────────┐ | ||
| 55 | -│ 编译器中端 (Middle-end) │ | ||
| 56 | -│ - 优化 Pass (内联、循环展开、常量折叠) │ | ||
| 57 | -│ - 生成中间表示 (IR) │ | ||
| 58 | -└────────────────────────┬────────────────────────────────────┘ | ||
| 59 | - │ | ||
| 60 | - ▼ | ||
| 61 | -┌─────────────────────────────────────────────────────────────┐ | ||
| 62 | -│ 编译器后端 (Backend) │ | ||
| 63 | -│ - 指令选择 │ | ||
| 64 | -│ - 寄存器分配 │ | ||
| 65 | -│ - 指令调度 │ | ||
| 66 | -│ - 生成目标代码 (.o) │ | ||
| 67 | -└────────────────────────┬────────────────────────────────────┘ | ||
| 68 | - │ | ||
| 69 | - ▼ | ||
| 70 | -┌─────────────────────────────────────────────────────────────┐ | ||
| 71 | -│ 链接器 (Linker) │ | ||
| 72 | -│ - 符号解析 │ | ||
| 73 | -│ - 重定位 │ | ||
| 74 | -│ - 生成可执行文件 / 共享库 │ | ||
| 75 | -└────────────────────────┬────────────────────────────────────┘ | ||
| 76 | - │ | ||
| 77 | - ▼ | ||
| 78 | -┌─────────────────────────────────────────────────────────────┐ | ||
| 79 | -│ 可执行文件 / 共享库 (.so / .exe) │ | ||
| 80 | -└─────────────────────────────────────────────────────────────┘ | ||
| 81 | -``` | ||
| 82 | - | ||
| 83 | -### 1.2 编译工具链 | ||
| 84 | - | ||
| 85 | -#### 必需工具 | ||
| 86 | - | ||
| 87 | -**CMake**: | ||
| 88 | -- 版本要求:>= 3.16 | ||
| 89 | -- 用途:构建系统生成器 | ||
| 90 | -- 安装: | ||
| 91 | - ```bash | ||
| 92 | - # Ubuntu/Debian | ||
| 93 | - sudo apt install cmake | ||
| 94 | - | ||
| 95 | - # CentOS/RHEL | ||
| 96 | - sudo yum install cmake | ||
| 97 | - | ||
| 98 | - # macOS | ||
| 99 | - brew install cmake | ||
| 100 | - | ||
| 101 | - # Windows | ||
| 102 | - # 从 https://cmake.org/download/ 下载安装 | ||
| 103 | - ``` | ||
| 104 | - | ||
| 105 | -**C++ 编译器**: | ||
| 106 | -- 要求:支持 C++20 标准 | ||
| 107 | -- Linux 选项: | ||
| 108 | - - GCC >= 13.0 | ||
| 109 | - - Clang >= 15.0 | ||
| 110 | -- Windows 选项: | ||
| 111 | - - MSVC 2022 (Visual Studio 17.0+) | ||
| 112 | - - MinGW-w64 (GCC 13+) | ||
| 113 | -- 安装: | ||
| 114 | - ```bash | ||
| 115 | - # Ubuntu/Debian - GCC | ||
| 116 | - sudo apt install g++-13 | ||
| 117 | - | ||
| 118 | - # Ubuntu/Debian - Clang | ||
| 119 | - sudo apt install clang-15 | ||
| 120 | - | ||
| 121 | - # CentOS/RHEL | ||
| 122 | - sudo yum install gcc-toolset-13 | ||
| 123 | - ``` | ||
| 124 | - | ||
| 125 | -**Python**: | ||
| 126 | -- 版本要求:>= 3.8 | ||
| 127 | -- 用途:构建脚本、测试工具 | ||
| 128 | -- 安装: | ||
| 129 | - ```bash | ||
| 130 | - # Ubuntu/Debian | ||
| 131 | - sudo apt install python3 python3-pip | ||
| 132 | - | ||
| 133 | - # CentOS/RHEL | ||
| 134 | - sudo yum install python3 python3-pip | ||
| 135 | - ``` | ||
| 136 | - | ||
| 137 | -#### 可选工具 | ||
| 138 | - | ||
| 139 | -**Ninja**: | ||
| 140 | -- 用途:加速构建(比 Make 快 2-3×) | ||
| 141 | -- 安装: | ||
| 142 | - ```bash | ||
| 143 | - # Ubuntu/Debian | ||
| 144 | - sudo apt install ninja-build | ||
| 145 | - | ||
| 146 | - # CentOS/RHEL | ||
| 147 | - sudo yum install ninja-build | ||
| 148 | - | ||
| 149 | - # macOS | ||
| 150 | - brew install ninja | ||
| 151 | - ``` | ||
| 152 | - | ||
| 153 | -**ccache**: | ||
| 154 | -- 用途:编译缓存(加速重复编译) | ||
| 155 | -- 安装: | ||
| 156 | - ```bash | ||
| 157 | - # Ubuntu/Debian | ||
| 158 | - sudo apt install ccache | ||
| 159 | - | ||
| 160 | - # 配置 | ||
| 161 | - export CC="ccache gcc" | ||
| 162 | - export CXX="ccache g++" | ||
| 163 | - ``` | ||
| 164 | - | ||
| 165 | -**clang-tidy**: | ||
| 166 | -- 用途:静态代码分析 | ||
| 167 | -- 安装: | ||
| 168 | - ```bash | ||
| 169 | - sudo apt install clang-tidy | ||
| 170 | - ``` | ||
| 171 | - | ||
| 172 | ---- | ||
| 173 | - | ||
| 174 | -## 2. 构建系统配置 | ||
| 175 | - | ||
| 176 | -### 2.1 CMake 基础配置 | ||
| 177 | - | ||
| 178 | -**最小配置示例**: | ||
| 179 | -```cmake | ||
| 180 | -# CMakeLists.txt | ||
| 181 | -cmake_minimum_required(VERSION 3.16) | ||
| 182 | -project(MyPTOOperator VERSION 1.0.0 LANGUAGES CXX) | ||
| 183 | - | ||
| 184 | -# 设置 C++ 标准 | ||
| 185 | -set(CMAKE_CXX_STANDARD 20) | ||
| 186 | -set(CMAKE_CXX_STANDARD_REQUIRED ON) | ||
| 187 | -set(CMAKE_CXX_EXTENSIONS OFF) | ||
| 188 | - | ||
| 189 | -# 查找 PTO 库 | ||
| 190 | -find_package(PTO REQUIRED) | ||
| 191 | - | ||
| 192 | -# 添加可执行文件 | ||
| 193 | -add_executable(my_operator | ||
| 194 | - src/my_operator.cpp | ||
| 195 | -) | ||
| 196 | - | ||
| 197 | -# 链接 PTO 库 | ||
| 198 | -target_link_libraries(my_operator | ||
| 199 | - PRIVATE PTO::pto | ||
| 200 | -) | ||
| 201 | -``` | ||
| 202 | - | ||
| 203 | -**完整配置示例**: | ||
| 204 | -```cmake | ||
| 205 | -cmake_minimum_required(VERSION 3.16) | ||
| 206 | -project(MyPTOOperator VERSION 1.0.0 LANGUAGES CXX) | ||
| 207 | - | ||
| 208 | -# ============ 编译选项 ============ | ||
| 209 | -set(CMAKE_CXX_STANDARD 20) | ||
| 210 | -set(CMAKE_CXX_STANDARD_REQUIRED ON) | ||
| 211 | -set(CMAKE_CXX_EXTENSIONS OFF) | ||
| 212 | - | ||
| 213 | -# 导出编译命令(用于 IDE 和工具) | ||
| 214 | -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) | ||
| 215 | - | ||
| 216 | -# ============ 构建类型 ============ | ||
| 217 | -if(NOT CMAKE_BUILD_TYPE) | ||
| 218 | - set(CMAKE_BUILD_TYPE Release) | ||
| 219 | -endif() | ||
| 220 | - | ||
| 221 | -# Debug 选项 | ||
| 222 | -set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -DDEBUG") | ||
| 223 | - | ||
| 224 | -# Release 选项 | ||
| 225 | -set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -march=native") | ||
| 226 | - | ||
| 227 | -# RelWithDebInfo 选项 | ||
| 228 | -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DNDEBUG") | ||
| 229 | - | ||
| 230 | -# ============ PTO 配置 ============ | ||
| 231 | -# 设置 PTO 后端 | ||
| 232 | -set(PTO_BACKEND "CPU" CACHE STRING "PTO backend: CPU or NPU") | ||
| 233 | -set_property(CACHE PTO_BACKEND PROPERTY STRINGS CPU NPU) | ||
| 234 | - | ||
| 235 | -# 设置 SOC 版本(NPU 后端) | ||
| 236 | -if(PTO_BACKEND STREQUAL "NPU") | ||
| 237 | - set(SOC_VERSION "Ascend910B1" CACHE STRING "SOC version") | ||
| 238 | - set_property(CACHE SOC_VERSION PROPERTY STRINGS | ||
| 239 | - Ascend910B1 # A2 | ||
| 240 | - Ascend910B2 # A3 | ||
| 241 | - Ascend910_9599 # A5 | ||
| 242 | - ) | ||
| 243 | -endif() | ||
| 244 | - | ||
| 245 | -# 查找 PTO 库 | ||
| 246 | -find_package(PTO REQUIRED) | ||
| 247 | - | ||
| 248 | -# ============ 源文件 ============ | ||
| 249 | -file(GLOB_RECURSE SOURCES | ||
| 250 | - src/*.cpp | ||
| 251 | -) | ||
| 252 | - | ||
| 253 | -# ============ 可执行文件 ============ | ||
| 254 | -add_executable(my_operator ${SOURCES}) | ||
| 255 | - | ||
| 256 | -# 包含目录 | ||
| 257 | -target_include_directories(my_operator | ||
| 258 | - PRIVATE | ||
| 259 | - ${CMAKE_CURRENT_SOURCE_DIR}/include | ||
| 260 | -) | ||
| 261 | - | ||
| 262 | -# 链接库 | ||
| 263 | -target_link_libraries(my_operator | ||
| 264 | - PRIVATE | ||
| 265 | - PTO::pto | ||
| 266 | -) | ||
| 267 | - | ||
| 268 | -# 编译选项 | ||
| 269 | -target_compile_options(my_operator | ||
| 270 | - PRIVATE | ||
| 271 | - -Wall | ||
| 272 | - -Wextra | ||
| 273 | - -Wpedantic | ||
| 274 | - $<$<CONFIG:Release>:-ffast-math> | ||
| 275 | -) | ||
| 276 | - | ||
| 277 | -# ============ 安装 ============ | ||
| 278 | -install(TARGETS my_operator | ||
| 279 | - RUNTIME DESTINATION bin | ||
| 280 | -) | ||
| 281 | - | ||
| 282 | -# ============ 测试 ============ | ||
| 283 | -enable_testing() | ||
| 284 | -add_subdirectory(tests) | ||
| 285 | -``` | ||
| 286 | - | ||
| 287 | -### 2.2 配置选项说明 | ||
| 288 | - | ||
| 289 | -**后端选择**: | ||
| 290 | -```bash | ||
| 291 | -# CPU 仿真构建(开发调试) | ||
| 292 | -cmake -B build -DPTO_BACKEND=CPU | ||
| 293 | - | ||
| 294 | -# NPU 构建(A2 芯片) | ||
| 295 | -cmake -B build -DPTO_BACKEND=NPU -DSOC_VERSION=Ascend910B1 | ||
| 296 | - | ||
| 297 | -# NPU 构建(A3 芯片) | ||
| 298 | -cmake -B build -DPTO_BACKEND=NPU -DSOC_VERSION=Ascend910B2 | ||
| 299 | - | ||
| 300 | -# NPU 构建(A5 芯片) | ||
| 301 | -cmake -B build -DPTO_BACKEND=NPU -DSOC_VERSION=Ascend910_9599 | ||
| 302 | -``` | ||
| 303 | - | ||
| 304 | -**构建类型**: | ||
| 305 | -```bash | ||
| 306 | -# Debug 构建(无优化,包含调试符号) | ||
| 307 | -cmake -B build -DCMAKE_BUILD_TYPE=Debug | ||
| 308 | - | ||
| 309 | -# Release 构建(完全优化,无调试符号) | ||
| 310 | -cmake -B build -DCMAKE_BUILD_TYPE=Release | ||
| 311 | - | ||
| 312 | -# RelWithDebInfo 构建(优化 + 调试符号) | ||
| 313 | -cmake -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo | ||
| 314 | - | ||
| 315 | -# MinSizeRel 构建(优化代码大小) | ||
| 316 | -cmake -B build -DCMAKE_BUILD_TYPE=MinSizeRel | ||
| 317 | -``` | ||
| 318 | - | ||
| 319 | -**编译器选择**: | ||
| 320 | -```bash | ||
| 321 | -# 使用 GCC | ||
| 322 | -cmake -B build -DCMAKE_CXX_COMPILER=g++-13 | ||
| 323 | - | ||
| 324 | -# 使用 Clang | ||
| 325 | -cmake -B build -DCMAKE_CXX_COMPILER=clang++-15 | ||
| 326 | - | ||
| 327 | -# 使用 ccache 加速 | ||
| 328 | -cmake -B build \ | ||
| 329 | - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ | ||
| 330 | - -DCMAKE_CXX_COMPILER=g++ | ||
| 331 | -``` | ||
| 332 | - | ||
| 333 | -**生成器选择**: | ||
| 334 | -```bash | ||
| 335 | -# 使用 Make(默认) | ||
| 336 | -cmake -B build | ||
| 337 | - | ||
| 338 | -# 使用 Ninja(推荐,更快) | ||
| 339 | -cmake -B build -G Ninja | ||
| 340 | - | ||
| 341 | -# 使用 Visual Studio(Windows) | ||
| 342 | -cmake -B build -G "Visual Studio 17 2022" | ||
| 343 | -``` | ||
| 344 | - | ||
| 345 | -### 2.3 构建命令 | ||
| 346 | - | ||
| 347 | -**标准构建流程**: | ||
| 348 | -```bash | ||
| 349 | -# 步骤1:配置 | ||
| 350 | -cmake -B build -DCMAKE_BUILD_TYPE=Release | ||
| 351 | - | ||
| 352 | -# 步骤2:编译 | ||
| 353 | -cmake --build build -j$(nproc) | ||
| 354 | - | ||
| 355 | -# 步骤3:运行测试 | ||
| 356 | -ctest --test-dir build --output-on-failure | ||
| 357 | - | ||
| 358 | -# 步骤4:安装 | ||
| 359 | -cmake --install build --prefix /path/to/install | ||
| 360 | -``` | ||
| 361 | - | ||
| 362 | -**增量构建**: | ||
| 363 | -```bash | ||
| 364 | -# 只重新编译修改的文件 | ||
| 365 | -cmake --build build | ||
| 366 | - | ||
| 367 | -# 强制重新编译所有文件 | ||
| 368 | -cmake --build build --clean-first | ||
| 369 | -``` | ||
| 370 | - | ||
| 371 | -**并行构建**: | ||
| 372 | -```bash | ||
| 373 | -# 使用所有 CPU 核心 | ||
| 374 | -cmake --build build -j$(nproc) | ||
| 375 | - | ||
| 376 | -# 使用指定数量的核心 | ||
| 377 | -cmake --build build -j8 | ||
| 378 | - | ||
| 379 | -# Ninja 自动并行 | ||
| 380 | -ninja -C build | ||
| 381 | -``` | ||
| 382 | - | ||
| 383 | -**详细输出**: | ||
| 384 | -```bash | ||
| 385 | -# 显示编译命令 | ||
| 386 | -cmake --build build --verbose | ||
| 387 | - | ||
| 388 | -# 或使用环境变量 | ||
| 389 | -VERBOSE=1 cmake --build build | ||
| 390 | -``` | ||
| 391 | - | ||
| 392 | ---- | ||
| 393 | - | ||
| 394 | -## 3. 编译步骤详解 | ||
| 395 | - | ||
| 396 | -### 3.1 预处理阶段 | ||
| 397 | - | ||
| 398 | -**宏展开**: | ||
| 399 | ```cpp | 13 | ```cpp |
| 400 | -// 源码 | ||
| 401 | -#define TILE_SIZE 256 | ||
| 402 | -#define TILE_SHAPE 16, TILE_SIZE | ||
| 403 | - | ||
| 404 | -using TileT = Tile<TileType::Vec, float, TILE_SHAPE>; | ||
| 405 | - | ||
| 406 | -// 预处理后 | ||
| 407 | -using TileT = Tile<TileType::Vec, float, 16, 256>; | ||
| 408 | -``` | ||
| 409 | - | ||
| 410 | -**头文件包含**: | ||
| 411 | -```cpp | ||
| 412 | -// 源码 | ||
| 413 | #include <pto/pto-inst.hpp> | 14 | #include <pto/pto-inst.hpp> |
| 414 | - | ||
| 415 | -// 预处理后(展开为所有 PTO 头文件) | ||
| 416 | -#include <pto/tile.hpp> | ||
| 417 | -#include <pto/global_tensor.hpp> | ||
| 418 | -#include <pto/intrinsics.hpp> | ||
| 419 | -// ... 更多头文件 | ||
| 420 | ``` | 15 | ``` |
| 421 | 16 | ||
| 422 | -**条件编译**: | 17 | +intrinsic 层主要由 [PTO 公共头文件](../../include/pto/README.md) 下的头文件提供,其中最核心的是 `../../include/pto/common/pto_instr.hpp`。 |
| 423 | -```cpp | ||
| 424 | -// 源码 | ||
| 425 | -#ifdef PTO_BACKEND_CPU | ||
| 426 | - // CPU 仿真代码 | ||
| 427 | - run_cpu_kernel(); | ||
| 428 | -#else | ||
| 429 | - // NPU 代码 | ||
| 430 | - run_npu_kernel(); | ||
| 431 | -#endif | ||
| 432 | 18 | ||
| 433 | -// 预处理后(CPU 后端) | 19 | +## 2. 构建与编译特征 |
| 434 | -run_cpu_kernel(); | ||
| 435 | 20 | ||
| 436 | -// 预处理后(NPU 后端) | 21 | +PTO Tile Lib 采用 **C++ intrinsic 接口**。 |
| 437 | -run_npu_kernel(); | 22 | + |
| 23 | +从公共 API 角度看,该库主要采用 **header-based / template-based** 的使用方式。 | ||
| 24 | +同一份 PTO 源码可以在不同 build 配置下对接不同 backend。 | ||
| 25 | +CPU 仿真是推荐的首选功能验证路径,NPU 执行则依赖 Ascend CANN 环境。 | ||
| 26 | +代码库要求使用 **C++20 或更高版本**。 | ||
| 27 | + | ||
| 28 | +项目级构建说明可参考 [项目概览](../../README.md) 和 [快速开始](../getting-started.md)。 | ||
| 29 | + | ||
| 30 | +## 3. 构建流程 | ||
| 31 | + | ||
| 32 | +从开发者视角看,构建流程可以概括为: | ||
| 33 | + | ||
| 34 | +```text | ||
| 35 | +PTO C++ 源码 | ||
| 36 | + -> C++ 预处理 / 编译 | ||
| 37 | + -> PTO intrinsic 头文件选择对应 backend 实现 | ||
| 38 | + -> 构建系统编译测试、kernel 或 demo | ||
| 39 | + -> 生成二进制或测试产物 | ||
| 438 | ``` | 40 | ``` |
| 439 | 41 | ||
| 440 | -**查看预处理结果**: | 42 | +该描述采用开发者视角,用于概括源代码到构建产物之间的主要关系。 |
| 43 | + | ||
| 44 | +当前文档不将某个完整的专有编译器流水线表述为公开契约,例如“frontend -> PTO intrinsic expansion -> middle-end IR -> backend lowering”这样的固定内部阶段顺序。相关过程可能存在于工具链中,但不作为本文档中的规范接口说明。 | ||
| 45 | + | ||
| 46 | +## 4. 公共 intrinsic 层与 backend 选择 | ||
| 47 | + | ||
| 48 | +公共 intrinsic 入口位于 `../../include/pto/common/pto_instr.hpp`。 | ||
| 49 | + | ||
| 50 | +该头文件暴露了以下一类接口: | ||
| 51 | + | ||
| 52 | +- `TASSIGN` | ||
| 53 | +- `TSYNC` | ||
| 54 | +- `TLOAD` | ||
| 55 | +- `TSTORE` | ||
| 56 | +- `TADD`、`TMUL`、`TEXP` 等向量类指令 | ||
| 57 | +- `TMATMUL` 等矩阵类指令 | ||
| 58 | + | ||
| 59 | +同时,这个头文件也会根据构建条件包含不同的 backend 实现头文件。 | ||
| 60 | + | ||
| 61 | +因此,从开发者角度理解编译过程时,更准确的方式是: | ||
| 62 | + | ||
| 63 | +1. 使用 PTO intrinsics 编写 C++ 代码 | ||
| 64 | +2. 按照仓库的构建配置进行编译 | ||
| 65 | +3. 由所选 backend 提供具体实现路径 | ||
| 66 | + | ||
| 67 | +## 5. 本仓库中实际使用的构建工具 | ||
| 68 | + | ||
| 69 | +当前仓库可以明确依赖以下工具: | ||
| 70 | + | ||
| 71 | +- **CMake** | ||
| 72 | +- **Python**(用于脚本和测试) | ||
| 73 | +- **支持 C++20 的编译器** | ||
| 74 | + | ||
| 75 | +本仓库中常见的命令例如: | ||
| 76 | + | ||
| 441 | ```bash | 77 | ```bash |
| 442 | -# GCC | 78 | +# CPU 仿真 |
| 443 | -g++ -E -P src/my_operator.cpp -o my_operator.i | 79 | +python3 tests/run_cpu.py --clean --verbose |
| 444 | 80 | ||
| 445 | -# Clang | 81 | +# 在 CPU 仿真上运行 demo |
| 446 | -clang++ -E -P src/my_operator.cpp -o my_operator.i | 82 | +python3 tests/run_cpu.py --demo gemm --verbose |
| 83 | + | ||
| 84 | +# 在 simulator backend 上运行 ST | ||
| 85 | +python3 tests/script/run_st.py -r sim -v a3 -t tadd -g TADDTest.case_float_64x64_64x64 | ||
| 447 | ``` | 86 | ``` |
| 448 | 87 | ||
| 449 | -### 3.2 编译阶段 | 88 | +在本仓库内进行构建时,建议优先采用已有脚本和文档中的命令,而不是自行假设一套独立的构建流程。 |
| 450 | 89 | ||
| 451 | -**词法分析**: | 90 | +## 6. CPU 仿真路径与 NPU 路径 |
| 452 | -```cpp | ||
| 453 | -// 源码 | ||
| 454 | -TLOAD(tile, input); | ||
| 455 | 91 | ||
| 456 | -// Token 流 | 92 | +### 6.1 CPU 仿真路径 |
| 457 | -IDENTIFIER(TLOAD) | ||
| 458 | -LPAREN | ||
| 459 | -IDENTIFIER(tile) | ||
| 460 | -COMMA | ||
| 461 | -IDENTIFIER(input) | ||
| 462 | -RPAREN | ||
| 463 | -SEMICOLON | ||
| 464 | -``` | ||
| 465 | 93 | ||
| 466 | -**语法分析**: | 94 | +CPU 仿真路径主要用于功能开发和正确性验证。 |
| 467 | -``` | ||
| 468 | -FunctionCall | ||
| 469 | -├─ Function: TLOAD | ||
| 470 | -└─ Arguments | ||
| 471 | - ├─ tile | ||
| 472 | - └─ input | ||
| 473 | -``` | ||
| 474 | 95 | ||
| 475 | -**语义分析**: | 96 | +在该路径下: |
| 476 | -```cpp | ||
| 477 | -// 检查类型匹配 | ||
| 478 | -TLOAD(tile, input); | ||
| 479 | -// tile: Tile<TileType::Vec, float, 16, 256> | ||
| 480 | -// input: GlobalTensor<float> | ||
| 481 | -// ✓ 类型兼容 | ||
| 482 | 97 | ||
| 483 | -// 检查对齐 | 98 | +- PTO intrinsic 仍以 C++ 源码形式直接出现 |
| 484 | -static_assert(256 % 16 == 0, "Tile width must be aligned"); | 99 | +- backend 行为由 CPU 仿真实现建模 |
| 485 | -// ✓ 对齐检查通过 | 100 | +- 某些仅设备端有效的同步细节会被简化,或者表现为 no-op |
| 486 | -``` | ||
| 487 | 101 | ||
| 488 | -**PTO 内建函数展开**: | 102 | +相关文档: |
| 489 | -```cpp | ||
| 490 | -// 源码 | ||
| 491 | -TLOAD(tile, input); | ||
| 492 | 103 | ||
| 493 | -// 展开为底层指令 | 104 | +- [CPU 仿真](cpu_sim.md) |
| 494 | -__builtin_pto_load( | 105 | +- [快速开始教程](tutorial.md) |
| 495 | - tile.data(), | 106 | +- [事件与同步](Event.md) |
| 496 | - input.data(), | ||
| 497 | - tile.size(), | ||
| 498 | - tile.alignment() | ||
| 499 | -); | ||
| 500 | -``` | ||
| 501 | 107 | ||
| 502 | -**生成目标代码**: | 108 | +### 6.2 NPU 路径 |
| 503 | -```bash | ||
| 504 | -# 编译为目标文件 | ||
| 505 | -g++ -std=c++20 -O3 -c src/my_operator.cpp -o build/my_operator.o | ||
| 506 | 109 | ||
| 507 | -# 查看生成的汇编代码 | 110 | +NPU 路径面向 Ascend 硬件或 simulator 侧执行。 |
| 508 | -g++ -std=c++20 -O3 -S src/my_operator.cpp -o build/my_operator.s | ||
| 509 | -``` | ||
| 510 | 111 | ||
| 511 | -### 3.3 链接阶段 | 112 | +在该路径下: |
| 512 | 113 | ||
| 513 | -**符号解析**: | 114 | +- 会使用面向 NPU 的 backend 实现 |
| 514 | -``` | 115 | +- 设备端约束会更直接地影响代码合法性 |
| 515 | -my_operator.o: | 116 | +- 指令是否可用需要结合 backend 支持表逐项确认 |
| 516 | - - 定义: main, my_kernel | ||
| 517 | - - 引用: TLOAD, TSTORE, TADD | ||
| 518 | 117 | ||
| 519 | -libpto.a: | 118 | +相关参考: |
| 520 | - - 定义: TLOAD, TSTORE, TADD, ... | ||
| 521 | 119 | ||
| 522 | -链接器解析: | 120 | +- [后端实现状态](../../include/README.md) |
| 523 | - my_operator.o::TLOAD → libpto.a::TLOAD ✓ | 121 | +- [PTO ISA 参考](../isa/README.md) |
| 524 | - my_operator.o::TSTORE → libpto.a::TSTORE ✓ | ||
| 525 | - my_operator.o::TADD → libpto.a::TADD ✓ | ||
| 526 | -``` | ||
| 527 | 122 | ||
| 528 | -**重定位**: | 123 | +## 7. 编译相关检查项 |
| 529 | -``` | ||
| 530 | -my_operator.o 中的调用: | ||
| 531 | - call TLOAD // 地址未知 | ||
| 532 | 124 | ||
| 533 | -链接后: | 125 | +当 PTO kernel 编译失败或行为不符合预期时,最可靠的检查路径是: |
| 534 | - call 0x12345678 // 解析为 libpto.a 中的实际地址 | ||
| 535 | -``` | ||
| 536 | 126 | ||
| 537 | -**生成可执行文件**: | 127 | +1. **头文件级 API 用法** |
| 538 | -```bash | 128 | + - intrinsic 的使用方式是否符合 `../../include/pto/common/pto_instr.hpp` 中的声明? |
| 539 | -# 链接 | ||
| 540 | -g++ build/my_operator.o \ | ||
| 541 | - -L/path/to/pto/lib \ | ||
| 542 | - -lpto \ | ||
| 543 | - -o build/my_operator | ||
| 544 | 129 | ||
| 545 | -# 查看依赖库 | 130 | +2. **ISA 约束** |
| 546 | -ldd build/my_operator | 131 | + - `docs/isa/` 中对应指令是否允许当前 tile 类型、布局和操作数组合? |
| 547 | -# 输出: | ||
| 548 | -# libpto.so => /path/to/pto/lib/libpto.so | ||
| 549 | -# libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 | ||
| 550 | -``` | ||
| 551 | 132 | ||
| 552 | ---- | 133 | +3. **Tile 与 GlobalTensor 定义** |
| 134 | + - tile shape、valid region、layout 是否合法? | ||
| 135 | + - `GlobalTensor` 的 shape / stride 声明是否正确? | ||
| 553 | 136 | ||
| 554 | -## 4. 编译选项说明 | 137 | +4. **backend 支持情况** |
| 138 | + - 目标指令在所选 backend 上是否已实现?可参考 [后端实现状态](../../include/README.md)。 | ||
| 555 | 139 | ||
| 556 | -### 4.1 优化级别 | 140 | +5. **构建环境** |
| 141 | + - 编译器、Python 环境、CANN 环境是否满足要求? | ||
| 557 | 142 | ||
| 558 | -**-O0(无优化)**: | 143 | +## 8. 关于构建示例的说明 |
| 559 | -- 用途:调试 | ||
| 560 | -- 特点: | ||
| 561 | - - 编译最快 | ||
| 562 | - - 代码与源码一一对应 | ||
| 563 | - - 便于调试 | ||
| 564 | -- 性能:最慢 | ||
| 565 | 144 | ||
| 566 | -**-O1(基本优化)**: | 145 | +一些在通用 AI 工具或网络示例中常见的片段,例如通用的 `find_package(PTO REQUIRED)`、假设存在的 `PTO::pto` 链接目标等,并**不能**直接视为本仓库已经正式定义的标准集成方式。 |
| 567 | -- 用途:快速编译 + 基本优化 | ||
| 568 | -- 特点: | ||
| 569 | - - 编译较快 | ||
| 570 | - - 基本优化(常量折叠、死代码消除) | ||
| 571 | -- 性能:中等 | ||
| 572 | 146 | ||
| 573 | -**-O2(标准优化)**: | 147 | +补充文档或扩展 PTO Tile Lib 时,应以仓库内构建脚本、顶层 `CMakeLists.txt` 以及现有测试和 demo 的构建方式为主要参考。 |
| 574 | -- 用途:生产环境(推荐) | ||
| 575 | -- 特点: | ||
| 576 | - - 编译时间适中 | ||
| 577 | - - 大部分优化(内联、循环优化) | ||
| 578 | - - 不影响调试 | ||
| 579 | -- 性能:快 | ||
| 580 | 148 | ||
| 581 | -**-O3(激进优化)**: | 149 | +## 9. 说明 |
| 582 | -- 用途:性能关键代码 | ||
| 583 | -- 特点: | ||
| 584 | - - 编译最慢 | ||
| 585 | - - 所有优化(向量化、循环展开) | ||
| 586 | - - 可能增加代码大小 | ||
| 587 | -- 性能:最快 | ||
| 588 | 150 | ||
| 589 | -**-Os(优化代码大小)**: | 151 | +PTO Tile Lib 的编译流程可概括为: |
| 590 | -- 用途:嵌入式系统 | ||
| 591 | -- 特点: | ||
| 592 | - - 最小化代码大小 | ||
| 593 | - - 牺牲部分性能 | ||
| 594 | -- 性能:中等 | ||
| 595 | 152 | ||
| 596 | -**-Ofast(超激进优化)**: | 153 | +- PTO 代码以 C++ 和公共 intrinsics 形式编写; |
| 597 | -- 用途:不严格遵守标准的代码 | 154 | +- 构建系统根据配置选择对应的 backend 实现; |
| 598 | -- 特点: | 155 | +- CPU 仿真是推荐的首选验证路径; |
| 599 | - - 包含 -O3 | 156 | +- backend 支持情况与指令合法性在开发过程中显式检查。 |
| 600 | - - 启用 -ffast-math(可能违反 IEEE 754) | ||
| 601 | -- 性能:最快(但可能不正确) | ||
| 602 | 157 | ||
| 603 | -**性能对比**: | 158 | +文档重点说明公共编程接口和使用模型;除非在专门的工具链文档中另行定义,编译器内部阶段仍属于实现细节。 |
| 604 | -```bash | ||
| 605 | -# 测试不同优化级别 | ||
| 606 | -for opt in O0 O1 O2 O3 Ofast; do | ||
| 607 | - g++ -$opt src/my_operator.cpp -o build/my_operator_$opt | ||
| 608 | - time ./build/my_operator_$opt | ||
| 609 | -done | ||
| 610 | - | ||
| 611 | -# 典型结果: | ||
| 612 | -# -O0: 1000 ms | ||
| 613 | -# -O1: 500 ms | ||
| 614 | -# -O2: 200 ms | ||
| 615 | -# -O3: 150 ms | ||
| 616 | -# -Ofast: 140 ms | ||
| 617 | -``` | ||
| 618 | - | ||
| 619 | -### 4.2 架构特定选项 | ||
| 620 | - | ||
| 621 | -**-march=native**: | ||
| 622 | -- 用途:针对当前 CPU 优化 | ||
| 623 | -- 特点: | ||
| 624 | - - 使用 CPU 特定指令(AVX2, AVX-512) | ||
| 625 | - - 性能提升 10-30% | ||
| 626 | - - 不可移植 | ||
| 627 | - | ||
| 628 | -**-march=x86-64**: | ||
| 629 | -- 用途:通用 x86-64 代码 | ||
| 630 | -- 特点: | ||
| 631 | - - 兼容所有 x86-64 CPU | ||
| 632 | - - 不使用高级指令 | ||
| 633 | - - 可移植 | ||
| 634 | - | ||
| 635 | -**示例**: | ||
| 636 | -```bash | ||
| 637 | -# 针对当前 CPU 优化 | ||
| 638 | -g++ -O3 -march=native src/my_operator.cpp | ||
| 639 | - | ||
| 640 | -# 通用构建 | ||
| 641 | -g++ -O3 -march=x86-64 src/my_operator.cpp | ||
| 642 | - | ||
| 643 | -# 针对特定 CPU | ||
| 644 | -g++ -O3 -march=skylake src/my_operator.cpp | ||
| 645 | -``` | ||
| 646 | - | ||
| 647 | -### 4.3 调试选项 | ||
| 648 | - | ||
| 649 | -**-g(包含调试符号)**: | ||
| 650 | -```bash | ||
| 651 | -# 基本调试信息 | ||
| 652 | -g++ -g src/my_operator.cpp | ||
| 653 | - | ||
| 654 | -# 详细调试信息(包含宏定义) | ||
| 655 | -g++ -g3 src/my_operator.cpp | ||
| 656 | - | ||
| 657 | -# 使用 gdb 调试 | ||
| 658 | -gdb ./my_operator | ||
| 659 | -``` | ||
| 660 | - | ||
| 661 | -**-fsanitize(运行时检查)**: | ||
| 662 | -```bash | ||
| 663 | -# 地址检查(检测内存错误) | ||
| 664 | -g++ -fsanitize=address src/my_operator.cpp | ||
| 665 | - | ||
| 666 | -# 未定义行为检查 | ||
| 667 | -g++ -fsanitize=undefined src/my_operator.cpp | ||
| 668 | - | ||
| 669 | -# 线程检查 | ||
| 670 | -g++ -fsanitize=thread src/my_operator.cpp | ||
| 671 | -``` | ||
| 672 | - | ||
| 673 | -### 4.4 警告选项 | ||
| 674 | - | ||
| 675 | -**推荐警告选项**: | ||
| 676 | -```bash | ||
| 677 | -g++ -Wall -Wextra -Wpedantic \ | ||
| 678 | - -Werror \ | ||
| 679 | - src/my_operator.cpp | ||
| 680 | - | ||
| 681 | -# -Wall: 常见警告 | ||
| 682 | -# -Wextra: 额外警告 | ||
| 683 | -# -Wpedantic: 严格标准警告 | ||
| 684 | -# -Werror: 警告视为错误 | ||
| 685 | -``` | ||
| 686 | - | ||
| 687 | ---- | ||
| 688 | - | ||
| 689 | -## 5. 交叉编译 | ||
| 690 | - | ||
| 691 | -### 5.1 x86 → ARM 交叉编译 | ||
| 692 | - | ||
| 693 | -**安装交叉编译工具链**: | ||
| 694 | -```bash | ||
| 695 | -# Ubuntu/Debian | ||
| 696 | -sudo apt install g++-aarch64-linux-gnu | ||
| 697 | - | ||
| 698 | -# 验证 | ||
| 699 | -aarch64-linux-gnu-g++ --version | ||
| 700 | -``` | ||
| 701 | - | ||
| 702 | -**CMake 配置**: | ||
| 703 | -```cmake | ||
| 704 | -# toolchain-aarch64.cmake | ||
| 705 | -set(CMAKE_SYSTEM_NAME Linux) | ||
| 706 | -set(CMAKE_SYSTEM_PROCESSOR aarch64) | ||
| 707 | - | ||
| 708 | -set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc) | ||
| 709 | -set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++) | ||
| 710 | - | ||
| 711 | -set(CMAKE_FIND_ROOT_PATH /usr/aarch64-linux-gnu) | ||
| 712 | -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) | ||
| 713 | -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) | ||
| 714 | -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) | ||
| 715 | -``` | ||
| 716 | - | ||
| 717 | -**构建**: | ||
| 718 | -```bash | ||
| 719 | -cmake -B build \ | ||
| 720 | - -DCMAKE_TOOLCHAIN_FILE=toolchain-aarch64.cmake \ | ||
| 721 | - -DPTO_BACKEND=NPU | ||
| 722 | - | ||
| 723 | -cmake --build build | ||
| 724 | -``` | ||
| 725 | - | ||
| 726 | -### 5.2 开发机 → NPU 交叉编译 | ||
| 727 | - | ||
| 728 | -**配置**: | ||
| 729 | -```bash | ||
| 730 | -# 设置 NPU 工具链路径 | ||
| 731 | -export NPU_TOOLCHAIN=/usr/local/Ascend/toolkit | ||
| 732 | - | ||
| 733 | -# 配置 CMake | ||
| 734 | -cmake -B build \ | ||
| 735 | - -DPTO_BACKEND=NPU \ | ||
| 736 | - -DSOC_VERSION=Ascend910B1 \ | ||
| 737 | - -DCMAKE_TOOLCHAIN_FILE=${NPU_TOOLCHAIN}/cmake/toolchain.cmake | ||
| 738 | - | ||
| 739 | -# 编译 | ||
| 740 | -cmake --build build | ||
| 741 | -``` | ||
| 742 | - | ||
| 743 | ---- | ||
| 744 | - | ||
| 745 | -## 6. 编译优化 | ||
| 746 | - | ||
| 747 | -### 6.1 加速编译 | ||
| 748 | - | ||
| 749 | -**使用 Ninja**: | ||
| 750 | -```bash | ||
| 751 | -# 比 Make 快 2-3× | ||
| 752 | -cmake -B build -G Ninja | ||
| 753 | -ninja -C build | ||
| 754 | -``` | ||
| 755 | - | ||
| 756 | -**使用 ccache**: | ||
| 757 | -```bash | ||
| 758 | -# 缓存编译结果 | ||
| 759 | -export CC="ccache gcc" | ||
| 760 | -export CXX="ccache g++" | ||
| 761 | - | ||
| 762 | -cmake -B build | ||
| 763 | -cmake --build build | ||
| 764 | - | ||
| 765 | -# 查看缓存统计 | ||
| 766 | -ccache -s | ||
| 767 | -``` | ||
| 768 | - | ||
| 769 | -**并行编译**: | ||
| 770 | -```bash | ||
| 771 | -# 使用所有核心 | ||
| 772 | -cmake --build build -j$(nproc) | ||
| 773 | - | ||
| 774 | -# 限制并行数(避免内存不足) | ||
| 775 | -cmake --build build -j4 | ||
| 776 | -``` | ||
| 777 | - | ||
| 778 | -**预编译头文件**: | ||
| 779 | -```cmake | ||
| 780 | -# CMakeLists.txt | ||
| 781 | -target_precompile_headers(my_operator | ||
| 782 | - PRIVATE | ||
| 783 | - <pto/pto-inst.hpp> | ||
| 784 | - <vector> | ||
| 785 | - <string> | ||
| 786 | -) | ||
| 787 | -``` | ||
| 788 | - | ||
| 789 | -### 6.2 减小二进制大小 | ||
| 790 | - | ||
| 791 | -**Strip 调试符号**: | ||
| 792 | -```bash | ||
| 793 | -# 编译时不包含调试符号 | ||
| 794 | -g++ -O3 -DNDEBUG src/my_operator.cpp | ||
| 795 | - | ||
| 796 | -# 或编译后 strip | ||
| 797 | -strip build/my_operator | ||
| 798 | - | ||
| 799 | -# 大小对比: | ||
| 800 | -# 带调试符号: 5.2 MB | ||
| 801 | -# strip 后: 1.1 MB | ||
| 802 | -``` | ||
| 803 | - | ||
| 804 | -**链接时优化(LTO)**: | ||
| 805 | -```cmake | ||
| 806 | -# CMakeLists.txt | ||
| 807 | -set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) | ||
| 808 | - | ||
| 809 | -# 或手动指定 | ||
| 810 | -target_compile_options(my_operator PRIVATE -flto) | ||
| 811 | -target_link_options(my_operator PRIVATE -flto) | ||
| 812 | -``` | ||
| 813 | - | ||
| 814 | ---- | ||
| 815 | - | ||
| 816 | -## 7. 常见问题排查 | ||
| 817 | - | ||
| 818 | -### 7.1 编译错误 | ||
| 819 | - | ||
| 820 | -**问题1:找不到头文件** | ||
| 821 | -``` | ||
| 822 | -error: pto/pto-inst.hpp: No such file or directory | ||
| 823 | -``` | ||
| 824 | - | ||
| 825 | -**原因**:PTO 库路径未设置 | ||
| 826 | - | ||
| 827 | -**解决方案**: | ||
| 828 | -```bash | ||
| 829 | -# 方法1:设置环境变量 | ||
| 830 | -export PTO_LIB_PATH=/path/to/pto-isa | ||
| 831 | - | ||
| 832 | -# 方法2:CMake 指定 | ||
| 833 | -cmake -B build -DPTO_ROOT=/path/to/pto-isa | ||
| 834 | - | ||
| 835 | -# 方法3:手动指定包含路径 | ||
| 836 | -g++ -I/path/to/pto-isa/include src/my_operator.cpp | ||
| 837 | -``` | ||
| 838 | - | ||
| 839 | -**问题2:静态断言失败** | ||
| 840 | -``` | ||
| 841 | -static_assert failed: "Tile shape not aligned" | ||
| 842 | -``` | ||
| 843 | - | ||
| 844 | -**原因**:Tile 尺寸不满足对齐要求 | ||
| 845 | - | ||
| 846 | -**解决方案**: | ||
| 847 | -```cpp | ||
| 848 | -// 错误:宽度 250 不是 16 的倍数 | ||
| 849 | -using TileT = Tile<TileType::Vec, float, 16, 250>; | ||
| 850 | - | ||
| 851 | -// 正确:宽度 256 是 16 的倍数 | ||
| 852 | -using TileT = Tile<TileType::Vec, float, 16, 256>; | ||
| 853 | -``` | ||
| 854 | - | ||
| 855 | -**问题3:链接错误** | ||
| 856 | -``` | ||
| 857 | -undefined reference to `pto::TLOAD(...)` | ||
| 858 | -``` | ||
| 859 | - | ||
| 860 | -**原因**:未链接 PTO 库 | ||
| 861 | - | ||
| 862 | -**解决方案**: | ||
| 863 | -```cmake | ||
| 864 | -# CMakeLists.txt | ||
| 865 | -target_link_libraries(my_operator PRIVATE PTO::pto) | ||
| 866 | - | ||
| 867 | -# 或手动链接 | ||
| 868 | -g++ build/my_operator.o -L/path/to/pto/lib -lpto -o build/my_operator | ||
| 869 | -``` | ||
| 870 | - | ||
| 871 | -### 7.2 性能问题 | ||
| 872 | - | ||
| 873 | -**问题:Release 构建性能差** | ||
| 874 | - | ||
| 875 | -**诊断**: | ||
| 876 | -```bash | ||
| 877 | -# 检查优化级别 | ||
| 878 | -cmake --build build --verbose | grep "\-O" | ||
| 879 | - | ||
| 880 | -# 应该看到 -O3 或 -O2 | ||
| 881 | -``` | ||
| 882 | - | ||
| 883 | -**解决方案**: | ||
| 884 | -```cmake | ||
| 885 | -# 显式设置优化选项 | ||
| 886 | -set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -march=native") | ||
| 887 | - | ||
| 888 | -# 或使用 LTO | ||
| 889 | -set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE) | ||
| 890 | -``` | ||
| 891 | - | ||
| 892 | -### 7.3 运行时错误 | ||
| 893 | - | ||
| 894 | -**问题:找不到共享库** | ||
| 895 | -``` | ||
| 896 | -error while loading shared libraries: libpto.so: cannot open shared object file | ||
| 897 | -``` | ||
| 898 | - | ||
| 899 | -**解决方案**: | ||
| 900 | -```bash | ||
| 901 | -# 方法1:设置 LD_LIBRARY_PATH | ||
| 902 | -export LD_LIBRARY_PATH=/path/to/pto/lib:$LD_LIBRARY_PATH | ||
| 903 | - | ||
| 904 | -# 方法2:添加到系统路径 | ||
| 905 | -sudo echo "/path/to/pto/lib" > /etc/ld.so.conf.d/pto.conf | ||
| 906 | -sudo ldconfig | ||
| 907 | - | ||
| 908 | -# 方法3:使用 RPATH | ||
| 909 | -cmake -B build -DCMAKE_INSTALL_RPATH=/path/to/pto/lib | ||
| 910 | -``` | ||
| 911 | - | ||
| 912 | ---- | ||
| 913 | - | ||
| 914 | -## 8. 高级主题 | ||
| 915 | - | ||
| 916 | -### 8.1 自定义编译 Pass | ||
| 917 | - | ||
| 918 | -**示例:添加自定义优化** | ||
| 919 | -```cmake | ||
| 920 | -# CMakeLists.txt | ||
| 921 | -target_compile_options(my_operator | ||
| 922 | - PRIVATE | ||
| 923 | - -fplugin=/path/to/my_plugin.so | ||
| 924 | - -fplugin-arg-my_plugin-option=value | ||
| 925 | -) | ||
| 926 | -``` | ||
| 927 | - | ||
| 928 | -### 8.2 编译时间分析 | ||
| 929 | - | ||
| 930 | -**GCC 时间报告**: | ||
| 931 | -```bash | ||
| 932 | -g++ -ftime-report src/my_operator.cpp 2>&1 | grep "TOTAL" | ||
| 933 | -``` | ||
| 934 | - | ||
| 935 | -**Clang 时间追踪**: | ||
| 936 | -```bash | ||
| 937 | -clang++ -ftime-trace src/my_operator.cpp | ||
| 938 | -# 生成 my_operator.json | ||
| 939 | -# 使用 chrome://tracing 查看 | ||
| 940 | -``` | ||
| 941 | - | ||
| 942 | -### 8.3 生成编译数据库 | ||
| 943 | - | ||
| 944 | -**用于 IDE 和工具**: | ||
| 945 | -```bash | ||
| 946 | -cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON | ||
| 947 | - | ||
| 948 | -# 生成 build/compile_commands.json | ||
| 949 | -# 用于 clangd, clang-tidy 等工具 | ||
| 950 | -``` | ||
| 951 | - | ||
| 952 | ---- | ||
| 953 | - | ||
| 954 | -## 参考资源 | ||
| 955 | - | ||
| 956 | -- [快速入门](../getting-started_zh.md) | ||
| 957 | -- [算子调试指南](debug_zh.md) | ||
| 958 | -- [性能优化指南](opt_zh.md) | ||
| 959 | -- [CMake 官方文档](https://cmake.org/documentation/) | ||
| 960 | -- [GCC 优化选项](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html) | ||
| @@ -0,0 +1,61 @@ | |||
| 1 | +# CPU_SIM | ||
| 2 | + | ||
| 3 | +CPU_SIM 是一个面向纯 CPU 系统执行的后端实现。 | ||
| 4 | + | ||
| 5 | +与 NPU 后端相比,CPU_SIM 当前存在以下差异和限制: | ||
| 6 | + | ||
| 7 | +- 所有操作都以同步方式执行(同步相关操作通常为空实现)。 | ||
| 8 | +- 使用特定的内存模型来模拟 NPU 内存层次(见下文)。 | ||
| 9 | +- 多线程支持尚不完整(`Tile` 对象的内存访问不具备线程间同步能力,因此不建议跨线程共享 Tile)。 | ||
| 10 | + | ||
| 11 | +## 启用 CPU_SIM | ||
| 12 | + | ||
| 13 | +可通过设置编译宏 `__CPU_SIM` 启用 CPU 后端(CPU_SIM)。启用后,可使用标准面向 CPU 的编译器(如 gcc 或 clang)构建程序。 | ||
| 14 | + | ||
| 15 | +为兼容原本面向 NPU 的程序,仓库在 `include/pto/common/cpu_stub.hpp` 中为 CPU 平台提供了一些 Ascend 相关函数的替代实现。对于已经使用 NPU 后端的已有程序,包含该头文件后通常只需做少量修改即可在 CPU 上编译。 | ||
| 16 | + | ||
| 17 | +如果不包含该头文件,则需要自行移除或替换诸如 `aclInit`、`aclrtSetDevice` 等函数调用。 | ||
| 18 | + | ||
| 19 | +## CPU_SIM 内存模型 | ||
| 20 | + | ||
| 21 | +通常情况下,CPU_SIM 中所有 Tile 的内存都分配在系统内存中。这与 NPU 后端不同:在 NPU 后端中,内存会划分为 host memory、device memory,以及设备内部不同的片上存储位置。 | ||
| 22 | + | ||
| 23 | +为了让 CPU_SIM 的行为更接近 NPU,CPU_SIM 会模拟若干与 NPU 架构对应的独立内存位置。 | ||
| 24 | + | ||
| 25 | +CPU_SIM 会为每个线程分配以下内存区域: | ||
| 26 | + | ||
| 27 | +- `UB` | ||
| 28 | +- `L1` | ||
| 29 | +- `L0A` | ||
| 30 | +- `L0B` | ||
| 31 | +- `L0C` | ||
| 32 | + | ||
| 33 | +这些区域本质上是按目标 NPU 架构容量预分配的数组。`TASSIGN` 会从这些数组中为 Tile 绑定某一段内存。例如: | ||
| 34 | + | ||
| 35 | +- 若对 `Loc == Mat` 的 Tile 调用 `TASSIGN(tile, 10)`,则该 Tile 会绑定到 `L1[10]` 开始的位置。 | ||
| 36 | + | ||
| 37 | +当前支持的架构包括 A2A3 和 A5。可通过 `pto::NPUMemoryModel::Initialize` 为每个线程指定要模拟的架构;该函数应在每个线程中调用一次。 | ||
| 38 | + | ||
| 39 | +- 若不显式调用,则默认使用 A2A3 架构。 | ||
| 40 | + | ||
| 41 | +更多信息请参考 `include/pto/cpu/NPUMemoryModel.hpp`。 | ||
| 42 | + | ||
| 43 | +## 自动内存分配 | ||
| 44 | + | ||
| 45 | +CPU_SIM 也支持自动内存分配。 | ||
| 46 | + | ||
| 47 | +启用方式是定义编译宏 `__PTO_AUTO__`。启用后,会使用惰性分配机制:当首次尝试获取 Tile 的内部内存指针时,如果此前未通过 `TASSIGN` 绑定内存,则自动为其分配内存。 | ||
| 48 | + | ||
| 49 | +需要注意的是,在自动分配模式下,内存来自 PC 的系统内存,而不是 `L1`、`L0A` 等预分配缓冲区。因此它不会与这些片上模拟缓冲区重叠;只有 `TASSIGN` 才会使用这些模拟缓冲区。 | ||
| 50 | + | ||
| 51 | +## 使用建议 | ||
| 52 | + | ||
| 53 | +在 CPU_SIM 下,建议采用以下两种策略之一: | ||
| 54 | + | ||
| 55 | +- **直接内存绑定**:为每个 Tile 显式调用 `TASSIGN` 绑定内存,并手动计算合适的偏移。 | ||
| 56 | +- **自动分配**:启用 `__PTO_AUTO__`,由系统自动为 Tile 分配内存;如有需要,仍可混合使用 `TASSIGN`。 | ||
| 57 | + | ||
| 58 | +**注意:** | ||
| 59 | + | ||
| 60 | +必须采用上述两种方式之一。如果既不显式绑定,也不启用自动分配,程序可能会因空指针访问而触发段错误。 | ||
| 61 | + | ||
| @@ -1,487 +1,475 @@ | |||
| 1 | -# Error Codes Reference | 1 | +# Error Codes Reference |
| 2 | - | 2 | + |
| 3 | -This document lists common error codes, error messages, and solutions encountered in PTO development. | 3 | +This document summarizes common PTO development failures and practical troubleshooting guidance. The examples are illustrative only: actual diagnostics depend on the compiler toolchain, runtime, and host environment. |
| 4 | - | 4 | + |
| 5 | -## Contents | 5 | +--- |
| 6 | - | 6 | + |
| 7 | -- [1. Compilation Errors (E001-E099)](#1-compilation-errors-e001-e099) | 7 | +## 1. Compilation Errors (E001-E099) |
| 8 | -- [2. Linking Errors (L001-L099)](#2-linking-errors-l001-l099) | 8 | + |
| 9 | -- [3. Runtime Errors (R001-R099)](#3-runtime-errors-r001-r099) | 9 | +### E001: Header File Not Found |
| 10 | -- [4. Memory Errors (M001-M099)](#4-memory-errors-m001-m099) | 10 | + |
| 11 | -- [5. Numerical Errors (N001-N099)](#5-numerical-errors-n001-n099) | 11 | +**Error Message**: |
| 12 | -- [6. Performance Issues (P001-P099)](#6-performance-issues-p001-p099) | 12 | +``` |
| 13 | -- [7. Framework Integration Errors (F001-F099)](#7-framework-integration-errors-f001-f099) | 13 | +error: pto/pto-inst.hpp: No such file or directory |
| 14 | - | 14 | +``` |
| 15 | ---- | 15 | + |
| 16 | - | 16 | +**Cause**: PTO library path not set |
| 17 | -## 1. Compilation Errors (E001-E099) | 17 | + |
| 18 | - | 18 | +**Solution**: |
| 19 | -### E001: Header File Not Found | 19 | +```bash |
| 20 | - | 20 | +# Method 1: Set environment variable |
| 21 | -**Error Message**: | 21 | +export PTO_LIB_PATH=/path/to/pto-isa |
| 22 | -``` | 22 | + |
| 23 | -error: pto/pto-inst.hpp: No such file or directory | 23 | +# Method 2: CMake specify |
| 24 | -``` | 24 | +cmake -B build -DPTO_ROOT=/path/to/pto-isa |
| 25 | - | 25 | + |
| 26 | -**Cause**: PTO library path not set | 26 | +# Method 3: Manual include path |
| 27 | - | 27 | +g++ -I/path/to/pto-isa/include src/my_operator.cpp |
| 28 | -**Solution**: | 28 | +``` |
| 29 | -```bash | 29 | + |
| 30 | -# Method 1: Set environment variable | 30 | +### E002: Static Assertion Failed - Tile Alignment |
| 31 | -export PTO_LIB_PATH=/path/to/pto-isa | 31 | + |
| 32 | - | 32 | +**Error Message**: |
| 33 | -# Method 2: CMake specify | 33 | +``` |
| 34 | -cmake -B build -DPTO_ROOT=/path/to/pto-isa | 34 | +static_assert failed: "Tile shape not aligned" |
| 35 | - | 35 | +static_assert failed: "Tile width must be multiple of 16" |
| 36 | -# Method 3: Manual include path | 36 | +``` |
| 37 | -g++ -I/path/to/pto-isa/include src/my_operator.cpp | 37 | + |
| 38 | -``` | 38 | +**Cause**: Tile dimensions don't meet alignment requirements |
| 39 | - | 39 | + |
| 40 | -### E002: Static Assertion Failed - Tile Alignment | 40 | +**Solution**: |
| 41 | - | 41 | +```cpp |
| 42 | -**Error Message**: | 42 | +// ❌ Wrong: width 250 is not multiple of 16 |
| 43 | -``` | 43 | +using TileT = Tile<TileType::Vec, float, 16, 250>; |
| 44 | -static_assert failed: "Tile shape not aligned" | 44 | + |
| 45 | -static_assert failed: "Tile width must be multiple of 16" | 45 | +// ✅ Correct: width 256 is multiple of 16 |
| 46 | -``` | 46 | +using TileT = Tile<TileType::Vec, float, 16, 256>; |
| 47 | - | 47 | + |
| 48 | -**Cause**: Tile dimensions don't meet alignment requirements | 48 | +// Alignment requirements: |
| 49 | - | 49 | +// - Vec Tile: width % 16 == 0 |
| 50 | -**Solution**: | 50 | +// - Cube Tile: height % 16 == 0 && width % 16 == 0 |
| 51 | -```cpp | 51 | +// - Acc Tile: height % 16 == 0 && width % 16 == 0 |
| 52 | -// ❌ Wrong: width 250 is not multiple of 16 | 52 | +``` |
| 53 | -using TileT = Tile<TileType::Vec, float, 16, 250>; | 53 | + |
| 54 | - | 54 | +### E003: Type Mismatch |
| 55 | -// ✅ Correct: width 256 is multiple of 16 | 55 | + |
| 56 | -using TileT = Tile<TileType::Vec, float, 16, 256>; | 56 | +**Error Message**: |
| 57 | - | 57 | +``` |
| 58 | -// Alignment requirements: | 58 | +error: no matching function for call to 'TADD(Tile<float>&, Tile<half>&)' |
| 59 | -// - Vec Tile: width % 16 == 0 | 59 | +``` |
| 60 | -// - Cube Tile: height % 16 == 0 && width % 16 == 0 | 60 | + |
| 61 | -// - Acc Tile: height % 16 == 0 && width % 16 == 0 | 61 | +**Cause**: Tile element types or shapes are inconsistent. |
| 62 | -``` | 62 | + |
| 63 | - | 63 | +**Solution**: |
| 64 | -### E003: Type Mismatch | 64 | +```cpp |
| 65 | - | 65 | +// ❌ Wrong: type mismatch |
| 66 | -**Error Message**: | 66 | +Tile<TileType::Vec, float, 16, 256> tile_a; |
| 67 | -``` | 67 | +Tile<TileType::Vec, half, 16, 256> tile_b; |
| 68 | -error: no matching function for call to 'TADD(Tile<float>&, Tile<half>&)' | 68 | +TADD(tile_a, tile_a, tile_b); // Error! |
| 69 | -``` | 69 | + |
| 70 | - | 70 | +// ✅ Correct: consistent types |
| 71 | -**Cause**: Tile types are inconsistent | 71 | +Tile<TileType::Vec, float, 16, 256> tile_a, tile_b, tile_c; |
| 72 | - | 72 | +TADD(tile_c, tile_a, tile_b); // Correct |
| 73 | -**Solution**: | 73 | +``` |
| 74 | -```cpp | 74 | + |
| 75 | -// ❌ Wrong: type mismatch | 75 | +Use the conversion instruction actually provided by PTO when an explicit type conversion is required; the exact API depends on the available instruction set and target branch. |
| 76 | -Tile<TileType::Vec, float, 16, 256> tile_a; | 76 | + |
| 77 | -Tile<TileType::Vec, half, 16, 256> tile_b; | 77 | +### E004: C++ Standard Not Supported |
| 78 | -TADD(tile_a, tile_a, tile_b); // Error! | 78 | + |
| 79 | - | 79 | +**Error Message**: |
| 80 | -// ✅ Correct: consistent types | 80 | +``` |
| 81 | -Tile<TileType::Vec, float, 16, 256> tile_a, tile_b, tile_c; | 81 | +error: 'concept' does not name a type |
| 82 | -TADD(tile_c, tile_a, tile_b); // Correct | 82 | +error: expected ';' before 'requires' |
| 83 | - | 83 | +``` |
| 84 | -// Or use type conversion | 84 | + |
| 85 | -TCAST(tile_b_float, tile_b); // half → float | 85 | +**Cause**: Compiler doesn't support C++20 |
| 86 | -TADD(tile_c, tile_a, tile_b_float); | 86 | + |
| 87 | -``` | 87 | +**Solution**: |
| 88 | - | 88 | +```bash |
| 89 | -### E004: C++ Standard Not Supported | 89 | +# Check compiler version |
| 90 | - | 90 | +g++ --version # Need >= 13.0 |
| 91 | -**Error Message**: | 91 | +clang++ --version # Need >= 15.0 |
| 92 | -``` | 92 | + |
| 93 | -error: 'concept' does not name a type | 93 | +# Explicitly specify C++20 |
| 94 | -error: expected ';' before 'requires' | 94 | +g++ -std=c++20 src/my_operator.cpp |
| 95 | -``` | 95 | + |
| 96 | - | 96 | +# CMake setting |
| 97 | -**Cause**: Compiler doesn't support C++20 | 97 | +set(CMAKE_CXX_STANDARD 20) |
| 98 | - | 98 | +set(CMAKE_CXX_STANDARD_REQUIRED ON) |
| 99 | -**Solution**: | 99 | +``` |
| 100 | -```bash | 100 | + |
| 101 | -# Check compiler version | 101 | +--- |
| 102 | -g++ --version # Need >= 13.0 | 102 | + |
| 103 | -clang++ --version # Need >= 15.0 | 103 | +## 2. Linking Errors (L001-L099) |
| 104 | - | 104 | + |
| 105 | -# Explicitly specify C++20 | 105 | +### L001: Undefined Reference |
| 106 | -g++ -std=c++20 src/my_operator.cpp | 106 | + |
| 107 | - | 107 | +**Error Message**: |
| 108 | -# CMake setting | 108 | +``` |
| 109 | -set(CMAKE_CXX_STANDARD 20) | 109 | +undefined reference to `pto::TLOAD(...)` |
| 110 | -set(CMAKE_CXX_STANDARD_REQUIRED ON) | 110 | +undefined reference to `pto::TSTORE(...)` |
| 111 | -``` | 111 | +``` |
| 112 | - | 112 | + |
| 113 | ---- | 113 | +**Cause**: PTO library not linked |
| 114 | - | 114 | + |
| 115 | -## 2. Linking Errors (L001-L099) | 115 | +**Solution**: |
| 116 | - | 116 | +```bash |
| 117 | -### L001: Undefined Reference | 117 | +# Manual linking |
| 118 | - | 118 | +g++ build/my_operator.o -L/path/to/pto/lib -lpto -o build/my_operator |
| 119 | -**Error Message**: | 119 | + |
| 120 | -``` | 120 | +# CMake configuration |
| 121 | -undefined reference to `pto::TLOAD(...)` | 121 | +target_link_libraries(my_operator PRIVATE PTO::pto) |
| 122 | -undefined reference to `pto::TSTORE(...)` | 122 | +``` |
| 123 | -``` | 123 | + |
| 124 | - | 124 | +### L002: Shared Library Not Found |
| 125 | -**Cause**: PTO library not linked | 125 | + |
| 126 | - | 126 | +**Error Message**: |
| 127 | -**Solution**: | 127 | +``` |
| 128 | -```bash | 128 | +error while loading shared libraries: libpto.so: cannot open shared object file |
| 129 | -# Manual linking | 129 | +``` |
| 130 | -g++ build/my_operator.o -L/path/to/pto/lib -lpto -o build/my_operator | 130 | + |
| 131 | - | 131 | +**Cause**: Runtime cannot find shared library |
| 132 | -# CMake configuration | 132 | + |
| 133 | -target_link_libraries(my_operator PRIVATE PTO::pto) | 133 | +**Solution**: |
| 134 | -``` | 134 | +```bash |
| 135 | - | 135 | +# Method 1: Set LD_LIBRARY_PATH |
| 136 | -### L002: Shared Library Not Found | 136 | +export LD_LIBRARY_PATH=/path/to/pto/lib:$LD_LIBRARY_PATH |
| 137 | - | 137 | + |
| 138 | -**Error Message**: | 138 | +# Method 2: Add to system path |
| 139 | -``` | 139 | +sudo echo "/path/to/pto/lib" > /etc/ld.so.conf.d/pto.conf |
| 140 | -error while loading shared libraries: libpto.so: cannot open shared object file | 140 | +sudo ldconfig |
| 141 | -``` | 141 | + |
| 142 | - | 142 | +# Method 3: Use RPATH |
| 143 | -**Cause**: Runtime cannot find shared library | 143 | +cmake -B build -DCMAKE_INSTALL_RPATH=/path/to/pto/lib |
| 144 | - | 144 | + |
| 145 | -**Solution**: | 145 | +# Verify |
| 146 | -```bash | 146 | +ldd ./my_operator |
| 147 | -# Method 1: Set LD_LIBRARY_PATH | 147 | +``` |
| 148 | -export LD_LIBRARY_PATH=/path/to/pto/lib:$LD_LIBRARY_PATH | 148 | + |
| 149 | - | 149 | +--- |
| 150 | -# Method 2: Add to system path | 150 | + |
| 151 | -sudo echo "/path/to/pto/lib" > /etc/ld.so.conf.d/pto.conf | 151 | +## 3. Runtime Errors (R001-R099) |
| 152 | -sudo ldconfig | 152 | + |
| 153 | - | 153 | +### R001: Kernel Launch Failed |
| 154 | -# Method 3: Use RPATH | 154 | + |
| 155 | -cmake -B build -DCMAKE_INSTALL_RPATH=/path/to/pto/lib | 155 | +**Error Message**: |
| 156 | - | 156 | +``` |
| 157 | -# Verify | 157 | +PTO_ERROR: Failed to launch kernel |
| 158 | -ldd ./my_operator | 158 | +Error code: -1 |
| 159 | -``` | 159 | +``` |
| 160 | - | 160 | + |
| 161 | ---- | 161 | +**Cause**: Kernel parameters incorrect or insufficient resources |
| 162 | - | 162 | + |
| 163 | -## 3. Runtime Errors (R001-R099) | 163 | +**Solution**: |
| 164 | - | 164 | +```cpp |
| 165 | -### R001: Kernel Launch Failed | 165 | +// Check block_num |
| 166 | - | 166 | +int block_num = get_available_cores(); // Don't exceed available cores |
| 167 | -**Error Message**: | 167 | +EXEC_KERNEL_CMD(MyKernel, block_num, ...); |
| 168 | -``` | 168 | + |
| 169 | -PTO_ERROR: Failed to launch kernel | 169 | +// Check parameter types |
| 170 | -Error code: -1 | 170 | +// ❌ Wrong: passed wrong pointer type |
| 171 | -``` | 171 | +EXEC_KERNEL_CMD(MyKernel, 24, int_ptr, ...); // Expected float* |
| 172 | - | 172 | + |
| 173 | -**Cause**: Kernel parameters incorrect or insufficient resources | 173 | +// ✅ Correct |
| 174 | - | 174 | +EXEC_KERNEL_CMD(MyKernel, 24, float_ptr, ...); |
| 175 | -**Solution**: | 175 | +``` |
| 176 | -```cpp | 176 | + |
| 177 | -// Check block_num | 177 | +### R002: Assertion Failed |
| 178 | -int block_num = get_available_cores(); // Don't exceed available cores | 178 | + |
| 179 | -EXEC_KERNEL_CMD(MyKernel, block_num, ...); | 179 | +**Error Message**: |
| 180 | - | 180 | +``` |
| 181 | -// Check parameter types | 181 | +PTO_ASSERT failed: condition 'size <= MAX_SIZE' |
| 182 | -// ❌ Wrong: passed wrong pointer type | 182 | +File: my_operator.cpp, Line: 42 |
| 183 | -EXEC_KERNEL_CMD(MyKernel, 24, int_ptr, ...); // Expected float* | 183 | +``` |
| 184 | - | 184 | + |
| 185 | -// ✅ Correct | 185 | +**Cause**: Runtime condition check failed |
| 186 | -EXEC_KERNEL_CMD(MyKernel, 24, float_ptr, ...); | 186 | + |
| 187 | -``` | 187 | +**Solution**: |
| 188 | - | 188 | +```cpp |
| 189 | -### R002: Assertion Failed | 189 | +// Add input validation |
| 190 | - | 190 | +void my_kernel(..., uint32_t size) { |
| 191 | -**Error Message**: | 191 | + // Check size limit |
| 192 | -``` | 192 | + if (size > MAX_SIZE) { |
| 193 | -PTO_ASSERT failed: condition 'size <= MAX_SIZE' | 193 | + printf("Error: size %u exceeds MAX_SIZE %u\n", size, MAX_SIZE); |
| 194 | -File: my_operator.cpp, Line: 42 | 194 | + return; |
| 195 | -``` | 195 | + } |
| 196 | - | 196 | + |
| 197 | -**Cause**: Runtime condition check failed | 197 | + // Continue execution |
| 198 | - | 198 | + // ... |
| 199 | -**Solution**: | 199 | +} |
| 200 | -```cpp | 200 | +``` |
| 201 | -// Add input validation | 201 | + |
| 202 | -void my_kernel(..., uint32_t size) { | 202 | +### R003: Null Pointer Dereference |
| 203 | - // Check size limit | 203 | + |
| 204 | - if (size > MAX_SIZE) { | 204 | +**Error Message**: |
| 205 | - printf("Error: size %u exceeds MAX_SIZE %u\n", size, MAX_SIZE); | 205 | +``` |
| 206 | - return; | 206 | +Segmentation fault (core dumped) |
| 207 | - } | 207 | +``` |
| 208 | - | 208 | + |
| 209 | - // Continue execution | 209 | +**Cause**: Accessed null pointer or invalid memory |
| 210 | - // ... | 210 | + |
| 211 | -} | 211 | +**Solution**: |
| 212 | -``` | 212 | +```cpp |
| 213 | - | 213 | +// Add null pointer checks |
| 214 | -### R003: Null Pointer Dereference | 214 | +void my_kernel(__gm__ float* out, __gm__ const float* in) { |
| 215 | - | 215 | + if (out == nullptr || in == nullptr) { |
| 216 | -**Error Message**: | 216 | + printf("Error: null pointer\n"); |
| 217 | -``` | 217 | + return; |
| 218 | -Segmentation fault (core dumped) | 218 | + } |
| 219 | -``` | 219 | + |
| 220 | - | 220 | + // Continue execution |
| 221 | -**Cause**: Accessed null pointer or invalid memory | 221 | + // ... |
| 222 | - | 222 | +} |
| 223 | -**Solution**: | 223 | + |
| 224 | -```cpp | 224 | +// Use AddressSanitizer for detection |
| 225 | -// Add null pointer checks | 225 | +g++ -fsanitize=address src/my_operator.cpp |
| 226 | -void my_kernel(__gm__ float* out, __gm__ const float* in) { | 226 | +``` |
| 227 | - if (out == nullptr || in == nullptr) { | 227 | + |
| 228 | - printf("Error: null pointer\n"); | 228 | +--- |
| 229 | - return; | 229 | + |
| 230 | - } | 230 | +## 4. Memory Errors (M001-M099) |
| 231 | - | 231 | + |
| 232 | - // Continue execution | 232 | +### M001: L1 Memory Overflow |
| 233 | - // ... | 233 | + |
| 234 | -} | 234 | +**Error Message**: |
| 235 | - | 235 | +``` |
| 236 | -// Use AddressSanitizer for detection | 236 | +PTO_ASSERT: L1 memory overflow |
| 237 | -g++ -fsanitize=address src/my_operator.cpp | 237 | +Required: 600 KB, Available: 512 KB |
| 238 | -``` | 238 | +``` |
| 239 | - | 239 | + |
| 240 | ---- | 240 | +**Cause**: Tile memory usage exceeds L1 capacity |
| 241 | - | 241 | + |
| 242 | -## 4. Memory Errors (M001-M099) | 242 | +**Solution**: |
| 243 | - | 243 | +```cpp |
| 244 | -### M001: L1 Memory Overflow | 244 | +// Method 1: Reduce Tile size |
| 245 | - | 245 | +// ❌ Wrong: 16 × 512 × 4 bytes = 32 KB, multiple Tiles exceed L1 |
| 246 | -**Error Message**: | 246 | +using TileT = Tile<TileType::Vec, float, 16, 512>; |
| 247 | -``` | 247 | + |
| 248 | -PTO_ASSERT: L1 memory overflow | 248 | +// ✅ Correct: Reduce to 256 |
| 249 | -Required: 600 KB, Available: 512 KB | 249 | +using TileT = Tile<TileType::Vec, float, 16, 256>; |
| 250 | -``` | 250 | + |
| 251 | - | 251 | +// Method 2: Use double buffering |
| 252 | -**Cause**: Tile memory usage exceeds L1 capacity | 252 | +Event e1, e2; |
| 253 | - | 253 | +TileT tile_a, tile_b; |
| 254 | -**Solution**: | 254 | + |
| 255 | -```cpp | 255 | +TLOAD(tile_a, input[0:size], e1); |
| 256 | -// Method 1: Reduce Tile size | 256 | +for (int i = 1; i < N; i++) { |
| 257 | -// ❌ Wrong: 16 × 512 × 4 bytes = 32 KB, multiple Tiles exceed L1 | 257 | + TLOAD(tile_b, input[i*size:size], e2); |
| 258 | -using TileT = Tile<TileType::Vec, float, 16, 512>; | 258 | + WAIT(e1); |
| 259 | - | 259 | + COMPUTE(tile_a); |
| 260 | -// ✅ Correct: Reduce to 256 | 260 | + WAIT(e2); |
| 261 | -using TileT = Tile<TileType::Vec, float, 16, 256>; | 261 | + COMPUTE(tile_b); |
| 262 | - | 262 | + swap(e1, e2); |
| 263 | -// Method 2: Use double buffering | 263 | + swap(tile_a, tile_b); |
| 264 | -Event e1, e2; | 264 | +} |
| 265 | -TileT tile_a, tile_b; | 265 | +``` |
| 266 | - | 266 | + |
| 267 | -TLOAD(tile_a, input[0:size], e1); | 267 | +### M002: Memory Alignment Error |
| 268 | -for (int i = 1; i < N; i++) { | 268 | + |
| 269 | - TLOAD(tile_b, input[i*size:size], e2); | 269 | +**Error Message**: |
| 270 | - WAIT(e1); | 270 | +``` |
| 271 | - COMPUTE(tile_a); | 271 | +PTO_ASSERT: Memory address not aligned |
| 272 | - WAIT(e2); | 272 | +Address: 0x12345678, Required alignment: 64 |
| 273 | - COMPUTE(tile_b); | 273 | +``` |
| 274 | - swap(e1, e2); | 274 | + |
| 275 | - swap(tile_a, tile_b); | 275 | +**Cause**: Memory address doesn't meet alignment requirements |
| 276 | -} | 276 | + |
| 277 | -``` | 277 | +**Solution**: |
| 278 | - | 278 | +```cpp |
| 279 | -### M002: Memory Alignment Error | 279 | +// Use aligned_alloc |
| 280 | - | 280 | +void* ptr = aligned_alloc(64, size); |
| 281 | -**Error Message**: | 281 | + |
| 282 | -``` | 282 | +// Or use C++17 aligned_new |
| 283 | -PTO_ASSERT: Memory address not aligned | 283 | +float* ptr = new(std::align_val_t{64}) float[size]; |
| 284 | -Address: 0x12345678, Required alignment: 64 | 284 | + |
| 285 | -``` | 285 | +// Check alignment |
| 286 | - | 286 | +assert(reinterpret_cast<uintptr_t>(ptr) % 64 == 0); |
| 287 | -**Cause**: Memory address doesn't meet alignment requirements | 287 | +``` |
| 288 | - | 288 | + |
| 289 | -**Solution**: | 289 | +--- |
| 290 | -```cpp | 290 | + |
| 291 | -// Use aligned_alloc | 291 | +## 5. Numerical Errors (N001-N099) |
| 292 | -void* ptr = aligned_alloc(64, size); | 292 | + |
| 293 | - | 293 | +### N001: Numerical Precision Error |
| 294 | -// Or use C++17 aligned_new | 294 | + |
| 295 | -float* ptr = new(std::align_val_t{64}) float[size]; | 295 | +**Error Message**: |
| 296 | - | 296 | +``` |
| 297 | -// Check alignment | 297 | +Numerical error: max_diff = 1e-2 |
| 298 | -assert(reinterpret_cast<uintptr_t>(ptr) % 64 == 0); | 298 | +Expected: 1.0, Got: 1.01 |
| 299 | -``` | 299 | +``` |
| 300 | - | 300 | + |
| 301 | ---- | 301 | +**Cause**: Floating-point precision issues or algorithm errors |
| 302 | - | 302 | + |
| 303 | -## 5. Numerical Errors (N001-N099) | 303 | +**Solution**: |
| 304 | - | 304 | +```cpp |
| 305 | -### N001: Numerical Precision Error | 305 | +// Method 1: Use higher precision |
| 306 | - | 306 | +// ❌ half (FP16): precision ~1e-3 |
| 307 | -**Error Message**: | 307 | +using TileT = Tile<TileType::Vec, half, 16, 256>; |
| 308 | -``` | 308 | + |
| 309 | -Numerical error: max_diff = 1e-2 | 309 | +// ✅ float (FP32): precision ~1e-7 |
| 310 | -Expected: 1.0, Got: 1.01 | 310 | +using TileT = Tile<TileType::Vec, float, 16, 256>; |
| 311 | -``` | 311 | + |
| 312 | - | 312 | +// Method 2: Adjust tolerance |
| 313 | -**Cause**: Floating-point precision issues or algorithm errors | 313 | +const float TOLERANCE = 1e-5; // Adjust based on data type |
| 314 | - | 314 | +assert(abs(result - expected) < TOLERANCE); |
| 315 | -**Solution**: | 315 | +``` |
| 316 | -```cpp | 316 | + |
| 317 | -// Method 1: Use higher precision | 317 | +### N002: NaN or Inf |
| 318 | -// ❌ half (FP16): precision ~1e-3 | 318 | + |
| 319 | -using TileT = Tile<TileType::Vec, half, 16, 256>; | 319 | +**Error Message**: |
| 320 | - | 320 | +``` |
| 321 | -// ✅ float (FP32): precision ~1e-7 | 321 | +Numerical error: NaN detected |
| 322 | -using TileT = Tile<TileType::Vec, float, 16, 256>; | 322 | +Numerical error: Inf detected |
| 323 | - | 323 | +``` |
| 324 | -// Method 2: Adjust tolerance | 324 | + |
| 325 | -const float TOLERANCE = 1e-5; // Adjust based on data type | 325 | +**Cause**: Division by zero, overflow, or invalid operations |
| 326 | -assert(abs(result - expected) < TOLERANCE); | 326 | + |
| 327 | -``` | 327 | +**Solution**: |
| 328 | - | 328 | +```cpp |
| 329 | -### N002: NaN or Inf | 329 | +// Add numerical checks |
| 330 | - | 330 | +void check_numerical_stability(const Tile& tile) { |
| 331 | -**Error Message**: | 331 | + for (int i = 0; i < tile.size(); i++) { |
| 332 | -``` | 332 | + float val = tile[i]; |
| 333 | -Numerical error: NaN detected | 333 | + if (std::isnan(val)) { |
| 334 | -Numerical error: Inf detected | 334 | + printf("NaN detected at index %d\n", i); |
| 335 | -``` | 335 | + } |
| 336 | - | 336 | + if (std::isinf(val)) { |
| 337 | -**Cause**: Division by zero, overflow, or invalid operations | 337 | + printf("Inf detected at index %d\n", i); |
| 338 | - | 338 | + } |
| 339 | -**Solution**: | 339 | + } |
| 340 | -```cpp | 340 | +} |
| 341 | -// Add numerical checks | 341 | + |
| 342 | -void check_numerical_stability(const Tile& tile) { | 342 | +// Avoid division by zero |
| 343 | - for (int i = 0; i < tile.size(); i++) { | 343 | +TADDS(denominator, denominator, 1e-8f); // Add small constant |
| 344 | - float val = tile[i]; | 344 | +TDIV(result, numerator, denominator); |
| 345 | - if (std::isnan(val)) { | 345 | + |
| 346 | - printf("NaN detected at index %d\n", i); | 346 | +// Use safe math functions |
| 347 | - } | 347 | +TCLIP(tile, tile, -1e10f, 1e10f); // Limit range |
| 348 | - if (std::isinf(val)) { | 348 | +``` |
| 349 | - printf("Inf detected at index %d\n", i); | 349 | + |
| 350 | - } | 350 | +--- |
| 351 | - } | 351 | + |
| 352 | -} | 352 | +## 6. Performance Issues (P001-P099) |
| 353 | - | 353 | + |
| 354 | -// Avoid division by zero | 354 | +### P001: Performance Below Expectations |
| 355 | -TADDS(denominator, denominator, 1e-8f); // Add small constant | 355 | + |
| 356 | -TDIV(result, numerator, denominator); | 356 | +**Symptoms**: Operator runtime far exceeds expectations |
| 357 | - | 357 | + |
| 358 | -// Use safe math functions | 358 | +**Diagnosis**: |
| 359 | -TCLIP(tile, tile, -1e10f, 1e10f); // Limit range | 359 | +```bash |
| 360 | -``` | 360 | +# Use msprof for analysis |
| 361 | - | 361 | +msprof --output=./profiling_data \ |
| 362 | ---- | 362 | + --application="./my_operator" \ |
| 363 | - | 363 | + --ai-core=on |
| 364 | -## 6. Performance Issues (P001-P099) | 364 | + |
| 365 | - | 365 | +# View report |
| 366 | -### P001: Performance Below Expectations | 366 | +msprof --export=on --output=./profiling_data |
| 367 | - | 367 | +``` |
| 368 | -**Symptoms**: Operator runtime far exceeds expectations | 368 | + |
| 369 | - | 369 | +**Common Causes and Solutions**: |
| 370 | -**Diagnosis**: | 370 | + |
| 371 | -```bash | 371 | +1. **Memory Access Bottleneck** |
| 372 | -# Use msprof for analysis | 372 | +```cpp |
| 373 | -msprof --output=./profiling_data \ | 373 | +// ❌ Problem: Frequent GM access |
| 374 | - --application="./my_operator" \ | 374 | +for (int i = 0; i < N; i++) { |
| 375 | - --ai-core=on | 375 | + TLOAD(tile, input[i]); |
| 376 | - | 376 | + COMPUTE(tile); |
| 377 | -# View report | 377 | + TSTORE(output[i], tile); |
| 378 | -msprof --export=on --output=./profiling_data | 378 | +} |
| 379 | -``` | 379 | + |
| 380 | - | 380 | +// ✅ Optimization: Batch loading |
| 381 | -**Common Causes and Solutions**: | 381 | +const int BATCH = 8; |
| 382 | - | 382 | +for (int i = 0; i < N; i += BATCH) { |
| 383 | -1. **Memory Access Bottleneck** | 383 | + TLOAD(tiles[0:BATCH], input[i:BATCH]); |
| 384 | -```cpp | 384 | + for (int j = 0; j < BATCH; j++) { |
| 385 | -// ❌ Problem: Frequent GM access | 385 | + COMPUTE(tiles[j]); |
| 386 | -for (int i = 0; i < N; i++) { | 386 | + } |
| 387 | - TLOAD(tile, input[i]); | 387 | + TSTORE(output[i:BATCH], tiles[0:BATCH]); |
| 388 | - COMPUTE(tile); | 388 | +} |
| 389 | - TSTORE(output[i], tile); | 389 | +``` |
| 390 | -} | 390 | + |
| 391 | - | 391 | +2. **Low Pipeline Efficiency** |
| 392 | -// ✅ Optimization: Batch loading | 392 | +```cpp |
| 393 | -const int BATCH = 8; | 393 | +// ❌ Problem: Serial execution |
| 394 | -for (int i = 0; i < N; i += BATCH) { | 394 | +TLOAD(tile, input); |
| 395 | - TLOAD(tiles[0:BATCH], input[i:BATCH]); | 395 | +WAIT_LOAD(); |
| 396 | - for (int j = 0; j < BATCH; j++) { | 396 | +COMPUTE(tile); |
| 397 | - COMPUTE(tiles[j]); | 397 | +WAIT_COMPUTE(); |
| 398 | - } | 398 | +TSTORE(output, tile); |
| 399 | - TSTORE(output[i:BATCH], tiles[0:BATCH]); | 399 | + |
| 400 | -} | 400 | +// ✅ Optimization: Pipeline parallelism |
| 401 | -``` | 401 | +Event load_event, compute_event; |
| 402 | - | 402 | +TLOAD(tile_a, input[0], load_event); |
| 403 | -2. **Low Pipeline Efficiency** | 403 | +for (int i = 1; i < N; i++) { |
| 404 | -```cpp | 404 | + TLOAD(tile_b, input[i], load_event); |
| 405 | -// ❌ Problem: Serial execution | 405 | + WAIT(load_event); |
| 406 | -TLOAD(tile, input); | 406 | + COMPUTE(tile_a, compute_event); |
| 407 | -WAIT_LOAD(); | 407 | + WAIT(compute_event); |
| 408 | -COMPUTE(tile); | 408 | + TSTORE(output[i-1], tile_a); |
| 409 | -WAIT_COMPUTE(); | 409 | + swap(tile_a, tile_b); |
| 410 | -TSTORE(output, tile); | 410 | +} |
| 411 | - | 411 | +``` |
| 412 | -// ✅ Optimization: Pipeline parallelism | 412 | + |
| 413 | -Event load_event, compute_event; | 413 | +--- |
| 414 | -TLOAD(tile_a, input[0], load_event); | 414 | + |
| 415 | -for (int i = 1; i < N; i++) { | 415 | +## 7. Framework Integration Errors (F001-F099) |
| 416 | - TLOAD(tile_b, input[i], load_event); | 416 | + |
| 417 | - WAIT(load_event); | 417 | +### F001: PyTorch Operator Registration Failed |
| 418 | - COMPUTE(tile_a, compute_event); | 418 | + |
| 419 | - WAIT(compute_event); | 419 | +**Error Message**: |
| 420 | - TSTORE(output[i-1], tile_a); | 420 | +``` |
| 421 | - swap(tile_a, tile_b); | 421 | +RuntimeError: No such operator npu::my_add |
| 422 | -} | 422 | +``` |
| 423 | -``` | 423 | + |
| 424 | - | 424 | +**Cause**: Operator not properly registered |
| 425 | ---- | 425 | + |
| 426 | - | 426 | +**Solution**: |
| 427 | -## 7. Framework Integration Errors (F001-F099) | 427 | +```cpp |
| 428 | - | 428 | +// Ensure proper registration |
| 429 | -### F001: PyTorch Operator Registration Failed | 429 | +TORCH_LIBRARY_FRAGMENT(npu, m) { |
| 430 | - | 430 | + m.def("my_add(Tensor x, Tensor y) -> Tensor"); |
| 431 | -**Error Message**: | 431 | +} |
| 432 | -``` | 432 | + |
| 433 | -RuntimeError: No such operator npu::my_add | 433 | +TORCH_LIBRARY_IMPL(npu, PrivateUse1, m) { |
| 434 | -``` | 434 | + m.impl("my_add", TORCH_FN(my_add_impl)); |
| 435 | - | 435 | +} |
| 436 | -**Cause**: Operator not properly registered | 436 | + |
| 437 | - | 437 | +// Python verification |
| 438 | -**Solution**: | 438 | +import torch |
| 439 | -```cpp | 439 | +print(torch.ops.npu.my_add) # Should display operator info |
| 440 | -// Ensure proper registration | 440 | +``` |
| 441 | -TORCH_LIBRARY_FRAGMENT(npu, m) { | 441 | + |
| 442 | - m.def("my_add(Tensor x, Tensor y) -> Tensor"); | 442 | +### F002: Device Type Mismatch |
| 443 | -} | 443 | + |
| 444 | - | 444 | +**Error Message**: |
| 445 | -TORCH_LIBRARY_IMPL(npu, PrivateUse1, m) { | 445 | +``` |
| 446 | - m.impl("my_add", TORCH_FN(my_add_impl)); | 446 | +RuntimeError: Expected all tensors to be on the same device, but found at least two devices, npu:0 and cpu! |
| 447 | -} | 447 | +``` |
| 448 | - | 448 | + |
| 449 | -// Python verification | 449 | +**Cause**: Input tensors on different devices |
| 450 | -import torch | 450 | + |
| 451 | -print(torch.ops.npu.my_add) # Should display operator info | 451 | +**Solution**: |
| 452 | -``` | 452 | +```python |
| 453 | - | 453 | +# Ensure all inputs on same device |
| 454 | -### F002: Device Type Mismatch | 454 | +x = x.npu() |
| 455 | - | 455 | +y = y.npu() |
| 456 | -**Error Message**: | 456 | +z = torch.ops.npu.my_add(x, y) |
| 457 | -``` | 457 | + |
| 458 | -RuntimeError: Expected all tensors to be on the same device, but found at least two devices, npu:0 and cpu! | 458 | +# Or check in operator |
| 459 | -``` | 459 | +at::Tensor my_add_impl(const at::Tensor& x, const at::Tensor& y) { |
| 460 | - | 460 | + TORCH_CHECK(x.device() == y.device(), |
| 461 | -**Cause**: Input tensors on different devices | 461 | + "Inputs must be on same device"); |
| 462 | - | 462 | + // ... |
| 463 | -**Solution**: | 463 | +} |
| 464 | -```python | 464 | +``` |
| 465 | -# Ensure all inputs on same device | 465 | + |
| 466 | -x = x.npu() | 466 | +--- |
| 467 | -y = y.npu() | 467 | + |
| 468 | -z = torch.ops.npu.my_add(x, y) | 468 | +## References |
| 469 | - | 469 | + |
| 470 | -# Or check in operator | 470 | +- [Debugging Guide](debug.md) |
| 471 | -at::Tensor my_add_impl(const at::Tensor& x, const at::Tensor& y) { | 471 | +- [Performance Optimization](opt.md) |
| 472 | - TORCH_CHECK(x.device() == y.device(), | 472 | +- [Compilation Process](compilation-process.md) |
| 473 | - "Inputs must be on same device"); | 473 | +- [Framework Integration](framework-integration.md) |
| 474 | - // ... | 474 | +- [Memory Optimization](memory-optimization.md) |
| 475 | -} | 475 | + |
| 476 | -``` | ||
| 477 | - | ||
| 478 | ---- | ||
| 479 | - | ||
| 480 | -## References | ||
| 481 | - | ||
| 482 | -- [Debugging Guide](debug.md) | ||
| 483 | -- [Performance Optimization](opt.md) | ||
| 484 | -- [Compilation Process](compilation-process.md) | ||
| 485 | -- [Framework Integration](framework-integration.md) | ||
| 486 | -- [Memory Optimization](memory-optimization.md) | ||
| 487 | - | ||
| @@ -1,16 +1,6 @@ | |||
| 1 | # 常见错误码说明 | 1 | # 常见错误码说明 |
| 2 | 2 | ||
| 3 | -本文档详细列出 PTO 开发中常见的错误码、错误信息及其解决方案,帮助开发者快速定位和解决问题。 | 3 | +本文档汇总 PTO 开发中常见的失败现象及排查建议。示例中的报错信息仅用于说明问题类型,实际诊断信息会随编译工具链、运行时环境和宿主系统而变化。 |
| 4 | - | ||
| 5 | -## 目录 | ||
| 6 | - | ||
| 7 | -- [1. 编译错误 (E001-E099)](#1-编译错误-e001-e099) | ||
| 8 | -- [2. 链接错误 (L001-L099)](#2-链接错误-l001-l099) | ||
| 9 | -- [3. 运行时错误 (R001-R099)](#3-运行时错误-r001-r099) | ||
| 10 | -- [4. 内存错误 (M001-M099)](#4-内存错误-m001-m099) | ||
| 11 | -- [5. 数值错误 (N001-N099)](#5-数值错误-n001-n099) | ||
| 12 | -- [6. 性能问题 (P001-P099)](#6-性能问题-p001-p099) | ||
| 13 | -- [7. 框架集成错误 (F001-F099)](#7-框架集成错误-f001-f099) | ||
| 14 | 4 | ||
| 15 | --- | 5 | --- |
| 16 | 6 | ||
| @@ -68,7 +58,7 @@ using TileT = Tile<TileType::Vec, float, 16, 256>; | |||
| 68 | error: no matching function for call to 'TADD(Tile<float>&, Tile<half>&)' | 58 | error: no matching function for call to 'TADD(Tile<float>&, Tile<half>&)' |
| 69 | ``` | 59 | ``` |
| 70 | 60 | ||
| 71 | -**原因**:Tile 类型不一致 | 61 | +**原因**:Tile 的元素类型或形状不一致。 |
| 72 | 62 | ||
| 73 | **解决方案**: | 63 | **解决方案**: |
| 74 | ```cpp | 64 | ```cpp |
| @@ -80,12 +70,10 @@ TADD(tile_a, tile_a, tile_b); // 错误! | |||
| 80 | // ✅ 正确:类型一致 | 70 | // ✅ 正确:类型一致 |
| 81 | Tile<TileType::Vec, float, 16, 256> tile_a, tile_b, tile_c; | 71 | Tile<TileType::Vec, float, 16, 256> tile_a, tile_b, tile_c; |
| 82 | TADD(tile_c, tile_a, tile_b); // 正确 | 72 | TADD(tile_c, tile_a, tile_b); // 正确 |
| 83 | - | ||
| 84 | -// 或使用类型转换 | ||
| 85 | -TCAST(tile_b_float, tile_b); // half → float | ||
| 86 | -TADD(tile_c, tile_a, tile_b_float); | ||
| 87 | ``` | 73 | ``` |
| 88 | 74 | ||
| 75 | +若确实需要显式类型转换,请使用当前目标分支和指令集实际提供的转换指令,具体 API 以对应版本文档为准。 | ||
| 76 | + | ||
| 89 | ### E004: C++ 标准版本不支持 | 77 | ### E004: C++ 标准版本不支持 |
| 90 | 78 | ||
| 91 | **错误信息**: | 79 | **错误信息**: |