我在尝试在下面的代码中实现非阻塞发送和接收时遇到麻烦,并且遇到此错误:
16 Reading <edge192x128.pgm>
17 Rank 2 [Sat Apr 28 11:24:58 2018] [c6-0c0s13n1] Fatal error in PMPI_Wait: Request pending due to failure, error stack:
18 PMPI_Wait(207): MPI_Wait(request=0x7ffffff95534, status=0x7fffffff74b0) failed
19 PMPI_Wait(158): Invalid MPI_Request
20 Rank 3 [Sat Apr 28 11:24:58 2018] [c6-0c0s13n1] Fatal error in PMPI_Wait: Request pending due to failure, error stack:
21 PMPI_Wait(207): MPI_Wait(request=0x7ffffff95534, status=0x7fffffff74b0) failed
22 PMPI_Wait(158): Invalid MPI_Request
23 _pmiu_daemon(SIGCHLD): [NID 01205] [c6-0c0s13n1] [Sat Apr 28 11:24:58 2018] PE RANK 2 exit signal Aborted
24 [NID 01205] 2018-04-28 11:24:58 Apid 30656034: initiated application termination
25 Application 30656034 exit codes: 134
26 Application 30656034 resources: utime ~0s, stime ~0s, Rss ~7452, inblocks ~7926, outblocks ~19640
我的程序尝试执行以下操作(此示例假设4个过程):
根进程将图像文件作为二维数组PM x PN读入masterbuf中;
根进程使用MPI_Issend将masterbuf的小节(PM / 2 x PN / 2)传输到所有4个进程(包括其自身)。我使用了strided数据类型将原始数组分为4个部分。
所有进程都使用MPI_Irecv将PM / 2 x PN / 2子节存储在自己的buf副本中。
调用MPI_Wait是为了防止程序在数据分发完成之前继续运行(我知道我可以在这里使用MPI_Waitall,在完成这项工作之后我打算这样做)。
我已经玩了几个小时的代码,只是无法解决此问题,因此将不胜感激。代码如下。我删除了一些不相关的块。
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <mpi.h>
4 #include <math.h>
5 #include "pgmio.h"
6
7 #define M 192
8 #define N 128
9
10 #define PX 2 // number of processes in X dimension
11 #define PY 2 // number of processes in Y dimension
12 #define MP M/PX
13 #define NP N/PY
14
15
16 #define FILEIN "edge192x128.pgm"
17 #define FILEOUT "ex7_0_192x128.pgm"
18
19 int main(int argc, char **argv)
20 {
21 double buf[MP][NP];
22 double old[MP + 2][NP + 2];
23 double new[MP + 2][NP + 2];
24 double edge[MP + 2][NP + 2];
25 double masterbuf[M][N];
26 double delta, delta_max, master_delta;
27
28 int rank, cart_rank, size, left, right, up, down, iter;
29 int dims[] = {2, 2};
30 int periods[] = {0, 0};
31 int reorder = 0;
32 int tag = 0;
33
34 MPI_Status status;
35 MPI_Comm comm = MPI_COMM_WORLD;
36 MPI_Comm cart_comm;
37
38 /* initialise MPI */
39 MPI_Init(&argc, &argv);
40 MPI_Comm_size(comm, &size);
41 MPI_Comm_rank(comm, &rank);
42 MPI_Request request[2 * size];
43 int coords[size][2];
44
45 /* initialise cartesian topology */
46 MPI_Cart_create(comm, 2, dims, periods, reorder, &cart_comm);
47 MPI_Comm_rank(cart_comm, &cart_rank);
48 MPI_Cart_shift(cart_comm, 1, 1, &left, &right);
49 MPI_Cart_shift(cart_comm, 0, 1, &up, &down);
50 printf("cart_rank: %d\n", cart_rank);
51
56
57 /* create block datatype for allocation of subsections of image to processes */
58 MPI_Datatype MPI_block;
59 MPI_Type_vector(M / PX, N / PY, N, MPI_DOUBLE, &MPI_block);
60 MPI_Type_commit(&MPI_block);
61
73
74 /* master process: read edges data file into masterbuff and distribute */
75 if (rank == 0)
76 {
77 printf("Reading <%s>\n", FILEIN);
78 pgmread(FILEIN, masterbuf, M, N);
79
80 printf("Distributing data to processes...\n");
81 for (int i = 0; i < size; i++)
82 {
83 /* send chunk to each process: i refers to cart_rank */
84 MPI_Cart_coords(cart_comm, i, 2, &coords[i][0]);
85 printf("coords = (%d, %d), rank = %d\n", coords[i][0], coords[i][1], \
86 cart_rank);
87 MPI_Issend(&masterbuf[coords[i][0] * MP][coords[i][1] * NP], MP * NP, \
88 MPI_block, i, tag, cart_comm, &request[i]);
89 }
90
91 MPI_Wait(&request[0], &status);
92 MPI_Wait(&request[1], &status);
93 MPI_Wait(&request[2], &status);
94 MPI_Wait(&request[3], &status);
95 }
96
97 /* all processes: receive data sent by master process */
98 MPI_Irecv(buf, MP * NP, MPI_block, cart_rank, tag, cart_comm, \
99 &request[cart_rank + size]);
100
101 /* Could change this to MPI_Waitall */
102 MPI_Wait(&request[5], &status);
103 MPI_Wait(&request[4], &status);
104 MPI_Wait(&request[7], &status);
105 MPI_Wait(&request[6], &status);
106
107 if (rank == 0)
108 {
109 printf("...complete.\n");
110 }
最佳答案
当等级0
发送至自身且尚未发布任何接收时,您的应用程序死锁。
此外,还有4
MPI_Wait()
,但只有一个MPI_Recv()
。
附带说明,您可以MPI_Waitall()
而不是调用多个连续的MPI_Wait()
。
关于c - MPI_Wait:由于失败而挂起的请求,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50075763/