Files
hakorune/docs/development/runtime/NUMERIC_ABI.md
nyash-codex 8750186e55 chore: Phase 26-H セッション完了 - 全ドキュメント更新
Phase 26-H 完了内容:
 JoinIR 型定義実装(src/mir/join_ir.rs)
 MIR → JoinIR 自動変換実装(lower_min_loop_to_joinir)
 自動変換テスト実装(mir_joinir_min_auto_lowering)
 PHI/Loop箱 → JoinIR 移行対応表追加(loopform_ssot.md)

ドキュメント更新:
- Phase 27 JoinIR タスク計画追加
- Phase 26-H タスク完了記録
- 各種 README 更新(進捗反映)
- CURRENT_TASK.md 更新

コミット統計: $(git status --short | wc -l) files changed

次のステップ: Phase 27 一般化 MIR → JoinIR 変換
2025-11-23 05:53:27 +09:00

7.5 KiB
Raw Blame History

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/private/roadmap2/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 パターンなど、実装スタイルを制約する。