バッチ ジョブの実行とワーカーからのファイルへのアクセス
batch
を使用して、計算をオフロードしバックグラウンドで実行することができます。
コードでファイルへのアクセスが必要な場合は、'AttachedFiles'
や 'AdditionalPaths'
などの追加オプションを使用して、データをアクセス可能にできます。計算の実行中も MATLAB での作業を続行できます。計算をリモート クラスターに投入すると、MATLAB を閉じて、結果を後で復元できます。
例の準備
サポート関数 prepareSupportingFiles
を使用して、この例に必要なデータを現在の作業フォルダーにコピーします。
prepareSupportingFiles;
これで、現在の作業フォルダーには、A.dat
、B1.dat
、B2.dat
、B3.dat
の 4 つのファイルが含まれています。
バッチ ジョブの実行
parcluster
を使用してクラスター オブジェクトを作成します。既定で、parcluster
は既定のクラスター プロファイルを使用します。既定のクラスター プロファイルは、MATLAB の [ホーム] タブの [環境] セクションの [並列]、[既定のクラスターの選択] で確認します。
c = parcluster();
関数内にコードを配置し、batch
を使用してバッチ ジョブとして投入します。カスタム関数の例については、サポート関数 divideData
を参照してください。必要な出力引数の数と、cell 配列を、関数の入力で指定します。
batch を使用してスクリプト ファイルを送信すると、MATLAB はスクリプトで使用しない場合でも、すべてのワークスペース変数をクラスターに転送します。ワークスペースが大きい場合、これはデータ転送時間に悪影響を及ぼします。ベスト プラクティスとして、スクリプトを関数ファイルに変換することにより、この通信オーバーヘッドを回避します。これを行うには、スクリプトの冒頭に関数の行を単純に追加します。この例では、オーバーヘッドを削減するために divideData
がこのライブ スクリプト外のファイルで定義されています。
コードで並列プールが使用されている場合、名前と値のペアの引数 'Pool'
を使用して、指定した数のワーカーがある並列プールを作成します。batch
は追加のワーカーを使用して関数自体を実行します。
既定では、batch
はワーカーの初期作業フォルダーを、MATLAB クライアントの現在のフォルダーに変更します。これは、ワーカーの初期作業フォルダーの制御に便利な場合があります。たとえば、クラスターの使用しているファイルシステムが異なり (Windows クライアント マシンから Linux クラスターに送信する場合など)、そのためにパスが異なる場合、この制御が必要となることがあります。
ワーカーの初期作業フォルダーを保持し、既定の設定を使用する場合は、
'CurrentFolder'
を'.'
に設定します。初期作業フォルダーを変更するには、
'CurrentFolder'
を目的のフォルダーに設定します。
この例では、3 つのワーカーがある並列プールを使用して、初期作業フォルダーの一時的な場所を選択しています。batch
を使用して、divideData
内の計算をオフロードします。
job = batch(c,@divideData,1,{}, ... 'Pool',3, ... 'CurrentFolder',tempdir);
batch
は並列ワーカー上で divideData
を実行するため、計算の実行中も MATLAB での作業を続行できます。
ジョブが完了するまで MATLAB をブロックする場合は、ジョブ オブジェクトに対して関数 wait
を使用します。
wait(job);
結果を取得するには、ジョブ オブジェクトに対して fetchOutputs
を使用します。divideData
はワーカーが検出できないファイルに依存しているため、fetchOutputs
はエラーをスローします。エラー情報にアクセスするには、ジョブの Task
オブジェクトの Error
プロパティに対して getReport
を使用します。この例では、コードはワーカーが検出できないファイルに依存しています。
getReport(job.Tasks(1).Error)
ans = 'Error using divideData (line 4) Unable to read file 'B2.dat'. No such file or directory.'
ワーカーからのファイルへのアクセス
既定では、batch
は自動的にコードを解析して必要なファイルをワーカーに転送します。場合によっては、これらのファイルを明示的に転送しなければなりません。たとえば、実行時にファイル名を決定する場合などです。
この例では、divideData
はサポート ファイル A.dat
にアクセスします。batch
はこのファイルを自動的に検出および転送します。この関数は B1.dat
にもアクセスしますが、ファイル名は実行時に解決されるため、依存関係の自動分析ではこのファイルは検出されません。
type divideData.m
function X = divideData() A = load("A.dat"); X = zeros(flip(size(A))); parfor i = 1:3 B = load("B" + i + ".dat"); X = X + A\B; end end
ワーカーがアクセスできる場所にデータが存在する場合、名前と値のペアの引数 'AdditionalPaths'
を使用してその場所を指定できます。'AdditionalPaths
' によりこのパスがワーカーの MATLAB 検索パスに追加され、ワーカーがデータを認識できるようになります。
pathToData = pwd; job(2) = batch(c,@divideData,1,{}, ... 'Pool',3, ... 'CurrentFolder',tempdir, ... 'AdditionalPaths',pathToData); wait(job(2));
ワーカーがアクセスできない場所にデータが存在する場合、名前と値のペアの引数 'AttachedFiles'
を使用してファイルをワーカーに転送することができます。クライアントとワーカーが同じファイル システムを共有していない場合や、クラスターで汎用スケジューラ インターフェイスが非共有モードで使用されている場合は、ファイルを転送する必要があります。詳細については、汎用スケジューラ インターフェイスを使用した構成 (MATLAB Parallel Server)を参照してください。
filenames = "B" + string(1:3) + ".dat"; job(3) = batch(c,@divideData,1,{}, ... 'Pool',3, ... 'CurrentFolder',tempdir, ... 'AttachedFiles',filenames);
既存のジョブの検索
ジョブをリモート クラスターに投入すると、ジョブの投入後に MATLAB を閉じて、結果を後で取得できます。MATLAB を閉じる前に、ジョブ ID をメモしておいてください。
job3ID = job(3).ID
job3ID = 25
もう一度 MATLAB を開いたときに、関数 findJob
を使用してこのジョブを検索できます。
job(3) = findJob(c,'ID',job3ID);
wait(job(3));
あるいは、ジョブ モニターを使用してジョブを追跡することもできます。これを開くには、MATLAB の [ホーム] タブの [環境] セクションで [並列]、[ジョブの監視] を選択します。
結果の取得とデータのクリーン アップ
バッチ ジョブの結果を取得するには、関数 fetchOutputs
を使用します。fetchOutputs
は、batch
で実行された関数の出力が含まれる cell 配列を返します。
X = fetchOutputs(job(3))
X = 1×1 cell array
{40×207 double}
必要な出力がすべて取得され、ジョブ オブジェクトがこれ以上必要ではない場合は、ジョブ オブジェクトを削除してデータをクリーン アップし、リソースを不必要に消費しないようにします。
delete(job)
clear job