Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' into depencencies
[simgrid.git] / teshsuite / smpi / mpich3-test / io / i_types_with_zeros.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
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <fcntl.h>
11 #include <sys/types.h>
12 #include <sys/uio.h>
13
14 #include <mpi.h>
15
16 #define MAXLEN 9
17
18 static void handle_error(int errcode, const char *str)
19 {
20     char msg[MPI_MAX_ERROR_STRING];
21     int resultlen;
22     MPI_Error_string(errcode, msg, &resultlen);
23     fprintf(stderr, "%s: %s\n", str, msg);
24     MPI_Abort(MPI_COMM_WORLD, 1);
25 }
26
27 enum {
28     INDEXED,
29     HINDEXED,
30     STRUCT
31 } testcases;
32
33 static int test_indexed_with_zeros(const char *filename, int testcase)
34 {
35     int i, rank, np, buflen, num, err, nr_errors = 0;
36     int nelms[MAXLEN], buf[MAXLEN], indices[MAXLEN], blocklen[MAXLEN];
37     MPI_File fh;
38     MPI_Request request;
39     MPI_Status status;
40     MPI_Datatype filetype;
41     MPI_Datatype types[MAXLEN];
42     MPI_Aint addrs[MAXLEN];
43
44     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
45     MPI_Comm_size(MPI_COMM_WORLD, &np);
46
47     /* set up the number of integers to write in each iteration */
48     for (i = 0; i < MAXLEN; i++)
49         nelms[i] = 0;
50     if (rank == 0)
51         nelms[4] = nelms[5] = nelms[7] = 1;
52     if (rank == 1)
53         nelms[0] = nelms[1] = nelms[2] = nelms[3] = nelms[6] = nelms[8] = 1;
54
55     /* pre-fill the file with integers -999 */
56     if (rank == 0) {
57         for (i = 0; i < MAXLEN; i++)
58             buf[i] = -999;
59         err = MPI_File_open(MPI_COMM_SELF, filename,
60                             MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
61         if (err != MPI_SUCCESS)
62             handle_error(err, "MPI_File_open");
63         err = MPI_File_write(fh, buf, MAXLEN, MPI_INT, &status);
64         if (err != MPI_SUCCESS)
65             handle_error(err, "MPI_File_write");
66         err = MPI_File_close(&fh);
67         if (err != MPI_SUCCESS)
68             handle_error(err, "MPI_File_close");
69     }
70     MPI_Barrier(MPI_COMM_WORLD);
71
72     /* define a filetype with spurious leading zeros */
73     buflen = num = 0;
74     for (i = 0; i < MAXLEN; i++) {
75         buflen += nelms[i];
76         indices[num] = i;
77         addrs[num] = i * sizeof(int);
78         blocklen[num] = nelms[i];
79         types[num] = MPI_INT;
80         num++;
81     }
82     switch (testcase) {
83     case INDEXED:
84         MPI_Type_indexed(num, blocklen, indices, MPI_INT, &filetype);
85         break;
86     case HINDEXED:
87         MPI_Type_hindexed(num, blocklen, addrs, MPI_INT, &filetype);
88         break;
89     case STRUCT:
90         MPI_Type_create_struct(num, blocklen, addrs, types, &filetype);
91         break;
92     default:
93         fprintf(stderr, "unknown testcase!\n");
94         return (-100);
95     }
96
97     MPI_Type_commit(&filetype);
98
99     /* initialize write buffer and write to file */
100     for (i = 0; i < MAXLEN; i++)
101         buf[i] = 1;
102     err = MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
103     if (err != MPI_SUCCESS)
104         handle_error(err, "MPI_File_open");
105     err = MPI_File_set_view(fh, 0, MPI_INT, filetype, "native", MPI_INFO_NULL);
106     if (err != MPI_SUCCESS)
107         handle_error(err, "MPI_File_set_view");
108     err = MPI_File_iwrite_all(fh, buf, buflen, MPI_INT, &request);
109     if (err != MPI_SUCCESS)
110         handle_error(err, "MPI_File_iwrite_all");
111     err = MPI_Wait(&request, &status);
112     if (err != MPI_SUCCESS)
113         handle_error(err, "MPI_Wait");
114     MPI_Type_free(&filetype);
115     err = MPI_File_close(&fh);
116     if (err != MPI_SUCCESS)
117         handle_error(err, "MPI_File_close");
118
119     /* read back and check */
120     if (rank == 0) {
121         err = MPI_File_open(MPI_COMM_SELF, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh);
122         if (err != MPI_SUCCESS)
123             handle_error(err, "MPI_File_open");
124         err = MPI_File_read(fh, buf, MAXLEN, MPI_INT, &status);
125         if (err != MPI_SUCCESS)
126             handle_error(err, "MPI_File_read");
127         err = MPI_File_close(&fh);
128         if (err != MPI_SUCCESS)
129             handle_error(err, "MPI_File_close");
130         for (i = 0; i < MAXLEN; i++) {
131             if (buf[i] < 0) {
132                 nr_errors++;
133                 printf("Error: unexpected value for case %d at buf[%d] == %d\n",
134                        testcase, i, buf[i]);
135             }
136         }
137     }
138     return nr_errors;
139 }
140
141 int main(int argc, char **argv)
142 {
143     int nr_errors, rank, np;
144     const char *filename;
145
146     filename = (argc > 1) ? argv[1] : "testfile";
147
148     MPI_Init(&argc, &argv);
149     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
150     MPI_Comm_size(MPI_COMM_WORLD, &np);
151
152     if (np != 2) {
153         if (rank == 0)
154             fprintf(stderr, "Must run on 2 MPI processes\n");
155         MPI_Finalize();
156         return 1;
157     }
158     nr_errors = test_indexed_with_zeros(filename, INDEXED);
159     nr_errors += test_indexed_with_zeros(filename, HINDEXED);
160     nr_errors += test_indexed_with_zeros(filename, STRUCT);
161
162     if (rank == 0 && nr_errors == 0)
163         printf(" No Errors\n");
164
165     MPI_Finalize();
166     return 0;
167 }