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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

MPI

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

C++

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

Q&A

解決済

1回答

758閲覧

MPI_Recvの適切な破棄の方法

Weapon

総合スコア106

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

MPI

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

C++

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

0グッド

0クリップ

投稿2020/11/02 12:29

前提・実現したいこと

以下のようにMPI_Iprobeで取得したMPI_TAGを見てデータの受け取りをするメッセージループを構築したのですが
もし想定外のMPI_TAGが飛んできたときにswitch文のdefaultで受け取るデータを破棄しようとしているのですけどsegmentation faultとなり処理を継続できません.
Iproveで得たデータは破棄しなければ次の処理に進めませんが
(1)このMPI_Cancelの使い方に問題があるのでしょうか?
(2)適切に受け取るデータを破棄するにはどうすればいいのでしょうか?

疑似コード

C

1time_t interval = 10;//variable 2time_t before = time(nullptr); 3while (1) 4{ 5 time_t now = time(nullptr); 6 7 while (now - before > interval) 8 { 9 int flag = 0; 10 MPI_Status ms; 11 MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &ms); 12 13 if (flag == false)break; 14 else 15 { 16 switch (ms.MPI_TAG) 17 { 18 case HOGEHOGE: 19 case PIYOPIYO: 20 { 21 MY_DATA md = { 0 }; 22 MPI_Recv(&md, 1, MPI_MY_DATA, ms.MPI_SOURCE, ms.MPI_TAG, MPI_COMM_WORLD, &ms); 23 goto COMEHERE; 24 } 25 break; 26 default: 27 { 28 MPI_Request rq; 29 MPI_Cancel(&rq); 30 printf("Connection Canceled\r\n"); 31 } 32 33 } 34 } 35 36 before = now; 37 } 38} 39 40COMEHERE:

補足情報

Windows10 Pro Hyper-V Ubuntu 20.04.1
OpenMPI ver.4.0.5

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

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

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

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

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

guest

回答1

0

ベストアンサー

(1)このMPI_Cancelの使い方に問題があるのでしょうか?

はい。端的に言うと、リクエスト情報 rq に有効な情報が入ってない状態でキャンセルを指示しても「何をキャンセルすれば良いか」MPIのライブラリが判断できません。
MPI_Cancelのmanページに次のようにある通り、

A call to MPI_Cancel marks for cancellation a pending, nonblocking communication operation (send or receive).

MPI_Cancelは、自分で発行した MPI_ISend や MPI_IRecv 等の非同期処理をキャンセルするための関数です。
※非同期処理を実行すると、処理の完了を判断する際にキーとなるリクエスト情報が保存されます。

(2)適切に受け取るデータを破棄するにはどうすればいいのでしょうか?

キャンセルは破棄ではありません。
データが不要ということなら、受け取るだけ受け取った上でデータを無視すれば済みます。
あるいは、例えば通信容量の関係でキャンセルが必要ということなら、何らかの手段で送信側に情報を送って、そちらでキャンセルをかけることになるでしょう。
※MPI_IRecvで受信処理だけ発行してキャンセルした場合 ( 受け取り完了前にキャンセルが効いたケース )、送信側は依然送信未完了状態でおかれますので、解決にならないことに注意 ( 上述のmanページの "any matching send has to be satisfied by another receive." )

どのような通信パターンを想定されているか分かりませんが、動的に通信相手を変える ( 各rankの担当する仕事量が可変だとか ) のでもない限り、送信側・受信側とも通信内容は把握しているはずなので、そもそも破棄を考えるということはないように思います。( 同じ理由で MPI_IProbe もまず使わない )

MPI初心者ということであれば、MPI_ISend や MPI_IRecv を使うプログラムの典型例をまず見て慣れた方が良いと思います。( 理研や筑波大等で参考資料は色々あると思います )

投稿2020/11/03 08:53

angel_p_57

総合スコア1672

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

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

Weapon

2020/11/03 15:32

MPIを触れ始めてすぐです Rank0を親としてそれぞれのスレッドでタスクが終了すれば親に次のタスクを振ってもらうようなラッパーをウィンドウプロシージャ風に書いていました.(そもそも科学計算向けのライブラリに汎用的な機能を持たせるのが間違ってるのかもしれませんが)
angel_p_57

2020/11/04 14:09

> それぞれのスレッドでタスクが終了すれば親に次のタスクを振ってもらうようなラッパーをウィンドウプロシージャ風に書いていました. それであれば、rank0 ⇔ その他のrank の通信が都度発生することになるので、tagでの区別は不要な気がします。あくまで「複数の通信の混在」を区別するためですので。割り振るタスクの違いは、データの内容で行えば十分に思えます。 通信パターンとしては、 rank0: 暇なrankがいれば、タスク情報を必要分 isend ( リクエスト情報が rank分できるので配列で保持 )、ランクからの終了通知を irecv して、wait で次のアクションまで待つ 他rank: まず recv でタスク情報を受け取り、タスク処理、sendで終了通知を送る。そしてまた recv でタスク情報を受け取る で良いのではないでしょうか。 もしタスク情報が可変ということなら、他rankで受け取る時に probe して長さを測ってから改めて recv することになります。 ※最後は、「処理完了」を意味するタスク情報を送って、各rankに終了を促すことになると思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問