私のアプリケーションはLAM/MPIで動作しますが、OpenMPIでクラッシュします。対応する非ブロッキングプリミティブがOpenMPIによって許可される前にMPI_Waitを呼び出すか?
以下は私のコードの外観です。
void Comm::nonblocking_send(int s_idx , int e_idx)
{
MPI_Wait(&mpireq,&mpistat);
buffer.clear();
list<class vertex*>::iterator vit;
for(vit=our_dag->cur_block_intmeds.begin() ; vit!=our_dag->cur_block_intmeds.end() ; vit++)
{
vertex * v = (*vit);
list<class edge*> in_edges = v->in_edges;
list<class edge*>::iterator eit;
for(eit=in_edges.begin() ; eit!=in_edges.end() ; eit++)
{
int x_idx = (*eit)->src->idx;
int y_idx = (*eit)->tgt->idx;
double dydx = (*eit)->partial;
struct partial * p = new partial();
//ownership info
p->rank = our_dag->rank;
//structural info
p->x_idx = x_idx;
p->y_idx = y_idx;
p->dydx = dydx;
//block info
p->block_idx = our_dag->block_idx;
p->s_idx = s_idx;
p->e_idx = e_idx;
buffer.push_back(*p);
delete p;
}
}
MPI_Isend(&buffer[0] , buffer.size() , MPI_PARTIAL , 0 , DAG_MERG_REQ , MPI_COMM_WORLD , &mpireq);
}
あなたが見ることができるよう、機能の開始時に、MPI_Waitは、いくつかの演算により、最終的には、関数の最後にそれぞれのMPI_ISendが続く、と呼ばれています。
私はOpenMPIを使用するたびにMPI_Wait内からセグメンテーションフォールトを取得し続けます。
ブール変数* first_time *で初めて関数が呼び出されているかどうかをチェックすることで、この問題を解決しました。
void Comm::nonblocking_send(int s_idx , int e_idx)
{
if(first_time)
first_time = false;
else
MPI_Wait(&mpireq,&mpistat);
buffer.clear();
list<class vertex*>::iterator vit;
for(vit=our_dag->cur_block_intmeds.begin() ; vit!=our_dag->cur_block_intmeds.end() ; vit++)
{
vertex * v = (*vit);
list<class edge*> in_edges = v->in_edges;
list<class edge*>::iterator eit;
for(eit=in_edges.begin() ; eit!=in_edges.end() ; eit++)
{
int x_idx = (*eit)->src->idx;
int y_idx = (*eit)->tgt->idx;
double dydx = (*eit)->partial;
struct partial * p = new partial();
//ownership info
p->rank = our_dag->rank;
//structural info
p->x_idx = x_idx;
p->y_idx = y_idx;
p->dydx = dydx;
//block info
p->block_idx = our_dag->block_idx;
p->s_idx = s_idx;
p->e_idx = e_idx;
buffer.push_back(*p);
delete p;
}
}
MPI_Isend(&buffer[0] , buffer.size() , MPI_PARTIAL , 0 , DAG_MERG_REQ , MPI_COMM_WORLD , &mpireq);
}
ここでは、このエラーについて考えている人はいますか?
乾杯。
この呼び出しの前に 'mpireq'と' mpistat'はどのように使われていますか?どのようにこの機能を呼びますか?すべてのプロセスがそれを呼び出しますか?より多くの文脈が役に立つでしょう。 – suszterpatt
@suszterpattプロセス0を除く各プロセスのこの関数への最初の呼び出しでは、MPI_Waitはユニット化された要求と状態を読み取りますが、次の呼び出しでは、前の呼び出しで対応するMPI_Isendによって初期化されます。 –
初期化されていないデータを決して関数に渡すことはありません。あなたがしたのは基本的に未定義の振る舞いです。あなたはLAM/MPIで幸運になりました。解決策をaswerとして投稿し、それを受け入れてください。 – suszterpatt