(57)【要約】【課題】計算的な解を見出すよう構成されたコンピューティング・システムにおけるフォールトトレランスを改善する方法を提供する。【解決手段】計算的な解を見出すよう構成されたコンピューティング・システムにおけるフォールトトレランスを改善する方法であって：階層をなす少なくとも二つの異なるソルバを並列に使うことによって前記解の少なくとも二つのバージョンを計算する段階と；あるソルバの実行の際に障害があって欠けている値が生じる場合、階層においてより低位のソルバからの値を代用してその欠けている値を置換する段階とを含む、方法。【選択図】図１
2014229307.tif 000002
【特許請求の範囲】
【請求項１】
計算的な解を見出すよう構成されたコンピューティング・システムにおけるフォールトトレランスを改善する方法であって：
階層をなす少なくとも二つの異なるソルバを並列に使うことによって前記解の少なくとも二つのバージョンを計算する段階と；
あるソルバの実行の際に障害があって欠けている値が生じる場合、階層においてより低位のソルバからの値を代用してその欠けている値を置換する段階とを含む、
方法。
【請求項２】
二つの異なるソルバがより精度の高いソルバおよびより精度の低いソルバであり、
前記より精度の高いソルバの実行の際に障害があって欠けている値が生じる場合、前記より精度の低いソルバからの値が前記より精度の高いソルバにおいてその欠けている値を置換するために代用される、請求項１記載の方法。
【請求項３】
前記コンピューティング・システムが複数の処理ユニットを有しており、好ましくは、前記より精度の低いソルバは前記より精度の高いソルバよりも少数の処理ユニット上で実行される、請求項１または２記載の方法。
【請求項４】
各ソルバは前記コンピューティング・システム上でホストされるある数のプロセスにおいて実行され、前記より精度の低いソルバのほうがより少数のプロセスに分割され、好ましくは、前記より精度の低いソルバのプロセスが、両方のソルバについてのプロセスの総数の20%未満、より好ましくは10%未満、最も好ましくは1%未満に相当する、請求項２または３記載の方法。
【請求項５】
前記の値の代用は、前記値が欠けているソルバにおける計算中に代入するために階層においてより低位のソルバからの現在値を与えるよう、制御アプリケーションによって管理される、請求項１ないし４のうちいずれか一項記載の方法。
【請求項６】
前記コンピューティング・システムが複数CPUシステムであり、好ましくはハイ・パフォーマンス・コンピューティング（HPC）システムである、請求項１ないし５のうちいずれか一項記載の方法。
【請求項７】
前記より精度の低いソルバが、前記より精度の高いソルバよりも、前記解を計算するためにより計算集約的でない近似を使う、請求項２ないし６のうちいずれか一項記載の方法。
【請求項８】
前記解の三つ以上の異なるバージョンが、異なる精度レベルの三つ以上のソルバの階層を使って計算され、当該方法が：
すべてのソルバを並列に使うことによって前記解の三つ以上のバージョンを計算する段階と；
それらのソルバの実行中に、より精度の低いソルバからの値を代用して、階層において前記より精度の低いソルバより階層において一レベル上の前記より精度の高いソルバにおける欠けている値を置換する段階とを含む、
請求項１ないし７のうちいずれか一項記載の方法。
【請求項９】
それらのソルバの実行中に、階層においてより高位の前記ソルバからの、あるいは階層においてより低位のソルバについての重複ソルバからの値を代用して、階層においてより低位の前記ソルバにおける、そのソルバの実行における障害から帰結する欠けている値を置換することを含む、請求項１ないし８のうちいずれか一項記載の方法。
【請求項１０】
前記より精度の高いソルバの方法論は、その計算にわたっての値の定期的な同期を含み、前記より精度の低いソルバは、前記より精度の高いソルバからの最も最近に同期された値を用いて定期的にリフレッシュされる、請求項２ないし９のうちいずれか一項記載の方法。
【請求項１１】
階層においてより低位の前記ソルバが数値的に不安定な方法を使う、請求項１ないし１０のうちいずれか一項記載の方法。
【請求項１２】
前記欠けている値が、前記コンピューティング・システムの処理ユニットの間の連絡不良のため、あるいは前記コンピューティング・システムのある処理ユニットにおける失敗した計算のためである、請求項１ないし１１のうちいずれか一項記載の方法。
【請求項１３】
メッセージ渡しインターフェースからの通知の受領による、あるいはソルバ自身の内部での検出による障害の検出をさらに含む、請求項１ないし１２のうちいずれか一項記載の方法。
【請求項１４】
相互接続によってリンクされた複数の処理ユニットを有しており、少なくとも二つの異なるソルバの階層を使って並列に計算的な解の少なくとも二つのバージョンを見出すよう構成されたコンピューティング・システムであって：
前記処理ユニットのより小さな部分集合が階層においてより低位のソルバを使って前記解の一つのバージョンを計算するよう構成されており、前記処理ユニットのより大きな部分集合が階層においてより高位のソルバを使って前記解の他方のバージョンを計算するよう構成されており、
前記階層においてより高位のソルバの実行の際に障害があって欠けている値が生じる場合、前記相互接続は、前記諸ソルバの実行中に、前記階層においてより低位のソルバからの値を代用して前記欠けている値を置換するよう構成されている、
システム。
【請求項１５】
コンピューティング・システム上で実行されたときに方法を実行するコンピュータ・プログラムであって、前記方法は：
異なるソルバの階層を使って計算的な解の少なくとも二つのバージョンを並列に計算する段階と；
あるソルバの実行の際に障害があって欠けている値が生じる場合、階層においてより低位のソルバからの値を代用して前記欠けている値を置換する段階と；
階層においてより高位の前記ソルバの解を、前記計算的な解として使う段階とを含む、
コンピュータ・プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、コンピューティング・システムにおける障害耐性（fault  resilience）に関する。障害耐性のあるコンピュータ・プログラムは、たとえば単純な計算から画像レンダリングおよび大規模かつ複雑なシミュレーションまで、オンザフライおよびオフライン処理を含め、幅広い範囲の応用領域において必要とされている。一つの重要な例として、ミッションクリティカルなジョブ（たとえば実用天気予報）またはシステム（たとえばインターネット）は障害に対して耐性をもつ必要がある。本発明は、こうした応用領域の全領域に向けられており、特に、データが多数のCPUに分散される非常に大規模なハイ・パフォーマンス・コンピューティング・システム上で走る分散式の並列コンピュータ・プログラムに焦点を当てる。
【背景技術】
【０００２】
計算集約的なアプリケーションは通例、ハイ・パフォーマンス・コンピュータ・システム上で実行される。そのようなハイ・パフォーマンス・コンピュータ（HPC:  high  performance  computer）システムはしばしば、複数の処理ユニットまたはコアがあってその上で実行可能物の処理スレッドが並列して自律的に走ることのできる分散環境を提供する。
【０００３】
多くの異なるハードウェア構成およびプログラミング・モデルがハイ・パフォーマンス・コンピューティングに適用可能である。現在、ハイ・パフォーマンス・コンピューティングに対するポピュラーなアプローチは、それぞれが一つまたは複数のマルチコア・プロセッサ（または「チップ」）をもつ複数のノードが高速ネットワークによって相互接続されるクラスター・システムである。各ノードは、そのノード内のすべてのコアにとってアクセス可能である独自のメモリ領域をもつと想定される。クラスター・システムは、一般的な機能を実行するための既存のコード・ライブラリを利用してソース・コードを書く人間のプログラマーによってプログラミングされることができる。次いで、ソース・コードは、特定の命令セットを有するプロセッサ・タイプによって実行されることのできる低レベルの実行可能コード、たとえばISA（Instruction  Set  Architecture［命令セット・アーキテクチャ］）レベルのコードに、あるいは特定のプロセッサ専用のアセンブリ言語にコンパイルされる。しばしば、アセンブリ・コードを実行可能な機械語コードにアセンブルする（または仮想マシンの場合にはインタープリットする）最終段がある。アプリケーションの実行可能形式（時に単に「実行可能物」と称される）は、オペレーティング・システム（OS）の監督の下で実行される。
【０００４】
複数のコアをもつコンピュータ・システムのためのアプリケーションは、通常のコンピュータ言語（C/C++またはフォートランなど）をプログラマーが複数コアの並列処理能力を活用できるようにするライブラリによって補強したもので、書くことができる。これに関し、コアの上で実行されている「プロセス」という言い方をするのが通常である。（複数スレッドの）プロセスは、多コアCPU内のいくつかのコアを横断して走ることがありうる。一つのそのようなライブラリはメッセージ渡しインターフェース（MPI:  Message  Passing  Interface）である。これは分散式メモリ・モデルを使い（各プロセスが独自のメモリ領域をもつと想定される）、プロセスどうしの間での通信を容易にする。MPIは、プロセスのグループを定義および区別できるようにし、いわゆる「バリア同期（barrier  synchronization）」のためのルーチンを含む。これは、複数のプロセスまたは処理要素が協働できるようにするための重要な機能である。バリア同期は、プログラム内のすべてのプロセスが同じ点に到達するまで、該プログラムを実行する同期グループ内のすべてのプロセスを待たせる技法である。これは、MPI関数コールによって達成される。これがグループのすべてのメンバーによってコールされてはじめて実行は先に進むことができる。
【０００５】
あるいはまた、共有メモリ並列プログラミングでは、すべてのプロセスまたはコアは同じメモリまたはメモリの同じ領域にアクセスできる。共有メモリ・モデルでは、プロセス間のデータの通信を明示的に指定する必要はない（あるプロセスによってなされるいかなる変更も他のすべてのプロセスに対して透明だから）。しかしながら、一時に一つのプロセスのみがデータを修正できることを保証するために、共有メモリへのアクセスを制御することが必要になることがある。OpenMPのような「スレッドのある（threaded）」共有メモリ・プログラミング・モデルでは、単一のプロセスが複数の、並行した実行経路をもつことができる（可能性としては物理的なコア一つ当たり一つの実行スレッドが該プロセスに対して利用可能）。
【０００６】
最新世代のスーパーコンピュータは何十万、またさらには何百万ものコアを含む。10Pflop/sを越える実効性能をもつ2012年11月のTOP500リストにある三つのシステムは、560,640個（タイタン）、1,572864個（セコイア）および705,024個（京）のコアを含む。ペタスケールからエクサスケールへと進むに当たり、主要なパフォーマンス上の利得は、システムにおけるコアの総数が一億以上に増加することから帰結することになる（コア当たりのフロップ数の増加は見込めない）。システム内のノード数が増すにつれて（特に受け容れ可能なパワー・エンベロープを維持するために低コスト、低エネルギーのノードが使われる場合には）、システムの平均コンポーネント故障寿命（mean-time-to-component-failure）が短くなる――最終的にはシステム上で実行される平均的なシミュレーションより短い時間になってしまう。よって、エクサスケール・ソフトウェアとしてはコンポーネント障害に対する耐性が必要になる。
【０００７】
故障耐性のあるエクサスケール・アプリケーション・ソフトウェアを達成するために使用されうるいくつかの方法があり、次のようなものが含まれる。
・アプリケーションに不可視な仕方でコンポーネント障害に自動的に対処するようMPIを改善。
・一つ（または複数）のMPIタスクが実行中に障害を受ける場合にソフトウェアが補償できるようソフトウェア内で実装できる新しいアルゴリズムを開発。
・大規模並列シミュレーションに対して、障害直前の点から再開できるよう、頻繁に（かつ迅速に）チェックポイント生成するための改善された方法。
・タスクが二つ以上の処理要素によって同一の形で実行されるような作業の複製――一つの処理要素に障害があっても一般には他からの結果がいまだ利用可能になる。
・再割り当てのあるタスク・プールの使用。マスター・プロセスが独立した諸タスクの実行の調整をし、もともと作業を割り当てられたプロセッサに障害があった場合にタスクを割り当て直すことができる。
【０００８】
こうした従来技術の方法のそれぞれには問題がある。障害に対する自動的なMPI応答は、特定の用途に対しては最適でないことがあり、そのため開発者はどのように障害に対処するかの制御を保持したいことがある。チェックポイント生成（特に非常に大規模なシステムでの）は時間がかかり、――チェックポイントが予定されている直前に（またはチェックポイントの最中に）障害が発生する場合には――大量の計算を繰り返さなければならないことになりうる。作業の複製も高価である――故障耐性のためにプログラム機能全体が複製されなければならないとすると――事実上、利用可能なコンピューティング・パワーは半分になる。再割り当てのあるタスク・プールはそれほど多くの作業を複製する必要は回避するが、いくつかのアプリケーション（特にエクサスケールのシステムで実行されることが予期される非常に大規模なアプリケーション）については、作業を十分細かい粒度の独立したタスクに分割することが可能でないことがありうる。
【０００９】
本発明者は、組み合わせ方法に基づくアルゴリズム・ベースのフォールトトレランスについての関連技術の方法を知っている。この方法では、組み合わせ方法はソルバ内で障害を克服するために使われる：いくつかの粗いグリッド上で解が計算され、それらが組み合わされてより正確な解を生成する。どれか一つのグリッドでのコンポーネント障害は組み合わされた解の精度を低下させるが、既知の許容度（tolerance）の範囲内でしかない。しかしながら、この方法にも欠点がある。特に、
・シミュレーションにおいて根底にグリッドがあることを前提としている。これは一般的な応用について必ずしも成り立たない。
・あるノードの障害は、他のノードも解に貢献できないことにつながる（それに、障害のあったノードが作業していた粗いグリッド上で解を計算している諸ノードが使用されない）。多数の粗いグリッドがあればこれは重要な問題ではないこともありうるが、一般に、アプリケーションは利用可能なすべての資源を活用することを望むであろう。
【発明の概要】
【発明が解決しようとする課題】
【００１０】
複数のプロセッサ上で走るシミュレーションが、たとえプロセッサのうちの一つ（または複数）が障害を受けたとしても、完了まで実行される（そして十分な精度を保持する）ことを可能にすることが望ましい。このことは、シミュレーションのようなアプリケーションが何百万ものプロセッサを使って実行されることが必要とされ、シミュレーションの実行中に少数の障害が生じる可能性が高いエクサスケール・コンピューティングにおいて特に適用可能であろう。
【００１１】
本発明は、ソフトウェアが障害に対処できるようにするよう実装されることができる新たな方法論を提案する。
【課題を解決するための手段】
【００１２】
本発明のある側面の諸実施形態は、計算的な解を見出すよう構成されたコンピューティング・システムにおけるフォールトトレランスを改善する方法であって、階層をなす異なるソルバを並列に使うことによって解の少なくとも二つのバージョンを計算する段階と；階層においてより高位のソルバの実行の際に障害があって欠けている値が生じる場合には階層においてより低位のソルバからの値を代用して欠けている値を置換する段階とを含む、方法を提供する。
【００１３】
本発明者は、本願において、たとえシステムの一つ（または複数）のノード、コア、CPU、FGPA、GPUまたは他の処理ユニットが故障したとしても、アプリケーションが完了まで実行されることを許容する、HPCソフトウェアのようなコンピューティング・ソフトウェア内のソルバ内で実装されることのできる方法論を提案する。本願での用語「ソルバ」は必ずしも数学的な方程式の解に対するものではなく、任意の計算（たとえばデータ処理または画像レンダリング）に対して等しく当てはまりうることを注意しておく。
【００１４】
アルゴリズム・ベースのフォールトトレランス（ABFT:  algorithm-based  fault-tolerance）は現行の研究領域であり、この研究の一部はグリッドを使うアプリケーションのためのものである（たとえば、有限な要素、有限な体積および有限差分法による偏微分方程式（partial  differential  equations）PDEの解）。そのようなABFTの発展は、より粗い諸グリッド上で複数の問題を解き、それらを組み合わせてより正確な結果を作り出すという可能性をもつ。これにより、障害を経験するグリッドは最終的な解において破棄されることができる。しかしながら、そのような方法は、グリッドに基づくのでないアプリケーション（たとえば、計算流体力学（CFD:  computational  fluid  dynamics）または計算化学において使われる粒子ベースの方法）には直接適用することができない。本発明は、グリッドを使わないものも含めHPCおよび他のアプリケーションと一緒に使う、汎用の、フォールトトレラントな方法論である。
【００１５】
本発明者は、フォールトトレラントなアプリケーション実行に関係する主要な技術的問題は、ノードまたは他の処理ユニットが故障したときのデータの喪失に関するという認識に至った。これはそのデータを通信できないことにつながる。計算を改めて開始することは、障害直前のデータが利用可能であれば比較的簡単であろう。多くの分散式のアプリケーションでは、各プロセスはアルゴリズム内の相互に関係したタスクを実行しており、他のプロセスからのデータの頻繁な通信はアルゴリズムの枢要な部分である。あるプロセスが障害を起こしたとすると、他のプロセスは、そのプロセスから受け取ることを期待していた情報の欠如にどのように対処できるだろうか。第二の技術的問題は、アプリケーションが障害のあったプロセスで実行されることを期待している計算の完了に関する。たとえこのプロセスに要求されるさらなる通信がなかったとしても、その出力は全体的な解の一部をなし、アプリケーションが成功裏に完了するためにはそれを生成し直さなければならない。
【００１６】
フォールトトレランスは現在のところMPI規格（http://www.mpi-forum.org/docs/）の一部ではない。しかしながら、上述したように、さまざまなフォールトトレラントなMPI実装が存在する（たとえば、フォールトトレランスはOpenMPI（http://www.open-mpi.org）の一部である）。一般に、これらは自動化されたチェックポイント・リスタートおよびメッセージ・ログ記録の技術に基づいており、アプリケーション実行の低速化を招く。ひとたび障害が同定されたら、最後のチェックポイント以降の、障害のあったプロセス上のすべての計算および該プロセスとの間のすべての通信を繰り返す必要がある。それが行なわれている間、残りのプロセスは待たなければならない（障害のあったプロセスから要求されるメッセージを受け取るまで進行できないので）。
【００１７】
よって、アプリケーションが障害を認識して該障害から回復できてもよい、発明実施形態に基づくアルゴリズム・ベースのフォールトトレランスは、フォールトトレラントなMPI実装を強化するために貴重である（それでも、フォールトトレラントなMPIは、アプリケーションに障害を通知し、障害のあるノードの秩序立ったシャットダウンを保証するために使われてもよい）。
【００１８】
発明実施形態は異なる複数のソルバを含む階層を使う。すなわち、各ソルバは同じように機能するのではなく、他のソルバとは異なる方法を使う。そのため、ソルバの重複はない。階層においてより高位のソルバはよりよい結果を与え、求解のために使用される。一方、階層においてより低位のソルバは本質的には障害耐性用である。たとえば、階層において二つのソルバがあって、その一方が好ましい方法論を使うことによりよりよい結果を与えるのでもよい。
【００１９】
好ましい諸実施形態では、二つの異なるソルバはより精度の低いソルバとより精度の高いソルバであり、より精度の高いソルバの実行中に障害があって欠けている値が生じた場合、より精度の低いソルバからの値が代用されて欠けている値を置換する。
【００２０】
階層においてより低位のソルバがより精度が低い場合、障害耐性のために必要とされる資源は、二つの同一のソルバによる等価な冗長な実装のために必要とされるよりも、かなり少なくなりうる。アプリケーションによって最終的に使われる解は、当然ながら、階層においてより高位の、より精度の高いソルバの解である。
【００２１】
より精度の低いソルバからの値の代用は、好ましくは、階層において隣接するより低位のソルバからであるが、二つより多いソルバのあるいくつかの実施形態では、該隣接するより低位のソルバにも障害がある場合には、そのソルバの下のソルバからの値が提供されてもよい。
【００２２】
例解として二つのソルバのある実施形態を取ると、利用可能なプロセスのいくつかは（ちょうど標準的な、フォールトトレラントでない実行と同じように）解の「正確な」（より精度の高い）バージョンを計算できる。しかしながら、他のプロセスは、その代わりに、解の「速い」（より精度の低い）バージョンを計算できる。速い解の計算が必要とする時間は、正確な解の計算の場合よりも短いはずである。好ましい例では、速い解の計算が要求する時間は、正確な解の場合より少なくとも一桁短いこともある。
【００２３】
時間の節約は、次のうちの一つまたは複数によって達成できる。
・（正確な解のための陰解法に対し）速い解のための陽解法の使用。
・（正確な解のためのより小さなものに対し）速い解におけるより大きな時間きざみの使用。
・（正確な解のための倍精度に対し）速い解における単精度の算術の使用。
・グリッド・ベースのソルバの場合、（正確な解のためのより細かいグリッドに対し）速い解におけるより粗いグリッドの使用。
・（正確な解における全データに対し）速い解におけるデータのサブセットのみの処理。
・速い解におけるよりゆるい収束基準の使用
・（正確な解においては必要とされる精度を保持する一方）速い解における、相対的に計算集約的でない他の任意の近似の使用。
【００２４】
このように、多くの例において、より精度の低いソルバは、解を計算するために、より精度の高いソルバよりも、計算的に集約的でない近似を使う。
【００２５】
正確な解を計算することに関わるプロセスが障害を受ける場合、その代わりに速い解からの対応する現在データが素早くアクセスされることができる。好ましくは、制御アプリケーション（これはこれらの階層式ソルバを実行しているアプリケーションであってもよい）が障害後の置換を管理して、階層においてより低位のソルバからの現在値を提供して、その値が欠けているソルバにおける計算において代用する。
【００２６】
代用は、いかなる好適な仕方で実施されてもよい。たとえば、より精度の低い解からの対応する実際の値による直接置換によってでも、あるいはより精度の低い解の実際の値から補間される置換値の計算によってでもよい。
【００２７】
一例では、精度のより低いソルバは、問題の同じ離散化をもつことができるが、より速い（そして精度が劣る）時間きざみ方法を使うことができる。よって、二つの解の間には一対一の対応がある――正確な（accurate）解の構成要素naが失われたら、それは速い（fast）解の構成要素nfによって直接置換されることができる。よって、構成要素nfは欠けている値naの代用とされる値である。
【００２８】
一般には、これが成り立たないこともある（たとえば、正確な解についてのより細かい離散化、速い解についてのより粗い離散化があることもある）。この状況では、制御アプリケーションは、正確な解が速い解からどのようにして近似されることができるかを定義するマッピングを維持することができる。たとえば、正確な解が速い解の二つ以上の構成要素からの補間によって計算される場合には、アプリケーションは、代用のための現在値を与えるために、速い解のどの構成要素が（どんな重みで）正確な解の各構成要素の補間において使用されるべきかを特定する事前計算されたマップをもつことができる。
【００２９】
発明実施形態に基づくコンピューティング・システムは、CPUのような複数の処理ユニットを有していてもよい。コンピューティング・システムはハイ・パフォーマンス・コンピューティング（HPC）システムであってもよい。ある実施形態では、各処理ユニットは多コアCPUのコアであってもよい。別の実施形態では、各処理ユニットはコンピューティング・システムにおけるノードであってもよい。さらなる実施形態では、処理ユニットは、CPU、FGPA、GPUまたは他の処理ユニットの任意の組み合わせでありうる。
【００３０】
負荷均衡化または他の目的のため、より精度の低いソルバは、より精度の高いソルバとは異なる数の処理ユニット上で、たとえばより少数の処理ユニット上で実行されることができる。この構成には、より精度の低い解が、必要とする処理ユニットの間の通信がより少ないので、障害に対してそれほど脆弱でなくなることがありうるという追加的な利点がある。
【００３１】
上述したように、より精度の低いソルバは、階層においてより高位のソルバより、同数の処理ユニットを使う場合、必要とする計算資源がより少なく、よってより迅速に実行される可能性が高い。より精度の高いソルバの実行をより多くの並列プロセスに分割することによって、二つのソルバの実行速度をより一貫させることができる。このように、各ソルバは、コンピューティング・システム上にホストされるいくつかのプロセスにおいて実行されてもよく、より精度の低いソルバはより少数のプロセスに分割されてもよい。冗長性を減らすため、ソルバ間の相違は、より精度の低いソルバのプロセスが、両方のソルバについてのプロセスの総数の20%未満、より好ましくは10%未満、最も好ましくは1%未満に相当するようなものである。
【００３２】
速い解を計算するプロセスにおける障害は相対的に可能性が低い（プロセス総数の小さな割合に相当するので）が、そうした障害からはいくつかの仕方で回復できる。
・正確な解からの再構成。
・速い解の計算の複製。
・速い解が計算されるよりずっと速く（だが精度は劣る）「非常に速い」解を計算する、階層におけるさらなる層のプロセス。
【００３３】
このように、上記の例は二つのソルバからなる階層に言及しているものの、階層中には任意の数のソルバが提供されてもよい。たとえば、3つ、4つまたは5つのソルバが使用されてもよい。一例では、三つ以上の異なるバージョンの解が、異なる精度レベルの三つ以上のソルバからなる階層を使って計算される。本方法は：すべてのソルバを並列に使うことによって解の三つ以上のバージョンを計算する段階と；それらのソルバの実行中に、より精度の低いソルバからの値を代用して、階層において前記より精度の低いソルバより階層において一レベル上のより精度の高いソルバにおける欠けている値を置換する段階とを含む。
【００３４】
代替的または追加的に、それらのソルバの実行中に（おそらくは階層において最も低位の最速のソルバについて）、発明実施形態の方法は、階層においてより高位のソルバからの、あるいは階層においてより低位のソルバについての重複ソルバからの値を代用して、前記階層においてより低位のソルバにおける欠けている値を置換することを含む。よって、二つのソルバのうちのより精度の高いほうからの値またはより精度の低いソルバについての重複ソルバからの値が、前記より精度の低いソルバにおける、該ソルバの実行中の障害から帰結する欠けている値を置換しうる。
【００３５】
有利には、少なくとも前記より精度の高いソルバの方法論は、その計算にわたっての値の周期的な同期を含み、前記より精度の低いソルバは、前記より精度の高いソルバからの最も最近に同期された値を用いて周期的にリフレッシュされる。たとえば、逐次反復式計算において、このリフレッシュ手順は、障害と同じ反復工程（ループ）において行なわれてもよいし、あるいはXループ毎に行なわれてもよい。ここで、Xは1以上である。値の代用について上述したのと同じ制御アプリケーションおよびマッピング方法論が、より精度の低いソルバにおける値をリフレッシュするために使用できる。
【００３６】
なお、速いソルバと正確なソルバとの間での定期的な同期のあるそのような逐次反復式ソルバについては、たとえすべての値がループの終わりにリフレッシュされることになるとしても、より精度の低い（速い）ソルバにおける欠けている値があればそれを置換しておくことが有利である。速いソルバはその近似を計算するのを続けるためにそれらの値を必要とするし、それらはリフレッシュ前に正確なソルバに障害があった場合に必要とされるであろう。
【００３７】
階層中のソルバは、いかなる好適な数値的方法を使うこともできる。しかしながら、階層においてより低位のソルバ（単数または複数）は最終的な解には使われないので、ソルバの選択に適用されるいくつかの通常の制約条件は適用されなくてもよい。たとえば、階層においてより低位のソルバ（単数または複数）は数値的に不安定な方法（単数または複数）を使ってもよい。
【００３８】
前記欠けている値は、コンピューティング・システムにおけるいかなる障害の結果であってもよい。いくつかの実施形態では、それはコンピューティング・システムの処理ユニットの間の連絡不良のため、あるいはコンピューティング・システムのある処理ユニットにおける失敗した計算のためである。
【００３９】
本方法はさらに、たとえばメッセージ渡しインターフェース（MPI）からの通知の受領による、あるいはソルバ自身の内部での検出による（この場合、おそらくは何らかの時間期間内に予期されたメッセージが受領されないことによる）障害の検出を含んでいてもよい。
【００４０】
システム側面のある実施形態によれば、相互接続によってリンクされた複数の処理ユニットを有しており、少なくとも二つの異なるソルバの階層を使って並列に計算的な解の少なくとも二つのバージョンを見出すよう構成されたコンピューティング・システムであって：前記処理ユニットのより小さな部分集合は階層においてより低位のソルバを使って前記解の一つのバージョンを計算するよう構成されており、前記処理ユニットのより大きな部分集合は階層においてより高位のソルバを使って前記解の他方のバージョンを計算するよう構成されており、階層においてより高位のソルバの実行の際に障害があって欠けている値が生じる場合、前記相互接続は、前記ソルバの実行中に、階層においてより低位のソルバからの値を代用して欠けている値を置換するよう構成されている、システムが提供される。
【００４１】
システム側面のより特定的な実施形態では、相互接続によってリンクされた複数のノードを有しており、計算的な解の少なくとも二つのバージョンを並列に見出すよう構成されたハイ・パフォーマンス・コンピューティング・システムであって：前記ノードのより小さな部分集合はより精度の低いソルバを使って前記解の一つのバージョンを計算するよう構成されており、前記ノードのより大きな部分集合はより精度の高いソルバを使って前記解の他方のバージョンを計算するよう構成されており、前記より精度の高いソルバの実行の際に障害があって欠けている値が生じる場合、前記相互接続は、両ソルバの実行中に、前記より精度の低いソルバからの値を代用して前記より精度の高いソルバにおける欠けている値を置換するよう構成されている、システムが提供される。
【００４２】
本発明のコンピュータ・プログラム側面のある実施形態は、コンピューティング・システム上で実行されたときに方法を実行するコンピュータ・プログラムであって、前記方法は：並列に異なるソルバの階層を使って計算的な解の少なくとも二つのバージョンを計算する段階と；あるソルバの実行の際に障害があって欠けている値が生じる場合には階層においてより低位のソルバからの値を代用して欠けている値を置換する段階と；階層においてより高位の前記ソルバの解を、前記計算的な解として使う段階とを含む、コンピュータ・プログラムを提供する。
【００４３】
前記コンピュータ・プログラムは、前記ソルバを含む制御アプリケーションであってもよく、あるいは前記ソルバを提供する別個のプログラムまたはサブルーチンを呼び出してもよい。
【００４４】
さらなる一般的なプログラム側面によれば、分散式コンピュータ・システムのようなコンピューティング装置上にロードされたときに該コンピューティング装置を、上述の方法定義のいずれかまたはその任意の組み合わせに基づく方法ステップを実行するよう構成する、プログラムが提供される。
【００４５】
本発明の異なる側面の任意のものの特徴およびサブ特徴が自由に組み合わせられうる。たとえば、コンピュータ・システムの好ましい実施形態が、方法の一つまたは複数の好ましい特徴に対応する機能を組み込むよう構成されてもよい。
【００４６】
本発明は、コンピュータ・ハードウェア、ファームウェア、ソフトウェアまたはそれらの組み合わせにおいて実装できる。本発明は、一つまたは複数のハードウェア・モジュールによる実行のためのまたは一つまたは複数のハードウェア・モジュールの動作を制御するための、コンピュータ・プログラムまたはコンピュータ・プログラム・プロダクト、すなわち情報担体に、たとえば機械可読記憶デバイスまたは伝搬信号において有体に具現されたコンピュータ・プログラムとして実装できる。
【００４７】
コンピュータ・プログラムは、コンピュータ・プログラム部分または二つ以上のコンピュータ・プログラムの形であることができ、コンパイル型言語またはインタープリター型言語を含むいかなる形のプログラミング言語で書くこともでき、スタンドアローン・プログラムとしてまたはモジュール・コンポーネント、サブルーチンまたはデータ処理環境での使用に好適な他の単位を含むいかなる形で展開されることもできる。コンピュータ・プログラムは、一つのモジュール上で、あるいは一つのサイトにおけるもしくは複数のサイトを横断して分散され通信ネットワークによって相互接続された複数のモジュール上で展開されることができる。
【００４８】
本発明の方法ステップは、コンピュータ・プログラムを実行する一つまたは複数のプログラム可能なプロセッサによって実行されて、入力データに対して作用して出力を生成することによって本発明の機能を実行することができる。
【００４９】
コンピュータ・プログラムの実行に好適なプロセッサは、例として、汎用および特殊目的のマイクロプロセッサならびに任意の種類のデジタルもしくは生物学的コンピュータの任意の一つまたは複数のプロセッサを含む。一般に、プロセッサは命令およびデータを読み出し専用メモリまたはランダム・アクセス・メモリまたはその両方から受領する。コンピュータの本質的な要素は、命令およびデータを記憶するための一つまたは複数のメモリ・デバイスに結合された、命令を実行するためのプロセッサである。
【００５０】
本発明は、具体的な実施形態を使って記述される。他の実施形態が下記の請求項の範囲内である。たとえば、本発明のステップは、異なる順序で実行され、それでも望ましい結果を達成することができる。
【００５１】
好ましい実施形態に基づく装置は、ある種の機能を実行するよう設定される、動作可能であるまたは構成される。この設定または構成は、ハードウェアまたはミドルウェアまたは他の任意の好適なシステムの使用によってでありうる。好ましい実施形態では、設定または構成はソフトウェアによる。
【００５２】
本発明についてこれから、図面に示されるような個別的な限定しない実施形態を参照しつつ述べる。
【図面の簡単な説明】
【００５３】
【図１】本発明の一般的な実施形態における階層的なソルバの図的な表現である。
【図２】フォールトトレランスのための階層構造の概観である。
【図３】ａは、現状技術に基づく分散式の並列コンピュータ・プログラムの実行を通じた経路を示すフローチャートであり、ｂは、発明実施形態に基づく分散式の並列コンピュータ・プログラムの実行を通じた経路を示すフローチャートである。
【図４ａ】1dの拡散方程式を解くときの解を示すプロットである。
【図４ｂ】1dの拡散方程式を解くときの絶対誤差を示すプロットである。
【図５】図４と同じ問題についてフォールトトレランス方法を走らせるときの、範囲10-5ないし0.1におけるpについての、障害の数と解の二乗平均平方根誤差との間の関係を示すグラフである。
【図６】ａは、区間[0,1]上でt＝1まで（時間きざみ10-3で）1dの拡散方程式（κ＝0.1）を解くときの解を示すプロットであり、ｂは、区間[0,1]上でt＝1まで（時間きざみ10-3で）1dの拡散方程式（κ＝0.1）を解くときの絶対誤差を示すプロットである。
【図７】図６と同じ問題についてフォールトトレランス方法を走らせるときの、範囲10-5ないし0.1におけるpについての、障害の数と解の二乗平均平方根誤差との間の関係を示すグラフである。
【図８ａ】1dの拡散方程式を解くときの解を示すさらなるプロットである。
【図８ｂ】1dの拡散方程式を解くときの絶対誤差を示すさらなるプロットである。
【図９】本発明に基づくコンピューティング・システムの構造を示すハードウェア図である。
【発明を実施するための形態】
【００５４】
図１は、発明実施形態に基づく二つの異なるソルバの概観図である。ソルバ１が左側に、ソルバ２が右側に示されている。階層矢印の左および右の点線によって示されるように、階層内に他のソルバがあってもよい。ソルバ２は階層においてより高位であり、よってその結果が計算的な解のために使われる。それはボールドで示されており、より高い、精度、複雑さ信頼度などにより、何らかの点でよりよいものと想定される。
【００５５】
図のいちばん上に示される段階Ａでは、両方のソルバが計算を実行している。これは、ブロックのセルへの分割によって示されている。ただし、グリッド・ベースの解法を特に指すことは意図していない。当業者は、図示している六つよりずっと多くの計算が通例は提供されること、両ソルバがそれぞれ異なる数の計算を含んでいてもよいことを理解するであろう。ソルバ２における一つの計算が失敗している。
【００５６】
たとえば本方法論においてループの終わりに行なわれうる段階Ｂでは、ソルバ１からの値がソルバ２における対応する計算中で代用（コピー）される。一つの代入しか示していないが、より多くが相続いてまたは一緒に実行されてもよい。さらに、両ソルバが異なる数の計算を含み、そのため直接対応する値がない場合には、代用される値はソルバ１における値から補間されてもよい。
【００５７】
段階Ｃでは、ソルバ１からの代用された値を含む、あるいは少なくとも部分的には代用された値から導出された値を含むソルバ２からの解が使われる。
【００５８】
図２は、発明実施形態に基づくフォールトトレランスのための階層構造を示している。ここでは三つのソルバが示されている。
【００５９】
（図のいちばん上に示される）最高レベルでは、利用可能なプロセスの大半は、アプリケーションによって要求される精度まで解を計算する。（この精度レベルより下に示される）より低い諸レベルは逐次、より低い精度の（だが計算するのがより速い）解を提供する。これらは計算するのがより速いので、最高レベルと同じランタイムを達成するために必要とするプロセスが少なくなる。より高いレベルのプロセスが障害を受ける場合には、対応するより低いレベルのプロセスからの解が代わりに使われる。この階層は三つより多くのレベルに拡張する（あるいは二レベルだけに縮小する）こともできることを注意しておく。
【００６０】
速い解において時間とともに誤差が蓄積しないことを保証するために、速い解は定期的に、正確な解の最新バージョンから初期化し直される。（たとえば、正確な解を計算する諸プロセスの間でデータが同期されるときは常に、この情報が速い解を計算しているプロセスにも通信されるべき。）
図３のａおよびｂは、従来技術の状況（フォールトトレランスなし）および発明実施形態のフォールトトレラントな実行の方法を使う場合の両方について、逐次反復的な実行で分散式並列コンピュータ・プログラムの実行を通じた経路を示す二つのフローチャートを示している。従来技術の状況では、アプリケーションはクラッシュすることがありうる一方、フォールトトレラントな方法を使うと、アプリケーションは完了し、解を返すことが保証される（全体的なCPU数に比較して少数の障害しかないとの前提で）。このフローチャートは階層における二つのレベルを想定しているが、これはより多くのレベルに拡張できる。
【００６１】
従来技術のフローチャートでは、アプリケーションはステップS10で始まり、並列計算はステップS20で実行される。ステップS30では、実行中の障害が検出されることがある。障害があれば、ステップS40でアプリケーションはクラッシュする。障害がなければ、ステップS50により計算中の諸反復工程が続けられる。これはステップS60においてプログラムが完了して解が返されるまで続く。
【００６２】
発明実施形態に目を転じると、アプリケーションはステップS100で始まる。ステップS110では、これが逐次反復の最初のループでない限り、正確な解が速い解にコピーされる。処理は正確な計算（ステップS120）と速い計算（ステップS140）に分かれる。ステップS130では、正確な実行中の障害が検出されることがあり、その場合、ステップS150において、正確な解は、速い解からの値を使って補修される。ステップS160では、完了かどうかのチェックと、完了でない場合のコピー・ステップおよび計算へのループ・バックがある。ステップS170において、プログラムが完了に達していた場合には解が返される。
【実施例】
【００６３】
検証
本方法を検証するために、（シミュレートされた）障害があるときに拡散方程式を解くよう、簡単なMATLABプロトタイプを実装した。（3dでの）拡散方程式は次のように書ける。
【数１】
2014229307.tif 000003
ここで、u(x,y,z,t)は温度、(x,y,z)は空間、tは時間、κは拡散係数である。この方程式を変域[0,1]×[0,1]×[0,1]上で、変域の端でu＝0という境界条件をもって解く場合、次の形のフーリエ解が存在する。
【数２】
2014229307.tif 000004
【００６４】
ここで、Bは定数であり、nは正の整数である。これらのフーリエ解の和から構築される厳密解は、数値的に計算された解の精度を評価するために使用できる。より低次元での解は、望まれない次元についての空間変数を0と置くことにより（たとえば2d解についてはz＝0、1d解についてはy＝0かつz＝0）計算できる。
【００６５】
このプロトタイプのフォールトトレラント・ソルバは、クランク・ニコルソン（Crank-Nicolson）法を「正確な」解法、前方オイラー法を「速い」解法として使って上記の熱伝導方程式を解く。クランク・ニコルソン法は陰解法（だが二次の精度）であり、一方前方オイラー法は陽解法（ただし一次の精度）であることを注意しておく。陰の方法は一般に、陽の方法より著しく多くの計算時間を必要とする。
【００６６】
各有限要素グリッド点が分散式コンピュータ・システムにおけるノードに対応すると考えられる。よって、あるグリッド点における解の値が、より大きなシミュレーションにおいてあるノードが所有するメモリに記憶されているデータを表わすと解釈される。前提として、障害があるとき、アプリケーションはそのノードを通信する能力を失い（少なくとも一時的に）、データが失われる。
【００６７】
障害は、シミュレーションの過程でランダムに生成される。各時間ステップにおいて、一様分布乱数のベクトル（空間的なグリッド点毎に一つの乱数）が生成される。乱数の一つまたは複数が所与の閾値p（単一の時間ステップにおける任意の所与のノードにおける障害の確率）より小さければ、ベクトル中のそれらの乱数の位置に対応するグリッド点は障害を起こしたと考えられる。障害の場合、その時間ステップについて速い（陽のオイラー）ソルバから計算されたuの値が、正確な（クランク・ニコルソン）ソルバから計算されたuの値の代わりに使われる。障害のあるノードからメッセージが送られないことをシミュレートするために、この値が正確な方法における陰解法の間に使われることを注意しておく。
【００６８】
図４ａは解を示すプロットであり、図４ｂは絶対誤差を示すプロットである。これは、区間[0,1]（空間きざみサイズ0.01）上でt＝1まで（時間きざみ5×10-4で）、初期条件u(x,0)＝100sin(3πx)を用い、p＝10-4として、クランク・ニコルソン法（破線）およびフォールトトレラントな方法（実線）を使って1dの拡散方程式（κ＝0.1）を解くときのものである。ランダムな障害を入れた十回の試行を実行した。各試行における障害の数は16,22,19,21,20,21,19,14,20,14であった。パラメータ値のこの選択は、CFL数0.5に対応する。これについては、陽のオイラー法は数値的に安定である。
【００６９】
各時間ステップにおける各ノードについての障害の確率はp＝10-4であり、結果的に、上記の試行の間に14ないし22回の障害を生じた。それぞれの場合において、解（図４ａ）は互いに、クランク・ニコルソン解から、および厳密解（点線）から区別できないことを注意しておく。誤差（図４ｂ）は本質的に、この図に示される諸プロットの広がりにおける中央の諸プロットの一つであるクランク・ニコルソン法を使って得られた誤差に等しい。障害の確率を変えることの効果は図５に示されている。図５は、障害の数と解の二乗平均平方根誤差との間の関係をプロットしている。障害の数が増すと精度の損失につながるものの、障害なしの解とp＝0.1の場合の解の精度は三倍の差しかないことが見て取れる。
【００７０】
図４および図５で使われた問題については、シミュレーションの精度は著しく低下しないものの、陽なオイラー法による速い解の計算は、クランク・ニコルソン法による正確な解の計算より約５倍しか速くない。しかしながら、この差はより大きな問題サイズについては大きくなることを注意しておく。たとえば、空間きざみが10-3まで小さくされたら、実行時間の差は50倍を超える。同様に、2dまたは3d問題の求解はより大きなシステム行列および陰陽の両方法の使用の間の時間差の増大につながる。
【００７１】
また、速いソルバとしては、数値的に安定でない方法を使うことも可能であることを注意しておく。
【００７２】
図６のａおよびｂは、区間[0,1]（空間きざみサイズ0.01）上でt＝1まで（時間きざみ10-3で）、初期条件u(x,0)＝100sin(3πx)を用い、p＝10-4として、クランク・ニコルソン法（破線）およびフォールトトレラントな方法（実線）を使って1dの拡散方程式（κ＝0.1）を解くときの解（ａ）および絶対誤差（ｂ）を示すプロットである。ランダムな障害を入れた十回の試行を実行した。各試行における障害の数は6,8,8,5,12,12,8,8,10,8であった。パラメータ値のこの選択は、CFL数1.0に対応する。これについては、陽のオイラー法は数値的に不安定である。
【００７３】
図６のａおよびｂは、図４ａおよび図４ｂを生成するために使われたシミュレーションを繰り返した結果を示している。ただし、時間きざみを倍の10-3としてあり、そのためCFL数は1.0となっている（0.5より大きなCFL数については陽なオイラー法は数値的に不安定）。これらのシミュレーションでは、6ないし12回の障害があった（時間ステップの数が半分なので、同じpの値についてより少数の障害となっている）。ここでもまた、フォールトトレラントな方法を使って得られた解は厳密解（点線で示す）およびクランク・ニコルソン解の両方から区別不能であり（図６のａ）、両方法からの誤差は同じオーダーである（図６のｂ）。ただし、誤差の大きさから、一般に、フォールトトレラントな解は、速い解が数値的に安定であった場合よりは精度が低くなっていることは明らかである。これは図７においてより明瞭に見て取れる。図７は、10-5ないし0.1の間のpでの多数のフォールトトレラントな試行についての二乗平均平方根誤差を示している。pのこの変化にもかかわらず、障害なしから１万以上に移るとき、誤差は約一桁しか大きくなっていない。
【００７４】
少数の誤差しか予期されない場合には、さらに数値的安定性が劣る速いソルバを使うことも可能でありうる。図８のａおよびｂは、区間[0,1]（空間きざみサイズ0.01）上でt＝1まで（時間きざみ5×10-3で）、初期条件u(x,0)＝100sin(3πx)を用い、p＝2×10-4として、クランク・ニコルソン法（破線）およびフォールトトレラントな方法（実線）を使って1dの拡散方程式（κ＝0.1）を解くときの解および絶対誤差を示すプロットである。ランダムな障害を入れた十回の試行を実行した。各試行における障害の数は3,4,3,4,5,3,3,5,2,10であった。パラメータ値のこの選択は、CFL数5に対応する。これについては、陽のオイラー法は数値的に不安定である。
【００７５】
このように、図８ａおよび図８ｂは、上記シミュレーションを時間きざみ5×10-3で走らせた結果を示しており、そのためCFL数は5.0となっている――陽なオイラー法が安定である最大値の10倍の大きさである。フォールトトレラントな試行のいくつかからの解は今やクランク・ニコルソン解および厳密解から明らかに区別でき（図８のａ）、誤差は、（最も小さい誤差数をもつプロットの一つである）クランク・ニコルソン法の場合の10倍にもなりうる（図８のｂ）。それにもかかわらず、速いソルバがどれだけ数値的安定性を過ぎて押し進められたかを考えると、これらの誤差は受け容れ可能と考えられうる。
【００７６】
図９は、n＋1個のプロセスを示す概略図である。このうち特にプロセス0およびプロセスnと称される二つのプロセス（６０）のみが示されている。これらのプロセスが実行されるハードウェア資源はコンピュータ・システム５０（図示せず）の一部である。各プロセスは、単一の処理ユニットまたは要素（７０）およびメモリ（８０）を含む個々の資源を使う。処理ユニット（７０）は入出力ユニット（９０）に接続されており、諸プロセスは相互接続（１００）を使って相互接続されることができる。プロセス0が速いソルバに属し、プロセスnが正確なソルバの対応するプロセスであるとすると、正確なソルバに障害がある場合には、プロセス0についてメモリに記憶された値が相互接続１００を介してプロセスnのためのメモリにコピーされることができる。
【００７７】
本発明の実施形態は以下のことを提供できる。
・障害があったとしてもアプリケーションが完了まで実行されて結果を返すことを保証する（障害の数がCPU数に比べて少ないと仮定して）アルゴリズム。アプリケーションの実行を通じた経路がどのようにこれを保証するかの概観については図３を参照。
・異なるレベルの精度での解の複数のバージョンの計算。より精度の低い解は必要とするCPU時間がずっと少なくなる。
・解のより精度の低いバージョンからの値を使って、障害の場合に、解のより精度の高いバージョンから失われた欠けている値を置換。
・より精度の高いバージョンの最新の値を使っての、解のより精度の低いバージョンの再初期化。これにより予備の解が最も正確な解からあまり大きく乖離しないことが保証される。
・より精度の低いソルバが数値的に安定であることが、フォールトトレラントな方法の全体的な精度が受け容れ可能であるために必要でないことがある。
【００７８】
発明実施形態の方法は、既存の現状技術に対して以下のような利点をもちうる。
・障害に対処するために根底にあるMPI実装に依拠しない（障害検出時にアプリケーションの実行がMPIによって自動的に打ち切られないという要件のほかは）。
・最後のチェックポイントが再計算されて以降の障害のあるノード上での計算の間（あるいは作業がタスク・プールの間で割り当て直される間）、諸プロセスが待つ必要がない。速い解は正確な解と同時に計算される。
・速い解を計算することに由来する、全体的な実行時間における代償はほとんどない。これを行なうために非常に少数のプロセスが必要とされるだけだからである。（利用可能な資源の50%が複製された作業のために使われる必要のある標準的な作業複製と比較。）
・アプリケーションの性質について、基礎になる前提条件（たとえばグリッド・ベース）がない。精度と計算時間の間のトレードオフが可能な任意のアプリケーションがこの解決策で扱える。
【符号の説明】
【００７９】
S10  アプリケーション開始
S20  並列計算実行
S30  実行中に障害あり？
S40  アプリケーションがクラッシュ
S50  プログラム完了？
S60  解
S100  アプリケーション開始
S110  正確な解を速い解にコピー
S120  正確な並列計算を実行
S130  実行中に障害あり？
S140  速い並列計算を実行
S150  速い解からの値を使って正確な解を修正
S160  プログラム完了？
S170  解
６０  プロセス
７０  処理ユニット
８０  メモリ
９０  I/Oユニット
１００  相互接続
【図１】
2014229307.tif 000005
【図２】
2014229307.tif 000006
【図３】
2014229307.tif 000007
【図４ａ】
2014229307.tif 000008
【図４ｂ】
2014229307.tif 000009
【図５】
2014229307.tif 000010
【図６】
2014229307.tif 000011
【図７】
2014229307.tif 000012
【図８ａ】
2014229307.tif 000013
【図８ｂ】
2014229307.tif 000014
【図９】
2014229307.tif 000015