説明

行列計算処理方法、プログラム及びシステム

【課題】 FMM(Funny Matrix Multiplication)の計算を高速化すること。
【解決手段】 FMMで中心となるva[k] + vb[k]の最小値を計算する処理において、k=1,…nについて順番に処理するのではなく、best = ∞に初期設定してから、以下の処理Xと処理Yを一回ずつ適用した上で、bestの値をva[k]+vb[k]の最小値として出力することにある。
(処理X) k=a1,a2,…の順にva[k]+vb[k]の値を計算していき、それまでに見つかった最小値をbestとしたときに、va[k] > best/2となるkで処理をやめる(そのようなkが無ければk = anまで処理したらやめる)
(処理Y) 処理Xと同様の処理をk = b1,b2,…についても行い、vb[k] > best/2の値となるkで処理をやめる(そのようなkが無ければk = bnまで処理したらやめる)。

【発明の詳細な説明】
【技術分野】
【0001】
この発明は、コンピュータの処理によって、行列の計算を行う技法に関し、より詳しくは、FMM(Funny Matrix Multiplication)の計算に関する。
【背景技術】
【0002】
FMMとは、通常の行列乗算処理におけるadd(加算)とmultiply(乗算)を、それぞれ、min演算とadd演算に置き換えた行列計算処理のことである。すなわち、2つの入力行列A、Bについて、C[i,j] = mink{A[i,k] + B[k,j]}を全ての(i,j)について計算することがFMMの定義である。FMMは正方行列に限定されないが、ここでは便宜上、行列Aと行列Bは、n×nの正方行列であると仮定する。
【0003】
FMMは、最短経路計算や画像処理などへの応用がある。例えば、A. V. Aho, J. E. Hopcroft, and J. D. Ullman, The Design and Analysis of Computer Algorithms. Addison-Wesley, 1974には、FMMを使った最短経路計算の技法の例が記述されている。
【0004】
FMMにおいては、長さnの2つのベクトルva、vbについて、va[k] + vb[k]の価を、k = 1,..,nの順に計算していき、そのうちの最小値をとる計算が基本となる。つまり、mink{va[k] + vb[k]}を計算する処理が中心となり、この処理をn2回行うので、
FMM全体の処理にO(n3)時間かかる。
【0005】
ところで、近年、交通シミュレーションやカー・ナビゲーションなどの分野で、最短経路計算をより高速に行うことの要望が高まっており、そのためFMMを高速化するアルゴリズムが、次の文献に記述されている。
【0006】
J. J. McAuley and T. S. Caetano, “An expected-case sub-cubic solution to the all-pairs shortest path problem in R,” arXiv:0912.0975v1, 2009は、二つのベクトルvaとvbについて、mink{va[k] + vb[k]}を計算する前に、va[a1] ≦ va[a2] ≦…≦ va[an], vb[b1] ≦ vb[b2] ≦…≦ vb[bn] となるような順列a1,a2,…,anとb1,b2,…,bnを事前に計算することを開示する。FMM全体の処理では、この事前計算をするには、全体で2n回のソート処理を行えば十分であり、すると、全体でO(n2log n)時間で計算を行うことが可能である。
【先行技術文献】
【非特許文献】
【0007】
【非特許文献1】J. J. McAuley and T. S. Caetano, “An expected-case sub-cubic solution to the all-pairs shortest path problem in R,” arXiv:0912.0975v1, 2009
【発明の概要】
【発明が解決しようとする課題】
【0008】
この発明の目的は、FMMの計算において、上記非特許文献1に開示されている技法を更に改良して高速にすることにある。
【課題を解決するための手段】
【0009】
本発明においても、mink{va[k] + vb[k]}を計算する前に、va[a1] ≦ va[a2] ≦…≦ va[an], vb[b1] ≦ vb[b2] ≦…≦ vb[bn] となるような順列a1,a2,…,anとb1,b2,…,bnを事前に計算することは行われる。
【0010】
本発明の特徴は、FMMで中心となるva[k] + vb[k]の最小値を計算する処理において、k=1,…nについて順番に処理するのではなく、best = ∞に初期設定してから、以下の処理Xと処理Yを一回ずつ適用した上で、bestの値をva[k]+vb[k]の最小値として出力することにある。
(処理X) k=a1,a2,…の順にva[k]+vb[k]の値を計算していき、それまでに見つかった最小値をbestとしたときに、va[k] > best/2となるkで処理をやめる(そのようなkが無ければk = anまで処理したらやめる)
(処理Y) 処理Xと同様の処理をk = b1,b2,…についても行い、vb[k] > best/2の値となるkで処理をやめる(そのようなkが無ければk = bnまで処理したらやめる)
【0011】
このような処理を採用したことにより、FMMの計算において、SIMD命令を利用して処理を高速化することが可能となった。この場合、行列Aと行列BのFMMを計算するとすると、行列Aを、列が主のレイアウト(column-majorlayout)、行列Bを、行が主のレイアウト(row-majorlayout)で保存するのがポイントである。ここで、列が主のレイアウトとは、行列 A をメモリ上に保管する際に(行列Aで)列方向に隣り合う要素を(メモリ上でも)なるべく隣り合うように並べる方法のことをいう。つまり、行列 A を、A[1,1], A[2,1], A[3,1],..., A[n,1], A[1,2], A[2,2], A[3,2], ..., A[n,2], A[1,3], A[2,3], ........., A[n,n] といった順番で並べる。一方、行が主のレイアウトとは、列が主のレイアウトにおいて、列と行を入れ替えたものであり、つまり、行列 A を、A[1,1], A[1,2], A[1,3],..., A[1,n], A[2,1], A[2,2], A[2,3], ..., A[2,n], A[3,1], A[3,2], ........., A[n,n] といった順番で並べる。
【発明の効果】
【0012】
この発明によれば、bestの値を一旦計算して、その値に基づき、最小値の計算を打ち切るようにすることにより、最小値の計算を速くすることによって、FMMの計算処理を高速化することができる。
【0013】
また、非特許文献1の技法ではSIMD命令を利用することは困難であったが、本発明の技法では、SIMD命令を有利に適用して、更にFMMの計算処理を高速化することが可能である。
【図面の簡単な説明】
【0014】
【図1】本発明を実施するためのハードウェア構成のブロック図である。
【図2】本発明に係る機能論理ブロック図である。
【図3】本発明の一実施例の処理全体のフローチャートを示す図である。
【図4】図3における、行列を更新する処理のフローチャートを示す図である。
【図5】図3における、行列を更新する処理のフローチャートを示す図である。
【図6】行列におけるSIMD命令に対応した処理を説明するための図である。
【図7】本発明の、SIMD命令に対応した実施例の処理全体のフローチャートを示す図である。
【図8】図7における、行列を更新する処理のフローチャートを示す図である。
【図9】図7における、行列を更新する処理のフローチャートを示す図である。
【発明を実施するための形態】
【0015】
以下、図面に基づき、この発明の実施例を説明する。特に断わらない限り、同一の参照番号は、図面を通して、同一の対象を指すものとする。尚、以下で説明するのは、本発明の一実施形態であり、この発明を、この実施例で説明する内容に限定する意図はないことを理解されたい。
【0016】
図1を参照すると、本発明の一実施例に係るシステム構成及び処理を実現するためのコンピュータ・ハードウェアのブロック図が示されている。図1において、システム・パス102には、CPU104と、主記憶(RAM)106と、ハードディスク・ドライブ(HDD)108と、キーボード110と、マウス112と、ディスプレイ114が接続されている。CPU104は、好適には、32ビットまたは64ビットのアーキテクチャに基づくものであり、例えば、インテル社のPentium(商標) 4、Core(商標)2 Duo、Xeon(商標)、AMD社のAthlon(商標)などを使用することができる。この実施例の目的のため、CPU104は、SIMD(Single Instruction Multiple Data)命令をもつものである。主記憶106は、好適には、4GB以上の容量をもつものである。ハードディスク・ドライブ108は、行列要素の基となる大量のデータを格納できるように、例えば、500GB以上の容量をもつものであることが望ましい。
【0017】
ハードディスク・ドライブ108には、個々に図示しないが、オペレーティング・システムが、予め格納されている。オペレーティング・システムは、Linux(商標)、マイクロソフト社のWindows XP(商標)、Windows(商標)7、アップルコンピュータのMac OS(商標)などの、CPU104に適合する任意のものでよい。
【0018】
ハードディスク・ドライブ108にはまた、好適には、C、C++、C#、Java(R)などのプログラム言語処理系も格納されている。このプログラム言語処理系は、後で説明する、本発明に係るFMM(Funny Matrix Multiplication)の計算処理のためのモジュールを作成し、保守するために使用される。
【0019】
ハードディスク・ドライブ108はさらに、プログラム言語処理系でコンパイルするためのソースコードを書くためのテキスト・エディタ、及び、Eclipse(商標)などの開発環境を含んでいてもよい。
【0020】
キーボード110及びマウス112は、オペレーティング・システムまたは、ハードディスク・ドライブ108から主記憶106にロードされ、ディスプレイ114に表示されたプログラム(図示しない)を起動したり、文字を打ち込んだりするために使用される。
【0021】
ディスプレイ114は、好適には液晶ディスプレイであり、例えば、XGA(1024×768の解像度)、またはUXGA(1600×1200の解像度)などの任意の解像度のものを使用することができる。ディスプレイ114は、図示しないが、本発明の処理を開始するための操作ウインドウや、FMMの計算結果を表示するために使用される。
【0022】
次に、図2の機能ブロック図を参照して、本発明の処理を実行するための処理ルーチンについて説明する。これらの処理ルーチンはC、C++などの、好適にはSIMD命令を利用可能なプログラム言語で作成されて、実行可能な形式でハードディスク・ドライブ108に保存され、オペレーティング・システムの動作で主記憶106にロードされて実行される。
【0023】
メイン・ルーチン202は、本発明の全体の動作を統合するためのプログラムであり、図示しないが、ディスプレイ114に操作ウインドウを表示したり、ユーザの操作を受け付けて処理を開始したりする機能を有する。
【0024】
入力ルーチン204は、ハードディスク・ドライブ108に保存された地図データなどである処理データ206のファイルからデータを読み込んで、行列Aと行列Bの各要素を決定する機能をもつ。
【0025】
ソート・ルーチン208は、本発明に従いFMMの計算を行うためのインデックスの順列を求めるためのソートを行う機能をもつ。この際のソートのアルゴリズムは、クイック・ソートであるが、これには限定されず、シェル・ソート、ヒープ・ソート、マージ・ソートなどの任意の適当なソート・アルゴリズムを用いることができる。
【0026】
更新ルーチン210は、ソートされたインデックスの順列を用いて、FMMの結果の行列Cの要素を更新するための処理を実行する機能をもつ。更新ルーチン210の処理の詳細は、図3〜図5のフローチャート、あるいは図7〜図9のフローチャートを参照して、後で説明する。
【0027】
出力ルーチン212は、行列Aと行列BとのFMM計算の結果得られた行列Cを、結果データ214のファイルとして書き出す機能をもつ。
【0028】
次に、図3のフローチャートを参照して、本発明による全体のFMM計算処理について説明する。この処理を開始するにあたって、メイン・ルーチン202は予め入力ルーチン204を呼び出し、処理データ206のファイルからデータを読み込むことによって、行列Aと行列Bの各要素の値を決定する。ここでは、行列Aと行列Bは、n×nの正方行列であると仮定する。しかし、本発明の処理は、正方行列以外の行列にも適用できることを理解されたい。
【0029】
さて図3において、ステップ302からステップ314までは、iの1からnまでの繰り返しのループである。ステップ304では、メイン・ルーチン202は、行列Aのi行目について、ソート・ルーチン208を呼び出して、値が昇順になるインデックスの順列{a1,...,an}を得る。
【0030】
ステップ306からステップ312までは、jの1からnまでの繰り返しのループである。ステップ308では、メイン・ルーチン202は、行列Aと行列BのFMM計算結果である行列Cについて、C[i,j] = ∞を格納する。ここで∞とは、実際の処理では現れないような十分大きい値のことである。行列Cも、行列A及び行列Bと同様に、n×nの正方行列である。
【0031】
ステップ310では、メイン・ルーチン202は、更新ルーチン210を呼び出して、C[i,j]を{ai}を用いて更新する。ここで、{ai}とは、{a1,...,an}の略記である。ステップ310の詳細は、図4のフローチャートを参照して後で説明する。
【0032】
メイン・ルーチン202は、ステップ312でjを1つインクリメントしてステップ306に戻る。ステップ306に戻って、メイン・ルーチン202は、jがn以下ならステップ308以下を繰り返す。jがnを超えたなら、ステップ306からステップ312までのループを抜ける。
【0033】
ステップ312でループを抜けると、メイン・ルーチン202は、ステップ314でiを1つインクリメントしてステップ302に戻る。ステップ302に戻って、メイン・ルーチン202は、iがn以下ならステップ304以下を繰り返す。iがnを超えたなら、ステップ302からステップ314までのループを抜ける。
【0034】
ステップ316からステップ326までは、iの1からnまでの繰り返しのループである。ステップ318では、メイン・ルーチン202は、行列Bのi列目について、ソート・ルーチン208を呼び出して、値が昇順になるインデックスの順列{b1,...,bn}を得る。
【0035】
ステップ320からステップ324までは、jの1からnまでの繰り返しのループである。
【0036】
ステップ322では、メイン・ルーチン202は、更新ルーチン210を呼び出して、C[i,j]を{bj}を用いて更新する。ここで、{bj}とは、{b1,...,bn}の略記である。ステップ322の詳細は、図5のフローチャートを参照して後で説明する。
【0037】
メイン・ルーチン202は、ステップ324でjを1つインクリメントしてステップ320に戻る。ステップ320に戻って、メイン・ルーチン202は、jがn以下ならステップ322以下を繰り返す。jがnを超えたなら、ステップ320からステップ324までのループを抜ける。
【0038】
ステップ324でループを抜けると、メイン・ルーチン202は、ステップ326でiを1つインクリメントしてステップ316に戻る。ステップ316に戻って、メイン・ルーチン202は、iがn以下ならステップ318以下を繰り返す。iがnを超えたなら、ステップ316からステップ326までのループを抜ける。
【0039】
ここまでの処理が終了すると、C[i,j]の要素が全て得られている。メイン・ルーチン202は、出力ルーチン212を呼び出して、C[i,j]の要素の値を、結果データ214を含むファイルとして、ハードディスク・ドライブ108に書き出す。
【0040】
図4は、図3のステップ310をより詳細に示すフローチャートである。図3では、この処理が、更新ルーチン210をサブルーチンとして呼び出す処理として説明されているが、図4のフローチャートに対応するコードがインライン的に埋め込まれて実行されるようにしてもよい。
【0041】
図4において、更新ルーチン210は、ステップ402で、変数kを1とおく。更新ルーチン210は、ステップ404で、bestという変数に、C[i,j]の値を格納する。
【0042】
ステップ406では、更新ルーチン210は、best = min{best, A[i,ak] + B[ak,j]}によりbestの値を更新し、ステップ408でkを1だけ増分する。
【0043】
ステップ410では、更新ルーチン210は、k > nもしくはA[i,ak] > best/2であるかどうか判断し、そうでないならステップ406に戻る。
【0044】
更新ルーチン210がステップ410で、k > nもしくはA[i,ak] > best/2であると判断すると、ステップ412でC[i,j] = bestと格納して、ステップ310が終了する。
【0045】
図5は、図3のステップ322をより詳細に示すフローチャートである。図3では、この処理が、更新ルーチン210をサブルーチンとして呼び出す処理として説明されているが、図4のフローチャートに対応するコードがインライン的に埋め込まれて実行されるようにしてもよい。
【0046】
図5において、更新ルーチン210は、ステップ502で、変数kを1とおく。更新ルーチン210は、ステップ504で、bestという変数に、C[i,j]の値を格納する。
【0047】
ステップ506では、更新ルーチン210は、best = min{best, A[i,bk] + B[bk,j]}によりbestの値を更新し、ステップ508でkを1だけ増分する。
【0048】
ステップ510では、更新ルーチン210は、k > nもしくはB[bk,j] > best/2であるかどうか判断し、そうでないならステップ506に戻る。
【0049】
更新ルーチン210がステップ510で、k > nもしくはB[bk,j] > best/2であると判断すると、ステップ512でC[i,j] = bestと格納して、ステップ322が終了する。
【0050】
この実施例は、図4のステップ410のA[i,ak] > best/2、あるいは、図5のステップ510のB[bk,j] > best/2の判断で、比較を早めに打ち切ることができるので、非特許文献1に記述されている技法よりも処理速度を向上することができる。
【0051】
本発明のさらなる特徴は、SIMD(Single Instruction Multiple Data)命令を有利に利用して、処理速度を向上することができることである。その技法を図6を参照して説明する。
【0052】
すなわち、本発明に従い、C[i,j]とC[i,j'](ここでj'= j+1)を計算するとき、
− C[i,j]については、まず、k = a1,a2,…の順にA[i,k] + B[k,j]を計算していく。
− C[i,j'] については、まず、k = a1,a2,… の順にA[i,k] + B[k,j']を計算していく。
この両者の計算では、行列Aについては同じ行にアクセスし、行列Bについては隣同士の値にアクセスしている。
【0053】
よって、C[i,j] と C[i,j'] の計算を融合して、同時に行えば両者を一つのループで処理できる。そして、A[i,k] + B[k,j] と A[i,k] + B[k,j'] は、2-wayのSIMD命令を使えば一つのvec_add命令で処理できて高速化が可能となる。
− ループを融合する際、ループの終了条件を調整する必要があるが、これも容易に実現可能
− ループを融合した結果、ループ長が長くなる場合があるが、これによる計算速度の低下は一般にSIMD命令による高速化に比べて小さい。
C[i,j]とC[i,j']の計算にあたっては、次にk = b1, b2, … についても計算をする必要があるが、この両者の計算は融合できない。ただ、i' = i+1とすると、C[i,j]とC[i',j]の計算は k = b1, b2, … についてループの融合ができる。よって、k = a1, a2, … の計算には列方向に隣同士の行列 C の計算を融合し、k = b1, b2, … の計算には行方向に隣同士の行列 C の計算を融合する、という二段階で行う。非特許文献1の手法では、k = a1, a2, … の計算と k = b1, b2, … の計算、というように分解ができないのが問題である。
【0054】
SIMDの実装方法は、これには限定されないが例えば、gcc、Visual C++などの処理系を使用して、emmintrin.hなどのヘッダファイルをインクルードし、__m128iなどのデータ型宣言を用いる。メモリからの読み出しは_mm_loadu_si128()を使用し、レジスタの初期化には_mm_set_epi32()を使用し、加算には_mm_add_epi32()を使用する、等である。
【0055】
次に、SIMDを実装するのに好適な実施例の処理の全体を、図7のフローチャートを参照して説明する。この処理を開始するにあたって、メイン・ルーチン202は予め入力ルーチン204を呼び出し、処理データ206のファイルからデータを読み込むことによって、行列Aと行列Bの各要素の値を決定する。ここでも、行列Aと行列Bは、n×nの正方行列であると仮定する。また、SIMDの多重度をsとし、nを、sで割り切れる数であると仮定する。
【0056】
さて図7において、ステップ702からステップ714までは、iの1からnまでの繰り返しのループである。ステップ704では、メイン・ルーチン202は、行列Aのi行目について、ソート・ルーチン208を呼び出して、値が昇順になるインデックスの順列{a1,...,an}を得る。
【0057】
ステップ706からステップ712までは、jの1からn/sまでの繰り返しのループである。ステップ708では、メイン・ルーチン202は、行列Aと行列BのFMM計算結果である行列Cについて、C[i,(j-1)*s+1] = ∞、C[i,(j-1)*s+2] = ∞、...、C[i,(j-1)*s+s-1] = ∞と格納する。ここで、行列Cも、行列A及び行列Bと同様に、n×nの正方行列である。
【0058】
ステップ710では、メイン・ルーチン202は、更新ルーチン210を呼び出して、C[i,(j-1)*s+1]、C[i,(j-1)*s+2]、...、C[i,(j-1)*s+s-1]を{ai}を用いて更新する。ステップ710の詳細は、図8のフローチャートを参照して後で説明する。
【0059】
メイン・ルーチン202は、ステップ712でjを1つインクリメントしてステップ706に戻る。ステップ706に戻って、メイン・ルーチン202は、jがn/s以下ならステップ708以下を繰り返す。jがn/sを超えたなら、ステップ706からステップ712までのループを抜ける。
【0060】
ステップ712でループを抜けると、メイン・ルーチン202は、ステップ714でiを1つインクリメントしてステップ702に戻る。ステップ702に戻って、メイン・ルーチン202は、iがn以下ならステップ704以下を繰り返す。iがnを超えたなら、ステップ702からステップ714までのループを抜ける。
【0061】
ステップ716からステップ726までは、iの1からnまでの繰り返しのループである。ステップ718では、メイン・ルーチン202は、行列Bのi列目について、ソート・ルーチン208を呼び出して、値が昇順になるインデックスの順列{b1,...,bn}を得る。
【0062】
ステップ720からステップ724までは、jの1からn/sまでの繰り返しのループである。
【0063】
ステップ722では、メイン・ルーチン202は、更新ルーチン210を呼び出して、C[(i-1)*s+1,j]、C[(i-1)*s+2,j]、...、C[(i-1)*s+s-1,j]を{bj}を用いて更新する。ステップ722の詳細は、図9のフローチャートを参照して後で説明する。
【0064】
メイン・ルーチン202は、ステップ724でjを1つインクリメントしてステップ720に戻る。ステップ720に戻って、メイン・ルーチン202は、jがn/s以下ならステップ722以下を繰り返す。jがn/sを超えたなら、ステップ720からステップ724までのループを抜ける。
【0065】
ステップ724でループを抜けると、メイン・ルーチン202は、ステップ726でiを1つインクリメントしてステップ716に戻る。ステップ716に戻って、メイン・ルーチン202は、iがn以下ならステップ718以下を繰り返す。iがnを超えたなら、ステップ716からステップ726までのループを抜ける。
【0066】
ここまでの処理が終了すると、C[i,j]の要素が全て得られている。メイン・ルーチン202は、出力ルーチン212を呼び出して、C[i,j]の要素の値を、結果データ214を含むファイルとして、ハードディスク・ドライブ108に書き出す。
【0067】
図8は、図7のステップ710をより詳細に示すフローチャートである。図7では、この処理が、更新ルーチン210をサブルーチンとして呼び出す処理として説明されているが、図8のフローチャートに対応するコードがインライン的に埋め込まれて実行されるようにしてもよい。
【0068】
更新ルーチン210は、図8のステップ802では、変数kに、1を格納する。
【0069】
ステップ804からステップ808までは、p = (j-1)*s + 1から(j-1)*s + s - 1までの繰り返しである。ステップ806では、更新ルーチン210は、t[p] = C[i,p]と値を格納する。このループがp = (j-1)*s + 1から(j-1)*s + s - 1まで終わると、ループを抜け出てステップ810に進む。
【0070】
次は、ステップ810からステップ814までで、p = (j-1)*s + 1から(j-1)*s + s - 1までの繰り返しである。ステップ812では、更新ルーチン210は、t[p] = min{t[p],A[i,ak]+B{ak,p]}を実行する。このとき、複数のA[i,ak]+B{ak,p]の計算に並列的にvec_addのSIMD命令を使用して、処理速度が向上される。このループがp = (j-1)*s + 1から(j-1)*s + s - 1まで終わると、ループを抜け出てステップ816に進む。
【0071】
更新ルーチン210は、ステップ816で、kを1だけ増分し、ステップ818で、k > nもしくは、A[i,ak] > maxp{t[p]/2}を判断する。この判断が否定的であるなら、処理はステップ810に戻る。
【0072】
ステップ816の判断が肯定的なら、ステップ820からステップ824までのループを実行する。ステップ820からステップ824は、p = (j-1)*s + 1から(j-1)*s + s - 1までの繰り返しである。更新ルーチン210は、ステップ822で、C[i,p] = t[p]と格納する。このループがp = (j-1)*s + 1から(j-1)*s + s - 1まで終わると、ステップ710が終了する。
【0073】
図9は、図7のステップ722をより詳細に示すフローチャートである。図7では、この処理が、更新ルーチン210をサブルーチンとして呼び出す処理として説明されているが、図9のフローチャートに対応するコードがインライン的に埋め込まれて実行されるようにしてもよい。
【0074】
更新ルーチン210は、図9のステップ902では、変数kに、1を格納する。
【0075】
ステップ904からステップ908までは、p = (i-1)*s + 1から(i-1)*s + s - 1までの繰り返しである。ステップ906では、更新ルーチン210は、t[p] = C[p,j]と値を格納する。このループがp = (i-1)*s + 1から(i-1)*s + s - 1まで終わると、ループを抜け出てステップ910に進む。
【0076】
次は、ステップ910からステップ914までで、p = (i-1)*s + 1から(i-1)*s + s - 1までの繰り返しである。ステップ912では、更新ルーチン210は、t[p] = min{t[p],A[p,bk]+B[bk,j]}を実行する。このとき、複数のA[p,bk]+B[bk,j]の計算に並列的にvec_addのSIMD命令を使用して、処理速度が向上される。このループがp = (i-1)*s + 1から(i-1)*s + s - 1まで終わると、ループを抜け出てステップ916に進む。
【0077】
更新ルーチン210は、ステップ916で、kを1だけ増分し、ステップ918で、k > nもしくは、B[bk,j] > maxp{t[p]/2}を判断する。この判断が否定的であるなら、処理はステップ910に戻る。
【0078】
ステップ916の判断が肯定的なら、ステップ920からステップ924までのループを実行する。ステップ920からステップ924は、p = (i-1)*s + 1から(i-1)*s + s - 1までの繰り返しである。更新ルーチン210は、ステップ922で、C[p,j] = t[p]と格納する。このループがp = (i-1)*s + 1から(i-1)*s + s - 1まで終わると、ステップ722が終了する。
【0079】
ところで、図4あるいは図5の処理を擬似コードで書くと、次のとおりである。
best = ∞
i = 1
repeat
best = min { best, va[ai] + vb[ai] }
i = i+1
until (i > n or va[ai] > best/2)
j = 1
repeat
best = min { best, va[bj] + vb[bj] }
j = j+1
until (j > n or vb[bj] > best/2)
output best
【0080】
ここの(j > n or vb[bj] > best/2)という判定条件については、次のような実施例も考えられる。
best = ∞, temp = ∞
i = 1
repeat
best = min { best, va[ai] + vb[ai] }
temp = min { temp, vb[ai] }
i = i+1
until (i > n or va[ai] > best/2)
j = 1
repeat
best = min { best, va[bj] + vb[bj] }
j = j+1
until (j > n or vb[bj] > min { best/2, temp })
output best
best/2 ≧ min { best/2, temp }なので、こうするとループの脱出が早まる。ここでは、2つのループの打ち切り条件が異なることに留意されたい。
【0081】
あるいは、以下のような例もありえる。
best = ∞
i = 1
repeat
best = min { best, va[ai] + vb[ai] }
i = i+1
until (i > n or va[ai] > best/2)
j = 1
repeat
best = min { best, va[bj] + vb[bj] }
j = j+1
until (j > n - 1 or vb[bj] > best/2)
output best
ここでも、2つのループの打ち切り条件が異なっている。
【0082】
また、上記実施例では、行列A、B、Cはどれもn×nの正方行列であると想定したが、これには限定されず、通常の行列の掛け算と同様に、行列Aがm×k、行列Bがk×nであるとしてよい。この結果、行列Cは、m×nとなる。
【0083】
以上、特定のハードウェアおよびソフトウェアのプラットフォーム上で実施するものとして本発明を説明してきたが、本発明は示されている例に限定されず、任意のコンピュータ・プラットフォーム上で実施可能である。
【符号の説明】
【0084】
102 システム・パス
104 CPU
106 主記憶
108 ハードディスク・ドライブ
110 キーボード
112 マウス
114 ディスプレイ
202 メイン・ルーチン
204 入力ルーチン
206 処理データ
208 ソート・ルーチン
210 更新ルーチン
212 出力ルーチン
214 結果データ

【特許請求の範囲】
【請求項1】
コンピュータの処理により、2つの行列(以下、それぞれA,Bとする)のFMM(Funny Matrix Multiplication)を計算する方法であって、
i = 1から前記行列Aの行の数までにおいて、各々の行について、値が昇順になるインデックスの順列{ai}を順に計算するステップと、
前記i番目の行において、j = 1から前記行列Aの列の数までについて、C[i,j]に先ず行列の値として想定されるよりも十分大きい値を格納し、FMMの計算結果である結果の行列Cのi,j成分であるC[i,j]の値を所定の変数(best)に格納し、k = 1から1つずつ増分しながら順次、best = min{best, A[i,ak]+B[ak,j]}を計算し、ここで、akは前記インデックスの順列{ai}のk番目の要素であり、kが前記行列Aの行の数を超えるかA[i,ak]がbest/2を超えることに応答して、C[i,j] = bestによりC[i,j]を更新するステップと、
j = 1から前記行列Bの列の数までにおいて、各々の列について、値が昇順になるインデックスの順列{bj}を順に計算するステップと、
前記j番目の列について、j = 1から前記行列Bの列の数までについて、前記行列Cのi,j成分であるC[i,j]をbestとおき、k = 1から1つずつ増分しながら順次、best = min{best, A[i,bk]+B[bk,j]}を計算し、ここで、bkは前記インデックスの順列{bj}のk番目の要素であり、kが前記行列Bの列の数を超えるかB[bk,j]がbest/2を超えることに応答して、C[i,j] = bestによりC[i,j]を更新するステップを有する、
行列計算処理方法。
【請求項2】
前記行列Aが列を主のレイアウトになるようにするとともに、前記行列Bが行を主のレイアウトになるようにし、
前記A[i,ak] > best/2であることに応答して、C[i,j] = bestによりC[i,j]を更新するステップと、前記B[bk,j] > best/2であることに応答して、C[i,j] = bestによりC[i,j]を更新するステップが、ループを融合して分割された部分をそれぞれ、SIMD命令により並列実行される、請求項1に記載の方法。
【請求項3】
前記行列A、B及びCが、n×nの正方行列である、請求項1に記載の方法。
【請求項4】
コンピュータの処理により、2つの行列(以下、それぞれA,Bとする)のFMM(Funny Matrix Multiplication)を計算するプログラムであって、
前記コンピュータに、
i = 1から前記行列Aの行の数までにおいて、各々の行について、値が昇順になるインデックスの順列{ai}を順に計算するステップと、
前記i番目の行において、j = 1から前記行列Aの列の数までについて、C[i,j]に先ず行列の値として想定されるよりも十分大きい値を格納し、FMMの計算結果である結果の行列Cのi,j成分であるC[i,j]の値を所定の変数(best)に格納し、k = 1から1つずつ増分しながら順次、best = min{best, A[i,ak]+B[ak,j]}を計算し、ここで、akは前記インデックスの順列{ai}のk番目の要素であり、kが前記行列Aの行の数を超えるかA[i,ak]がbest/2を超えることに応答して、C[i,j] = bestによりC[i,j]を更新するステップと、
j = 1から前記行列Bの列の数までにおいて、各々の列について、値が昇順になるインデックスの順列{bj}を順に計算するステップと、
前記j番目の列について、j = 1から前記行列Bの列の数までについて、前記行列Cのi,j成分であるC[i,j]をbestとおき、k = 1から1つずつ増分しながら順次、best = min{best, A[i,bk]+B[bk,j]}を計算し、ここで、bkは前記インデックスの順列{bj}のk番目の要素であり、kが前記行列Bの列の数を超えるかB[bk,j]がbest/2を超えることに応答して、C[i,j] = bestによりC[i,j]を更新するステップを実行させる、
行列計算処理プログラム。
【請求項5】
前記行列Aが列を主のレイアウトになるようにするとともに、前記行列Bが行を主のレイアウトになるようにし、
前記A[i,ak] > best/2であることに応答して、C[i,j] = bestによりC[i,j]を更新するステップと、前記B[bk,j] > best/2であることに応答して、C[i,j] = bestによりC[i,j]を更新するステップが、ループを融合して分割された部分をそれぞれ、SIMD命令により並列実行される、請求項4に記載のプログラム。
【請求項6】
前記行列A、B及びCが、n×nの正方行列である、請求項4に記載のプログラム。
【請求項7】
コンピュータの処理により、2つの行列(以下、それぞれA,Bとする)のFMM(Funny Matrix Multiplication)を計算するシステムであって、
i = 1から前記行列Aの行の数までにおいて、各々の行について、値が昇順になるインデックスの順列{ai}を順に計算する手段と、
前記i番目の行について、j = 1から前記行列Aの列の数までについて、C[i,j]に先ず行列の値として想定されるよりも十分大きい値を格納し、FMMの計算結果である結果の行列Cのi,j成分であるC[i,j]の値を所定の変数(best)に格納し、k = 1から1つずつ増分して順次、best = min{best, A[i,ak]+B[ak,j]}を計算し、ここで、akは前記インデックスの順列{ai}のk番目の要素であり、kが前記行列Aの行の数を超えるかA[i,ak]がbest/2を超えることに応答して、C[i,j] = bestによりC[i,j]を更新する手段と、
j = 1から前記行列Bの列の数までにおいて、各々の列について、値が昇順になるインデックスの順列{bj}を順に計算する手段と、
前記j番目の列について、j = 1から前記行列Bの列の数までについて、前記行列Cのi,j成分であるC[i,j]をbestとおき、k = 1から1つずつ増分して順次、best = min{best, A[i,bk]+B[bk,j]}を計算し、ここで、bkは前記インデックスの順列{bj}のk番目の要素であり、kが前記行列Bの列の数を超えるかB[bk,j]がbest/2を超えることに応答して、C[i,j] = bestによりC[i,j]を更新する手段を有する、
行列計算処理システム。
【請求項8】
前記行列Aが列を主のレイアウトになるようにするとともに、前記行列Bが行を主のレイアウトになるようにし、
前記A[i,ak] > best/2であることに応答して、C[i,j] = bestによりC[i,j]を更新する手段と、前記B[bk,j] > best/2であることに応答して、C[i,j] = bestによりC[i,j]を更新する手段が、ループを融合して分割された部分をそれぞれ、SIMD命令により並列実行される、請求項7に記載のシステム。
【請求項9】
前記行列A、B及びCが、n×nの正方行列である、請求項7に記載のシステム。

【図1】
image rotate

【図2】
image rotate

【図3】
image rotate

【図4】
image rotate

【図5】
image rotate

【図6】
image rotate

【図7】
image rotate

【図8】
image rotate

【図9】
image rotate


【公開番号】特開2012−164039(P2012−164039A)
【公開日】平成24年8月30日(2012.8.30)
【国際特許分類】
【出願番号】特願2011−22311(P2011−22311)
【出願日】平成23年2月4日(2011.2.4)
【国等の委託研究の成果に係る記載事項】(出願人による申告)平成21年度、総務省、「自動車二酸化炭素排出量削減のための大規模モビリティ社会シミュレータの研究開発」委託事業、産業技術力強化法第19条の適用を受ける特許出願
【出願人】(390009531)インターナショナル・ビジネス・マシーンズ・コーポレーション (4,084)
【氏名又は名称原語表記】INTERNATIONAL BUSINESS MASCHINES CORPORATION
【Fターム(参考)】