Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' into depencencies
[simgrid.git] / teshsuite / smpi / mpich3-test / io / i_coll_test.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 "mpi.h"
8 #include <stdlib.h>
9 #include <string.h>
10 #include <stdio.h>
11
12 /* A 32^3 array. For other array sizes, change array_of_gsizes below. */
13
14 /* Uses nonblocking collective I/O. Writes a 3D block-distributed array to
15    a file corresponding to the global array in row-major (C) order, reads it
16    back, and checks that the data read is correct. */
17
18 /* Note that the file access pattern is noncontiguous. */
19
20 void handle_error(int errcode, const char *str);
21
22 void handle_error(int errcode, const char *str)
23 {
24     char msg[MPI_MAX_ERROR_STRING];
25     int resultlen;
26     MPI_Error_string(errcode, msg, &resultlen);
27     fprintf(stderr, "%s: %s\n", str, msg);
28     MPI_Abort(MPI_COMM_WORLD, 1);
29 }
30
31 int main(int argc, char **argv)
32 {
33     MPI_Datatype newtype;
34     int i, ndims, array_of_gsizes[3], array_of_distribs[3];
35     int order, nprocs, j, len;
36     int array_of_dargs[3], array_of_psizes[3];
37     int *readbuf, *writebuf, mynod, *tmpbuf, array_size;
38     MPI_Count bufcount;
39     char *filename;
40     int errs = 0, toterrs;
41     MPI_File fh;
42     MPI_Status status;
43     MPI_Request request;
44     MPI_Info info = MPI_INFO_NULL;
45     int errcode;
46
47     MPI_Init(&argc, &argv);
48     MPI_Comm_rank(MPI_COMM_WORLD, &mynod);
49     MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
50
51     /* process 0 broadcasts the file name to other processes */
52     if (!mynod) {
53         filename = (char*)"testfile";
54         len = strlen(filename);
55         MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
56         MPI_Bcast(filename, len + 1, MPI_CHAR, 0, MPI_COMM_WORLD);
57     }
58     else {
59         MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
60         filename = (char *) malloc(len + 1);
61         MPI_Bcast(filename, len + 1, MPI_CHAR, 0, MPI_COMM_WORLD);
62     }
63
64
65     /* create the distributed array filetype */
66     ndims = 3;
67     order = MPI_ORDER_C;
68
69     array_of_gsizes[0] = 32;
70     array_of_gsizes[1] = 32;
71     array_of_gsizes[2] = 32;
72
73     array_of_distribs[0] = MPI_DISTRIBUTE_BLOCK;
74     array_of_distribs[1] = MPI_DISTRIBUTE_BLOCK;
75     array_of_distribs[2] = MPI_DISTRIBUTE_BLOCK;
76
77     array_of_dargs[0] = MPI_DISTRIBUTE_DFLT_DARG;
78     array_of_dargs[1] = MPI_DISTRIBUTE_DFLT_DARG;
79     array_of_dargs[2] = MPI_DISTRIBUTE_DFLT_DARG;
80
81     for (i = 0; i < ndims; i++)
82         array_of_psizes[i] = 0;
83     MPI_Dims_create(nprocs, ndims, array_of_psizes);
84
85     MPI_Type_create_darray(nprocs, mynod, ndims, array_of_gsizes,
86                            array_of_distribs, array_of_dargs,
87                            array_of_psizes, order, MPI_INT, &newtype);
88     MPI_Type_commit(&newtype);
89
90     /* initialize writebuf */
91
92     MPI_Type_size_x(newtype, &bufcount);
93     bufcount = bufcount / sizeof(int);
94     writebuf = (int *) malloc(bufcount * sizeof(int));
95     for (i = 0; i < bufcount; i++)
96         writebuf[i] = 1;
97
98     array_size = array_of_gsizes[0] * array_of_gsizes[1] * array_of_gsizes[2];
99     tmpbuf = (int *) calloc(array_size, sizeof(int));
100     MPI_Irecv(tmpbuf, 1, newtype, mynod, 10, MPI_COMM_WORLD, &request);
101     MPI_Send(writebuf, bufcount, MPI_INT, mynod, 10, MPI_COMM_WORLD);
102     MPI_Wait(&request, &status);
103
104     j = 0;
105     for (i = 0; i < array_size; i++)
106         if (tmpbuf[i]) {
107             writebuf[j] = i;
108             j++;
109         }
110     free(tmpbuf);
111
112     if (j != bufcount) {
113         fprintf(stderr, "Error in initializing writebuf on process %d\n", mynod);
114         MPI_Abort(MPI_COMM_WORLD, 1);
115     }
116     /* end of initialization */
117
118     /* write the array to the file */
119     errcode = MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, info, &fh);
120     if (errcode != MPI_SUCCESS)
121         handle_error(errcode, "MPI_File_open");
122
123     errcode = MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info);
124     if (errcode != MPI_SUCCESS)
125         handle_error(errcode, "MPI_File_set_view");
126
127     errcode = MPI_File_iwrite_all(fh, writebuf, bufcount, MPI_INT, &request);
128     if (errcode != MPI_SUCCESS)
129         handle_error(errcode, "MPI_File_iwrite_all");
130     MPI_Wait(&request, &status);
131
132     errcode = MPI_File_close(&fh);
133     if (errcode != MPI_SUCCESS)
134         handle_error(errcode, "MPI_File_close");
135
136     if (!mynod) {
137         /* wkl suggests potential for false " No Errors" if both read
138          * and write use the same file view */
139         /* solution: rank 0 reads entire file and checks write values */
140         errcode = MPI_File_open(MPI_COMM_SELF, filename, MPI_MODE_RDONLY, info, &fh);
141         if (errcode != MPI_SUCCESS)
142             handle_error(errcode, "MPI_File_open");
143
144         readbuf = (int *) malloc(array_size * sizeof(int));
145         errcode = MPI_File_read(fh, readbuf, array_size, MPI_INT, &status);
146         if (errcode != MPI_SUCCESS)
147             handle_error(errcode, "MPI_File_read");
148
149         errcode = MPI_File_close(&fh);
150         if (errcode != MPI_SUCCESS)
151             handle_error(errcode, "MPI_File_close");
152
153         for (i = 0; i < array_size; i++)
154             if (readbuf[i] != i) {
155                 errs++;
156                 fprintf(stderr, "Error: write integer %d but read %d\n", i, readbuf[i]);
157                 break;
158             }
159         free(readbuf);
160     }
161     MPI_Barrier(MPI_COMM_WORLD);
162
163     /* now read it back */
164     readbuf = (int *) malloc(bufcount * sizeof(int));
165     errcode = MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, info, &fh);
166     if (errcode != MPI_SUCCESS)
167         handle_error(errcode, "MPI_File_open");
168
169     errcode = MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info);
170     if (errcode != MPI_SUCCESS)
171         handle_error(errcode, "MPI_File_set_view");
172     errcode = MPI_File_iread_all(fh, readbuf, bufcount, MPI_INT, &request);
173     if (errcode != MPI_SUCCESS)
174         handle_error(errcode, "MPI_File_iread_all");
175     MPI_Wait(&request, &status);
176     errcode = MPI_File_close(&fh);
177     if (errcode != MPI_SUCCESS)
178         handle_error(errcode, "MPI_File_close");
179
180     /* check the data read */
181     for (i = 0; i < bufcount; i++) {
182         if (readbuf[i] != writebuf[i]) {
183             errs++;
184             fprintf(stderr, "Process %d, readbuf %d, writebuf %d, i %d\n",
185                     mynod, readbuf[i], writebuf[i], i);
186         }
187     }
188
189     MPI_Allreduce(&errs, &toterrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
190     if (mynod == 0) {
191         if (toterrs > 0) {
192             fprintf(stderr, "Found %d errors\n", toterrs);
193         }
194         else {
195             fprintf(stdout, " No Errors\n");
196         }
197     }
198
199     MPI_Type_free(&newtype);
200     free(readbuf);
201     free(writebuf);
202     if (mynod)
203         free(filename);
204
205     MPI_Finalize();
206     return 0;
207 }