feat(phase-21.8+25): Complete imports resolution + Ring0/Ring1 numeric ABI design
Phase 21.8 完了 (imports resolution): - ✅ using nyash.core.numeric.matrix_i64 as MatI64 完全対応 - ✅ hakorune_emit_mir.sh で imports 抽出・MirBuilder に配線 - ✅ MatI64/IntArrayCore の静的参照解決が安定動作 - ✅ matmul_core ベンチ MIR 生成成功 (VM/LLVM 両対応) Phase 25 設計完了 (Ring0/Ring1 + numeric ABI): - 🎯 Ring0/Ring1 責務分離を明文化 (Rust Freeze Policy 具体化) - 🎯 Call/ExternCall 明確な分離設計 - Call: Ring1 Hako 関数 (numeric core 等) - ExternCall: Ring0 intrinsic (rt_mem_* 等の FFI のみ) - 🎯 BoxCall → Call 変換方針確定 (AotPrep で実施) - 🎯 MatI64.mul_naive を NyNumericMatI64.mul_naive に分離 (System Hakorune subset で完全実装済み) 実装: - ✅ AotPrepNumericCoreBox 診断パス実装 (NYASH_AOT_NUMERIC_CORE=1) - ✅ numeric ABI ドキュメント整備 (NUMERIC_ABI.md) - ✅ System Hakorune subset 定義 (system-hakorune-subset.md) - ✅ IntArrayCore/MatI64 仕様固定 (lang/src/runtime/numeric/README.md) - ✅ ENV_VARS.md に NYASH_AOT_NUMERIC_CORE トグル追記 今後のタスク: - BoxCall(MatI64) → Call(NyNumericMatI64) 変換実装 (opt-in) - IntArrayCore の numeric core 整備 - matmul_core スモークテスト (NYASH_AOT_NUMERIC_CORE=0/1 両対応) 🎉 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -75,6 +75,11 @@ NYASH_DISABLE_PLUGINS = "1"
|
||||
- NYASH_AOT_OBJECT_OUT: AOT パイプラインで使用する `.o` 出力ディレクトリ/パス
|
||||
- NYASH_LLVM_USE_HARNESS: "1" で llvmlite ハーネス経路を有効化(MIR(JSON)→Python→.ll→llc→.o)
|
||||
|
||||
## AotPrep / Numeric Core(Phase 25 実験用)
|
||||
- NYASH_AOT_COLLECTIONS_HOT: Array/Map boxcall を externcall に書き換えるホットパス(CollectionsHot パスを有効化)
|
||||
- NYASH_AOT_NUMERIC_CORE: 数値系 BoxCall(MatI64 / IntArrayCore 等)の診断パスを有効化(`AotPrepNumericCoreBox`)。現状はログ出力のみで MIR は変更しない(将来の BoxCall→Call 降ろし用の足場)。
|
||||
- NYASH_AOT_NUMERIC_CORE_TRACE: 上記 numeric core パスの詳細トレース("1" で `mul_naive/at/set` など候補 BoxCall を stderr にログ出力)
|
||||
|
||||
### LLVM Feature 詳細
|
||||
- **llvm** (デフォルト): llvmlite Python ハーネス使用、LLVM_SYS_180_PREFIX不要
|
||||
- **llvm-inkwell-legacy**: Rust inkwell bindings使用、LLVM_SYS_180_PREFIX必要
|
||||
|
||||
147
docs/development/runtime/NUMERIC_ABI.md
Normal file
147
docs/development/runtime/NUMERIC_ABI.md
Normal file
@ -0,0 +1,147 @@
|
||||
# Numeric ABI (IntArrayCore / MatI64) — Design Stage
|
||||
|
||||
Status: design-stage; Phase 25 scope; no behaviour change yet.
|
||||
|
||||
## Purpose
|
||||
|
||||
- Define a minimal, stable **numeric ABI** for IntArrayCore / MatI64 that:
|
||||
- 実装としては Ring1 Hakorune の通常関数(`Call`)として表現でき、
|
||||
- 必要に応じて Ring0 Rust / C 側からも同じシグネチャで呼び出せる(将来の FFI/ExternCall 連携の基礎になる)。
|
||||
- Keep **all box-specific knowledge in Ring1**:
|
||||
- Box/Handle/Core の構造(ptr/len/rows/cols/stride 等)。
|
||||
- 行列積などの数値アルゴリズム本体。
|
||||
- 境界チェックと Fail‑Fast ポリシー。
|
||||
- Allow Ring0/LLVM to treat numeric calls as:
|
||||
- 通常の関数呼び出し(`Call @ny_numeric_*`)として扱えるようにし、
|
||||
- 必要な場合のみ、既存の `ExternCall`/FFI 構造の上に同じ関数群を載せ替えられるようにする(Phase 25 では必須ではない)。
|
||||
|
||||
Related docs:
|
||||
- Phase 25 roadmap: `docs/development/roadmap/phases/phase-25/README.md`
|
||||
- Ring1 numeric runtime layout: `lang/src/runtime/numeric/README.md`
|
||||
- System Hakorune subset (runtime/numeric 用記法): `docs/development/runtime/system-hakorune-subset.md`
|
||||
|
||||
## Conventions
|
||||
|
||||
- **Types / encoding**
|
||||
- Numeric ABI 関数のシグネチャは **i64 と Handle(実体は i64×N)** のみを使う。
|
||||
- `IntArrayHandle` / `MatI64Handle` は「i64×N の値」として表現される:
|
||||
- C 側イメージ(概念):
|
||||
- `typedef struct { int64_t *ptr; int64_t len; } ny_intarray_handle;`
|
||||
- `typedef struct { int64_t *ptr; int64_t rows; int64_t cols; int64_t stride; } ny_mat_i64_handle;`
|
||||
- MIR では「複数の i64 をまとめた値」として `Call` の引数/戻り値に現れる。
|
||||
- **命名**
|
||||
- Ring1/Hakorune 側では、`ny_numeric_intarray_*` / `ny_numeric_mat_i64_*` 系の関数名(またはそれに相当するモジュール+メソッド名)で実装する。
|
||||
- C/Rust 側から直接呼びたい場合は、同じ名前でシンボルをエクスポートする(必要になったタイミングで ExternCall に載せ替え可能)。
|
||||
- **Fail‑Fast**
|
||||
- numeric ABI では、事前条件違反(負の長さ、境界外 index、dims 不整合)は **すべてバグ扱い** とし、Fail‑Fast で扱う。
|
||||
- 「エラーコードを返して上層で if」するスタイルは禁止(AGENTS.md の対処療法禁止に準拠)。
|
||||
|
||||
## ABI Surface — IntArrayCore (i64 1D)
|
||||
|
||||
Conceptual handle:
|
||||
- `IntArrayHandle`: 実体は「`ptr: i64` + `len: i64`」等で構成される Core 構造体を指す値。
|
||||
- Box レベル仕様は `lang/src/runtime/numeric/README.md` の IntArrayCore セクションを参照。
|
||||
|
||||
Functions (proposal; Phase 25 scope):
|
||||
|
||||
- `ny_numeric_intarray_new(len: i64) -> IntArrayHandle`
|
||||
- Allocate zero-initialized buffer of length `len`.
|
||||
- Preconditions:
|
||||
- `len >= 0`
|
||||
- `len` が i64 範囲内であり、`len * sizeof(i64)` の計算がオーバーフローしない。
|
||||
- Failure:
|
||||
- OOM / 明らかな誤りは Fail‑Fast(戻り値でのエラー表現は行わない)。
|
||||
|
||||
- `ny_numeric_intarray_free(a: IntArrayHandle)`
|
||||
- Free underlying Core.
|
||||
- Double-free / invalid handle は未定義動作とし、所有権設計(Ring1 側)で防ぐ。
|
||||
|
||||
- `ny_numeric_intarray_len(a: IntArrayHandle) -> i64`
|
||||
- Return current logical length.
|
||||
- Used mainly for assertions / diagnostics;通常は Box 側で長さを保持しない方向に寄せる。
|
||||
|
||||
- `ny_numeric_intarray_get(a: IntArrayHandle, idx: i64) -> i64`
|
||||
- Load `a[idx]`.
|
||||
- Preconditions:
|
||||
- `0 <= idx < len(a)`.
|
||||
- Failure:
|
||||
- Precondition violated → Fail‑Fast(例外 or プロセス終了; 実際の実装は後続フェーズで決定)。
|
||||
|
||||
- `ny_numeric_intarray_set(a: IntArrayHandle, idx: i64, v: i64)`
|
||||
- Store `v` into `a[idx]`.
|
||||
- Preconditions:
|
||||
- `0 <= idx < len(a)`.
|
||||
- Failure:
|
||||
- Precondition violated → Fail‑Fast。
|
||||
|
||||
Mapping to MIR(Phase 25 の基本方針):
|
||||
- BoxCall(例): `BoxCall(IntArrayCore, "get_unchecked", [arr, idx])`
|
||||
- AotPrep: 数値コア関数への通常 `Call` に書き換え(例: `Call NyNumericIntArray.get(arr_handle, idx)`)。
|
||||
- LLVM/VM: どちらも同じ `Call` を実行するだけで numeric ABI に到達する。
|
||||
|
||||
## ABI Surface — MatI64 (i64 2D matrix)
|
||||
|
||||
Conceptual handle:
|
||||
- `MatI64Handle`: 「`ptr`, `rows`, `cols`, `stride`」を持つ Core 構造を指す値。
|
||||
- Box レベル仕様は `lang/src/runtime/numeric/README.md` の MatI64 セクションを参照。
|
||||
|
||||
Functions (proposal; Phase 25 scope):
|
||||
|
||||
- `ny_numeric_mat_i64_new(rows: i64, cols: i64) -> MatI64Handle`
|
||||
- Allocate zero-initialized `rows x cols` matrix, row‑major。
|
||||
- Preconditions:
|
||||
- `rows >= 0`, `cols >= 0`.
|
||||
- `rows * cols` が i64 範囲内であり、`rows * cols * sizeof(i64)` がオーバーフローしない。
|
||||
|
||||
- `ny_numeric_mat_i64_free(m: MatI64Handle)`
|
||||
- Free underlying matrix Core(所有権は Box 側で管理)。
|
||||
|
||||
- `ny_numeric_mat_i64_dims(m: MatI64Handle) -> (rows: i64, cols: i64)`
|
||||
- Return matrix dimensions(行数・列数)。
|
||||
|
||||
- `ny_numeric_mat_i64_get(m: MatI64Handle, row: i64, col: i64) -> i64`
|
||||
- Load element at `(row, col)`.
|
||||
- Preconditions:
|
||||
- `0 <= row < rows(m)`, `0 <= col < cols(m)`.
|
||||
|
||||
- `ny_numeric_mat_i64_set(m: MatI64Handle, row: i64, col: i64, v: i64)`
|
||||
- Store `v` into `(row, col)`.
|
||||
- Preconditions:
|
||||
- 同上。
|
||||
|
||||
- `ny_numeric_mat_i64_mul_naive(a: MatI64Handle, b: MatI64Handle, n: i64) -> MatI64Handle`
|
||||
- Naive O(n³) matrix multiplication for `n x n` matrices.
|
||||
- Preconditions:
|
||||
- `rows(a) == cols(a) == rows(b) == cols(b) == n`.
|
||||
- `n >= 0`。
|
||||
- Failure:
|
||||
- 上記条件を満たさない場合は Fail‑Fast。ベンチマークバグを隠さない。
|
||||
|
||||
Mapping to MIR(Phase 25 の基本方針):
|
||||
- BoxCall(例): `BoxCall(MatI64, "mul_naive", [a, b])`
|
||||
- AotPrep: `Call NyNumericMatI64.mul_naive(a_handle, b_handle, n)` のような numeric core 関数呼び出しに書き換え。
|
||||
- LLVM/VM: どちらも同じ `Call` を実行するだけで numeric ABI に到達する。
|
||||
|
||||
## BoxCall / Call / ExternCall の役割分担
|
||||
|
||||
- Initial MIR:
|
||||
- `BoxCall(MatI64, "new", [rows, cols])`
|
||||
- `BoxCall(MatI64, "mul_naive", [a, b])`
|
||||
- AotPrep (Ring1):
|
||||
- これらを numeric core 関数への `Call` に変換する(BoxCall を LLVM まで持ち込まない)。
|
||||
- Box 名やメソッド名ベースの一時的 if ではなく、「Box 型ID + メソッドID → numeric core 関数 ID」テーブル化を目指す。
|
||||
- Ring0 / LLVM:
|
||||
- `Call @ny_numeric_*` を普通の関数呼び出しとして扱う。
|
||||
- 低レベルのメモリアクセスや OS 連携が必要な場合のみ、既存の `ExternCall`(例: `rt_mem_alloc_i64`)を使う。numeric ABI 自体は必須では ExternCall に依存しない。
|
||||
|
||||
## Relation to other docs
|
||||
|
||||
- Phase 25 roadmap:
|
||||
- Numeric ABI の設計方針(Ring0/Ring1 分離、Call/ExternCall のみ、Fail‑Fast)を高レベルで説明。
|
||||
- このファイルは、そのうち IntArrayCore / MatI64 に関わる ABI 面のみを詳細化する。
|
||||
- `lang/src/runtime/numeric/README.md`:
|
||||
- IntArrayCore / MatI64 の **Box レベル API**(フィールド・メソッド契約)を定義。
|
||||
- Numeric ABI はその下で動く「Core/Handle レベル」の境界として扱う。
|
||||
- `docs/development/runtime/system-hakorune-subset.md`:
|
||||
- Numeric ABI の実装を記述する際に使う Hakorune 言語機能の subset を規定。
|
||||
- ループ/Fail‑Fast/Box/Handle パターンなど、実装スタイルを制約する。
|
||||
87
docs/development/runtime/system-hakorune-subset.md
Normal file
87
docs/development/runtime/system-hakorune-subset.md
Normal file
@ -0,0 +1,87 @@
|
||||
# System Hakorune Subset — Runtime / Numeric Core Design
|
||||
|
||||
Status: design-stage; subset definition only. No behavior change yet.
|
||||
|
||||
## Purpose
|
||||
|
||||
- Provide a small, predictable subset of Hakorune for implementing **runtime / numeric core logic** in Ring1(IntArrayCore, MatI64, stats, policy, etc.)。
|
||||
- Make this subset explicit so that:
|
||||
- Box / numeric kernels can be moved from Rust to `.hako` **without increasing semantic complexity**.
|
||||
- AotPrep / VM / LLVM can rely on a restricted feature set when reasoning about these modules.
|
||||
- Align with Phase 25 goals:
|
||||
- Ring0(Rust)は intrinsic と最小 VM/FFI のみ。
|
||||
- Ring1(Hakorune)は「元・C 相当の実装」をこの subset で記述する。
|
||||
|
||||
Related docs:
|
||||
- Phase 25 roadmap: `docs/development/roadmap/phases/phase-25/README.md`
|
||||
- Ring1 numeric runtime layout: `lang/src/runtime/numeric/README.md`
|
||||
- Numeric ABI surface (IntArrayCore / MatI64): `docs/development/runtime/NUMERIC_ABI.md`
|
||||
|
||||
## Scope & Typical Use
|
||||
|
||||
- 対象モジュールの例:
|
||||
- `nyash.core.numeric.intarray`(IntArrayCore 本体)
|
||||
- `nyash.core.numeric.matrix_i64`(MatI64 本体)
|
||||
- 将来の数値箱(例: F64ArrayCore, MatF64 など)
|
||||
- ランタイムポリシー / stats / 軽量な AotPrep 補助ロジック
|
||||
- 非対象(ここでは扱わないもの):
|
||||
- 高レベルアプリケーションロジック(UI、CLI コマンド等)。
|
||||
- 重い I/O / ネットワーク / プラグイン動的ロード。
|
||||
- 実験的な言語機能(例外、async 等)を前提とするコード。
|
||||
|
||||
## Allowed Features(推奨)
|
||||
|
||||
- 制御構造:
|
||||
- `if / else`、`while`、インデックス付きの従来型 `for` ループ。
|
||||
- ネストは OK だが、循環依存や過度な再帰は避ける。
|
||||
- データ構造:
|
||||
- Box フィールドを明示した構造体的なパターン(`handle.ptr`, `handle.len` 等)。
|
||||
- 固定長 or 単純な一次元/二次元配列アクセス(IntArrayCore / MatI64)。
|
||||
- 関数:
|
||||
- 引数/戻り値が `i64` と Box/Handle 型に限定された関数。
|
||||
- 純粋 or 副作用が局所(配列/行列への書き込み)のみの関数。
|
||||
- エラーハンドリング:
|
||||
- **Fail‑Fast** を前提とした設計(事前条件違反は即失敗)。
|
||||
- 戻り値でのエラーコード運搬は禁止(AGENTS.md の対処療法禁止と合わせる)。
|
||||
|
||||
## Restricted / Forbidden Features
|
||||
|
||||
- 例外 / 非同期:
|
||||
- `throw/try` や async 相当の機能は numeric core の実装では使わない方針(後続フェーズで必要になった場合に個別に設計)。
|
||||
- 動的ディスパッチ:
|
||||
- 文字列ベースの `by-name` ディスパッチ(`if method == "mul"` 等)は避け、事前に決まった numeric ABI 関数を直接呼び出す。
|
||||
- 動的ロード / プラグイン依存:
|
||||
- numeric core から直接プラグインをロードしない。必要なら上位層(アプリ側)がプラグイン経由で呼ぶ。
|
||||
- 型拡張:
|
||||
- 汎用的な「任意型の配列/行列」をここで扱わない。Phase 25 では **i64 専用(IntArrayCore / MatI64)** にスコープを絞る。
|
||||
|
||||
## Design Patterns & Guidelines
|
||||
|
||||
- 明示的ループ:
|
||||
- 数値カーネルは map/filter 的な高階関数ではなく、`for` / `while` による明示ループで書く。
|
||||
- これにより AotPrep / LLVM でのループ変換・アンローリング等の解析がしやすくなる。
|
||||
- Box / Handle の役割分離:
|
||||
- Box(例: `MatI64`)は **API と所有権** を管理する層。
|
||||
- Handle/Core(例: `IntArrayCore`, `MatI64Core`)は **実データとループ本体** を持つ層。
|
||||
- Box メソッドは「引数検査 → numeric ABI 呼び出し」の薄いラッパに留める。
|
||||
- Fail‑Fast:
|
||||
- インデックスや次元の検査は、「バグを隠さない」方向で実装する。
|
||||
- `idx < 0` や `idx >= len` など明らかなバグは例外 or プロセス終了で即座に検出し、フォールバックや silent failure は行わない。
|
||||
|
||||
## Relation to Ring0 / Numeric ABI
|
||||
|
||||
- Ring0(Rust):
|
||||
- IntArrayCore / MatI64 向けには「ptr/len/rows/cols/stride を受け取る intrinsic」だけを提供する。
|
||||
- ループ本体や境界チェックは実装しない(System Hakorune subset 側に責務を寄せる)。
|
||||
- Ring1(Hakorune):
|
||||
- この subset 上で numeric ABI 関数群(`ny_numeric_intarray_*`, `ny_numeric_mat_i64_*`)を実装する。
|
||||
- AotPrep は BoxCall → numeric ABI への `ExternCall` 変換を行い、LLVM 側は汎用 Call/ExternCall として扱うだけでよい。
|
||||
|
||||
## Roadmap(Phase 25 以降)
|
||||
|
||||
- Phase 25:
|
||||
- Subset の定義を docs として固定(このファイル)。
|
||||
- IntArrayCore / MatI64 の API 仕様と合わせて、どの機能を subset に含めるかを明示する。
|
||||
- 後続フェーズ(22.x / 26.x など):
|
||||
- 実際の `.hako` 実装を subset 遵守で書き起こす。
|
||||
- AotPrep / VM / LLVM の観点から「subset で書かれた numeric core を前提にした最適化/診断」を設計する。
|
||||
Reference in New Issue
Block a user