Skip to content

Commit 684531f

Browse files
authored
Merge pull request #19 from jjhursey/comm-split-hw
Add a `MPI_Comm_split_type` `MPI_COMM_TYPE_HW_GUIDED` test
2 parents 3a3013f + ed88eb2 commit 684531f

File tree

3 files changed

+294
-0
lines changed

3 files changed

+294
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@ collective-big-count/test_reduce
3232
collective-big-count/test_scatter
3333
collective-big-count/test_scatterv
3434
collective-big-count/*_uniform_count
35+
36+
comm_split_type/cmsplit_type

comm_split_type/Makefile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
CFLAGS = -g -O0
3+
MPICC = mpicc
4+
5+
PROGS = cmsplit_type
6+
7+
all: $(PROGS)
8+
9+
cmsplit_type: cmsplit_type.c
10+
$(MPICC) cmsplit_type.c $(CFLAGS) -o cmsplit_type
11+
12+
clean:
13+
rm $(PROGS)
14+

comm_split_type/cmsplit_type.c

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
/*
2+
* Modified / Simplified version of MPICH MPI test suite version
3+
* for Open MPI specific split_topo values:
4+
* mpich-testsuite-4.1a1/comm/cmsplit_type.c
5+
*
6+
*/
7+
8+
#include "mpi.h"
9+
#include <stdio.h>
10+
#include <stdlib.h>
11+
#include <unistd.h>
12+
#include <string.h>
13+
14+
static const char *split_topo[] = {
15+
"mpi_shared_memory",
16+
"hwthread",
17+
"core",
18+
"l1cache",
19+
"l2cache",
20+
"l3cache",
21+
"socket",
22+
"numanode",
23+
"board",
24+
"host",
25+
"cu",
26+
"cluster",
27+
NULL
28+
};
29+
30+
int verbose = 0;
31+
int mcw_rank = 0;
32+
int mcw_size = 0;
33+
34+
static void sync_hr(void) {
35+
if (verbose) {
36+
fflush(NULL);
37+
MPI_Barrier(MPI_COMM_WORLD);
38+
if (mcw_rank == 0) {
39+
printf("-----------------------------------\n");
40+
usleep(1000000);
41+
}
42+
fflush(NULL);
43+
MPI_Barrier(MPI_COMM_WORLD);
44+
}
45+
}
46+
47+
int main(int argc, char *argv[])
48+
{
49+
int rank, size, errs = 0, tot_errs = 0;
50+
int i;
51+
MPI_Comm comm;
52+
MPI_Info info;
53+
int ret;
54+
55+
MPI_Init(&argc, &argv);
56+
MPI_Comm_rank(MPI_COMM_WORLD, &mcw_rank);
57+
MPI_Comm_size(MPI_COMM_WORLD, &mcw_size);
58+
59+
/*
60+
* Verbosity
61+
*/
62+
if (getenv("MPITEST_VERBOSE")) {
63+
verbose = 1;
64+
}
65+
MPI_Bcast(&verbose, 1, MPI_INT, 0, MPI_COMM_WORLD);
66+
67+
/*
68+
* Check to see if MPI_COMM_TYPE_SHARED works correctly
69+
*/
70+
MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0, MPI_INFO_NULL, &comm);
71+
if (comm == MPI_COMM_NULL) {
72+
printf("MPI_COMM_TYPE_SHARED (no hint): got MPI_COMM_NULL\n");
73+
errs++;
74+
} else {
75+
MPI_Comm_rank(comm, &rank);
76+
MPI_Comm_size(comm, &size);
77+
if (rank == 0 && verbose) {
78+
printf("MPI_COMM_TYPE_SHARED (no hint): Created shared subcommunicator of size %d\n",
79+
size);
80+
}
81+
MPI_Comm_free(&comm);
82+
}
83+
84+
sync_hr();
85+
86+
/*
87+
* Test MPI_COMM_TYPE_HW_GUIDED:
88+
* - Test with "mpi_hw_resource_type" = "mpi_shared_memory"
89+
*/
90+
MPI_Info_create(&info);
91+
MPI_Info_set(info, "mpi_hw_resource_type", "mpi_shared_memory");
92+
if (mcw_rank == 0 && verbose) {
93+
printf("MPI_COMM_TYPE_HW_GUIDED: Trying MPI Standard value %s\n", "mpi_shared_memory");
94+
}
95+
ret = MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_HW_GUIDED, 0, info, &comm);
96+
if (ret != MPI_SUCCESS) {
97+
printf("MPI_COMM_TYPE_HW_GUIDED (%s) failed\n", split_topo[i]);
98+
errs++;
99+
} else if (comm != MPI_COMM_NULL) {
100+
MPI_Comm_rank(comm, &rank);
101+
MPI_Comm_size(comm, &size);
102+
if (rank == 0 && verbose) {
103+
printf("MPI_COMM_TYPE_HW_GUIDED (%s): Created shared subcommunicator of size %d\n",
104+
"mpi_shared_memory", size);
105+
}
106+
MPI_Comm_free(&comm);
107+
}
108+
MPI_Info_free(&info);
109+
110+
sync_hr();
111+
112+
/*
113+
* Test MPI_COMM_TYPE_HW_GUIDED:
114+
* - Test with a variety of supported info values
115+
*/
116+
for (i = 0; split_topo[i]; i++) {
117+
MPI_Info_create(&info);
118+
MPI_Info_set(info, "mpi_hw_resource_type", split_topo[i]);
119+
if (mcw_rank == 0 && verbose) {
120+
printf("MPI_COMM_TYPE_HW_GUIDED: Trying value %s\n", split_topo[i]);
121+
}
122+
ret = MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_HW_GUIDED, 0, info, &comm);
123+
/* result will depend on platform and process bindings, just check returns */
124+
if (ret != MPI_SUCCESS) {
125+
printf("MPI_COMM_TYPE_HW_GUIDED (%s) failed\n", split_topo[i]);
126+
errs++;
127+
} else if (comm != MPI_COMM_NULL) {
128+
MPI_Comm_rank(comm, &rank);
129+
MPI_Comm_size(comm, &size);
130+
if (rank == 0 && verbose) {
131+
printf("MPI_COMM_TYPE_HW_GUIDED (%s): Created shared subcommunicator of size %d\n",
132+
split_topo[i], size);
133+
}
134+
MPI_Comm_free(&comm);
135+
}
136+
MPI_Info_free(&info);
137+
sync_hr();
138+
}
139+
140+
/*
141+
* Test MPI_COMM_TYPE_HW_GUIDED:
142+
* - pass MPI_INFO_NULL, it must return MPI_COMM_NULL.
143+
*/
144+
if (mcw_rank == 0 && verbose) {
145+
printf("MPI_COMM_TYPE_HW_GUIDED: Trying MPI_INFO_NULL\n");
146+
}
147+
info = MPI_INFO_NULL;
148+
MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_HW_GUIDED, 0, info, &comm);
149+
if (comm != MPI_COMM_NULL) {
150+
printf("MPI_COMM_TYPE_HW_GUIDED with MPI_INFO_NULL didn't return MPI_COMM_NULL\n");
151+
errs++;
152+
MPI_Comm_free(&comm);
153+
} else {
154+
if (mcw_rank == 0 && verbose) {
155+
printf("MPI_COMM_TYPE_HW_GUIDED: Trying MPI_INFO_NULL - Passed\n");
156+
}
157+
}
158+
159+
sync_hr();
160+
161+
/*
162+
* Test MPI_COMM_TYPE_HW_GUIDED:
163+
* - info without correct key, it must return MPI_COMM_NULL.
164+
*/
165+
if (mcw_rank == 0 && verbose) {
166+
printf("MPI_COMM_TYPE_HW_GUIDED: Trying invalid key\n");
167+
}
168+
MPI_Info_create(&info);
169+
MPI_Info_set(info, "bogus_key", split_topo[0]);
170+
MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_HW_GUIDED, 0, info, &comm);
171+
if (comm != MPI_COMM_NULL) {
172+
printf("MPI_COMM_TYPE_HW_GUIDED without correct key didn't return MPI_COMM_NULL\n");
173+
errs++;
174+
MPI_Comm_free(&comm);
175+
} else {
176+
if (mcw_rank == 0 && verbose) {
177+
printf("MPI_COMM_TYPE_HW_GUIDED: Trying invalid key - Passed\n");
178+
}
179+
}
180+
MPI_Info_free(&info);
181+
182+
sync_hr();
183+
184+
/*
185+
* Test MPI_COMM_TYPE_HW_GUIDED:
186+
* - info with correct key, but different values a different ranks, it must throw an error
187+
*/
188+
#if 0
189+
for (i = 0; NULL != split_topo[i]; i++) {
190+
;
191+
}
192+
if (i < 2) {
193+
if (mcw_rank == 0 && verbose) {
194+
printf("MPI_COMM_TYPE_HW_GUIDED: Trying mismatched values -- SKIPPED not enough valid values (%d)\n", i);
195+
}
196+
} else {
197+
if (mcw_rank == 0 && verbose) {
198+
printf("MPI_COMM_TYPE_HW_GUIDED: Trying mismatched values\n");
199+
}
200+
MPI_Info_create(&info);
201+
if (mcw_rank == 0) {
202+
MPI_Info_set(info, "mpi_hw_resource_type", split_topo[0]);
203+
} else {
204+
MPI_Info_set(info, "mpi_hw_resource_type", split_topo[1]);
205+
}
206+
MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_HW_GUIDED, 0, info, &comm);
207+
if (comm != MPI_COMM_NULL) {
208+
printf("MPI_COMM_TYPE_HW_GUIDED with mismatched values key didn't return MPI_COMM_NULL\n");
209+
errs++;
210+
MPI_Comm_free(&comm);
211+
}
212+
MPI_Info_free(&info);
213+
}
214+
#endif
215+
216+
/* Test MPI_COMM_TYPE_HW_GUIDED:
217+
* - info with semantically matching split_types and keys, it must throw an error
218+
*/
219+
#if 0
220+
if (mcw_rank == 0 && verbose) {
221+
printf("MPI_COMM_TYPE_HW_GUIDED: Trying mismatched keys but semantically matching\n");
222+
}
223+
224+
if (mcw_rank == 0) {
225+
MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0, MPI_INFO_NULL, &comm);
226+
} else {
227+
MPI_Info_create(&info);
228+
MPI_Info_set(info, "mpi_hw_resource_type", "mpi_shared_memory");
229+
MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_HW_GUIDED, 0, info, &comm);
230+
}
231+
if (comm != MPI_COMM_NULL) {
232+
printf("MPI_COMM_TYPE_HW_GUIDED with mismatched values key didn't return MPI_COMM_NULL\n");
233+
errs++;
234+
MPI_Comm_free(&comm);
235+
}
236+
MPI_Info_free(&info);
237+
#endif
238+
239+
/* Test MPI_COMM_TYPE_HW_UNGUIDED:
240+
* - TODO
241+
*/
242+
#if 0
243+
if (mcw_rank == 0 && verbose)
244+
printf("MPI_COMM_TYPE_HW_UNGUIDED: Trying basic\n");
245+
MPI_Info_create(&info);
246+
MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_HW_UNGUIDED, 0, info, &comm);
247+
if (comm != MPI_COMM_NULL) {
248+
int newsize;
249+
MPI_Comm_size(comm, &newsize);
250+
if (!(newsize < mcw_size)) {
251+
printf("MPI_COMM_TYPE_HW_UNGUIDED: Expected comm to be a proper sub communicator\n");
252+
errs++;
253+
}
254+
char resource_type[100] = "";
255+
int has_key = 0;
256+
MPI_Info_get(info, "mpi_hw_resource_type", 100, resource_type, &has_key);
257+
if (!has_key || strlen(resource_type) == 0) {
258+
printf("MPI_COMM_TYPE_HW_UNGUIDED: info for mpi_hw_resource_type not returned\n");
259+
errs++;
260+
}
261+
262+
MPI_Comm_free(&comm);
263+
}
264+
else if (mcw_rank == 0 && verbose) {
265+
printf("MPI_COMM_TYPE_HW_UNGUIDED: Returned MPI_COMM_NULL\n");
266+
}
267+
#endif
268+
269+
/*
270+
* All done - figure out if we passed
271+
*/
272+
done:
273+
MPI_Reduce(&errs, &tot_errs, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
274+
275+
MPI_Finalize();
276+
277+
return tot_errs;
278+
}

0 commit comments

Comments
 (0)