(57)【特許請求の範囲】
【請求項１】
N行M列（Ｎ、Ｍはともに1以上の整数）の二値行列XとM次元の実数ベクトルqとの積Xqを計算する行列ベクトル積演算装置であって、
行分割単位L（Lは1以上かつMより小さい整数）で分割した前記二値行列Xに対応するZDD（ゼロサプレス型二分決定グラフ）を、ノードIDをインデックスとする配列として表した配列データを格納するデータ記憶手段と、
行列ベクトル積演算時の演算データを記憶する演算データ記憶手段と、
前記演算データ記憶手段において出力データを格納するN個の記憶領域と、一時的な計算結果を格納するN×L＋１個の記憶領域を用意し、前記配列データに基づいて、前記N個の記憶領域と前記N×L＋１個の記憶領域を利用することにより、前記積Xqを算出する演算実行手段と、
前記演算実行手段により算出された前記積Xqの値である前記N個の記憶領域に格納されたデータを出力する出力手段と
を備えることを特徴とする行列ベクトル積演算装置。
【請求項２】
前記配列データは、ノードID(i)毎に、ノードのラベル(v(i))、HIリンク先のノードID(HI(i))、LOリンク先のノードID(LO(i))、先頭ノードフィールド、レベル番号フィールドを有し、前記先頭ノードフィールドの内容は、対応ノードが分割された行列の各行で最左の１に対応するノードであった場合の行番号の集合であり、レベル番号フィールドの値は、同じラベルを持つノードのうち何番目のノードであるかを示す整数であり、
前記N個の記憶領域の要素をscore[i]  (1≦i≦N)、前記N×L＋１個の記憶領域の要素をdata[i]  (1≦i≦N×L+1)とし、
num(i)をノードiのレベル番号としたときの配列data中での位置を示す関数address(i)を、
【数１】
0005736336.tif 000004
と定義し、
v(i)  =ejとした場合において、
前記演算実行手段は、
data[address(i)]の値を、実数ベクトルの要素qjとdata[address(HI(i))]の値の和に更新し、iの先頭ノードフィールドが空でないかを調べ、空でなければ先頭ノードフィールドの各値について、score[j]  =  score[j]  +  data[address(i)]を計算することによりscore[j]を更新し、iの先頭ノードフィールドが空である場合、又は空でない場合のscore[j]の更新が終了した後に、次のiについて処理に進む処理ステップを、iを3から配列データサイズ−Nまで変化させて繰り返す
ことを特徴とする請求項１に記載の行列ベクトル積演算装置。
【請求項３】
前記二値行列の各行に対応するシンボルをrk(k=1〜N）とした場合において、
j  =  HI(i)を取得し、jが１でないなら配列データのj番目の要素の先頭ノードフィールドに、対応するrkの添字kを追加し、j  =  LO(j)と更新する処理をjが１になるまで繰り返すステップを、v(i)=r1,  r2,  ...,  rNとなるN個のノードについて順に実行することにより、前記先頭ノードフィールドの値を設定する手段
を有することを特徴とする請求項２に記載の行列ベクトル積演算装置。
【請求項４】
N行M列（Ｎ、Ｍはともに1以上の整数）の二値行列XとM次元の実数ベクトルqとの積Xqを計算する行列ベクトル積演算装置が実行する行列ベクトル積演算方法であって、
前記行列ベクトル積演算装置は、
行分割単位L（Lは1以上かつMより小さい整数）で分割した前記二値行列Xに対応するZDD（ゼロサプレス型二分決定グラフ）を、ノードIDをインデックスとする配列として表した配列データを格納するデータ記憶手段と、
行列ベクトル積演算時の演算データを記憶する演算データ記憶手段と、を備え、
前記演算データ記憶手段において出力データを格納するN個の記憶領域と、一時的な計算結果を格納するN×L＋１個の記憶領域を用意し、前記配列データに基づいて、前記N個の記憶領域と前記N×L＋１個の記憶領域を利用することにより、前記積Xqを算出する演算実行ステップと、
前記演算実行ステップにより算出された前記積Xqの値である前記N個の記憶領域に格納されたデータを出力する出力ステップと
を備えることを特徴とする行列ベクトル積演算方法。
【請求項５】
前記配列データは、ノードID(i)毎に、ノードのラベル(v(i))、HIリンク先のノードID(HI(i))、LOリンク先のノードID(LO(i))、先頭ノードフィールド、レベル番号フィールドを有し、前記先頭ノードフィールドの内容は、対応ノードが分割された行列の各行で最左の１に対応するノードであった場合の行番号の集合であり、レベル番号フィールドの値は、同じラベルを持つノードのうち何番目のノードであるかを示す整数であり、
前記N個の記憶領域の要素をscore[i]  (1≦i≦N)、前記N×L＋１個の記憶領域の要素をdata[i]  (1≦i≦N×L+1)とし、
num(i)をノードiのレベル番号としたときの配列data中での位置を示す関数address(i)を、
【数２】
0005736336.tif 000005
と定義し、
v(i)  =ejとした場合において、
前記演算実行ステップにおいて、前記行列ベクトル積演算装置は、
data[address(i)]の値を、実数ベクトルの要素qjとdata[address(HI(i))]の値の和に更新し、iの先頭ノードフィールドが空でないかを調べ、空でなければ先頭ノードフィールドの各値について、score[j]  =  score[j]  +  data[address(i)]を計算することによりscore[j]を更新し、iの先頭ノードフィールドが空である場合、又は空でない場合のscore[j]の更新が終了した後に、次のiについて処理に進む処理ステップを、iを3から配列データサイズ−Nまで変化させて繰り返す
ことを特徴とする請求項４に記載の行列ベクトル積演算方法。
【請求項６】
前記二値行列の各行に対応するシンボルをrk(k=1〜N）とした場合において、
j  =  HI(i)を取得し、jが１でないなら配列データのj番目の要素の先頭ノードフィールドに、対応するrkの添字kを追加し、j  =  LO(j)と更新する処理をjが１になるまで繰り返すステップを、v(i)=r1,  r2,  ...,  rNとなるN個のノードについて順に実行することにより、前記先頭ノードフィールドの値を設定するステップを、
前記演算実行ステップの前段階のステップとして有することを特徴とする請求項５に記載の行列ベクトル積演算方法。
【請求項７】
前記データ記憶手段と前記演算データ記憶手段を備えるコンピュータを、請求項１又は２に記載の前記演算実行手段、前記出力手段として機能させるための行列ベクトル積演算プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、0または1を要素としてとる二値行列と、実数ベクトルとの乗算に必要な処理時間を削減するための技術に関するものである。なお、本明細書で扱う乗算とは、N行M列（Ｎ、Ｍはともに1以上の整数）の二値行列Xと、M次元の実数ベクトルqを受け取り、p = XqとしてN次元の実数ベクトルpを求める処理のことをいう。
【背景技術】
【０００２】
二値行列と実数ベクトルの乗算は、さまざまな場面で実行される基本的な演算である。この演算の計算回数を削減するための手法として、二値行列をゼロサプレス型二分決定グラフ(Zero-Suppressed Binary Decision Diagrams、ZDD) を用いて表現し、そのうえで行列とベクトルの乗算を行う手法がある（非特許文献1）。なお、上記の演算は、キャッシュメモリを搭載した中央演算処理装置(CPU)上で実行される。
【先行技術文献】
【非特許文献】
【０００３】
【非特許文献１】西野正彬、安田宜仁、小林透、"ZDDを用いた効率的な集合拡張の計算"、人工知能学会第25回全国大会、2011
【発明の概要】
【発明が解決しようとする課題】
【０００４】
非特許文献1に開示された手法では、行列とベクトルの乗算のためにはZDDのノードの個数個の実数を保持するための記憶領域を用意し、それに対して読み込み/書き出しを行う必要があった。キャッシュメモリを搭載した中央演算処理装置を用いて演算を実行する際に、大量のメモリに対する読み込み/書き出しがあると、CPUキャッシュメモリを有効に利用できないため、処理速度が低下する問題があった。
【０００５】
本発明は上記の問題点に鑑みてなされたものであり、ZDDを用いた行列とベクトルの乗算において、計算途中にアクセスする必要がある記憶領域を削減し、CPUキャッシュヒット率を高めることで、処理速度を高速にすることを目的とする。
【課題を解決するための手段】
【０００６】
上記の課題を解決するために、本発明は、N行M列（Ｎ、Ｍはともに1以上の整数）の二値行列XとM次元の実数ベクトルqとの積Xqを計算する行列ベクトル積演算装置であって、
行分割単位L（Lは1以上かつMより小さい整数）で分割した前記二値行列Xに対応するZDD（ゼロサプレス型二分決定グラフ）を、ノードIDをインデックスとする配列として表した配列データを格納するデータ記憶手段と、
行列ベクトル積演算時の演算データを記憶する演算データ記憶手段と、
前記演算データ記憶手段において出力データを格納するN個の記憶領域と、一時的な計算結果を格納するN×L＋１個の記憶領域を用意し、前記配列データに基づいて、前記N個の記憶領域と前記N×L＋１個の記憶領域を利用することにより、前記積Xqを算出する演算実行手段と、
前記演算実行手段により算出された前記積Xqの値である前記N個の記憶領域に格納されたデータを出力する出力手段とを備えることを特徴とする行列ベクトル積演算装置として構成される。
【０００７】
また、本発明は、行列ベクトル積演算装置が実行する行列ベクトル積演算方法として構成することもできる。また、本発明は、前記データ記憶手段と前記演算データ記憶手段を備えるコンピュータを、前記演算実行手段、前記出力手段として機能させるための行列ベクトル積演算プログラムとして構成することもできる。
【発明の効果】
【０００８】
本発明によれば、二値行列を表現したZDDの節点の個数分の記憶領域を用意する代わりに、(N + N×L＋1)だけの記憶領域を用意して計算を行うので、使用する記憶領域が削減され、CPUキャッシュヒット率が上昇するため、処理速度を高速にできる。
【図面の簡単な説明】
【０００９】
【図１】本発明の実施の形態に係る行列ベクトル積演算装置の機能構成図である。
【図２】ZDDによって組み合わせ集合を表した例を示す図である。
【図３】行列ベクトル積演算装置の処理を示すフローチャートである。
【図４Ａ】行分割単位Lを３としたときの二値行列の例を示す図である。
【図４Ｂ】図４Aに示す二値行列に対応するZDDを示す図である。
【図４Ｃ】図４Bに示すZDDの配列上の表現を示す図である。
【図５】先頭ノードマーク処理のフローチャートである。
【図６】行列とベクトルの積を計算する処理のフローチャートである。
【発明を実施するための形態】
【００１０】
以下、図面を参照して本発明の実施の形態を説明する。なお、以下で説明する実施の形態は一例に過ぎず、本発明が適用される実施の形態は、以下の実施の形態に限られるわけではない。
【００１１】
（装置構成）
図１に、本実施の形態に係る行列ベクトル積演算装置の機能構成図を示す。図１に示すように、本実施の形態の行列ベクトル積演算装置は、ベクトル入力部(M2)、行列演算実行部（M3）、計算結果出力部(M4) 、データ入力部(M5)、ZDD構築部(M6)、データ記憶部(M7)を有する。
【００１２】
ベクトル入力部(M2)では、乗算の対象となる実数ベクトルを外部から受け取り行列演算実行部（M3）に渡す。行列演算実行部(M3)では、データ記憶部（M7）に格納された二値行列と、ベクトル入力部(M2)から与えられたベクトルとの積を計算する。
【００１３】
なお、図１に示すように、行列ベクトル積演算装置は、ハードウェア的にはキャッシュメモリを備えた中央演算装置(M1)を含み、二値行列とベクトルとの積の演算を含む各種の演算は当該中央演算装置(M1)で実行される。行列演算実行部（M3）は、この中央演算装置(M1)により実現される二値行列とベクトルとの積の演算機能を有する機能部である。
【００１４】
行列演算実行部（M3）により計算された結果は、計算結果出力部(M4)から外部に出力される。データ入力部(M5)は、二値行列を受け取る。ZDD構築部(M6)は、データ入力部(M5)から受け取った二値行列をZDDに変換し、それをデータ記憶部(M7)に保管する機能を有する。
【００１５】
行列ベクトル積演算装置は、上記中央演算装置(M1)及びデータ記憶部（M7)等を備えたコンピュータに、本実施の形態で説明する処理に対応するプログラムを実行させることにより実現可能である。当該プログラムは、可搬メモリ等の記憶媒体に格納して配布し、上記装置にインストールして用いてもよいし、ネットワーク上のサーバからダウンロードして上記装置にインストールしてもよい。
【００１６】
また、図１に示す行列ベクトル積演算装置は、複数のコンピュータで実現してもよい。例えば、ZDD構築部(M6)を別のコンピュータに備え、当該別のコンピュータで算出したZDDの配列データを、行列演算実行部（M3）とデータ記憶部（M7）を含むコンピュータ（これを行列ベクトル積演算装置と呼んでもよい）におけるデータ記憶部（M7）に格納して行列ベクトル積の演算を行ってもよい。
【００１７】
（ZDDについて）
本実施の形態に係る処理を説明する前に、まず、ZDDについて簡単に説明しておく。なお、ZDD自体は既存技術である。
【００１８】
ZDDは、組み合わせ集合を二分グラフの形で保持するデータ構造である。ここで、組み合わせ集合とは、あるアイテムの集合A= {a1, a2, ..., }に対して、e⊆Aであるようなeを要素とする集合のことである。例えば、集合B = {a, b, c}に対し、集合{{a,c}, {b}, {c}}はBの組み合わせ集合である。
【００１９】
ZDDによって組み合わせ集合を表した例を図２に示す。ZDDは指向性をもったグラフ構造であり、ノードには0または1のラベルをもった終端ノードと、対応するアイテムのラベルをもった中間ノードの2種類がある。各中間ノードはHIリンク、LOリンクとよばれる2つの子ノードを指すリンクを持つ。また、ひとつのZDDには先頭のノードを表すポインタがある。図２(a)は組み合わせ集合{{a,c}, {b}, {c}}を表すZDDである。図中では、終端ノードは四角のノード、中間ノードは丸いノード、HIリンクは実線の矢印、LOリンクは破線の矢印、先頭ノードを表すポインタは実線の矢印でそれぞれ表現される。各ノード中の文字は、ノードのラベルを表す。ある組み合わせeが、ZDDが表す組み合わせ集合に含まれるかどうかは、以下の手続きによって知ることができる。まず、ZDDの先頭ノードを表すポインタに沿って、先頭ノードに遷移する。そこで、先頭ノードのラベルが表すアイテムがeに含まれているならHIリンクが指すノードに遷移し、そうでないならLOリンクが指すノードに遷移する。以上の手続きを最終的に終端ノードにたどり着くまで実行し、最終的にラベル1をもつ終端ノードに遷移し、かつeに含まれるすべてのアイテムに対応するノードを遷移してきているなら、eは組み合わせ集合に含まれる。そうでないならeは組み合わせ集合に含まれない。
【００２０】
図２(a)のZDDは、計算機上では、図２(b)のように、ノードIDをインデックスとする配列として表現される。配列の一つの要素には、ノードのラベル、HIリンク先のノードID、LOリンク先のノードIDが格納されている。以下、ノードIDがiであるノードのラベルをv(i)、HIリンク先のノードのノードIDをHI(i)、LOリンク先ノードのノードIDをLO(i) と表す。ある組み合わせ集合をZDDとして表すときには、アイテム間にあらかじめ順序を定められており、ZDD中ではあるノードのラベルであるアイテムとその子ノードのラベルであるアイテムとを比較したときに、必ず子ノードのアイテムのほうが、順序が後になるという制約がある。本実施の形態のZDDでは、アイテムa, b, cの間にa, b, cの順で順序が定められているものとする。また、配列中では、i > 2のときに常にHI(i) < i, LO(i) < iが成り立つように構成されているものとする。
【００２１】
（行列ベクトル積演算装置の処理動作）
以下、本実施の形態に係る行列ベクトル積演算装置の処理を図３のフローチャートに示す手順に沿って説明する。
【００２２】
まず、ステップS01において、データ入力部（M5）より行列を受け取る。行例はZDD構築部（M６）に渡され、ステップS02で、ZDD構築部（M６）は、行列から対応するZDDを構築する。このZDDの構築自体は既存技術であり、非特許文献1に開示された手法を用いることができる。また、本実施の形態では、非特許文献1に開示されているように、行分割による節点数削減も行っている。
【００２３】
行分割単位L（Lは１以上であり、行列の列数Mよりも小さい整数）を３としたときの、二値行列と対応するZDD、およびその配列上の表現について、図４A〜４Cに示す。図４Aの二値行列に対応する組み合わせ集合は、行分割単位が 3のときに
【００２４】
【数１】
0005736336.tif 000002
となり、対応するZDDは図４B、その配列上での表現は図４Cのようになる。ここで、各シンボルr1,....r3は行列の各行に対応するシンボルであり、e1,....,e6は各列に対応するシンボルである。また、図４B中では，0終端節点に達する0枝は省略してある。
【００２５】
図４C中の先頭フィールドには、そのノードが分割された行列の各行で最左の1に対応するノードであった場合に、その行に対応する番号の列が与えられる。例えば、図４Cにおいて、ノードIDが３であるe6は、図４Aに示すように、分割された右側の行列の２行目で最左の１（左から見て最初に登場する１）に対応しているので、先頭フィールドに２が追加されている。なお、先頭ノードの値の設定はステップS03で行うため、この時点ではすべてのノードについて先頭フィールドは空とする。レベルNoフィールドには、同じラベルを持つノードのうち何番目のノードであるかを示す整数が与えられる。この値は配列作成時に付与するものとする。
【００２６】
行列演算実行部（M3）（又はZDD構築部（M６））は、ステップS03で先頭ノードマーク処理を行う。この処理を図５に示すフローチャートを用いて説明する。
【００２７】
v(i)=r1, r2, ..., rNとなるN個のノードについて順に処理する（ステップS31）。r1, r2, ..., rNの各ラベルをもったノードはそれぞれ一つしか存在しないため、行列の行数がNなら処理はN回繰り返される。次にj = hi(i)を取り出し（ステップS32）、それが１でないなら（すなわち0終端節点でないなら）配列のj番目の要素の先頭フィールドに、対応するrkの添字kを追加する（ステップS33、S34)。次にj = lo(j)と更新し（ステップS35)、0終端節点にたどり着くまで同様の手順を繰り返す。
【００２８】
例えば、図４Cの例では、最初に、j = hi(13)＝1となるから、次のノードr2に進み、j = hi(12)＝7になるから７番目のノードの先頭ノードフィールドに２を追加する。次に、j=3となるから、３番目のノードの先頭ノードフィールドに２を追加する。このようにして処理が進められる。
【００２９】
行列演算実行部（M3）は、ステップS04 において、実数ベクトルをベクトル入力部（M2）から受け取る。受け取ったベクトルをq、qのi番目の要素をqiと表す。そして、行列演算実行部（M3）は、行列とベクトルの積を計算する行列演算処理を行う（ステップS05)。
【００３０】
以下、図６のフローチャートを用いて行列とベクトルの積を計算する処理を詳細に説明する。計算においては、出力を格納する大きさNの記憶領域scoreと、一時的な計算結果を書き込む大きさN×L+1の記憶領域dataを用意する。これらの記憶領域は、中央演算装置におけるキャッシュメモリ（演算データ記憶手段）として実現されるものである。
【００３１】
まず、ステップS51でM次元の実数値のベクトルqを入力として受け取る。次に、ステップS52でscoreのN個の値全てとdataのN×L+1個の値全てを0に初期化する。
【００３２】
次に、iを3からZDDの配列のサイズ−Nまで変化させて繰り返しS54〜S58を実行する（ステップS53）。ここで，ZDDの配列のサイズとは、ZDDを計算機上に配列として表現したときの配列の要素数であり、例えば図４AのZDDのサイズは、13である。この図４Aの例では、iを3から10(=13-3)まで繰り返すことになる。
【００３３】
ステップS54では、data[address(i)]の値を、qjとdata[address(HI(i))]の値の和に更新する。ここで、jはv(i) =ejであるような値とする。address(i)は配列data中での位置を示す関数であり、以下のように定義する。
【００３４】
【数２】
0005736336.tif 000003
上記の数式において、num(i)は節点iのレベルNoである。address(i) の取りうる値は[1, N×L+1]であり、非特許文献1のように節点数個の記憶領域を用意する必要がなくなるため、CPUキャッシュヒット率が上昇する効果が得られる。
ステップS55でiの先頭ノードフィールドが空でないかを調べ、空でなければステップS56に遷移する。空ならばステップS59に遷移する。ステップS56、S57では、各先頭ノードフィールドについて、score[j] = score[j] + data[address(i)]を計算することによりscore[j]を更新する処理を行う。
【００３５】
処理が終了すると、scoreの値（N個の値）が演算結果のベクトルとして計算結果出力部（M4）から出力される。
【００３６】
（実施の形態の効果）
既存手法では、計算のある時点からアクセスされなくなる記憶領域があるが、本実施の形態では、このことに着目し、計算途中にアクセスする必要がある記憶領域を削減し、CPUキャッシュヒット率を高めている。
【００３７】
本実施の形態に係る技術を利用することにより、二値行列と実数ベクトルとの乗算において、計算に利用する記憶領域を削減し、CPUキャッシュヒット率を増加させることができるため、処理速度を速めることができる。
【００３８】
本発明は、上記の実施の形態に限定されることなく、特許請求の範囲内において、種々変更・応用が可能である。
【符号の説明】
【００３９】
M1  中央演算装置
M2  ベクトル入力部
M3  行列演算実行部
M4  計算結果出力部
M5  データ入力部
M6  ZDD構築部
M7  データ記憶部
【図１】
0005736336.tif 000006
【図２】
0005736336.tif 000007
【図３】
0005736336.tif 000008
【図４Ａ】
0005736336.tif 000009
【図４Ｂ】
0005736336.tif 000010
【図４Ｃ】
0005736336.tif 000011
【図５】
0005736336.tif 000012
【図６】
0005736336.tif 000013