ドキュメンテーション

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

複数の GPU での MATLAB 関数の実行

この例では、MATLAB コードを複数の GPU で並列に実行する方法を説明します。まずローカル マシンで実行し、次にクラスターにスケール アップします。この例では、サンプル問題としてロジスティック マップ (人口の増加をモデル化した方程式) を使用します。

MATLAB の増加し続ける機能により、マルチ GPU サポートなど、追加コーディングの一切不要な自動並列サポートが提供されています。詳細については、MathWorks 製品での並列計算のサポートを参照してください。たとえば、関数 trainNetwork はニューラル ネットワークの学習および推論用のマルチ GPU サポートを提供しています詳細については、GPU および並列でのビッグ データを使用した深層学習 (Deep Learning Toolbox)を参照してください。

次の手順に従うと、複数の GPU で実行される独自の並列コードを記述する方法がわかります。

単一の GPU の使用

単一の GPU 上で計算を実行するには、gpuArrayオブジェクトを GPU 対応 MATLAB 関数の入力として使用します。GPU 対応関数の詳細については、GPU での MATLAB 関数の実行を参照してください。

増加率 r、人口 x の gpuArray を作成します。gpuArray の作成の詳細については、GPU での配列の確立を参照してください。

N = 1000;
r = gpuArray.linspace(0,4,N);
x = rand(1,N,'gpuArray');

単純なアルゴリズムを使用してロジスティック マップを反復します。このアルゴリズムでは GPU 対応の演算子を gpuArray に使用しているため、計算は GPU 上で実行されます。

numIterations = 1000;
for n=1:numIterations
    x = r.*x.*(1-x);
end

計算の完了後、人口に対して増加率をプロットします。

plot(r,x,'.');

さらに高いパフォーマンスが必要な場合、gpuArray はいくつかのオプションをサポートしています。そのリストについては、関数gpuArrayのページを参照してください。たとえば、この例のアルゴリズムは gpuArray の要素単位の演算のみを行っているため、関数arrayfunを使用して GPU 用にプリコンパイルすることができます。詳細については、GPU での要素単位の MATLAB コードの実行を参照してください。

parfor による複数の GPU の使用

parforループを使用して for ループの反復を複数の並列ワーカーに分散できます。計算で GPU 対応関数を使用している場合、計算はワーカーの GPU で実行されます。例として、モンテカルロ法を使用して人口の変化をランダムにシミュレーションします。このシミュレーションは parfor ループを使用して複数の GPU で並列に計算されます。

使用可能な GPU と同じ数のワーカーをもつ並列プールを作成します。利用可能な GPU の数を調べるには、関数gpuDeviceCountを使用します。既定で、MATLAB は最高のパフォーマンスを得るために各ワーカーに異なる GPU を割り当てます。並列プールにおける GPU の選択の詳細については、並列プールにおける複数の GPU の使用を参照してください。

parpool(gpuDeviceCount);
Starting parallel pool (parpool) using the 'local' profile ...
connected to 2 workers.

シミュレーション回数を定義し、各シミュレーションの人口ベクトルを格納する配列を GPU 内に作成します。

numSimulations = 100;
X = zeros(numSimulations,N,'gpuArray');

parfor ループを使用して、プール内のワーカーにシミュレーションを分散します。ループ内のコードにより初期の人口のランダムな gpuArray が作成され、それに対してロジスティック マップが反復されます。このコードは GPU 対応の演算子を gpuArray に使用するため、計算は自動的にワーカーの GPU で実行されます。

parfor i = 1:numSimulations
    X(i,:) = rand(1,N,'gpuArray');
    for n=1:numIterations
        X(i,:) = r.*X(i,:).*(1-X(i,:));
    end
end

計算の完了後、すべてのシミュレーションの結果をプロットします。それぞれの色は異なるシミュレーションを表します。

figure
plot(r,X,'.');

計算をさらに細かく制御する必要がある場合は、より高度な並列機能を使用できます。たとえば、DataQueueを使用して計算中にワーカーからデータを送信できます。例は、parfor を使用したパラメーター スイープ中のプロットを参照してください。

再現可能な一連の乱数を発生させる場合は、ワーカー GPU での乱数発生を制御できます。詳細については、乱数ストリームの制御を参照してください。

parfeval による複数 GPU の非同期の使用

parfeval を使用すると、並列プール ワーカーで計算を非同期で実行できます。計算で GPU 対応関数を使用している場合、計算はワーカーの GPU で実行されます。たとえば、複数の GPU 上でモンテカルロ シミュレーションを非同期で実行することができます。

ワーカーでの計算完了後の計算結果を保持するために、Future オブジェクトを使用します。各シミュレーションの結果用に Future オブジェクトの配列を事前に割り当てます。

f(numSimulations) = parallel.FevalFuture;

parfeval を使用して計算を実行するには、それらを関数内に配置しなければなりません。たとえば、myParallelFcn には単一のシミュレーションのコードが含まれています。

type myParallelFcn
function x = myParallelFcn(r)
    N = 1000;
    x = gpuArray.rand(1,N);
    numIterations = 1000;
    for n=1:numIterations
        x = r.*x.*(1-x);
    end
end

for ループを使用してシミュレーションをループし、parfeval を使用して並列プール内のワーカーでシミュレーションを非同期で実行します。myParallelFcn は GPU 対応関数を gpuArray に使用するため、それらの関数はワーカーの GPU で実行されます。parfeval は計算を非同期で実行するため、MATLAB はブロックされず、計算の実行中も作業を続行できます。

for i=1:numSimulations
    f(i) = parfeval(@myParallelFcn,1,r);
end

結果の準備ができたときに parfeval から結果を収集するには、Future オブジェクトに対してfetchOutputs (FevalFuture)またはfetchNextを実行します。また、afterEachまたはafterAllを使用して、結果の準備ができたときに自動的に結果に対して関数を呼び出すこともできます。たとえば、各シミュレーションの完了直後にその結果をプロットするには、Future オブジェクトに対して afterEach を使用します。それぞれの色は異なるシミュレーションを表します。

figure
hold on
afterEach(f,@(x) plot(r,x,'.'),0);

クラスターでの複数の GPU の使用

複数の GPU をもつクラスターを使用できる場合は、計算をスケール アップすることができます。関数parpoolを使用して、クラスター上の並列プールを起動します。これにより、parfor ループ、parfeval などの並列機能がクラスター ワーカーで実行されます。計算で gpuArray に GPU 対応関数を使用する場合、これらの関数はクラスター ワーカーの GPU で実行されます。クラスター上での並列機能の実行の詳細については、デスクトップからクラスターへのスケール アップを参照してください。

参考

| | | | | |

関連する例

詳細

外部の Web サイト