リモート定義

並列カーネルはマスターカーネルで定義されている値にも,ローカルで定義されている関数にもアクセスすることができない.

Wolfram言語にはコマンドDistributeDefinitionsが含まれており,これにより全並列カーネルへのローカルの変数と定義の移送が簡単になる.この方法の主な利点は,リモートカーネルにアプリケーションパッケージをインストールする必要がないということである.すべての定義は,既存の接続を使ってリモートカーネルに送信される.

定義を分配する

DistributeDefinitions[s1,s2,]シンボル si の全定義をすべてのリモートカーネルに分配する
DistributeDefinitions["Context`"]特定のコンテキストの全シンボルの定義を分配する

定義の分配

DistributeDefinitionsはシンボルの評価を避けるために属性HoldAllを持つ.

DistributeDefinitionsOwnValuesDownValuesSubValuesUpValuesDefaultValuesNValuesのような定義をエキスポートする.

DistributeDefinitionsはリモートシンボルの属性を,ProtectedLocked等の属性を除き,ローカルで定義された属性と等しくなるように設定する.

リモート側に存在していた古い定義はすべて,新しい定義が行われる前にクリアされる.

いくつかの並列カーネルを開始する.
変数に値,関数に属性を定義する.
以下の評価に示すように,リモートカーネルはシンボルvarを知らない.
細かい点であるが,次のリモート評価は,シンボルがリモート側で定義されていないにもかかわらず,うまく動作しているように見える.

このように見えるのは,関数と変数がリモートカーネルで定義されていないので,リモートカーネルは未評価の式func[var]を返すからである.マスターカーネルは返された結果をさらに評価するが,これは順次行われる.

リモートおよびローカルでの評価の違いが明らかになる例は簡単に作成できる.

ローカルカーネルでシンボルvarは評価されて5になり,5HeadIntegerである.
リモートカーネルではvarはシンボルのままで,頭部はSymbolである.
ローカルの定義はリモートカーネルにエキスポートすることができる.
これで,リモート評価もローカルの場合と同じ結果となる.

定義の自動分配

ParallelizeParallelTableParallelSum等のより高レベルの並列コマンドは,引数として現れるシンボルの定義を自動的に分配する.

次の並列表において,関数fと反復境界nはサブカーネルで評価されるので,うまく動作するようにするためには,これらの定義が分配されなれなければならない.

この自動分配は同じノートブック内でインタラクティブに定義したあらゆる関数と変数について(厳密には,デフォルトコンテキストの全シンボルについて)行われる.パッケージの関数等,他のコンテキストの定義は,自動的には分配されない.

デフォルトコンテキスト以外のコンテキストのシンボルctx`sは自動的には分配されない.
そのため,シンボルはリモートカーネルから評価されずに返される.並列計算終了後にのみ評価され,$KernelIDはゼロである.
このようなシンボルはDistributeDefinitionsを使って分配できる.

コンテキストを分配する

DistributeDefinitions["Context`"]は全シンボルの定義をすべて指定のコンテキストにエキスポートする.そのため,以下を使ってインタラクティブに入力されたすべての定義をリモートカーネルに知らせることができる.

ロードしたパッケージのコンテキストをエキスポートしても,リモートカーネルでは各リモートカーネルでパッケージをロードしたのと同じ効果が得られないことがある.これは,パッケージをロードすると,ある初期化が行われ,これにより他のコンテキスト(プライベートコンテキスト等)の補助的な関数も定義されることがあるからである.また,パッケージは追加の補助的なパッケージもロードすることがあり,そのようなパッケージは独自のコンテキストを構築する.

DistributeDefinitions["Context`"]はリモートカーネルで使うように明示的に設定した定義のコンテキストのエキスポートに便利である.パッケージのリモートのロードのために別のコマンドParallelNeedsがある.

Parallel`Developer`ClearKernels[]はリモートカーネルのGlobal`コンテキストの定義をすべてクリアする.

リモートカーネルにパッケージをロードする

ParallelNeeds["Context`"]利用できる全並列カーネルでNeeds["Context`"]を評価する

パッケージのロード

ParallelNeeds["Context`"]は基本的にはParallelEvaluate[Needs["Context`"]]と同じであるが,これは記憶され,その後新しく起動したリモートカーネルも初期化される.

ロードしたパッケージのコンテキストをエキスポートしても,リモートカーネルでは各リモートカーネルでパッケージをParallelNeeds[]でロードしたのと同じ効果が得られないことがある.これは,パッケージをロードすると,ある初期化が行われ,これにより他のコンテキスト(プライベートコンテキスト等)の補助的な関数も定義されることがあるからである.また,パッケージは追加の補助的なパッケージもロードすることがあり,そのようなパッケージは独自のコンテキストを構築する.

次の2つのコマンドはWolfram言語パッケージFiniteFields`をマスターカーネルと全リモートカーネルにロードする.

マスターカーネルで利用できるWolfram言語パッケージは古いバージョンのWolfram言語のリモートカーネルでは利用できないことがある.

例:行列の固有値

定義

パラメータprec× の乱数行列の固有値の計算に希望する精度を与える.
関数matは数値要素を持つ × の乱数行列を生成する.
関数tfは固有値を求めるのに必要な時間を測定する.
メインの関数tfの定義を分配するので十分である.これに影響する値はすべて自動的に分配される.

実行例

5×5から25×25の行列の固有値を求めるのに必要な時間を測定する.計算はプロセッサの速さが異なるリモートコンピュータで行われることがあるので,結果は必ずしも増加列になるとは限らない.
別の方法として,各並列プロセッサで同じ計算を行い,相対速度を測定する.ここでは,20×20の行列の固有値を各並列プロセッサで計算した場合の速度である.