Multithreading 我的mpi程序的行为是随机的
我有一个行为随机的mpi程序,有时正常完成,而其他程序挂起,我在每个进程中创建一个额外的线程。我不知道会发生什么事。 以下是代码摘要:Multithreading 我的mpi程序的行为是随机的,multithreading,mpi,Multithreading,Mpi,我有一个行为随机的mpi程序,有时正常完成,而其他程序挂起,我在每个进程中创建一个额外的线程。我不知道会发生什么事。 以下是代码摘要: void* listen(void * args) { int id = ((__arg *) (args))->id; while (true) { MPI_Status status; MPI_Recv(&sender, 1, MPI_INT, MPI_ANY_SOURCE, 10000 + id
void* listen(void * args) {
int id = ((__arg *) (args))->id;
while (true) {
MPI_Status status;
MPI_Recv(&sender, 1, MPI_INT, MPI_ANY_SOURCE, 10000 + id, MPI_COMM_WORLD, &status);
if (sender >= 90000) {
// ...
} else {
MPI_Recv(&node, 1, MPI_INT, sender, 30000 + id, MPI_COMM_WORLD, &status);
int n = 3;//change later
MPI_Send(&n, 1, MPI_INT, sender, 20000 + sender, MPI_COMM_WORLD);
}
}
return NULL;
}
int main(int argc, char* argv[]) {
MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
pthread_t tid;
__arg args;
args.id = rank;
args.np = size;
pthread_create(&tid, NULL, &listen, (void *) (&args));
for (int s_aux = 0; s_aux < local_vertex_count; ++s_aux) {
int s = size * s_aux + rank;
queue<int> Q;
Q.push(s);
while (!Q.empty()) {
int v = Q.front();
Q.pop();
int own = v % size;
int idxv = v / size;
if (own == rank) {
//...
}
else {// send message to owner
MPI_Send(&rank, 1, MPI_INT, own, 10000 + own, MPI_COMM_WORLD);
MPI_Send(&v, 1, MPI_INT, own, 30000 + own, MPI_COMM_WORLD);
int neighbors;
MPI_Status status;
MPI_Recv(&neighbors, 1, MPI_INT, own, 20000 + rank, MPI_COMM_WORLD, &status);
}//send message to owner
}// while (!Q.epmty())
}
//tell all processes to finish
for (int i = 0; i < size; ++i) {
int buf = 90000 + rank;
MPI_Send((void*) &buf, 1, MPI_INT, i, 10000 + i, MPI_COMM_WORLD);
}
pthread_join(tid, NULL);
MPI_Finalize();
return 0;
}
void*侦听(void*args){
int id=((u arg*)(args))->id;
while(true){
MPI_状态;
MPI_Recv(&sender,1,MPI_INT,MPI_ANY_SOURCE,10000+id,MPI_COMM_WORLD,&status);
如果(发送方>=90000){
// ...
}否则{
MPI_Recv(&node,1,MPI_INT,sender,30000+id,MPI_COMM_WORLD,&status);
int n=3;//稍后更改
MPI_发送(&n,1,MPI_INT,发送方,20000+发送方,MPI_通信世界);
}
}
返回NULL;
}
int main(int argc,char*argv[]){
MPI_Init_线程(&argc,&argv,MPI_线程多个,&provided);
int等级、大小;
MPI通信等级(MPI通信世界和等级);
MPI_通信大小(MPI_通信世界和大小);
pthread_t tid;
__精氨酸精氨酸;
args.id=等级;
args.np=大小;
pthread_创建(&tid,NULL,&listen,(void*)(&args));
对于(int s_aux=0;s_aux
您的代码并不容易理解,您是否可以将其简化或用文字解释,它应该做什么?您推到队列中的s
是什么?而且,我只看到每个队列一次推送…我尝试做的是BFS,s
是全局顶点索引。加载图形时,进程I的顶点为k*size+I(size是进程数)。在BFS中,我们必须推送当前顶点的所有邻居,如果当前顶点不属于当前进程,我要求正确的进程发送该顶点的邻居。我在每个MPI进程中创建一个线程来响应其他进程的请求。我不知道问题是否来自于混合线程和MPI。我的第一个猜测是不匹配的消息。或者,一个队列的元素用完了,然后(从另一个进程)获取新元素。由于(!Q.empty())时循环已终止,因此将不会处理这些。看起来您正在使用阻止邻居之间的发送-接收,但发送/接收顺序没有明确的顺序。如果它们没有按特定顺序发送/接收,您可能会被锁定,其中所有任务都在接收,而没有响应。对于这种情况,您可能应该对通信进行排序,或者查看非阻塞发送/接收。否则,一个并行调试器(Totalview或其他东西)此时可能会派上用场)我发现这一行MPI_Recv(&neights,1,MPI_INT,own,20000+秩,MPI_COMM_WORLD,&status)
是有问题的,如果我对它进行注释,它可以正常工作,但我仍然无法找出该Recv有什么问题