ascendc-operator-design について
AscendC オペレーターの要件から、後続のコード生成に使う設計ドキュメントを作成するスキルです。実装方式、API 呼び出しの疑似コード、二段階の Tiling、UB の割り当てを扱います。
主な機能
- 01要件分析と実装方式の選定
- 02AscendC API の計算疑似コード生成
- 03Block 単位と UB 単位の Tiling 設計
- 04UB バッファーと係数の明記
- 05精度変換とハードウェア制約の記載
活用シーン
- 01オペレーターのコード生成用設計書の作成
- 02オペレーター種別に応じた Tiling と UB 使用量の計画
- 03実装前の PyTorch または NumPy との意味の整合
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ ascend/ agent-skills --skill ascendc-operator-designインストール後、Claude Code で/ascendc-operator-designを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/elementwise-tiling.mdgeneral-tiling-principles.mdhardware-architecture.mdindex-tiling.mdpooling-tiling.mdreduction-tiling.mdsort-tiling.mdtemplates/design-template.md詳細
AscendC Operator Design Skill
算子の要件に基づいて完全な設計ドキュメント(design.md)を生成し、後続の code-gen skill で使用します。
使用シーン
ascendc-operator-project-init で骨組みを作成した後、ascendc-operator-code-gen でコードを生成する前に呼び出します。
設計フロー
1. 算子要件の分析
スケジューリング skill から呼び出された場合、算子名と機能の説明はすでに確定しているため、手順 2 に進みます。
単独で呼び出された場合、以下の情報をユーザーに確認します。
| 情報 | 必須 | 説明 |
|---|---|---|
| 算子名(snake_case) | はい | 例:acosh、rms_norm |
| 機能の説明/数式 | はい | 例:「acosh(x) = ln(x + sqrt(x²-1))」 |
| サポートするデータ型 | いいえ | デフォルトは float16 + float32 |
MANDATORY: PyTorch/NumPy に同名のインターフェースが存在するか確認します。存在する場合、インターフェースのシグネチャとセマンティクスは 必ず それに合わせてください(例:torch.acosh、torch.softmax)。
2. 実装パスの選択
算子の特性に基づいて、適切な実装方法を推奨します。
| 実装パス | 適用シーン | 判断基準 |
|---|---|---|
| AscendC Kernel | 純粋な vector 算子 | 行列乗算を含まない |
| CATLASS テンプレートライブラリ | GEMM / FlashAttention | cube 行列計算を含む |
| ACLNN ラッパー | CANN に組み込み算子がある | カスタム kernel が不要 |
新しい算子には、行列乗算を明確に含む場合を除き、デフォルトで AscendC Kernel パスを使用します。
3. 詳細設計ドキュメントの生成
MANDATORY: 設計ドキュメントを生成する前に、以下の参考ドキュメントを必ず読みます。
- 必読:
templates/design-template.md— 設計ドキュメントのテンプレート - 算子の種類に応じて選択:
- 要素ごとの操作(add/relu/acosh/sigmoid...)→
references/elementwise-tiling.md - リダクション操作(softmax/layernorm...)→
references/reduction-tiling.md - インデックス操作(gather/index_select/scatter...)→
references/index-tiling.md - ソート操作(sort/topk...)→
references/sort-tiling.md - プーリング操作(avgpool/maxpool/...)→
references/pooling-tiling.md
- 要素ごとの操作(add/relu/acosh/sigmoid...)→
- 共通の参考資料:
references/general-tiling-principles.md
参考ドキュメントの確認を絶対に省略しないでください。
3.1 設計ドキュメントの構成
設計ドキュメントには、以下の主要セクションを含めます。
- 算子インターフェースの定義 — 関数シグネチャ、パラメーターの説明、サポートするデータ型
- 計算ロジックの設計 — アルゴリズムの説明、AscendC API 呼び出しの擬似コード、実装パスの選択
- Tiling 戦略 — 2 段階 Tiling 設計(Block レベル + UB レベル)、UB 割り当て表、tileLength の計算
- Workspace の要件 — Workspace サイズの計算
- 性能最適化 — 主要な最適化ポイント、算子特性の分析
- Kernel 側の実装ポイント — オフセット計算、実行フロー、FP16/BF16 の精度向上処理
- 実装チェックリスト — ファイル構成、コードの要点、テストの要点
3.2 計算ロジックの擬似コード(重要な成果物)
数式を AscendC API 呼び出しのシーケンスに分解することが必須です。これは code-gen skill への直接の入力となります。
よく使われる数式から AscendC API への対応関係:
| 数学演算 | AscendC API | 備考 |
|---|---|---|
| x + y | Add(dst, src0, src1, len) | 2 入力 |
| x - y | Sub(dst, src0, src1, len) | 2 入力 |
| x * y | Mul(dst, src0, src1, len) | 2 入力 |
| x / y | Div(dst, src0, src1, len) | 2 入力 |
| x + scalar | Adds(dst, src, scalar, len) | スカラー演算。優先して使用 |
| x * scalar | Muls(dst, src, scalar, len) | スカラー演算。優先して使用 |
| abs(x) | Abs(dst, src, len) | |
| exp(x) | Exp(dst, src, len) | |
| ln(x) | Ln(dst, src, len) | |
| sqrt(x) | Sqrt(dst, src, len) | |
| 1/x | Reciprocal(dst, src, len) | |
| 1/sqrt(x) | Rsqrt(dst, src, len) | |
| tanh(x) | Tanh(dst, src, len) | |
| relu(x) | Relu(dst, src, len) | |
| max(x,y) | Max(dst, src0, src1, len) | |
| min(x,y) | Min(dst, src0, src1, len) | |
| fp16→fp32 | Cast(dst, src, CAST_NONE, len) | 精度向上。損失なし |
| fp32→fp16 | Cast(dst, src, CAST_ROUND, len) | 精度低下。損失あり |
例 — acosh(x) の API 呼び出しシーケンス:
Mul(tmp, x, x, len); // tmp = x²
Adds(tmp, tmp, -1.0f, len); // tmp = x² - 1
Sqrt(tmp, tmp, len); // tmp = sqrt(x² - 1)
Add(tmp, tmp, x, len); // tmp = x + sqrt(x² - 1)
Ln(y, tmp, len); // y = ln(x + sqrt(x² - 1))
注意:計算シーケンス内のあるステップで dst と src が同じ場合(インプレース操作)、ほとんどの AscendC API が対応していますが、API ごとに確認が必要です。
3.2 Tiling 戦略
重要: AscendC 算子では 2 段階の Tiling 戦略を採用します。算子の種類に応じて、対応するドキュメントを参照してください。
┌─────────────────────────────────────────────────────────────┐
│ 全局内存 (GM) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ totalLength 元素数据 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌────────────────┼────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Core 0 │ │ Core 1 │ ... │ Core 39 │ ← Block级Tiling (核间切分)
└──────────┘ └──────────┘ └──────────┘
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ UB 0 │ │ UB 1 │ │ UB 39 │ ← UB级Tiling (核内切分)
└──────────┘ └──────────┘ └──────────┘
Block レベルの Tiling(コア間の分割):
- データを複数の AI Core に割り当てて並列処理します
- 負荷分散: 全コア/末尾コア方式を採用し、末尾コアが処理するデータ量は全コア以下とします
UB レベルの Tiling(コア内の分割):
- 各 Core 内でデータをブロックに分けて処理します
- UB のアライメント: 32 バイト
- UB 容量: UB_SIZE_LIMIT を超えないようにします(実際のコーディング時にはインターフェースから取得します。例の値は 192KB)
参考ドキュメント:
- 要素ごとの操作:
references/elementwise-tiling.mdを読みます(2 段階 Tiling の実装全体を含む) - リダクション操作:
references/reduction-tiling.mdを読みます - インデックス操作:
references/index-tiling.mdを読みます - ソート操作:
references/sort-tiling.mdを読みます - プーリング操作:
references/pooling-tiling.mdを読みます - 一般原則:
references/general-tiling-principles.mdを参照します
3.3 ハードウェア制約に関する説明
- UB バッファー: 32 バイト境界にアラインする必要があります。論理的に少量のデータしか格納しない場合も同様です
- リダクション系の算子: 単一値のバッファーには 32B の領域が必要です
- 精度処理:
- FP32 入力: 精度向上は不要で、そのまま計算します
- FP16 入力: 計算精度を確保するため、必ず FP32 に精度を上げて計算します
- BF16 入力: vector 計算ユニットは bfloat16 の直接計算をサポートしていないため、必ず FP32 に精度を上げて計算します
- Workspace の要件:
- elementwise 系: SYSTEM_WORKSPACE_SIZE(通常 16MB)
- その他の算子: 実際の tiling data サイズに基づいて計算します
3.4 代表的な演算子タイプの UB 割り当て早見表
演算子の入力数とデータ型に基づいて、bufferCoefficient をすばやく特定します。
単一入力・単一出力の要素単位演算(acosh、relu、sigmoid、exp、ln、sqrt、abs...):
| データ型 | UB レイアウト | bufferCoefficient |
|---|---|---|
| float32 | inQ(2×4) + outQ(2×4) + tmpBuf(1×4) = 20 | 20 |
| float16 | inQ(2×2) + outQ(2×2) + tmpBuf1(1×4) + tmpBuf2(1×4) = 16 | 16 |
二重入力・単一出力の要素単位演算(add、mul、sub、div...):
| データ型 | UB レイアウト | bufferCoefficient |
|---|---|---|
| float32 | inQ_X(2×4) + inQ_Y(2×4) + outQ(2×4) + tmpBuf(2×4) = 32 | 32 |
| float16 | inQ_X(2×2) + inQ_Y(2×2) + outQ(2×2) + tmpBuf(3×4) = 24 | 24 |
実践的な知見:bufferCoefficient はコード生成段階で最も重要なパラメーターです。設計ドキュメントには、dtype ごとの値を必ず明記してください。そうしないと、コード生成で tileLength を正しく計算できません。
3.5 設計ドキュメントの生成
収集した情報に基づいて、templates/design-template.md テンプレートを読み込み、すべてのセクションに記入して、csrc/ops/<op_name>/design.md に出力します。
出力先:ascend-kernel/csrc/ops/<op_name>/design.md(初期化段階で作成したプレースホルダーファイルを上書き)
対話フロー
呼び出し元の skill から呼び出された場合(推奨フロー):
- 演算子名と機能の説明を受け取ります
- 実装パスを自動的に選択します
- 参考ドキュメントを読み込み、設計ドキュメントを作成します
- design.md に出力します
単独で呼び出された場合:
- 要件の収集:対話を通じて演算子の要件を把握します
- 方式の推奨:要件に基づいて実装パスを推奨します
- 詳細設計:設計ドキュメントを作成します
- 確認:ユーザーと設計の要点を確認します
- 開発への引き継ぎ:チェックリストを作成し、コーディング段階に進む準備をします
注意事項
Tiling パラメーターの設計原則
-
パラメーターの構造化:
// 好的做法:使用结构体 struct MyOperatorTilingData { int64_t totalLength; // 总数据长度 int64_t formerNum; // 整核数量 int64_t formerLength; // 整核数据长度 int64_t tailNum; // 尾核数量 int64_t tailLength; // 尾核数据长度 int64_t tileLength; // UB单次处理长度 }; // 避免:使用大量独立参数 void KernelFunc(int64_t totalLength, int64_t tileNum, int64_t tileLength, ...); -
2 段階のアラインメント:
// Block级: Cache Line 对齐 (512字节) constexpr int64_t CACHE_LINE_BYTE_LENGTH = 512; int64_t totalLengthCoreAlign = ((totalLengthCore + CACHE_LINE_BYTE_LENGTH - 1) / CACHE_LINE_BYTE_LENGTH) * CACHE_LINE_BYTE_LENGTH; // UB级: 32字节对齐 int64_t ubAlignElements = 32 / dtypeSize; int64_t tileLengthAligned = ((tileLength + ubAlignElements - 1) / ubAlignElements) * ubAlignElements; -
UB 割り当て表:各演算子の設計には、次の項目を明記した UB 割り当て表を必ず含めてください。
- すべての buffer 名と用途
- 各 buffer のサイズ(バイト単位)
- buffer の数(単一 buffer または double buffer)
- UB の合計使用量と制約の検証
-
Double Buffer:BUFFER_NUM=2 を使用して double buffer を実現し、メモリー遅延を隠します
その他の注意事項
- データ型の整合性:PyTorch tensor の型と AscendC kernel の型が一致していることを確認します(half ↔ float16、float ↔ float32)
- メモリーアラインメント:AscendC ではメモリーアドレスのアラインメントが必要です(UB 32B、Cache Line 512B)
- Shape の制約:演算子によっては Shape に特別な要件があります(例:tile size で割り切れる必要がある)
- 性能のトレードオフ:コードの複雑さと性能のバランスを取ります
- インターフェースの定義:PyTorch/Numpy などのライブラリーに類似の演算子インターフェースがあるか確認し、存在する場合は、そのインターフェース定義を参考にします
- テスト入力範囲:設計ドキュメントに演算子の有効な入力範囲(例:acosh では x >= 1 が必要)を記載し、それに基づいてテストケース用のデータを生成します
完了基準(DoD)
設計ドキュメントの生成後、次の成果物を必ず含めてください(code-gen skill が直接使用します)。
- 関数シグネチャ:
at::Tensor op_name(const at::Tensor &self, ...)の完全な宣言 - サポートするデータ型:明確に列挙します(例:float16、float32)
- AscendC API 呼び出しの擬似コード:各計算ステップを具体的な API に対応付けます
- UB 割り当て表:dtype ごとの buffer レイアウトと bufferCoefficient
- Tiling パラメーター構造体:フィールド定義と計算式
- FP16/BF16 の精度引き上げフロー:半精度をサポートする場合は、Cast の経路を必ず記述します
次のステップ
設計完了後、ascendc-operator-code-gen skill を使用して具体的なコード実装を生成します。