1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
3 * (C) 2001 by Argonne National Laboratory.
4 * See COPYRIGHT in top-level directory.
12 static int verbose = 0;
14 int main(int argc, char *argv[]);
15 int parse_args(int argc, char **argv);
16 int single_struct_test(void);
17 int array_of_structs_test(void);
18 int struct_of_structs_test(void);
20 struct test_struct_1 {
26 int main(int argc, char *argv[])
31 MPI_Init(&argc, &argv);
32 parse_args(argc, argv);
34 /* To improve reporting of problems about operations, we
35 change the error handler to errors return */
36 MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
38 err = single_struct_test();
39 if (verbose && err) fprintf(stderr, "error in single_struct_test\n");
42 err = array_of_structs_test();
43 if (verbose && err) fprintf(stderr, "error in array_of_structs_test\n");
46 err = struct_of_structs_test();
47 if (verbose && err) fprintf(stderr, "error in struct_of_structs_test\n");
50 /* print message and exit */
52 fprintf(stderr, "Found %d errors\n", errs);
55 printf(" No Errors\n");
61 int single_struct_test(void)
64 int bufsize, position = 0;
65 struct test_struct_1 ts1, ts2;
66 MPI_Datatype mystruct;
69 MPI_Aint disps[3] = {0, 2*sizeof(int), 3*sizeof(int)}; /* guessing... */
70 int blks[3] = { 2, 2, 1 };
71 MPI_Datatype types[3] = { MPI_INT, MPI_CHAR, MPI_INT };
79 err = MPI_Type_struct(3, blks, disps, types, &mystruct);
80 if (err != MPI_SUCCESS) {
83 fprintf(stderr, "MPI_Type_struct returned error\n");
87 MPI_Type_commit(&mystruct);
89 MPI_Pack_size(1, mystruct, MPI_COMM_WORLD, &bufsize);
90 buffer = (char *) malloc(bufsize);
99 if (err != MPI_SUCCESS) {
102 fprintf(stderr, "MPI_Pack returned error\n");
107 err = MPI_Unpack(buffer,
114 if (err != MPI_SUCCESS) {
117 fprintf(stderr, "MPI_Unpack returned error\n");
121 MPI_Type_free(&mystruct);
124 if (ts1.a != ts2.a) {
127 fprintf(stderr, "ts2.a = %d; should be %d\n", ts2.a, ts1.a);
130 if (ts1.b != ts2.b) {
133 fprintf(stderr, "ts2.b = %d; should be %d\n", ts2.b, ts1.b);
136 if (ts1.c != ts2.c) {
139 fprintf(stderr, "ts2.c = %d; should be %d\n",
140 (int) ts2.c, (int) ts1.c);
143 if (ts1.d != ts2.d) {
146 fprintf(stderr, "ts2.d = %d; should be %d\n",
147 (int) ts2.d, (int) ts1.d);
150 if (ts1.e != ts2.e) {
153 fprintf(stderr, "ts2.e = %d; should be %d\n", ts2.e, ts1.e);
160 int array_of_structs_test(void)
162 int i, err, errs = 0;
163 int bufsize, position = 0;
164 struct test_struct_1 ts1[10], ts2[10];
165 MPI_Datatype mystruct;
168 MPI_Aint disps[3] = {0, 2*sizeof(int), 3*sizeof(int)}; /* guessing... */
169 int blks[3] = { 2, 2, 1 };
170 MPI_Datatype types[3] = { MPI_INT, MPI_CHAR, MPI_INT };
172 for (i=0; i < 10; i++) {
186 err = MPI_Type_struct(3, blks, disps, types, &mystruct);
187 if (err != MPI_SUCCESS) {
190 fprintf(stderr, "MPI_Type_struct returned error\n");
194 MPI_Type_commit(&mystruct);
196 MPI_Pack_size(10, mystruct, MPI_COMM_WORLD, &bufsize);
197 buffer = (char *) malloc(bufsize);
206 if (err != MPI_SUCCESS) {
209 fprintf(stderr, "MPI_Pack returned error\n");
214 err = MPI_Unpack(buffer,
221 if (err != MPI_SUCCESS) {
224 fprintf(stderr, "MPI_Unpack returned error\n");
228 MPI_Type_free(&mystruct);
231 for (i=0; i < 10; i++) {
232 if (ts1[i].a != ts2[i].a) {
235 fprintf(stderr, "ts2[%d].a = %d; should be %d\n",
236 i, ts2[i].a, ts1[i].a);
239 if (ts1[i].b != ts2[i].b) {
242 fprintf(stderr, "ts2[%d].b = %d; should be %d\n",
243 i, ts2[i].b, ts1[i].b);
246 if (ts1[i].c != ts2[i].c) {
249 fprintf(stderr, "ts2[%d].c = %d; should be %d\n",
250 i, (int) ts2[i].c, (int) ts1[i].c);
253 if (ts1[i].d != ts2[i].d) {
256 fprintf(stderr, "ts2[%d].d = %d; should be %d\n",
257 i, (int) ts2[i].d, (int) ts1[i].d);
260 if (ts1[i].e != ts2[i].e) {
263 fprintf(stderr, "ts2[%d].e = %d; should be %d\n",
264 i, ts2[i].e, ts1[i].e);
272 int struct_of_structs_test(void)
274 int i, j, err, errs = 0, bufsize, position;
276 char buf[50], buf2[50], *packbuf;
278 MPI_Aint disps[3] = {0, 3, 0};
279 int blks[3] = {2, 1, 0};
280 MPI_Datatype types[3], chartype, tiletype1, tiletype2, finaltype;
282 /* build a contig of one char to try to keep optimizations
283 * from being applied.
285 err = MPI_Type_contiguous(1, MPI_CHAR, &chartype);
286 if (err != MPI_SUCCESS) {
289 fprintf(stderr, "chartype create failed\n");
294 /* build a type that we can tile a few times */
298 err = MPI_Type_struct(2, blks, disps, types, &tiletype1);
299 if (err != MPI_SUCCESS) {
302 fprintf(stderr, "tiletype1 create failed\n");
307 /* build the same type again, again to avoid optimizations */
308 err = MPI_Type_struct(2, blks, disps, types, &tiletype2);
309 if (err != MPI_SUCCESS) {
312 fprintf(stderr, "tiletype2 create failed\n");
317 /* build a combination of those two tiletypes */
324 types[0] = tiletype1;
325 types[1] = tiletype2;
327 err = MPI_Type_struct(3, blks, disps, types, &finaltype);
328 if (err != MPI_SUCCESS) {
331 fprintf(stderr, "finaltype create failed\n");
336 MPI_Type_commit(&finaltype);
337 MPI_Type_free(&chartype);
338 MPI_Type_free(&tiletype1);
339 MPI_Type_free(&tiletype2);
341 MPI_Pack_size(5, finaltype, MPI_COMM_WORLD, &bufsize);
343 packbuf = malloc(bufsize);
344 if (packbuf == NULL) {
347 fprintf(stderr, "pack buffer allocation (%d bytes) failed\n", bufsize);
352 for (j=0; j < 10; j++) {
353 for (i=0; i < 5; i++) {
354 if (i == 2 || i == 4) buf[5*j + i] = 0;
355 else buf[5*j + i] = i;
360 err = MPI_Pack(buf, 5, finaltype, packbuf, bufsize, &position, MPI_COMM_WORLD);
361 if (err != MPI_SUCCESS) {
364 fprintf(stderr, "pack failed\n");
371 err = MPI_Unpack(packbuf, bufsize, &position, buf2, 5, finaltype, MPI_COMM_WORLD);
372 if (err != MPI_SUCCESS) {
375 fprintf(stderr, "unpack failed\n");
380 for (j=0; j < 10; j++) {
381 for (i=0; i < 5; i++) {
382 if (buf[5*j + i] != buf2[5*j + i]) {
386 "buf2[%d] = %d; should be %d\n",
396 MPI_Type_free(&finaltype);
400 int parse_args(int argc, char **argv)
405 while ((ret = getopt(argc, argv, "v")) >= 0)
414 if (argc > 1 && strcmp(argv[1], "-v") == 0)