Files
hakorune/docs/development/runtime/NUMERIC_ABI.md
nyash-codex 864a94d013 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>
2025-11-14 20:19:00 +09:00

148 lines
7.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 等)。
- 行列積などの数値アルゴリズム本体。
- 境界チェックと FailFast ポリシー。
- 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 に載せ替え可能)。
- **FailFast**
- numeric ABI では、事前条件違反(負の長さ、境界外 index、dims 不整合)は **すべてバグ扱い** とし、FailFast で扱う。
- 「エラーコードを返して上層で 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 / 明らかな誤りは FailFast戻り値でのエラー表現は行わない
- `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 → FailFast例外 or プロセス終了; 実際の実装は後続フェーズで決定)。
- `ny_numeric_intarray_set(a: IntArrayHandle, idx: i64, v: i64)`
- Store `v` into `a[idx]`.
- Preconditions:
- `0 <= idx < len(a)`.
- Failure:
- Precondition violated → FailFast。
Mapping to MIRPhase 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, rowmajor。
- 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:
- 上記条件を満たさない場合は FailFast。ベンチマークバグを隠さない。
Mapping to MIRPhase 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 のみ、FailFastを高レベルで説明。
- このファイルは、そのうち 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 を規定。
- ループ/FailFast/Box/Handle パターンなど、実装スタイルを制約する。