アーキテクチャ
このガイドでは、luna_thread の MoonBit パッケージ、C ランタイム、JavaScript アドオンがどう組み合わさるか、そしてどの整数コードが外部関数インターフェースを越えるかを説明します。各 MoonBit パッケージの詳細はパッケージのページにあります。
レイヤー
仕様は 2 つの実現経路を挙げています。
MoonBit facade -> MoonBit C FFI -> C wrapper -> C runtime
MoonBit facade -> MoonBit JS FFI -> JS wrapper -> N-API addon -> C runtime
1 つ目の経路は存在します。2 つ目は MoonBit 側で止まっています。backend/js は JavaScript ターゲットを示すだけで、js/ のアドオンは runtimeName 関数しかエクスポートしません。
MoonBit パッケージの依存関係に閉路はありません。
| パッケージ | インポート |
|---|---|
shared | コアライブラリのみ |
plan | shared |
workflow | plan, shared |
backend/js | plan, shared |
backend/native | plan, shared, workflow |
core | backend/native, plan, shared, workflow |
sharedはほかのすべてのパッケージが使う語彙を持ちます。バックエンドターゲット、実行モード、順序の保証、実行ポリシーとその検証、ランタイムケイパビリティの表、C のリクエスト構造体を整数コードで写したものです。planは型付きの入力領域に対する 1 つのデータ並列操作を記述し、v1 のサブセットに照らして検査します。workflowは、ノードが計算プランやケイパビリティに結び付いた同期ステップであるタスクグラフを記述し、その構造を検査します。backend/nativeはプランを型付きのネイティブリクエストに変換し、C のカーネルを呼び出し、ワークフローを整列して C スケジューラに渡します。- ルートパッケージ
coreはよく使う入口を既定値付きで再エクスポートし、投入をネイティブバックエンドに振り分けます。
C ランタイム
ランタイムは 1 つの C ファイルと 1 つのヘッダからなります。
| ファイル | 役割 |
|---|---|
native/include/luna_thread_runtime.h | 公開 C API。ステータスコード、リクエスト構造体、ワークフローの型です。 |
native/src/runtime.c | カーネル、検証、ワークフロースケジューラです。 |
luna_thread/backend/native/ffi_runtime_impl.c | 同じソースを MoonBit のネイティブスタブとしてコンパイルしたもので、違いは #include のパスだけです。 |
luna_thread/backend/native/ffi_runtime_bridge.c | MoonBit の引数をリクエスト構造体に変換する luna_mbt_* ラッパーです。 |
luna_thread/backend/native/ffi_stub.c | luna_mbt_* ラッパーの宣言です。 |
native/tests/smoke.c | カーネルとその失敗ステータスに対する C のスモークテストです。 |
ランタイムの 2 つのコピーは手作業で同一に保たなければなりません。
ビルドは 2 通りあります。moon はシステムの C コンパイラで OpenMP のフラグなしにスタブをコンパイルするので、#pragma omp のループは呼び出し元のスレッドで実行されますが、ワークフロースケジューラは POSIX スレッドを起動します。CMake(make native-configure、make native-build)は、LUNA_THREAD_ENABLE_OPENMP が有効なら native/ を OpenMP 付きの静的ライブラリとしてビルドし、スモークテストも一緒にビルドします。両方の実行モデルはネイティブバックエンドの設計で説明しています。
インターフェースを越えるコード
すべての列挙値は Int として C インターフェースを越えます。MoonBit 側では backend/native(ステータスは shared)で対応づけます。
ステータスコード
| コード | C の名前 | MoonBit の NativeStatus |
|---|---|---|
| 0 | LUNA_THREAD_STATUS_OK | Ok |
| 1 | INVALID_ARGUMENT | InvalidArgument |
| 2 | UNSUPPORTED_BACKEND | UnsupportedBackend |
| 3 | UNSUPPORTED_MODE | UnsupportedMode |
| 4 | UNSUPPORTED_VALUE_TYPE | UnsupportedValueType |
| 5 | UNSUPPORTED_REDUCTION_KERNEL | UnsupportedReductionKernel |
| 6 | OVERFLOW | Overflow |
| 7 | NULL_POINTER | NullPointer |
| 8 | UNSUPPORTED_RUNTIME_PRIMITIVE | なし |
| 9 | RUNTIME_BROKEN | なし |
| 10 | CHANNEL_EMPTY | なし |
| 11 | CHANNEL_CLOSED | なし |
| 12 | MUTEX_PROTOCOL_ERROR | なし |
| 13 | CONDVAR_PROTOCOL_ERROR | なし |
| 14 | BARRIER_BROKEN | なし |
コード 8 から 14 はワークフローランタイムからのみ返され、WorkflowResult::status が生の整数として運びます。
ワークフローのコード
| コード | ノードの種類 | ケイパビリティの種類 | エッジの種類 | ランタイムの状態 |
|---|---|---|---|---|
| 0 | Compute | OwnedBuffer | DataDependency | Submitted |
| 1 | Spawn | SharedReadView | ControlDependency | Running |
| 2 | Join | AtomicCell | OwnershipTransfer | Completed |
| 3 | Send | Mutex | SynchronizationDependency | Failed |
| 4 | Recv | Condvar | Rejected | |
| 5 | Lock | RwLock | ||
| 6 | Unlock | Semaphore | ||
| 7 | Wait | Barrier | ||
| 8 | Signal | Channel | ||
| 9 | Barrier | Opaque | ||
| 10 | ReadShared | |||
| 11 | WriteShared |
値の型は I32 が 0、I64 が 1、リダクションカーネルは Sum が 0、Min が 1、Max が 2 です。
JavaScript アドオン
js/ は node-gyp のプロジェクト(make js-install、make js-build)で、その C ソースは "luna_thread_addon" を返す関数 runtimeName を 1 つだけ登録します。まだ C ランタイムはリンクしていません。
仕様
doc/attachments/moonbit_parallel_spec/main.typ は規範となる英語の仕様で、main.zh_CN.typ はその中国語版です。make docs で両方をコンパイルします。仕様はワークフロー計算、所有権の移転、ABI のレイアウト、適合性の義務を定めています。実装は第 I 部のデータモデルと検証、そしてその一部のネイティブ実現を扱っており、どの部分かは各パッケージの設計ページに書かれています。docs/spec-review-report-zh.md にはレビューの所見が中国語で記録されています。
リポジトリの構成
| パス | 内容 |
|---|---|
luna_thread/ | MoonBit モジュール(moon.mod)とそのパッケージです。 |
native/ | C ランタイム、ヘッダ、CMake ビルド、スモークテストです。 |
js/ | Node.js アドオンのひな形です。 |
doc/ | このマニュアル、その翻訳、仕様です。 |
scripts/check-env.sh | MoonBit、C、Node.js、Typst のツールチェーンを検査します。 |
Makefile | 検査、ネイティブランタイムとアドオンのビルド、仕様のコンパイルのためのショートカットです。 |