並列ワーカーへの配列の分散
分散配列を使用したワーカー間でのデータの分割
データがメモリに収まるかどうかに応じて、次の方法のいずれかを選択します。
データが現在ローカル マシンのメモリにある場合は、関数
distributed
を使用して、既存の配列をクライアント ワークスペースから並列プールのワーカーに分散することができます。このオプションは、repmat
のように配列のサイズを大幅に増加させる操作のテストや、その操作の実行前に有用です。データがローカル マシンのメモリに収まらないが、クラスターのメモリには収まる場合、
datastore
を関数distributed
と併用して、並列プールのワーカーのメモリにデータを読み込むことができます。データがクラスターのメモリに収まらない場合、
datastore
をtall
配列と併用してデータをチャンクに分割し、処理することができます。tall 配列およびデータ ストアを使用するビッグ データのワークフローも参照してください。
datastore
を使用した分散配列の並列読み込み
データがローカル マシンのメモリに収まらないが、クラスターのメモリには収まる場合、datastore
を関数 distributed
と併用して分散配列を作成し、ワーカー間でデータを分割することができます。
次の例では、datastore
を使用して分散配列を作成し、読み込む方法を説明します。航空会社のフライト データの表形式ファイルを使用して、データ ストアを作成します。このデータセットは小さすぎるため、ワーカー間でデータが均等に分割されません。大規模なデータセットをシミュレートするため、repmat
を使用してデータ ストアのサイズを人為的に増加します。
files = repmat({'airlinesmall.csv'}, 10, 1);
ds = tabularTextDatastore(files);
例の変数を選択します。
ds.SelectedVariableNames = {'DepTime','DepDelay'}; ds.TreatAsMissing = 'NA';
データ ストアを並列で読み取ることにより分散テーブルを作成します。ワーカーごとに 1 パーティションとなるように、データ ストアを分割します。これにより、各ワーカーは対応するパーティションからすべてのデータを読み取ります。ファイルは、ワーカーがアクセスできる共有場所になければなりません。
dt = distributed(ds);
Starting parallel pool (parpool) using the 'Processes' profile ... connected to 4 workers.
分散テーブルに関する概要情報を表示します。
summary(dt)
Variables: DepTime: 1,235,230×1 double Values: min 1 max 2505 NaNs 23,510 DepDelay: 1,235,230×1 double Values: min -1036 max 1438 NaNs 23,510
tall table のサイズを求めます。
size(dt)
ans = 1235230 2
dt
の最初の数行を返します。
head(dt)
ans = DepTime DepDelay _______ ________ 642 12 1021 1 2055 20 1332 12 629 -1 1446 63 928 -2 859 -1 1833 3 1041 1
最後に、各ワーカーが読み込んだデータ量をチェックします。
spmd, dt, end
Worker 1: This worker stores dt2(1:370569,:). LocalPart: [370569×2 table] Codistributor: [1×1 codistributor1d] Worker 2: This worker stores dt2(370570:617615,:). LocalPart: [247046×2 table] Codistributor: [1×1 codistributor1d] Worker 3: This worker stores dt2(617616:988184,:). LocalPart: [370569×2 table] Codistributor: [1×1 codistributor1d] Worker 4: This worker stores dt2(988185:1235230,:). LocalPart: [247046×2 table] Codistributor: [1×1 codistributor1d]
データはワーカーに均等に分割されています。datastore
の詳細については、データストアとはを参照してください。
ビッグ データのワークフローの詳細については、並列計算の解決策の選択を参照してください。
分散配列および対話型分散配列を作成する代替方法
データがローカル マシンのメモリに収まる場合は、分散配列を使用してワーカー間にデータを分割できます。関数 distributed
を使用して MATLAB クライアントに分散配列を作成し、開いている並列プールのワーカーにそのデータを格納します。分散配列は単一の次元内で、その次元に沿ってできるだけ均等にワーカー間に分散されます。分散配列を作成する際、分散の詳細は制御できません。
分散配列は、いくつかの方法で作成できます。
関数
distributed
を使用して、既存の配列をクライアント ワークスペースから並列プールのワーカーに分散する。任意の関数
distributed
を使用して、ワーカーに分散配列を直接作成する。この手法では配列があらかじめクライアントに存在している必要がないため、クライアント ワークスペースのメモリ要件が少なくて済みます。関数には
やeye
(___,'distributed')
などがあります。完全な一覧については、rand
(___,'distributed')distributed
オブジェクトのリファレンス ページを参照してください。spmd
ステートメント内に対話型分散配列を作成し、spmd
ステートメント外で分散配列としてその配列にアクセスする。この手法では、既定以外の分散スキームを使用できます。
最初の 2 つの手法では、配列の作成に spmd
が関わっていませんが、この方法で作成された配列を spmd
を使用して操作することができます。以下に例を示します。
クライアント ワークスペースで配列を作成し、それを分散配列にします。
parpool('Processes',2) % Create pool W = ones(6,6); W = distributed(W); % Distribute to the workers spmd T = W*2; % Calculation performed on workers, in parallel. % T and W are both codistributed arrays here. end T % View results in client. whos % T and W are both distributed arrays here. delete(gcp) % Stop pool
別の方法として、関数 codistributed
を使用できます。これにより、次元や分割など、より多くのオプションを制御できますが、多くの場合はより複雑になります。codistributed
配列は、spmd
ステートメント内または通信ジョブ内のいずれかで、ワーカー自体で実行することにより作成できます。codistributed
配列の作成時に、次元や分割など、分散のあらゆる特徴を制御できます。
分散配列と対話型分散配列の関係は観点の 1 つです。対話型分散配列は、それを作成または操作するコードの実行元となるワーカーの間で分割されます。クライアントで分散配列を作成すると、spmd
ステートメント内で対話型分散配列としてこの配列にアクセスできます。spmd
ステートメント内で対話型分散配列を作成すると、クライアント内では分散配列としてこの配列にアクセスできます。spmd
ステートメントを使用した場合のみ、同じ配列データに 2 つの異なる観点からアクセスできます。
codistributed
配列は複数の方法で作成できます。
spmd
ステートメントまたは通信ジョブ内で、関数codistributed
を使用して、そのジョブを実行するワーカーに既に存在しているデータを対話型で分散する。任意の対話型分散関数を使用して、対話型分散配列をワーカーに直接作成する。この手法では、ワーカーにあらかじめその配列が存在している必要がありません。関数には
やeye
(___,'codistributed')
などがあります。完全な一覧については、rand
(___,'codistributed')codistributed
オブジェクトのリファレンス ページを参照してください。spmd
ステートメント外で分散配列を作成し、同じ並列プールで実行されるspmd
ステートメント内でその配列に対話型分散配列としてアクセスする。
既定ではない分散スキームを使用して、spmd
ステートメント内で対話型分散配列を作成します。まず、3 番目の次元に沿って 1 次元の分散を定義し、ワーカー 1 に 4 つの部分、ワーカー 2 に 12 の部分を割り当てます。続いて、ゼロからなる 3×3×16 の配列を作成します。
parpool('Processes',2) % Create pool spmd codist = codistributor1d(3,[4,12]); Z = zeros(3,3,16,codist); Z = Z + spmdIndex; end Z % View results in client. % Z is a distributed array here. delete(gcp) % Stop pool
対話型分散配列の詳細については、対話型分散配列の取り扱いを参照してください。
参考
distributed
| codistributed
| tall
| datastore
| spmd
| repmat
| eye
| rand