1 /*
2  * Copyright (C) by Argonne National Laboratory
3  *     See COPYRIGHT in top-level directory
4  */
5 
6 /* This is a very weak sanity test that all nonblocking collectives specified by
7  * MPI-3 are present in the library and take arguments as expected.  This test
8  * does not check for progress, matching issues, or sensible output buffer
9  * values. */
10 
11 #include "mpi.h"
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include "mpitest.h"
15 
16 #define NUM_INTS (2)
17 
18 #define my_assert(cond_)                                                  \
19     do {                                                                  \
20         if (!(cond_)) {                                                   \
21             fprintf(stderr, "assertion (%s) failed, aborting\n", #cond_); \
22             MPI_Abort(MPI_COMM_WORLD, 1);                                 \
23         }                                                                 \
24     } while (0)
25 
main(int argc,char ** argv)26 int main(int argc, char **argv)
27 {
28     int errs = 0;
29     int i;
30     int rank, size;
31     int *sbuf = NULL;
32     int *rbuf = NULL;
33     int *scounts = NULL;
34     int *rcounts = NULL;
35     int *sdispls = NULL;
36     int *rdispls = NULL;
37     MPI_Datatype *types = NULL;
38     MPI_Comm comm;
39     MPI_Request req;
40 
41     MTest_Init(&argc, &argv);
42 
43     comm = MPI_COMM_WORLD;
44 
45     MPI_Comm_size(comm, &size);
46     MPI_Comm_rank(comm, &rank);
47 
48     /* enough space for every process to contribute at least NUM_INTS ints to any
49      * collective operation */
50     sbuf = malloc(NUM_INTS * size * sizeof(int));
51     my_assert(sbuf);
52     rbuf = malloc(NUM_INTS * size * sizeof(int));
53     my_assert(rbuf);
54     scounts = malloc(size * sizeof(int));
55     my_assert(scounts);
56     rcounts = malloc(size * sizeof(int));
57     my_assert(rcounts);
58     sdispls = malloc(size * sizeof(int));
59     my_assert(sdispls);
60     rdispls = malloc(size * sizeof(int));
61     my_assert(rdispls);
62     types = malloc(size * sizeof(MPI_Datatype));
63     my_assert(types);
64 
65     for (i = 0; i < size; ++i) {
66         sbuf[2 * i] = i;
67         sbuf[2 * i + 1] = i;
68         rbuf[2 * i] = i;
69         rbuf[2 * i + 1] = i;
70         scounts[i] = NUM_INTS;
71         rcounts[i] = NUM_INTS;
72         sdispls[i] = i * NUM_INTS;
73         rdispls[i] = i * NUM_INTS;
74         types[i] = MPI_INT;
75     }
76 
77     MPI_Ibarrier(comm, &req);
78     MPI_Wait(&req, MPI_STATUS_IGNORE);
79 
80     MPI_Ibcast(sbuf, NUM_INTS, MPI_INT, 0, comm, &req);
81     MPI_Wait(&req, MPI_STATUS_IGNORE);
82 
83     MPI_Igather(sbuf, NUM_INTS, MPI_INT, rbuf, NUM_INTS, MPI_INT, 0, comm, &req);
84     MPI_Wait(&req, MPI_STATUS_IGNORE);
85 
86     if (0 == rank)
87         MPI_Igather(MPI_IN_PLACE, -1, MPI_DATATYPE_NULL, rbuf, NUM_INTS, MPI_INT, 0, comm, &req);
88     else
89         MPI_Igather(sbuf, NUM_INTS, MPI_INT, rbuf, NUM_INTS, MPI_INT, 0, comm, &req);
90     MPI_Wait(&req, MPI_STATUS_IGNORE);
91 
92     MPI_Igatherv(sbuf, NUM_INTS, MPI_INT, rbuf, rcounts, rdispls, MPI_INT, 0, comm, &req);
93     MPI_Wait(&req, MPI_STATUS_IGNORE);
94 
95     if (0 == rank)
96         MPI_Igatherv(MPI_IN_PLACE, -1, MPI_DATATYPE_NULL, rbuf, rcounts, rdispls, MPI_INT, 0, comm,
97                      &req);
98     else
99         MPI_Igatherv(sbuf, NUM_INTS, MPI_INT, rbuf, rcounts, rdispls, MPI_INT, 0, comm, &req);
100     MPI_Wait(&req, MPI_STATUS_IGNORE);
101 
102     MPI_Iscatter(sbuf, NUM_INTS, MPI_INT, rbuf, NUM_INTS, MPI_INT, 0, comm, &req);
103     MPI_Wait(&req, MPI_STATUS_IGNORE);
104 
105     if (0 == rank)
106         MPI_Iscatter(sbuf, NUM_INTS, MPI_INT, MPI_IN_PLACE, -1, MPI_DATATYPE_NULL, 0, comm, &req);
107     else
108         MPI_Iscatter(sbuf, NUM_INTS, MPI_INT, rbuf, NUM_INTS, MPI_INT, 0, comm, &req);
109     MPI_Wait(&req, MPI_STATUS_IGNORE);
110 
111     MPI_Iscatterv(sbuf, scounts, sdispls, MPI_INT, rbuf, NUM_INTS, MPI_INT, 0, comm, &req);
112     MPI_Wait(&req, MPI_STATUS_IGNORE);
113 
114     if (0 == rank)
115         MPI_Iscatterv(sbuf, scounts, sdispls, MPI_INT, MPI_IN_PLACE, -1, MPI_DATATYPE_NULL, 0, comm,
116                       &req);
117     else
118         MPI_Iscatterv(sbuf, scounts, sdispls, MPI_INT, rbuf, NUM_INTS, MPI_INT, 0, comm, &req);
119     MPI_Wait(&req, MPI_STATUS_IGNORE);
120 
121     MPI_Iallgather(sbuf, NUM_INTS, MPI_INT, rbuf, NUM_INTS, MPI_INT, comm, &req);
122     MPI_Wait(&req, MPI_STATUS_IGNORE);
123 
124     MPI_Iallgather(MPI_IN_PLACE, -1, MPI_DATATYPE_NULL, rbuf, NUM_INTS, MPI_INT, comm, &req);
125     MPI_Wait(&req, MPI_STATUS_IGNORE);
126 
127     MPI_Iallgatherv(sbuf, NUM_INTS, MPI_INT, rbuf, rcounts, rdispls, MPI_INT, comm, &req);
128     MPI_Wait(&req, MPI_STATUS_IGNORE);
129 
130     MPI_Iallgatherv(MPI_IN_PLACE, -1, MPI_DATATYPE_NULL, rbuf, rcounts, rdispls, MPI_INT, comm,
131                     &req);
132     MPI_Wait(&req, MPI_STATUS_IGNORE);
133 
134     MPI_Ialltoall(sbuf, NUM_INTS, MPI_INT, rbuf, NUM_INTS, MPI_INT, comm, &req);
135     MPI_Wait(&req, MPI_STATUS_IGNORE);
136 
137     MPI_Ialltoall(MPI_IN_PLACE, -1, MPI_DATATYPE_NULL, rbuf, NUM_INTS, MPI_INT, comm, &req);
138     MPI_Wait(&req, MPI_STATUS_IGNORE);
139 
140     MPI_Ialltoallv(sbuf, scounts, sdispls, MPI_INT, rbuf, rcounts, rdispls, MPI_INT, comm, &req);
141     MPI_Wait(&req, MPI_STATUS_IGNORE);
142 
143     MPI_Ialltoallv(MPI_IN_PLACE, NULL, NULL, MPI_DATATYPE_NULL, rbuf, rcounts, rdispls, MPI_INT,
144                    comm, &req);
145     MPI_Wait(&req, MPI_STATUS_IGNORE);
146 
147     MPI_Ialltoallw(sbuf, scounts, sdispls, types, rbuf, rcounts, rdispls, types, comm, &req);
148     MPI_Wait(&req, MPI_STATUS_IGNORE);
149 
150     MPI_Ialltoallw(MPI_IN_PLACE, NULL, NULL, NULL, rbuf, rcounts, rdispls, types, comm, &req);
151     MPI_Wait(&req, MPI_STATUS_IGNORE);
152 
153     MPI_Ireduce(sbuf, rbuf, NUM_INTS, MPI_INT, MPI_SUM, 0, comm, &req);
154     MPI_Wait(&req, MPI_STATUS_IGNORE);
155 
156     if (0 == rank)
157         MPI_Ireduce(MPI_IN_PLACE, rbuf, NUM_INTS, MPI_INT, MPI_SUM, 0, comm, &req);
158     else
159         MPI_Ireduce(sbuf, rbuf, NUM_INTS, MPI_INT, MPI_SUM, 0, comm, &req);
160     MPI_Wait(&req, MPI_STATUS_IGNORE);
161 
162     MPI_Iallreduce(sbuf, rbuf, NUM_INTS, MPI_INT, MPI_SUM, comm, &req);
163     MPI_Wait(&req, MPI_STATUS_IGNORE);
164 
165     MPI_Iallreduce(MPI_IN_PLACE, rbuf, NUM_INTS, MPI_INT, MPI_SUM, comm, &req);
166     MPI_Wait(&req, MPI_STATUS_IGNORE);
167 
168     MPI_Ireduce_scatter(sbuf, rbuf, rcounts, MPI_INT, MPI_SUM, comm, &req);
169     MPI_Wait(&req, MPI_STATUS_IGNORE);
170 
171     MPI_Ireduce_scatter(MPI_IN_PLACE, rbuf, rcounts, MPI_INT, MPI_SUM, comm, &req);
172     MPI_Wait(&req, MPI_STATUS_IGNORE);
173 
174     MPI_Ireduce_scatter_block(sbuf, rbuf, NUM_INTS, MPI_INT, MPI_SUM, comm, &req);
175     MPI_Wait(&req, MPI_STATUS_IGNORE);
176 
177     MPI_Ireduce_scatter_block(MPI_IN_PLACE, rbuf, NUM_INTS, MPI_INT, MPI_SUM, comm, &req);
178     MPI_Wait(&req, MPI_STATUS_IGNORE);
179 
180     MPI_Iscan(sbuf, rbuf, NUM_INTS, MPI_INT, MPI_SUM, comm, &req);
181     MPI_Wait(&req, MPI_STATUS_IGNORE);
182 
183     MPI_Iscan(MPI_IN_PLACE, rbuf, NUM_INTS, MPI_INT, MPI_SUM, comm, &req);
184     MPI_Wait(&req, MPI_STATUS_IGNORE);
185 
186     MPI_Iexscan(sbuf, rbuf, NUM_INTS, MPI_INT, MPI_SUM, comm, &req);
187     MPI_Wait(&req, MPI_STATUS_IGNORE);
188 
189     MPI_Iexscan(MPI_IN_PLACE, rbuf, NUM_INTS, MPI_INT, MPI_SUM, comm, &req);
190     MPI_Wait(&req, MPI_STATUS_IGNORE);
191 
192     if (sbuf)
193         free(sbuf);
194     if (rbuf)
195         free(rbuf);
196     if (scounts)
197         free(scounts);
198     if (rcounts)
199         free(rcounts);
200     if (sdispls)
201         free(sdispls);
202     if (rdispls)
203         free(rdispls);
204     if (types)
205         free(types);
206 
207     MTest_Finalize(errs);
208     return MTestReturnValue(errs);
209 }
210