コンパイルされたコンポーネント

はじめに

コンパイルされたコンポーネントは,コンパイルされた機能の集まりを表す.これには,コンパイルされたコードで使うことのできる宣言やトップレベルのコードで使うことのできるインストールされた関数が含まれる.コンパイルされたコンポーネントはこの機能をパッケージ化し配布するためのフレームワークを提供する.

コンパイラベースのパクレットの作成

パクレットシステムと統合すると,コンパイルされたコンポーネントやそれに関連付けられたビルドを単一のカーネルセッションを超えて配布することが可能になる.この例では,数個のインストールされた関数を示し,外部ライブラリに依存するコンパイルされたコンポーネントを定義する.

パクレットの定義

まず新規のパクレットを作成する:
PacletInfo.wlファイルが"LibraryResources"拡張を含むように変更する.これによってコンポーネントシステムがコンポーネントのビルドライブラリを後で見付けることができるようになる:
PacletObject[
    <|
        "Name" -> "ComponentPaclet",
        "Version" -> "0.0.1",
        "WolframVersion" -> "13.2+",
        "Extensions" -> {
                {"Kernel", "Root" -> "Kernel", "Context" -> "ComponentPaclet`"},
                {"LibraryResources"}
            }
    |>
]
作成するパクレットのソースを変更し,コンパイルされたコンポーネントを入れる:
BeginPackage["ComponentPaclet`"]

AddOne
RaiseToPower

Begin["`Private`"]

(* Declare compiler declarations *)
DeclareCompiledComponent["ExampleComponent", {
    LibraryFunctionDeclaration["addone", "compilerDemoBase", {"CInt"}->"CInt"],

    FunctionDeclaration[AddOne,
        Typed[{"CInt"} -> "CInt"]@
        Function[arg, LibraryFunction["addone"][arg]]
    ],

    FunctionDeclaration[RaiseToPower,
        Typed[{"MachineInteger","MachineInteger"} -> "MachineInteger"]@
        Function[{x,y}, x^y]
    ]
}];

(* Declare installed functions *)
DeclareCompiledComponent["ExampleComponent", "InstalledFunctions" -> {
    AddOne,
    RaiseToPower
}];

(* Declare library functions *)
DeclareCompiledComponent["ExampleComponent", "LibraryFunctions" -> <|
    "sqrt" -> Function[Typed[arg,"Real64"], Sqrt[arg]]
|>];

(* Declare external library dependencies *)
DeclareCompiledComponent["ExampleComponent", "ExternalLibraries" -> {
    "compilerDemoBase"
}];

End[] (* End `Private` *)

EndPackage[]

パクレットのロード

パクレットをロードする:
パクレットをロードすることでコンポーネントが定義される.これはコンパイルされたコードで使うことができる:
コンポーネントはまだビルドされていないので,そのインストールされた関数を使おうとするとエラーが出る:

コンポーネントの構築

コンパイルされたライブラリ関数やインストールされた関数にアクセスするためには,コンパイルされたコンポーネントが構築されなければならない.

コンポーネントはBuildCompiledComponentを使って構築することができる.ビルドの目的地としてPacletObjectを指定することによって,パクレットにコンポーネントライブラリが置かれる:
BuildCompiledComponentの呼出しによって,パクレット内にLibraryResourcesディレクトリが作成され,コンポーネントによって指定されたすべての関数を含む動的ライブラリが追加された:

コンポーネントのロード

これでコンポーネントができたので,インストールされた関数が使える.

インストールされた関数が最初に使われるとき,自動的にコンポーネントライブラリをロードしようと試みる:

これはFindLibraryを使ってコンポーネントのビルドを見付ける.コンポーネントのビルドはPacletInfo.wlファイルの中で"LibraryResources"拡張が与えられたので,パクレットの中に見付けることができる.

あるいはLoadCompiledComponentを使って明示的にコンポーネントビルドをロードすることもできる.これによってビルドのすべての特性にアクセスできるようになる:
LoadCompiledComponentを使うと,コンポーネントで指定されたライブラリ関数にアクセスすることが可能になる:

コンポーネントがビルドされているので,"ComponentPaclet"パクレットはソースを再コンパイルしなくても新規のカーネルセッションですぐに使える.また,ビルドを別のマシンに配布することもかのうであるが,構築されたプラットフォームでのみ互換性がある.クロスプラットフォームのコンポーネントライブラリを構築するためには,すべてのターゲットプラットフォームでBuildCompiledComponentを実行する必要がある.