複数のデバイスにおける CUDALink
This feature is not supported on the Wolfram Cloud.

Wolfram言語の中核である関数型,およびリスト志向の特性により,CUDALink は組込みの即時データ並列化が提供でき,利用できるGPUカードに自動的に計算を分配する.

はじめに

まず CUDALink アプリケーションをロードする.

In[6]:=
Click for copyable input

デバイス数と同じだけワーカーカーネルを開始する.

In[2]:=
Click for copyable input
Out[2]=

$CUDADeviceCountはシステム上のデバイス数である.

$CUDADeviceCountシステム上のCUDAデバイス数

$CUDADeviceCountはシステム上のCUDA GPUデバイス数を取得する

CUDALink を全ワーカーカーネル上にロードする.

In[3]:=
Click for copyable input

CUDALink は既存のWolfram言語並列計算機能を使って複数のGPU上で実行する.このセクションでは,以下の関数を使う.

ParallelNeedsパッケージを全並列サブカーネルにロードする
DistributeDefinitions並列計算に必要な定義を分配する
ParallelEvaluate利用できる全並列カーネルで入力式を評価して得られた結果のリストを返す

CUDALink はWolfram言語の並列計算機能で複数のGPUを使う

すべてのカーネル上の$CUDADevice変数を設定する.

In[4]:=
Click for copyable input
Out[4]=

CUDALink 関数

画像処理,線形代数,高速フーリエ(Fourier)変換等の高レベル CUDALink 関数は他のWolfram言語関数と同様に異なるカーネルで使用できる.違いは,$CUDADeviceが計算が行われるデバイスに設定されるということだけである.

画像の名前をExampleDataデータ集合から取られるように設定する.

In[5]:=
Click for copyable input

変数をワーカーカーネルに分配する.

In[6]:=
Click for copyable input
Out[6]=

ExampleDataから取られた画像にCUDAErosionを適用する.

In[7]:=
Click for copyable input
Out[7]=

速度が2倍改善されたことに注目されたい.これらの画像は小さく,データは転送されなければならないので,パフォーマンスは4倍は上がらない.

In[8]:=
Click for copyable input
Out[8]=

その他の場合は,データの転送にかかる時間は計算に必要な時間に比べると多くない.ここでは2000のランダムな整数ベクトルを割り当てる.

In[9]:=
Click for copyable input

各デバイスにCUDAFoldをマップする.

In[10]:=
Click for copyable input
Out[10]=

より速度が上がった.

In[11]:=
Click for copyable input
Out[11]=

CUDALink プログラミング

CUDAFunctionは最適化されており,GPUに局所的であるため,DistributeDefinitionsを使ってワーカーカーネルと共有することはできない.このセクションではGPUをプログラムする別の方法を述べる.

2を足す

ベクトルに2を足す基本的なCUDAコードをロードする.

In[12]:=
Click for copyable input

CUDAFunctionをロードする.割当てにSetDelayedが使われている.これにより,DistributeDefinitionsCUDAFunctionLoad呼出しのすべての従属変数を分配することができる.

In[13]:=
Click for copyable input

入力パラメータを設定する.

In[14]:=
Click for copyable input

ワーカーカーネル間に定義を分配する.

In[17]:=
Click for copyable input
Out[17]=

異なるCUDAデバイスを使って各ワーカーカーネルでCUDAFunctionを実行する.

In[18]:=
Click for copyable input
Out[18]=

最初の20要素を示す結果を集める.

In[19]:=
Click for copyable input
Out[19]=

マンデルブロ(Mandelbrot)集合

これは CUDALink ドキュメントの別のセクションで定義されたものと同じCUDAコードである.

In[7]:=
Click for copyable input

CUDAFunctionをロードする.

In[8]:=
Click for copyable input
In[9]:=
Click for copyable input

ワーカーカーネルと変数を共有する.

In[10]:=
Click for copyable input
Out[10]=

それぞれ異なるズームレベルでカーネルを開始し,画像を返す.

In[24]:=
Click for copyable input
Out[24]=

乱数生成器

以下のファイルにメルセンヌツイスタ(Mersenne Twister)が実装されている.

In[25]:=
Click for copyable input
Out[25]=

関数をWolfram言語にロードする.

In[26]:=
Click for copyable input

CUDAFunctionのための入力変数を設定する.

In[27]:=
Click for copyable input

関数と入力パラメータをを分配する.

In[32]:=
Click for copyable input
Out[32]=

シードの値を割り当てる.乱数が相関性を持たないようにするために,シードの評価は各ワーカーカーネルで行われなければならないことに注意.出力メモリも割り当てられ,計算が行われ,結果が可視化される.

In[33]:=
Click for copyable input
Out[33]=

メモリ

CUDAMemoryはカーネルとそれがロードされているデバイスの両方に結び付けられているため,ワーカーカーネルには分配できない.

マスターカーネルにメモリをロードする.

In[34]:=
Click for copyable input
Out[34]=

それから定義を分配する.

In[35]:=
Click for copyable input
Out[35]=

分配されたCUDAMemoryはワーカーカーネルによって操作することはできない.

In[36]:=
Click for copyable input
Out[36]=

メモリはParallelEvaluateを使ってワーカーカーネルにロードできる.

In[37]:=
Click for copyable input
Out[37]=

ParallelEvaluateを使ってメモリ上でさらに処理を行う.

In[38]:=
Click for copyable input
Out[38]=

帯域幅

場合によっては,データの転送に費やす時間が計算に必要な時間より多くなることがある.

大きなリストをロードする.

In[39]:=
Click for copyable input

並列処理では大きなリストをワーカーカーネルと共有しなければならないので,直列処理を行う場合より大幅に時間がかかる.

In[40]:=
Click for copyable input
Out[40]=

データを転送する必要がない直列処理の方が速い.

In[41]:=
Click for copyable input
Out[41]=