OpenCLLink`
OpenCLLink`

OpenCLFunctionLoad

OpenCLFunctionLoad["src",fun,argtypes,blockdims]

文字列 src をコンパイルし,funOpenCLFunctionとしてWolfram言語内で使えるようにする.

OpenCLFunctionLoad[File[srcfile],fun,argtypes,blockdim]

ソースコードファイル srcfile をコンパイルしてから,funOpenCLFunctionとしてロードする.

OpenCLFunctionLoad[File[libfile],fun,argtypes,blockdim]

前にコンパイルされたライブラリ libfile から funOpenCLFunctionとしてロードする.

詳細とオプション

  • OpenCLLink アプリケーションは,Needs["OpenCLLink`"]を使ってロードしなければならない.
  • libfile がダイナミックライブラリである場合には,ダイナミックライブラリ関数 fun がロードされる.
  • 使用できる引数と戻り値の型,および対応するOpenCLの型:
  • _IntegermintWolfram言語整数
    "Integer32"int32ビット整数
    "Integer64"long/long long64ビット整数
    _RealReal_tGPUの実数型
    "Double"double機械倍数
    "Float"float機械浮動小数
    {base, rank, io}OpenCLMemory特定の基底型,階数,入出力オプションのメモリ
    "Local" | "Shared"mintローカルメモリあるいは共有メモリのパラメータ
    {"Local" | "Shared", type}mintローカルメモリあるいは共有メモリのパラメータ
  • 指定{base, rank, io}では,有効な io は,"Input""Output""InputOutput"である.
  • {base}が渡されると,{base,_,"InputOutput"}がデフォルトで使用される.{base,rank}が渡されると,{base,rank,"InputOutput"}が使用される.
  • 引数指定{base}{base,_,"InputOutput"}に等しく,{base,rank}{base,rank,"InputOutput"}に等しい.
  • 階数は,{base,_,io}あるいは{base,io}を使って省略することができる.
  • 使用可能な基底型:
  • _Integer_Real_Complex
    "Byte""Bit16""Integer32"
    "Byte[2]""Bit16[2]""Integer32[2]"
    "Byte[4]""Bit16[4]""Integer32[4]"
    "Byte[8]""Bit16[8]""Integer32[8]"
    "Byte[16]""Bit16[16]""Integer32[16]"
    "UnsignedByte""UnsignedBit16""UnsignedInteger"
    "UnsignedByte[2]""UnsignedBit16[2]""UnsignedInteger[2]"
    "UnsignedByte[4]""UnsignedBit16[4]""UnsignedInteger[4]"
    "UnsignedByte[8]""UnsignedBit16[8]""UnsignedInteger[8]"
    "UnsignedByte[16]""UnsignedBit16[16]""UnsignedInteger[16]"
    "Double""Float""Integer64"
    "Double[2]""Float[2]""Integer64[2]"
    "Double[4]""Float[4]""Integer64[4]"
    "Double[8]""Float[8]""Integer64[8]"
    "Double[16]""Float[16]""Integer64[16]"
  • OpenCLFunctionLoadは,異なる引数を使って2度以上呼び出すことができる.
  • OpenCLFunctionLoadでロードされた関数は,Wolfram言語カーネルと同じプロセスで実行される.
  • OpenCLFunctionLoadでロードされた関数は,Wolfram言語カーネルが終了する際にアンロードされる.
  • ブロック次元はリストあるいは整数でよく,起動するのに各ブロックに対していくつのスレッドが必要であるかを表す.
  • ブロック次元の最大サイズは,OpenCLInformation"Maximum Work Group Size"特性によって返される.
  • 起動時に,スレッドの数が(OpenCLFunctionの追加の引数として)指定されていない場合には,最大の階数と次元を持つ要素の次元が選ばれる.画像については,階数は2に設定される.
  • 起動時に,スレッドの数がブロック次元の倍数ではない場合には,スレッド数はブロック次元の倍数になるようにインクリメントされる.
  • 使用できるオプション:
  • "CompileOptions"{}直接OpenCLコンパイラに渡されるコンパイルオプション
    "Defines"AutomaticOpenCLプリプロセッサに渡される定義
    "Device"$OpenCLDevice計算に使用されるOpenCLデバイス
    "IncludeDirectories"{}コンパイルに含むディレクトリ
    "Platform"$OpenCLPlatform計算に使用するOpenCLプラットフォーム
    "ShellCommandFunction"Noneコンパイルに使用するシェルコマンドで呼び出す関数
    "ShellOutputFunction"Noneコンパイルコマンドを実行したシェル出力で呼び出す関数
    "TargetPrecision"Automatic計算に使用する精度
    "WorkingDirectory"Automatic一時的なファイルが生成されるディレクトリ

例題

すべて開くすべて閉じる

  (5)

まず OpenCLLink アプリケーションをロードする:

ロードするOpenCLソースコードを定義する:

OpenCL関数をロードする:

入力パラメータを定義する:

引数を持つ関数を呼び出す:

ArrayPlotを使って結果をプロットする:

"SupportFiles/vectorAdd.cl"からOpenCLソースファイルへのパスを定義する:

ファイルからOpenCL関数をコンパイルしロードする:

関数を呼び出す:

OpenCLLink ライブラリの例である"addTwo_Dobule"を見付ける:

OpenCLFunctionLoadを使ってライブラリをロードする:

関数は2つを入力リストに加える:

この例のソースコードは OpenCLLink にバンドルされている:

OpenCLFunctionを呼び出す際に追加の引数を与えることができる.引数は,起動するスレッドの数(あるいは大域的な作業グループサイズ)を示す.上の例を使う:

ファイルからOpenCL関数をロードする:

32のスレッドで関数を呼び出す.これにより,vectorAddの最初の32個の値のみが計算される:

コードに構文エラーがあると,"compilation failed(コンパイルの失敗)"というエラーが返される:

"ShellOutputFunction" オプションを使ってビルドログを表示することができる:

上のエラーは,コード中にタイポ(コード中の0の後にz)があることを示す:

スコープ  (2)

テンプレートされた関数  (1)

テンプレートされた関数は,マクロを使ってシミュレーションを行うことができる.未定義のマクロとしてを残す:

コンパイル中にマクロに設定する:

マクロを代りにに設定する:

共有メモリとローカルメモリ  (1)

OpenCLFunctionLoadを使って起動に"Local"メモリと"Shared"メモリのどちらかを指定することができる.以下のコードは,共有メモリを使って勾配計算の大域メモリを保存する:

入力引数を指定し,最後の引数を共有メモリについて"Shared"とする.ブロックの大きさを256と設定する:

グレイスケール画像の平坦化された長さを計算する:

関数を呼び出す.共有メモリの大きさを(blockSize+2)sizeof (int)と設定し,起動スレッド数を画像の平坦化された長さに設定する:

共有メモリの大きさを指定するよりよい方法は,型を使う方法である:

共有メモリの型を使うと,型のサイズを渡す必要がない:

アプリケーション  (10)

画像入力  (1)

入力は画像でもよい.画像間の線形補間を行うコードを書く(これはImageComposeを使って行うこともできる):

上のソースコードからOpenCLFunctionをロードする:

heightwidthchannel の値を設定する.またメモリをoutputに割り当てる:

{width,height}のスレッドで関数を呼び出す:

メモリを得て,画像としてこれを表示する:

上を使って,関数OpenCLImageLinearCombineを作成することができる:

関数はImageComposeと似た構文を持つ:

Manipulateを使って補間係数を操作することができる:

効果が作成できる.以下では滑らかなアニメーションを見ることができる:

一様な乱数生成  (1)

一様な乱数生成器は,多くのアプリケーションにおいてよく見られるシード問題である.OpenCLに一様な乱数生成器を実装する:

ソースをOpenCLFunctionとしてロードする.このアルゴリズムは画像を使って乱数の上限を提供する:

OpenCLFunctionを呼び出す.画像は,指定された適切な型を使って解釈することができる限り,OpenCLFunctionに直接渡すことができる:

以下は通常のアヒルの画像とは異なっている.これはアルファチャンネルが1に(SetAlphaChannelを使って)設定された4チャンネル画像である:

ランダムな出力を使って画像の重要なエッジを検出する:

メルセンヌツイスタを使った乱数生成  (1)

メルセンヌ(Mersenne)ツイスタは,もう一つの一様な乱数生成器アルゴリズムである(上のアルゴリズムよりもこちらの方が高度である).実装は以下の場所にある:

OpenCLFunctionをロード,つまり型_Realを指定する.これは,Realの型はCPUの機能(これが倍数精度をサポートするかどうか)に依存することを意味する:

メルセンヌツイスタの入出力パラメータを設定する(詳細についてはアルゴリズムのページを参照のこと):

OpenCLFunctionを呼び出す:

出力の結果をプロットする:

出力にかかる時間を計る:

ほぼ11倍の速さになったことが分かる:

接頭部和のアルゴリズム  (1)

スキャン,つまり接頭辞の総和のアルゴリズムは,FoldListに似ており,さまざまな場合に使えて大変便利なプリミティブアルゴリズムである.OpenCLの実装は以下の場所にある:

計算に使われる3つのカーネルをロードする:

ランダムな入力データを生成する:

出力バッファを割り当てる:

ブロックとグリッドの次元を計算する:

計算に一時的なバッファが必要である:

スキャン操作を行う:

出力バッファを取り出す:

OpenCLMemory要素を解放する:

行列操作  (1)

行列転置は,多くのアプリケーションにおける基本的なアルゴリズムである.入力を指定する:

OpenCLFunctionをロードする:

OpenCLFunctionを呼び出す:

結果のMatrixFormを示す:

結果はWolfram言語の結果と同じである:

行列乗算  (1)

行列乗算を以下で行う:

ブロックの大きさを定義する:

OpenCLFunctionをロードする.入力が階数2でなければならないことが指定されている:

ランダムな入力を作成し,出力を割り当てる:

OpenCLFunctionを呼び出す:

OpenCLMemoryGetを使って出力メモリを得る:

上の出力はWolfram言語の出力と同じである:

高速フーリエ変換  (1)

一次元の離散高速フーリエ(Fourier)変換は,OpenCLLink を使って実装することができる.この実装は,入力が2のベキであると仮定する:

OpenCLFunctionLoadを使ってOpenCLFunctionをロードする:

入出力リストを作成する:

出力メモリを呼び出して複雑なリストを作成し,最初の50個の要素だけを表示する:

上の結果は,Fourierを使った場合と同じである:

金融派生商品  (1)

ブラック・ショールズ(BlackScholes)は,金融派生商品の投資をモデル化するもので,これはOpenCLに実装されている:

OpenCLFunctionをロードする:

入力パラメータを割り当てる:

OpenCLFunctionを呼び出す:

呼出しの値を得る:

結果はFinancialDerivativeの出力に一致する:

所要時間を見るために,評価されるオプションの数を増やす:

C2050では,2048個のオプションを評価するのに1/100秒かかる:

Core i7 950では,, FinancialDerivative は1.13秒かかる.上は280倍の速さである.オプションの数を増やすと,速さの違いがより大きくなる:

ガウシアンフィルタ  (1)

再帰的なガウス行列がガウシアンフィルタを近似するのに使われる.アルゴリズムは,ガウス行列が分離可能であるという事実に依存している:

一次ガウス行列の外積として書くことができる:

再帰的なガウス行列は以下の場所に実装されている:

OpenCLFunctionLoadを使って2つの関数をロードする:

の値を指定する.ガウス行列は である:

を5.0に設定して正規分布を計算する:

Wolfram言語で分布をプロットすることができる:

再帰的なガウス行列のパラメータを計算する:

入力,出力,一時的なストレッジにOpenCLMemoryを割り当てる:

関数を呼び出す.まず水平にガウス行列を行ってから転置し,次にガウス行列を垂直に行ってから転置し,完全なガウス行列を得る:

データから画像を再構築する:

もう一度所要時間を比べる:

パフォーマンスが4倍高速化したことが分かる:

ソート  (1)

バイトニックソートは,整数の任意集合をソートする.これは原則としてマージソートに似ている.OpenCLの実装は,2のベキの長さのリストのみに使えるもので,以下の場所にある:

入力の長さを設定し,これをロードする.方向は,最高から最低へ,あるいは最低から最高へソートするかを示す.この場合は最低から最高へソートする:

入力リストを得る:

マージソートに似たバイトニックソートを呼び出す.完全ソートを行うためには,複数回呼出しを行う必要がある:

出力リストはソートされた形で取り込まれる:

考えられる問題  (5)

最大作業項目の大きさ(ブロック次元)はOpenCLInformationで返される:

システムによっては,これは1に限られる.

OpenCLコードで倍精度操作を使用するには,コードヘッダに以下のpramasを置く必要がある:

#ifdef USING_DOUBLE_PRECISIONQ
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
#pragma OPENCL EXTENSION cl_amd_fp64 : enable
#endif /* USING_DOUBLE_PRECISIONQ */

関数の呼出しにおけるエラーは,OpenCLLink を使用不可な状態に置くことがある.これはユーザが任意のカーネルを書くことができるようにしたことによる副次的な結果である.カーネルコード内の無限ループ,バッファオーバーフロー等は,OpenCLLink およびビデオドライバを使用不可なものにすることがある.極端な場合には,表示ドライバがクラッシュする場合もあるが,通常はOpenCLコードをさらに評価した場合に無効な結果を返すだけである.

OpenCL実装のバグの中には,"IncludeDirectories"の1つにスペースが含まれていると,カーネルをクラッシュさせるものもある.

__constant等のメモリ修飾子の使用は,OpenCLLink ではサポートされていない.OpenCLFunctionに渡されるメモリは__globalでなければならない.

インタラクティブな例題  (5)

マンデルブロ集合  (1)

マンデルブロ集合は,再帰方程式 は複素数)を満足するすべての点をプロットする.以下ではOpenCLにおいて集合を実装する(滑らかに色の移行が行われるように,少し複雑な色付け方法が使われている):

ジュリア集合  (1)

マンデルブロ集合は,ジュリア集合が制約された形である.以下はジュリア集合のコードである:

入力のメモリとパラメータを定義する:

OpenCLFunctionをロードする:

ジュリア集合を計算し,これをReliefPlotを使ってプロットする:

ジュリア集合を計算し,これをグレイスケール画像として表示する:

画像調整  (1)

ImageAdjustは,画像をスケールし直して高い値と低い値を入力する.ガンマ補正も考慮する.以下では,簡単な形のImageAdjustをOpenCLで定義する:

OpenCLFunctionをロードする:

簡単なWolfram言語ラッパー関数を定義して,OpenCL関数がImageAdjustと似た構文を持つようにする:

0.3から0.8の間の値を0.0から1.0の間の値にスケールし直すことで,画像を調節する:

Manipulateを使って値をスケールし直すことによって画像を調整する:

0.3から0.8の間の値を0.0から1.0の間の値にスケールし直すことで,画像を調節する:

跳ねるボール  (1)

以下の例では,さまざまな初期力で箱の中の各素粒子の位置を計算する.素粒子物理学の部分はOpenCLで行い,残りの作業はすべてWolfram言語で行う:

OpenCLコードを定義して,関数をWolfram言語内にロードする:

n体シミュレーション  (1)

n体シミュレーションは,古典的なニュートン問題である.これをOpenCLで実装する:

OpenCLFunctionをロードする:

素粒子数,時間ステップ,イプシロン距離を選択する:

入出力のメモリを設定する:

NBody関数を呼び出す:

体の点をプロットする:

結果をDynamicで示す:

おもしろい例題  (1)

SymbolicC  (1)

OpenCLLink ではSymbolicCのコード生成機能を使用することができる.SymbolicCを使うには,ユーザはこれをロードしなければならない:

OpenCLLink ではSymbolicCのコード生成機能を使用することができる.ここでは,Wolfram言語文を取って,これをSymbolicC 式に変換するメソッドであるtoSymbolicCを定義する(Wolfram言語のコマンドすべてを変換することはできないが,これらのコマンドをユーザが加えることはできる):

Wolfram言語式は変換することができる:

Cに変換するには,ToCCodeStringを使う:

これを OpenCLLink の記号的コード生成機能に結び付けてOpenCLMapSource関数を作成することができる:

OpenCLMapSourceはWolfram言語の純関数を使うことができる:

コードを使って予め定義されたWolfram言語関数で作業することもできる:

上のコードをOpenCLFunctionLoadを使ってロードする:

関数は評価することができる:

これを一般的なものにするためには,OpenCLMap関数を実装することができる:

関数は評価できる.以下ではaddTwo関数を実装する:

BitNotの演算子を使う:

Wolfram Research (2010), OpenCLFunctionLoad, Wolfram言語関数, https://reference.wolfram.com/language/OpenCLLink/ref/OpenCLFunctionLoad.html.

テキスト

Wolfram Research (2010), OpenCLFunctionLoad, Wolfram言語関数, https://reference.wolfram.com/language/OpenCLLink/ref/OpenCLFunctionLoad.html.

CMS

Wolfram Language. 2010. "OpenCLFunctionLoad." Wolfram Language & System Documentation Center. Wolfram Research. https://reference.wolfram.com/language/OpenCLLink/ref/OpenCLFunctionLoad.html.

APA

Wolfram Language. (2010). OpenCLFunctionLoad. Wolfram Language & System Documentation Center. Retrieved from https://reference.wolfram.com/language/OpenCLLink/ref/OpenCLFunctionLoad.html

BibTeX

@misc{reference.wolfram_2024_openclfunctionload, author="Wolfram Research", title="{OpenCLFunctionLoad}", year="2010", howpublished="\url{https://reference.wolfram.com/language/OpenCLLink/ref/OpenCLFunctionLoad.html}", note=[Accessed: 22-November-2024 ]}

BibLaTeX

@online{reference.wolfram_2024_openclfunctionload, organization={Wolfram Research}, title={OpenCLFunctionLoad}, year={2010}, url={https://reference.wolfram.com/language/OpenCLLink/ref/OpenCLFunctionLoad.html}, note=[Accessed: 22-November-2024 ]}