shared API

パッケージ Luna-Flow/luna_thread/shared は @shared としてインポートされ、モジュールのほかのすべてのパッケージが使う語彙を持ちます。バックエンドターゲット、実行モード、順序の保証、実行ポリシーとその検証、各バックエンドが宣言するケイパビリティ、ネイティブのステータスコード、そして C のリクエスト構造体を写した整数コードのレコードです。すべてのターゲットでビルドできます。

このパッケージの列挙型はパッケージの外では読み取り専用です。コンストラクタでパターンマッチはできますが、値は以下の関数で作ってください。

ターゲット、モード、順序

BackendTarget

プランやワークフローを実行するランタイムです。

pub enum BackendTarget {
  Native
  JavaScript
} derive(Eq, @debug.Debug)

ExecutionMode

投入が終わるまでブロックするかどうかです。

pub enum ExecutionMode {
  Synchronous
  Asynchronous
} derive(Eq, @debug.Debug)

OrderingGuarantee

結果が入力の順序を保たなければならないかどうかです。

pub enum OrderingGuarantee {
  PreserveInputOrder
  RelaxedOrder
} derive(Eq, @debug.Debug)

native_target、javascript_target、synchronous_mode、asynchronous_mode、preserve_input_order、relaxed_order

Native、JavaScript、Synchronous、Asynchronous、PreserveInputOrder、RelaxedOrder を返します。

pub fn native_target() -> BackendTarget
pub fn javascript_target() -> BackendTarget
pub fn synchronous_mode() -> ExecutionMode
pub fn asynchronous_mode() -> ExecutionMode
pub fn preserve_input_order() -> OrderingGuarantee
pub fn relaxed_order() -> OrderingGuarantee

backend_label

"native" または "javascript" を返します。

pub fn backend_label(BackendTarget) -> String
test "targets" {
  inspect(@shared.backend_label(@shared.javascript_target()), content="javascript")
  assert_true(@shared.relaxed_order() is @shared.RelaxedOrder)
}

実行ポリシー

ExecutionPolicy

プランやワークフローの実行方法です。バックエンド、モード、ワーカー数、チャンクサイズ、順序からなります。

pub struct ExecutionPolicy {
  backend : BackendTarget
  mode : ExecutionMode
  worker_count : Int
  chunk_size : Int
  ordering : OrderingGuarantee
} derive(Eq, @debug.Debug)

PolicyIssue と PolicyError

ポリシーが v1 のサブセットから外れる理由と、最初の理由を運ぶエラーです。

pub enum PolicyIssue {
  WorkerCountMustBePositive(Int)
  ChunkSizeMustBePositive(Int)
  UnsupportedBackendForV1(BackendTarget)
  UnsupportedModeForV1(ExecutionMode)
} derive(Eq, @debug.Debug)

pub struct PolicyError {
  issue : PolicyIssue
} derive(Eq, @debug.Debug)

make_execution_policy

ポリシーを作り、最初の問題を PolicyError として返します。

pub fn make_execution_policy(backend? : BackendTarget, mode? : ExecutionMode, worker_count? : Int, chunk_size? : Int, ordering? : OrderingGuarantee) -> Result[ExecutionPolicy, PolicyError]

既定値は Native、Synchronous、1、1、PreserveInputOrder です。検査は worker_count > 0、chunk_size > 0、backend == Native、mode == Synchronous の順に行われ、順序は検査されません。

ExecutionPolicy::new

make_execution_policy と同じようにポリシーを作り、エラーになる場合は中断します。

pub fn ExecutionPolicy::new(backend? : BackendTarget, mode? : ExecutionMode, worker_count? : Int, chunk_size? : Int, ordering? : OrderingGuarantee) -> Self

native_policy と javascript_policy

既定のネイティブポリシーを返します。後者は JavaScript バックエンドで同じことを試みます。

pub fn native_policy() -> ExecutionPolicy
pub fn javascript_policy() -> ExecutionPolicy

native_policy() は make_execution_policy().unwrap() です。javascript_policy() は make_execution_policy(backend=JavaScript).unwrap() で、JavaScript バックエンドが拒否されるため v1 では中断します。

validate_policy

既存のポリシーのすべての問題を、上の検査の順序で返します。

pub fn validate_policy(ExecutionPolicy) -> Array[PolicyIssue]

上の関数で作ったポリシーは常に検査を通ります。validate_policy が意味を持つのはワークフローに保存されたポリシーで、@workflow.validate がそれを再検査します。

is_parallel

ポリシーが 2 つ以上のワーカーを求めるとき true を返します。

pub fn is_parallel(ExecutionPolicy) -> Bool
test "policies" {
  let policy = @shared.make_execution_policy(worker_count=4, chunk_size=8).unwrap()
  assert_true(@shared.is_parallel(policy))
  assert_eq(@shared.validate_policy(policy).length(), 0)
  let rejected = @shared.make_execution_policy(backend=@shared.javascript_target())
  debug_inspect(
    rejected,
    content="Err({ issue: UnsupportedBackendForV1(JavaScript) })",
  )
  assert_false(@shared.is_parallel(@shared.native_policy()))
}

ランタイムケイパビリティ

RuntimeCapabilities

バックエンドが宣言する機能です。

pub struct RuntimeCapabilities {
  backend : BackendTarget
  supports_parallelism : Bool
  supports_async : Bool
  supports_zero_copy_buffers : Bool
} derive(Eq, @debug.Debug)

RuntimeCapabilities::for_backend

バックエンドが宣言する表を返します。

pub fn RuntimeCapabilities::for_backend(BackendTarget) -> Self
バックエンド並列実行非同期ゼロコピーバッファ
Nativetruefalsefalse
JavaScripttruetruetrue

この表は固定の宣言であり、実行中のシステムを調べた結果ではありません。JavaScript の行は仕様が計画しているバックエンドを表しており、JavaScript バックエンドはまだ何も実行しません。

ネイティブのステータスコード

NativeStatus

C ランタイムのステータスコード 0 から 7 です。

pub enum NativeStatus {
  Ok
  InvalidArgument
  UnsupportedBackend
  UnsupportedMode
  UnsupportedValueType
  UnsupportedReductionKernel
  Overflow
  NullPointer
} derive(Eq, @debug.Debug)

native_status_code と native_status_from_code

NativeStatus とその C のコードを相互に変換します。

pub fn native_status_code(NativeStatus) -> Int
pub fn native_status_from_code(Int) -> NativeStatus

native_status_code はコンストラクタに宣言順で 0 から 7 の番号を付けます。native_status_from_code は 0 から 7 の範囲でその逆写像になり、ワークフローのステータス 8 から 14 を含むほかのすべてのコードを InvalidArgument に写します。

test "status codes" {
  assert_true(@shared.native_status_from_code(6) is @shared.Overflow)
  assert_true(@shared.native_status_from_code(14) is @shared.InvalidArgument)
  for code in 0..<8 {
    let status = @shared.native_status_from_code(code)
    assert_eq(@shared.native_status_code(status), code)
  }
}

整数コードのネイティブレコード

これらのレコードは C の構造体 luna_thread_buffer、luna_thread_map_request、luna_thread_reduce_request、luna_thread_scan_request をフィールドごとに写したもので、列挙値は Int のコードで表します。モジュール内のどのパッケージもこれらを使っておらず、backend/native は独自の型付きレコードを使います。引数は検査せずに保存します。

NativeBuffer

Int で表したポインタと長さです。

pub struct NativeBuffer {
  ptr : Int
  length : Int
} derive(Eq, @debug.Debug)
pub fn NativeBuffer::new(Int, Int) -> Self
pub fn NativeBuffer::ptr(Self) -> Int
pub fn NativeBuffer::length(Self) -> Int

NativeMapRequest

入力と出力のバッファ、要素数、値の型のコード、ワーカー数、チャンクサイズです。

pub struct NativeMapRequest {
  input : NativeBuffer
  output : NativeBuffer
  element_count : Int
  value_type : Int
  worker_count : Int
  chunk_size : Int
} derive(Eq, @debug.Debug)
pub fn NativeMapRequest::new(NativeBuffer, NativeBuffer, Int, Int, Int, Int) -> Self
pub fn NativeMapRequest::input(Self) -> NativeBuffer
pub fn NativeMapRequest::output(Self) -> NativeBuffer
pub fn NativeMapRequest::element_count(Self) -> Int
pub fn NativeMapRequest::value_type(Self) -> Int
pub fn NativeMapRequest::worker_count(Self) -> Int
pub fn NativeMapRequest::chunk_size(Self) -> Int

コンストラクタはフィールドを宣言順に受け取ります。

NativeReduceRequest と NativeScanRequest

NativeMapRequest と同じフィールドに、値の型の後ろにリダクションカーネルのコードが加わります。

pub struct NativeReduceRequest {
  input : NativeBuffer
  output : NativeBuffer
  element_count : Int
  value_type : Int
  reduction_kernel : Int
  worker_count : Int
  chunk_size : Int
} derive(Eq, @debug.Debug)
pub fn NativeReduceRequest::new(NativeBuffer, NativeBuffer, Int, Int, Int, Int, Int) -> Self
pub fn NativeReduceRequest::input(Self) -> NativeBuffer
pub fn NativeReduceRequest::output(Self) -> NativeBuffer
pub fn NativeReduceRequest::element_count(Self) -> Int
pub fn NativeReduceRequest::value_type(Self) -> Int
pub fn NativeReduceRequest::reduction_kernel(Self) -> Int
pub fn NativeReduceRequest::worker_count(Self) -> Int
pub fn NativeReduceRequest::chunk_size(Self) -> Int

pub struct NativeScanRequest {
  input : NativeBuffer
  output : NativeBuffer
  element_count : Int
  value_type : Int
  reduction_kernel : Int
  worker_count : Int
  chunk_size : Int
} derive(Eq, @debug.Debug)
pub fn NativeScanRequest::new(NativeBuffer, NativeBuffer, Int, Int, Int, Int, Int) -> Self
pub fn NativeScanRequest::input(Self) -> NativeBuffer
pub fn NativeScanRequest::output(Self) -> NativeBuffer
pub fn NativeScanRequest::element_count(Self) -> Int
pub fn NativeScanRequest::value_type(Self) -> Int
pub fn NativeScanRequest::reduction_kernel(Self) -> Int
pub fn NativeScanRequest::worker_count(Self) -> Int
pub fn NativeScanRequest::chunk_size(Self) -> Int
test "native records" {
  let buffer = @shared.NativeBuffer::new(0, 4)
  let request = @shared.NativeReduceRequest::new(buffer, buffer, 4, 0, 1, 2, 2)
  assert_eq(request.reduction_kernel(), 1)
  assert_eq(request.input().length(), 4)
}

等価性とパッケージ情報

T::equal

構造的な等価性で、このパッケージのすべての型 BackendTarget、ExecutionMode、ExecutionPolicy、NativeBuffer、NativeMapRequest、NativeReduceRequest、NativeScanRequest、NativeStatus、OrderingGuarantee、PolicyError、PolicyIssue、RuntimeCapabilities のメソッドとして昇格されています。== と != を使ってください。

pub fn ExecutionPolicy::equal(Self, Self) -> Bool

package_name

"shared" を返します。

pub fn package_name() -> String