Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' into adrien
[simgrid.git] / teshsuite / smpi / mpich3-test / pt2pt / pscancel.c
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  *  (C) 2003 by Argonne National Laboratory.
4  *      See COPYRIGHT in top-level directory.
5  */
6 #include "mpi.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "mpitest.h"
10
11 /*
12 static char MTEST_Descrip[] = "Test of various send cancel calls";
13 */
14
15 int main(int argc, char *argv[])
16 {
17     int errs = 0;
18     int rank, size, dest;
19     MPI_Comm comm;
20     MPI_Status status;
21     MPI_Request req;
22     static int bufsizes[4] = { 1, 100, 10000, 1000000 };
23     char *buf;
24     int cs, flag, n;
25 #ifdef TEST_IRSEND
26     int veryPicky = 0;          /* Set to 1 to test "quality of implementation" in
27                                  * a tricky part of cancel */
28 #endif
29
30     MTest_Init(&argc, &argv);
31
32     comm = MPI_COMM_WORLD;
33     MPI_Comm_rank(comm, &rank);
34     MPI_Comm_size(comm, &size);
35
36     dest = size - 1;
37
38     for (cs = 0; cs < 4; cs++) {
39         if (rank == 0) {
40             n = bufsizes[cs];
41             buf = (char *) malloc(n);
42             if (!buf) {
43                 fprintf(stderr, "Unable to allocate %d bytes\n", n);
44                 MPI_Abort(MPI_COMM_WORLD, 1);
45             }
46             MPI_Send_init(buf, n, MPI_CHAR, dest, cs + n + 1, comm, &req);
47             MPI_Start(&req);
48             MPI_Cancel(&req);
49             MPI_Wait(&req, &status);
50             MPI_Test_cancelled(&status, &flag);
51             if (!flag) {
52                 errs++;
53                 printf("Failed to cancel a persistent send request\n");
54                 fflush(stdout);
55             }
56             else {
57                 n = 0;
58             }
59             MPI_Request_free(&req);
60             /* Send the size, zero for successfully cancelled */
61             MPI_Send(&n, 1, MPI_INT, dest, 123, comm);
62             /* Send the tag so the message can be received */
63             n = cs + n + 1;
64             MPI_Send(&n, 1, MPI_INT, dest, 123, comm);
65             free(buf);
66         }
67         else if (rank == dest) {
68             int nn, tag;
69             char *btemp;
70             MPI_Recv(&nn, 1, MPI_INT, 0, 123, comm, &status);
71             MPI_Recv(&tag, 1, MPI_INT, 0, 123, comm, &status);
72             if (nn > 0) {
73                 /* If the message was not cancelled, receive it here */
74                 btemp = (char *) malloc(nn);
75                 if (!btemp) {
76                     fprintf(stderr, "Unable to allocate %d bytes\n", nn);
77                     MPI_Abort(MPI_COMM_WORLD, 1);
78                 }
79                 MPI_Recv(btemp, nn, MPI_CHAR, 0, tag, comm, &status);
80                 free(btemp);
81             }
82         }
83         MPI_Barrier(comm);
84
85         if (rank == 0) {
86             char *bsendbuf;
87             int bsendbufsize;
88             int bf, bs;
89             n = bufsizes[cs];
90             buf = (char *) malloc(n);
91             if (!buf) {
92                 fprintf(stderr, "Unable to allocate %d bytes\n", n);
93                 MPI_Abort(MPI_COMM_WORLD, 1);
94             }
95             bsendbufsize = n + MPI_BSEND_OVERHEAD;
96             bsendbuf = (char *) malloc(bsendbufsize);
97             if (!bsendbuf) {
98                 fprintf(stderr, "Unable to allocate %d bytes for bsend\n", n);
99                 MPI_Abort(MPI_COMM_WORLD, 1);
100             }
101             MPI_Buffer_attach(bsendbuf, bsendbufsize);
102             MPI_Bsend_init(buf, n, MPI_CHAR, dest, cs + n + 2, comm, &req);
103             MPI_Start(&req);
104             MPI_Cancel(&req);
105             MPI_Wait(&req, &status);
106             MPI_Test_cancelled(&status, &flag);
107             if (!flag) {
108                 errs++;
109                 printf("Failed to cancel a persistent bsend request\n");
110                 fflush(stdout);
111             }
112             else {
113                 n = 0;
114             }
115             MPI_Request_free(&req);
116             /* Send the size, zero for successfully cancelled */
117             MPI_Send(&n, 1, MPI_INT, dest, 123, comm);
118             /* Send the tag so the message can be received */
119             n = cs + n + 2;
120             MPI_Send(&n, 1, MPI_INT, dest, 123, comm);
121             free(buf);
122             MPI_Buffer_detach(&bf, &bs);
123             free(bsendbuf);
124         }
125         else if (rank == dest) {
126             int nn, tag;
127             char *btemp;
128             MPI_Recv(&nn, 1, MPI_INT, 0, 123, comm, &status);
129             MPI_Recv(&tag, 1, MPI_INT, 0, 123, comm, &status);
130             if (nn > 0) {
131                 /* If the message was not cancelled, receive it here */
132                 btemp = (char *) malloc(nn);
133                 if (!btemp) {
134                     fprintf(stderr, "Unable to allocate %d bytes\n", nn);
135                     MPI_Abort(MPI_COMM_WORLD, 1);
136                 }
137                 MPI_Recv(btemp, nn, MPI_CHAR, 0, tag, comm, &status);
138                 free(btemp);
139             }
140         }
141         MPI_Barrier(comm);
142
143         /* Because this test is erroneous, we do not perform it unless
144          * TEST_IRSEND is defined.  */
145 #ifdef TEST_IRSEND
146         /* We avoid ready send to self because an implementation
147          * is free to detect the error in delivering a message to
148          * itself without a pending receive; we could also check
149          * for an error return from the MPI_Irsend */
150         if (rank == 0 && dest != rank) {
151             n = bufsizes[cs];
152             buf = (char *) malloc(n);
153             if (!buf) {
154                 fprintf(stderr, "Unable to allocate %d bytes\n", n);
155                 MPI_Abort(MPI_COMM_WORLD, 1);
156             }
157             MPI_Rsend_init(buf, n, MPI_CHAR, dest, cs + n + 3, comm, &req);
158             MPI_Start(&req);
159             MPI_Cancel(&req);
160             MPI_Wait(&req, &status);
161             MPI_Test_cancelled(&status, &flag);
162             /* This can be pretty ugly.  The standard is clear (Section 3.8)
163              * that either a sent message is received or the
164              * sent message is successfully cancelled.  Since this message
165              * can never be received, the cancel must complete
166              * successfully.
167              *
168              * However, since there is no matching receive, this
169              * program is erroneous.  In this case, we can't really
170              * flag this as an error */
171             if (!flag && veryPicky) {
172                 errs++;
173                 printf("Failed to cancel a persistent rsend request\n");
174                 fflush(stdout);
175             }
176             if (flag) {
177                 n = 0;
178             }
179             MPI_Request_free(&req);
180             /* Send the size, zero for successfully cancelled */
181             MPI_Send(&n, 1, MPI_INT, dest, 123, comm);
182             /* Send the tag so the message can be received */
183             n = cs + n + 3;
184             MPI_Send(&n, 1, MPI_INT, dest, 123, comm);
185             free(buf);
186         }
187         else if (rank == dest) {
188             int n, tag;
189             char *btemp;
190             MPI_Recv(&n, 1, MPI_INT, 0, 123, comm, &status);
191             MPI_Recv(&tag, 1, MPI_INT, 0, 123, comm, &status);
192             if (n > 0) {
193                 /* If the message was not cancelled, receive it here */
194                 btemp = (char *) malloc(n);
195                 if (!btemp) {
196                     fprintf(stderr, "Unable to allocate %d bytes\n", n);
197                     MPI_Abort(MPI_COMM_WORLD, 1);
198                 }
199                 MPI_Recv(btemp, n, MPI_CHAR, 0, tag, comm, &status);
200                 free(btemp);
201             }
202         }
203         MPI_Barrier(comm);
204 #endif
205
206         if (rank == 0) {
207             n = bufsizes[cs];
208             buf = (char *) malloc(n);
209             if (!buf) {
210                 fprintf(stderr, "Unable to allocate %d bytes\n", n);
211                 MPI_Abort(MPI_COMM_WORLD, 1);
212             }
213             MPI_Ssend_init(buf, n, MPI_CHAR, dest, cs + n + 4, comm, &req);
214             MPI_Start(&req);
215             MPI_Cancel(&req);
216             MPI_Wait(&req, &status);
217             MPI_Test_cancelled(&status, &flag);
218             if (!flag) {
219                 errs++;
220                 printf("Failed to cancel a persistent ssend request\n");
221                 fflush(stdout);
222             }
223             else {
224                 n = 0;
225             }
226             MPI_Request_free(&req);
227             /* Send the size, zero for successfully cancelled */
228             MPI_Send(&n, 1, MPI_INT, dest, 123, comm);
229             /* Send the tag so the message can be received */
230             n = cs + n + 4;
231             MPI_Send(&n, 1, MPI_INT, dest, 123, comm);
232             free(buf);
233         }
234         else if (rank == dest) {
235             int nn, tag;
236             char *btemp;
237             MPI_Recv(&nn, 1, MPI_INT, 0, 123, comm, &status);
238             MPI_Recv(&tag, 1, MPI_INT, 0, 123, comm, &status);
239             if (nn > 0) {
240                 /* If the message was not cancelled, receive it here */
241                 btemp = (char *) malloc(nn);
242                 if (!btemp) {
243                     fprintf(stderr, "Unable to allocate %d bytes\n", nn);
244                     MPI_Abort(MPI_COMM_WORLD, 1);
245                 }
246                 MPI_Recv(btemp, nn, MPI_CHAR, 0, tag, comm, &status);
247                 free(btemp);
248             }
249         }
250         MPI_Barrier(comm);
251     }
252
253     MTest_Finalize(errs);
254     MPI_Finalize();
255     return 0;
256 }