[解決済み] MPI_ScatterとMPI_GatherはC言語からどのように使用するのですか?
質問内容
これまでのところ、私のアプリケーションは、整数のリストを含むtxtファイルを読み込んでいます。これらの整数は、マスタープロセス、すなわちランク0のプロセッサによって配列に格納される必要があります。これは問題なく動作しています。
さて、プログラムを実行すると、マスタープロセスかどうかをチェックするif文があり、マスタープロセスなら
MPI_Scatter
コマンドを実行します。
私の理解では、これは数字で配列を細分化し、スレーブプロセス、すなわちランク > 0 のすべてに渡します。しかし、私はどのように
MPI_Scatter
. スレーブプロセスはどのようにサブアレイを取得するのでしょうか?マスター以外のプロセスにサブアレイで何かをするように指示するにはどうすればよいですか?
マスタープロセスが配列から要素を送り出し、スレーブがその合計をマスターに返し、マスターがすべての合計を足し合わせてプリントアウトする方法を示す簡単な例をどなたか教えてください。
これまでの私のコード
#include <stdio.h>
#include <mpi.h>
//A pointer to the file to read in.
FILE *fr;
int main(int argc, char *argv[]) {
int rank,size,n,number_read;
char line[80];
int numbers[30];
int buffer[30];
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
fr = fopen ("int_data.txt","rt"); //We open the file to be read.
if(rank ==0){
printf("my rank = %d\n",rank);
//Reads in the flat file of integers and stores it in the array 'numbers' of type int.
n=0;
while(fgets(line,80,fr) != NULL) {
sscanf(line, "%d", &number_read);
numbers[n] = number_read;
printf("I am processor no. %d --> At element %d we have number: %d\n",rank,n,numbers[n]);
n++;
}
fclose(fr);
MPI_Scatter(&numbers,2,MPI_INT,&buffer,2,MPI_INT,rank,MPI_COMM_WORLD);
}
else {
MPI_Gather ( &buffer, 2, MPI_INT, &numbers, 2, MPI_INT, 0, MPI_COMM_WORLD);
printf("%d",buffer[0]);
}
MPI_Finalize();
return 0;
}
解決方法は?
これはMPIを初めて使う人によくある誤解で、特に集団操作では、ブロードキャスト(
MPI_Bcast
を呼び出すことで、他のプロセッサに何らかの形でデータをプッシュすることを期待しています。 ほとんどのMPI通信は、送信側と受信側の両方でMPIコールを行う必要があります。
特に
MPI_Scatter()
と
MPI_Gather()
(そして
MPI_Bcast
や、その他多数)は
コレクティブ
操作によって呼び出される必要があります。
すべて
のタスクのうち、Communicatorのタスクの コミュニケータ内の全てのプロセッサが同じ呼び出しを行い、操作が実行されます。 (scatterとgatherがパラメータの1つとして、すべてのデータが行き来する"root"プロセスを要求するのはそのためです)。 このようにすることで、MPI実装は通信パターンを最適化する余地が多くあります。
そこで、簡単な例を挙げてみましょう( 更新 を追加し、ギャザーを追加しました)。
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int size, rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int *globaldata=NULL;
int localdata;
if (rank == 0) {
globaldata = malloc(size * sizeof(int) );
for (int i=0; i<size; i++)
globaldata[i] = 2*i+1;
printf("Processor %d has data: ", rank);
for (int i=0; i<size; i++)
printf("%d ", globaldata[i]);
printf("\n");
}
MPI_Scatter(globaldata, 1, MPI_INT, &localdata, 1, MPI_INT, 0, MPI_COMM_WORLD);
printf("Processor %d has data %d\n", rank, localdata);
localdata *= 2;
printf("Processor %d doubling the data, now has %d\n", rank, localdata);
MPI_Gather(&localdata, 1, MPI_INT, globaldata, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0) {
printf("Processor %d has data: ", rank);
for (int i=0; i<size; i++)
printf("%d ", globaldata[i]);
printf("\n");
}
if (rank == 0)
free(globaldata);
MPI_Finalize();
return 0;
}
実行すると、次のようになります。
gpc-f103n084-$ mpicc -o scatter-gather scatter-gather.c -std=c99
gpc-f103n084-$ mpirun -np 4 ./scatter-gather
Processor 0 has data: 1 3 5 7
Processor 0 has data 1
Processor 0 doubling the data, now has 2
Processor 3 has data 7
Processor 3 doubling the data, now has 14
Processor 2 has data 5
Processor 2 doubling the data, now has 10
Processor 1 has data 3
Processor 1 doubling the data, now has 6
Processor 0 has data: 2 6 10 14
関連
-
[解決済み】エラー:cの入力の最後に期待される宣言またはステートメント
-
[解決済み】strcmpが機能しない
-
[解決済み】 `S_ISREG()` とは何ですか、そして何をするのですか?
-
[解決済み】MPI通信でMPI_Bcastを使用する場合
-
[解決済み】0LLや0x0ULの意味は何ですか?
-
[解決済み】宣言指定子で2つ以上のデータ型がある場合のエラー【非公開
-
[解決済み】Makefile:1: ***セパレータがありません。停止します。
-
[解決済み】配列型char[]が代入できない [重複]。
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] C++のヘッダーファイルで#ifndefと#defineが使われているのはなぜですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】ポインタと整数の比較で警告が出る
-
[解決済み】GCC Cコードで静的宣言が非静的宣言に続くことを解決するには?
-
[解決済み】 strcpyとstrdupの比較
-
[解決済み】初期化がキャストなしで整数からポインタを作成 - C言語
-
[解決済み】警告:組み込み関数'printf'の非互換な暗黙の宣言(デフォルトで有効]
-
[解決済み】LinuxのI_PUSHに相当するもの
-
[解決済み】「複数の定義」「最初に定義されたのはここです」エラーについて
-
[解決済み】警告:引数「互換性のないポインタ型から」を渡す[デフォルトで有効]。
-
[解決済み] [Solved] .Cファイルをコンパイルしています。アーキテクチャ x86_64 の未定義シンボル
-
[解決済み】C言語でpow( )への未定義参照、math.hを含むにもかかわらず【重複】。