1 名前:デフォルトの名無しさん [04/11/07 18:25:56.net] MPIによる並列プログラミングについて話し合う統合スレッドです。 とりあえず本家 www-unix.mcs.anl.gov/mpi/
321 名前:デフォルトの名無しさん mailto:sage [2009/03/22(日) 05:57:00 .net] >>318 Windows SDK for Windows Server 2008 and .NET Framework 3.5 を一緒に入れると使えます。 参考:tech.ckme.co.jp/vc.shtml
322 名前:デフォルトの名無しさん [2009/04/02(木) 20:54:42 .net] 初めまして、MPIを勉強中の者で、使用言語はGFORTRANを使っています。 メイン又はサブにMPI_INIT〜MPI_FINALIZE及び計算式を一括して含む場合は 問題なくプログラムは動きますが、メインにMPI_INIT〜MPI_SIZEを サブにMPI_SEND、MPI_RECV、MPI_BCAST等と計算式を分離した場合、 リンクはできますが、実行時OSがエラーを発行し動きません。 そこで’MPI_COMM_WORLD’をメインでラベルつきCOMMONで確保し サブに渡すと、OSからのエラーメッセージはなく実行は出来ますが、 今度は’MPI_COMM_WORLD’からINVARID DATA TYPEが発行され、 値が上手く通信できません。ご指導願います。
323 名前:デフォルトの名無しさん mailto:sage [2009/04/03(金) 03:39:48 .net] 質問です。1〜300の分子のうち今、rank0が分子を1~100個目、rank1が101~205個目、 rank2が205~300個目の速度の計算を受け持ったとします。で、計算が終わった後、 自分が受け持った分の分子の速度をそれぞれ別の全てのプロセスに渡したいとします。 ちなみにそれぞれのプロセスが受け持つ個数も総数も計算中に変動するので、 それぞれのプロセスの最初の分子の番号をista_mol、もってる個数をnum_mol n個目の分子の速度をvel_mol(n)として、 do n=1,3 CALL MPI_BCAST(vel_mol(ista_mol),num_mol,MPI_REAL8,n,MPI_COMM_WORLD,IERR) end do とやらかすと、それぞれのプロセスが持っているista_mol,num_molの値が違うので絵 受信側と送信側のアドレスと要素数がずれて困ったことになりますね。 この場合、ista_mol(n),num_mol(n)とでもしてそれぞれ別の値として持たせて、 (ista_mol(1)にrank0の値を、ista_mol(2)にrank1の値を…) do n=1,3 CALL MPI_BCAST(vel_mol(ista_mol(n)),num_mol(n),MPI_REAL8,n,MPI_COMM_WORLD,IERR) end do とでもしないとダメなんでしょうか?どう考えてももっとスマートなやりかたが ありそうなんですがどうなんでしょうか?どなたか教えていただけませんか?
324 名前:デフォルトの名無しさん mailto:sage [2009/04/03(金) 12:07:03 .net] >>321 MPI_ALLGATHERV
325 名前:デフォルトの名無しさん mailto:sage [2009/04/05(日) 04:03:40 .net] お答え頂き有難うございます。ただ、ほとんど基本的なサブルーチンしか使ってないので MPI_ALLGATHERVはよくわからないんですが、今見た感じだと受信バッファ内の 位置は指定しないといけないんですよね?とすると結局他のプロセスが持っている個数に 関してはこの通信の前に教えてやる必要があるということになるでしょうか?
326 名前:デフォルトの名無しさん mailto:sage [2009/04/05(日) 08:34:21 .net] >>323 そうです。
327 名前:デフォルトの名無しさん mailto:sage [2009/04/05(日) 15:13:03 .net] なるほど、大体分かりました。mpi_allgathervを使う場合、 num_molを個別に持たせる必要がある以外はほぼ上の形で書けそうですね。 mpi_allgathervなら送信バッファと受信バッファ個別に指定できるので 送信の開始アドレスをずらして指定して大丈夫なんですよね? それと別の質問なんですが、mpich2をマルチコアcpu一個のマシンでで使う場合って mpiconfigでホストのところに動かすマシンを追加するほかは特に設定いらないでしょうか? あとは -np 4 をつけて実行するだけ?なんか単純な問題でも妙に遅いんですが… キャッシュとかはCPU側で勝手に最適化して使ってくれてるんですかね?
328 名前:デフォルトの名無しさん mailto:sage [2009/04/06(月) 02:44:25 .net] コード例を示したほうが良さげですね。こういう具合です。 int num_mol; // 各プロセスが持つ分子の数 double vel_mol[...]; // 分子の速度の配列。要素数は num_mol int recvbuf_num_mol[NUM_PROCS]; int displs_vel_mol[NUM_PROCS]; double recvbuf_vel_mol[TOTAL_NUM_MOL]; // 1. まず各プロセスが自分の num_mol を他のプロセスに送る // recvbuf_num_mol[i] にはランク i の num_mol が入る MPI_Allgather(&num_mol, 1, MPI_INT, recvbuf_num_mol, 1, MPI_INT, MPI_COMM_WORLD); // 2. recvbuf_num_mol から ALLGATHERV に必要な displs_vel_mol を作る count = 0; for (i = 0; i < NUM_PROCS; i++) { displs_vel_mol[i] = count; count = count + recv_num_mol[i]; } // 3. 上記 1. で得た recvbuf_num_mol と 2. で得た displs_vel_mol を使って // 各プロセスが自分の vel_mol (サイズ不定の配列) を他のプロセスに送る MPI_Allgatherv (vel_mol, num_mol, MPI_DOUBLE, recvbuf_vel_mol, recvbuf_num_mol, displs_vel_mol, MPI_DOUBLE, MPI_COMM_WORLD); マルチコアマシン1台で並列実行する場合は -machinefile オプションに与えるファイルに localhost:4 のように記述するか -machinefile オプションを使わずに mpirun -localonly 4 のように実行すると 良いような気がします。
329 名前:デフォルトの名無しさん mailto:sage [2009/04/08(水) 01:08:39 .net] あるある
330 名前:デフォルトの名無しさん [2009/06/03(水) 17:15:01 .net] PVMからMPIに鞍替えしようと思って勉強を始めようと思うのだが 今だとOpenMPIとMPICH2のどちらを勉強すればいいのだろう Mac OS X LeopardにはOpenMPIがもれなくついてくるらしいのだが MPICH2とどう特徴が異なるのかを見極めて判断したいのですが・・・
331 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 23:59:12 .net] >>328 MPIの実装に依存するようなプログラムでも作る気かい?
332 名前:お願いします [2009/06/18(木) 20:47:03 .net] MPIでどうしてもわかりません。 f(x)=x*xの0~1の積分なんですが、答えが通常0.3333となるはずですが なぜ以下のプログラムだと違った答えがでるのでしょうか? すみません、どなたか教えていただけないでしょうか? ちなみにプログラムはよくあるMPI(倍風館)の本のものです。 実行すると0.000488のような値がでてきます。困っています。 どうやれば0.3333みたいな値を得ることができるでしょうか?
333 名前:お願いします [2009/06/18(木) 20:53:12 .net] #include <stdio.h> #include <mpi.h> main(int argc, char** argv) { int my_rank; /* カレントプロセスのランク */ int p; /* プロセスの数 */ float a = 0.0; /* 全積分区間の左端 */ float b = 1.0; /* 全積分区間の右端 */ int n = 1024; /* 台形の全個数 */ float h; /* 台形の底辺の長さ */ float local_a; /* 本プロセスの積分区間の左端 */ float local_b; /* 本プロセスの積分区間の右端 */ int local_n; /* 本プロセスの台形の数 */ float integral; /* 本プロセスの積分 */ float total; /* 全積分値 */ int source; /* 積分を送るプロセス */ int dest = 0; /* すべてのメッセージは0へ */
334 名前:お願いします [2009/06/18(木) 20:53:55 .net] int tag = 0; MPI_Status status; /* ローカルな積分を計算する */ float Trap(float local_a, float local_b, int local_n, float h); /* MPIの初期化 */ MPI_Init(&argc, &argv); /* カレントプロセスのランクを求める */ MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); /* プロセスの数を求める */ MPI_Comm_size(MPI_COMM_WORLD, &p); h = (b-a)/n; /* hはすべてのプロセスで同じ */ local_n = n/p; /* したがって台形の数も同じ */ /* 各プロセスの積分区間の長さはlocal_n*hである。 */ /* 本区間は次から始まる */ local_a = a + my_rank*local_n*h; local_b = local_a + local_n*h; integral = Trap(local_a, local_b, local_n, h);
335 名前:お願いします [2009/06/18(木) 20:54:39 .net] /* 各プロセスの積分を加算する */ if (my_rank == 0) { total = integral; for (source = 1; source < p; source++) { MPI_Recv(&integral, 1, MPI_FLOAT, source, tag, MPI_COMM_WORLD, &status); total = total + integral; } } else { MPI_Send(&integral, 1, MPI_FLOAT, dest, tag, MPI_COMM_WORLD); } /* 結果のプリント */ if (my_rank == 0) { printf("With n = %d trapezoids, our estimate\n", n); printf("of the integral from %f to %f = %f\n", a, b, total); } /* MPIを閉じる */ MPI_Finalize(); } /* main */
336 名前:お願いします [2009/06/18(木) 20:55:45 .net] float Trap( float local_a /* 入力 */, float local_b /* 入力 */, int local_n /* 入力 */, float h /* 入力 */){ float integral; /* 積分値 */ float x; int i; float f(float x); /* 被積分関数 */ integral = (f(local_a) + f(local_b))/2.0; x = local_a; for (i = 1; i <= local_n-1; i++) { x = x + h; integral = integral + f(x); } integral = integral*h; return integral; } /* Trap */ float f(float x) { float return_val; /* f(x) を計算する */ /* return_val に計算結果を入れる */ return_val = x * x; return return_val; } /* f */
337 名前:お願いします [2009/06/18(木) 20:57:04 .net] これと一緒なんです。 tetralog.in/t/?date=20060118 本当よろしくお願いします。
338 名前:デフォルトの名無しさん mailto:sage [2009/06/19(金) 00:14:35 .net] まず各ノードのintegralを送信せずに表示してみろよ。 積分が間違ってるのか送受信でやらかしてるのか区別つくだろ。 この程度のことくらいやってから他人に聞けば?
339 名前:デフォルトの名無しさん mailto:sage [2009/06/19(金) 14:08:34 .net] >>330 手元で実行してみたが $ mpirun -np 2 ./a.out With n = 1024 trapezoids, our estimate of the integral from 0.000000 to 1.000000 = 0.333333 となったぞ。ハードウェアの構成は何だ?
340 名前:お願いします [2009/06/19(金) 19:45:20 .net] ありがとうございます。 PCクラスタ環境は Fujitsu PRIMERGY RS200 ×16台 Xeon 3.20GHz/L3:1MB ×2 2GBメモリ 146.8GB HDD ×2(RAID1利用のため実効はこの半分) 73GB HDD ×5(RAID5利用のため実効はこの4/5) こんな感じです。
341 名前:お願いします [2009/06/19(金) 20:10:05 .net] 見直したんですがやっぱり出てくる答えは0.000488になって正しくないです。
342 名前:デフォルトの名無しさん mailto:sage [2009/06/19(金) 21:01:54 .net] >>339 だからよ、まずは積分単体が戻す答えを見て見ろっての。 どうせなにかの打ち間違いだろ。
343 名前:デフォルトの名無しさん [2009/06/19(金) 21:04:22 .net] MPIがおかしいと思うなら、そんな積分した答えじゃなく、1とか単純な値を送信しろよ。 自分で問題切り分ける意思がゼロだな。
344 名前:デフォルトの名無しさん mailto:sage [2009/06/20(土) 04:41:49
] [ここ壊れてます]
345 名前: .net mailto: 本当にコピペしたコードそのままで打ち間違いが無いのなら、 まずはMPI部分を全部削って1CPUで動かしてみろよ。 [] [ここ壊れてます]
346 名前:お願いします [2009/06/20(土) 12:43:17 .net] MPI部分なしでやれば0.333でます
347 名前:デフォルトの名無しさん [2009/06/20(土) 18:44:42 .net] Mac用のMPIはどこで手に入りますか?
348 名前:デフォルトの名無しさん mailto:sage [2009/06/20(土) 18:45:15 .net] MacにはOpenMPIが入っているが
349 名前:デフォルトの名無しさん [2009/06/21(日) 07:22:30 .net] 通常のGigabitイーサネットとInfiniBandではMPIを使った際にどの程度差が出ますか? もちろんプログラムにもよるでしょうが、InfiniBandに投資するだけの価値はありますか?
350 名前:デフォルトの名無しさん mailto:sage [2009/06/27(土) 19:20:41 .net] >>346 自分のGigabit環境で、MPIプログラムの通信部分と演算部分の比率を出してみれば、 InfiniBand環境でどれくらい改善するか、予測が付くだろう。 あと、B/F値への要求が高いコードでは、マルチコア環境で、メモリアクセス速度により、 並列化効率がでない場合も多いので、この点も注意した方がいい。
351 名前:デフォルトの名無しさん [2009/07/06(月) 06:59:07 .net] MPIの本を読むとSendとReceiveって奇数ノードと偶数ノードそれぞれ順序を逆にして書かないとデッドロックが発生するようなのですが、 今まで、すべてのノードでSendを先に書いていたのですが、とくにデッドロックしたことはありません。 OSか何かに依存するのでしょうか?
352 名前:デフォルトの名無しさん mailto:sage [2009/07/06(月) 21:10:54 .net] MPI_SendとMPI_Recvは送受信が完了するまで戻ってきませんが。 MPIの仕様なのでOSには依存しません。 別に偶数ノードと奇数ノードとか関係ありません。 送信と受信が対になって実行されないといけないだけです。 ノンブロッキング通信なら送信、受信動作が完了しなくても戻ってきますが、 別の関数で送受信が完了しているか確認をとる必要があります。
353 名前:デフォルトの名無しさん mailto:sage [2009/07/06(月) 21:46:09 .net] >>348 どの本のどういう記述よ
354 名前:デフォルトの名無しさん mailto:sage [2009/07/07(火) 14:04:08 .net] そういえば、標準モードでMPIが勝手にバッファリングモードを使用していたら対応する受信が起動ていなくても戻ってくるか。 そういう意味ではMPIの実装依存でデッドロックが起きていないということになるわな。
355 名前:デフォルトの名無しさん [2009/07/07(火) 16:32:14 .net] n 行 n 列 の整数二次元配列 A(i, j) のうち、i = 1 の成分 (A(1, 1), A(1, 2), A(1, 3), ..., A(1, n-1), A(1, n)) だけを j = 1 から m 個ローカルプロセスの B(j) に集めたいと思います。 そこで、mpi_gather を使って以下のように書いたのですが、 このままでは m/n 個しか B(j) に渡されないようなのです。 call mpi_gather(A(1, 1), m, mpi_integer, B(1), m, mpi_integer, 0, mpi_comm_world, ierr) fortran で書いていますので、この原因がメモリ上でのデータの 並び方(データがメモリ上で A(1, 1), A(2, 1), A(3, 1), ..., A(n, 1), A(1, 2), ... と並ぶ)なのだろうと思いますが、もし 飛び飛びでデータを選ぶ(j だけ m 個 ローカルに渡す)方法を ご存じでしたら教えて頂けないでしょうか? 初心的な質問ですみません。
356 名前:デフォルトの名無しさん mailto:sage [2009/07/07(火) 19:07:19 .net] >>352 つ MPI_TYPE_VECTOR
357 名前:デフォルトの名無しさん [2009/07/07(火) 20:32:32 .net] >> 353 神様、仏様、353様! 早速お教え頂きありがとうございました。
358 名前:デフォルトの名無しさん [2009/07/24(金) 16:46:11 .net] MPICH2とOpenMPIを使い分ける基準ってなんなのだろう 構文の違いと通信のしかたの違いとでどういう特徴があるのか・・・
359 名前:355 [2009/07/24(金) 16:49:25 .net] ちなみに自分のはMac OS XなのでOpenMPIが標準で入っているそうですが (XgridもOpenMPIを通して使うそうですね) MPICH2のほうはどうなのか、ちと気になりましてw
360 名前:デフォルトの名無しさん [2009/09/06(日) 10:48:01 .net] mpif77 でコンパイルは出来るのですが、 実行時 に mpirun -np 4 tttt と入力すると error while loading shared libraries : libompi_f77.so.o cannot open云々 となって動きません。libにはあるんですが、どうしたらよいか教えて下さい
361 名前:デフォルトの名無しさん mailto:sage [2009/09/06(日) 11:37:43 .net] >>357 実行時に .so ファイルを探したが見つからないというエラーなので適当な設定を加える必要がある。 libompi_f77.so のあるディレクトリを仮に /opt/lib とすると a) コンパイル時に -Wl,-rpath,/opt/lib オプションを指定する b) 実行時に環境変数 LD_LIBRARY_PATH=/opt/lib を設定する c) /etc/ld.so.conf に /opt/lib を追加して ldconfig コマンドを root 権限で実行する のどれかをすればいいと思われ。 a) は gcc のオプションで他のコンパイラにも同じようなオプションがある(はず)。 b) の環境変数の指定方法はあなたが使っているシェル(bash とか tcsh とか)によって違うので調べて。 c) は Linux の方法で、他の OS だとファイル名が違うかも知れない。
362 名前:デフォルトの名無しさん [2009/09/06(日) 13:37:28 .net] サンプルプログラムを実行することができました。有難うございます
363 名前:デフォルトの名無しさん mailto:sage [2009/09/18(金) 16:07:43 .net] rank数が0から始まるとちょっと使いにくいんですが、 勝手に include 'mpif.h' call mpi_init(ierr) call mpi_comm_rank(mpi_comm_world,np,ierr) call mpi_comm_size(mpi_comm_world,npe,ierr) np=np+1 ってやって使っても問題ないでしょうか?
364 名前:デフォルトの名無しさん mailto:sage [2009/09/18(金) 18:29:39 .net] 好きにせぇや
365 名前:デフォルトの名無しさん mailto:sage [2009/09/19(土) 00:13:13 .net] すいません、Visual studioのスレで聞いたんですが、 こっちで聞いた方が良いとのことでこっちにきました。 Visual studio2008+MPICH2+ifortranを使ってます。 ブレークポイントやステップ実行などが使いたいのですが、 デバッグ開始にすると「デバッグ情報が見つからないか、または一致しません」となります。 msdn.microsoft.com/ja-jp/library/ms164731.aspx 上のサイトにプロジェクトのプロパティのデバッグで[起動するデバッガ] を選択しろとありますが、 デバッガー-デバッガーの種類 しかそれらしいものが見当たらず、 また、グレーの文字になっていて変更できそうにありません(ネイティブのみとなっています) ちなみにデバッグなしで開始なら問題なく実行できますが… 今までCygwin上でwrite文を打ち込みながら原始的にやっていたので、 さっぱりVSの仕組みが分かっていなくて要領を得ないかと思うんですが、 どうすればデバッグモードで実行できるでしょうか?お手数ですが、アドバイスを頂くにあたって 足りない情報などあればご指摘ください。
366 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 17:43:11 .net] >>362 VSスレの方がいいんじゃねーかな。 windowsでMPI使う物好きは少ないと思うし。 つーか、モロにVSの使い方だし。
367 名前:デフォルトの名無しさん mailto:sage [2009/10/13(火) 21:53:16 .net] 質問です。fortranで配列の要素数をプロセス数に応じて決めたいのですが、 どのように宣言したらよいのでしょうか?allocateを使うしかないでしょうか? 77では無理ですか?
368 名前:デフォルトの名無しさん [2009/10/14(水) 11:12:10 .net] call mpiplay(n) subroutine mpiplay(n) real data(n) とか、かな。Initializeやfinalizeはメイン階層でしてね。 もっとも今は77とそれ以降を混ぜて書いても解釈してくれるから allocate でがんがんやっても良いと思うけど。
369 名前:デフォルトの名無しさん mailto:sage [2009/10/14(水) 19:51:56 .net] >>365 なるほど。動的配列を使うまでもなくそれでいいのですか。 ありがとうございます。もう一つお聞きしたいのですが、 メインでもその配列を使いたいときはどうすればよいでしょう? rank等の取得の前に宣言部が来るのでそのやり方では出来ないでしょうか? ダミー的にメインを作って、本当のメインをサブルーチンとして呼ぶとか?
370 名前:365 [2009/10/15(木) 05:59:50 .net] 365の例では サブルーチンでの型宣言 integer n とMPI呼出呪文w include 'mpif.h' が抜けてたね。 呪文はメイン階層でもする必要があるけど。 >>366 配列の要素数を、例えばプロセス数の100倍にしたければ、 program mpiwrapper (略;なんか行があったりなかったり) include 'mpif.h' (略、宣言部とか) call mpi_init(ierr) (略) call mpi_comm_size(mpi_comm_world,nprocs,ierr) n=nprocs*100 call mpiplay(n) (略) call mpi_finalize(ierr) stop end program mpiwrapper subroutine mpiplay(n) include 'mpif.h' integer n real data(n) (略) call mpi_comm_rank(mpi_comm_world,myrank,ierr) (略;分割対象のループがいっぱい。初期化とかiteration処理とか) (略その2;data配列をmainにお持ち帰りできないので書き出しとかはこの階層で) return end subroutine mpiplay かな?wrapperの表現が適切かはちと疑問だけど、まあここではOKということで・・・。 この例だと変数の初期値代入から書き出し保存などは全部 mpiplay(n)階層ですることになるね。
371 名前:デフォルトの名無しさん [2009/10/15(木) 06:29:09 .net] そんなわけで、fortran77コンパチで且つ前もって配列サイズを決めなくて良い、というのは できるけど。めんどいよねw. 自分自身はコマンドラインの引数を使いたい、 計算コード自身は77で書いてしまった、の2つの理由で メイン階層のWrapperをCでつくる事が多いけど。上の例は良くつかう。 やはり、というか配列サイズが前もって決まっていないタイプのコードは 最適化が抑制されるのか、遅いね。まあいちいちコード編集&コンパイルの 手間がかからないから楽といえば楽だけど。
372 名前:デフォルトの名無しさん [2009/10/15(木) 06:37:31 .net] だらだら書いてしまったけど・・・・ >>366 ダミー的にメインを作って、本当のメインをサブルーチンとして呼ぶとか? にYes!と書けば終わりだったな・・・・w 早起きはするものではないね。
373 名前:デフォルトの名無しさん mailto:sage [2009/10/17(土) 05:54:20 .net] >>369 いえ、結構怪しかったんで具体的に書いてもらって助かります。 丁寧に教えてくれてありがとう。
374 名前:デフォルトの名無しさん mailto:sage [2009/10/17(土) 20:52:34 .net] すみません、もう一つ質問なんですが、 vel(3,m) pos(3,m) (それぞれm番目の分子のxyz座標の速度と位置)を buffer(6,n) 1~3に速度(vel)を、4~6に位置(pos)をというように一つのbufferに詰め込んで 別のプロセスに送りたいんですけど、一回のアクセスで送り先のvel,pos両方に 格納することって出来ますか?別々にやらないとだめでしょうか? それとも受信用の配列(rbuffer(6,n))とか用意して、別の処理で受信用bufferから vel,posにそれぞれ移し替える方がよいでしょうか? ちなみに送られる分子のmは不連続なので送る過程ではbufferに詰め込んでますが、 送り先では送り先にある最大の分子の番号の末尾から連続で入れればよし、というような状況です。 (送り先に既にm個あったらm+1~m+nまで) 基本的に通信回数は減らした方がパフォは上がるという認識で良いですよね?
375 名前:デフォルトの名無しさん mailto:sage [2009/10/18(日) 05:40:13 .net] ・・・ラグランジュ法的な粒子なのね。 隣接関係(最近接の粒子番地)がころころかわるから厄介そう。 前半最後の2行が王道だとおもう。型の同じ変数は一つの配列名のに付けてから一度に送受信。 いっそ、最初からvelpos(6,m)みたいに位置や速度の情報を一つの大きめの配列にまとめちゃう方が いいかもね。vi(m) とか sed だと、 1,$s/pos(1/velposi(4/g 1,$s/pos(m/velposi(3+m/g みたいな感じでわりと一括置換が効きやすそうだし。 ・・・・・恐いけどw
376 名前:デフォルトの名無しさん mailto:sage [2009/10/18(日) 06:45:10 .net] >>372 うーん、やっぱそうですか。たびたびありがとうございます。 ちなみに代入はf90が使える場面なら PV(1:3,m+1:m+nmbuf)=rbuffer(1:3,1:nmbuf) PP(4:6,m+1:m+nmbuf)=rbuffer(4:6,1:nmbuf) みたいにループ使わずに書く方が速度的にもいいですか? (上であってます?間違いや冗長なところありますかね?) 上は簡略化してるんですが、実はもう少し複雑なので あまりパフォが違わないなら慣れた添え字ループの代入が無難かな。 情けない話ですが出来る限りコマンドラインを避けてるのでviとかsedとかの話あまり分かりません。 でもそれで置換出来るならプログラム書く効率あがりそうですね。覚えた方がいいと思いつつ… 統合環境がそういう複雑な置換装備してくれたらいいのにな。甘えすぎですか。
377 名前:デフォルトの名無しさん mailto:sage [2009/10/18(日) 09:38:00 .net] >>373 例では第一添え字が6要素だから、 do i=1,nmbuf pv(1:3,m+i) = rbuffer(1:3,i) pp(1:3,m+i) = rbuffer(4:6,i) enddo にするといいかな? 右側の要素を:つかって範囲指定すると遅くなることが多い・・・とおもう。 実装にも依存するけど、ベクトル的表現は第一添字(右端)だけに しておくのが安全&安心。 エディタでの一括置換は楽だけど諸刃の剣w
378 名前:デフォルトの名無しさん mailto:sage [2009/10/18(日) 09:39:35 .net] 第一添字(右端) ↓ 第一添字(左端)
379 名前:デフォルトの名無しさん [2009/10/20(火) 06:46:25 .net] インテルコンパイラだけど、MPI使うには、インテルの売ってるやつを使わないといけないの?
380 名前:デフォルトの名無しさん mailto:sage [2009/10/20(火) 22:03:31 .net] 何でもええ。 ライブラリがリンクできれば。
381 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 02:41:08 .net] MPI はコンパイラもだけど mpirun がないと。 自宅で文法チェックするだけなら -I -L
382 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 02:52:21 .net] max plunk institute !
383 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 06:45:10 .net] >>374 遅くなったけど本当にどうもありがとう。うまくできました。 ロードバランス大して考えずに領域の広さを均等にぶった切ったけどcore2quadで 3倍強の加速率でした。動的に負荷を割り振ったらもう少し早くなりそうかな?
384 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 20:05:53 .net] 最近HyperThreading対応の4coreのCPUが家庭向けの値段まで落ちてきたので 購入したのだが、ここまでスレッド数が多くなるとメモリ帯域か何かが溢れて 評価しないと使えないな。 同じプログラムが、 Pentium4 2.8GHz(1core * 2スレッド)ではMPIで2プロセス走らせると1.6倍ぐらい速くなったけど、 Corei7-860(4core * 2スレッド)ではMPIで8プロセス走らせると4プロセスに比べて0.9倍 ぐらいに遅くなったよ。
385 名前:デフォルトの名無しさん [2009/10/26(月) 06:36:28 .net] core i7か・・・いいな。このお金持ちめw いくらだった? 1 thread あたりの作業量は 4つの時に比べて0.9*4/8=45%くらいの残念くんだった、って事? 職場での印象では mpirun がメモリアクセスのスケジューリングを うまくさばいてくれていないような気はしたな。気がしただけで検証もなにもしてないけど。 やはり分散メモリのシステムとは根本的に違う、という事なのだろうな。 ・・・・OpenMPだともう少しマシな数字がでてくるのかな?
386 名前:デフォルトの名無しさん mailto:sage [2009/10/26(月) 06:42:32 .net] >>381 CPU とプロセス(またはスレッド)のアフィニティはどうしてる? プロセス数が多くなればなるほど、きっちり固定してやらないと パフォーマンス低下の原因になる希ガス。
387 名前:382 mailto:sage [2009/10/26(月) 07:00:00 .net] OpenMPはデフォだとうろうろするのは知ってたけど。 MPIも固定しないのか・・・知らんかった・・・。
388 名前:デフォルトの名無しさん mailto:sage [2009/10/26(月) 09:46:19 .net] windowsだとOSがウロウロさせるんだけど。 高負荷のシングルスレッドを実行させると全CPUが12%程度になるよ(8core)。 LinuxでもたまにCPUを乗り換えるけどwindowsほど頻繁じゃない。
389 名前:381 mailto:sage [2009/10/26(月) 23:47:19 .net] ふと4とか8プロセスとかとか切りのよい数字じゃなくて5とか6プロセスで 実行したらどうなるんだろうと思った。 現在1〜8プロセスの全てのパターンをベンチ中。多分終わるのは明日。 > core i7か・・・いいな。このお金持ちめw いくらだった? 再利用などしたので、マザボとメモリとCPUしか買ってませんが、46,675円 > 1 thread あたりの作業量は 4つの時に比べて0.9*4/8=45%くらいの残念くんだった、って事? そういう事です。 > CPU とプロセス(またはスレッド)のアフィニティはどうしてる? そのあたり詳しくないのでほとんど設定変更せず使ってます。 ちなみにOpenMPI/CentOS5.4です。
390 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 16:27:05 .net] Pentium4ほどパイプラインがスカスカじゃないからHTの効能はあまりないんじゃないかな。 マルチ「スレッド」のプログラムならメモリ資源などの共用が多くHTの効果がでるかもしれないけど、 マルチ「プロセス」のMPIじゃ同一コアでキャッシュとメモリ帯域の争奪戦をするだけで効率低下すると思うけど。
391 名前:デフォルトの名無しさん [2009/10/28(水) 02:43:34 .net] Visual C++2008でMPIを使いたいのですが、何をインストールすればよいのでしょうか?
392 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 02:57:18 .net] HTは結局コアが4つしかないから、メモリ転送がネックになる場合だと、パフォーマンスが落ちるよ。 アフィニティで固定したとしても、論理コアが物理コアとリンクしているとは限らないだろうから、 コア間で依存性があった場合は注意が必要だと思う。 HTは簡単に言うと、あいているパイプラインを有効に使うことだから、2つの処理を同じコアで計算させていることだからね。 ただ、3次キャッシュが大きいので、コアが増えることでプリフェッチの恩恵は受けやすくなるかも。
393 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 02:59:50 .net] >>384 そりゃそうでしょ。MPIだってコアの指定をしないとだめ。 もちろんPthreadでも。
394 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 03:24:38 .net] いわれるとそりゃそうだわ、なんだけど 383のを見るまで気づかんかったw OpenMPだと dplace や taskset で固定できるけど、 これはハードベンダが作った奴だしねぇ。MPIで固定するのはどうするの(特にWin機)?
395 名前:381 [2009/10/28(水) 21:52:47 .net] >>386 悪禁になってしまったのだが結果だけかくと 5プロセスで走らせると最速のようです
396 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 01:33:12 .net] >>392 それだとメモリアクセスが一番のボトルネックじゃない? ちょうど5コアでいい感じでメモリ帯域を食ってくれて、それ以下だと使い切れなくて、 それ以上だといっぱいになってしまう。 という感じに思える。
397 名前:デフォルトの名無しさん [2009/10/29(木) 03:41:16 .net] そんな感じっぽいね。381氏の実験に感謝。 最近はベクトル化を意識してループを短くして,(メモリでかくなったから)配列に中間結果を格納して・・・ というのがスパコンでは流行、というか推奨されるけど、HTでは ループ内での処理が冗長なベクトル化をあまり意識してないw古いタイプの コードが並列化では利得が大きいかも・・という事なのかな。 いまはCacheも大きいからたいがいループ内が長くても収まるし。
398 名前:デフォルトの名無しさん [2009/12/04(金) 22:16:21 .net] mpiの勉強を始めたばかりの者です。今、Bcastをやっていますが、どうにも解らなくなりました。ご指導ください。 使っているコンパイラー等はGfortran、open mpiです。解らなくなったのは、メインでBcastを使っても問題ないのですが、 サブルーチンでBcastを使うとエラーが発生してしまうんです。なんででしょうか?ちなみにプログラムは以下のとおりなんですが。 * MPI 宣言文 * IF(Nrank.EQ.0) NCP1=1000 CALL MPI_BCAST(NCP1,1,MPI_integer,0,MPI_COMM_WORLD,ierr) * KKK = 100 NNN = NCP1 + Nrank*KKK PRINT *, NNN これは問題なく動きますが、 IF(Nrank.eq.0) NCP1 = 1000 CALL MPI_BCAST(NCP1,1,MPI_integer,0,MPI_COMM_WORLD,ierr) 部分を IF(Nrank.EQ.0) CALL MAINSUBとし、サブルーチンを SUBROUTINE MAINSUB IMPLICIT REAL*8(A-H,O-Z) COMMON /ACTIVE/ NCP1 * NCP1 = 1000 CALL MPI_BCAST(NCP1,1,MPI_integer,0,MPI_COMM_WORLD,ierr) * RETURN END として、コンパイルし実行すると、 1000、 100、200、300と画面に出力され、notice thatjob rank 1 with PID 4737...の メッセージが表示されますが、何故か原因が解らないのです。よろしくお願いします。
399 名前:デフォルトの名無しさん mailto:sage [2009/12/04(金) 22:49:20 .net] >>395 サブルーチンMAINSUBの中でmpif.hのインクルードしてる?
400 名前:デフォルトの名無しさん [2009/12/05(土) 07:53:23 .net] 395 ですがやっていません。やってみます。
401 名前:デフォルトの名無しさん [2009/12/05(土) 08:04:52 .net] 395 ですが、動きました。どうも有難うございます。
402 名前:デフォルトの名無しさん [2009/12/12(土) 13:25:37 .net] WindowsでMPIをつこうたプログラムをコンパイルしたいのですが、 Windows XP+Vistal C++ 2008 Express以外に、どれをインストールすればよいのでしょうか?
403 名前:デフォルトの名無しさん mailto:sage [2009/12/12(土) 23:30:24 .net] MPICH
404 名前:デフォルトの名無しさん [2009/12/20(日) 02:28:58 .net] MPIってユーザーグループの会とか友の会とかないんですかね?? もしなかったら作ってみたいなっと思いまして.2ヶ月に一度くらい勉強会とかライトニングトークしあう的な規模のもので.
405 名前:デフォルトの名無しさん mailto:sage [2009/12/20(日) 11:22:07 .net] あんなもん、一旦意味がわかればマニュアル見るだけでOKなので 2ヶ月に一度とかタルいことしてたら、次の勉強会までにプログラムできるようになっている。 てか、それでできない人間だけ集まっても意味ないし、できる人間は参加してもタルいだけだろう。
406 名前:デフォルトの名無しさん mailto:sage [2009/12/20(日) 11:52:25 .net] プログラムのほとんどを1スレッドで走らせ、一部を並列計算させたい場合、 その一部以外を if(myrank==0) で囲えばいいの?
407 名前:デフォルトの名無しさん [2009/12/20(日) 13:09:48 .net] うん、たいていそれでいいよ。 非並列処理部分の結果を並列部分で使いたい時だったら ちゃんと伝達するのを忘れないように><
408 名前:デフォルトの名無しさん mailto:sage [2009/12/21(月) 05:10:55 .net] ですよね なんとなく「プログラムのほとんどが if 文」ってのが違和感なんだけど 他に書き方ないよね
409 名前:デフォルトの名無しさん mailto:sage [2009/12/21(月) 09:37:58 .net] そうそう、なんかif (myrank .....が冗長に出てくるのがなんかイヤw 並列の出入口でやることが決まっていれば関数に押し込めるけど、そういう事ってあまり多くないし 引数受渡し部分でちょんぼすることあるし・・・><
410 名前:デフォルトの名無しさん [2009/12/23(水) 09:49:25 .net] 現在勉強中で、Send、Recvを使って簡単なプログラムを作って動かしていますが、送るデータの個数が 500以下だと問題なく送受でき、送受結果を画面に表示できるのですが、500個を超えると送受結果が 画面に表示できません。プログラムが暴走したような状態になってしまうんです。 データの型は倍精度浮動小数点なんですが、解決策は無いでしょうか?使用している mpiは openmpiです。
411 名前:デフォルトの名無しさん [2009/12/23(水) 10:52:26 .net] 受信側のメモリを確保しているのかと3秒問いつめたい
412 名前:デフォルトの名無しさん [2009/12/23(水) 12:40:54 .net] 407ですが、受け側でも送り側と同じ配列だけメモリーは設定しております。 当初は配列をアロケートしていましたが、疑問に思い、配列を設定して 再コンパイルして実行しても同じなんですが。
413 名前:デフォルトの名無しさん mailto:sage [2009/12/23(水) 13:05:15 .net] 他人に自分の意志を伝えられない奴が コンピュータに自分の意志を伝えるプログラミングができるわけがない。 ソースもなしに・・・エスパーも求もと書いとけ。
414 名前:デフォルトの名無しさん mailto:sage [2009/12/27(日) 20:24:15 .net] openfabrics.orgがつながらない、、、
415 名前:デフォルトの名無しさん [2009/12/28(月) 22:57:30 .net] 先日、Bcastの件で指導を頂いたものですが、今回、ScatterとGatherについてご指導願います。 プログラムは program TEST implicit real*8(a-h,o-z) : : MPIの使用開始の手続き : dimension a(2000),b(2000) ! if(Nrank.eq.0) then do i=1, 2000 a(i)=dble(i) enddo endif ! call MPI_Scatter(a(1),20,MPI_DOUBLE_Precision,b(1),20,0,MPI_COMM_WORLD,ierr) ! if(Nrank.gt.0) then do i=1, 20 print *,Nrank,b(i) :この部分で画面に出力 enddo endif ! iiii = 1 + Nrank*10 call MPI_Gather(b(1),10,MPI=DOUBLE_Precision,a(iiii),10,MPI_DOUBLE_Precision,0,MPI_COMM_WORLD,ierr) : として、実行したのですが、画面出力部分では、出力値が全てのランクで0.0となるんです。 当然のことながらGatherでも同様なんですが、どうやった良いのか原因も何も解りません。どうかご指導ください
416 名前:デフォルトの名無しさん [2009/12/28(月) 23:06:52 .net] 失礼しました、 Scatterで...,b(1),20,の後にMPI_DOUBLE_Precision,を書き漏らしております。 質問時の記入ミスです。すみません。
417 名前:デフォルトの名無しさん [2010/01/06(水) 09:09:27 .net] これで出力が出ます。 それとGatherの方で MPI=DOUBLE_Precision の=が_の間違い。 a(iiii)は、ランク0に送るなら ランク0の受信バッファーを指定するので多分a(1)です。 implicit real*8(a-h,o-z) include'mpif.h' dimension a(2000),b(2000) call mpi_init(ierr) call mpi_comm_rank(mpi_comm_world,Nrank,ierr) if(Nrank.eq.0) then do i=1, 2000 a(i)=dble(i) enddo endif call MPI_Scatter(a(1),20,MPI_DOUBLE_Precision, & b(1),20,MPI_DOUBLE_Precision, & 0,MPI_COMM_WORLD,ierr) if(Nrank.gt.0) then do i=1, 20 print *,Nrank,b(i) enddo endif call mpi_finalize(ierr) end
418 名前:デフォルトの名無しさん [2010/02/08(月) 17:39:36 .net] PCだと大丈夫なんですが、大規模な計算機にジョブを投げたとき、 あるプロセスからの出力だけ途中で止まることがあります。 PCはintel fortran+mpich、大規模計算機はPGIfortran+Voltaire MPIです。 例えばプロセスごとにoutput00,output01,output02,output03のように 別のファイルに出力させているんですが、何かの拍子にいくつかが出力 されなくなったりします。ループの途中にbcastやbarrier等の同期があるので、 出力がないプロセスも計算そのものが停止しているということはないと思うのですが、 別のファイルや標準出力への出力も停止するのでうまく調べきれず、定かではありません。 かなり情報が少なくて申し訳ないのですが、考えうる原因、調査法、解決法もしくは それに至らなくとも何か思いついたことでもあれば教えて頂けませんか?
419 名前:デフォルトの名無しさん mailto:sage [2010/02/08(月) 19:42:12 .net] >>415 2桁のファイル名を決める整数が 違うプロセスで同じ整数になっちゃって・・・とか とびとびになってしまって、とかは無いのかな? PCとスパコンで違う並列数でやっておかしくなったのなら 同じ並列数(2とかw)でやってテストしてみては? CPUが自分のプロセス番号(例題でよく変数名Myrankになるやつ) を決める部分のチェックとかもやるといいかも。 とあるシステムでちゃんと動いてるので415さんのMPIの (データ転送とかの)部分にミスがあるとは考えにくい、 という推定からすると他にはあまり思いつかないな。
420 名前:デフォルトの名無しさん mailto:sage [2010/02/09(火) 00:30:15 .net] >>415 ノードローカルのディスクに書いてるとかいうオチならブチキレ
421 名前:デフォルトの名無しさん mailto:sage [2010/02/09(火) 02:35:40 .net] でもたいていのシステムではジョブ終了時に一箇所にまとめるから 少なくともジョブ終了後にユーザーがファイルを移動する操作を する必要は無いような気もするけど・・・・ その可能性は大いにあるね。