Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Update comm, datatype from mpich trunk
[simgrid.git] / teshsuite / smpi / mpich3-test / datatype / sendrecvt4.c
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  *  (C) 2014 by Argonne National Laboratory.
4  *      See COPYRIGHT in top-level directory.
5  */
6 #include "mpi.h"
7 #include "mpitest.h"
8 #include <stdio.h>
9 #include "dtypes.h"
10
11
12 /*
13    This program is derived from one in the MPICH-1 test suite
14
15    This version sends and receives EVERYTHING from MPI_BOTTOM, by putting
16    the data into a structure.
17  */
18 int main( int argc, char **argv )
19 {
20     MPI_Datatype *types;
21     void         **inbufs, **outbufs;
22     int          *counts, *bytesize, ntype;
23     MPI_Comm     comm;
24     int          rank, np, partner, tag, count;
25     int          j, k, err, world_rank, errloc;
26     MPI_Status   status;
27     char         *obuf;
28     MPI_Datatype offsettype;
29     int          blen;
30     MPI_Aint     displ, extent, natural_extent;
31     char         myname[MPI_MAX_OBJECT_NAME];
32     int          mynamelen;
33
34     MTest_Init( &argc, &argv );
35
36     MTestDatatype2Allocate( &types, &inbufs, &outbufs, &counts, &bytesize,
37                             &ntype );
38     MTestDatatype2Generate( types, inbufs, outbufs, counts, bytesize, &ntype );
39
40     MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );
41
42     /* Test over a wide range of datatypes and communicators */
43     err = 0;
44     tag = 0;
45     while (MTestGetIntracomm( &comm, 2 )) {
46         if (comm == MPI_COMM_NULL) continue;
47         MPI_Comm_rank( comm, &rank );
48         MPI_Comm_size( comm, &np );
49         if (np < 2) continue;
50         tag++;
51         for (j=0; j<ntype; j++) {
52             MPI_Type_get_name( types[j], myname, &mynamelen );
53             if (world_rank == 0)
54                 MTestPrintfMsg( 10, "Testing type %s\n", myname );
55             if (rank == 0) {
56                 MPI_Get_address( inbufs[j], &displ );
57                 blen = 1;
58                 MPI_Type_create_struct( 1, &blen, &displ, types + j,
59                                         &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 );
66                 if (extent < 0) {
67                     if (world_rank == 0)
68                         MTestPrintfMsg( 10,
69                         "... skipping (appears to have explicit MPI_UB\n" );
70                     MPI_Type_free( &offsettype );
71                     continue;
72                 }
73                 MPI_Type_extent( types[j], &natural_extent );
74                 if (natural_extent != extent) {
75                     MPI_Type_free( &offsettype );
76                     continue;
77                 }
78                 partner = np - 1;
79                 MPI_Send( MPI_BOTTOM, counts[j], offsettype, partner, tag,
80                           comm );
81                 MPI_Type_free( &offsettype );
82             }
83             else if (rank == np-1) {
84                 partner = 0;
85                 obuf = outbufs[j];
86                 for (k=0; k<bytesize[j]; k++)
87                     obuf[k] = 0;
88                 MPI_Get_address( outbufs[j], &displ );
89                 blen = 1;
90                 MPI_Type_create_struct( 1, &blen, &displ, types + j,
91                                         &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 );
98                 if (extent < 0) {
99                     MPI_Type_free( &offsettype );
100                     continue;
101                 }
102                 MPI_Type_extent( types[j], &natural_extent );
103                 if (natural_extent != extent) {
104                     MPI_Type_free( &offsettype );
105                     continue;
106                 }
107                 MPI_Recv( MPI_BOTTOM, counts[j], offsettype,
108                           partner, tag, comm, &status );
109                 /* Test for correctness */
110                 MPI_Get_count( &status, types[j], &count );
111                 if (count != counts[j]) {
112                     fprintf( stderr,
113                         "Error in counts (got %d expected %d) with type %s\n",
114                          count, counts[j], myname );
115                     err++;
116                 }
117                 if (status.MPI_SOURCE != partner) {
118                     fprintf( stderr,
119                         "Error in source (got %d expected %d) with type %s\n",
120                          status.MPI_SOURCE, partner, myname );
121                     err++;
122                 }
123                 if ((errloc = MTestDatatype2Check( inbufs[j], outbufs[j],
124                                                    bytesize[j] ))) {
125                     fprintf( stderr,
126                   "Error in data with type %s (type %d on %d) at byte %d\n",
127                          myname, j, world_rank, errloc - 1 );
128                     if (err < 10) {
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];
132                         int jj;
133                         jj = errloc - 1;
134                         jj &= 0xfffffffc; /* lop off a few bits */
135                         in_p += jj;
136                         out_p += jj;
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] );
140                     }
141                     err++;
142                 }
143                 MPI_Type_free( &offsettype );
144             }
145         }
146         MTestFreeComm( &comm );
147     }
148
149     MTestDatatype2Free( types, inbufs, outbufs, counts, bytesize, ntype );
150     MTest_Finalize( err );
151     MPI_Finalize();
152     return MTestReturnValue( err );
153 }