SCSL ユーザガイド 第2.2版 - 日本SGI

SCSL ユーザガイド 第2.2版 - 日本SGI SCSL ユーザガイド 第2.2版 - 日本SGI

26.12.2014 Views

SGI 科 学 技 術 計 算 ライブラリ SCSL (Scientific Computing Software Library) ユーザガイド 第 2.2 版

SGI 科 学 技 術 計 算 ライブラリ<br />

<strong>SCSL</strong><br />

(Scientific Computing Software Library)<br />

ユーザガイド<br />

第 2.2 版


第 2.2 版<br />

平 成 20 年 7 月 16 日<br />

改 訂 履 歴<br />

版 番 号 日 付 変 更 内 容<br />

第 2.2 版 平 成 20 年 7 月 16 日 ・ 第 5 章 、 PDSLDLT_SOLVEM 、 及 び<br />

DPSLDU_SOLVEM の 仕 様 変 更 に 伴 う 引 数 説 明 の 追<br />

加<br />

・プログラム 例 において Frank 行 列 の 名 称 を 削 除 。<br />

また、 利 用 されているテスト 行 列 の 定 義 を 追 加<br />

第 2.1 版 平 成 17 年 1 月 26 日 ・ 第 5 章 、 第 5.5.4 節 の 引 数 一 覧 の convtol の 説 明<br />

を 修 正<br />

第 2.0 版 平 成 15 年 6 月 1 日 ・レイアウト 修 正<br />

・ 第 4 章 、 第 4.3.1 節 、 及 び 第 4.3.2 節 においてサン<br />

プルプログラムと 実 行 例 を 追 加<br />

第 1.1 版 平 成 13 年 10 月 29 日 ・ 第 5 章 、 第 5.5 節 において、 疎 行 列 の 反 復 解 法<br />

DIterative ルーチンの 説 明 を 追 加<br />

・ 第 6 章 において、 乱 数 発 生 ルーチンについての 説<br />

明 を 追 加<br />

・ 各 ライブラリについて、サンプルプログラムを 追 加<br />

・ 各 ライブラリについて、 性 能 グラフを 追 加<br />

第 1.0 版 平 成 13 年 4 月 27 日<br />

新 規 作 成<br />

本 マニュアルのお 問 い 合 わせは、 下 記 アドレス 宛 てにお 送 りください。<br />

tech_doc_lib_qa@sgi.co.jp<br />

よろしくお 願 いいたします。<br />

- i -<br />

日 本 SGI 株 式 会 社


1. はじめに...................................................................................................................................................................................1<br />

1.1. <strong>SCSL</strong> に 含 まれるルーチン ....................................................................................................................................1<br />

1.1.1. FFT ライブラリ ....................................................................................................................................................1<br />

1.1.2. BLAS ライブラリ.................................................................................................................................................2<br />

1.1.3. LAPACK ライブラリ...........................................................................................................................................2<br />

1.1.4. 疎 行 列 の 直 接 解 法 、 反 復 解 法 ....................................................................................................................2<br />

1.1.5. 乱 数 発 生 ルーチン............................................................................................................................................2<br />

1.2. 精 度 ..................................................................................................................................................................................2<br />

1.3. 計 算 インテンシティ.....................................................................................................................................................3<br />

1.4. コンパイルとリンク......................................................................................................................................................3<br />

1.5. 並 列 化 .............................................................................................................................................................................4<br />

1.5.1. OMP_NUM_THREADS......................................................................................................................................4<br />

1.5.2. OMP_DYNAMIC..................................................................................................................................................5<br />

1.5.3. MPC_GANG .........................................................................................................................................................5<br />

1.6. 8 バイト 整 数 ..................................................................................................................................................................6<br />

1.7. C/C++プロトタイプ......................................................................................................................................................6<br />

1.7.1. FFT ライブラリ 及 び BLAS ライブラリ.........................................................................................................6<br />

1.7.2. LAPACK ライブラリ 及 び 疎 行 列 の 直 接 解 法 、 反 復 解 法 ....................................................................7<br />

1.8. マルチスレッドセーフ.................................................................................................................................................7<br />

1.9. C プログラムからの <strong>SCSL</strong> の 呼 び 出 し.............................................................................................................7<br />

1.9.1. BLAS ライブラリ、FFT ライブラリ、 疎 行 列 の 直 接 解 法 、 反 復 解 法 ................................................8<br />

1.9.2. LAPACK ライブラリ........................................................................................................................................ 11<br />

1.10. インストールと 使 用 方 法 ........................................................................................................................................ 16<br />

1.10.1. Modules の 利 用 方 法 .................................................................................................................................... 16<br />

1.11. ドキュメント ................................................................................................................................................................. 17<br />

1.12. 参 考 文 献 ..................................................................................................................................................................... 18<br />

2. FFT ルーチン ...................................................................................................................................................................... 19<br />

2.1. データ 型 ...................................................................................................................................................................... 19<br />

2.2. 関 数 一 覧 ..................................................................................................................................................................... 20<br />

2.3. 注 意 ............................................................................................................................................................................... 20<br />

2.4. Real-to-complex FFT............................................................................................................................................ 23<br />

2.4.1. SCFFT のアプリケーションプログラムインターフェース (API) ..................................................... 24<br />

2.4.2. DZFFT のアプリケーションプログラムインターフェース (API)...................................................... 24<br />

2.4.3. 詳 細 ..................................................................................................................................................................... 24<br />

2.4.4. データ 型 ............................................................................................................................................................. 26<br />

- ii -<br />

日 本 SGI 株 式 会 社


2.4.5. 注 意 ..................................................................................................................................................................... 26<br />

2.5. Complex-to-real FFT............................................................................................................................................. 27<br />

2.6. 初 期 化 .......................................................................................................................................................................... 28<br />

2.7. 配 列 の 次 元 及 び 寸 法 ............................................................................................................................................. 28<br />

2.8. 畳 み 込 みルーチン 及 び 相 関 ルーチン ............................................................................................................. 29<br />

2.9. サンプルプログラム ................................................................................................................................................ 30<br />

2.9.1. 1 次 元 real-to-complex FFT DZFFT .................................................................................................... 30<br />

2.10. FFT ルーチンの 性 能 .............................................................................................................................................. 33<br />

3. BLAS ルーチン................................................................................................................................................................... 35<br />

3.1. データ 型 ...................................................................................................................................................................... 35<br />

3.2. マニュアルページ 名 ................................................................................................................................................ 35<br />

3.3. レベル 1....................................................................................................................................................................... 36<br />

3.3.1. 増 分 引 数 ........................................................................................................................................................... 36<br />

3.3.2. FORTRAN での 関 数 の 型 宣 言 .................................................................................................................. 37<br />

3.3.3. サーチ 関 数 ....................................................................................................................................................... 37<br />

3.3.4. 関 数 一 覧 ........................................................................................................................................................... 37<br />

3.4. レベル 2....................................................................................................................................................................... 38<br />

3.4.1. 多 次 元 配 列 ...................................................................................................................................................... 38<br />

3.4.2. 関 数 一 覧 ........................................................................................................................................................... 39<br />

3.5. レベル 3....................................................................................................................................................................... 39<br />

3.5.1. 多 次 元 配 列 ...................................................................................................................................................... 39<br />

3.5.2. 関 数 一 覧 ........................................................................................................................................................... 40<br />

3.6. CBLAS ライブラリ .................................................................................................................................................... 40<br />

3.6.1. ヘッダファイル ................................................................................................................................................. 40<br />

3.6.2. 呼 び 出 し 名 ........................................................................................................................................................ 41<br />

3.6.3. 配 列 引 数 ........................................................................................................................................................... 41<br />

3.6.4. 複 素 数 データ................................................................................................................................................... 42<br />

3.6.5. インデックスを 返 すルーチン...................................................................................................................... 43<br />

3.6.6. 複 素 数 を 返 すルーチン................................................................................................................................ 43<br />

3.6.7. その 他 ................................................................................................................................................................ 43<br />

3.7. サンプルプログラム ................................................................................................................................................ 43<br />

3.7.1. 倍 精 度 スカラー・ベクトル 乗 算 及 びベクトル 同 士 の 和 DASPY ................................................... 44<br />

3.7.2. 倍 精 度 実 一 般 行 列 同 士 の 積 DGEMM ................................................................................................. 46<br />

3.8. BLAS の 性 能 ............................................................................................................................................................. 51<br />

4. LAPACK ルーチン............................................................................................................................................................. 52<br />

4.1. <strong>SCSL</strong> に 含 まれる LAPACK ルーチン.............................................................................................................. 52<br />

- iii -<br />

日 本 SGI 株 式 会 社


4.2. ネーミングスキーム................................................................................................................................................. 53<br />

4.3. サンプルプログラム ................................................................................................................................................ 54<br />

4.3.1. 倍 精 度 実 一 般 行 列 用 連 立 一 次 方 程 式 の 解 法 DGESV................................................................. 54<br />

4.3.2. 倍 精 度 実 帯 行 列 用 連 立 一 次 方 程 式 の 解 法 DGBSV..................................................................... 56<br />

4.3.3. 倍 精 度 実 一 般 行 列 の LU 分 解 DGETRF と LU 分 解 を 用 いた 連 立 一 次 方 程 式 の 解 法<br />

DGETRS 60<br />

4.3.4. 全 部 または 指 定 した 範 囲 の 倍 精 度 実 対 称 固 有 値 問 題 (dqds アルゴリズム) DSYEVR ... 64<br />

4.4. LAPACK の 性 能 ....................................................................................................................................................... 71<br />

5. 疎 行 列 の 直 接 解 法 、 反 復 解 法 .................................................................................................................................... 72<br />

5.1. はじめに ...................................................................................................................................................................... 72<br />

5.2. 注 意 ............................................................................................................................................................................... 73<br />

5.3. DPSLDLT、ZPSLDLT ルーチン ......................................................................................................................... 73<br />

5.3.1. 関 数 一 覧 ........................................................................................................................................................... 74<br />

5.3.2. 詳 細 ..................................................................................................................................................................... 76<br />

5.3.3. 疎 行 列 の 格 納 形 式 ........................................................................................................................................ 77<br />

5.3.4. オーダリングの 方 法 ...................................................................................................................................... 78<br />

5.3.5. 置 換 ベクトル .................................................................................................................................................... 78<br />

5.3.6. 対 角 項 がゼロになる 行 列 ........................................................................................................................... 79<br />

5.3.7. メモリの 使 用 量 ................................................................................................................................................ 79<br />

5.3.8. アウトオブコア 分 解 ........................................................................................................................................ 79<br />

5.3.9. 複 数 の 右 辺 に 対 する 解 ............................................................................................................................... 79<br />

5.3.10. 各 ルーチンの 引 数 の 説 明 .......................................................................................................................... 80<br />

5.3.11. 環 境 変 数 ........................................................................................................................................................... 81<br />

5.4. DPSLDU、ZPSLDU ルーチン.............................................................................................................................. 81<br />

5.4.1. 関 数 一 覧 ........................................................................................................................................................... 81<br />

5.4.2. 詳 細 ..................................................................................................................................................................... 83<br />

5.4.3. 疎 行 列 の 格 納 形 式 ........................................................................................................................................ 84<br />

5.4.4. オーダリングの 方 法 ...................................................................................................................................... 85<br />

5.4.5. 置 換 ベクトル .................................................................................................................................................... 86<br />

5.4.6. 対 角 項 がゼロになる 行 列 ........................................................................................................................... 86<br />

5.4.7. メモリの 使 用 量 ................................................................................................................................................ 87<br />

5.4.8. アウトオブコア 分 解 ........................................................................................................................................ 87<br />

5.4.9. 複 数 の 右 辺 に 対 する 解 ............................................................................................................................... 87<br />

5.4.10. 各 ルーチンの 引 数 の 説 明 .......................................................................................................................... 87<br />

5.4.11. 環 境 変 数 ........................................................................................................................................................... 88<br />

5.5. DIterative ルーチン ................................................................................................................................................ 88<br />

- iv -<br />

日 本 SGI 株 式 会 社


5.5.1. 関 数 一 覧 ........................................................................................................................................................... 89<br />

5.5.2. 詳 細 ..................................................................................................................................................................... 89<br />

5.5.3. 疎 行 列 の 格 納 形 式 ........................................................................................................................................ 90<br />

5.5.4. 引 数 ..................................................................................................................................................................... 92<br />

5.5.5. 環 境 変 数 ........................................................................................................................................................... 93<br />

5.6. サンプルプログラム ................................................................................................................................................ 94<br />

5.6.1. 倍 精 度 実 対 称 疎 行 列 の 直 接 解 法 DPSLDLT.................................................................................... 94<br />

5.6.2. 倍 精 度 実 疎 行 列 の 反 復 解 法 (ヤコビ 前 処 理 付 CG 法 ) ................................................................. 98<br />

5.7. スパースソルバーの 性 能 ...................................................................................................................................103<br />

6. 乱 数 発 生 ルーチン ..........................................................................................................................................................104<br />

6.1. Drand64 ルーチン..................................................................................................................................................104<br />

6.1.1. 関 数 一 覧 .........................................................................................................................................................104<br />

6.1.2. 詳 細 ...................................................................................................................................................................106<br />

6.1.3. 使 用 例 ..............................................................................................................................................................107<br />

6.1.4. 例 1 ....................................................................................................................................................................107<br />

6.1.5. 例 2....................................................................................................................................................................108<br />

6.1.6. 例 3 ....................................................................................................................................................................109<br />

6.1.7. 注 意 ...................................................................................................................................................................110<br />

- v -<br />

日 本 SGI 株 式 会 社


1. はじめに<br />

SGI の 科 学 技 術 計 算 ライブラリ <strong>SCSL</strong> (Scientific Computing Software Library) は、1000 以 上 にもおよぶ<br />

スカラ、ベクトル、 行 列 などに 対 する 浮 動 小 数 点 演 算 (32 ビットおよび 64 ビット)、 整 数 、 論 理 データに 対<br />

する 処 理 をおこなうルーチンを 集 めたものです。 これらは、 線 形 代 数 方 程 式 、 固 有 値 解 析 、 行 列 演 算 、<br />

疎 行 列 、 高 速 フーリエ 変 換 (FFT)、 信 号 処 理 などの 処 理 を 含 んでいるので、ユーザはプログラム 開 発 に<br />

労 力 を 割 くことなく、 適 切 な <strong>SCSL</strong> ライブラリを 呼 ぶだけで 望 む 処 理 を 行 うことができます。<br />

これらのルーチンは、FORTRAN の 慣 習 にしたがったデータの 格 納 、 引 数 の 受 け 渡 しを 採 用 しており、<br />

FORTRAN から 呼 び 出 せるように 設 計 されています。すべての 行 列 要 素 を、FORTRAN の 慣 習 に 従 い 列<br />

方 向 を 優 先 して 主 記 憶 上 の 連 続 した 領 域 に 格 納 していますが、C プログラムから 利 用 することも 可 能 で<br />

す。その 際 、 複 素 数 型 データおよび 文 字 列 データの 引 き 渡 し、 行 列 データの 格 納 形 式 の 相 違 などについ<br />

て 注 意 を 払 う 必 要 があります。 詳 細 は、1-9 節 の“C プログラムからの <strong>SCSL</strong> の 呼 び 出 し”をご 参 照 くだ<br />

さい。<br />

<strong>SCSL</strong> に 含 まれるルーチンの 多 くはマルチプロセッサシステムのために、 計 算 インテンシティの 改 善 、ソフ<br />

トウェア・パイプライニング、キャッシュ 管 理 、 並 列 プログラミング[1]などの 最 適 化 がなされています。<br />

1.1. <strong>SCSL</strong> に 含 まれるルーチン<br />

<strong>SCSL</strong> には、 以 下 のようなルーチンが 含 まれます。<br />

• FFT ライブラリ (FFT ルーチン 及 び 線 形 フィルタリングルーチン)<br />

• BLAS ライブラリ<br />

• LAPACK ライブラリ<br />

• 疎 行 列 の 直 接 解 法 、 反 復 解 法<br />

• 64bit のスレッドセーフな 乱 数 ジェネレータ<br />

1.1.1. FFT ライブラリ<br />

FFT サブライブラリは、 高 速 フーリエ 変 換 を 行 なうためのルーチンより 成 り 立 っています。1 次 元 、2 次 元 、<br />

3 次 元 の FFT 及 び 複 数 の1 次 元 データに 対 する 多 重 FFT ルーチンが 含 まれています。<br />

また、 畳 み 込 みルーチン 及 び 相 関 ルーチン 等 の 線 形 フィルタリングルーチンが 含 まれています。<br />

1<br />

日 本 SGI 株 式 会 社


1.1.2. BLAS ライブラリ<br />

BLAS (Basic Linear Algebra Subprograms) サブライブラリは、 線 形 代 数 計 算 における 多 くの 重 要 なルー<br />

チンを 提 供 します。BLAS には、BLAS1、BLAS2、BLAS3 で 表 わされる3のレベルの 130 種 類 を 超 えるサ<br />

ブプログラム[2] [3] [4] があります。<br />

また、LAPACK サブライブラリは、 多 くの BLAS ルーチンをカーネルルーチンとして 引 用 しています。<br />

1.1.3. LAPACK ライブラリ<br />

LAPACK ライブラリは、 線 形 代 数 計 算 、 最 小 自 乗 法 、 固 有 値 問 題 、 特 異 点 問 題 などの 多 くの 線 形 代 数 問<br />

題 の 数 値 解 析 に 共 通 するサブルーチンのライブラリです。これらは、 多 くのコンピュータの 上 で 高 速 に 動<br />

作 するように 設 計 されています。<br />

1.1.4. 疎 行 列 の 直 接 解 法 、 反 復 解 法<br />

疎 行 列 に 対 する 直 接 解 法 および 反 復 解 法 ルーチンを 提 供 します。 対 称 及 び 非 対 称 行 列 それぞれについ<br />

て 解 法 ルーチンが 用 意 されています。<br />

1.1.5. 乱 数 発 生 ルーチン<br />

64bit スレッドセーフな 乱 数 発 生 ルーチンを 提 供 します。 並 列 処 理 において、 異 なるプロセッサ 間 で 独 立<br />

な 乱 数 列 を 生 成 するように 設 計 されています。<br />

1.2. 精 度<br />

ライブラリには、32 ビット 精 度 と 64 ビット 精 度 のものがあります。これらは、 標 準 的 な “S”,“ D”, “C”,<br />

“Z” を 用 いたライブラリ 名 の 慣 例 に 従 っています。<br />

S 単 精 度 実 数 (32 ビット) REAL*4, REAL<br />

D 倍 精 度 実 数 (64 ビット) REAL*8, DOUBLE PRECISION<br />

C 単 精 度 複 素 数 (32 ビット) COMPLEX*8, COMPLEX<br />

Z 倍 精 度 複 素 数 (64 ビット) COMPLEX*16, DOUBLE COMPLEX<br />

2<br />

日 本 SGI 株 式 会 社


1.3. 計 算 インテンシティ<br />

メモリとのデ−タ 参 照 は、これらのルーチンの 性 能 に 重 要 な 影 響 をもたらします。 演 算 回 数 と 参 照 される<br />

データ 量 の 比 率 は 計 算 インテンシティ[5][6]と 呼 ばれ、 次 式 で 定 義 されます。<br />

計 算 インテンシティ = 演 算 回 数 / 参 照 されたデータワード 数 (1)<br />

数 値 計 算 の 分 野 において 演 算 回 数 は、 通 常 、 浮 動 小 数 点 演 算 を 表 わし、また、 整 数 演 算 が 支 配 的 な 計<br />

算 においては 整 数 演 算 回 数 に 等 しくなります。<br />

この 計 算 インテンシティは、あるメモリシステム 上 においてそのシステムのメモリバンド 幅 が 明 らかになれ<br />

ば、 性 能 予 測 に 活 用 することが 可 能 です。<br />

演 算 性 能 = 計 算 インテンシティ × メモリバンド 幅 (2)<br />

( 演 算 回 数 / 秒 ) = ( 演 算 回 数 / ワード) X (ワード / 秒 ) (3)<br />

(2), (3) 式 では、あるアプリケーションに 対 して、メモリシステムが 提 供 できるデータ 供 給 量 に 制 限 される 最<br />

大 の 性 能 を 与 えます。また、ここではシステムの 浮 動 小 数 点 演 算 能 力 については 触 れていませんが、し<br />

ばしば、 実 際 の 性 能 に 良 い 予 測 を 与 えます。 計 算 インテンシティを 大 きくすることにより、どんなメモリシ<br />

ステムにあっても、その 実 行 性 能 は 向 上 します。<br />

表 1-1 に BLAS のそれぞれのレベルとその 計 算 インテンシティの 見 積 りを 合 わせて 示 します。<br />

表 1-1 BLAS の 計 算 インテンシティ<br />

BLAS BLAS 演 算 回 数 使 用 した 計 算 インテンシティ<br />

ルーチン レベル ワード 数 ( 演 算 回 数 /ワード 数 )<br />

DAXPY BLAS1 2N 3N 2/3<br />

DGEMV BLAS2 2N 2 N 2 2<br />

DGEMM BLAS3 2N 3 /3 2N 2 N/3<br />

より 高 いレベルの BLAS ルーチンを 使 用 することで、より 高 い 性 能 を 発 揮 することが 可 能 となります。<br />

<strong>SCSL</strong> では、 計 算 インテンシティが 高 いルーチンについては 並 列 化 による、よりいっそうの 高 速 化 が 可 能<br />

となっています。<br />

1.4. コンパイルとリンク<br />

多 くの <strong>SCSL</strong> ルーチンは 並 列 化 されており、シリアル 版 と 並 列 版 の 2 つのライブラリがあります。<strong>SCSL</strong> の<br />

3<br />

日 本 SGI 株 式 会 社


シリアル 版 をリンクするためには、-lscs をリンク 行 の 末 尾 に 追 加 します。<br />

% f77 foo.f -lscs<br />

並 列 版 をリンクする 場 合 には、-lscs_mp を 使 用 します。また、 並 列 化 コードをリンクする 場 合 には、 必 ず<br />

-mp フラグを 指 定 して MP ライブラリをリンクしなければなりません。<br />

% f77 -mp bar.f -lscs_mp<br />

<strong>SCSL</strong> は 標 準 数 学 ライブラリを 使 用 しているため、<strong>SCSL</strong> のリンクの 後 に、libm または libfastm をリンクす<br />

る 必 要 があります。FORTRAN の 場 合 には、libm は 自 動 にリンクされるので 指 定 する 必 要 はありません。<br />

libfastm は、 標 準 数 学 ライブラリ libm に 含 まれるルーチンのサブセットであり、 高 度 に 最 適 化 されたルー<br />

チンの 集 まりです。libfastm の 最 適 化 ルーチンには、 単 精 度 、 倍 精 度 の sin, cos, tan, exp, log, powなどが<br />

含 まれます。<br />

C/C++で 書 かれたプログラムである 場 合 は、 明 示 的 に –lm もしくは –lfastm をリンクする 必 要 がありま<br />

す。<br />

1.5. 並 列 化<br />

十 分 な 大 きさ ( 計 算 粒 度 ) をもった 問 題 に 対 し、 複 数 のプロセッサを 備 えたシステムでは 並 列 化 は 性 能<br />

を 向 上 させます。<strong>SCSL</strong> ルーチンは、ユーザが 指 定 したプロセッサ 数 に 従 って 並 列 処 理 を 行 ないます。<br />

<strong>SCSL</strong> は、 並 列 処 理 の 実 行 が 可 能 な 並 列 版 とシリアル 版 の2つのバージョンが 用 意 されています。 並 列<br />

処 理 を 行 う 場 合 には、 並 列 版 をリンクすることが 必 要 です。<br />

リンク 方 法 につきましては、1.4 節 の「コンパイルとリンク」をご 参 照 ください。<br />

1.5.1. OMP_NUM_THREADS<br />

<strong>SCSL</strong> の 並 列 版 を 使 用 する 場 合 、ルーチンで 使 用 するプロセッサ 数 を 指 定 するためには、 環 境 変 数<br />

OMP_NUM_THREADS を 指 定 しなければなりません。csh で、10 プロセッサを 使 用 する 場 合 には、 以 下<br />

のようにします。<br />

% setenv OMP_NUM_THREDS 10<br />

4<br />

日 本 SGI 株 式 会 社


一 方 、sh を 使 用 している 場 合 には、<br />

$ OMP_NUM_THREDS=10; export OMP_NUM_THREDS<br />

のようにします。<br />

これらの 値 を 設 定 すると、 実 行 時 に 使 用 される 最 大 の CPU 数 は、OMP_NUM_THREDS で 指 定 された<br />

値 になります。<br />

また、 以 下 に 並 列 処 理 時 に 設 定 すべき 環 境 変 数 を 示 します。<br />

1.5.2. OMP_DYNAMIC<br />

IRIX は、 標 準 ではシステムの 負 荷 によってプログラムの 使 用 するプロセッサ 数 を 変 更 します。 環 境 変 数<br />

OMP_DYNAMIC はこの 機 能 を 制 御 します。OMP_DYNAMIC=TRUE (デフォルト) である 場 合 、システムの<br />

負 荷 を 常 に 監 視 する 必 要 があり、そのためのオーバーヘッドがかかりますが、システムの CPU 数 以 上 の<br />

プロセスが 同 時 に 実 行 されないようにしてシステムの 運 用 効 率 を 上 げます。システムが 比 較 的 空 いてい<br />

る 場 合 などには、OMP_DYNAMIC=FALSE にすることをお 勧 めします。<br />

csh で、OMP_DYNAMIC を 設 定 する 場 合 には、 以 下 のようにします。<br />

% setenv OMP_DYNAMIC FALSE<br />

1.5.3. MPC_GANG<br />

環 境 変 数 MPC_GANG は、プロセスのスケジューリングについて、GANG スケジューリングと 呼 ばれる 手<br />

法 で 実 行 することを 指 定 します。 一 般 には、GANG スケジューリングは OpenMP や 自 動 並 列 化 機 能 によ<br />

り 並 列 化 されたプログラムの 実 行 の 際 には 非 効 率 となるため、この 機 能 をオフにします。<br />

csh で、MPC_GANG を 設 定 する 場 合 には、 以 下 のようにします。<br />

% setenv MPC_GANG OFF<br />

並 列 処 理 時 の 最 大 性 能 は、プロセッサが 他 の 仕 事 に 用 いられていない 状 況 でのみ 得 られます。 例 えば、<br />

40 プロセッサ 構 成 のシステムで 複 数 のジョブが 30 プロセッサを 使 用 しているような 場 合 、まだ 10 プロセ<br />

ッサは 余 裕 があるため、10 プロセッサを 使 用 するようなジョブを 投 入 することには 意 味 がありますが、こ<br />

のような 状 況 でさらに 40 プロセッサを 使 用 する 並 列 化 されたプログラムを 投 入 したところで 最 大 の 高 速<br />

5<br />

日 本 SGI 株 式 会 社


化 を 得 ることはできません。<br />

1.6. 8 バイト 整 数<br />

-lscs あるいは、-lscs_mp の 指 定 でリンクされる <strong>SCSL</strong> ライブラリの 整 数 型 引 数 の 大 きさは 4 バイト (32<br />

ビット) です。<strong>SCSL</strong> には、 整 数 型 引 数 の 大 きさを 8 バイト (64 ビット) としたバージョンもあります。この 8<br />

バイト 整 数 データを 扱 うことが 可 能 なルーチンは、 大 きな 配 列 データを 処 理 したり、 整 数 型 データが 8 バ<br />

イトであったシステムで 開 発 されたコードの 移 植 には 便 利 です。こちらを 使 用 する 場 合 は、-lscs_i8 あるい<br />

は-lscs_i8_mp オプションを 指 定 します。1 本 のプログラムでは、4 バイト 整 数 型 あるいは 8 バイト 整 数 型 の<br />

どちらか 一 方 のバージョンを 使 用 することが 可 能 ですが、 両 者 を 混 在 させることは 出 来 ません。<br />

1.7. C/C++プロトタイプ<br />

1.7.1. FFT ライブラリ 及 び BLAS ライブラリ<br />

信 号 処 理 ルーチンに 関 する C/C++ 関 数 プロトタイプは、4 バイト 整 数 を 使 う 場 合 は、<br />

()で 提 供 され、8 バイト 整 数 を 使 う 場 合 は、 () で 提 供 されます。<br />

これらのヘッダファイルでは、 複 素 数 型 である scsl_complex と scsl_zomplex を 定 義 しています。これらの<br />

型 は、プロトタイプで 使 用 されます。あるいは、C++プログラムでは、 標 準 クラスライブラリ (STL) の<br />

complexと complex 型 を 用 いた 引 数 を 宣 言 しているかもしれません。しかし、これらの 型<br />

が 使 用 された 場 合 、は、 () (もしくは、<br />

()) の 前 でインクルードする 必 要 があります。 一 方 で、2 つの 複 素 数 タイプは 同 等 であると<br />

いう 点 に 注 意 する 必 要 があります。すなわち、 複 素 数 タイプは、( 実 数 部 , 虚 数 部 )というようにメモリ 上 に<br />

連 続 的 に 格 納 された 浮 動 小 数 点 数 の 対 として 表 現 されます。 適 切 なキャストによって、 複 素 数 の 引 数 を<br />

持 つルーチンに 浮 動 小 数 点 データの 配 列 が 渡 されます。<br />

しかしながら、キャストは 無 効 化 される 可 能 性 もあります。ヘッダファイルである と<br />

では 直 接 ユーザ 定 義 の 複 素 数 タイプを 使 用 するか、もしくは、 複 素 数 引 数 に 関 するプロトタ<br />

イプのチェックが 完 全 に 行 われないように 定 義 されています。もしくは、をインク<br />

ルードする 前 に シンボル <strong>SCSL</strong>_VOID_ARGS を 定 義 することによって、 全 ての 複 素 数 引 数 は、void * と<br />

してプロトタイプされます。シンボル <strong>SCSL</strong>_VOID_ARGS を 定 義 するためには、コンパイル 時 に -D コン<br />

パイラオプションを 使 うか ( 即 ち、-D<strong>SCSL</strong>_VOID_ARGS) 、もしくは、 明 示 的 にソースコード 内 で #define<br />

<strong>SCSL</strong>_VOID_ARGS を 定 義 します。こう<br />

することにより、コンパイル 時 にコンパイラからの 警 告 なく 複 素 数 型 のデータ 構 造 を 使 用 可 能 にし、 上 記<br />

で 述 べた 構 造 が 提 供 されます。すなわち、<br />

6<br />

日 本 SGI 株 式 会 社


1. 実 部 と 虚 部 はメモリ 上 で 連 続 である 必 要 がある。<br />

2. 連 続 的 な 配 列 要 素 もメモリ 上 で 連 続 である 必 要 がある。<br />

コンパイラからの 警 告 なく、 標 準 でない 複 素 数 型 が 利 用 可 能 になりますが、コンパイラが 型 のミスマッチ<br />

を 捉 えられないという 不 都 合 も 生 じます。<br />

<strong>SCSL</strong> 標 準 の 複 素 数 型 の 代 わりに、ユーザ 定 義 の 複 素 数 型 を 用 いることによって、 強 制 的 な 型 チェック<br />

が 可 能 で す 。 こ の た め に 、 <strong>SCSL</strong>_USER_COMPLEX_T=my_comlex と<br />

<strong>SCSL</strong>_USER_ZOMPLEX_T=my_zomplex を 定 義 します。my_complex と my_zomplex は、ユーザ 定 義 の 複 素<br />

数 型 の 名 前 です。これらの 複 素 数 型 は (もしくは、) ヘッダファイルをインク<br />

ルードする 前 に 定 義 される 必 要 があります。<br />

1.7.2. LAPACK ライブラリ 及 び 疎 行 列 の 直 接 解 法 、 反 復 解 法<br />

C/C++ 関 数 プロトタイプは、<strong>SCSL</strong> の 4 バイト 整 数 については 適 切 に 行 われます。8 バイト 整 数 のバージョ<br />

ンを 使 用 する 時 は、int 型 の 変 数 は long long 型 になり、LAPACK ライブラリを 使 用 の 場 合 は<br />

を、 疎 行 列 の 直 接 解 法 、 反 復 解 法 を 使 用 する 場 合 はをインクルードし<br />

なければなりません。<br />

1.8. マルチスレッドセーフ<br />

<strong>SCSL</strong>ルーチンは、マルチスレッドセーフです。したがって、<strong>SCSL</strong>は 並 列 実 行 領 域 から 呼 び 出 された 場 合<br />

にも、 逐 次 実 行 領 域 から 呼 び 出 された 場 合 にも 正 しく 動 作 します。ここで 言 う 並 列 実 行 領 域 とは、ユーザ<br />

あるいはコンパイラによって 定 義 された 複 数 のスレッドでの 処 理 実 行 部 分 です。<br />

また、<strong>SCSL</strong> では、もし 並 列 版 がリンクされたとしても、 並 列 実 行 領 域 から <strong>SCSL</strong> ルーチンが 呼 び 出 された<br />

時 には、<strong>SCSL</strong> ルーチンはシーケンシャルに 実 行 されます ( 各 スレッドはシーケンシャルに <strong>SCSL</strong> ルーチ<br />

ンを 実 行 します)。<br />

1.9. C プログラムからの <strong>SCSL</strong> の 呼 び 出 し<br />

<strong>SCSL</strong> 1.3 からは <strong>SCSL</strong> の LAPACK を 除 くライブラリルーチンに 対 して、ルーチン 名 、プロトタイプ 宣 言 、C<br />

言 語 の 仕 様 にはない 複 素 数 型 を 取 り 扱 うためのヘッダーファイルが 用 意 されました。<br />

以 下 に BLAS ライブラリ、FFT ライブラリ、 疎 行 列 の 直 接 解 法 を C/C++プログラムから 呼 び 出 す 方 法 と<br />

LAPACK ライブラリを C/C++プログラムから 呼 び 出 す 方 法 を 説 明 します。<br />

7<br />

日 本 SGI 株 式 会 社


また、BLAS ライブラリには Basic Linear Algebra Subprograms Technical (BLAST) によって 提 案 された C<br />

インターフェースのライブラリ CBLAS も 存 在 します。これらについては、3.6 節 の“CBLAS ライブラリ”で 説<br />

明 します。<br />

1.9.1. BLAS ライブラリ、FFT ライブラリ、 疎 行 列 の 直 接 解 法 、 反 復 解 法<br />

<strong>SCSL</strong> 1.3 からは <strong>SCSL</strong> の LAPACK の 除 くルーチンに 対 して、ルーチン 名 、プロトタイプ 宣 言 、C 言 語 の 仕<br />

様 にはない 複 素 数 型 を 取 り 扱 うためのヘッダーファイルが 用 意 されました。この 変 更 にともない、 使 用 す<br />

るルーチンに 対 して 次 のヘッダーファイルをインクルードする 必 要 があります。<br />

分 野 man ページ インクルードファイル<br />

BLAS man_intro_blas #include <br />

FFT man_intro_fft #include <br />

疎 行 列 の 解 法 man_intro_solvers #include<br />

• 呼 び 出 し 名<br />

FORTRAN プログラムでは、 大 文 字 、 小 文 字 の 区 別 はありませんが、C/C++プログラムからの 呼 び<br />

出 し 時 には、すべて 小 文 字 になります。 また、man ページの 記 述 にも C/C++からの 呼 び 出 し 方 法 が<br />

明 記 されるようになりました。<br />

( 例 )<br />

FORTRAN: CDOTC ( 大 文 字 、 小 文 字 の 区 別 はありません。)<br />

C: cdotc ( 必 ず 小 文 字 です。)<br />

• 配 列 データの 持 ち 方 の 違 い<br />

FORTRAN では、 列 方 向 優 先 のデータの 持 ち 方 、 一 方 、C では 行 方 向 優 先 のデータの 持 ち 方 なので、<br />

その 違 いに 注 意 してください。<br />

FORTRAN: A(2,2)<br />

A = | 1 3 | -> {1, 2, 3, 4} メモリ 上 の 格 納 順 序<br />

| 2 4 |<br />

C: a[2][2]<br />

a = | 1 2 | -> {1, 2, 3, 4} メモリ 上 の 格 納 順 序<br />

| 3 4 |<br />

8<br />

日 本 SGI 株 式 会 社


以 上 の 点 に 注 意 して 頂 ければ、C プログラムからも 容 易 に <strong>SCSL</strong> の ライブラリを 呼 び 出 すことが 可 能 で<br />

す。<br />

以 下 C プログラムから cdotc を 呼 び 出 す 方 法 を 示 します。<br />

% man cdotc<br />

:<br />

:<br />

C/C++:<br />

#include <br />

scsl_complex cdotc(int n, scsl_complex *x, int incx,<br />

scsl_complex *y, int incy);<br />

scsl_complex cdotu(int n, scsl_complex *x, int incx,<br />

scsl_complex *y, int incy);<br />

:<br />

:<br />

CDOTC/ZDOTC の 演 算 内 容<br />

n<br />

_<br />

dot


double re;<br />

double im;<br />

} __scsl_zomplex;<br />

scsl_blas.h のヘッダーファイルの 中 で FORTRAN の 複 素 数 型 を 構 造 体 を 用 いて 定 義 しているので、 実 部 、<br />

虚 部 はそれぞれ.re, .im のメンバーとして 参 照 可 能 です。<br />

プログラム 例<br />

% cat excdotc.c<br />

#include <br />

#include <br />

#include <br />

#define N 10<br />

int main(void)<br />

{<br />

int i,n,incx,incy;<br />

scsl_complex x[N],y[N];<br />

scsl_complex cdot;<br />

n=N;<br />

incx=1;<br />

incy=1;<br />

for (i=0;i


実 行 例<br />

## リンクオプション – lscs を 指 定 してコンパイル<br />

% cc excdotc.c – lscs<br />

## 実 行<br />

% ./a.out<br />

dot = 20.000000 0.000000<br />

%<br />

1.9.2. LAPACK ライブラリ<br />

LAPACK のライブラリルーチンを C/C++から 呼 び 出 す 場 合 には、 次 の FORTRAN と C/C++の 違 いに 注 意<br />

すれば、C/C++からも 利 用 することが 可 能 です。<br />

• 呼 び 出 し 名<br />

FORTRAN プログラムでは、 大 文 字 、 小 文 字 の 区 別 はありませんが、C/C++プログラムからの 呼 び<br />

出 し 名 は、 小 文 字 名 +_になりますので C から 呼 び 出 す 場 合 は 呼 び 出 し 名 の 違 いに 注 意 してくださ<br />

い。<br />

( 例 )<br />

FORTRAN: SSYEV ( 大 文 字 、 小 文 字 の 区 別 はありません。)<br />

C: ssyev_ ( 必 ず 小 文 字 です。)<br />

• アドレス 渡 し<br />

FORTRAN プログラムの 引 数 は、アドレス 渡 しなので、C のプログラム 側 でも、アドレス 渡 しを 意 識 し<br />

て 記 述 する 必 要 があります。 <strong>SCSL</strong> が 使 用 している 文 字 型 データは、 最 初 の1 文 字 で 判 定 している<br />

ので、 最 初 の 文 字 が 渡 れば 十 分 です。<br />

• 配 列 データの 持 ち 方 の 違 い<br />

FORTRAN では 列 方 向 優 先 のデータの 持 ち 方 、 一 方 、C では 行 方 向 優 先 のデータの 持 ち 方 なので、<br />

その 違 いに 注 意 してください。<br />

FORTRAN: A(2,2)<br />

A = | 1 3 | -> {1, 2, 3, 4} メモリ 上 の 格 納 順 序<br />

| 2 4 |<br />

C: a[2][2]<br />

a = | 1 2 | -> {1, 2, 3, 4} メモリ 上 の 格 納 順 序<br />

| 3 4 |<br />

11<br />

日 本 SGI 株 式 会 社


以 上 3 点 に 注 意 すれば、C プログラムからも 容 易 に <strong>SCSL</strong> のライブラリを 呼 び 出 すことが 可 能 です。 この<br />

3 点 を 確 認 しながら、 同 じプログラムを C と FORTRAN で 記 述 した 以 下 の 例 を 参 照 してください。<br />

C: main.c<br />

FORTRAN: main.f<br />

データの 持 ち 方 は、C で a[i][j]を 表 示 すると、 下 三 角 行 列 のように 見 えますが、FORTRAN 流 に 見 ると 上<br />

三 角 行 列 となり uplo='u'になることに 注 意 してください。<br />

問 題<br />

下 記 で 定 義 されるテスト 行 列 に 対 して、 実 対 称 行 列 用 固 有 値 ソルバ SSYEV を 用 いて、 行 列 の 固 有 値 を<br />

求 めます。C と Fortran でのデータの 持 ち 方 の 違 いをご 確 認 ください。<br />

サイズ N の 行 列 A=a[i][j] が 下 記 の 通 りに 定 義 されます。<br />

a[i][j]= a[j][i] = n+1-i, if i >= j.<br />

サイズ 4 の 場 合 の 行 列 は 下 記 の 通 りです。<br />

プログラム 例<br />

C<br />

12<br />

日 本 SGI 株 式 会 社


% cat main.c<br />

#include <br />

#include <br />

#define N 10<br />

#define LDA (N)<br />

#define LWORK (3*N-1)<br />

static float a[N][LDA],w[N],work[LWORK];<br />

int main(void)<br />

{<br />

char jobz, uplo;<br />

int i,j;<br />

int n, lda, lwork, info;<br />

jobz='n';<br />

uplo='u';<br />

n=N;<br />

lda=LDA;<br />

lwork=LWORK;<br />

/*<br />

*/<br />

set test matrix<br />

for (j=0;j


*/<br />

printf("eigen value \n");<br />

for (i=0;i


parameter(N=10)<br />

parameter(LDA=N,LWORK=3*N-1)<br />

character*1 jobz, uplo<br />

integer i, j, info<br />

common a(LDA,N),w(N),work(LWORK)<br />

!<br />

! set test matrix<br />

!<br />

do j=1,N<br />

do i=1,j<br />

a(i,j)=N-j+1<br />

enddo<br />

enddo<br />

write(*,'(10f8.0)') ((a(i,j),j=1,N),i=1,N)<br />

jobz='n'<br />

uplo='u'<br />

call ssyev( jobz, uplo, N, a, LDA, w, work, LWORK, info );<br />

!<br />

! eigenvalues in ascending order.<br />

!<br />

print *,'eigen value'<br />

write(*,'(10f10.6)') (w(i),i=1,N)<br />

print *,'info = ',info<br />

stop<br />

end<br />

実 行 例<br />

## リンクオプション -lscs を 指 定 してコンパイル<br />

% f90 main.f – lscs<br />

15<br />

日 本 SGI 株 式 会 社


## 実 行<br />

% ./ a.out<br />

10. 9. 8. 7. 6. 5. 4. 3. 2. 1.<br />

0. 9. 8. 7. 6. 5. 4. 3. 2. 1.<br />

0. 0. 8. 7. 6. 5. 4. 3. 2. 1.<br />

0. 0. 0. 7. 6. 5. 4. 3. 2. 1.<br />

0. 0. 0. 0. 6. 5. 4. 3. 2. 1.<br />

0. 0. 0. 0. 0. 5. 4. 3. 2. 1.<br />

0. 0. 0. 0. 0. 0. 4. 3. 2. 1.<br />

0. 0. 0. 0. 0. 0. 0. 3. 2. 1.<br />

0. 0. 0. 0. 0. 0. 0. 0. 2. 1.<br />

0. 0. 0. 0. 0. 0. 0. 0. 0. 1.<br />

eigen vector<br />

0.255680 0.273787 0.307980 0.366209 0.465233 0.643104 1.000001 1.873024<br />

5.048917 44.766079<br />

info = 0<br />

%<br />

1.10. インストールと 使 用 方 法<br />

<strong>SCSL</strong> は、modules 環 境 下 (/opt/scsl/) もしくは、デフォルトのディレクトリ (/ root ファイルシステム) に<br />

インストールされています。modules 環 境 下 では、バージョンの 異 なる <strong>SCSL</strong> ソフトウェアをインストールし、<br />

利 用 することが 可 能 になります。modules を 利 用 するためには、Modules Software をインストールする 必<br />

要 があります。<br />

1.10.1. Modules の 利 用 方 法<br />

modules をシェル 及 びサブシェル 上 で 利 用 するためには、 次 の 設 定 が 必 要 になります。これらの 設 定<br />

は、.cshrc などのユーザドットファイルに 記 述 しておくことをお 勧 めします。<br />

C シェルでの 利 用 方 法 は 次 の 通 りです。<br />

% source /opt/modules/modules/init/csh<br />

% module load modules<br />

% module load scsl<br />

異 なるバージョンの <strong>SCSL</strong> がインストールされている 場 合 には、 以 下 の 方 法 により 使 用 する <strong>SCSL</strong> のバー<br />

ジョンを 変 更 することができます。 例 えば 現 在 使 用 している <strong>SCSL</strong>がバージョン 1.3.0.0 以 前 のものであり、<br />

16<br />

日 本 SGI 株 式 会 社


module コマンドによりバージョン 1.3.0.0 の <strong>SCSL</strong> を 使 用 するように 変 更 するとします。<br />

% module avail<br />

------- /opt/modulefiles --------<br />

MIPSpro mpt nqe scsl scsl1.3.0.0<br />

-------- /opt/modules/modules/modulefiles --------<br />

modules<br />

% module swap scsl scsl.1.3.0.0<br />

“module avail”コマンドにより、modules 環 境 下 にインストールされているソフトウェアの 一 覧 が 表 示 され<br />

ます。“module swap”コマンドにより、<strong>SCSL</strong> のバージョンを 変 更 することができます。<br />

1.11. ドキュメント<br />

<strong>SCSL</strong> のドキュメントは、 各 ルーチンに 対 してオンラインマニュアルが 用 意 されています。 標 準 的 な UNIX<br />

の man コマンドによりルーチン 名 を 指 定 することで 参 照 可 能 です。SGI の 公 開 Web サイトである (Tech<br />

Pubs Library Search, http://techpubs.engr.sgi.com/library/tpl/cgi-bin/init.cgi) からも 利 用 可 能 です。ま<br />

た、<strong>SCSL</strong> を 構 成 する 各 ライブラリの 概 要 を 紹 介 しているマニュアルページ ( 以 下 のページ 名 を 指 定 して<br />

ください。) も 利 用 可 能 です。<br />

• intro_libscsl: <strong>SCSL</strong> ライブラリルーチンの 概 要<br />

• intro_blas1: レベル 1 BLAS ライブラリの 概 要<br />

• intro_blas2: レベル 2 BLAS ライブラリの 概 要<br />

• intro_blas3: レベル 3 BLAS ライブラリの 概 要<br />

• intro_cblas: BLAS ライブラリの C インターフェースについての 概 要<br />

• intro_fft: FFT ライブラリの 概 要<br />

• intro_lapack: LAPACK ライブラリの 概 要<br />

• intro_solvers.3s: 疎 行 列 の 直 接 解 法 、 反 復 解 法 ルーチンの 概 要<br />

出 版 物 としては、SIAM[7] から 出 されている LAPACK User's Guide があります。LAPACK User's Guide<br />

は、すべての LAPACK ルーチンのマニュアルページ、 入 門 的 な 内 容 を 含 んでいます。また、LAPACK<br />

User's Guide の 日 本 語 訳 が 丸 善 [8]より 出 版 されています。<br />

17<br />

日 本 SGI 株 式 会 社


1.12. 参 考 文 献<br />

[1] B. R. Rau and C. D. Glaser, Some scheduling techniques and an easily schedleable horizontal<br />

architecture for high performance scientific computing, in: Proceedings of the Fourteenth Annual<br />

Workshop on Microprogramming(1981) 183-198.<br />

[2] Lawson, C. L., Hanson, R. J., Kincaid, D. R., and Krogh, F. T., "Basic Linear Algebra Subprograms for<br />

FORTRAN Usage", ACM Transactions on Mathematical Software, Volume 5, Number 3, September<br />

1979, Pages 308-323.<br />

[3] Dongarra, J. J., Du Croz, J. J., Hammarling, S., and Hanson, R. J., "An Extended Set of FORTRAN<br />

Basic Linear Algebra Sub-programs". Technical Memorandum No. 41 (Revision 3), Mathematics and<br />

Computer Science Division, Argonne National Laboratory, 9700 South Cass Avenue, Argonne, Illinois<br />

60439.<br />

[4] Dongarra, J. J., Du Croz, J. J.,and Hammarling, S., "A Set of Level 3 Basic Linear Algebra<br />

Subprograms". Technical Memorandum No. 88 (Revision 1), Mathematics and Computer Science<br />

Division, Argonne National Laboratory, 9700 South Cass Avenue, Argonne, Illinois 60439.<br />

[5] R. W. Hockney, r・ , n1/2 , s1/2 measurements on the 2 CPU CRAY X-MP, Parallel Computing<br />

2(1985) 1-14.<br />

[6] R. W. Hockney and C. R. Jesshope, Parallel Computers, Adam Hilger, Philadelphia, Second Edition,<br />

106-108, 1981.<br />

[7] E. Anderson et al, LAPACK User's Guide, Society for Industrial and Applied Mathematics (SIAM),<br />

3600 University City Science Center, Philadelphia, Pennsylvania, 19104-2688.<br />

[8] E. Anderson et al, 小 国 力 訳 . LAPACK 利 用 の 手 引 き, 丸 善 (1995)<br />

18<br />

日 本 SGI 株 式 会 社


2. FFT ルーチン<br />

FFTライブラリでは、 高 速 フーリエ 変 換 (FFT)、 畳 み 込 みルーチン 及 び 相 関 ルーチンから 構 成 される 信 号<br />

処 理 に 関 するルーチンを 提 供 します。<br />

2.1. データ 型<br />

これらのルーチンでは 以 下 のデータ 型 が 使 用 されます。<br />

• 単 精 度 実 数 型 :<br />

FORTRAN の real 型 、C/C++ の float 型 であり、これらは 32 ビット 浮 動 小 数 点 実 数 です。これらの<br />

ルーチン 名 は S で 始 まります。<br />

• 単 精 度 複 素 数 型 :<br />

FORTRANの complex 型 、C/C++の scsl_complex 型 ( で 定 義 されています。) C++ STL<br />

の complex 型 (で 定 義 されています。) であり、これらは 2 つの 32 ビット 浮 動 小<br />

数 点 実 数 です。これらのルーチン 名 は C で 始 まります。<br />

• 倍 精 度 実 数 型 :<br />

FORTRAN の double precision 型 、 C/C++の double 型 であり、これらは 64 ビット 浮 動 小 数 点 実 数<br />

です。これらのルーチン 名 は、D で 始 まります。<br />

• 倍 精 度 複 素 数 型 :<br />

FORTRAN の double complex 型 、C/C++の scsl_zomplex 型 (で 定 義 されています。)、<br />

C++ STL の complex 型 (で 定 義 されています。) であり、これらは 2 つの 64 ビ<br />

ット 浮 動 小 数 点 実 数 です。これらのルーチン 名 は Z で 始 まります。<br />

注 意 : 複 素 数 型 を 定 義 するために C++の 標 準 クラスライブラリ (STL) を 用 いる 時 は、 以 下 の 順 でインク<br />

ルードする 必 要 があります。<br />

#include <br />

#include <br />

入 力 データや 出 力 データのデータ 型 以 外 でもバージョンにより 多 少 の 違 いが 生 じてきます。この 場 合 は、<br />

そのルーチンについて man ページで 説 明 されます。<br />

man(1)コマンドにより、 実 数 、 複 素 数 、 倍 精 度 及 び 倍 精 度 複 素 数 での FFT ルーチンの 名 前 で、オンライン<br />

マニュアルページを 参 照 できます。<br />

上 記 ルーチンの 引 数 である scale, table 及 び work は、 関 数 に 応 じてデータ 型 が 異 なります。ルーチン 名<br />

が CC, SC 及 び CS で 始 まるルーチンでは、これらの 引 数 は 単 精 度 になります。ルーチン 名 が ZZ, DZ 及<br />

19<br />

日 本 SGI 株 式 会 社


び ZD で 始 まるルーチンでは、これらの 引 数 は 倍 精 度 になります。<br />

2.2. 関 数 一 覧<br />

以 下 はサポートされている FFT ルーチンの 一 覧 です。これらのルーチンはそれぞれ、シングルプロセッ<br />

サ 用 に 非 常 に 最 適 化 されています。2 次 元 、3 次 元 及 び 複 数 の 1 次 元 配 列 に 対 する 処 理 ルーチンは、 並<br />

列 化 (マルチスレッド 化 ) されています。それぞれのルーチンは、FFT の 正 変 換 、 逆 変 換 を 行 います。<br />

以 下 の 一 覧 では、 行 は、 列 に 挙 げられたルーチンの 入 力 と 出 力 のデータ 型 を 表 しています。<br />

• C -> C は、32 ビット 複 素 数 の 入 力 と 出 力 であることを 表 しています。<br />

• Z -> Z は、64 ビット 倍 精 度 複 素 数 の 入 力 と 出 力 であることを 表 しています。<br />

• S -> C は、32 ビット 実 数 の 入 力 と 32 ビット 複 素 数 の 出 力 であることを 表 しています。<br />

• D -> Z は、64 ビット 倍 精 度 実 数 の 入 力 と 64 ビット 倍 精 度 複 素 数 の 出 力 であることを 表 しています。<br />

• C -> S は、32 ビット 複 素 数 の 入 力 と 32 ビット 実 数 の 出 力 であることを 表 しています。<br />

• Z -> D は、64 ビット 倍 精 度 複 素 数 の 入 力 と 64 ビット 倍 精 度 実 数 の 出 力 であることを 表 しています。<br />

表 の 列 は、それぞれの 行 の FFT ルーチンに 関 する 次 元 を 表 しています。 1 次 元 (シングル) は、1 次 元<br />

FFT の 計 算 を 行 います。 1 次 元 ( 多 重 ) は、2 次 元 行 列 のそれぞれの 列 (**FFTM) もしくは、 行<br />

(**FFTMR) に 対 して 1 次 元 FFT の 計 算 を 行 います。<br />

--------------------------------------------------------------------------<br />

1 次 元 1 次 元 2 次 元 3 次 元<br />

(シングル) ( 多 重 )<br />

--------------------------------------------------------------------------<br />

C->C CCFFT CCFFTM CCFFTMR CCFFT2D CCFFT3D<br />

Z->Z ZZFFT ZZFFTM ZZFFTMR ZZFFT2D ZZFFT3D<br />

S->C SCFFT SCFFTM SCFFT2D SCFFT3D<br />

D->Z DZFFT DZFFTM DZFFT2D DZFFT3D<br />

C->S CSFFT CSFFTM CSFFT2D CSFFT3D<br />

Z->D ZDFFT ZDFFTM ZDFFT2D ZDFFT3<br />

--------------------------------------------------------------------------<br />

2.3. 注 意<br />

FFT ルーチンは、 多 くの 異 なるアーキテクチャ 上 で 効 率 よく 実 装 出 来 るように 設 計 されています。 呼 び 出<br />

20<br />

日 本 SGI 株 式 会 社


し 手 続 きは、それらの 実 装 で 共 通 です。しかしながら、 一 部 については、 特 定 の 実 装 に 基 いています。<br />

異 なる 部 分 としては、 例 えば、table 配 列 及 び work 配 列 のサイズがあります。 異 なるシステム 上 では、 異<br />

なるサイズが 必 要 になるかもしれません。サブルーチン 呼 び 出 し 部 分 の 変 更 は 必 要 ではありませんが、<br />

DIMENSION 文 での 配 列 サイズの 変 更 や 配 列 を 宣 言 している 型 の 変 更 をする 必 要 が 出 てくるかもしれま<br />

せん。 以 下 では、Origin システム 上 で 要 求 される 配 列 サイズを 示 しています。ここで 使 用 している NR と<br />

NFR の 値 については、 以 下 で 説 明 します。<br />

• CCFFT<br />

table: 2n + NF REAL WORDS<br />

work: 2n REAL WORDS<br />

• ZZFFT<br />

table: 2n + NF DBL PREC WORDS<br />

work: 2n DBL PREC WORDS<br />

• CCFFTMR<br />

table: 2n + NF REAL WORDS<br />

work: 2n REAL WORDS<br />

• ZZFFTMR<br />

table: 2n + NF DBL PREC WORDS<br />

work: 2n DBL PREC WORDS<br />

• CCFFT2D<br />

table: (2*n1+NF) + (2*n2+NF) REAL WORDS<br />

work: 2*MAX(n1,n2) REAL WORDS<br />

• ZZFFT2D<br />

table: (2*n1*NF) + (2*n2*NF) DBL PREC WORDS<br />

work: 2*MAX(n1,n2) DBL PREC WORDS<br />

• CCFFT3D<br />

table: (2*n1*NF) + (2*n2+NF) + (2*n3+NF) REAL WORDS<br />

work: 2*MAX(n1,n2,n3) REAL WORDS<br />

• ZZFFT3D<br />

table: (2*n1+NF) + (2*n2+NF) + (2*n3+NF) DBL PREC WORDS<br />

work: 2*MAX(n1,n2,n3) DBL PREC WORDS<br />

• CCFFTM<br />

table: (NF+2*n) + REAL WORDS<br />

work: 2n REAL WORDS<br />

• ZZFFTM<br />

21<br />

日 本 SGI 株 式 会 社


table: (NF+2*n) + DBL PREC WORDS<br />

work: 2n DBL PREC WORDS<br />

• SCFFT, CSFFT<br />

table: (n+NFR) REAL WORDS<br />

work: n+2 REAL WORDS<br />

• DZFFT, ZDFFT<br />

table: (n+NFR) DBL PREC WORDS<br />

work: n+2 DBL PREC WORDS<br />

• SCFFT2D, CSFFT2D<br />

table: (n1+NFR) + (2*n2+NF) REAL WORDS<br />

work: n1+4*n2 REAL WORDS<br />

• DZFFT2D, ZDFFT2D<br />

table: (n1+NFR) + (2*n2+NF) DBL PREC WORDS<br />

work: n1+4*n2 DBL PREC WORDS<br />

• SCFFT3D, CSFFT3D<br />

table: (n1+NFR) + (2*n2+NF) + (2*n3+NF) REAL WORDS<br />

work: n1+4*n3 REAL WORDS<br />

• DZFFT3D, ZDFFT3D<br />

table: (n1+NFR) + (2*n2+NF) + (2*n3+NF) DBL PREC WORDS<br />

work: n1+4*n3 DBL PREC WORDS<br />

• SCFFTM, CSFFTM<br />

table: (n+NFR) REAL WORDS<br />

work: n+2 REAL WORDS<br />

• DZFFTM, ZDFFTM<br />

table: (n+NFR) DBL PREC WORDS<br />

work: n+2 DBL PREC WORDS<br />

その 他 の 異 なる 部 分 には、isys というパラメータ 配 列 がありますが、これはある 実 装 に 特 有 の 情 報 を 与<br />

えます。 特 定 の 実 装 に 依 存 した 機 能 は、この isys 配 列 に 限 定 されます。 任 意 の 実 装 において、デフォル<br />

トの 0 を 用 いることができます。<br />

Origin シリーズでの 実 装 では、isys(0)=0 と isys(0)=1 がサポートされています。<strong>SCSL</strong> のバージョン 1.3 以<br />

前 では、isys(0)=0 のみのサポートでした。 三 角 関 数 などの 係 数 を 格 納 するテーブルの 大 きさを 指 定 する<br />

際 の NFR 値 は、isys(0)=0 では NF=30 と NFR=15 となり、isys(0)=1 では NF=NFR=256 となります。<br />

isys(0)=0 の 時 の NF と NFR の 小 さな 値 は、 歴 史 的 なものです。それらは、 高 性 能 な FFT で 要 求 される 全<br />

22<br />

日 本 SGI 株 式 会 社


ての 要 素 を 格 納 するには 小 さすぎるため、isys(0)=0 の 時 は、table 配 列 が 初 期 化 される 時 に 陰 的 に 余 分<br />

なスペースがアロケートされます。メモリリークをさけるため、この 余 分 なスペースは、table 配 列 が 必 要<br />

なくなった 時 には 解 放 されるべきです。CCFFTF 及 び CCFFTMF などのルーチンが、このメモリを 解 放 す<br />

るために 使 用 されます。メモリーリークが 生 じる 可 能 性 があるため、isys(0)=0 の 使 用 はさけるべきでしょ<br />

う。<br />

isys(0)=1 では、NF と NFR の 値 は 十 分 大 きいため、 余 分 なメモリが 陰 的 にアロケートされることはなく、ま<br />

たそのため、メモリを 解 放 するために CCFFTF ルーチンなどを 呼 出 す 必 要 はありません。( 仮 に 呼 ばれた<br />

としても、これらのルーチンは 何 もしないでしょう。)<br />

注 :) isys(0)=1 は、isys が 2 つの 要 素 をもつ 整 数 配 列 であることを 意 味 しますが、isys(1)は 参 照 されませ<br />

ん。<br />

2.4. Real-to-complex FFT<br />

マニュアルページで 示 されているように、real-to-complex FFT ルーチンでは、n 個 の 実 数 入 力 X と n/2+1<br />

個 の 複 素 数 の 出 力 Y があります。これは、real-to-complex FFT の 特 徴 です。<br />

フーリエ 変 換 の 数 学 的 定 義 では、n 個 の 複 素 数 列 を 用 い、それを n 個 の 複 素 数 列 に 変 換 します。CCFFT<br />

や CCFFTM のような complex-to-complex FFT ルーチンは、n 個 の 複 素 数 入 力 データを 用 い n 個 の 複 素<br />

数 の 出 力 を 得 ます。 実 際 、real-to-complex FFT の 簡 単 な 計 算 法 の 一 つとしては、 入 力 データを 複 素 数<br />

配 列 x に 格 納 し、CCFFT ルーチンを 呼 ぶ 方 法 があります。この 方 法 でも SCFFT/SCFFTM ルーチンと 同<br />

じ 結 果 が 得 られます。<br />

real-to-complex FFT ルーチンである SCFFT や SCFFTM はより 効 率 的 です。というのは、 入 力 データが<br />

実 数 であるということを 利 用 すれば、 作 業 領 域 としてはほぼ 半 分 の 領 域 を 確 保 すれば 済 むからです。フ<br />

ーリエ 変 換 の 理 論 では、 実 数 の 入 力 データに 対 しては、 最 初 の n/2+1 の 複 素 数 出 力 値 のみ 計 算 するこ<br />

とになります。 残 りの 値 は 次 の 簡 単 な 公 式 によって 最 初 の 半 分 の 値 から 計 算 されます。<br />

Y k,L = conjg(Y n-k,L ) for n/2 ≦ k ≦ n-1<br />

ここで、conjg(Y)は、Y の 複 素 共 役 を 表 しています。 実 際 、 多 くのアプリケーションでは、 複 素 数 出 力 の 残<br />

りの 半 分 は 明 示 的 には 計 算 されないし、 格 納 もされません。 後 述 しますが、complex-to-real FFT に 対 し<br />

ても 同 様 に、 複 素 数 データの 最 初 の 半 分 のみを 与 えます。<br />

FFT の 理 論 によると、 実 数 入 力 データに 関 しては、 最 初 の 出 力 データ Y(0)は 常 に 実 数 となります。それゆ<br />

23<br />

日 本 SGI 株 式 会 社


え 虚 数 部 は 必 ず 0 となります。また、n が 偶 数 であれば Y(n/2)もまた 実 数 となり、 虚 数 部 として 0 を 持 ちま<br />

す。<br />

2.4.1. SCFFT のアプリケーションプログラムインターフェース (API)<br />

Fortran:<br />

CALL SCFFT (isign, n, scale, x, y, table, work, isys)<br />

C/C++<br />

#include <br />

int scfft (int isign, int n, float scale, float *x,scsl_complex *y, float *table, float<br />

*work, int *isys);<br />

C++ STL<br />

#include <br />

#include <br />

int scfft (int isign, int n, float scale, float *x,complex *y, float*table, float<br />

*work, int *isys);<br />

2.4.2. DZFFT のアプリケーションプログラムインターフェース (API)<br />

Fortran<br />

CALL DZFFT (isign, n, scale, x, y, table, work, isys)<br />

C/C++<br />

#include <br />

int dzfft (int isign, int n, double scale, float *x,scsl_zomplex *y, double *table, double<br />

*work, int *isys);<br />

C++ STL<br />

#include <br />

#include <br />

int dzfft (int isign, int n, double scale, double *x,complex *y, double *table,<br />

double *work, int *isys);<br />

2.4.3. 詳 細<br />

SCFFT/DZFFT ルーチンは、 実 配 列 X の FFT を 計 算 し、 結 果 を 複 素 数 配 列 Y に 格 納 します。<br />

SCFFT/DZFFT は 対 応 する 逆 conplex-to-real 変 換 を 計 算 します。<br />

FFT アプリケーションにおいて 通 常 そうであるように、 配 列 の 添 え 字 は 0 から 始 まります。これらのルーチ<br />

ンの 配 列 は 次 の 宣 言 されます。<br />

Fortran<br />

REAL<br />

X(0:n-1)<br />

24<br />

日 本 SGI 株 式 会 社


COMPLEX Y(0:n/2)<br />

C/C++<br />

float x[n];<br />

scsl_complex y[n/2+1];<br />

C++ STL<br />

float x[n];<br />

complex y[n/2+1];<br />

出 力 は、 入 力 の 配 列 を 用 いて、FFT の 公 式 により 次 のようになります。<br />

n-1<br />

Y(k) = scale * Sum [ X(j)*w**(isign*j*k) ] for k = 0, ..., n/2<br />

j=0<br />

where:<br />

w =exp(2*pi*i/n),<br />

i =+ sqrt(-1),<br />

pi =3.14159...,<br />

isign =+1 or -1.<br />

もし SCFFT が isign と scale の 値 について、ある 特 定 の 値 で 呼 び 出 された 場 合 、-isign と 1/(n*scale) で<br />

CSFFT が 呼 ばれることによって 数 学 的 な 逆 関 数 が 計 算 されます。 実 際 、もし 前 進 FFT に 関 して、SCFFT<br />

関 数 で isign = +1、scale = 1.0 を 使 用 した 場 合 、isign = -1、scale = 1.0/n で CSFFT を 使 用 することによっ<br />

て 逆 FFT を 計 算 することが 可 能 です。<br />

以 下 の 引 数 の 説 明 で 使 用 されているデータ 型 の 置 き 換 えについては、データ 型 の 節 をご 参 照 ください。<br />

本 ルーチンで 使 用 される 引 数 は 次 の 通 りです。<br />

引 数 一 覧<br />

引 数<br />

isign<br />

n<br />

( 入 力 ) 整 数 型<br />

Isign=0: テーブル 配 列 の 初 期 化<br />

Isign=±1: 指 数 の 符 合 を 表 す<br />

( 入 力 ) 整 数 型<br />

変 換 のサイズ<br />

説 明<br />

scale ( 入 力 )<br />

SCFFT: 単 精 度 実 数 型<br />

DZFFT: 倍 精 度 実 数 型<br />

フーリエ 変 換 の 後 、 出 力 配 列 の 各 要 素 に scale を 掛 ける<br />

x ( 入 力 )<br />

SCFFT: 単 精 度 実 数 型<br />

DZFFT: 倍 精 度 実 数 型<br />

25<br />

日 本 SGI 株 式 会 社


次 元 n の 配 列<br />

y ( 出 力 )<br />

SCFFT: 単 精 度 実 数 型<br />

DZFFT: 倍 精 度 実 数 型<br />

次 元 n/2+1 の 配 列<br />

table ( 入 力 、もしくは 出 力 )<br />

SCFFT: 単 精 度 実 数 型<br />

DZFFT: 倍 精 度 実 数 型<br />

次 元 n+NFR の 配 列 。isign=0 の 時 、 出 力 。isign=±1 の 時 、table 配 列 の 値 は isign=0 によっ<br />

てすでに 初 期 化 されているとみなされる<br />

work ( 作 業 領 域 )<br />

SCFFT: 単 精 度 実 数 型<br />

DZFFT: 倍 精 度 実 数 型<br />

次 元 n+2 の 配 列<br />

isys ( 入 力 )<br />

実 装 に 特 化 した 情 報 を 与 える 引 数 。Origin では 常 に 0<br />

2.4.4. データ 型<br />

上 記 の 引 数 についての 説 明 で 使 用 されている 用 語 について、 対 応 するデータ 型 を 説 明 いたします。<br />

用 語<br />

Fortran<br />

整 数 型<br />

単 精 度 実 数 型<br />

倍 精 度 実 数 型<br />

C/C++<br />

整 数 型<br />

単 精 度 実 数 型<br />

倍 精 度 実 数 型<br />

C++ STL<br />

整 数 型<br />

単 精 度 実 数 型<br />

倍 精 度 実 数 型<br />

データ 型<br />

INTEGER (INTEGER*8 for –lscs_i8_[mp])<br />

REAL<br />

DOUBLE PRECISION<br />

int (long long for –lscs_i8_[mp])<br />

float<br />

double<br />

int (long long for –lscs_i8_[mp])<br />

float<br />

double<br />

2.4.5. 注 意<br />

232-1 を 超 える 素 因 子 に 関 する 変 換 は 本 ライブラリの 8 バイト 整 数 版 ではサポートされていません。<br />

作 業 配 列 work に 加 えて、FFT ルーチンはスタックからスクラッチスペースを 動 的 に 割 り 当 てます。 割 り 当<br />

てられた 空 間 の 大 きさは 最 大 のプロセッサキャッシュサイズよりも 多 少 大 きくなります。シングルプロセッ<br />

サでの 実 行 では、デフォルトのスタックサイズは、これらの 割 り 当 てが 通 常 問 題 なく 出 来 る 程 度 に 十 分 大<br />

26<br />

日 本 SGI 株 式 会 社


きなサイズとなっています。しかし、 並 列 実 行 に 関 しては、スレーブスレッドのスタックサイズがこのスクラ<br />

ッチスペースを 持 つのに 十 分 大 きいということを 保 証 する 必 要 があります。 十 分 なスタックスペースを 確<br />

保 するのに 失 敗 した 場 合 は、スタックオーバーフローによるコアダンプが 生 じます。MP ライブラリのスレ<br />

ーブスレッドのスタックサイズは、MP_SLAVE_STACKSIZE 環 境 変 数 、もしくは mp_set_slave_stacsize() ラ<br />

イブラリルーチンによってコントロールすることが 可 能 です。スレーブスタックサイズをコントロールするた<br />

めのさらなる 情 報 につきましては、mp(3C), mp(3F), 及 び pe_environ(5) の man ページをご 参 照 ください。<br />

pthread アプリケーションに 関 しては、スレッドのスタックサイズは pthread_create(3P) 関 数 における<br />

pthread_attr_t に 関 する 引 数 で 提 供 される 多 くの 属 性 の 一 つで 決 定 されます。スタックサイズの 属 性 は<br />

pthread_attr_setstacksize(3P) 呼 び 出 し を 使 用 す る こ と で 明 示 的 に 設 定 さ れ ま す 。<br />

pthread_attr_setstacksize(3P) 呼 び 出 しは、pthread_attr_init(3P) の man ページで 説 明 されています。<br />

2.5. Complex-to-real FFT<br />

計 算 結 果 はマニュアルページの 公 式 で 与 えられます。<br />

一 般 的 に FFT は 複 素 数 列 を 複 素 数 列 に 変 換 しますが、 複 素 数 の 入 力 列 X が 実 数 列 を 変 換 したものであ<br />

る 場 合 には、 出 力 列 Y は 実 数 になります。この 場 合 、 計 算 作 業 領 域 として 半 分 だけ 確 保 すればすみま<br />

す。<br />

フーリエ 変 換 の 理 論 によると、 実 数 列 となる 出 力 列 Y に 関 しては、 入 力 列 に 対 する 次 の 式 が 適 用 されま<br />

す。<br />

X k,L = conjg(X n-k,L ) for n/2 ≦ k ≦ n-1<br />

また、 実 際 以 下 の 入 力 データ<br />

X k,L for k > n/2<br />

は 使 用 されません。なぜなら、 最 初 の 半 分 の 入 力 値 から 推 測 できるからです。<br />

このように、complex-to-real ルーチン CSFFTM では、 配 列 は 以 下 の 次 元 と 大 きさを 取 ります。<br />

Fortran:<br />

COMPLEX X(0:ldx-1, 0:lot-1)<br />

REAL Y(0:ldy-1, 0:lot-1)<br />

C/C++<br />

scsl_complex x[lot][ldx]<br />

float y[lot][ldy]<br />

C++ STL<br />

27<br />

日 本 SGI 株 式 会 社


complex x[lot][ldx]<br />

float y[lot][ldy]<br />

where ldx ≧ n/2 + 1, ldy ≧ n.<br />

それぞれの 列 で、(n/2) + 1 の 複 素 数 入 力 値 と n の 実 数 出 力 値 があります。(n/2) + 1 の 入 力 値 のみが 適<br />

用 されますが、 変 換 のサイズはこの 場 合 n となります。なぜなら、 陰 的 に、n の 長 さの 列 をもつ FFT の 公<br />

式 が 使 用 されるからです。<br />

X(0, L) は 実 数 (すなわち 虚 数 部 は 0) となります。もし n が 偶 数 ならば、X(n/2, L) もまた 実 数 となります。<br />

CSFFTM と CSFFT ルーチンではこれらの 値 は 実 数 とみなされます。もし 非 ゼロ 虚 数 部 が 与 えられれば、<br />

それは 無 視 されます。<br />

2.6. 初 期 化<br />

table 配 列 は FFT の 計 算 で 使 われる 三 角 法 のテーブルを 格 納 します。 変 換 に 先 立 って、isign に 0 を 指 定<br />

してルーチンを 呼 出 すことで table 配 列 を 初 期 化 する 必 要 があります。 問 題 サイズが n で 変 更 がないなら<br />

ば、table 配 列 は 再 初 期 化 する 必 要 はありません。<br />

SCFFT と CSFFT は table 配 列 に 関 して 同 じフォーマットを 使 用 するため、どちらのルーチンを 用 いて 初 期<br />

化 しても 構 いません。 (CCFFT は 異 なる table フォーマットを 用 いることに 注 意 してください。)<br />

2.7. 配 列 の 次 元 及 び 寸 法<br />

前 述 の 説 明 や 特 定 のマニュアルページでは、FFT アプリケーションにおいて 通 常 そうであるように、 配 列<br />

の 添 字 は 0 から 始 まります。しかしながら、 通 常 の FORTRAN のように、1 から 始 めたい 時 でも 呼 び 出 し<br />

部 分 の 変 更 は 必 要 ありません。<br />

--------------------------------------------------------------------<br />

Routine subscripts starting at 0 subscripts starting at 1<br />

--------------------------------------------------------------------<br />

CCFFT COMPLEX X(0:N-1) COMPLEX X(N)<br />

COMPLEX Y(0:N-1)<br />

COMPLEX Y(N)<br />

CCFFT2D COMPLEX X(0:ldx-1, 0:n2-1) REAL X(ldx, n2)<br />

COMPLEX Y(0:ldy-1, 0:n2-1) COMPLEX Y(ldy, n2)<br />

SCFFT REAL X(0:n-1) REAL X(n)<br />

COMPLEX Y(0:n/2) COMPLEX Y(n/2 + 1)<br />

SCFFT2D REAL X(0:ldx-1, 0:n2-1) COMPLEX X(ldx, n2)<br />

COMPLEX Y(0:ldy-1, 0:n2-1) COMPLEX Y(ldy, n2)<br />

28<br />

日 本 SGI 株 式 会 社


CCFFTM COMPLEX X(0:ldx-1, 0:lot-1) COMPLEX X(ldx, lot)<br />

COMPLEX Y(0:ldy-1, 0:lot-1) COMPLEX Y(ldy, lot)<br />

CCFFTMR COMPLEX X(0:ldx-1, 0:n-1) COMPLEX X(ldx, n)<br />

COMPLEX Y(0:ldy-1, 0:n-1) COMPLEX Y(ldy, n)<br />

--------------------------------------------------------------------<br />

2.8. 畳 み 込 みルーチン 及 び 相 関 ルーチン<br />

有 限 長 インパルス 応 答 FIR (Finite Impulse Response) に 関 する 畳 み 込 みと 相 関 を 取 り 上 げます。これら<br />

のルーチンはそれぞれシングルプロセッサで 利 用 するために 最 適 化 されています。2 次 元 の 入 力 列 を 使<br />

用 するルーチンは、 並 列 化 (マルチスレッド 化 ) に 対 応 しています。<br />

畳 み 込 みと 相 関 のルーチンは、 非 常 に 一 般 的 です。この 一 般 性 と 最 大 限 の 柔 軟 性 を 達 成 するために、1<br />

次 元 の 数 列 は、3 つのパラメータによって 定 義 されています。2 次 元 配 列 のためには、6 つのパラメータが<br />

必 要 です。この 一 般 性 に 対 する 代 償 は、 呼 び 出 し 手 続 きが 長 くなる 点 です。<br />

以 下 の 一 覧 中 のそれぞれのルーチンにはマニュアルページが 存 在 します。この 一 覧 表 における 行 では、<br />

ルーチンのデータタイプを 示 しています。<br />

• C は、32 ビット 複 素 数 データであることを 示 しています。<br />

• Z は、64 ビット 倍 精 度 複 素 数 データであることを 示 しています。<br />

• S は、32ビット 実 数 であることを 示 しています。<br />

• D は、64 ビット 倍 精 度 実 数 であることを 示 しています。<br />

表 の 列 は、 行 で 示 された 畳 み 込 みもしくは 相 関 に 関 するルーチンの 計 算 の 型 と 次 元 を 示 しています。<br />

• 1 次 元 FIR は、1 次 元 信 号 に 対 して 有 限 長 インパルス 応 答 フィルタを 適 用 します。<br />

• 複 数 1 次 元 FIR は、 複 数 の 1 次 元 信 号 に 対 して 有 限 長 インパルス 応 答 フィルタを 適 用 します。<br />

• 2 次 元 FIR は、2 次 元 信 号 に 対 して 有 限 長 インパルス 応 答 フィルタを 適 用 します。<br />

• 1 次 元 COR は、1 次 元 数 列 の 相 関 を 計 算 します。<br />

• 複 数 1 次 元 COR は、 複 数 の 1 次 元 数 列 の 相 関 を 計 算 します。<br />

• 2 次 元 COR は 2 次 元 数 列 の 相 関 を 計 算 します。<br />

---------------------------------------------<br />

Type 1 次 元 複 数 1 次 元 2 次 元<br />

---------------------------------------------<br />

C CFIR1D CFIRM1D CFIR2D<br />

29<br />

日 本 SGI 株 式 会 社


Z ZFIR1D ZFIRM1D ZFIR2D<br />

S SFIR1D SFIRM1D SFIR2D<br />

D DFIR1D DFIRM1D DFIR2D<br />

---------------------------------------------<br />

C CCOR1D CCORM1D CCOR2D<br />

Z ZCOR1D ZCORM1D ZCOR2D<br />

S SCOR1D SCORM1D SCOR2D<br />

D DCOR1D DCORM1D DCOR2D<br />

---------------------------------------------<br />

2.9. サンプルプログラム<br />

2.9.1. 1 次 元 real-to-complex FFT DZFFT<br />

問 題<br />

以 下 に FORTRAN, C/C++において、 一 次 元 の 波 形 データ(128 点 サンプリング)を dzfft で 変 換 し、 結 果 を<br />

表 示<br />

します。<br />

DZFFT 引 数 一 覧<br />

DZFFT (isign,n,scale,x,y,table,work,isys)<br />

isign ( 入 力 ) 整 数 型 。<br />

Isign=0: テーブル 配 列 の 初 期 化<br />

Isign=±1: 指 数 の 符 合 を 表 す<br />

n<br />

( 入 力 ) 整 数 型 。 変 換 のサイズ<br />

scale ( 入 力 ) 倍 精 度 実 数 型 。フーリエ 変 換 の 後 、 出 力 配 列 の 各 要 素 に scale を 掛 ける<br />

x<br />

( 入 力 ) 倍 精 度 実 数 型 。 次 元 n の 配 列<br />

y<br />

( 出 力 ) 倍 精 度 複 素 数 型 。 次 元 n/2+1 の 配 列<br />

table ( 入 力 、もしくは 出 力 ) 倍 精 度 実 数 型 。 次 元 n+NFR の 配 列 。isign=0 の 時 、 出 力 。isign=±<br />

1 の 時 、table 配 列 の 値 は isign=0 によってすでに 初 期 化 されているとみなされる<br />

work ( 作 業 領 域 ) 倍 精 度 実 数 。 次 元 n+2 の 配 列<br />

isys ( 入 力 ) 実 装 に 特 化 した 情 報 を 与 える 引 数 。Origin では 常 に 0<br />

プログラム 例<br />

FORTRAN<br />

C<br />

implicit double precision (a-h,o-z)<br />

parameter (n=128,iterm=n/4)<br />

30<br />

日 本 SGI 株 式 会 社


C<br />

C<br />

C<br />

C<br />

C<br />

C<br />

integer i,isys<br />

double precision pi,x(0:n-1),table(n+256),work(n+2)<br />

complex*16 y(0:n/2)<br />

波 形 データの 初 期 化<br />

pi=4.d0*atan(1.d0)<br />

do i=0,n-1<br />

x(i)=cos(2.d0*iterm*i*pi/n)<br />

end do<br />

isys=0<br />

FFTテーブルの 初 期 化<br />

call dzfft(0,n,1.d0,x,y,table,work,isys)<br />

FFT<br />

call dzfft(1,n,1.d0,x,y,table,work,isys)<br />

結 果 の 表 示<br />

do i=0,n/2<br />

write(*,*) i,zabs(y(i))<br />

end do<br />

stop<br />

end<br />

C/C++<br />

#include <br />

#include <br />

#include <br />

#define N 128<br />

#define ITERM (N / 4)<br />

int main(void)<br />

{<br />

int i, isys;<br />

double pi, x[N];<br />

double table[N + 256], work[N + 2];<br />

scsl_zomplex y[N / 2 + 1];<br />

31<br />

日 本 SGI 株 式 会 社


* 波 形 データの 初 期 化 */<br />

pi = 4.0 * atan(1.0);<br />

for(i = 0; i < N; i++){<br />

x[i] = cos(2.0 * ITERM * i * pi / N);<br />

}<br />

isys = 0;<br />

/* FFTテーブルの 初 期 化 */<br />

dzfft(0, N, 1.0, x, y, table, work, &isys);<br />

/* FFT */<br />

dzfft(1, N, 1.0, x, y, table, work, &isys);<br />

/* 結 果 の 表 示 */<br />

for(i = 0; i < N / 2 + 1; i++){<br />

printf("%d %g\n", i, sqrt(y[i].re * y[i].re + y[i].im * y[i].im));<br />

}<br />

}<br />

return 0;<br />

32<br />

日 本 SGI 株 式 会 社


2.10. FFT ルーチンの 性 能<br />

Origin3000 400MHzでの 一 次 元 複 素 FFT ルーチンの 性 能 グラフを 示 します。<br />

測 定 に 用 いたプロセッサのピーク 性 能 は 800MFLOPS です。 単 精 度 / 倍 精 度 、 共 にピーク 性 能 の 8 割 以<br />

上 の 性 能 を 達 成 しています。<br />

Complex 1D FFTs<br />

Origin3000/R12000@400MHz<br />

700<br />

600<br />

Double Precision<br />

Single Precision<br />

500<br />

Mflops<br />

400<br />

300<br />

200<br />

100<br />

0<br />

32<br />

64<br />

128<br />

256<br />

512<br />

1024<br />

2048<br />

4096<br />

8192<br />

16384<br />

32768<br />

65536<br />

131072<br />

262144<br />

524288<br />

1048576<br />

Size<br />

33<br />

日 本 SGI 株 式 会 社


次 に、2 次 元 /3 次 元 FFT を 並 列 実 行 した 場 合 の 性 能 グラフを 示 します。<br />

プロセッサ 数 に 応 じた 良 好 なスケーラビリティが 得 られていることがわかります。<br />

Effective Gflo<br />

12<br />

10<br />

8<br />

6<br />

4<br />

2<br />

0<br />

Multidimensional Fast Fourier Transforms<br />

400 MHz Origin 3000<br />

1 10 100<br />

Number of Processors<br />

4096 x 4096 512 x 512 x 512<br />

34<br />

日 本 SGI 株 式 会 社


3. BLAS ルーチン<br />

基 本 線 形 代 数 サブプログラム (BLAS) は、 線 形 代 数 の 数 値 計 算 を 行 う 行 列 の 低 水 準 サブプログラム 群<br />

です。BLAS は 3 つのレベルから 構 成 されています。レベル1ルーチンは、ベクトル 対 ベクトルのルーチン<br />

で、 一 度 に1 行 もしくは1 列 を 扱 うときに 用 いられます。レベル 2 ルーチンは、 行 列 対 ベクトルのルーチン<br />

で、 行 列 とベクトルの 演 算 に 用 いられます。レベル 3 ルーチンは、 行 列 対 行 列 のルーチンで、 行 列 と 行 列<br />

の 演 算 に 用 いられます。<br />

ベクトルを 扱 うルーチンは、ストライドパラメータが 指 定 できるので 要 素 が 連 続 している 必 要 はありませ<br />

ん。<br />

3.1. データ 型<br />

これらのルーチンでは 以 下 のデータ 型 が 使 用 されます。<br />

• 単 精 度 : FORTRAN の real 型 、C/C++ の float 型 であり、これらは 32 ビット 浮 動 小 数 点 実 数 です。<br />

これらのルーチン 名 は S で 始 まります。<br />

• 単 精 度 複 素 数 : FORTRAN の complex 型 、C/C++の scsl_complex 型 ( で 定 義 されてい<br />

ます。) C++ STL の complex 型 (で 定 義 されています。) であり、これらは 2 つの<br />

32 ビット 浮 動 小 数 点 実 数 です。これらのルーチン 名 は C で 始 まります。<br />

• 倍 精 度 : FORTRAN の double precision 型 、 C/C++の double 型 であり、これらは 64 ビット 浮 動 小 数<br />

点 実 数 です。これらのルーチン 名 は、D で 始 まります。<br />

• 倍 精 度 複 素 数 : FORTRAN の double complex 型 、C/C++の scsl_zomplex 型 (で 定 義 さ<br />

れています。)、C++ STL の complex 型 (で 定 義 されています。) であり、これ<br />

らは 2 つの 64 ビット 浮 動 小 数 点 実 数 です。これらのルーチン 名 は Z で 始 まります。<br />

入 力 データや 出 力 データのデータ 型 以 外 でもバージョンにより 多 少 の 違 いが 生 じてきます。この 場 合 は、<br />

そのルーチンの man ページで 説 明 されます。<br />

3.2. マニュアルページ 名<br />

man(1) コマンドでは、 単 精 度 実 数 、 単 精 度 複 素 数 、 倍 精 度 実 数 、 倍 精 度 複 素 数 のいずれのルーチン 名<br />

でもオンラインマニュアルを 参 照 できます。<br />

以 下 の 表 は、これらのルーチンの 命 名 規 則 を 示 しています。<br />

35<br />

日 本 SGI 株 式 会 社


実 数 実 数 複 素 数 複 素 数<br />

単 精 度 倍 精 度 単 精 度 倍 精 度<br />

form: Sname Dname Cname Zname<br />

example: SGEMM DGEMM CGEMM ZGEMM<br />

3.3. レベル 1<br />

レベル 1 BLAS ルーチンとしては、 次 の 3 つのベクトル 対 ベクトル 演 算 が 利 用 可 能 です。<br />

• 内 積 と 種 々のベクトルノルム<br />

• 定 数 倍 の 計 算 、ベクトルのコピー、ベクトルの 交 換 及 びベクトルの 線 形 結 合 の 計 算<br />

• 平 面 回 転 変 換 、 修 正 平 面 回 転 変 換<br />

また、レベル1 BLAS では、 絶 対 値 が 最 大 の 要 素 をサーチするなどのいくつかのサーチ 関 数 も 提 供 され<br />

ています。<br />

3.3.1. 増 分 引 数<br />

ベクトルは、 配 列 名 (x や y) と 格 納 の 間 隔 ( 増 分 ) (incx や incy) によって 定 義 されます。 増 分 は、 正 の<br />

数 のこともあれば 負 の 数 であることもあります。ベクトル x が n 個 の 要 素 を 持 つとする 場 合 、 対 応 する 実<br />

際 の 配 列 引 数 は、 少 なくとも 1+(n-1)*|incx|の 長 さを 持 ちます。 負 の 増 分 である 場 合 は、x の 最 初 の 要 素<br />

は FORTRAN では x(1+(n-1)*|incx|) であり、C/C++ では、x[(n-1)*|incx|] となります。この 機 能 は 標 準<br />

BLAS に 対 する 拡 張 であるため、_SCAL, _NRM2, _ASUM 及 び I_AMAX の 標 準 仕 様 では、 負 の 増 分 に 対<br />

してはこれらの 振 る 舞 いは 定 義 されていません。<br />

増 分 引 数 が 0 である 場 合 は、 予 測 不 可 能 な 結 果 が 生 じます。<br />

incx: 増 分<br />

: 要 素<br />

incx<br />

‥‥<br />

incx<br />

‥‥<br />

incx<br />

‥‥<br />

以 下 の 例 では、 要 素 数 5、 増 分 3 の 時 のベクトルへの 要 素 の 格 納 のされ 方 を 示 します。<br />

36<br />

日 本 SGI 株 式 会 社


3 3 3 3<br />

1 2 3 4 5 6 7 8 9 10 11 12 13<br />

n = 5<br />

incx = 3<br />

配 列 の 長 さ = 1+(n-1)x|incx|<br />

= 1+(5-1)x|3|<br />

= 13<br />

3.3.2. FORTRAN での 関 数 の 型 宣 言<br />

FORTRAN では、 外 部 関 数 のデータ 型 を 宣 言 する 必 要 があります。 複 素 数 のレベル 1 BLAS 関 数 のデー<br />

タ 型 を 宣 言 することは 特 に 重 要 です。なぜなら、 関 数 名 と FORTRAN のデータ 型 の 規 則 に 従 うと、デフォ<br />

ルトのデータ 型 では 実 数 となってしまうためです。<br />

関 数 名 に 対 応 する FORTRAN での 型 宣 言 は 次 のようになります。<br />

型<br />

REAL<br />

COMPLEX<br />

DOUBLE PRECISION<br />

DOUBLE COMPLEX<br />

INTEGER<br />

関 数 名<br />

SASUM, SCASUM, SCNRM2, SDOT, SNRM2, SSUM<br />

CDOTC, CDOTU, CSUM<br />

DASUM, DZASUM, DDOT, DNRM2, DZNRM2, DSUM<br />

ZDOTC, ZDOTU, ZSUM<br />

ISAMAX, IDAMAX, ICAMAX, IZAMAX, ISAMIN, IDAMIN,<br />

ISMAX, IDMAX, ISMIN, IDMIN<br />

3.3.3. サーチ 関 数<br />

レベル 1 BLAS では、いくつかのサーチ 関 数 が 提 供 されています。 以 下 にこれらの 関 数 を 列 挙 していま<br />

す。<br />

(アスタリスク [*] のついた 関 数 は、 標 準 のレベル 1 BLAS ルーチンに 対 する 拡 張 となっています。)<br />

ISAMAX, ICAMAX, ISAMIN*, ISMAX*, ISMIN*<br />

IDAMAX IZAMAX, IDAMIN*, IDMAX*, IDMIN*<br />

3.3.4. 関 数 一 覧<br />

アスタリスク [*] がついた 関 数 は、 標 準 レベル 1 BLAS ルーチンの 拡 張 となっています。 詳 細 につきまし<br />

ては、 各 ルーチンのマニュアルページをご 参 照 ください。<br />

37<br />

日 本 SGI 株 式 会 社


実 数<br />

単 精 度<br />

実 数<br />

倍 精 度<br />

複 素 数<br />

単 精 度<br />

複 素 数<br />

倍 精 度<br />

説 明<br />

SASUM DASUM 実 数 ベクトル 要 素 の 絶 対 値 の 合 計 (1 ノルム)<br />

SCASUM DZASUM<br />

複 素 ベクトル 要 素 の 絶 対 値 の 合 計<br />

SAXPBY* DAXPBY* CAXPBY* ZAXPBY* ベクトルの 定 数 倍 同 士 の 和<br />

SAXPY DAXPY CAXPY ZAXPY ベクトルの 定 数 倍 とベクトルの 和<br />

SCOPY DCOPY CCOPY ZCOPY ベクトルを 他 のベクトルへコピー<br />

SDOT DDOT CDOTU ZDOTU 内 積<br />

CDOTC ZDOTC 共 役 内 積<br />

SHAD* DHAD* CHAD* ZHAD* 2 つのベクトルのアダマール 積<br />

SNRM2 DNRM2 実 数 ベクトルのユークリッドノルム (L2 ノルム)<br />

SCNRM2 DZNRM2 複 素 ベクトルのユークリッドノルム (L2 ノルム)<br />

CSROT* ZDROT* 実 平 面 回 転 変 換 の 複 素 ベクトルの 対 への 適 用<br />

CROT* ZROT*<br />

SROT DROT 直 行 平 面 回 転 変 換<br />

SROTG DROTG CROTG* ZROTG* Givens 回 転 行 列 の 計 算<br />

SROTM DROTM 修 正 Givens 回 転 変 換<br />

SROTMG DROTMG<br />

修 正 Givens 回 転 行 列 の 計 算<br />

SSCAL DSCAL CSCAL ZSCAL ベクトルの 定 数 倍<br />

CSSCAL ZDSCAL<br />

SSUM* SDUM* CSUM* ZSUM* ベクトル 要 素 の 和<br />

SSWAP DSWAP CSWAP ZSWAP ベクトルの 交 換<br />

ISAMAX IDAMAX ICAMAX IZAMAX 絶 対 値 が 最 大 となる 要 素 のサーチ<br />

ISAMIN* IDAMIN* 絶 対 値 が 最 小 となる 要 素 のサーチ<br />

ISMAX* IDMAX* 最 大 値 となる 要 素 のサーチ<br />

ISMIN* IDMIN* 最 小 値 となる 要 素 のサーチ<br />

3.4. レベル 2<br />

3.4.1. 多 次 元 配 列<br />

BLAS ルーチンへの 引 数 として 渡 される 多 次 元 配 列 は、 列 方 向 の 順 で 格 納 されます。 即 ち、FORTRAN プ<br />

ログラムで 用 いられる 格 納 の 慣 習 です。C/C++ のユーザは 明 示 的 に 列 方 向 で 多 次 元 配 列 に 値 を 格 納<br />

する 必 要 があります。 一 つの 方 法 としては、FORTRAN での 宣 言 を 考 慮 して、 配 列 の 次 元 の 順 序 を 逆 に<br />

するという 方 法 があります ( 例 えば、FORTRAN で x(ldx,n)である 場 合 は、C/C++では x[n][ldx] としま<br />

す)。 で 使 われているプロトタイプのため、コンパイラからの 型 のミスマッチによるエラーや<br />

警 告 を 避 けるために、 配 列 を BLAS ルーチンへの 引 数 として 渡 す 時 は、 適 切 な 型 に 対 するポインタとして<br />

キャストします。<br />

38<br />

日 本 SGI 株 式 会 社


BLAS ルーチンを 呼 ぶ 際 に、 多 次 元 配 列 に 関 して 行 方 向 の 格 納 形 式 を 望 む C/C++ユーザは、<br />

INTRO_CBLAS(3S) マニュアルページをご 参 照 ください。<br />

3.4.2. 関 数 一 覧<br />

アスタリスク [*] がついた 関 数 は、 標 準 レベル 2 BLAS ルーチンの 拡 張 となっています。 詳 細 につきまし<br />

ては、 各 ルーチンのマニュアルページをご 参 照 ください。<br />

実 数<br />

単 精 度<br />

実 数<br />

倍 精 度<br />

複 素 数<br />

単 精 度<br />

複 素 数<br />

倍 精 度<br />

CHBMV ZHBMV 複 素 エルミート 帯 行 列 と 複 素 ベクトルの 積<br />

CHEMV ZHEMV 複 素 エルミート 行 列 と 複 素 ベクトルの 積<br />

CHER ZHER 複 素 エルミート 行 列 のエルミート ランク 1 更 新<br />

CHER2 ZHER2 複 素 エルミート 行 列 のエルミート ランク 2 更 新<br />

CHPMV ZHPMV 圧 縮 形 式 での 複 素 エルミート 行 列 と 複 素 ベクトルの 積<br />

CHPR ZHPR 圧 縮 形 式 での 複 素 エルミート 行 列 のエルミート ランク 1 更 新<br />

CHPR2 ZHPR2 圧 縮 形 式 での 複 素 エルミート 行 列 のエルミート ランク 2 更 新<br />

SGBMV DGBMV CGBMV ZGBMV 一 般 帯 行 列 とベクトルの 積<br />

SGEMV DGEMV CGEMV ZGEMV 一 般 行 列 とベクトルの 積<br />

SGER DGER 実 一 般 行 列 の ランク 1 更 新<br />

CGERC ZGERC 複 素 一 般 行 列 の 共 役 ランク 1 更 新<br />

CGERU ZGERU 複 素 一 般 行 列 の 非 共 役 ランク 1 更 新<br />

SGESUM* DGESUM* CGESUM* ZGESUM* 行 列 の 定 数 倍 同 士 の 和<br />

SSBMV DSBMV 実 対 称 帯 行 列 と 実 ベクトルの 積<br />

SSPMV DSPMV CSPMV* ZSPMV* 圧 縮 形 式 での 対 称 行 列 とベクトルの 積<br />

SSPR DSPR CSPR* ZSPR* 圧 縮 形 式 での 対 称 行 列 の 対 称 ランク 1 更 新<br />

SSPR2 DSPR2 圧 縮 形 式 での 実 対 称 行 列 の 対 称 ランク 2 更 新<br />

SSYMV DSYMV CSYMV ZSYMV 対 称 行 列 とベクトルの 積<br />

SSYR DSYR CSYR* ZSYR* 対 称 行 列 の 対 称 ランク 1 更 新<br />

SSYR2 DSYR2 実 対 称 行 列 の 対 称 ランク 2 更 新<br />

STBMV DTBMV CTBMV ZTBMV 三 角 帯 行 列 とベクトルの 積<br />

STBSV DTBSV CTBSV ZTBSV 三 角 帯 行 列 の 求 解<br />

STPMV DTPMV CTPMV ZTPMV 圧 縮 形 式 での 三 角 行 列 とベクトルの 積<br />

STPSV DTPSV CTPSV ZTPSV 圧 縮 形 式 での 三 角 行 列 の 求 解<br />

STRMV DTRMV CTRMV ZTRMV 三 角 行 列 とベクトルの 積<br />

STRSV DTRSV CTRSV ZTRSV 三 角 行 列 の 求 解<br />

説 明<br />

3.5. レベル 3<br />

3.5.1. 多 次 元 配 列<br />

BLAS ルーチンへの 引 数 として 渡 される 多 次 元 配 列 は、 列 方 向 の 順 で 格 納 されます。 即 ち、FORTRAN プ<br />

39<br />

日 本 SGI 株 式 会 社


ログラムで 用 いられる 格 納 の 慣 習 です。C/C++ のユーザは 明 示 に 列 方 向 で 多 次 元 配 列 に 値 を 格 納 す<br />

る 必 要 があります。 一 つの 方 法 としては、FORTRAN での 宣 言 を 考 慮 して、 配 列 の 次 元 の 順 序 を 逆 にす<br />

るという 方 法 があります ( 例 えば、FORTRAN で x(ldx,n)である 場 合 は、C/C++では x[n][ldx] とします)。<br />

で 使 われているプロトタイプのため、コンパイラからの 型 のミスマッチによるエラーや 警 告 を<br />

避 けるために、 配 列 を BLAS ルーチンへの 引 数 として 渡 す 時 は、 適 切 な 型 に 対 するポインタとしてキャス<br />

トします。<br />

BLAS ルーチンを 呼 ぶ 際 に、 多 次 元 配 列 に 関 して 行 方 向 の 格 納 形 式 を 望 む C/C++ユーザは、 次 節 3.6<br />

節 の“CBLAS ライブラリ”、または、INTRO_CBLAS(3S) マニュアルページをご 参 照 ください。<br />

3.5.2. 関 数 一 覧<br />

アスタリスク [*] がついた 関 数 は、 標 準 レベル 3 BLAS ルーチンの 拡 張 となっています。 詳 細 につきまし<br />

ては、 各 ルーチンのマニュアルページをご 参 照 ください。<br />

実 数<br />

単 精 度<br />

実 数<br />

倍 精 度<br />

複 素 数<br />

単 精 度<br />

複 素 数<br />

倍 精 度<br />

SGIMM DGEMM CGEMM ZGEMM 一 般 行 列 同 士 の 積<br />

CGEMM3M* ZGEMM3M* 一 般 行 列 同 士 の 積<br />

Strassen のアルゴリズムのバリエーションを 用 いた<br />

DGEMMS*<br />

倍 精 度 行 列 同 士 の 積<br />

SSYMM DSYMM CSYMM ZSYMM 対 称 行 列 と 一 般 行 列 の 積<br />

CHEMM ZHEMM エルミート 行 列 と 複 素 一 般 行 列 の 積<br />

SSYR2K DSYR2K CSYR2K ZSYR2K 対 称 行 列 の ランク 2k 更 新<br />

CHER2K ZHER2K エルミート 行 列 の ランク 2k 更 新<br />

SSYRK DSYRK CSYRK ZSYRK 対 称 行 列 の ランク k 更 新<br />

CHERK ZHERK エルミート 行 列 の ランク k 更 新<br />

STRMM DTRMM CTRMM ZTRMM 三 角 行 列 と 一 般 行 列 の 積<br />

STRSM DTRSM CTRSM ZTRSM 三 角 行 列 方 程 式 の 求 解<br />

説 明<br />

3.6. CBLAS ライブラリ<br />

<strong>SCSL</strong> には、BLAS ライブラリに 対 して 2 つの C/C++インターフェースが 存 在 します。 一 つは 1.9 節 で 述 べ<br />

た 方 法 によるもので、scsl_blas.h に 定 義 されたインターフェースを 使 用 します。 本 節 ではもう 一 つのインタ<br />

ーフェース CBLAS ライブラリについて 説 明 します。<br />

3.6.1. ヘッダファイル<br />

CBLAS インターフェースを 使 用 するには、プログラムにおいて cblas.h ファイルをインクルードする 必 要 が<br />

40<br />

日 本 SGI 株 式 会 社


あります。<br />

#include <br />

3.6.2. 呼 び 出 し 名<br />

FORTRAN 77 インターフェースにおける 文 字 列 引 数 は、CBLAS インターフェースでは 列 挙 型 によって 定<br />

義 されています。 以 下 の 一 覧 をご 参 照 ください。<br />

FORTRAN インターフェース<br />

CBLAS インターフェース<br />

文 字 型 引 数 値 列 挙 型 値<br />

SIDE 'L' CBLAS_SIDE CblasLeft<br />

'R'<br />

CblasRight<br />

UPLO 'U' CBLAS_UPLO CblasUpper<br />

'L'<br />

CblasLower<br />

DIAG 'N' CBLAS_DIAG CblasNonUnit<br />

'U'<br />

CblasUnit<br />

TRANSPOSE 'N' CBLAS_TRANSPOSE CblasNoTrans<br />

'T'<br />

CblasTrans<br />

'C'<br />

CblasConjTrans<br />

CBLAS_ORDER CblasRowMajor<br />

CblasColMajor<br />

上 記 の 表 の 最 後 の 列 挙 型 にある CBLAS_ORDER は、 対 応 する FORTRAN での 引 数 は 存 在 しません。こ<br />

れは、 以 下 の 節 で 説 明 しますが、2 次 元 配 列 を 持 つ 全 てのルーチンに 対 する 引 数 として 使 用 されます。<br />

3.6.3. 配 列 引 数<br />

配 列 要 素 は、メモリ 中 で 連 続 していることが 要 求 されます。 引 数 として 2 次 元 配 列 を 持 つすべての BLAS<br />

ルーチンは、CBLAS インターフェースにおいては 引 数 が 追 加 されます。 引 数 リストにおける 最 初 の 引 数<br />

は、 列 挙 型 の 引 数 です。<br />

enum CBLAS_ORDER {CblasRowMajor=101, CblasColMajor=102};<br />

CblasRowMajor は、 配 列 の 行 内 の 要 素 がメモリ 中 で 連 続 になることを 示 しています。 配 列 の 列 内<br />

の 要 素 は、 定 数 ストライドだけ 離 れます。このストライドパラメータは、FORTRAN 77 インターフ<br />

ェースのリーディングディメンジョン (LDA) に 等 しくなります。<br />

同 様 に CblasColMajor は、 配 列 の 列 中 の 要 素 がメモリ 中 で 連 続 になることを 示 しており、 配 列 の<br />

列 中 の 要 素 が 定 数 ストライドだけ 離 れます。<br />

41<br />

日 本 SGI 株 式 会 社


CBLAS_ORDER パラメータは、ルーチン 内 の 全 ての 配 列 オペランドに 対 して 適 用 されます。<br />

3.6.4. 複 素 数 データ<br />

標 準 の BLAS では、 複 素 数 引 数 をもつルーチンで 使 用 するための 複 素 数 データ 型 は 定 義 していません。<br />

代 わりに、 全 ての 複 素 数 スカラ 値 と 配 列 は void * としてプロトタイプされます。これにより、コンパイラか<br />

らの 警 告 が 生 じることなく、 以 下 で 述 べる 仕 様 を 満 たしているあらゆる 複 素 数 型 のデータ 構 造 を 使 用 する<br />

ことが 可 能 になりますが、コンパイラが 型 のミスマッチを 捉 えられないという 不 都 合 も 生 じます。<br />

CBLAS インターフェースで 使 用 されている、あらゆる C/C++の 複 素 数 データ 型 は 以 下 の 要 求 を 満 たす 必<br />

要 があります。<br />

1. 実 部 と 虚 部 はメモリ 上 で 連 続 である 必 要 がある。<br />

2. 連 続 的 な 配 列 要 素 もメモリ 上 で 連 続 である 必 要 がある。<br />

標 準 の BLAS に 対 する 拡 張 として、<strong>SCSL</strong> は 複 素 数 引 数 について 強 制 的 な 型 チェックのサポートを 提 供 し<br />

ています。これを 可 能 にするために、<strong>SCSL</strong>_NO_VOID_ARGS を CBLAS のヘッダファイルをインクルードす<br />

る 前 に 定 義 する 必 要 があります ( 例 えば、コンパイル 時 に-D<strong>SCSL</strong>_NO_VOID_ARGS を 指 定 するか、 明 示<br />

的 に#define <strong>SCSL</strong>_NO_VOID_ARGS をソースコードに 記 述 します)。 この 定 義 によるデフォルトの 振 る 舞<br />

いは、 以 下 のようになります。<br />

• C++の 標 準 クラスライブラリ (STL) の 複 素 数 型 が 使 われている C++コードについては、 単 精 度 複 素<br />

数 の 引 数 は complex* としてプロトタイプされ、 倍 精 度 複 素 数 の 引 数 は、complex*と<br />

してプロトタイプされます。<br />

• そうでなければ、C/C++の 両 方 に 関 して、 単 精 度 複 素 数 引 数 は scsl_complex *としてプロトタイプさ<br />

れ、 倍 精 度 複 素 数 引 数 は scsl_zomplex* としてプロトタイプされます。<strong>SCSL</strong> 複 素 数 型 は 次 のように<br />

定 義 されています。<br />

typedef struct {float re; float im;} scsl_complex;<br />

typedef struct {double re; double im;} scsl_zomplex;<br />

強 制 的 な 型 チェックは、ユーザ 定 義 の 複 素 数 型 を 用 いているプログラムでも 可 能 です。これを<br />

可 能 にするために、<strong>SCSL</strong>_USER_COMPLEX_T=my_complex か <strong>SCSL</strong>_USER_COMPLEX_T=my_zomplex を<br />

定 義 します。ここで my_comlex と my_zomplex はユーザ 定 義 の 複 素 数 型 の 名 前 です。 これらの<br />

複 素 数 型 は、<strong>SCSL</strong>_NO_VOID_ARGS と 同 様 に CBLAS ヘッダファイルをインクルードする 前 に 定 義<br />

することが 必 要 です。<br />

42<br />

日 本 SGI 株 式 会 社


3.6.5. インデックスを 返 すルーチン<br />

FORTRAN 77 の 配 列 インデックスの 慣 習 に 従 うと、BLASルーチンは、1≦i≦nの 範 囲 のインデックスを 返<br />

します。ここで n は 要 素 数 であり、i はインデックスです。このため 返 り 値 であるインデックスは 直 接 配 列 の<br />

インデックスとして 使 用 することが 可 能 です。C インターフェースは、 同 じ 理 由 により 0≦i


3.7.1. 倍 精 度 スカラー・ベクトル 乗 算 及 びベクトル 同 士 の 和 DASPY<br />

以 下 の 例 では、DAXPY ルーチンによるベクトル 同 士 の 和 を 行 い、 解 析 的 に 正 しい 結 果 との 比 較 を 行 いま<br />

す。<br />

問 題<br />

入 力 となるベクトル X, Y の 各 要 素 は 次 の 式 により 与 えます。<br />

x(i)=i, y(i)=n-α*i, where i=1,n, α=2.0<br />

すなわち、DAXPY で 行 われる 演 算<br />

Y


C<br />

C<br />

C<br />

x(i)=i<br />

y(i)=n-a*i<br />

end do<br />

演 算<br />

call daxpy(n,a,x,1,y,1)<br />

正 しい 解 との 比 較<br />

derr=0.d0<br />

do i=1,n<br />

derr=derr+(y(i)-n)*(y(i)-n)<br />

end do<br />

derr=dsqrt(derr)<br />

write(*,*) derr<br />

stop<br />

end<br />

C/C++<br />

#include <br />

#include <br />

#include <br />

#define N 100<br />

int main(void)<br />

{<br />

int i;<br />

double a, derr;<br />

double x[N], y[N];<br />

/* 初 期 化 */<br />

a = 2.0;<br />

for(i = 0; i < N; i++){<br />

x[i] = i;<br />

y[i] = N - a * i;<br />

}<br />

/* 演 算 */<br />

daxpy(N, a, x, 1, y, 1);<br />

45<br />

日 本 SGI 株 式 会 社


}<br />

/* 正 しい 解 との 比 較 */<br />

derr = 0.0;<br />

for(i = 0; i < N; i++){<br />

derr += (y[i] - N) * (y[i] - N);<br />

}<br />

derr = sqrt(derr);<br />

printf("%g\n", derr);<br />

return 0;<br />

3.7.2. 倍 精 度 実 一 般 行 列 同 士 の 積 DGEMM<br />

サブルーチン DGEMM では、 行 列 A, B、および C とスカラー 値 α、およびβに 対 して 次 の 操 作 をします。<br />

C = j.<br />

46<br />

日 本 SGI 株 式 会 社


サイズ 4 の 場 合 の 行 列 は 下 記 の 通 りです。<br />

DGEMM 引 数 一 覧<br />

DGEMM (TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)<br />

TRANSA ( 入 力 ) 文 字 型 。 行 列 A を 転 置 するか 否 かを 指 定 します。<br />

TRANSA=’N’もしくは’n’: op(A)=A<br />

TRANSA=’Y’もしくは’y’: op(A)= T A<br />

TRANSB ( 入 力 ) 文 字 型 。 行 列 B を 転 置 するか 否 かを 指 定 します。<br />

TRANSA=’N’もしくは’n’: op(B)=B<br />

TRANSA=’Y’もしくは’y’: op(B)= T B<br />

M<br />

( 入 力 ) 整 数 型 。 行 列 op(A) 及 び C の 行 数<br />

N<br />

( 入 力 ) 整 数 型 。 行 列 op(B) 及 び C の 列 数<br />

K<br />

( 入 力 ) 整 数 型 。 行 列 op(A)の 列 数 、 及 び op(B)の 行 数<br />

ALPHA ( 入 力 ) 倍 精 度 実 数 型 。スカラ 値<br />

A ( 入 力 ) 倍 精 度 実 数 型 。 次 元 (LDA,KA) の 配 列 。<br />

TRANSA=’N’だったら KA は K, そうでなければ M<br />

LDA ( 入 力 ) 整 数 型 。 配 列 A の 第 1 次 元<br />

B ( 入 力 ) 倍 精 度 実 数 型 。 次 元 (LDB,KB)の 配 列 。<br />

TRANSB=’N’だったらKBはN、そうでなければK<br />

LDB ( 入 力 ) 整 数 型 。 配 列 B の 第 1 次 元<br />

BETA ( 入 力 ) 倍 精 度 実 数 型 。スカラ 値<br />

C<br />

( 入 出 力 ) 倍 精 度 実 数 型 。 次 元 (LDC,N)の 配 列<br />

LDC ( 入 力 ) 実 数 型 。 配 列 C の 第 1 次 元<br />

データの 格 納 方 法<br />

BLASルーチンへの 引 数 として 渡 される 多 次 元 配 列 は、 列 方 向 の 順 で 格 納 されます。<br />

47<br />

日 本 SGI 株 式 会 社


プログラム 例<br />

FORTRAN<br />

implicit double precision (a-h,o-z)<br />

C<br />

parameter (n=10)<br />

parameter (lda=n,ldb=n,ldc=n)<br />

integer i,j<br />

double precision dtmp,alpha,beta<br />

double precision a(lda,n),b(ldb,n),c(ldc,n)<br />

C 初 期 化<br />

C A: テスト 行 列 B: テスト 行 列 の 逆 行 列 C: 零 行 列<br />

alpha=1.d0<br />

beta =0.d0<br />

do j=1,n<br />

do i=1,n<br />

a(i,j)=n+1.d0-max(i,j)<br />

c(i,j)=0.d0<br />

if((i .eq. 1) .and. (j .eq. 1)) then<br />

b(i,j)=1.d0<br />

else if((i .eq. j-1) .or. (i .eq. j+1)) then<br />

b(i,j)=-1.d0<br />

else if(i .eq. j) then<br />

b(i,j)=2.d0<br />

else<br />

b(i,j)=0.d0<br />

end if<br />

end do<br />

end do<br />

C C := A*B<br />

call dgemm('N','N',n,n,n,alpha,a,lda,b,ldb,beta,c,ldc)<br />

C 正 しい 解 との 比 較<br />

dtmp=0.d0<br />

do j=1,n<br />

do i=1,n<br />

if(i .eq. j) then<br />

dtmp=dtmp+(c(i,j)-1.d0)*(c(i,j)-1.d0)<br />

48<br />

日 本 SGI 株 式 会 社


C<br />

C<br />

else<br />

dtmp=dtmp+c(i,j)*c(i,j)<br />

end if<br />

end do<br />

end do<br />

dtmp=dsqrt(dtmp)<br />

write(*,*) dtmp<br />

stop<br />

end<br />

C/C++<br />

#include <br />

#include <br />

#include <br />

#define N 10<br />

#define LDA N<br />

#define LDB N<br />

#define LDC N<br />

#define MAX(i,j) (((i) > (j)) (i) : (j))<br />

int main(void)<br />

{<br />

int i, j;<br />

double dtmp, alpha, beta;<br />

double a[LDA * N], b[LDB * N], c[LDC *N];<br />

/* 初 期 化 */<br />

/* A: テスト 行 列 B: テスト 行 列 の 逆 行 列 C: 零 行 列 */<br />

alpha = 1.0;<br />

beta = 0.0;<br />

for(j = 0; j < N; j++){<br />

for(i = 0; i < N; i++){<br />

a[j * LDA + i] = N - MAX(i, j);<br />

c[j * LDC + i] = 0.0;<br />

49<br />

日 本 SGI 株 式 会 社


if(i == 0 && j == 0){<br />

b[j * LDB + i] = 1.0;<br />

}else if(i == j - 1 || i == j + 1){<br />

b[j * LDB + i] = -1.0;<br />

}else if(i == j){<br />

b[j * LDB + i] = 2.0;<br />

}else{<br />

b[j * LDB + i] = 0.0;<br />

}<br />

}<br />

}<br />

/* C := A*B */<br />

dgemm("N", "N", N, N, N, alpha, a, LDA, b, LDB, beta, c, LDC);<br />

/* 正 しい 解 との 比 較 */<br />

dtmp = 0.0;<br />

for(j = 0; j < N; j++){<br />

for(i = 0; i < N; i++){<br />

if(i == j){<br />

dtmp += (c[j * LDC + i] - 1.0) * (c[j * LDC + i] - 1.0);<br />

}else{<br />

dtmp += c[j * LDC + i] * c[j * LDC + i];<br />

}<br />

}<br />

}<br />

dtmp = sqrt(dtmp);<br />

printf("%g\n", dtmp);<br />

}<br />

return 0;<br />

50<br />

日 本 SGI 株 式 会 社


3.8. BLAS の 性 能<br />

以 下 にLevel 3 BLASの 複 素 行 列 積 ZGEMMルーチンの 並 列 処 理 における 性 能 グラフを 示 します。<br />

理 論 ピーク 性 能 の8 割 以 上 の 性 能 を 維 持 したまま、プロセッサ 数 の 増 加 に 伴 い、ほぼリニアなスケール<br />

で 性 能 が 向 上 しているのがわかります。また、<strong>SCSL</strong>の 提 供 する3Mカーネルによる 複 素 行 列 積 のルーチ<br />

ンを 用 いることにより、 標 準 的 なZGEMMよりも 短 時 間 で 解 を 求 めることができます。<br />

Gflops (based o<br />

standard ZGEMM<br />

4000 x 4000 Complex Matrix Multiplication<br />

400 MHz Origin 3000<br />

8<br />

7<br />

6<br />

5<br />

4<br />

3<br />

2<br />

1<br />

0<br />

0 2 4 6 8 10<br />

Number of Processors<br />

Standard ZGEMM "3M" ZGEMM Theoretical Peak<br />

51<br />

日 本 SGI 株 式 会 社


4. LAPACK ルーチン<br />

LAPACK は 密 行 列 に 対 する 線 形 代 数 の 問 題 を 解 くためのサブルーチンを 与 えるパブリックドメインのライ<br />

ブラリであり、 以 下 のものを 含 みます。<br />

• 連 立 一 次 方 程 式<br />

• 線 形 最 小 自 乗 問 題<br />

• 固 有 値 問 題<br />

• 特 異 値 分 解 (SVD)<br />

LAPACK パッケージは、LINPACK や EISPACK パッケージにとって 替 わるものであり、これらの 古 いパッ<br />

ケージよりも 現 在 の 高 性 能 な 計 算 機 をより 効 率 よく 利 用 するために 設 計 さています。また、 均 衡 化 や 反<br />

復 改 良 、 誤 差 境 界 の 計 算 法 や、 線 形 システムのドライバルーチン、Schur 分 解 を 計 算 しリオーダリングす<br />

るためのルーチン、そして、 固 有 値 問 題 のための 条 件 数 を 評 価 するためのルーチンを 含 むことによって<br />

機 能 を 拡 張 しています。<br />

レベル 2, 3 の BLAS コードを 用 いて 計 算 効 率 のよいアルゴリズムを 使 用 することで、 性 能 面 での 最 適 化<br />

が 図 られています。ほとんどの BLAS コードは、シングル 及 びマルチプロセッサ 環 境 上 で 最 適 化 されてい<br />

るため、LAPACK 自 身 も 最 適 な 性 能 を 提 供 します。<br />

E. Anderson, Z. Bai, C. Bischof, J. Demmel, J. Dongarra, J. DuCroz, A. Greenbaum, S. Hammarling, A.<br />

McKenney, S. Ostrouchov, and D. Sorensen,らによって LAPACK ユーザガイドで 述 べられたオリジナル<br />

の FORTRAN プログラムは、1992 年 に SIAM より 出 版 されています。<br />

4.1. <strong>SCSL</strong> に 含 まれる LAPACK ルーチン<br />

LAPACK3.0 に 含 まれる 全 ての 実 数 及 び 複 素 数 ルーチンがサポートされています。これには、 連 立 一 次<br />

方 程 式 、 最 小 自 乗 問 題 、 固 有 値 問 題 及 び 特 異 値 問 題 に 関 するドライバルーチンと 計 算 ルーチンを 含 み<br />

ます。また、 基 本 的 な 直 交 変 換 を 行 うための 補 助 ルーチンがサポートされています。<br />

科 学 技 術 計 算 ライブラリ 中 の LAPACK ルーチンについてはオンラインのマニュアルページで 説 明 されて<br />

います。 例 えば、 一 般 行 列 のための 連 立 一 次 方 程 式 を 解 くためのエキスパートドライバルーチンに 対 す<br />

る 引 数 の 説 明 を 見 たいときは、 次 のコマンドを 入 力 します。<br />

% man sgesvx<br />

サポートされている 全 ての LAPACK ルーチンに 対 するユーザインターフェースは、 標 準 の LAPACK イン<br />

ターフェースと 厳 密 に 同 じです。<br />

<strong>SCSL</strong> 中 で 提 供 されているブロックアルゴリズムに 関 するチューニングパラメータは、LAPACK ルーチン<br />

52<br />

日 本 SGI 株 式 会 社


ILAENV(3) 中 のパラメータの 集 合 です。ILAENV(3) は、 問 題 の 型 や 次 元 に 関 する 情 報 を 受 け 付 ける 整<br />

数 関 数 であり、 最 適 なブロックサイズ、ブロックアルゴリズムが 使 用 するべき 最 少 のブロックサイズ、また、<br />

クロスオーバーポイント (ブロック 化 されていないアルゴリズムを 用 いる 際 の 基 準 となる 問 題 サイズ) な<br />

どの 一 つの 整 数 パラメータを 返 します。チューニングパラメータは 自 動 的 に 生 成 されますが、 使 用 される<br />

値 を 見 つけるために ( 例 えば、どの 程 度 の 作 業 空 間 が 必 要 であるかを 知 るために) 直 接 ILAENV(3S)<br />

ルーチンを 呼 ぶことになります。<br />

4.2. ネーミングスキーム<br />

各 LAPACK ルーチン 名 は、その 機 能 のコード 名 となっています (ただし、 標 準 FORTRAN 77 の 6 文 字 名<br />

称 の 制 限 に 従 っています)。 全 てのドライバ 及 び 計 算 ルーチンは、XYYZZ や XYYZZZ などの 5 もしくは 6<br />

文 字 の 名 前 になっています。<br />

それぞれの 名 前 の 最 初 の 文 字 X は、 以 下 のデータの 型 を 意 味 します。<br />

S REAL<br />

D DOUBLE PRECISION<br />

C COMPLEX<br />

Z DOUBLE COMPLEX<br />

続 く 2 文 字 YY は、 行 列 ( 最 も 特 徴 を 示 していると 思 われる 行 列 ) の 種 類 を 示 しています。これらの 2 文<br />

字 で 示 されるコードは、 実 及 び 複 素 行 列 のどちらにも 適 用 されますが、ごくわずかに、どちらか 一 方 にの<br />

みしか 適 用 されないものがあります。 行 列 の 種 類 は、 次 の 通 りです。<br />

BD 準 対 角 行 列<br />

DI 対 角 行 列<br />

GB 一 般 帯 行 列<br />

GE 一 般 行 列 ( 非 対 称 )<br />

GG 一 般 化 問 題 での 一 般 行 列<br />

GT 一 般 三 重 対 角 行 列<br />

HB エルミート 帯 行 列 ( 複 素 のみ)<br />

HE エルミート 行 列 ( 複 素 のみ)<br />

HG 一 般 化 問 題 でのヘッセンベルグ 行 列<br />

HP 圧 縮 形 式 でのエルミート 行 列 ( 複 素 のみ)<br />

HS 上 三 角 ヘッセンベルグ 行 列<br />

OP 圧 縮 形 式 での 直 交 行 列 ( 実 数 のみ)<br />

OR 直 交 行 列 ( 実 数 のみ)<br />

53<br />

日 本 SGI 株 式 会 社


PB 正 値 帯 行 列 ( 対 称 もしくはエルミート)<br />

PO 正 値 行 列 ( 対 称 もしくはエルミート)<br />

PP 圧 縮 形 式 での 正 値 行 列 ( 対 称 もしくはエルミート)<br />

PT 正 値 三 重 対 角 行 列 ( 対 称 もしくはエルミート)<br />

SB 対 称 帯 行 列 ( 実 数 のみ)<br />

SP 圧 縮 形 式 での 対 称 行 列<br />

ST 対 称 三 重 対 角 行 列<br />

SY 対 称 行 列<br />

TB 三 角 帯 行 列<br />

TG 一 般 化 問 題 での 三 角 行 列<br />

TP 圧 縮 形 式 三 角 行 列<br />

TR 三 角 行 列<br />

TZ 台 形 行 列<br />

UN ユニタリ 行 列 ( 複 素 のみ)<br />

UP 圧 縮 形 式 でのユニタリ 行 列 ( 複 素 のみ)<br />

最 後 の 2 もしくは 3 文 字 である ZZ もしくは、ZZZ は、どのような 計 算 が 行 われたかを 示 します。 例 えば、<br />

SGETRF は、 単 精 度 実 数 (Single-precision, real) の 一 般 行 列 (GEneral) に 対 して 3 角 分 解 (TRiangular<br />

Factorization) が 行 われたことを 示 し、CGETRF は、 複 素 一 般 行 列 (Complex GEneral) に 対 して 同 様 の<br />

分 解 が 行 われたことを 示 しています。<br />

<strong>SCSL</strong> で 利 用 可 能 な LAPACK のドライバ 及 び 計 算 ルーチンの 一 覧 や 引 数 、 及 び 使 い 方 に 関 する 詳 細 は、<br />

マニュアルページをご 参 照 ください。<br />

4.3. サンプルプログラム<br />

4.3.1. 倍 精 度 実 一 般 行 列 用 連 立 一 次 方 程 式 の 解 法 DGESV<br />

ここでは 次 のような 連 立 一 次 方 程 式 を 例 にとって 説 明 します。<br />

問 題<br />

⎡1.0<br />

⎢<br />

⎢<br />

1.0<br />

⎢⎣<br />

1.0<br />

3.0<br />

3.0<br />

4.0<br />

3.0⎤<br />

⎡ 1.0 ⎤<br />

4.0<br />

⎥ ⎢ ⎥<br />

⎥<br />

∗ x =<br />

⎢<br />

4.0<br />

⎥<br />

3.0⎥⎦<br />

⎢⎣<br />

−1.0⎥⎦<br />

この 連 立 一 次 方 程 式 に 対 する 解 ベクトル x は 次 の 通 りです。<br />

54<br />

日 本 SGI 株 式 会 社


⎡−<br />

2.0⎤<br />

x =<br />

⎢ ⎥<br />

⎢<br />

− 2.0<br />

⎥<br />

⎢⎣<br />

3.0 ⎥⎦<br />

サブルーチン DGESV の 呼 び 出 しに 必 要 な 引 数 は 次 の 通 りです。<br />

DGESV 引 数 一 覧<br />

DGESV( N, NRHS, A, LDA, IPIV, B, LDB, INFO )<br />

N ( 入 力 ) 整 数 型 。 係 数 行 列 A の 次 数<br />

NRHS ( 入 力 ) 整 数 型 。 右 辺 の 行 列 B の 列 数<br />

A ( 入 出 力 ) 単 精 度 実 数 。 係 数 行 列 A を 格 納 する 次 元 (LDA,N) の 配 列 。 出 力 時 は<br />

LU 分 解 の 結 果<br />

LDA ( 入 力 ) 整 数 型 。 配 列 A の 第 1 次 元<br />

IPIV ( 出 力 ) 整 数 型 。 軸 選 択 用 添 字 を 格 納 する 次 元 N の 配 列<br />

B ( 入 出 力 ) 単 精 度 実 数 。 右 辺 の 行 列 B を 格 納 する 次 元 (LDB,NRHS)の 配 列 。 出 力<br />

時 は INFO=0 の 時 、(n,nrhs)の 解 行 列 X<br />

LDB ( 入 力 ) 整 数 型 。 配 列 B の 第 1 次 元<br />

INFO ( 出 力 ) 整 数 型<br />

0: 正 常 終 了<br />

0 以 外 : 異 常 終 了<br />

データの 格 納 方 法<br />

サブルーチン DGESV は 非 対 称 一 般 行 列 に 対 する 解 法 であり、 本 サブルーチンでの 係 数 行 列 データの<br />

配 列 への 格 納 形 式 は、 密 行 列 に 対 する 伝 統 的 な 格 納 形 式 を 使 用 します。この 格 納 形 式 では 行 列 A の 行<br />

列 要 素 a ij を 2 次 元 配 列 A の 配 列 要 素 A(i,j) に 格 納 します。<br />

a ij -> A(I,j)<br />

プログラム 例 は 次 の 通 りです。<br />

プログラム 例<br />

1: C EXAMPLE LAPACK DGESV<br />

2: INTEGER N, LDA, NRHS, LDB, INFO<br />

3: PARAMETER (N=3,LDA=3,NRHS=1,LDB=3)<br />

4: INTEGER IPIV(N)<br />

5: REAL*8 A(LDA,N), B(LDB,NRHS)<br />

6: C A=( 1.0 3.0 3.0 )<br />

7: C 1.0 3.0 4.0 )<br />

8: C 1.0 4.0 3.0 )<br />

55<br />

日 本 SGI 株 式 会 社


9: C B=( 1.0<br />

10: C 4.0<br />

11: C -1.0 )<br />

12: DATA A/1.0,1.0,1.0,3.0,3.0,4.0,3.0,4.0,3.0/<br />

13: DATA B/1.0,4.0,-1.0/<br />

14:<br />

15: CALL DGESV(N,NRHS,A,LDA,IPIV,B,LDB,INFO)<br />

16:<br />

17: WRITE(*,*) 'INFO=',INFO<br />

18: IF (INFO.EQ.0) THEN<br />

19: WRITE(6,630) ((I,B(I,J),I=1,LDB),J=1,NRHS)<br />

20: END IF<br />

21: 630 FORMAT('0',10X,'SOLUTION VECTOR'<br />

22: * /(10X,5('(',I3,')',E16.8)))<br />

23: END<br />

実 行 例<br />

## リンクオプション –lscs を 指 定 してコンパイル<br />

% f77 dgesv_main.f -lscs<br />

## 実 行<br />

% ./a.out<br />

INFO= 0<br />

0 SOLUTION VECTOR<br />

( 1) -0.20000000E+01( 2) -0.20000000E+01( 3) 0.30000000E+01(<br />

4.3.2. 倍 精 度 実 帯 行 列 用 連 立 一 次 方 程 式 の 解 法 DGBSV<br />

ここでは 次 のような 連 立 一 次 方 程 式 を 例 にとって 説 明 します。<br />

問 題<br />

⎡2.0<br />

⎢<br />

⎢<br />

4.0<br />

⎢6.0<br />

⎢<br />

⎢0.0<br />

⎢<br />

⎣0.0<br />

−1.0<br />

1.0<br />

1.0<br />

2.0<br />

0.0<br />

0.0<br />

2.0<br />

1.0<br />

3.0<br />

2.0<br />

0.0<br />

0.0<br />

4.0<br />

6.0<br />

1.0<br />

0.0⎤<br />

⎡ 0.0 ⎤<br />

0.0<br />

⎥ ⎢ ⎥<br />

⎥ ⎢<br />

12.0<br />

⎥<br />

0.0⎥<br />

∗ x = ⎢27.0⎥<br />

⎥ ⎢ ⎥<br />

1.0⎥<br />

⎢42.0⎥<br />

5.0⎥<br />

⎦<br />

⎢<br />

⎣35.0⎥<br />

⎦<br />

56<br />

日 本 SGI 株 式 会 社


この 連 立 一 次 方 程 式 に 対 する 解 ベクトル x は 次 の 通 りです。<br />

⎡1.0⎤<br />

⎢ ⎥<br />

⎢<br />

2.0<br />

⎥<br />

x = ⎢3.0⎥<br />

⎢ ⎥<br />

⎢4.0⎥<br />

⎢<br />

⎣5.0⎥<br />

⎦<br />

DGESV 引 数 一 覧<br />

DGBSV( N, NRHS, A, LDA, IPIV, B, LDB, INFO )<br />

N ( 入 力 ) 整 数 型 。 係 数 行 列 A の 次 数<br />

KL ( 入 力 ) 整 数 型 。A の 帯 内 の 対 角 下 要 素 の 個 数 ( 対 角 下 帯 幅 )<br />

KU ( 入 力 ) 整 数 型 。A の 帯 内 の 対 角 上 要 素 の 個 数 ( 対 角 上 帯 幅 )<br />

NRHS ( 入 力 ) 整 数 型 。 右 辺 の 個 数 。 行 列 B の 列 数<br />

AB ( 入 出 力 ) 倍 精 度 実 数 型 。 係 数 行 列 を 帯 格 納 形 式 で 格 納 する 次 元 (LDAB,N)の<br />

配 列 。 出 力 時 、 三 角 分 解 の 詳 細 。<br />

LDAB ( 入 力 ) 整 数 型 。 配 列 AB の 第 1 次 元<br />

IPIV ( 入 力 ) 整 数 型 。<br />

B 右 辺 の 行 列 B を 格 納 する 次 元 (LDB,NRHS)の 配 列 。 出 力 時 は INFO=0 の 時 、<br />

(n,nrhs)の 解 行 列 X<br />

LDB ( 出 力 ) 整 数 型 。 軸 選 択 用 添 字 を 格 納 する 次 元 N の 配 列<br />

INFO ( 出 力 ) 整 数 型<br />

0: 正 常 終 了<br />

0 以 外 : 異 常 終 了<br />

データの 格 納 方 法<br />

サブルーチン DGBSV は 非 対 称 一 般 帯 行 列 に 対 する 解 法 であり、 本 サブルーチンでの 係 数 行 列 データ<br />

の 配 列 への 格 納 形 式 は、 帯 格 納 形 式 を 使 用 します。 帯 格 納 形 式 では、 下 バンド 幅 を k l 、 上 バンド 幅 を k u<br />

とした 場 合 、n 次 元 の 帯 行 列 を h l +h u +1 個 の 行 と n 個 の 列 をもつ 2 次 元 配 列 に 詰 めて 格 納 します。 行 列 の<br />

列 はこの 配 列 の 対 応 する 列 に 格 納 し、 行 列 の 対 角 要 素 は 配 列 の 同 一 行 に 格 納 します。<br />

本 ルーチンでは、 係 数 行 列 を 格 納 する 配 列 を 出 力 時 に 三 角 分 解 の 詳 細 を 格 納 する 配 列 としても 使 用 す<br />

るため、 配 列 の 行 サイズは、2*h l +h u +1 として、 係 数 行 列 の 要 素 は、 行 h l+1 行 2*h l +h u +1 に 格 納 します。<br />

この 格 納 方 法 では、max(1,j-k u )≦i≦min(n,j+k l ) に 対 して 行 列 A の 行 列 要 素 a ij を 2 次 元 配 列 A の 配 列 要<br />

素 AB(h l +k u +1+i-j,j) に 格 納 します。<br />

a ij -> AB(h l +k u +1+i-j,j) ,max(1,j-k u )≦i≦min(n,j+k l )<br />

57<br />

日 本 SGI 株 式 会 社


本 問 題 で 扱 う 係 数 行 列 は 配 列 AB に 次 のように 格 納 されます。<br />

⎡2.0<br />

⎢<br />

⎢<br />

4.0<br />

⎢6.0<br />

⎢<br />

⎢0.0<br />

⎢<br />

⎣0.0<br />

帯 行 列 A<br />

−1.0<br />

0.0 0.0<br />

1.0 2.0 0.0<br />

1.0 1.0 4.0<br />

2.0 3.0 6.0<br />

0.0 2.0 1.0<br />

0.0⎤<br />

0.0<br />

⎥<br />

⎥<br />

0.0⎥<br />

⎥<br />

1.0⎥<br />

5.0⎥<br />

⎦<br />

⎡ *<br />

⎢<br />

⎢<br />

*<br />

⎢ *<br />

⎢<br />

⎢2.0<br />

⎢4.0<br />

⎢<br />

⎣6.0<br />

配 列 AB への 帯 格 納<br />

* * * * ⎤<br />

* * * *<br />

⎥<br />

⎥<br />

−1.0<br />

2.0 4.0 1.0⎥<br />

⎥<br />

1.0 1.0 6.0 5.0⎥<br />

1.0 3.0 1.0 * ⎥<br />

⎥<br />

2.0 2.0 * *<br />

⎦<br />

プログラム 例 は 次 の 通 りです。<br />

プログラム 例<br />

1: C EXAMPLE LAPACK DGESV<br />

2: INTEGER N, KL, KU, LDAB, NRHS, LDB, INFO<br />

3: PARAMETER (N=5,KL=2,KU=1,LDAB=2*KL+1+KU,NRHS=1,LDB=5)<br />

4: INTEGER IPIV(N)<br />

5: REAL*8 AB(LDAB,N), B(LDB,NRHS)<br />

6: C<br />

7: C AB=( * * * * *<br />

8: C * * * * *<br />

9: C * -1.0 2.0 4.0 1.0<br />

10: C 2.0 1.0 1.0 6.0 5.0<br />

11: C 4.0 1.0 3.0 1.0 *<br />

12: C 6.0 2.0 2.0 * *)<br />

13: C<br />

14: C B=( 0.0<br />

15: C 12.0<br />

16: C 27.0<br />

17: C 42.0<br />

18: C 35.0 )<br />

19:<br />

20: DATA B/0.0,12.0,27.0,42.0,35.0/<br />

21:<br />

22: READ(5,*) ((AB(I,J),I=KL+1,LDAB),J=1,N)<br />

23: WRITE(6,600) N,((I,J,AB(I,J),J=1,N),I=1,LDAB)<br />

58<br />

日 本 SGI 株 式 会 社


24:<br />

25: CALL DGBSV(N,KL,KU,NRHS,AB,LDAB,IPIV,B,LDB,INFO)<br />

26:<br />

27: WRITE(*,*) 'INFO=',INFO<br />

28: IF (INFO.EQ.0) THEN<br />

29: WRITE(6,630) ((I,B(I,J),I=1,LDB),J=1,NRHS)<br />

30: END IF<br />

31: 600 FORMAT('1',10X,'** COEFFICIENT ','MATRIX'/12X,'ORDER=',I5/<br />

32: * (10X,5('(',I3,',',I3,')',E16.8)))<br />

33: 630 FORMAT('0',10X,'SOLUTION VECTOR'<br />

34: * /(10X,5('(',I3,')',E16.8)))<br />

35: END<br />

実 行 例<br />

## リンクオプション –lscs を 指 定 してコンパイル<br />

% f77 dgbsv_main.f -lscs<br />

% cat dgbsv.5.data<br />

0.0 2.0 4.0 6.0 -1.0 1.0 1.0 2.0 2.0 1.0 3.0 2.0 4.0 6.0 1.0 0.0 1.0 5.0 0.0 0.0<br />

## 実 行<br />

% ./a.out < dgbsv.5.data<br />

1 ** COEFFICIENT MATRIX<br />

ORDER= 5<br />

( 1, 1) 0.00000000E+00( 1, 2) 0.24209217E+00( 1, 3)<br />

0.19367373E+00( 1, 4) 0.12996486E+00( 1, 5) 0.38286897E+00<br />

( 2, 1) 0.13048633E+00( 2, 2) 0.13023846E+00( 2, 3)<br />

0.10609715E+00( 2, 4) 0.00000000E+00( 2, 5) 0.00000000E+00<br />

( 3, 1) 0.00000000E+00( 3, 2) -0.10000000E+01( 3, 3)<br />

0.20000000E+01( 3, 4) 0.40000000E+01( 3, 5) 0.10000000E+01<br />

( 4, 1) 0.20000000E+01( 4, 2) 0.10000000E+01( 4, 3)<br />

0.10000000E+01( 4, 4) 0.60000000E+01( 4, 5) 0.50000000E+01<br />

( 5, 1) 0.40000000E+01( 5, 2) 0.10000000E+01( 5, 3)<br />

0.30000000E+01( 5, 4) 0.10000000E+01( 5, 5) 0.00000000E+00<br />

( 6, 1) 0.60000000E+01( 6, 2) 0.20000000E+01( 6, 3)<br />

0.20000000E+01( 6, 4) 0.00000000E+00( 6, 5) 0.00000000E+00<br />

INFO= 0<br />

0 SOLUTION VECTOR<br />

59<br />

日 本 SGI 株 式 会 社


( 1) 0.10000000E+01( 2) 0.20000000E+01( 3) 0.30000000E+01( 4)<br />

0.40000000E+01( 5) 0.50000000E+01<br />

4.3.3. 倍 精 度 実 一 般 行 列 の LU 分 解 DGETRF と LU 分 解 を 用 いた 連 立 一 次<br />

方 程 式 の 解 法 DGETRS<br />

本 例 題 では、LU 分 解 を 使 って 逆 行 列 を 求 め、 元 の 行 列 との 積 が 単 位 行 列 になることを 確 かめます。<br />

問 題<br />

係 数 行 列 A は 倍 精 度 の 乱 数 発 生 ルーチンによりデータを 与 えます。LU 分 解 を 用 いた 連 立 一 次 方 程 式 の<br />

解 法 ルーチンである DGETRS は、 複 数 個 の 右 辺 ベクトルを 2 次 元 配 列 ( 右 辺 行 列 )で 与 えます。 本 例 題<br />

では、 右 辺 行 列 が 単 位 行 列 となるようにデータを 与 えて、DGETRS を 呼 び 出 すことにより、 解 行 列 ( 各 右<br />

辺 ベクトルに 対 応 する 複 数 の 解 ベクトルの 並 び)が 係 数 行 列 の 逆 行 列 となるようにします。<br />

AX=B において B=E の 時 、<br />

X=A -1 E<br />

X=A -1<br />

DGETRF 引 数 一 覧<br />

DGETRF(M,N,A,LDA,IPIV,INFO )<br />

M ( 入 力 ) 整 数 型 。 係 数 行 列 A の 行 数<br />

N ( 入 力 ) 整 数 型 。 係 数 行 列 A の 列 数<br />

A ( 入 出 力 ) 倍 精 度 実 数 型 。 係 数 行 列 A を 格 納 する 次 元 (LDA,N)の 配 列<br />

LDA ( 入 力 ) 整 数 型 。 配 列 A の 第 1 次 元<br />

IPIV ( 出 力 ) 整 数 型 。 軸 選 択 用 添 え 字 を 格 納 する 次 元 N の 配 列<br />

INFO ( 出 力 ) 整 数 型<br />

0: 正 常 終 了<br />

0 以 外 : 異 常 終 了<br />

DGETRS 引 数 一 覧<br />

DGETRS(TRANS,N,NRHS,A,LDA,IPIV,B,LDB,INFO )<br />

TRANS ( 入 力 ) 文 字 型 。 係 数 行 列 A を 転 置 するか 否 かを 指 定 します。<br />

’N’ : 転 置 しない<br />

‘T’: 転 置 する<br />

N<br />

( 入 力 ) 整 数 型 。 係 数 行 列 A のオーダー。<br />

NRHS ( 入 力 ) 整 数 型 。 右 辺 行 列 B の 列 数<br />

A<br />

( 入 力 ) 倍 精 度 実 数 型 。 係 数 行 列 A を 格 納 する 次 元 (LDA,N)の 配 列<br />

LDA ( 入 力 ) 整 数 型 。 配 列 A の 第 1 次 元<br />

IPIV ( 出 力 ) 整 数 型 。 軸 選 択 用 添 え 字 を 格 納 する 次 元 N の 配 列 で、DGETRF からの 出 力 を 使<br />

60<br />

日 本 SGI 株 式 会 社


B<br />

LDB<br />

INFO<br />

用 する<br />

( 入 出 力 ) 倍 精 度 実 数 型 。 次 元 (LDB,NRHS)の 右 辺 行 列<br />

( 入 力 ) 整 数 型 。 右 辺 行 列 B の 第 1 次 元<br />

( 出 力 ) 整 数 型<br />

0: 正 常 終 了<br />

0 以 外 : 異 常 終 了<br />

データの 格 納 方 法<br />

DGETRF, DGETRS は 実 一 般 行 列 に 対 するルーチンであり、 係 数 行 列 A の 各 要 素 の 配 列 への 格 納 方 法<br />

は、 密 行 列 に 対 する 伝 統 的 な 格 納 形 式 を 使 用 します。この 格 納 形 式 では 行 列 A の 行 列 要 素 a ij を2 次 元<br />

配 列 A の 配 列 要 素 A(i,j) に 格 納 します。<br />

a ij -> A(I,j)<br />

プログラム 例<br />

以 下 に、FORTRAN、C/C++での、BLAS ルーチンを 使 用 したサンプルプログラムを 示 します。<br />

<strong>SCSL</strong> の LAPACK ルーチンは C/C++のインターフェイスを 提 供 していないので、FORTRAN のインターフ<br />

ェイスを 直 接 呼 び 出 していることに 注 意 してください。<br />

FORTRAN<br />

implicit double precision (a-h,o-z)<br />

C<br />

parameter (n=10)<br />

parameter (lda=n,ldb=n)<br />

integer i,j,info,ipiv(n)<br />

integer*8 seed<br />

double precision dummy<br />

double precision dtmp,alpha,beta<br />

double precision a1(lda,n),a2(lda,n),b(ldb,n)<br />

C 初 期 化<br />

C A1,A2: 乱 数 行 列 (A1=A2) B: 単 位 行 列<br />

seed = 1<br />

call drand64_set(seed)<br />

do j=1,n<br />

do i=1,n<br />

a1(i,j)=drand64(dummy)<br />

a2(i,j)=a1(i,j)<br />

61<br />

日 本 SGI 株 式 会 社


C<br />

C<br />

C<br />

C<br />

C<br />

if(i .eq. j) then<br />

b(i,j)=1.d0<br />

else<br />

b(i,j)=0.d0<br />

end if<br />

end do<br />

end do<br />

LU 分 解<br />

call dgetrf(n,n,a1,lda,ipiv,info)<br />

逆 行 列 の 計 算<br />

call dgetrs('N',n,n,a1,lda,ipiv,b,ldb,info)<br />

行 列 積 が 単 位 行 列 になることを 確 かめる<br />

alpha=1.d0<br />

beta =0.d0<br />

call dgemm('N','N',n,n,n,alpha,a2,lda,b,ldb,beta,a1,lda)<br />

dtmp =0.d0<br />

do j=1,n<br />

do i=1,n<br />

if(i .eq. j) then<br />

dtmp=dtmp+(a1(i,j)-1.d0)*(a1(i,j)-1.d0)<br />

else<br />

dtmp=dtmp+a1(i,j)*a1(i,j)<br />

end if<br />

end do<br />

end do<br />

dtmp=dsqrt(dtmp)<br />

write(*,*) dtmp<br />

stop<br />

end<br />

C/C++<br />

#include <br />

#include <br />

#include <br />

62<br />

日 本 SGI 株 式 会 社


#include <br />

#define N 10<br />

#define LDA N<br />

#define LDB N<br />

int main(void)<br />

{<br />

int i, j, n, lda, ldb, info, ipiv[N];<br />

long long seed = 1LL;<br />

double dummy;<br />

double dtmp, alpha, beta;<br />

double a1[LDA * N], a2[LDA * N], b[LDB * N];<br />

/* 初 期 化 */<br />

/* A1,A2: 乱 数 行 列 (A1=A2) B: 単 位 行 列 */<br />

drand64_set(seed);<br />

for(j = 0; j < N; j++){<br />

for(i = 0; i < N; i++){<br />

a1[j * LDA + i] = drand64(&dummy);<br />

a2[j * LDA + i] = a1[j * LDA + i];<br />

if(i == j){<br />

b[j * LDA + i] = 1.0;<br />

}else{<br />

b[j * LDA + i] = 0.0;<br />

}<br />

}<br />

}<br />

n = N;<br />

lda = LDA;<br />

ldb = LDB;<br />

/* LU 分 解 */<br />

dgetrf_(&n, &n, a1, &lda, ipiv, &info);<br />

/* 逆 行 列 の 計 算 */<br />

dgetrs_("N", &n, &n, a1, &lda, ipiv, b, &ldb, &info);<br />

/* 行 列 積 が 単 位 行 列 になることを 確 かめる */<br />

alpha = 1.0;<br />

63<br />

日 本 SGI 株 式 会 社


eta = 0.0;<br />

dgemm("N", "N", N, N, N, alpha, a2, LDA, b, LDB, beta, a1, LDA);<br />

dtmp = 0.0;<br />

for(j = 0; j < N; j++){<br />

for(i = 0; i < N; i++){<br />

if(i == j){<br />

dtmp += (a1[j * LDA + i] - 1.0) * (a1[j * LDA + i] - 1.0);<br />

}else{<br />

dtmp += a1[j * LDA + i] * a1[j * LDA + i];<br />

}<br />

}<br />

}<br />

dtmp = sqrt(dtmp);<br />

printf("%g\n", dtmp);<br />

}<br />

return 0;<br />

4.3.4. 全 部 または 指 定 した 範 囲 の 倍 精 度 実 対 称 固 有 値 問 題 (dqds アルゴリ<br />

ズム) DSYEVR<br />

問 題<br />

本 例 題 では、 対 称 行 列 の 固 有 値 / 固 有 ベクトルを 求 め、 得 られた 固 有 値 を 正 しい 解 と 比 較 します。<br />

テスト 行 列 は、 下 記 で 定 義 される 行 列 を 用 います。<br />

サイズ N の 行 列 A=a[i][j] が 下 記 の 通 りに 定 義 されます。<br />

a[i][j]= a[j][i] = n+1-i, if i >= j.<br />

64<br />

日 本 SGI 株 式 会 社


サイズ 4 の 場 合 の 行 列 は 下 記 の 通 りです。<br />

DSYEVR 引 数 一 覧<br />

DSYEVR(JOBZ,RANGE,UPLO,N,A,LDA,VL,VU,IL,IU,ABSTOL,M,W,Z,LDZ,ISUPPZ,WORK,LWORK,IW<br />

ORK,LIWORK,INFO)<br />

JOBZ<br />

( 入 力 ) 文 字 型 。 固 有 ベクトルを 計 算 するか 否 かを 指 定<br />

=’N’: 固 有 値 のみ 計 算<br />

=’V’: 固 有 値 と 固 有 ベクトルを 計 算<br />

RANGE<br />

( 入 力 ) 文 字 型 。 計 算 する 固 有 値 の 範 囲 を 指 定<br />

=’A’: すべての 固 有 値 を 計 算<br />

=’V’: 半 開 区 間 (VL,VU〕 の 固 有 値 を 計 算<br />

=’I’: IL 番 目 から IU 番 目 の 固 有 値 を 計 算<br />

UPLO<br />

( 入 力 ) 文 字 型 。 配 列 に 格 納 する 係 数 行 列 が 上 三 角 部 分 か 下 三 角 部 分 かを<br />

指 定<br />

=’U’: 係 数 行 列 A の 上 三 角 部 分 を 格 納<br />

=’L’: 係 数 行 列 A の 下 三 角 部 分 を 格 納<br />

N<br />

( 入 力 ) 整 数 型 。 係 数 行 列 A のオーダー<br />

A<br />

( 入 出 力 ) 倍 精 度 実 数 型 。 係 数 行 列 を 格 納 する 次 元 (LDA,N)の 配 列 。 格 納 方<br />

法 は 密 行 列 に 対 する 伝 統 的 な 格 納 形 式 をとり、 格 納 するのは UPLO で 指 定 し<br />

た 当 該 三 角 部 分 となる。 出 力 時 内 容 は 保 存 されない。<br />

LDA<br />

( 入 力 ) 整 数 型 。 配 列 A の 第 1 次 元<br />

VL<br />

( 入 力 ) 倍 精 度 実 数 型 。RANGE=’V’の 時 、 計 算 する 固 有 値 の 範 囲 における 下<br />

限 を 指 定 。<br />

RANGE=’A’または’I’の 時 は 参 照 されない。<br />

VU<br />

( 入 力 ) 倍 精 度 実 数 型 。RANGE=’V’の 時 、 計 算 する 固 有 値 の 範 囲 における 上<br />

限 を 指 定 。<br />

RANGE=’A’または’I’の 時 は 参 照 されない。<br />

IL ( 入 力 ) 整 数 型 。RANGE=’I’の 時 、 計 算 する 最 小 固 有 値 の 添 え 字 を 指 定 。<br />

65<br />

日 本 SGI 株 式 会 社


RANGE=’A’または’V’の 時 は 参 照 されない。<br />

IU ( 入 力 ) 整 数 型 。RANGE=’I’の 時 、 計 算 する 最 大 固 有 値 の 添 え 字 を 指 定 。<br />

RANGE=’A’または’V’の 時 は 参 照 されない。<br />

ABSTOL ( 入 力 ) 倍 精 度 実 数 型 。 固 有 値 に 対 する 絶 対 許 容 誤 差 。 詳 細 については、<br />

LAPACK マニュアルの 当 該 ルーチンの 説 明 箇 所 を 参 照 ください<br />

M<br />

( 出 力 ) 整 数 型 。 見 つかった 固 有 値 の 総 数<br />

W<br />

( 出 力 ) 倍 精 度 実 数 型 。 最 初 の M 個 の 要 素 は、 見 つかった M 個 の 固 有 値 が 昇<br />

順 で 格 納 される。 次 元 N の 配 列<br />

Z<br />

( 出 力 ) 倍 精 度 実 数 型 。 計 算 された 固 有 ベクトルが 入 る 次 元 (LDZ,max(1,M))<br />

の 配 列 。Z の 第 i 列 には W(i)に 関 係 した 固 有 ベクトルが 入 る<br />

LDZ<br />

( 入 力 ) 整 数 型 。 配 列 Z の 第 1 次 元<br />

ISUPPZ ( 出 力 ) 整 数 型 。 配 列 Z における 非 ゼロ 要 素 の 添 え 字 が 格 納 される。 第 i 番 目<br />

の 固 有 ベクトルのうち、ISUPPZ(2*i-1)から ISUPPZ(2*i)の 要 素 のみが 非 ゼロで<br />

ある。<br />

WORK<br />

( 作 業 領 域 / 出 力 ) 倍 精 度 実 数 型 。 次 元 LWORK の 配 列 。 出 力 時 、WORK(1)に<br />

最 適 な LWORK が 返 される。<br />

LWORK<br />

( 入 力 ) 整 数 型 。 配 列 WORK の 次 元 。LWORK≧max(1,26+N)<br />

IWORK<br />

( 作 業 領 域 / 出 力 ) 整 数 型 。 次 元 LIWORK の 配 列 。 出 力 時 、IWROK(1)に 最 適 な<br />

LIWORK が 返 される。<br />

LIWORK ( 入 力 ) 整 数 型 。 配 列 IWORK の 次 元 。LIWORK≧max(1,10*N)<br />

INFO<br />

( 出 力 ) 整 数 型<br />

0: 正 常 終 了<br />

< 0: i 番 目 の 引 数 が 適 切 でない<br />

> 0: 異 常 終 了<br />

データの 格 納 方 法<br />

ルーチン DSYVR は 対 称 固 有 値 問 題 に 対 するルーチンです。 行 列 の 配 列 への 格 納 方 法 は、 密 行 列 に 対<br />

する 伝 統 的 な 格 納 形 式 をとり、 格 納 するのは UPLO で 指 定 した 当 該 三 角 部 分 となります。<br />

本 例 題 では、UPLO=’U’ を 指 定 しています。これは、 行 列 A の 上 三 角 部 分 を 配 列 A に 格 納 することを 指<br />

定 しています。 以 下 は N=4 で、UPLO=’U’の 時 の 配 列 への 格 納 のされ 方 を 示 しています。 配 列 の 残 りの<br />

要 素 ( 下 三 角 部 分 )は 設 定 する 必 要 はありません。<br />

⎡a11<br />

⎢<br />

⎢<br />

a21<br />

⎢a31<br />

⎢<br />

⎣a41<br />

対 称 行 列 A<br />

a12<br />

a13<br />

a22<br />

a23<br />

a32<br />

a33<br />

a42<br />

a43<br />

a14⎤<br />

a24<br />

⎥<br />

⎥<br />

a34⎥<br />

⎥<br />

a44⎦<br />

配 列 A への 格 納<br />

a11<br />

a12<br />

a14<br />

a14<br />

* a22<br />

a23<br />

a24<br />

* * a33<br />

a34<br />

* * * a44<br />

66<br />

日 本 SGI 株 式 会 社


プログラム 例<br />

FORTRAN<br />

C<br />

C<br />

C<br />

C<br />

C<br />

C<br />

C<br />

C<br />

implicit double precision (a-h,o-z)<br />

parameter (n=10,lda=n,ldz=n)<br />

parameter (nw=(n+16)*n,niw=(n+1)*n)<br />

parameter (eps=1.d-12)<br />

integer i,j,m,n,il,info<br />

integer isuupz(2*n),iwork(niw)<br />

double precision derr,vl,vu<br />

double precision a(lda,n),w(n)<br />

double precision z(ldz,n),work(nw)<br />

初 期 化<br />

A: テスト 行 列 の 上 三 角 部 分<br />

vl=0.d0<br />

vu=0.d0<br />

do j=1,n<br />

do i=1,j<br />

a(i,j)=n-j+1.d0<br />

end do<br />

end do<br />

全 固 有 値 / 固 有 ベクトルの 計 算<br />

call dsyevr('V','A','U',n,a,lda,vl,vu,<br />

& il,n,eps,m,w,z,ldz,isuppz,work,nw,iwork,niw,info)<br />

固 有 値 が 正 しい 値 であるか、 確 かめる<br />

derr=0.d0<br />

do i=1,n<br />

derr=derr+(w(i)-deigen(n,i))*(w(i)-deigen(n,i))<br />

end do<br />

derr=dsqrt(derr)<br />

write(*,*) derr<br />

stop<br />

end<br />

67<br />

日 本 SGI 株 式 会 社


C<br />

C<br />

C<br />

C<br />

テスト 行 列 の 固 有 値 関 数<br />

double precision function deigen(n,i)<br />

implicit double precision (a-h,o-z)<br />

integer n,i<br />

double precision dpi<br />

dpi =4.d0*atan(1.d0)<br />

deigen=1.d0/(2.d0*(1.d0-cos(dpi*<br />

& (2.d0*(n+1-i)-1.d0)/(2.d0*n+1.d0))))<br />

return<br />

end<br />

C/C++<br />

#include <br />

#include <br />

#include <br />

#define N 10<br />

#define LDA N<br />

#define LDZ N<br />

#define NW ((N + 16) * N)<br />

#define NIW ((N + 1) * N)<br />

#define EPS 1.0e-12<br />

double deigen(int n, int i);<br />

int main(void)<br />

{<br />

int lda, ldz, nw, niw;<br />

int i, j, m, n, il, info;<br />

int isuppz[2 * N], iwork[NIW];<br />

double derr, vl, vu, eps;<br />

double a[LDA * N], w[N];<br />

double z[LDZ * N], work[NW];<br />

68<br />

日 本 SGI 株 式 会 社


* 初 期 化 */<br />

/* A: テスト 行 列 の 上 三 角 部 分 */<br />

vl = 0.0;<br />

vu = 0.0;<br />

for(j = 0; j < N; j++){<br />

for(i = 0; i < N; i++){<br />

a[j * LDA + i] = N - j;<br />

}<br />

}<br />

n = N;<br />

lda = LDA;<br />

ldz = LDZ;<br />

nw = NW;<br />

niw = NIW;<br />

eps = EPS;<br />

/* 全 固 有 値 / 固 有 ベクトルを 求 める */<br />

dsyevr_("V", "A", "U", &n, a, &lda, &vl, &vu,<br />

&il, &n, &eps, &m, &w, z, &ldz, isuppz,<br />

work, &nw, iwork, &niw, &info);<br />

/* 固 有 値 が 正 しい 値 であることを 確 かめる */<br />

derr = 0.0;<br />

for(i = 0; i < N; i++){<br />

derr += (w[i] - deigen(N, i)) * (w[i] - deigen(N, i));<br />

}<br />

derr = sqrt(derr);<br />

printf("%g\n", derr);<br />

}<br />

return 0;<br />

/* テスト 行 列 の 固 有 値 関 数 */<br />

double deigen(int n, int i)<br />

{<br />

double dpi;<br />

69<br />

日 本 SGI 株 式 会 社


dpi = 4.0 * atan(1.0);<br />

return 1.0/(2.0 * (1.0 -<br />

cos(dpi * (2.0 * (n - i) - 1.0) / (2.0 * n + 1))));<br />

}<br />

70<br />

日 本 SGI 株 式 会 社


4.4. LAPACK の 性 能<br />

以 下 に LAPACK ルーチン DGETRF(LU 分 解 )の 並 列 処 理 における 性 能 グラフを 示 します。<br />

プロセッサ 数 を 多 くしても、スケーラビリティの 高 い、 良 好 な 並 列 性 能 が 得 られていることがわかります。<br />

Gflops<br />

30<br />

25<br />

20<br />

15<br />

10<br />

5<br />

0<br />

LAPACK DGETRF Routine -- LU<br />

Factorization<br />

400 MHz Origin 3000<br />

1 10 100<br />

Number of Processors<br />

4000 x 4000 system 16000 x 16000 system<br />

71<br />

日 本 SGI 株 式 会 社


5. 疎 行 列 の 直 接 解 法 、 反 復 解 法<br />

5.1. はじめに<br />

<strong>SCSL</strong> 科 学 技 術 計 算 ライブラリは、 疎 行 列 に 対 して2 種 類 の 直 接 法 ルーチンを 提 供 しています。<br />

• DPSLDLT, ZPSLDLT ( 対 称 線 形 一 次 方 程 式 の 解 法 )<br />

• DPSLDU , ZPSLDU( 非 対 称 線 形 一 次 方 程 式 の 解 法 )<br />

また、 疎 行 列 反 復 解 法 として Diterative ルーチンを 提 供 しています。<br />

これらのルーチンは、SGI が 開 発 したものであり、SGI のシステムに 最 適 化 されています。 密 行 列 の 線 形<br />

方 程 式 に 対 する 直 接 法 ソルバは INTRO_LAPACK(3S) のマニュアルページをご 参 照 ください。<br />

DPSLDLT、ZPSLDLT は、 疎 行 列 の 対 称 線 形 方 程 式 Ax=b を 解 きます。ここで、A は n×n の 対 称 行 列 、b<br />

は 次 元 n の 右 辺 ベクトル、x は 次 元 n の 解 ベクトルです。<br />

これらのソルバは、 直 接 法 を 用 いています。A は 次 の 形 式 に 分 解 できます。<br />

A = L D L T<br />

ここで、L は 対 角 要 素 が 1 の 下 三 角 行 列 、D は 対 角 項 だけの 行 列 を 示 しています。<br />

ソルバは、 倍 精 度 実 数 版 、 倍 精 度 複 素 数 版 が 用 意 されており、<strong>SCSL</strong> の 並 列 化 にも 対 応 しています。 詳<br />

細 は、DPSLDLT(3S)、ZPSLDLT(3S)のマニュアルページをご 参 照 ください。<br />

DPSLDU、ZPSLDU は、 非 対 称 の 対 称 線 形 方 程 式 Ax=b を 解 きます。ここで、A は n×n の 非 ゼロ 要 素 の<br />

位 置 については 対 称 であるが 値 は 非 対 称 である 行 列 、b は 次 元 n の 右 辺 ベクトル、x は 次 元 n の 解 ベク<br />

トルです。<br />

これらのソルバこれらのソルバは、 直 接 法 を 用 いています。A は 次 の 形 式 に 分 解 できます。<br />

A = L D U<br />

ここで、L は 対 角 要 素 が 1 の 下 三 角 行 列 、D は 対 角 項 だけの 行 列 、U は 対 角 要 素 が 1 の 上 三 角 行 列 を<br />

示 しています。<br />

72<br />

日 本 SGI 株 式 会 社


このソルバは、 倍 精 度 実 数 版 、 倍 精 度 複 素 数 版 が 用 意 されており、<strong>SCSL</strong> の 並 列 化 にも 対 応 しています。<br />

詳 細 は、DPSLDU(3S)、ZPSLDU(3S)のマニュアルページをご 参 照 ください。<br />

Diterative ルーチンは 疎 行 列 線 形 方 程 式 Ax=bを 反 復 法 で 解 きます。ここで、A はCSCまたはCSR 形 式<br />

で 格 納 されたnXnの 入 力 行 列 、b は 次 元 n の 右 辺 ベクトル、x は 次 元 n の 解 ベクトルです。<br />

反 復 ソルバでは4つの 前 処 理 付 反 復 法 を 利 用 できます。 対 称 行 列 向 けの 解 法 として、 共 役 勾 配 (CG) 法<br />

および 共 役 残 差 (CR) 法 、 非 対 称 行 列 向 けの 解 法 として、 共 役 勾 配 二 乗 (CGS) 法 およびその 変 種 で 収<br />

束 の 過 程 がよりスムーズな 双 共 役 勾 配 安 定 (BiCGSTAB) 法 が 含 まれます。 反 復 法 へ 適 用 する 前 処 理<br />

としては、ヤコビ、 対 称 逐 次 緩 和 (SSOR) 法 、パターンによる 不 完 全 LU 分 解 、 値 による 不 完 全 LU 分 解<br />

が 利 用 できます。 不 完 全 LU 分 解 は 対 称 行 列 にのみ 適 用 でき、 値 による 不 完 全 LU 分 解 はまだ 並 列 化 さ<br />

れていません。<br />

反 復 ソルバは、 現 在 、 倍 精 度 実 数 版 のみをサポートしています。 詳 細 は ITERATIVE(3S)を 御 覧 ください。<br />

5.2. 注 意<br />

これらの 疎 行 列 に 対 するルーチンはピボッティングのための 枢 軸 の 選 択 を 行 いません。<br />

現 在 、<strong>SCSL</strong> はリシェイプト 配 列 (reshaped array) をサポートする 予 定 はありません。<br />

また、これらのルーチンは SGI R8000, R10000, R12000 のシステム 向 けに 最 適 化 されています。<br />

5.3. DPSLDLT、ZPSLDLT ルーチン<br />

ここでは、 対 称 疎 行 列 直 接 解 法 DPSLDLT、ZPSLDLT ルーチンの 使 用 方 法 に 関 して 説 明 します。 以 下 で<br />

は 倍 精 度 実 数 版 を 例 に 説 明 しますが、 倍 精 度 複 素 数 版 も 基 本 的 には 同 じです。 倍 精 度 複 素 数 版 の 場 合<br />

には、 関 数 の 接 頭 文 字 D をZに、ops と ooclimit を 除 く 引 数 の DOUBLE PRECISION 型 を COMPLREX*16<br />

型 (C/C++では double 型 を scsl_zcomplex 型 )に、 各 々 読 み 替 えてください。<br />

なお、 環 境 変 数 に 関 しては、DPSLDLT、ZPSLDLT ともに 共 通 です。<br />

DPSLDLT では、 対 称 疎 行 列 に 対 する 並 列 化 対 応 直 接 法 ソルバを 提 供 し、 以 下 のルーチンより 構 成 され<br />

ています。これらのルーチンの 詳 細 については、 本 節 以 降 をご 参 照 ください。<br />

DPSLDLT_Destroy, DPSLDLT_ExtractPerm, PSLDDLT_Factor, DPSLDLT_FactorOOC,<br />

73<br />

日 本 SGI 株 式 会 社


DPSLDLT_OOCLimit, DPSLDLT_OOCPath, DPSLDLT__Ordering, DPSLDLT_Preprocess,<br />

DPSLDLT_PreprocessZ, DPSLDLT_Solve, DPSLDLTT_SolveM, DPSLDLT_Storage<br />

5.3.1. 関 数 一 覧<br />

以 下 に、 各 関 数 の 引 数 のデータ 型 を 示 します。 各 引 数 についての 説 明 は、 第 5.3.10 節 引 数 の 説 明 を<br />

ご 参 照 ください。<br />

5.3.1.1. FORTRAN<br />

SUBROUTINE DPSLDLT_DESTROY (token)<br />

INTEGER<br />

token<br />

SUBROUTINE DPSLDLT_EXTRACTPERM (token, perm)<br />

INTEGER<br />

token, perm(*)<br />

SUBROUTINE DPSLDLT_FACTOR (token, n, pointers, indices, values)<br />

INTEGER<br />

token, n, pointers(*), indices(*)<br />

DOUBLE PRECISION values(*)<br />

SUBROUTINE DPSLDLT_FACTOROOC (token, n, pointers, indices, values)<br />

INTEGER<br />

token, n, pointers(*), indices(*)<br />

DOUBLE PRECISION values(*)<br />

SUBROUTINE DPSLDLT_OOCLIMIT (token, ooclimit)<br />

INTEGER<br />

token<br />

DOUBLE PRECISION ooclimit<br />

SUBROUTINE DPSLDLT_OOCPATH (token, oocpath, length)<br />

INTEGER<br />

token, length<br />

CHARACTER<br />

oocpath(*)<br />

SUBROUTINE DPSLDLT_ORDERING (token, method)<br />

INTEGER<br />

token, method<br />

SUBROUTINE DPSLDLT_PREPROCESS (token, n, pointes, indices,non_zeros, ops)<br />

INTEGER<br />

token, n, pointers(*), indices(*)<br />

INTEGER*8<br />

non_zeros<br />

DOUBLE PRECISION ops<br />

74<br />

日 本 SGI 株 式 会 社


SUBROUTINE DPSLDLT_PREPROCESSZ (token, n, pointers, indices, mask, non_zeros, ops)<br />

INTEGER<br />

INTEGER*8<br />

DOUBLE PRECISION<br />

token, n, pointers(*), indices(*), mask(*)<br />

non_zeros<br />

ops<br />

SUBROUTINE DPSLDLT_SOLVE (token, x, b)<br />

INTEGER<br />

token<br />

DOUBLE PRECISION x(*), b(*)<br />

SUBROUTINE DPSLDT_SOLVEM (token, X, ldx, B, ldb, nrhs)<br />

INTEGER<br />

Token, ldx, ldb, nrhs<br />

DOUBLE PRECISION X(*), B(*)<br />

DOUBLE PRECISION FUNCTION DPSLDLT_STORAGGE(token)<br />

INTEGER<br />

token<br />

5.3.1.2. C/C++<br />

#include <br />

void DPSLDLT_Destroy (int token );<br />

void DPSLDLT_ExtractPerm (int token int perm[];<br />

void DPSLDLT_Factor (int token, int n, int pointers[], intindices[], double values[] );<br />

void DPSLDLT_FactorOOC (int token, int n, int pointers[], intindices[], double values[] );<br />

void DPSLDLT_OOCLimit (int token, double ooclimit );<br />

void DPSLDLT_OOCPath (int token, char oocpath );<br />

void DPSLDLT_Ordering (int token, int method );<br />

void DPSLDLT_Preprocess (int token, int n, int ponters[], int indices[], long long<br />

*non_zeros, double *ops );<br />

void DPSLDLT_PreprocessZ (int token, int n, int pointers[], intindices[], int mask[], long<br />

75<br />

日 本 SGI 株 式 会 社


long *non_zeros, double *ops );<br />

void DPSLDLT_Solve (int token, double x[], doublle b[] );<br />

void DPSLDLT_SolveM (int token, double X[], int ldx, double B[], int ldb, int nrhs);<br />

double DPSLDLT_Storage (int token);<br />

5.3.2. 詳 細<br />

DPSLDLT は、 疎 行 列 の 対 称 線 形 方 程 式 Ax=b を 解 きます。ここで、A は n×n の 対 称 行 列 、b は 次 元 n<br />

の 右 辺 ベクトル、x は 次 元 n の 解 ベクトルです。<br />

DPSLDLT は、 直 接 法 を 用 いています。A は 次 の 形 式 に 分 解 できます。<br />

A = L D L T<br />

ここで、L は 対 角 要 素 が 1 の 下 三 角 行 列 、D は 対 角 項 だけの 行 列 を 示 しています。<br />

このルーチンは、 倍 精 度 版 だけが 用 意 されており、<strong>SCSL</strong> の 並 列 化 にも 対 応 しています。<br />

このルーチンではピボッティングを 行 わないことに 注 意 してください。<br />

DPSLDLT ライブラリは、5 つのメインルーチンから 構 成 されています。<br />

• DPSLDLT_Ordering() は、 行 列 の 前 処 理 段 階 で 使 われる 5 つのオーダリング 方 法 を 選 択 します。<br />

• DPSLDLT_Preprocess() は、 行 列 A の 構 造 に 対 して 前 処 理 を 行 います。(L のフィルインを 減 少 させ<br />

るオーダリングや、シンボル 分 解 など)<br />

• DPSLDLT_Factor() は、 先 に 処 理 した 行 列 A を L と D に 分 解 します。<br />

• DPSLDLT_Solve() は、 右 辺 bベクトルに 対 する 解 ベクトルxを 求 めます。<br />

• DPSLDLT_Destroy() は、 行 列 A の 分 解 に 使 用 したメモリ 領 域 を 開 放 します。(L, D の 他 に 前 処 理 段<br />

階 で 必 要 となるデータ 構 造 などを 含 みます。)<br />

非 ゼロ 要 素 の 位 置 は 同 じで 値 が 異 なる 行 列 、すなわち、 構 造 が 同 じ 行 列 であれば、<br />

DPSLDLT_Preprocess()は 一 度 だけ 呼 べばよく、それらの 行 列 を L と D に 分 解 するための<br />

DPSLDLT_Factor()は 複 数 回 呼 び 出 すことが 可 能 です。 同 様 に、 複 数 の 右 辺 を 解 くために、<br />

76<br />

日 本 SGI 株 式 会 社


DPSLDLT_Factor()を 1 回 呼 び 出 した 後 、DPSLDLT_Solve()を 複 数 回 呼 び 出 すことも 可 能 です。また、 複<br />

数 の 右 辺 を 1 次 元 の 配 列 にすべて 格 納 して、DPSLDLT_SolveM()を 呼 び 出 すことも 可 能 です。<br />

5.3.3. 疎 行 列 の 格 納 形 式<br />

疎 行 列 A は、DPSLDLT に 対 して、ハーウェル ボーイング (Compressed Column Storage の 名 でも 呼 ば<br />

れています) 形 式 の 入 力 でなければなりません。<br />

対 象 とする 行 列 は、pointers, indices, values の 3 つ 配 列 から 構 成 されています。Indices 配 列 は、 配 列 A<br />

の 非 ゼロ 要 素 の 行 番 号 を 格 納 しています。Values 配 列 は、その 位 置 の 非 ゼロ 要 素 の 値 を 格 納 します。<br />

Pointers 配 列 は、 配 列 A の 各 列 について 最 初 の 非 ゼロ 要 素 が 何 番 目 の 非 ゼロ 要 素 かを 格 納 した 配 列 で<br />

す。こうして、i 列 目 の 非 ゼロ 要 素 に 対 する 行 番 号 は、indices[pointers[i]]から indices[pointers[i+1]-1]に<br />

格 納 されています。それに 対 応 する 配 列 A の 非 ゼロ 要 素 の 値 は、 values[pointers[i]]から<br />

values[pointers[i+1]-1]に 格 納 されています。<br />

対 称 行 列 A に 対 しては、A の 下 三 角 あるいは 上 三 角 のどちらかを 与 えれば 良 く、 両 方 を 与 える 必 要 はあ<br />

りません。A の 同 じ 列 内 の 要 素 については 順 序 は 問 いません。<br />

対 称 行 列 に 対 する 例 を 以 下 に 示 します。<br />

1.0<br />

0.0 3.0<br />

2.0 0.0 5.0<br />

0.0 4.0 0.0 6.0<br />

は、FORTRAN では 次 のように 記 述 されます。<br />

INTEGER pointers(5), indices(6), i<br />

DOUBLE PRECISION values(6)<br />

DATA (pointers(i), i = 1, 5) / 1, 3, 5, 6, 7 /<br />

DATA (indices(i), i = 1, 6) / 1, 3, 2, 4, 3, 4 /<br />

DATA (values(i), i = 1, 6) / 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 /<br />

C の 様 に 0 から 始 まる 添 字 で 示 すと、pointers と indices の 配 列 は、 次 のようになります。<br />

Int pointers[] = {0, 2, 4, 5, 6}<br />

77<br />

日 本 SGI 株 式 会 社


int indices[] = {0, 2, 1, 3, 2, 3}<br />

double values[] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}<br />

5.3.4. オーダリングの 方 法<br />

DPSLDLT_Ordering(token, method) ルーチンは、 行 列 の 分 解 を 行 う 前 に 前 処 理 に 用 いるオーダリングの<br />

方 法 を 変 更 します。このルーチンは DPSLDLT_Preprocess の 前 に 呼 び 出 さなければなりません。 現 在 、5<br />

種 類 の method の 指 定 ができます。<br />

• Method 0 は 前 処 理 のオーダリングを 行 わない。<br />

• Method 1 フィルインが 最 小 となるようなオーダリング<br />

• Method 2 シングルネスト 分 析 によるオーダリング(デフォルト)<br />

• Method 3 マルチプルネスト 分 析 によるオーダリング( 並 列 化 対 応 )<br />

• Method 4 マルチプルネスト 分 析 によるオーダリング( 並 列 化 対 応 )<br />

メソッド 4 では、 同 じ 行 列 構 造 に 対 しては 前 回 の 結 果 を 学 習 してもっとも 効 率 的 なオーダリングを 行<br />

ないます。メソッド 3 と 4 は 同 じマルチプルネスト 分 析 のアルゴリズムを 採 用 しています。<br />

メソッド 2 はメソッド 1 に 比 較 して、 演 算 量 は 多 くなりますが、はるかに 良 いオーダリングを 行 います。メソ<br />

ッド 3 は、 特 にマルチプロセッサのシステムで 有 効 です。メソッド 3 は、OMP_NUM_THREADS (OpenMP で<br />

使 用 するプロセッサ 数 を 指 定 する 環 境 変 数 ) 種 類 の 行 列 のオーダリングの 評 価 を 並 列 に 行 ない、 行 列<br />

の 分 解 段 階 でもっとも 浮 動 小 数 点 演 算 が 減 るようなオーダリングを 選 択 します。<br />

メソッド 4 は、 同 じ 非 ゼロ 要 素 構 造 の 行 列 に 対 して、 複 数 の 右 辺 に 対 する 解 を 求 める 場 合 にだけに 使 用<br />

します。メソッド 4 は、「 学 習 」ファイルに 最 大 200 個 分 の 行 列 の 構 造 と 前 回 の 履 歴 情 報 を 記 録 します。 次<br />

回 のメソッド 4 の 呼 び 出 しでは、 同 じ 非 ゼロ 構 造 の 行 列 に 対 して、2 * OMP_NUM_THREADS 種 類 のオー<br />

ダリングを 評 価 して、もっとも 浮 動 小 数 点 演 算 が 少 なくなるオーダリングを 選 択 します。こうして、オーダリ<br />

ングの 質 は 計 算 を 続 けるにしたがって 改 良 され 続 けます。<br />

メソッド 3 と 4 は、デフォルトの 行 列 の 前 処 理 よりも 計 算 時 間 を 要 します。しかし、 大 規 模 な 系 あるいは 分<br />

解 を 繰 り 返 すにしたがい、メソッド 2 に 対 してソルバ 全 体 で 大 幅 な 性 能 改 善 (1.1〜2 倍 程 度 )が 得 られま<br />

す。<br />

5.3.5. 置 換 ベクトル<br />

メソッド 0 を 選 択 しない 場 合 、DPSLDLT は、 行 列 A に 対 して 行 列 の 分 解 を 行 なう 前 に 行 の 入 れ 替 えを 行<br />

ないます。その 結 果 、 一 般 的 に 行 の 入 れ 替 えを 終 えた 行 列 はオリジナルの 行 列 に 対 してフィルインが 減<br />

78<br />

日 本 SGI 株 式 会 社


少 します。また、token の 対 応 した 行 の 入 れ 替 えを 行 なった 行 列 を DPSLDLT_ExtractPerm(token, perm)<br />

を 呼 び 出 すことで 得 ることができます。 置 換 ベクトルは、 大 きさ n の 1 次 元 の 配 列 1≦perm(i) ≦n に 戻 り<br />

ます。 (C コードに 対 しては 0 ≦perm[i] < n です。 )<br />

perm(i)の k の 値 は、オリジナルの i 行 の 値 が 新 しいオーダリングでは k 行 になることを 表 しています。<br />

5.3.6. 対 角 項 がゼロになる 行 列<br />

先 に 述 べたように、 行 列 の 分 解 では 安 定 性 向 上 のためのピボッティングを 行 いません。 対 角 項 がゼロ、<br />

あるいはゼロに 非 常 に 近 い 場 合 、DPSLDLT はエラーメッセージを 出 力 し 実 行 を 停 止 します。この 場 合 、<br />

わずかに 結 果 が 異 なるかも 知 れませんが、 安 定 性 の 高 いオーダリングを 行 う DPSLDLT_PreprocessZ()<br />

を 使 用 することが 可 能 です。この 場 合 、DPSLDLT_PreprocessZ()に 対 して 整 数 型 の 配 列 mask が 必 要 に<br />

なります。もし、mask(i)=0 であれば、DPSLDLT はできるかぎり 対 角 項 の|Aii|が 最 大 になるようにオーダリ<br />

ングをします。<br />

5.3.7. メモリの 使 用 量<br />

DPSLDLT_Storage()は、 行 列 のデータ 構 造 に 応 じて 必 要 とされるメモリの 総 量 の 見 積 りをメガ・バイト 単<br />

位 で 返 します。<br />

5.3.8. アウトオブコア 分 解<br />

分 解 に 必 要 な 2 種 類 のメモリ 管 理 方 法 のルーチンを 提 供 します。 DPSLDLT_Factor()は、 分 解 に 必 要 な<br />

メモリを 内 部 的 に 確 保 した 後 、DPSLDLT_Destroy()が 呼 ばれるまで 確 保 し 続 けます。もう 一 つは、アウト<br />

オブコア 分 解 のルーチンである DPSLDLT_FactorOOC()です。このルーチンでは、メモリの 使 用 量 は 少 な<br />

くて 済 みますが、 残 りの 必 要 な 領 域 をディスク 上 に 確 保 します。DPSLDLT_OOCPath()は、 分 解 ファイル<br />

が 作 成 されるディレクトリを 指 示 し、DPSLDLT_OOCLimit()は、 行 列 の 分 解 に 必 要 とされるメモリ 領 域 の 上<br />

限 を 与 えます。より 多 くのメモリを 使 用 すれば、ディスク I/O は 減 少 して 行 列 分 解 部 分 の 性 能 が 向 上 しま<br />

す。インコア 分 解 からアウトオブコア 分 解 へは、DPSLDLT_Factor()を DPSLDLT_FactorOOC()に 変 更 す<br />

るだけです。 他 のルーチン(DPSLDLT_Solve(), DPSLDLT_Destroy()など)は、アウトオブコア 分 解 ルーチン<br />

と 互 換 性 があるように 設 計 されています。DPSLDLT_FactorOOC とそれに 続 く DPSLDLT_Solve の 呼 び 出<br />

しは 並 列 化 されていないことに 注 意 してください。<br />

5.3.9. 複 数 の 右 辺 に 対 する 解<br />

DPSLDLT は、DPSLDLT_SolveM()を 1 回 呼 び 出 すことで、 複 数 の 右 辺 に 対 する 解 を 求 めます。<br />

79<br />

日 本 SGI 株 式 会 社


DPSLDLT_SolveM()は、これらの 右 辺 に 対 する 計 算 を 各 プロセッサで 並 列 に 行 ないます。<br />

5.3.10. 各 ルーチンの 引 数 の 説 明<br />

DPSLDLT の 各 ルーチンは 以 下 の 引 数 をとります。<br />

引 数<br />

説 明<br />

token<br />

( 入 力 ) DPSLDLT は 同 時 に 複 数 の 行 列 を 扱 うことができます。Token は、 行 列 の 選<br />

択 に 使 用 します。DPSLDLT_Factor()に 渡 される token は、 同 じ token で、 以 前 に<br />

DPSLDLT_Preprocess()で 呼 び 出 されていなければなりません。 同 様 に、<br />

DPSLDLT_Solve()に 渡 される token は、 以 前 に DPSLDLT_Factor()で 呼 び 出 されてい<br />

なければなりません。<br />

method ( 入 力 ) オーダリングの 選 択 を 行 なう 整 数 型 変 数 0 ≦ method ≦ 4<br />

n ( 入 力 ) 行 列 A の 行 と 列 の 数 。N ≧ 0<br />

pointers ( 入 力 ) pointers と indices 配 列 は、 疎 行 列 A の 非 ゼロ 要 素 の 構 造 をハーウェル ボー<br />

indices, イング(Compressed Column Storage の 名 前 でも 呼 ばれています) 形 式 で 格 納 しま<br />

values<br />

す。Pointers 配 列 は n+1 個 の 整 数 型 で、pointers[i]は 行 列 A の i 列 目 の 最 初 の 非 ゼ<br />

ロ 要 素 の 順 番 を 与 えます。Indices 配 列 は、A の 非 ゼロ 要 素 の 行 番 号 を 格 納 します。<br />

Values 配 列 は、 配 列 A の 非 ゼロ 要 素 の 値 を 格 納 します。<br />

non_zeros ( 出 力 ) 下 三 角 行 列 L の 非 ゼロ 要 素 の 個 数 。<br />

ops<br />

( 出 力 ) 行 列 A の 分 解 に 必 要 な 浮 動 小 数 点 演 算 回 数<br />

mask<br />

( 入 力 ) DPSLDLT_PreprocessZ()で 使 用 される 次 元 n の 整 数 型 配 列 。Mask(i)=0 であ<br />

れば、ピボッティングのゼロ 割 りを 避 けるようにオーダリングされる。<br />

b<br />

( 入 力 ) DPSLDLT_Solve の 呼 び 出 しの 右 辺 ベクトルを 格 納 する。<br />

x<br />

( 出 力 ) DPSLDLT_Solve の 呼 び 出 しの 解 ベクトルを 格 納 する。<br />

nrhs ( 入 力 ) DPSLDLT_SolveM()の 呼 び 出 しで、 解 くべき 右 辺 ベクトルの 組 数 。<br />

B<br />

( 入 力 ) DPSLDLT_SolveM()の 右 辺 行 列 。 列 方 向 優 先 の 格 納 形 式 で、 各 次 元 は n でな<br />

ければならない。<br />

X<br />

( 出 力 ) DPSLDLT_SolveM()の 呼 び 出 した 後 、 解 を 格 納 する 配 列 。 列 方 向 優 先 の 格 納<br />

形 式 で、 各 次 元 は n でなければならない。<br />

oocpath ( 入 力 ) 文 字 型 の 配 列 あるいは 変 数 。アウトオブコアの 行 列 分 解 ファイルを 格 納 する<br />

場 所 を 指 定 する。もし、ストライプ(RAID 0 など)されたファイルシステムが 指 定 されて<br />

いるのであれば、アウトオブコアのソルバの 性 能 が 向 上 します。デフォルトは<br />

/usr/tmp です。<br />

length<br />

( 入 力 ) oocpath の 文 字 列 の 文 字 数<br />

occlimit ( 入 力 ) 倍 精 度 型 変 数 。DPSLDLT_FactorOOC の 呼 び 出 しで 使 用 されるメモリ 量 を M<br />

バイト 単 位 で 指 定 する。 行 列 を 直 接 格 納 する 配 列 以 外 に 大 量 の 作 業 領 域 が 必 要 な<br />

ことに 注 意 してください。デフォルト 値 は 64M バイトです。<br />

perm<br />

( 出 力 ) n 次 元 の 整 数 型 配 列 。 行 列 A の 置 換 ベクトルを 格 納 する。<br />

ldb<br />

( 入 力 ) 行 列 B のリーディングディメンジョン。ldb ≧ n<br />

ldx<br />

( 入 力 ) 行 列 X のリーディングディメンジョン。ldx ≧ n<br />

80<br />

日 本 SGI 株 式 会 社


5.3.11. 環 境 変 数<br />

メソッド 3 とメソッド 4 のオーダリングに 影 響 する 環 境 変 数 は 2 つあります。SPARSE_NUM_ORDERS は、<br />

オーダリングの 評 価 を 行 なう 種 類 を、デフォルト 値 (メソッド 3 では OMP_NUM_THREADS、メソッド 4 では<br />

(2*OMP_NUM_THREADS))と 異 なる 数 に 設 定 する 場 合 に 使 用 します。SPARSE_FEEDBACK_FILE は、「 学<br />

習 」ファイルが 作 成 されるパスとファイル 名 を 指 定 します。デフォルトでは「 学 習 」ファイルは<br />

$HOME/.sparseFeedback に 作 成 されます。このファイルは 5K バイト 以 下 の 大 きさです。<br />

環 境 変 数 OMP_NUM_THREADS は、 行 列 の 分 解 を 行 なう 時 に 使 用 するプロセッサ 数 を 指 定 します。アウト<br />

オブコアのソルバは 並 列 化 に 対 応 していません。 環 境 変 数 PSLDLT_VERBOSE を 設 定 することにより、<br />

行 列 の 分 解 過 程 のさまざまな 情 報 を 出 力 します。<br />

5.4. DPSLDU、ZPSLDU ルーチン<br />

ここでは、 非 対 称 疎 行 列 直 接 解 法 DPSLDU、ZPSLDU ルーチンの 使 用 方 法 に 関 して 説 明 します。 以 下 で<br />

は 倍 精 度 実 数 版 を 例 に 説 明 しますが、 倍 精 度 複 素 数 版 も 基 本 的 には 同 じです。 倍 精 度 複 素 数 版 の 場 合<br />

には、 関 数 の 接 頭 文 字 D をZに、ops と ooclimit を 除 く 引 数 の DOUBLE PRECISION 型 を COMPLREX*16<br />

型 (C/C++では double 型 を scsl_zcomplex 型 )に、 各 々 読 み 替 えてください。<br />

なお、 環 境 変 数 に 関 しては DPSLDU、ZPSLDU ともに 共 通 です。<br />

DPSLDU ルーチンでは、 以 下 の 非 対 称 疎 行 列 に 対 する 並 列 化 対 応 直 接 法 ソルバを 提 供 します。これら<br />

のルーチンの 詳 細 については、 本 節 以 降 をご 参 照 ください。<br />

DPSLDU_Destroy, DPSLDU_ExtractPerm, PSLDDLT_Factor, DPSLDU_FactorOOC,<br />

DPSLDU_OOCLimit, DPSLDU_OOCPath, DPSLDU__Ordering, DPSLDU_Preprocess,<br />

DPSLDU_PreprocessZ, DPSLDU_Solve, DPSLDUT_SolveM, DPSLDU_Storage<br />

5.4.1. 関 数 一 覧<br />

以 下 に、 各 関 数 の 引 数 のデータ 型 を 示 します。 各 引 数 についての 説 明 は、 第 5.3.10 節 引 数 の 説 明 を<br />

ご 参 照 ください。<br />

5.4.1.1. FORTRAN<br />

SUBROUTINE DPSLDU_DESTROY (token)<br />

INTEGER<br />

token<br />

SUBROUTINE DPSLDU_EXTRACTPERM (token, perm)<br />

81<br />

日 本 SGI 株 式 会 社


INTEGER token<br />

perm(*)<br />

SUBROUTINE DPSLDU_FACTOR (token, n, pointers, indices, values)<br />

INTEGER<br />

token, n, pointers(*), indices(*)<br />

DOUBLE PRECISION values(*)<br />

SUBROUTINE DPSLDU_FACTOROOC (token, n, pointers, indices, values)<br />

INTEGER<br />

token, n, pointers(*), indices(*)<br />

DOUBLE PRECISION values(*)<br />

SUBROUTINE DPSLDU_OOCLIMIT (token, ooclimit)<br />

INTEGER<br />

token<br />

DOUBLE PRECISION ooclimit<br />

SUBROUTINE DPSLDU_OOCPATH (token, oocpath, length)<br />

INTEGER<br />

token, length<br />

CHARACTER<br />

oocpath(*)<br />

SUBROUTINE DPSLDU_ORDERING (token, method)<br />

INTEGER<br />

token, method<br />

SUBROUTINE DPSLDU_PREPROCESS (token, n, pointes, indices,non_zeros, ops)<br />

INTEGER<br />

token, n, pointers(*), indices(*)<br />

INTEGER*8<br />

non_zeros<br />

DOUBLE PRECISION ops<br />

SUBROUTINE DPSLDU_PREPROCESSZ (token, n, pointers, indices, mask,non_zeros, ops)<br />

INTEGER<br />

token, n, pointers(*), indices(*), mask(*)<br />

INTEGER*8<br />

non_zeros<br />

DOUBLE PRECISION ops<br />

SUBROUTINE DPSLDU_SOLVE (token, x, b)<br />

INTEGER<br />

token<br />

DOUBLE PRECISION x(*), b(*)<br />

SUBROUTINE DPSLDU_SOLVEM (token, X, ldx, B, ldb, nrhs)<br />

INTEGER<br />

token, ldx, ldb, nrhs<br />

DOUBLE PRECISION X(*), B(*)<br />

DOUBLE PRECISION FUNCTION DPSLDU_STORAGGE(token)<br />

INTEGER<br />

token<br />

82<br />

日 本 SGI 株 式 会 社


5.4.1.2. C/C++<br />

#include <br />

void DPSLDU_Destroy (int token );<br />

void DPSLDU_ExtractPerm (int token int perm[];<br />

void DPSLDU_Factor (int token, int n, int pointers[], intindices[], double values[] );<br />

void DPSLDU_FactorOOC (int token, int n, int pointers[], int indices[], double values[] );<br />

void DPSLDU_OOCLimit (int token, double ooclimit );<br />

void DPSLDU_OOCPath (int token, char oocpath );<br />

void DPSLDU_Ordering (int token, int method );<br />

void DPSLDU_Preprocess (int token, int n, int ponters[], int indices[], long long<br />

*non_zeros, double *ops );<br />

void DPSLDU_PreprocessZ (int token, int n, int pointers[], int indices[], int mask[], long<br />

long *non_zeros, double *ops );<br />

void DPSLDU_Solve (int token, double x[], doublle b[] );<br />

void DPSLDU_SolveM (int token, double X[], int ldx, double B[], int ldb, int nrhs);<br />

double DPSLDU_Storage (int token);<br />

5.4.2. 詳 細<br />

DPSLDU は、 疎 行 列 の 非 対 称 線 形 方 程 式 Ax=b を 解 きます。ここで、A は n×n の 非 対 称 行 列 、b は 次 元<br />

n の 右 辺 ベクトル、x は 次 元 n の 解 ベクトルです。<br />

DPSLDU は、 直 接 法 を 用 いています。A は 次 の 形 式 に 分 解 できます。<br />

A = L D U<br />

83<br />

日 本 SGI 株 式 会 社


ここで、L は 対 角 要 素 が 1 の 下 三 角 行 列 、D は 対 角 項 だけの 行 列 、U は 対 角 要 素 が 1 の 上 三 角 行 列 を<br />

示 しています。<br />

このルーチンは、 倍 精 度 版 だけが 用 意 されており、<strong>SCSL</strong> の 並 列 化 にも 対 応 しています。<br />

このルーチンではピボッティングを 行 わないことに 注 意 してください。<br />

DPSLDU ライブラリは、5 つのメインルーチンから 構 成 されています。<br />

• DPSLDU_Ordering() は、 行 列 の 前 処 理 段 階 で 使 われる 5 つのオーダリング 方 法 を 選 択 します。<br />

• DPSLDU_Preprocess() は、 行 列 A の 構 造 に 対 して 前 処 理 を 行 います。(L のフィルインを 減 少 させる<br />

オーダリングや、シンボル 分 解 など)<br />

• DPSLDU_Factor() は、 先 に 処 理 した 行 列 A を L と D と U に 分 解 します。<br />

• DPSLDU_Solve() は、 右 辺 b ベクトルに 対 する 解 ベクトル x を 求 めます。<br />

• DPSLDU_Destroy() は、 行 列 A の 分 解 に 使 用 したメモリ 領 域 を 開 放 します。(L, D,U の 他 に 前 処 理 段<br />

階 で 必 要 となるデータ 構 造 などを 含 みます。)<br />

非 ゼロ 要 素 の 位 置 は 同 じで 値 が 異 なる 行 列 、すなわち、 構 造 が 同 じ 行 列 であれば、<br />

DPSLDLT_Preprocess()は 一 度 だけ 呼 べばよく、それらの 行 列 を L と D に 分 解 するための<br />

DPSLDLT_Factor()は 複 数 回 呼 び 出 すことが 可 能 です。 同 様 に、 複 数 の 右 辺 を 解 くために、<br />

DPSLDU_Factor()を 1 回 呼 び 出 した 後 、DPSLDU_Solve()を 複 数 回 呼 び 出 すことも 可 能 です。また、 複 数<br />

の 右 辺 を 1 次 元 の 配 列 にすべて 格 納 して、DPSLDU_SolveM()を 呼 び 出 すことも 可 能 です。<br />

5.4.3. 疎 行 列 の 格 納 形 式<br />

疎 行 列 A は、DPSLDU に 対 して、ハーウェル ボーイング(Compressed Column Storage の 名 でも 呼 ばれ<br />

ています) 形 式 の 入 力 でなければなりません。<br />

対 象 とする 行 列 は、pointers, indices, values の 3 つ 配 列 から 構 成 されています。indices 配 列 は、 配 列 A<br />

の 非 ゼロ 要 素 の 行 番 号 を 格 納 しています。values 配 列 は、その 位 置 の 非 ゼロ 要 素 の 値 を 格 納 します。<br />

pointers 配 列 は、 配 列 A の 各 列 について 最 初 の 非 ゼロ 要 素 が 何 番 目 の 非 ゼロ 要 素 かを 格 納 した 配 列 で<br />

す。こうして、i 列 目 の 非 ゼロ 要 素 に 対 する 行 番 号 は、indices[pointers[i]]から indices[pointers[i+1]-1]に<br />

格 納 されています。それに 対 応 する 配 列 A の 非 ゼロ 要 素 の 値 は、 values[pointers[i]]から<br />

values[pointers[i+1]-1]に 格 納 されています。<br />

行 列 A に 対 して、 同 一 列 内 の 非 ゼロ 要 素 は、 行 番 号 が 大 きくなる 順 番 に 格 納 されていなければなりませ<br />

ん。<br />

84<br />

日 本 SGI 株 式 会 社


非 対 称 行 列 に 対 する 例 を 以 下 に 示 します。<br />

1.0 0.0 5.0 0.0<br />

0.0 3.0 0.0 8.0<br />

2.0 0.0 7.0 0.0<br />

0.0 4.0 0.0 9.0<br />

は、FORTRAN では 次 のように 記 述 されます。<br />

INTEGER pointers(5), indices(8), i<br />

DOUBLE PRECISION values(8)<br />

DATA (pointers(i), i = 1, 5) / 1, 3, 5, 7, 9 /<br />

DATA (indices(i), i = 1, 8) / 1, 3, 2, 4, 1, 3, 2, 4 /<br />

DATA (values(i), i = 1, 8) / 1.0, 2.0, 3.0, 4.0, 5.0, 7.0, 8.0, 9.0 /<br />

C の 様 に 0 から 始 まる 添 字 で 示 すと、pointers と indices の 配 列 は、 次 のようになります。<br />

int pointers[] = {0, 2, 4, 6, 8}<br />

int indices[] = {0, 2, 1, 3, 0, 2, 1, 3}<br />

double values[] = {1.0, 2.0, 3.0, 4.0, 5.0, 7.0, 8.0, 9.0}<br />

5.4.4. オーダリングの 方 法<br />

DPSLDU_Ordering(token, method) ルーチンは、 行 列 の 分 解 を 行 う 前 に 前 処 理 に 用 いるオーダリングの<br />

方 法 を 変 更 します。このルーチンは DPSLDU_Preprocess の 前 に 呼 び 出 さなければなりません。 現 在 、5<br />

種 類 の method の 指 定 ができます。<br />

• Method 0 は 前 処 理 のオーダリングを 行 わない。<br />

• Method 1 フィルインが 最 小 となるようなオーダリング<br />

• Method 2 シングルネスト 分 析 によるオーダリング(デフォルト)<br />

• Method 3 マルチプルネスト 分 析 によるオーダリング( 並 列 化 対 応 )<br />

• Method 4 マルチプルネスト 分 析 によるオーダリング( 並 列 化 対 応 )<br />

メソッド 4 では、 同 じ 行 列 構 造 に 対 しては 前 回 の 結 果 を 学 習 してもっとも 効 率 的 なオーダリングを 行<br />

ないます。メソッド 3 と 4 は 同 じマルチプルネスト 分 析 のアルゴリズムを 採 用 しています。<br />

85<br />

日 本 SGI 株 式 会 社


メソッド 2 はメソッド 1 に 比 較 して、 演 算 量 は 多 くなりますが、はるかに 良 いオーダリングを 行 ないます。メ<br />

ソッド 3 は、 特 にマルチプロセッサのシステムで 有 効 です。<br />

メソッド 3 は、OMP_NUM_THREADS(OpenMP で 使 用 するプロセッサ 数 を 指 定 する 環 境 変 数 )<br />

種 類 の 行 列 のオーダリングの 評 価 を 並 列 に 行 ない、 行 列 の 分 解 段 階 でもっとも 浮 動 小 数 点 演 算 が 減 る<br />

ようなオーダリングを 選 択 します。<br />

メソッド 4 は、 同 じ 非 ゼロ 要 素 構 造 の 行 列 に 対 して、 複 数 の 右 辺 に 対 する 解 を 求 める 場 合 にだけに 使 用<br />

します。メソッド 4 は、「 学 習 」ファイルに 最 大 200 個 分 の 行 列 の 構 造 と 前 回 の 履 歴 情 報 を 記 録 します。 次<br />

回 のメソッド 4 の 呼 び 出 しでは、 同 じ 非 ゼロ 構 造 の 行 列 に 対 して、2 * OMP_NUM_THREADS 種 類 のオー<br />

ダリングを 評 価 して、もっとも 浮 動 小 数 点 演 算 が 少 なくなるオーダリングを 選 択 します。こうして、オーダリ<br />

ングの 質 は 計 算 を 続 けるにしたがって 改 良 され 続 けます。<br />

メソッド 3 と 4 は、デフォルトの 行 列 の 前 処 理 よりも 計 算 時 間 を 要 します。しかし、 大 規 模 な 系 あるいは 分<br />

解 を 繰 り 返 すにしたがい、メソッド 2 に 対 してソルバ 全 体 で 大 幅 な 性 能 改 善 (1.1〜2 倍 程 度 )が 得 られま<br />

す。<br />

5.4.5. 置 換 ベクトル<br />

メソッド 0 を 選 択 しない 場 合 、DPSLDU は、 行 列 A に 対 して 行 列 の 分 解 を 行 なう 前 に 行 の 入 れ 替 えを 行 な<br />

います。その 結 果 、 一 般 的 に 行 の 入 れ 替 えを 終 えた 行 列 はオリジナルの 行 列 に 対 してフィルインが 減 少<br />

します。また、token の 対 応 した 行 の 入 れ 替 えを 行 なった 行 列 を DPSLDU_ExtractPerm(token, perm)を 呼<br />

び 出 すことで 得 ることができます。 置 換 ベクトルは、 大 きさ n の 1 次 元 の 配 列 1≦perm(i)≦n に 戻 ります。<br />

(C コードに 対 しては 0≦perm[i]


5.4.7. メモリの 使 用 量<br />

DPSLDU_Storage()は、 行 列 のデータ 構 造 に 応 じて 必 要 とされるメモリの 総 量 の 見 積 りを M バイト 単 位 で<br />

返 します。<br />

5.4.8. アウトオブコア 分 解<br />

分 解 に 必 要 な 2 種 類 のメモリ 管 理 方 法 のルーチンを 提 供 します。 DPSLDU_Factor()は、 分 解 に 必 要 なメ<br />

モリを 内 部 的 に 確 保 した 後 、DPSLDU_Destroy()が 呼 ばれるまで 確 保 し 続 けます。もう 一 つは、アウトオブ<br />

コア 分 解 のルーチンである DPSLDU_FactorOOC() です。このルーチンでは、メモリの 使 用 量 は 少 なくて<br />

済 みますが、 残 りの 必 要 な 領 域 をディスク 上 に 確 保 します。DPSLDU_OOCPath()は、 分 解 ファイルが 作<br />

成 されるディレクトリを 指 示 し、DPSLDU_OOCLimit()は、 行 列 の 分 解 に 必 要 とされるメモリ 領 域 の 上 限 を<br />

与 えます。より 多 くのメモリを 使 用 すれば、ディスク I/O は 減 少 して 行 列 分 解 部 分 の 性 能 が 向 上 します。<br />

インコア 分 解 からアウトオブコア 分 解 へは、DPSLDU_Factor()を DPSLDU_FactorOOC()に 変 更 するだけ<br />

です。 他 のルーチン(DPSLDU_Solve(), DPSLDU_Destroy()など)は、アウトオブコア 分 解 ルーチンと 互 換 性<br />

があるように 設 計 されています。DPSLDU_FactorOOC とそれに 続 く DPSLDU_Solve の 呼 び 出 しは 並 列 化<br />

されていないことに 注 意 してください。<br />

5.4.9. 複 数 の 右 辺 に 対 する 解<br />

DPSLDU は、DPSLDU_SolveM()を 1 回 呼 び 出 すことで、 複 数 の 右 辺 に 対 する 解 を 求 めます。<br />

DPSLDU_SolveM()は、これらの 右 辺 に 対 する 計 算 を 各 プロセッサで 並 列 に 行 ないます。<br />

5.4.10. 各 ルーチンの 引 数 の 説 明<br />

DPSLDU の 各 ルーチンは 以 下 の 引 数 をとります。<br />

引 数<br />

説 明<br />

token<br />

( 入 力 ) DPSLDU は 同 時 に 複 数 の 行 列 を 扱 うことができます。token は、 行 列 の 選 択<br />

に 使 用 します。DPSLDU_Factor()に 渡 される token は、 同 じ token で 以 前 に<br />

DPSLDU_Preprocess()で 呼 び 出 されていなければなりません。 同 様 に、<br />

DPSLDU_Solve()に 渡 される token は、 以 前 に DPSLDU_Factor()で 呼 び 出 されていな<br />

ければなりません。<br />

method ( 入 力 ) オーダリングの 選 択 を 行 なう 整 数 型 変 数 0 ≦ method ≦ 4<br />

n ( 入 力 ) 行 列 A の 行 と 列 の 数 。n ≧ 0<br />

pointers ( 入 力 ) pointers と indices 配 列 は、 疎 行 列 A の 非 ゼロ 要 素 の 構 造 をハーウェル ボー<br />

indices<br />

イング(Compressed Column Storage の 名 前 でも 呼 ばれています) 形 式 で 格 納 しま<br />

values<br />

す。pointers 配 列 は n+1 個 の 整 数 型 で、pointers[i]は 行 列 A の i 列 目 の 最 初 の 非 ゼ<br />

ロ 要 素 の 順 番 を 与 えます。indices 配 列 は、A の 非 ゼロ 要 素 の 行 番 号 を 格 納 します。<br />

values 配 列 は、 配 列 A の 非 ゼロ 要 素 の 値 を 格 納 します。<br />

87<br />

日 本 SGI 株 式 会 社


non_zeros ( 出 力 ) 非 ゼロ 要 素 の 個 数 。<br />

ops<br />

( 出 力 ) 行 列 A の 分 解 に 必 要 な 浮 動 小 数 点 演 算 回 数<br />

mask<br />

( 入 力 ) DPSLDU_PreprocessZ()で 使 用 される 次 元 n の 整 数 型 配 列 。mask(i)=0 であれ<br />

ば、ピボッティングのゼロ 割 りを 避 けるようにオーダリングされる。<br />

b<br />

( 入 力 ) DPSLDU_Solve の 呼 び 出 しの 右 辺 ベクトルを 格 納 する。<br />

x<br />

( 出 力 ) DPSLDU_Solve の 呼 び 出 しの 解 ベクトルを 格 納 する。<br />

nrhs ( 入 力 ) DPSLDU_SolveM()の 呼 び 出 しで、 解 くべき 右 辺 ベクトルの 組 数 。<br />

B<br />

( 入 力 ) DPSLDU_SolveM()の 右 辺 行 列 。 列 方 向 優 先 の 格 納 形 式 で、 各 次 元 は n でな<br />

ければならない。<br />

X<br />

( 出 力 ) DPSLDU_SolveM()の 呼 び 出 した 後 、 解 を 格 納 する 配 列 。 列 方 向 優 先 の 格 納<br />

形 式 で、 各 次 元 は n でなければならない。<br />

oocpath ( 入 力 ) 文 字 型 の 配 列 あるいは 変 数 。アウトオブコアの 行 列 分 解 ファイルを 格 納 する<br />

場 所 を 指 定 する。もし、ストライプ(RAID 0 など)されたファイルシステムが 指 定 されて<br />

いるのであれば、アウトオブコアのソルバの 性 能 が 向 上 します。デフォルトは<br />

/usr/tmp です。<br />

length<br />

( 入 力 ) oocpath の 文 字 列 の 文 字 数<br />

occlimit ( 入 力 ) 倍 精 度 型 変 数 。DPSLDU_FactorOOC の 呼 び 出 しで 使 用 されるメモリ 量 を M バ<br />

イト 単 位 で 指 定 する。 行 列 を 直 接 格 納 する 配 列 以 外 に 大 量 の 作 業 領 域 が 必 要 なこと<br />

に 注 意 してください。デフォルト 値 は 64M バイトです。<br />

perm<br />

( 出 力 ) n 次 元 の 整 数 型 配 列 。 行 列 A の 置 換 ベクトルを 格 納 する。<br />

ldb<br />

( 入 力 ) 行 列 B のリーディングディメンジョン。ldb ≧ n<br />

ldx<br />

( 入 力 ) 行 列 X のリーディングディメンジョン。ldx ≧ n<br />

5.4.11. 環 境 変 数<br />

メソッド 3 とメソッド 4 のオーダリングに 影 響 する 環 境 変 数 は 2 つあります。SPARSE_NUM_ORDERS は、<br />

オーダリングの 評 価 を 行 なう 種 類 を、デフォルト 値 (メソッド 3 では OMP_NUM_THREADS、メソッド 4 では<br />

(2*OMP_NUM_THREADS)) と 異 なる 数 に 設 定 する 場 合 に 使 用 します。SPARSE_FEEDBACK_FILE は、<br />

「 学 習 」ファイルが 作 成 されるパスとファイル 名 を 指 定 します。デフォルトでは「 学 習 」ファイルは<br />

$HOME/.sparseFeedback に 作 成 されます。このファイルは 5K バイト 以 下 の 大 きさです。<br />

環 境 変 数 OMP_NUM_THREADS は、 行 列 の 分 解 を 行 なう 時 に 使 用 するプロセッサ 数 を 指 定 します。アウト<br />

オブコアのソルバは 並 列 化 に 対 応 していません。 環 境 変 数 PSLDU_VERBOSE を 設 定 することにより、 行<br />

列 の 分 解 過 程 のさまざまな 情 報 を 出 力 します。<br />

5.5. DIterative ルーチン<br />

Diterative ルーチンでは、 以 下 の 疎 行 列 に 対 する 並 列 化 対 応 反 復 法 ソルバを 提 供 します。これらのルー<br />

チンの 詳 細 については、 本 節 以 降 をご 参 照 ください。<br />

88<br />

日 本 SGI 株 式 会 社


• DIterative<br />

• DIterative_DropTol<br />

• DIterative_DropStorage<br />

5.5.1. 関 数 一 覧<br />

Diterative の 各 ルーチンは 以 下 の 引 数 をとります。 引 数 の 詳 細 に 関 しては、 第 5.5.4 節 引 数 の 説 明 をご<br />

参 照 ください。<br />

5.5.1.1. FORTRAN<br />

SUBROUTINE DITERATIVE (n, pointers, indices, values, storage, x, b, method, precond,<br />

maxiters, convtol, iters, finalres)<br />

INTEGER<br />

n, storage, method, precond, maxiters, iters<br />

INTEGER<br />

pointers(*), indices(*)<br />

DOUBLE<br />

PRECISION values(*), x(*), b(*)<br />

DOUBLE PRECISION convtol, finalres<br />

SUBROUTINE DITERATIVE_DROPTOL (DropTolerance)<br />

DOUBLE PRECISION DropTolerance<br />

SUBROUTINE DITERATIVE_DROPSTORAGE (Storage_Multiplier)<br />

DOUBLE PRECISION Storage_Multiplier<br />

5.5.1.2. C/C++<br />

#include <br />

void DIterative (int n, int pointers[], int indices[], double values[], int storage, double x[], double b[], int<br />

method, int precond, int maxiters, double convtol, int *iters, double *finalres)<br />

void DIterative_DropTol (double drop_tolerance );<br />

void DIterative_DropStorage (double storage_multiplier );<br />

5.5.2. 詳 細<br />

Diterative ルーチンは、 疎 な 線 形 方 程 式 Ax=bを 解 くために 反 復 法 を 用 います。 解 法 は4つの 前 処 理 付<br />

89<br />

日 本 SGI 株 式 会 社


反 復 法 の 中 から 選 択 できます。 対 称 行 列 向 けには 共 役 勾 配 (CG) 法 、 共 役 残 差 法 、 非 対 称 行 列 向 けに<br />

は 共 役 勾 配 二 乗 (CGS) 法 およびその 変 種 で 収 束 過 程 がよりスムーズな 双 共 役 勾 配 安 定 (BiCGSTAB)<br />

法 が 利 用 できます。<br />

前 処 理 としては、ヤコビ、 対 称 逐 次 緩 和 (SSOR) 法 、no-fill ILU として 知 られる、パターンによる 不 完 全<br />

LU 分 解 、スレッシュホールド ILU として 知 られる、 値 による 不 完 全 LU 分 解 の4つの 方 法 が 利 用 できます。<br />

不 完 全 LU 分 解 による 前 処 理 は 対 称 行 列 にのみ 適 用 できます。 現 在 、 値 による 不 完 全 LU 分 解 の 並 列 化<br />

はされていません。<br />

値 による 不 完 全 LU 分 解 のパラメータの 設 定 のために 以 下 の2つのルーチンがあります。<br />

• DIterative_DropTol() は 不 完 全 LU 分 解 の drop tolerance を 設 定 します。<br />

• DIterative_DropStorage() は 不 完 全 LU 分 解 の 要 素 を 格 納 するメモリの 容 量 を 設 定 します。<br />

5.5.3. 疎 行 列 の 格 納 形 式<br />

疎 行 列 A は DIterative ルーチンに 対 して、 列 圧 縮 格 納 形 式 (ハーウェルボーイングの 名 でも 呼 ばれてい<br />

ます)、または 行 圧 縮 格 納 形 式 で 入 力 しなければなりません。<br />

5.5.3.1. 列 圧 縮 格 納 形 式<br />

対 象 とする 行 列 は、pointers, indices, values の 3 つ 配 列 から 構 成 されています。 列 圧 縮 格 納 形 式 では<br />

indices 配 列 は、 行 列 A の 非 ゼロ 要 素 の 行 番 号 を 格 納 しています。values 配 列 は、その 位 置 の 非 ゼロ 要<br />

素 の 値 を 格 納 します。pointers 配 列 は、 配 列 A の 各 列 について 最 初 の 非 ゼロ 要 素 が 何 番 目 の 非 ゼロ 要<br />

素 かを 格 納 した 配 列 です。こうして、i 列 目 の 非 ゼロ 要 素 に 対 する 行 番 号 は、indices[pointers[i]から<br />

indices[pointers[i+1]-1]に 格 納 されています。それに 対 応 する 行 列 A の 非 ゼロ 要 素 の 値 は、<br />

values[pointers[i]]から values[pointers[i+1]-1]に 格 納 されています。<br />

対 称 行 列 A に 対 しては、A の 下 三 角 あるいは 上 三 角 のどちらかを 与 えれば 良 く、 両 方 を 与 える 必 要 はあ<br />

りません。A の 同 じ 列 内 の 要 素 については 順 序 は 問 いません。<br />

対 称 行 列 に 対 する 例 を 以 下 に 示 します。<br />

1.0<br />

0.0 3.0<br />

2.0 0.0 5.0<br />

0.0 4.0 0.0 6.0<br />

90<br />

日 本 SGI 株 式 会 社


は、FORTRAN では 次 のように 記 述 されます。<br />

INTEGER pointers(5), indices(6), i<br />

DOUBLE PRECISION values(6)<br />

DATA (pointers(i), i = 1, 5) / 1, 3, 5, 6, 7 /<br />

DATA (indices(i), i = 1, 6) / 1, 3, 2, 4, 3, 4 /<br />

DATA (values(i), i = 1, 6) / 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 /<br />

C の 様 に 0 から 始 まる 添 字 で 示 すと、pointers と indices の 配 列 は、 次 のようになります。<br />

int pointers[] = {0, 2, 4, 5, 6}<br />

int indices[] = {0, 2, 1, 3, 2, 3}<br />

double values[] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}<br />

5.5.3.2. 行 圧 縮 格 納 形 式<br />

行 圧 縮 格 納 形 式 では、indices 配 列 は、 行 列 A の 非 ゼロ 要 素 の 列 番 号 を 格 納 しています。values 配 列 は、<br />

その 位 置 の 非 ゼロ 要 素 の 値 を 格 納 します。pointers 配 列 は、 行 列 A の 各 行 について 最 初 の 非 ゼロ 要 素<br />

の 場 所 を 格 納 した 配 列 です。こうして、i 行 目 の 非 ゼロ 要 素 に 対 する 列 番 号 は、indices[pointers[i]から<br />

indices[pointers[i+1]-1]に 格 納 されています。それに 対 応 する 列 A の 非 ゼロ 要 素 の 値 は、<br />

values[pointers[i]]から values[pointers[i+1]-1]に 格 納 されています。<br />

上 記 例 と 同 じ 対 称 行 列 に 対 する 例 を 示 します。<br />

1.0<br />

0.0 3.0<br />

2.0 0.0 5.0<br />

0.0 4.0 0.0 6.0<br />

行 圧 縮 格 納 形 式 を 用 いると、FORTRAN では 次 のように 記 述 されます。<br />

INTEGER pointers(5), indices(6), i<br />

DOUBLE PRECISION values(6)<br />

DATA (pointers(i), i = 1, 5) / 1, 2, 3, 5, 7 /<br />

DATA (indices(i), i = 1, 6) / 1, 2, 1, 3, 2, 4 /<br />

DATA (values(i), i = 1, 6) / 1.0, 3.0, 2.0, 5.0, 4.0, 6.0 /<br />

C 言 語 で 用 いられる、0からはじまるインデックスで 表 すと pointers と indeices 配 列 は 次 のようになりま<br />

91<br />

日 本 SGI 株 式 会 社


す。<br />

int pointers[] = {0, 1, 2, 4, 6}<br />

int indices[] = {0, 1, 0, 2, 1, 3}<br />

double values[] = {1.0, 3.0, 2.0, 5.0, 4.0, 6.0}<br />

5.5.4. 引 数<br />

DIterative ルーチンは 以 下 の 引 数 をとります。<br />

引 数<br />

n<br />

pointers<br />

indices<br />

values<br />

説 明<br />

( 入 力 ) 行 列 Aの 行 と 列 の 数 を 示 す 整 数 。 n>=0<br />

( 入 力 ) 配 列 pointers と indices は 疎 行 列 Aの 0 を 含 まない 構 造 を 行 圧 縮 格 納 形 式 、<br />

または 列 圧 縮 格 納 形 式 で 持 ちます。<br />

列 圧 縮 格 納 形 式 では、pointers 配 列 は n+1 個 の 整 数 を 持 ち、pointers[i]は 疎 行 列 A<br />

の i 行 目 の 非 零 要 素 の、 配 列 indices での 最 初 の 位 置 を 示 します。 配 列 indices は 行<br />

列 Aの 非 零 要 素 の 行 のインデックスを 持 ちます。values 配 列 は 行 列 Aの 非 零 要 素 の<br />

値 を 持 ちます。<br />

storage<br />

( 入 力 ) 行 列 データが 行 圧 縮 格 納 形 式 と 列 圧 縮 格 納 形 式 のどちらであるかを 示 しま<br />

す。storage=0 であれば、 列 圧 縮 格 納 形 式 とみなします。storage=1 であれば、 行 圧<br />

縮 格 納 形 式 とみなします。<br />

x<br />

( 入 力 / 出 力 )ベクトルxの 初 期 値 と 最 終 的 に 得 られた 解 になります。<br />

b<br />

( 入 力 ) 右 辺 ベクトルb<br />

method ( 入 力 ) 使 用 する 反 復 解 法 を 指 定 する 整 数 。<br />

method=0: 共 役 勾 配 (CG) 法<br />

method=1: 共 役 残 差 (CR) 法<br />

method=10: 共 役 勾 配 二 乗 (CGS) 法<br />

method=11: 双 共 役 勾 配 安 定 (BiCGSTAB) 法<br />

precond ( 入 力 ) 反 復 法 で 使 用 される 前 処 理 を 指 定 する 整 数 。0


成 分 の 値 と storage_multiplier との 積 の 値 よりも 多 くの 非 零 成 分 を 含 む 場 合 、<br />

drop_tolerance の 値 が 自 動 的 に 引 き 上 げられます。<br />

5.5.5. 環 境 変 数<br />

以 下 の 環 境 変 数 は 様 々なランタイム 時 の 動 作 特 性 を 制 御 します。<br />

• ITERATIVE_VERBOSE は 実 行 時 のステップ 毎 の 情 報 を 表 示 します。<br />

• ITERATIVE_DUMP は 行 列 を”ppcr.mat”ファイルへ 圧 縮 列 格 納 (ハーウェルボーイング) 形 式 で 表 示<br />

します。<br />

• ITERATIVE_RCM は 行 列 のオーダリングを 制 御 します。ディフォルトでは 行 列 へのオーダリングは 適<br />

用 されません。 設 定 されるべき 値 は 以 下 の 通 りです。<br />

0: 行 列 のオーダリングは 適 用 されません。(RCM に 何 も 設 定 しない 場 合 と 同 じです。)<br />

1: 末 端 ノードのみを 探 索 する、トリミングされた Cuthill-McKee リオーダリングが 適 用 されます。<br />

-1: 逆 Cuthill-McKee リオーダリングが 適 用 されます。<br />

環 境 変 数 OMP_NUM_THREADS は 反 復 法 を 行 うときに 使 用 するプロセッサ 数 を 指 定 します。 環 境 変 数<br />

ITREATIVE_VERBOSE をセットすると DITERATIVE ルーチンに 行 列 分 解 に 関 する 情 報 を 出 力 させること<br />

ができます。<br />

93<br />

日 本 SGI 株 式 会 社


5.6. サンプルプログラム<br />

以 下 に FORTRAN, C/C++における、スパースソルバーのサンプルプログラムを 示 します。<br />

5.6.1. 倍 精 度 実 対 称 疎 行 列 の 直 接 解 法 DPSLDLT<br />

問 題<br />

下 記 で 定 義 されるテスト 行 列 を 用 いて、 対 称 行 列 直 接 法 スパースソルバーの 実 行 例 を 示 します。 実 行 例<br />

では、 下 記 で 定 義 される 逆 行 列 ( 対 称 三 重 対 角 行 列 )の 逆 行 列 を 求 め、 元 の 行 列 になることを 確 かめま<br />

す。オーダリングは 入 れ 子 分 析 法 (デフォルト)を 用 います。<br />

サイズ N の 行 列 A=a[i][j] が 下 記 の 通 りに 定 義 されます。<br />

a[i][j]= a[j][i] = n+1-i, if i >= j.<br />

サイズ 4 の 場 合 の 行 列 は 下 記 の 通 りです。<br />

データの 格 納 方 法 については、 第 5.3.3 節 疎 行 列 の 格 納 形 式 をご 参 照 ください。 関 数 の 引 数 についての<br />

詳 細 は 第 5.3.10 節 の 各 ルーチンの 引 数 の 説 明 をご 参 照 ください。<br />

94<br />

日 本 SGI 株 式 会 社


プログラム 例<br />

FORTRAN<br />

C<br />

C<br />

C<br />

C<br />

implicit double precision (a-h,o-z)<br />

parameter (n=10)<br />

parameter (method=2)<br />

integer*8 non_zeros<br />

integer i,j,k,info<br />

integer iptr(n+1),idx(2*n)<br />

double precision val(2*n)<br />

double precision dtmp,ops<br />

double precision b(n,n),x(n,n)<br />

逆 行 列 の 初 期 化<br />

k=1<br />

do j=1,n<br />

iptr(j)=k<br />

do i=max(1,j-1),j<br />

if(i .eq. j) then<br />

if(i .eq. 1) then<br />

val(k)=1.d0<br />

else<br />

val(k)=2.d0<br />

end if<br />

else<br />

val(k)=-1.d0<br />

end if<br />

idx(k)=i<br />

k =k+1<br />

end do<br />

end do<br />

iptr(j)=k<br />

RHSを 単 位 行 列 に 初 期 化<br />

do j=1,n<br />

do i=1,n<br />

95<br />

日 本 SGI 株 式 会 社


C<br />

C<br />

C<br />

C<br />

x(i,j)=0.d0<br />

if(i .eq. j) then<br />

b(i,j)=1.d0<br />

else<br />

b(i,j)=0.d0<br />

end if<br />

end do<br />

end do<br />

L D L^T 分 解<br />

call DPSLDLT_Ordering(1,method)<br />

call DPSLDLT_Preprocess(1,n,iptr,idx,non_zeros,ops)<br />

call DPSLDLT_Factor(1,n,iptr,idx,val)<br />

call DPSLDLT_SolveM(1,x,b,n)<br />

call DPSLDLT_Destroy(1)<br />

逆 行 列 が 元 の 行 列 になることを 確 かめる<br />

dtmp=0.d0<br />

do j=1,n<br />

do i=1,n<br />

dtmp=dtmp+<br />

&<br />

(x(i,j)-(n+1.d0-max(i,j)))*(x(i,j)-(n+1.d0- max(i,j)))<br />

end do<br />

end do<br />

dtmp=dsqrt(dtmp)<br />

write(*,*) dtmp<br />

stop<br />

end<br />

C/C++<br />

#include <br />

#include <br />

#include <br />

#define N 10<br />

#define METHOD 2<br />

96<br />

日 本 SGI 株 式 会 社


#define MAX(i,j) (((i) > (j)) (i) : (j))<br />

int main(void)<br />

{<br />

long long non_zeros;<br />

int i,j,k,info;<br />

int iptr[N + 1], idx[2 * N];<br />

double val[2 * N];<br />

double dtmp, ops;<br />

double b[N * N], x[N * N];<br />

/* 逆 行 列 を 初 期 化 */<br />

k = 0;<br />

for(j = 0; j < N; j++){<br />

iptr[j] = k;<br />

for(i = MAX(0, j - 1); i


[j * N + i] = 0.0;<br />

}<br />

}<br />

}<br />

/* L D L^T 分 解 */<br />

DPSLDLT_Ordering(1,METHOD);<br />

DPSLDLT_Preprocess(1,N,iptr,idx,&non_zeros,&ops);<br />

DPSLDLT_Factor(1,N,iptr,idx,val);<br />

DPSLDLT_SolveM(1,x,b,N);<br />

DPSLDLT_Destroy(1);<br />

/* 逆 行 列 が 元 の 行 列 になることを 確 かめる */<br />

dtmp = 0.0;<br />

for(j = 0; j < N; j++){<br />

for(i = 0; i < N; i++){<br />

dtmp += (x[j * N + i] - (N - MAX(i, j))) *<br />

(x[j * N + i] - (N - MAX(i, j)));<br />

}<br />

}<br />

dtmp=sqrt(dtmp);<br />

printf("%g\n", dtmp);<br />

}<br />

return 0;<br />

5.6.2. 倍 精 度 実 疎 行 列 の 反 復 解 法 (ヤコビ 前 処 理 付 CG 法 )<br />

問 題<br />

反 復 法 スパースソルバで、 下 記 で 定 義 されるテスト 行 列 の 逆 行 列 を 係 数 行 列 とする 連 立 一 次 方 程 式 を<br />

解 き、 正 しい 解 と 比 較 します。 反 復 法 はヤコビ 前 処 理 付 CG 法 を 用 いる。 行 列 データは 列 圧 縮 格 納 形 式 と<br />

なります。<br />

データの 格 納 方 法 については、 第 5.5.3 節 疎 行 列 の 格 納 形 式 をご 参 照 ください。 関 数 の 引 数 についての<br />

詳 細 は 第 5.5.4 節 の 各 ルーチンの 引 数 の 説 明 をご 参 照 ください。<br />

98<br />

日 本 SGI 株 式 会 社


サイズ N の 行 列 A=a[i][j] が 下 記 の 通 りに 定 義 されます。<br />

a[i][j]= a[j][i] = n+1-i, if i >= j.<br />

サイズ 4 の 場 合 の 行 列 は 下 記 の 通 りです。<br />

プログラム 例<br />

FORTRAN<br />

C<br />

C<br />

C<br />

implicit double precision (a-h,o-z)<br />

parameter (n=10,maxiter=2*n)<br />

parameter (mstorage=0)<br />

parameter (imethod=0,iprecond=0)<br />

parameter (deps=1.d-12)<br />

integer i,j,k,iter<br />

integer iptr(n+1),idx(2*n)<br />

double precision val(2*n),b(n),x(n)<br />

double precision dtmp,res<br />

テスト 行 列 の 逆 行 列 の 初 期 化<br />

99<br />

日 本 SGI 株 式 会 社


C<br />

C<br />

C<br />

C<br />

C<br />

k=1<br />

do j=1,n<br />

iptr(j)=k<br />

do i=max(1,j-1),j<br />

if(i .eq. j) then<br />

if(i .eq. 1) then<br />

val(k)=1.d0<br />

else<br />

val(k)=2.d0<br />

end if<br />

else<br />

val(k)=-1.d0<br />

end if<br />

idx(k)=i<br />

k =k+1<br />

end do<br />

end do<br />

iptr(j)=k<br />

RHSの 初 期 化<br />

do i=1,n<br />

x(i)=0.d0<br />

b(i)=0.d0<br />

end do<br />

b(1)=1.d0<br />

ヤコビ 前 処 理 付 CG 法<br />

call diterative(n,iptr,idx,val,mstorage,x,b,<br />

& imethod,iprecond,maxiter,deps,iter,res)<br />

正 しい 解 が 得 られていることを 確 かめる<br />

dtmp=0.d0<br />

do i=1,n<br />

dtmp=dtmp+(x(i)-n+i-1)*(x(i)-n+i-1)<br />

end do<br />

dtmp=dsqrt(dtmp)<br />

write(*,*) dtmp<br />

100<br />

日 本 SGI 株 式 会 社


stop<br />

end<br />

C/C++<br />

#include <br />

#include <br />

#include <br />

#define N 10<br />

#define MAXITER (2 * N)<br />

#define MSTORAGE 0 /* CCS */<br />

#define IMETHOD 0 /* CG */<br />

#define IPRECOND 0 /* Jacobi */<br />

#define DEPS 1.e-12<br />

#define MAX(i, j) (((i) > (j)) (i) : (j))<br />

int main(void)<br />

{<br />

int i, j, k, iter;<br />

int iptr[N + 1], idx[2 * N];<br />

double val[2 * N], b[N], x[N];<br />

double dtmp, res;<br />

/* テスト 行 列 の 逆 行 列 の 初 期 化 */<br />

k = 0;<br />

for(j = 0; j < N; j++){<br />

iptr[j] = k;<br />

for(i = MAX(0, j - 1); i


idx[k] = i;<br />

k++;<br />

}<br />

}<br />

iptr[j] = k;<br />

/* RHSの 初 期 化 */<br />

for(i = 0; i < N; i++){<br />

x[i] = b[i] = 0.0;<br />

}<br />

b[0] = 1.0;<br />

/* ヤコビ 前 処 理 付 CG 法 */<br />

DIterative(N, iptr, idx, val, MSTORAGE, x, b,<br />

IMETHOD, IPRECOND, MAXITER, DEPS, &iter, &res);<br />

/* 正 しい 解 が 得 られていることを 確 かめる */<br />

dtmp = 0.0;<br />

for(i = 0; i < N; i++){<br />

dtmp += (x[i] - N + i) * (x[i] - N + i);<br />

}<br />

dtmp = sqrt(dtmp);<br />

printf("%g\n", dtmp);<br />

}<br />

return 0;<br />

102<br />

日 本 SGI 株 式 会 社


5.7. スパースソルバーの 性 能<br />

以 下 に、 対 称 疎 行 列 に 対 する 直 接 法 スパースソルバーDPSLDLT の 並 列 処 理 性 能 のグラフを 示 します。<br />

一 般 にスパースソルバーは、 密 行 列 に 対 するソルバーとは 異 なり、プロセッサの 性 能 を 引 き 出 すことが<br />

難 しいのですが、DPSLDLT では 理 論 ピーク 性 能 の 7 割 近 くの 性 能 が 得 られています。プロセッサ 数 の 増<br />

加 と 共 に、リニアに 近 い 性 能 向 上 がみられ、 良 好 なスケーラビリティであることがわかります。<br />

Seconds<br />

PSLDLT Sparse Solver -- 400 MHz<br />

Origin 3000<br />

1.75 million DOF, 41.8 million nonzeros<br />

400<br />

300<br />

200<br />

100<br />

0<br />

0 2 4 6 8 10<br />

Number of Processors<br />

5<br />

4<br />

3<br />

2<br />

1<br />

0<br />

Gflops<br />

Total Solution Time<br />

Factorization Speed<br />

103<br />

日 本 SGI 株 式 会 社


6. 乱 数 発 生 ルーチン<br />

<strong>SCSL</strong> では 64bit のスレッドセーフな 乱 数 発 生 ルーチン Drand64 を 提 供 します。このルーチンは <strong>SCSL</strong> の<br />

並 列 化 にも 対 応 しています。 詳 細 は Drand64(3S)のマニュアルページをご 参 照 ください。<br />

6.1. Drand64 ルーチン<br />

Drand64 ルーチンでは、 以 下 の 並 列 化 対 応 64bit 乱 数 発 生 ルーチンを 提 供 します。これらのルーチンの<br />

詳 細 については、 本 節 以 降 をご 参 照 ください。<br />

• srand64<br />

• drand64<br />

• drand64_advance<br />

• drand64_get<br />

• drand64_getv<br />

• drand64_maxthreads<br />

• drand64_set<br />

• drand64_setv<br />

• drand64_thread<br />

6.1.1. 関 数 一 覧<br />

以 下 に、 各 関 数 が 扱 うデータの 型 を 示 します。<br />

6.1.1.1. FORTRAN<br />

REAL FUNCTION SRAND64 (harvest)<br />

REAL<br />

harvest<br />

DOUBLE PRECISION FUNCTION DRAND64 (harvest)<br />

DOUBLE PRECISION harvest<br />

SUBROUTINE DRAND64_ADVANCE (count)<br />

INTEGER*8<br />

count<br />

SUBROUTINE DRAND64_GET (seed, count, thread)<br />

INTEGER*8<br />

seed, count<br />

104<br />

日 本 SGI 株 式 会 社


INTEGER<br />

thread<br />

SUBROUTINE DRAND64_GETV (state, count)<br />

INTEGER*8<br />

state(*), count(*)<br />

INTEGER FUNCTION DRAND64_MAXTHREADS ()<br />

SUBROUTINE DRAND64_SET (seed)<br />

INTEGER*8<br />

seed<br />

SUBROUTINE DRAND64_SETV (state, count)<br />

INTEGER*8 state(*) count(*)<br />

INTEGER FUNCTION DRAND64_THREAD (thread)<br />

INTEGER<br />

thread<br />

6.1.1.2. C/C++<br />

#include <br />

float srand64 (float *harvest);<br />

double drand64 (double *harvest);<br />

void drand64_advance (long long count);<br />

void drand64_get (long long *seed, long long *count, int thread);<br />

void drand64_getv (long long state[], long long count[]);<br />

int drand64_maxthreads (void);<br />

void drand64_set (long long seed);<br />

void drand64_setv (long long state[], long long count[]);<br />

int drand64_thread (int thread);<br />

105<br />

日 本 SGI 株 式 会 社


6.1.2. 詳 細<br />

これらのルーチンは、 以 下 の 式 で 示 される 線 形 合 同 法 を 基 にした 64bit のスレッドセーフな 並 列 化 乱 数 ジ<br />

ェネレータです。<br />

Y(n+1)=(a X(n) + c) mod 2^64<br />

パラメータ a, c は Knuth, The Art of Computer Programming, Vol. 2, Addison Wesley 1981, page 102. か<br />

ら<br />

a = 6364136223846793005<br />

c = 1<br />

を 用 いています。<br />

乱 数 の 生 成 をスレッド 間 で 分 割 することによって 安 全 性 を 保 ちます。 そのため、 各 スレッドであらかじめ<br />

設 定 した 値 からスタートする、 それぞれ 独 立 した 乱 数 を 生 成 します。 最 大 で drand_64_maxthreads()ルー<br />

チンの 返 す 値 までの 乱 数 生 成 の 並 列 処 理 がサポートされます。<br />

関 数<br />

srand64<br />

drand64<br />

drand64_advance<br />

drand64_get<br />

drand64_getv<br />

drand64_maxthreads<br />

drand64_set<br />

drand64_setv<br />

drand64_thread()<br />

詳 細<br />

この 関 数 は 区 間 [0,1)の 範 囲 の 単 精 度 の 乱 数 を 返 します。 引 数 が 与 えられれ<br />

ば、 引 数 にも 同 じ 値 を<br />

返 します。<br />

この 関 数 は 区 間 [0,1)の 範 囲 の 倍 精 度 の 乱 数 を 返 します。 引 数 が 与 えられれ<br />

ば、 引 数 にも 同 じ 値 を<br />

返 します。<br />

srand64()あるいは drand64()が count 回 呼 ばれたかのように 呼 び 出 し 元 のス<br />

レッドの 内 部 状 態<br />

のテーブルを 変 化 させます。<br />

3 番 目 の 引 数 のスレッドごとの invocation count と 同 様 に drand64 と srand64<br />

のスタートポイントを 得 ます。<br />

drand64 と srand64 の 内 部 状 態 を 得 ます。 引 数 は rand64_setv の 引 数 に 与 え<br />

られる seed と invocation counts の 配 列 です。 これらのテーブルは 最 低 で<br />

drand64_maxthreads()の 返 す 値 の 数 だけのエントリーが 必 要 です。<br />

この 関 数 は 乱 数 を 並 列 に 生 成 することのできるストリームの 最 大 数 を 返 しま<br />

す。drand64_getv(), drand64_setv() 関 数 で 用 いられる 内 部 状 態 テーブルはこの<br />

関 数 の 返 す 値 の 数 だけのエントリーを 持 ちます。<br />

drand64()と srand64()のスタートポイントをセットします。 デフォルトで-1です。<br />

drand64 と srand64 の 内 部 状 態 をセットします。 引 数 は、drand64_getv で 返 され<br />

た seed と<br />

invocation counts の 配 列 です。これらのテーブルは 最 低 で<br />

drand64_maxthreads()の 返 す 値 の 数 だけのエントリーが 必 要 です。<br />

この 関 数 を 呼 んだ 直 後 から、srand64(), drand64() 関 数 は、drand64_thread()の<br />

引 数 で 与 えた 数 で 識 別 されるスレッドから 呼 ばれたかの 如 く 動 作 します。<br />

106<br />

日 本 SGI 株 式 会 社


この 関 数 はそれまでに 乱 数 列 を 生 成 していたスレッドの 識 別 番 号 を 返 します。<br />

6.1.3. 使 用 例<br />

以 下 に、drand64()の 使 用 例 を 示 します。<br />

6.1.4. 例 1<br />

問 題<br />

単 一 のシードによって 乱 数 を 初 期 化 し、 各 スレッドから 乱 数 を 並 列 に 生 成 します。<br />

プログラム 例<br />

Fortran 77<br />

EXTERNAL SRAND64<br />

REAL SRAND64<br />

INTEGER*8 SEED<br />

REAL S1, DUMMY<br />

SEED = 1<br />

CALL DRAND64_SET(SEED)<br />

C Each thread gets a different random number<br />

C$OMP PARALLEL PRIVATE(S1, DUMMY)<br />

S1 = SRAND64(DUMMY)<br />

C$OMP END PARALLEL<br />

C/C++<br />

#include <br />

float s1, dummy;<br />

long long seed = 1LL;<br />

drand64_set(seed);<br />

/* Each thread gets a different random number */<br />

#pragma omp parallel private(s1, dummy)<br />

{<br />

s1 = srand64(&dummy);<br />

107<br />

日 本 SGI 株 式 会 社


}<br />

6.1.5. 例 2<br />

問 題<br />

乱 数 生 成 の 内 部 状 態 テーブルをセーブ 後 、 各 スレッドで11 個 の 乱 数 を 生 成 します。そして、 内 部 状 態 テ<br />

ーブルを 元 にもどし、drand_advance() 関 数 で 10 個 の 乱 数 の 生 成 をスキップします。そして、 次 に 生 成 され<br />

る 乱 数 が、 先 ほど 生 成 した 11 番 目 の 乱 数 と 同 じになります。<br />

プログラム 例<br />

Fortran 90<br />

INTEGER(KIND=8), DIMENSION(:), ALLOCATABLE :: STATE, COUNT<br />

EXTERNAL DRAND64_MAXTHREADS, OMP_GET_THREAD_NUM<br />

EXTERNAL DRAND64<br />

INTEGER :: I, TABLE_SIZE, DRAND64_MAXTHREADS<br />

INTEGER :: OMP_GET_THREAD_NUM<br />

REAL(KIND=8) :: D1, DUMMY, DRAND64<br />

TABLE_SIZE = DRAND64_MAXTHREADS()<br />

ALLOCATE(STATE(TABLE_SIZE))<br />

ALLOCATE(COUNT(TABLE_SIZE))<br />

CALL DRAND64_GETV(STATE, COUNT)<br />

!$OMP PARALLEL PRIVATE(I, D1, DUMMY)<br />

DO I = 1, 11<br />

D1 = DRAND64(DUMMY)<br />

END DO<br />

PRINT *, OMP_GET_THREAD_NUM(), D1<br />

!$OMP END PARALLEL<br />

CALL DRAND64_SETV(STATE, COUNT)<br />

!$OMP PARALLEL PRIVATE(D1, DUMMY)<br />

DRAND64_ADVANCE(10_8)<br />

D1 = DRAND64(DUMMY)<br />

PRINT *, OMP_GET_THREAD_NUM(), D1<br />

!$OMP END PARALLEL<br />

108<br />

日 本 SGI 株 式 会 社


C/C++<br />

#include <br />

#include <br />

#include <br />

#include <br />

ong long *state, *count;<br />

int i, table_size;<br />

double d1, dummy;<br />

table_size = drand64_maxthreads();<br />

state = (long long *) malloc(table_size * sizeof(long long));<br />

count = (long long *) malloc(table_size * sizeof(long long));<br />

drand64_getv(state, count);<br />

#pragma omp parallel private(i, d1, dummy)<br />

{<br />

for (i = 0; i < 11; i++)<br />

d1 = drand64(&dummy);<br />

printf("%d, %g0, omp_get_thread_num(), d1);<br />

}<br />

drand64_setv(state, count);<br />

#pragma omp parallel private(d1, dummy)<br />

{<br />

drand64_advance(10LL);<br />

d1 = drand64(&dummy);<br />

printf("%d, %g0, omp_get_thread_num(), d1);<br />

}<br />

6.1.6. 例 3<br />

単 一 のスレッドのみを 用 い、11 本 の 独 立 な 乱 数 のストリームを 生 成 します。<br />

Fortran 77<br />

EXTERNAL DRAND64_THREAD, SRAND64<br />

INTEGER DRAND64_THREAD<br />

REAL SRAND64<br />

INTEGER I, J, OLDID<br />

REAL STREAM(1000,10), DUMMY<br />

109<br />

日 本 SGI 株 式 会 社


DO J = 1, 10<br />

OLDID = DRAND64_THREAD(J-1)<br />

DO I = 1, 1000<br />

STREAM(I, J) = SRAND64(DUMMY)<br />

END DO<br />

END DO<br />

C RESTORE ORIGINAL BASE THREAD<br />

OLDID = DRAND64_THREAD(0)<br />

C/C++<br />

#include <br />

int i, j, oldid;<br />

float stream[10][1000], dummy;<br />

for (i = 0; i < 10; i++) {<br />

oldid = drand64_thread(i);<br />

for (j = 0; j < 1000; j++)<br />

stream[i][j] = srand64(&dummy);<br />

}<br />

/* restore original base thread */<br />

oldid = drand64_thread(0);<br />

6.1.7. 注 意<br />

drand64_thread() 関 数 が 並 列 処 理 を 行 う 領 域 で 使 用 される 場 合 には、 注 意 が 必 要 です。もし、 複 数 のスレ<br />

ッドが drand64_thread() 関 数 で 設 定 される 同 じスレッド 識 別 番 号 を 設 定 してしまうと、スレッドの 安 全 性 は<br />

失 われてしまい、 異 なるスレッドが 独 立 した 乱 数 列 を 生 成 することが 保 証 されません。 個 々のスレッド 上<br />

の 乱 数 列 における 統 計 的 な 乱 数 性 も 失 われることがあります。<br />

110<br />

日 本 SGI 株 式 会 社

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!