• 締切済み

MPIを用いた並列計算における3次元配列の通信に関して

以下のプログラムで,ランク0の3次元配列rec_f[][][]に,ランクpの3次元配列id[][][]を,要素ごとではなく,そのままコピーすることを考えています. しかし,途中出力したid[6][24][3]とrec_f[6][24][3]が異なる値になってしまい,その理由が分かりません. 宜しければ,原因と修正箇所をご教示頂けないでしょうか. 宜しくお願い致します. if(my_rank != 0) { MPI_Isend(id, lx * my * mz, MPI_INT,    dest, 0, MPI_COMM_WORLD, &request); if(my_rank == 2) cout << id[6][24][3] << " "; } else {   for(i = 1; i < lx - 1; i ++) {  for(p = 1; p <= p_num-1; p++)   {   source = p;   MPI_Irecv(rec_f, lx * my * mz, MPI_INT, source, 0,                      MPI_COMM_WORLD, &request);  if(p == 2) cout << rec_f[6][24][3] << " ";   } } MPI_Wait(&request,&status);

みんなの回答

  • chie65535
  • ベストアンサー率43% (8536/19408)
回答No.1

MPIは無関係な気がします。 配列rec_fと配列idの型は何でしょうか? 型によっては「代入する前の計算結果と、代入した後の変数で、値が異なる」と言う事が起きます。

medousa
質問者

補足

ご回答ありがとうございます. 配列rec_fと配列idの型はどちらもint型で定義しています.

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • MPIプログラムの実行でエラーが出てしまいます

    エラストテネスのふるいのプログラムなんですが、どうもエラーが出て実行できません。 他の部分などを直して、なんとかエラーをひとつにしたんですが、どうも#include "MyMPI.h"に関連する部分でミスがあってできないようなのです。 エラーの内容は文字化けしているので読めません。 どなたかお教えしてもらえないでしょうか。 #include<mpi.h> #include<math.h> #include<stdio.h> #include "MyMPI.h" #define MIN(a,b) ((a)<(b)?(a):(b)) int main(int argc, char *argv[]) { int count; double elapsed_time; int first; int global_count; int high_value; int i; int id; int index; int low_value; char *marked; int n; int p; int proc0_size; int prime; int size; MPI_Init(&argc, &argv); MPI_Barrier(MPI_COMM_WORLD); elapsed_time = -MPI_Wtime(); MPI_Comm_rank (MPI_COMM_WORLD,&id); MPI_Comm_size (MPI_COMM_WORLD,&p); if (argc != 2) { if (!id) printf("Command line: %s <m>\n", argv[0]); MPI_Finalize(); exit(1); } n = atoi(argv[1]); low_value = 2 + BLOCK_LOW(id,p,n-1); high_value = 2 + BLOCK_HIGH(id,p,n-1); size = BLOCK_SIZE(id,p,n-1); proc0_size = (n-1)/p; if ((2 + proc0_size) < (int) sqrt((double) n)) { if (!id) printf("Too many processes\n"); MPI_Finalize(); exit (1); } marked = (char *) malloc (size); if (marked == NULL) { printf("Cannot allocate enough memory\n"); MPI_Finalize(); exit(1); } for (i = 0; i < size; i++) marked[i] = 0; if (!id) index = 0; prime = 2; do { if (prime * prime > low_value) first = prime * prime - low_value; else { if (!(low_value % prime)) first = 0; else first = prime - (low_value % prime); } for (i = first; i < size; i += prime) marked[i] = 1; if (!id) { while (marked[++index]); prime = index + 2; } MPI_Bcast (&prime, 1, MPI_INT, 0, MPI_COMM_WORLD); } while (prime * prime <= n); count = 0; for (i = 0; i < size; i++) if (!marked[i]) count++; MPI_Reduce (&count, &global_count, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); elapsed_time += MPI_Wtime(); if (!id) { printf("%d primes are less than or equal to %d\n",global_count, n); printf("Total elapsed time: %10.6f\n", elapsed_time); } MPI_Finalize(); return 0; }

  • MPI

    MPIのエラーメッセージの意味がわからないので質問します。 エラーメッセージは以下の通りです。 ----------------------------------------------------------------------------------------- [cli_1]: aborting job: Fatal error in MPI_Send: Other MPI error, error stack: MPI_Send(172).............................: MPI_Send(buf=0x80e557c, count=26, MPI_INT, dest=2, tag=0, MPI_COMM_WORLD) failed MPIDI_CH3_Progress_wait(199)..............: an error occurred while handling an event returned by MPIDU_Sock_Wait() MPIDI_CH3I_Progress_handle_sock_event(436): MPIDI_CH3U_Handle_recv_pkt(247)...........: failure occurred while allocating memory for a request object rank 1 in job 258 cs080_12340 caused collective abort of all ranks exit status of rank 1: killed by signal 9 [cli_0]: aborting job: Fatal error in MPI_Send: Other MPI error, error stack: MPI_Send(172).............................: MPI_Send(buf=0x80e557c, count=26, MPI_INT, dest=1, tag=0, MPI_COMM_WORLD) failed MPIDI_CH3_Progress_wait(199)..............: an error occurred while handling an event returned by MPIDU_Sock_Wait() MPIDI_CH3I_Progress_handle_sock_event(777): MPIDU_Socki_handle_pollhup(418)...........: connection closed by peer (set=0,sock=1) ----------------------------------------------------------------------------------------- これはやはりメモリ関係のエラーなのでしょうか? 詳しい方、知っている方がいましたら教えてください。 よろしくお願いします。

  • 二次元配列のつかいかた。

    配列の中に、同じ値があるかどうか、確認して、なければ データを渡すというようなプログラムを書きましたが、どうもうまくいきません.二次元配列が間違っているのだと思いますが、どこがいけないのでしょうか. my @databe=qw(aa:ee:rr:rr aa:rr:tt:aa dd:tt:dd:aa); my @nonumber=qw(ringo mikan tamago susi); my @check=();#not same contents my $p=0; my @array=(); foreach( @databe ){ my @f = split(/:/); my $i=0; foreach(@f){ push( @{$array[$p]}, $_); $i++; } $p++; } for(my $i=2;$i<$#nonumber;$i++){ for(my $p=0;$p<$#databe;$p++){ unless($array[0][$i] eq $array[$p][$i]){ push(@check, $i); } } } foreach( @databe ){ my @f = split(/:/); my %tmp; $tmp{GEBEN1}=$f[$check[0]];#html::template $tmp{GEBEN2}=$f[$check[1]];#html::template push( @alldata,\%tmp); } プログラム初心者です。自分なりに組んでみたのですがどうもうまくいきません. 分かる方御回答よろしくお願いします。

  • 3次元配列を2次元配列にする方法はありますか?

    3次元配列を2次元配列にする方法はありますか? すいません、初心者です。 オープンソースとyahooとgoogleのAPIを使って統合型メタ検索エンジンを作っています。 yahooの結果の配列は2次元配列で出せました。 $search_results[$i]["url"] google APIは1回のリクエストで8件までしか呼び出せないみたいなので、 curl_multi関数を使って複数のリクエストを同時に取得しています。 そうしたら結果の配列は三次元配列になりました。 $search_results[$id][$i]["url"] 以下googleの関数です。curl_multiの部分等、文字数の関係で省略しています。 省略した部分のソースは下記リンクにのっています。 http://phpspot.org/blog/archives/2008/02/phpapi.html function search_google($query) { $curls = array(); $search_results = array(); $i=0; $site_results = array( 'http://ajax.googleapis.com/&start=0', 'http://ajax.googleapis.com/&start=8', 'http://ajax.googleapis.com/&start=16', 'http://ajax.googleapis.com/&start=24', 'http://ajax.googleapis.com/&start=32', 'http://ajax.googleapis.com/&start=40', 'http://ajax.googleapis.com/&start=48', 'http://ajax.googleapis.com/&start=56'); foreach($curls as $id=>$c) { $searchs[$id] = curl_multi_getcontent($c);//$cが$site_resultsのリクエスト結果 curl_multi_remove_handle($mh, $c); $json=json_decode($searchs[$id]); if($json->responseStatus != 200){exit();} $responseData = $json->responseData; $results = $responseData->results; for($i=0;$i<count($results);$i++){ $title = $current_result->title; $search_results[$id][$i]["title"]= $title; } } curl_multi_close($mh); return $search_results; } 統合型メタ検索にしたいと考えているのでgoogle配列の変数[$id]同士を結合して yahooの結果と同じく $search_results[$i]["url"] のような二次元配列にしたいのですが、そのようなことは可能ですか? 本当は両方とも3次元配列にするという処理が適切だと思いますが、初心者がオープンソースを改良して使用しているので、どこを直せば3次元配列のものをうまく表示できるのかわからないのです。 わかりにくかったらすいません。どうか、よろしくお願いします。

    • ベストアンサー
    • PHP
  • C++ 2次元配列について 【 初心者です 】

    こんにちは.C++初心者です. 以下のプログラムは, オブジェクトの2次元配列の作成と そのアクセスをポインタで行うことを 目的としています. 以下の□■部が質問箇所です. なぜobをsamp型でキャストするのか分かりません. obはすでにsamp型で宣言しているのに… それと※部において 2度目のp++処理について教えていただきたいです. メモリーイメージを書いてもらえると ありがたいです。 よろしくおねがいします。 #include <iostream.h> using namespace std; class samp { int a; public: samp(int n) { a = n; } int get_val() { return a; } }; int main(void) { samp ob[3][2] = { 1, 2 3, 4, 5, 6 }; int i; samp *p; // □■□■□■□■ p = (samp *) ob; for(i = 0; i < 3; i++) { cout << p->get_val() << ' '; p++; ※ cout << p->get_val() << endl; ※ p++; } cout << endl; return 0; } }

  • 二次元配列を作り、要素に値を入れていくには?

    二次元配列がそもそもうまく作れていません。一応以下のようにつくってみましたが、うまく動作していないようです。 どこが原因でしょうか? for(i=0; i<=gapnum; ++i){ for(iii=0; iii<=gapnum; ++iii){ if(lng > lat2){ if(ICONarray[[i],[iii]]==""){ ICONarray[[i],[iii]]=d_id; }else{ CONarray[[i],[iii]]=ICONarray[[i],[iii]]+","+d_id; }; } } }

  • arraylist 二次元配列

    こんにちは 今アレイリストの二次元配列を学習しています DBからデータを取得で表示したいと思っています そこでfor文の拡張とつかうとうまくいうのですが 普通に記述するとうまくいきません 拡張FOR 文を使うのは初めてなので 何が違うかアドバイスお願いします コンパイルできません↓ if(request.getAttribute("list")!=null || request.getAttribute("list1")!=null || request.getAttribute("list2")!=null){ ArrayList<ArrayList> hai = new ArrayList<ArrayList>(); ArrayList list = (ArrayList)request.getAttribute("list"); if (list != null) { hai.add(list); } ArrayList list1 = (ArrayList)request.getAttribute("list1"); if (list1 != null) { hai.add(list1); } ArrayList list2 = (ArrayList)request.getAttribute("list2"); if (list2 != null) { hai.add(list2); } for (int i = 0; i < hai.get(0).size(); i++) { %> <table border="3"> <tr> <% for (int k = 0 ; k <= hai.size(); k++) { %> <td width="60"> <% out.print(hai.get(i)); } %> コンパイルOK 表示できています <% if(request.getAttribute("list")!=null || request.getAttribute("list1")!=null || request.getAttribute("list2")!=null){ ArrayList<ArrayList> hai = new ArrayList<ArrayList>(); ArrayList list = (ArrayList)request.getAttribute("list"); if (list != null) { hai.add(list); } ArrayList list1 = (ArrayList)request.getAttribute("list1"); if (list1 != null) { hai.add(list1); } ArrayList list2 = (ArrayList)request.getAttribute("list2"); if (list2 != null) { hai.add(list2); } for (int i = 0; i < hai.get(0).size(); i++) { %> <table border="3"> <tr> <% for (ArrayList list4 : hai) { %> <td width="60"> <% out.print(list4.get(i)); } %> <br> </tr> </table> <% 上のソースの エラーメッセージ 2013/04/16 9:24:12 org.apache.catalina.core.ApplicationDispatcher invoke 致命的: サーブレット jsp のServlet.service()が例外を投げました java.lang.IndexOutOfBoundsException: Index: 2, Size: 2 よろしくお願いします

    • ベストアンサー
    • Java
  • 多次元配列の new

    多次元配列を new すると、どのような型のサイズの領域の配列が確保されるんでしょうか?たとえば、  int (*a)[2] = new int[3][2]; とすると、  1. 長さ2のintの配列へのポインタ型の長さ3の配列の領域が確保される のか、  2. int[3][2] すなわち、int が 6 つ分の領域が確保される のか。 今まで、「そりゃあ 2 の方だろう」と信じ込んであまり考えずにいたんですが、「コードの型形式からすると 1 の方の解釈でもいいよなぁ」と、ふと思ったものですから、質問させていただきました。 わたしの環境で調べてみると(配列用のハウスキーピング的な余分の領域とか、パディングなどは無視して)、確かに 1 の方なんですか、これで標準準拠なんでしょうかね?^^; XP Home Edition Ver.2002 SP2 cygwin v.1.0.2-1 GNU g++ v.4.1.1 ===== #include <iostream> #include <new> #include <cstdlib> struct A { char a; void *operator new(std::size_t s) { void *p = std::malloc(s); std::cout << "A::new(): " << p << '\t' << s << '\n'; return p; } void operator delete(void *p, std::size_t s) { std::cout << "A::delete(): " << p << '\t' << s << '\n'; if (p) std::free(p); } void *operator new[](std::size_t s) { void *p = std::malloc(s); std::cout << "A::new[](): " << p << '\t' << s << '\n'; return p; } void operator delete[](void *p, std::size_t s) { std::cout << "A::delete[](): " << p << '\t' << s << '\n'; if (p) std::free(p); } }; int main() { std::cout << sizeof(char) << '\t' << sizeof(A) << '\t' << sizeof(A(*)[8]) << '\n'; A *a = new A; std::cout << a << '\n'; A *aa = new A[8]; std::cout << aa << '\n'; A (*aaa)[8] = new A[8][8]; std::cout << aaa << '\n'; A (*aaaa)[8][8] = new A[8][8][8]; std::cout << aaaa << '\n'; delete[] aaaa; delete[] aaa; delete[] aa; delete a; } ===== % ./a.exe 1 1 4 A::new(): 0x870668 1 0x870668 A::new[](): 0x870678 12 0x87067c A::new[](): 0x870688 68 0x87068c A::new[](): 0x8706d0 516 0x8706d4 A::delete[](): 0x8706d0 516 A::delete[](): 0x870688 68 A::delete[](): 0x870678 12 A::delete(): 0x870668 1

  • 多次元配列から重複を削除

    Perlにて$f[i][j]のような2次元配列でデータを格納しています。 ここの[i]列には重複したデータが入っているので、 それを排除して[i]列の重複なしの配列を新たに作りたいのですが うまくいきません。 for ($j=0; $j<= $index; $j++){ if($chlist[j]==$f[$i][0]){ $chlist[j]==$f[$i][0]; last; } } こんな感じで作ってみたのですが永遠にデータが入りません。

  • 多次元配列の初期化

    多次元配列の初期化を行いたいのですが、 下記の方法では、配列の値が多くなったときに大変 なので他に良い方法はありませんでしょうか? char lesson[7][6] = { {'A', 'B', 'C', 'D', 'E', 'F'}, {'G', 'H', 'I', 'J', 'K', 'L'}, {'M', 'N', 'O', 'P', 'Q', 'R'}, {'S', 'T', 'U', 'V', 'W', 'X'}, {'Y', 'Z', 'a', 'b', 'c', 'd'}, {'e', 'f', 'g', 'h', 'i', 'j'}, {'k', 'l', 'm', 'n', 'o', 'p'}, };