質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

MPI

MPIは、並列プログラミングを利用するための標準化規格、及び実装自体のことを指します。バイト列で構成されたメッセージとして、いくつかのCPUが情報を送受信することにより協調動作を可能にします。

並列処理

複数の計算が同時に実行される手法

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

4522閲覧

MPIにおける多次元vector配列の送受信について

hinatades

総合スコア10

C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

MPI

MPIは、並列プログラミングを利用するための標準化規格、及び実装自体のことを指します。バイト列で構成されたメッセージとして、いくつかのCPUが情報を送受信することにより協調動作を可能にします。

並列処理

複数の計算が同時に実行される手法

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2016/11/10 10:37

編集2016/11/10 10:40

並列計算ライブラリMPIを使う際に、多次元vector配列の送受信を行いたいと考えています。送受信を行う際に、多次元vector配列の先頭アドレスが必要になるのですが、例えば以下のサンプルのように(ここではわざわざvectorを使う必要はありませんが)MPI_Reduceを書いても上手くいきません。ちなみにvectorを使わないと成功します。

どなたか教えていただけるとありがたいです。

以下のサンプルは成功するとwの全要素に3が入ります。
使用ライブラリはOpen MPI 2.0.1です。

vect_test.cpp

1#include <mpi.h> 2#include <iostream> 3#include <vector> 4 5using namespace std; 6 7int main(int argc, char **argv){ 8 9 int i, j, k, my_rank, p; 10 int n_value = 2; 11 int n_visible = 3; 12 int n_hidden = 4; 13 14 std::vector<std::vector<std::vector<double>>> w; 15 std::vector<std::vector<std::vector<double>>> vect3d; 16 17 MPI_Init(&argc, &argv); 18 MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); 19 MPI_Comm_size(MPI_COMM_WORLD, &p); 20 21 w.resize(n_value); 22 for(auto &ref :w) { 23 ref.resize(n_visible); 24 for(auto &ref2 :ref){ 25 ref2.resize(n_hidden); 26 for(auto &ref3 :ref2){ 27 ref3 = 0.0; 28 } 29 } 30 } 31 32 vect3d.resize(n_value); 33 for(auto &ref :vect3d) { 34 ref.resize(n_visible); 35 for(auto &ref2 :ref){ 36 ref2.resize(n_hidden); 37 for(auto &ref3 :ref2){ 38 ref3 = (double)my_rank; 39 } 40 } 41 } 42 43 if(my_rank==0){ 44 for(i=0; i<n_value; i++){ 45 for(j=0; j<n_visible; j++){ 46 for(k=0; k<n_hidden; k++){ 47 printf("w[%d][%d][%d]=%f \n", i, j, k, w[i][j][k]); 48 } 49 } 50 } 51 printf("\n"); 52 } 53 54 MPI_Reduce(&vect3d[0][0][0], &w[0][0][0], n_value * n_visible * n_hidden, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); 55 56 if(my_rank==0){ 57 for(i=0; i<n_value; i++){ 58 for(j=0; j<n_visible; j++){ 59 for(k=0; k<n_hidden; k++){ 60 printf("w[%d][%d][%d]=%f \n", i, j, k, w[i][j][k]); 61 } 62 } 63 } 64 printf("\n"); 65 } 66 67 MPI_Finalize(); 68 return 0; 69}
$ mpic++ -std=c++11 vect_test.cpp -o vect_test $ mpirun -np 3 ./vect_test w[0][0][0]=0.000000 w[0][0][1]=0.000000 w[0][0][2]=0.000000 w[0][0][3]=0.000000 w[0][1][0]=0.000000 w[0][1][1]=0.000000 w[0][1][2]=0.000000 w[0][1][3]=0.000000 w[0][2][0]=0.000000 w[0][2][1]=0.000000 w[0][2][2]=0.000000 w[0][2][3]=0.000000 w[1][0][0]=0.000000 w[1][0][1]=0.000000 w[1][0][2]=0.000000 w[1][0][3]=0.000000 w[1][1][0]=0.000000 w[1][1][1]=0.000000 w[1][1][2]=0.000000 w[1][1][3]=0.000000 w[1][2][0]=0.000000 w[1][2][1]=0.000000 w[1][2][2]=0.000000 w[1][2][3]=0.000000 w[0][0][0]=3.000000 w[0][0][1]=3.000000 w[0][0][2]=3.000000 w[0][0][3]=3.000000 w[0][1][0]=3.000000 w[0][1][1]=0.996108 w[0][1][2]=3.000000 w[0][1][3]=3.000000 w[0][2][0]=0.000000 w[0][2][1]=0.000000 w[0][2][2]=0.000000 w[0][2][3]=0.000000 w[1][0][0]=0.000000 w[1][0][1]=0.000000 w[1][0][2]=0.000000 w[1][0][3]=0.000000 w[1][1][0]=0.000000 w[1][1][1]=0.000000 w[1][1][2]=0.000000 w[1][1][3]=0.000000 w[1][2][0]=0.000000 w[1][2][1]=0.000000 w[1][2][2]=0.000000 w[1][2][3]=0.000000 vect_test(47908,0x7fff9b8e73c0) malloc: *** error for object 0xff7f8e9782d0: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug [] *** Process received signal *** [] Signal: Abort trap: 6 (6) [] Signal code: (0) [] [ 0] 0 libsystem_platform.dylib 0x00007fff92dd4bba _sigtramp + 26 [] [ 1] 0 ??? 0x000000011a78e968 0x0 + 4739098984 [] [ 2] 0 libsystem_c.dylib 0x00007fff92c5b420 abort + 129 [] [ 3] 0 libsystem_malloc.dylib 0x00007fff92d4b097 szone_size + 0 [] [ 4] 0 libopen-pal.20.dylib 0x000000010d60450f mca_base_var_enum_destructor + 52 [] [ 5] 0 libmpi.20.dylib 0x000000010d4917ab ompi_win_finalize + 354 [] [ 6] 0 libmpi.20.dylib 0x000000010d4901fb ompi_mpi_finalize + 870 [] [ 7] 0 vect_test 0x000000010d4655ea main + 4906 [] [ 8] 0 libdyld.dylib 0x00007fff92bc7255 start + 1 [] *** End of error message *** -------------------------------------------------------------------------- mpirun noticed that process rank 0 with PID 0 on node !my_name! exited on signal 6 (Abort trap: 6). --------------------------------------------------------------------------

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

MPIって動的配列の場合の大きさが変化するとエラー。だから動的配列でも宣言の時に大きさを定義すると通るはずですが。
std::vector<std::vector<std::vector<double>>> w; std::vector<std::vector<std::vector<double>>> w(3);とか。

投稿2016/11/10 11:09

MasahikoHirata

総合スコア3747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hinatades

2016/11/10 12:01

回答ありがとうございます! 1次元vector配列だと教えてくださった書き方で書けるようですが、2次元以上の場合、例えば3次元だったら // int vvvi[30][20][10] vector<vector<vector<int>>> vvi(30, vector<vector<int>>(20, vector<int>(10, 0))); のように書いて大きさを定義するようです。
guest

0

ベストアンサー

こんにちは。

MPIについては知らないのですがMPI_Reduce()のパラメータを見る限り、連続領域へのポインタを渡す必要があるように見えます。
しかし、std::vector<>の多次元配列の記憶領域は連続しません。std::vector<>の多次元配列はジャグ配列ですから。

投稿2016/11/10 11:00

編集2016/11/10 11:01
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hinatades

2016/11/10 12:05

回答ありがとうございます! 教えてくださったように、std::vector<>の多次元配列の記憶領域が連続しないことが原因のようです。1次元vector、もしくはboostライブラリのboost::multi_arrayというのもあるらしいのでそちらを使って書き換えたいと思います!
episteme

2016/11/10 12:10

std::valarray<T>てのもあるよー
hinatades

2016/11/11 14:37

ありがとうございます!試してみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問