- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我试图在这个简化的代码中实现的是:
我有这样的代码:
int numprocs, id, arr[10], winner = -1;
bool stop = false;
MPI_Request reqs[10], winnerNotification;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &id);
for (int half = 0; half < 1; half++) {
for (int round = 0; round < 1; round++) {
if (id == 10) { // root
// keeps track of who has "completed"
fill_n(arr, 10, -1);
for (int i = 0; i < 10; i++) {
MPI_Irecv(&arr[i], 1, MPI_INT, i, 0, MPI_COMM_WORLD, &reqs[i]);
}
} else if (id < 10) { // children
// listen to root of winner notification/indication to stop
MPI_Irecv(&winner, 1, MPI_INT, 10, 1, MPI_COMM_WORLD, &winnerNotification);
}
while (winner == -1) {
//cout << id << " is in loop" << endl;
if (id < 10 && !stop && ((rand() % 10) + 1) < 3) {
// children has 20% chance to stop (finish work)
MPI_Send(&id, 1, MPI_INT, 10, 0, MPI_COMM_WORLD);
cout << id << " sending to root" << endl;
stop = true;
} else if (id == 10) {
// root checks number of children completed
int numDone = 0;
for (int i = 0; i < 10; i++) {
if (arr[i] >= 0) {
//cout << "root knows that " << i << " has completed" << endl;
numDone++;
}
}
cout << "numDone = " << numDone << endl;
// if all done, send notification to players to stop
if (numDone == 10) {
winner = 1;
for (int i = 0; i < 10; i++) {
MPI_Send(&winner, 1, MPI_INT, i, 1, MPI_COMM_WORLD);
}
cout << "root sent notification of winner" << endl;
}
}
}
}
}
MPI_Finalize();
调试 cout
的输出看起来像:问题似乎是 root 没有收到所有 child 的完成通知?
2 sending to root
3 sending to root
0 sending to root
4 sending to root
1 sending to root
8 sending to root
9 sending to root
numDone = 1
numDone = 1
... // many numDone = 1, but why 1 only?
7 sending to root
...
我想也许我不能接收到一个数组:但我试过了
if (id == 1) {
int x = 60;
MPI_Send(&x, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
} else if (id == 0) {
MPI_Recv(&arr[1], 1, MPI_INT, 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
cout << id << " recieved " << arr[1] << endl;
}
哪个有效。
更新
如果我在 while 循环结束前添加一个 MPI_Barrier(MPI_COMM_WORLD)
似乎可以解决这个问题,但为什么呢?即使进程不同步,最终,子进程也会将他们已完成的消息发送给 root,而 root 应该“监听”并进行相应处理吗?似乎正在发生的事情是 root 一直在运行,占用所有资源供 children 执行?或者这里发生了什么?
更新 2:一些 child 没有收到来自 root 的通知
好的,现在问题是 root 没有收到 child 的通知,他们已经完成了 @MichaelSh 的回答,我关注的是 child 没有收到 parent 的通知。这是重现该问题的代码:
int numprocs, id, arr[10], winner = -1;
bool stop = false;
MPI_Request reqs[10], winnerNotification;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &id);
srand(time(NULL) + id);
if (id < 10) {
MPI_Irecv(&winner, 1, MPI_INT, 10, 0, MPI_COMM_WORLD, &winnerNotification);
}
MPI_Barrier(MPI_COMM_WORLD);
while (winner == -1) {
cout << id << " is in loop ..." << endl;
if (id == 10) {
if (((rand() % 10) + 1) < 2) {
winner = 2;
for (int i = 0; i < 10; i++) {
MPI_Send(&winner, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
}
cout << "winner notifications sent" << endl;
}
}
}
cout << id << " b4 MPI_Finalize. winner is " << winner << endl;
MPI_Finalize();
输出看起来像:
# 1 run
winner notifications sent
10 b4 MPI_Finalize. winner is 2
9 b4 MPI_Finalize. winner is 2
0 b4 MPI_Finalize. winner is 2
# another run
winner notifications sent
10 b4 MPI_Finalize. winner is 2
8 b4 MPI_Finalize. winner is 2
注意到一些进程似乎没有从父进程那里得到通知?为什么,子进程的 MPI_Wait
只会挂起它们?那么我该如何解决呢?
还有
All
MPI_Barrier
does in your case -- it waits for child responses to complete. Please check my answer for a better solution
如果我不这样做,我想每个 child 的 react 只需要几毫秒?所以即使我不等待/障碍,我希望接收仍然会在发送后不久发生吗?除非进程最终占用资源并且其他进程不运行?
最佳答案
请尝试此代码块(为简单起见省略了错误检查):
...
// root checks number of children completed
int numDone = 0;
MPI_Status statuses[10];
MPI_Waitall(10, reqs, statuses);
for (int i = 0; i < 10; i++) {
...
编辑 更好的解决方案:
每个子节点发起root winner notification receipt并将其通知发送给root。
Root 向数组发起获胜者通知接收并进入等待接收所有通知,然后将获胜者的 id 发送给 child 。在 for (int round = 0; round < 1; round++)
之后插入此代码
if (id == 10)
{ // root
// keeps track of who has "completed"
memset(arr, -1, sizeof(arr));
for (int i = 0; i < 10; i++)
{
MPI_Irecv(&arr[i], 1, MPI_INT, i, 0, MPI_COMM_WORLD, &reqs[i]);
}
}
else if (id < 10)
{ // children
// listen to root of winner notification/indication to stop
MPI_Irecv(&winner, 1, MPI_INT, 10, 1, MPI_COMM_WORLD, &winnerNotification);
}
if (id < 10)
{
while(((rand() % 10) + 1) < 3) ;
// children has 20% chance to stop (finish work)
MPI_Send(&id, 1, MPI_INT, 10, 0, MPI_COMM_WORLD);
std::cout << id << " sending to root" << std::endl;
// receive winner notification
MPI_Status status;
MPI_Wait(&winnerNotification, &status);
// Process winner notification
}
else if (id == 10)
{
MPI_Status statuses[10];
MPI_Waitall(10, reqs, statuses);
// if all done, send notification to players to stop
{
winner = 1;
for (int i = 0; i < 10; i++)
{
MPI_Send(&winner, 1, MPI_INT, i, 1, MPI_COMM_WORLD);
}
std::cout << "root sent notification of winner" << std::endl;
}
}
关于c++ - MPI_Irecv 没有收到所有发送?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13426771/
我的代码可以在我的github上找到: https://github.com/chrismunley/ParallelProgramming/tree/master 我得到的错误是:PGC-W-009
我有这段代码用于测试 MPI_Irecv 和 MPI_Isend if(rank==1){ int cc; MPI_Request request;
我一直在并行执行哲学家就餐问题,但遇到了一个我无法解决的问题。基本上,我有一个 for 循环,其中一个进程检查是否有任何新消息,然后休眠半秒钟(它重复随机次数)。在该部分之后,它会尝试收集所有需要的
来自 OpenMPI 文档:C++ 语法 Request Comm::Irecv(void* buf, int count, const Datatype& datatype, int sou
我试图在这个简化的代码中实现的是: 2 种类型的进程(根进程和子进程,ids/rank 分别为 10 和 0-9) 初始化: root 会听 child “完成” children 将在所有完成后收听
MPI_IRecv(&myArr[0], 5, MPI_INT, 1, MPI_ANY_TAG, MPI_COMM_WORLD, request); MPI_IRecv(&myArr[5], 5, M
我想知道为什么我无法通过 MPI_Recv 命令访问数据。我有一个包含 100 个元素的数组,我想将其分为 8 个进程。由于 100/8 返回不等长度的 block ,因此我手动执行此操作。然后我计算
对于MPI中的异步通信,以下哪个更好(在性能、可靠性、可读性等方面): MPI_Isend with buffer 然后 MPI_Iprobe & MPI_Recv 一旦接收器准备好,或者 带缓冲区的
我有一个一维矩阵数据作为 Q_send_matrix。在每次迭代中,每个处理器更新其Q_send_matrix并将其发送到前一个处理器(rank-1),同时它接收一个新更新的矩阵作为Q_recv_ma
我正在编写一个程序来检测远程机器的突然崩溃。 manager 进程在机器 1 上运行,worker 进程在机器 2 上运行。 manager 服务器通过调用 MPI_Isend 向工作进程发送消息。
我想了解 MPI 如何处理发送和接收。假设我分配一个 [12][50] 元素的缓冲区,如下所示: int **buf= malloc(12 * sizeof(int *)); for (i = 0;
我对两个 MPI_Irecv 使用了 2 个 MPI_Irecv,然后是 2 个 MPI_Send,然后是 MPI_Waitall,如下所示。经过几次计算后,我再次编写了相同的代码块。但 MPI 进程
MPI_Isend 和 MPI_Irecv 有问题。我正在研究按行分布的图的邻接矩阵。我们可以假设每个处理器包含一行。对于每对索引 (i,j) 我需要发送和接收 2 个整数。基本上,我需要从其他行接收
我在使用 C 语言的 MPI 程序时遇到了一些问题。我想使用 MPI_Send 从从站向主站发送两条消息(使用 MPI_Send、MPI_Irecv 和 MPI_Test),但只有第一条消息有效。在那
当我尝试在四个处理器上运行一个问题时收到以下错误序列。我使用的 MPI 命令是 mpirun -np 4 我很抱歉按原样发布错误消息(主要是由于缺乏破译给定信息的知识)。感谢您在以下方面的意见: 错误
我有一个项目,我需要使用 MPI_Isend 和 MPI_Irecv 对 MPI_Bcast 的任何错误实现进行计时,并将其与 MPI_Bcast 进行比较。因为这些程序的时间是 0.000000 秒
我正在学习 c 中的 mpi 通信。我在尝试使用 MPI_Isend 从一个节点发送消息并使用 MPI_Irecv 在另一个节点上接收它时遇到问题。这是代码: #include #include
我想运行一个程序来了解 MPI_Isend 和 MPI_Irecv 的工作原理。等级 0 的 Isend 和 Irecv 工作正常,但等级 5 的 Irecv 采用默认值。有人可以向我解释一下吗? #
我是一名优秀的程序员,十分优秀!