1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
3 * (C) 2014 by Argonne National Laboratory.
4 * See COPYRIGHT in top-level directory.
13 This program is derived from one in the MPICH-1 test suite
15 This version sends and receives EVERYTHING from MPI_BOTTOM, by putting
16 the data into a structure.
18 int main(int argc, char **argv)
21 void **inbufs, **outbufs;
22 int *counts, *bytesize, ntype;
24 int rank, np, partner, tag, count;
25 int j, k, err, world_rank, errloc;
28 MPI_Datatype offsettype;
30 MPI_Aint displ, extent, natural_extent;
31 char myname[MPI_MAX_OBJECT_NAME];
34 MTest_Init(&argc, &argv);
36 MTestDatatype2Allocate(&types, &inbufs, &outbufs, &counts, &bytesize, &ntype);
37 MTestDatatype2Generate(types, inbufs, outbufs, counts, bytesize, &ntype);
39 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
41 /* Test over a wide range of datatypes and communicators */
44 while (MTestGetIntracomm(&comm, 2)) {
45 if (comm == MPI_COMM_NULL)
47 MPI_Comm_rank(comm, &rank);
48 MPI_Comm_size(comm, &np);
52 for (j = 0; j < ntype; j++) {
53 MPI_Type_get_name(types[j], myname, &mynamelen);
55 MTestPrintfMsg(10, "Testing type %s\n", myname);
57 MPI_Get_address(inbufs[j], &displ);
59 MPI_Type_create_struct(1, &blen, &displ, types + j, &offsettype);
60 MPI_Type_commit(&offsettype);
61 /* Warning: if the type has an explicit MPI_UB, then using a
62 * simple shift of the offset won't work. For now, we skip
63 * types whose extents are negative; the correct solution is
64 * to add, where required, an explicit MPI_UB */
65 MPI_Type_extent(offsettype, &extent);
68 MTestPrintfMsg(10, "... skipping (appears to have explicit MPI_UB\n");
69 MPI_Type_free(&offsettype);
72 MPI_Type_extent(types[j], &natural_extent);
73 if (natural_extent != extent) {
74 MPI_Type_free(&offsettype);
79 MPI_Type_dup(offsettype, &dup);
80 MPI_Send(MPI_BOTTOM, counts[j], dup, partner, tag, comm);
81 MPI_Type_free(&offsettype);
84 else if (rank == np - 1) {
87 for (k = 0; k < bytesize[j]; k++)
89 MPI_Get_address(outbufs[j], &displ);
91 MPI_Type_create_struct(1, &blen, &displ, types + j, &offsettype);
92 MPI_Type_commit(&offsettype);
93 /* Warning: if the type has an explicit MPI_UB, then using a
94 * simple shift of the offset won't work. For now, we skip
95 * types whose extents are negative; the correct solution is
96 * to add, where required, an explicit MPI_UB */
97 MPI_Type_extent(offsettype, &extent);
99 MPI_Type_free(&offsettype);
102 MPI_Type_extent(types[j], &natural_extent);
103 if (natural_extent != extent) {
104 MPI_Type_free(&offsettype);
108 MPI_Type_dup(offsettype, &dup);
109 MPI_Recv(MPI_BOTTOM, counts[j], dup, partner, tag, comm, &status);
110 /* Test for correctness */
111 MPI_Get_count(&status, types[j], &count);
112 if (count != counts[j]) {
114 "Error in counts (got %d expected %d) with type %s\n",
115 count, counts[j], myname);
118 if (status.MPI_SOURCE != partner) {
120 "Error in source (got %d expected %d) with type %s\n",
121 status.MPI_SOURCE, partner, myname);
124 if ((errloc = MTestDatatype2Check(inbufs[j], outbufs[j], bytesize[j]))) {
126 "Error in data with type %s (type %d on %d) at byte %d\n",
127 myname, j, world_rank, errloc - 1);
129 /* Give details on only the first 10 errors */
130 unsigned char *in_p = (unsigned char *) inbufs[j],
131 *out_p = (unsigned char *) outbufs[j];
134 jj &= 0xfffffffc; /* lop off a few bits */
137 fprintf(stderr, "%02x%02x%02x%02x should be %02x%02x%02x%02x\n",
138 out_p[0], out_p[1], out_p[2], out_p[3],
139 in_p[0], in_p[1], in_p[2], in_p[3]);
143 MPI_Type_free(&offsettype);
147 MTestFreeComm(&comm);
150 MTestDatatype2Free(types, inbufs, outbufs, counts, bytesize, ntype);
153 return MTestReturnValue(err);