MPI で個々のスレッドからグローバル ベクトルにアクセスするにはどうすればよいですか?
CVODE ( SUNDIALSの一部) と呼ばれるライブラリ、具体的には ODE ソルバー ライブラリを使用しています。ライブラリは MPI で動作するため、複数のスレッドが並行して実行されます。それらはすべて同じコードを実行しています。各スレッドは、「隣の」スレッドにデータを送信します。しかし、スレッドの 1 つ (ランク = 0) が、ある時点でデータの状態を出力するようにします。
ライブラリには、各スレッドが独自のデータ (ローカル ベクトル) にアクセスできるようにする関数が含まれています。しかし、グローバルベクトルにアクセスする方法はありません。
特定の時間にすべての方程式の値を出力する必要があります。そのためには、グローバル ベクトルにアクセスする必要があります。MPI ベクトル内のすべてのデータを取得する方法を知っている人はいますか (可能であれば CVODE を使用)。
たとえば、各スレッドが実行する私のコードは次のとおりです
for (iout=1, tout=T1; iout <= NOUT; iout++, tout += DTOUT) {
flag = CVode(cvode_mem, tout, u, &t, CV_NORMAL);
if(check_flag(&flag, "CVode", 1, my_pe)) break;
if (my_pe == 0) PrintData(t, u);
}
...
static void PrintData(realtype t, N_Vector u) {
I want to print data from all threads in here
}
関数f
(私が解いている関数) では、 and を使用してデータをやり取りしMPI_Send
ますMPI_Recv
。しかし、他のプロセスが先に実行されているため、PrintData で実際にそれを行うことはできません。また、メッセージングのオーバーヘッドを追加したくありません。のグローバル ベクトルにアクセスして、PrintData
必要なものを出力したいだけです。出来ますか?
編集:より良い答えを待っている間、データを0番目のスレッドに戻す各スレッドをプログラムしました。メッセージングのオーバーヘッドが増えすぎているとは思いませんが、より良い方法があれば、専門家の意見を聞きたいです (悪い方法はないと確信しています! :D )。
編集 2 : angainor のソリューションは確かに優れていますが、私が作成したものに固執しました。同じ質問をした人の将来の参考のために、ここに私がそれをした方法の基本があります:
/* Is called by all threads */
static void PrintData(realtype t, N_Vector u, UserData data) {
... declarations and such ...
for (n=1; n<=my_length; n++) {
mass_num = my_base + n;
z[mass_num - 1] = udata[n-1];
z[mass_num - 1 + N] = udata[n - 1 + my_length];
}
if (my_pe != 0) {
MPI_Send(&z, 2*N, PVEC_REAL_MPI_TYPE, 0, my_pe, comm);
} else {
for (i=1; i<npes; i++) {
MPI_Recv(&z1, 2*N, PVEC_REAL_MPI_TYPE, i, i, comm, &status);
for (n=0; n<2*N; n++)
z[n] = z[n] + z1[n];
}
... now I can print it out however I like...
return;
}