(公開用)
T2C_
1
本日の流れ
1. 実行環境
2. METIS導入
3. METISの使用テスト1,2
4. 分割後の可視化
5. nd24kを用いた本番
6. 並列化
7. FX10上での実行
8. まとめ、課題
2
実行環境
OS:Windows 7 Professional 64-bit Service Pack 1
CPU:Intel(R) Core(TM) i7-2600 CPU
@ 3.40GHz (8 CPUs), ~3.7GHz
メモリ:8192MB RAM
実行環境:Cygwin、FX10(性能は後述)
3
環境導入 リベンジ
4
前回まで
make デキナイ!!
5
今回
6
Cygwin導入時に使用したsetup-x86_64.exeを用いてパッケージの追加
「make」や「metis」で検索して出てくる使いそうな物は全てぶちこむ
パッケージを追加→done
• 関係ありそうなものを片っ端から入れたので
どれを入れたかは記憶無し。10分くらい。
7
METISを利用したリオーダリング
8
テスト&概要
9












65000
00400
00032
01000
という簡単な行列を3分割する。
col = {3,0,1,2,3,4}
index= {0,1,3,4,6} である。
コード
#include <stdio.h>
#include <stdlib.h>
#include <metis.h>
void main()
{
int nz = 6,i;
int col2[100] = {3,0,1,2,3,4};
int index2[100] = {0,1,3,4,6};
int val[100] = {1,2,3,4,5,6};
double objval2[100] ={0};
int part2[100] ={0};
idx_t *nvtxs, *ncon, *col, *index,*nparts, *objval, *part;
nvtxs = (int *) malloc(1000 * sizeof(int));
ncon = (int *) malloc(1000 * sizeof(int)) 確保すべき
col = (int *) malloc(1000 * sizeof(int)); 領域??
index = (int *) malloc(1000 * sizeof(int));
nparts = (int *) malloc(1000 * sizeof(int));
objval = (int *) malloc(1000 * sizeof(int));
part = (int *) malloc(1000 * sizeof(int));
*nvtxs = (int)nz; → M??
*ncon = (int)1;
*col = *col2;
*index = *index2;
*nparts = (int)3;
10
printf("HelloMetis!n");
METIS_PartGraphKway(nvtxs,ncon,col,index,NULL,NULL,NULL,nparts
,NULL,NULL,NULL,objval,part);
for(i=0;i<nz;i++)
{
printf("part[%d]=%dn",i,part[i]);
}
printf("objval= %d n",objval);
free(nvtxs);
free(ncon);
free(col);
free(index);
free(nparts);
free(objval);
free(part);
}
結果
見事に分割、しかしobjval…?
11












65000
00400
00032
01000
テスト2&概要
MM形式の.mtxファイル
(今回は494_bus.mtxを使用)
をCRSに変換
→metis.hを使って分割
12
Size Type
494 x 494, 1080 entries
real symmetric indefinite symmetric
positive definite
コード
read_example.cに先程のコードを追加。
▫ idx_t *nvtxs, *ncon, *col2, *index2, *nparts,
*objval, *part;
▫ *nvtxs = (int)nz;
▫ *ncon = (int)1;
▫ *col2 = *col;
▫ *index2 = *index;
▫ *nparts = (int)20;
13
結果
出来てる(20分割)。
どんな風に分割されたか
確認したいので可視化を
目指す。
14
可視化
目的:行・列・分割された番号を用いて
色付けするなどしてどの様に分割されたか
を確認する。(最初は自分で見易くするため改行)
以下を追加。
15
//for 494_bus.mtx
printf("0n");
for(i=0,j=0;i<=nz;i++)
{
if(col[i] > col[i+1])
{
printf("n");
j++;
}
printf("%dn",j);
}
printf("nn --------- above:line number below:col -------- nn");
for(i=0;i<nz;i++)
{
printf("%dn",col[i]);
if(col[i] > col[i+1])
{
printf("n");
}
}
printf("nn --------- above:col below:part --------
nn");
for(i=0;i<nz;i++)
{
printf("%dn",part[i]);
if(col[i] > col[i+1])
{
printf("n");
}
}
可視化2
$ ./a.exe 494_bus.mtx >result.txt
で関数にmtxファイルを渡し、リダイレクトで
result.txtに出力する。(勝手に作ってくれる)
16
出力結果
メモ帳→nで改行されない サクラエディタ→٩(๑❛ᴗ❛๑)۶
17
しかし…
行番号が307までしか割り振られない(本来497)
→全て非0の行はスキップ?→indexも使わねば
→時間の都合上、一時断念
18
本番&概要(目標)
• Matrix MarketよりMM形式の行列ファイル
であるnd24kをDL
• nd24kの分割
• 時間の計測(&理論時間の算出)
• 並列化
• その他高速化
19
nd24k
• COOL
 Matrix properties
 number of rows 72,000
 number of columns 72,000
 nonzeros 28,715,634
 structure symmetric
20
追加したコード
• #include <omp.h>
• double time1=0,time2=0;
• time1,2 = omp_get_wtime();
• printf("time = %lfnn",(time2-time1));
• $ gcc newread.c mmio.c -lm -lmetis -fopenmp
• 図は494_busでテストしたもの
21
実行
• 長い。
• 図は実行中の
タスクマネージャ
• CPU13%
• メモリ267MB 使用
22
結果
• 無事分割(20分割)
• グラフ分割に時間を
割いている訳ではない
• リオーダリング無しで
総時間約40分
• 235MB
23
理論時間
• FLOPS 理論値 =
( クロック ) × ( コア数 ) × 大体一致。
(コア・クロックあたりの浮動小数点演算回数)
=(3.40 * 10^9) * (4) * (8) = 110.8 * 10^9 FLOPS
=110.8GFLOPS
∴nz(= 28,715,634) / 110.8G ≒ 260000 * 10^-9
= 0.00026sec / nz1周の処理
∴readtime = 0.00026sec
sorttime = (nz * M)回 = nz1 * 72,000 = 18.72sec
metistime = (nz * objval?)回 = 取り忘れ
alltime = SUM(read,sort,metis) = ?
24
比較
理論値 実際
Read 0.00026sec 9.138236 sec
Sort 18.72sec 2479.721206 sec
Metis ? 20.328463 sec
all ? 2515.525911 sec
25
顕著なズレ(ハードを扱いきれていない?)
リオーダリング?
• 色々試行錯誤したものの出来ず
• 多分認識が違う
• 自分の認識ではordering[i][j] = kで
分割番号i、そこに入る順のj、kが通し番号
→Cで二次元配列(仮)を作ろうとすると
・ordering[分割数][nz/非ゼロ数]で
大き過ぎて作れない
・**ordering , *ordering でコンパイルは通るが
実行時即時に落とされる(原因わからず)
26
メモリの確保方法もわからず
仮にポインタのポインタが実装出来たとして
ordering =
(int **)malloc(DIVNUM * sizeof(int));
for(i=0; i<DIVNUM; i++)
{
ordering[i] =
(int *)malloc( (nz/DIVNUM)*3 *sizeof(int) );
}
だろうか?
27
並列化(読み込み部)
for (i=0; i<nz; i++)
{
fscanf(f, "%d %d %lgn", &I[i], &J[i], &val[i]);
I[i]--;
J[i]--;
}
28
#pragma omp parallel for private(i)
for (i=0; i<nz; i++)
{
fscanf(f, "%d %d %lgn", &I[i], &J[i], &val[i]);
I[i]--;
J[i]--;
}
(結局ソートするので同じ所の情報が取り出せれば
順番はどうでも良い(?))
並列化(ソート部)
index[0]=0;
for(i=1; i<=M; i++)
{
for(j=0; j<nz; j++)
{
if(I[j]==i)
{
//ソート部
val2[count] = val[j];
col[count] = J[j];
count++;
}
}
//index作成部
index[i] = count;
}
29
countの数に依存するので
別の設計が必要
(先週参照)
並列化(出力部)
for(i=0;i<nz;i++)
{
printf("part[%d]=%dn",i,part[i]);
}
不可。
30
FX10でも実行
• FX10
31
項目
仕様
Oakleaf-FX Oakbridge-FX
システ
ム全体
(計算
ノード)
総理論演算性能 1.135 PFlops 136.2 TFlops
総主記憶容量 150 TByte 18 TByte
総ノード数 4,800 576
インターコネク
ト
6 次元メッシュ /
トーラス
6 次元メッシュ /
トーラス
ローカルファイ
ルシステム
1.1 PByte 147 TByte
共有ファイルシ
ステム
2.1 PByte 295 TByte
FX10上でのMETISの導入
• module load METIS をする
• $ fccpx ~~でコンパイル
(並列の場合は –Kopenmpも付加する)
• (ドキュメント閲覧時表示の遵守事項)
核兵器又は生物化学兵器及びこれらを
運搬するためのミサイル等の大量破壊兵器の
開発、設計、製造、保管及び使用等の目的に
利用しない ←すごい
Oakleaf-FX利用手引書(ログイン後表示)
32
結果
33
まとめ
• METISの導入成功
• グラフ分割の成功
• MM→CSR→分割の成功
• 時間計測の成功
• (正誤はともかく)理論値の算出
• 可視化の失敗
• リオーダリングの不理解
34
課題
• リファクタリング(関数化など)や
そもそもの設計
• レベル的におそらく可能なので可視化
• バージョン管理
• 理論値の算出(並列化後・ FX10上のものも)
• orderingの宣言、初期化領域(メモリ確保数)
• FX10上での実行、
• 時間の確保
35
ありがとうございました
36

Spmv9forpublic