AMPI #952: update ROMIO to MPICH2-1.4.1p1
[charm.git] / src / libs / ck-libs / ampi / romio / test / noncontig.c
blobbb435e53ac47f29c7c23738af8ceab824bfe1e59
1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3 * (C) 2001 by Argonne National Laboratory.
4 * See COPYRIGHT in top-level directory.
5 */
6 #include "mpi.h"
7 #include <stdio.h>
8 #include <string.h>
9 #include <stdlib.h>
11 /* tests noncontiguous reads/writes using independent I/O */
13 #define SIZE 5000
15 #define VERBOSE 0
16 int main(int argc, char **argv)
18 int *buf, i, mynod, nprocs, len, b[3];
19 int errs=0, toterrs;
20 MPI_Aint d[3];
21 MPI_File fh;
22 MPI_Status status;
23 char *filename;
24 MPI_Datatype typevec, newtype, t[3];
25 MPI_Info info;
27 MPI_Init(&argc,&argv);
28 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
29 MPI_Comm_rank(MPI_COMM_WORLD, &mynod);
31 if (nprocs != 2) {
32 fprintf(stderr, "Run this program on two processes\n");
33 MPI_Abort(MPI_COMM_WORLD, 1);
36 /* process 0 takes the file name as a command-line argument and
37 broadcasts it to other processes (length first, then string) */
38 if (!mynod) {
39 i = 1;
40 while ((i < argc) && strcmp("-fname", *argv)) {
41 i++;
42 argv++;
44 if (i >= argc) {
45 fprintf(stderr, "\n*# Usage: noncontig -fname filename\n\n");
46 MPI_Abort(MPI_COMM_WORLD, 1);
48 argv++;
49 len = strlen(*argv);
50 filename = (char *) malloc(len+1);
51 strcpy(filename, *argv);
52 MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
53 MPI_Bcast(filename, len+1, MPI_CHAR, 0, MPI_COMM_WORLD);
55 else {
56 MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
57 filename = (char *) malloc(len+1);
58 MPI_Bcast(filename, len+1, MPI_CHAR, 0, MPI_COMM_WORLD);
61 buf = (int *) malloc(SIZE*sizeof(int));
63 MPI_Type_vector(SIZE/2, 1, 2, MPI_INT, &typevec);
65 /* create a struct type with explicitly set LB and UB; displacements
66 * of typevec are such that the types for the two processes won't
67 * overlap.
69 b[0] = b[1] = b[2] = 1;
70 d[0] = 0;
71 d[1] = mynod*sizeof(int);
72 d[2] = SIZE*sizeof(int);
73 t[0] = MPI_LB;
74 t[1] = typevec;
75 t[2] = MPI_UB;
77 /* keep the struct, ditch the vector */
78 MPI_Type_struct(3, b, d, t, &newtype);
79 MPI_Type_commit(&newtype);
80 MPI_Type_free(&typevec);
82 MPI_Info_create(&info);
83 /* I am setting these info values for testing purposes only. It is
84 better to use the default values in practice. */
85 MPI_Info_set(info, "ind_rd_buffer_size", "1209");
86 MPI_Info_set(info, "ind_wr_buffer_size", "1107");
88 if (!mynod) {
89 #if VERBOSE
90 fprintf(stderr, "\ntesting noncontiguous in memory, noncontiguous in file using independent I/O\n");
91 #endif
92 MPI_File_delete(filename, MPI_INFO_NULL);
94 MPI_Barrier(MPI_COMM_WORLD);
96 MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR,
97 info, &fh);
99 /* set the file view for each process -- now writes go into the non-
100 * overlapping but interleaved region defined by the struct type up above
102 MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info);
104 /* fill our buffer with a pattern and write, using our type again */
105 for (i=0; i<SIZE; i++) buf[i] = i + mynod*SIZE;
106 MPI_File_write(fh, buf, 1, newtype, &status);
108 MPI_Barrier(MPI_COMM_WORLD);
110 /* fill the entire buffer with -1's. read back with type.
111 * note that the result of this read should be that every other value
112 * in the buffer is still -1, as defined by our type.
114 for (i=0; i<SIZE; i++) buf[i] = -1;
115 MPI_File_read_at(fh, 0, buf, 1, newtype, &status);
117 /* check that all the values read are correct and also that we didn't
118 * overwrite any of the -1 values that we shouldn't have.
120 for (i=0; i<SIZE; i++) {
121 if (!mynod) {
122 if ((i%2) && (buf[i] != -1)) {
123 errs++;
124 fprintf(stderr, "Process %d: buf %d is %d, should be -1\n",
125 mynod, i, buf[i]);
127 if (!(i%2) && (buf[i] != i)) {
128 errs++;
129 fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
130 mynod, i, buf[i], i);
133 else {
134 if ((i%2) && (buf[i] != i + mynod*SIZE)) {
135 errs++;
136 fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
137 mynod, i, buf[i], i + mynod*SIZE);
139 if (!(i%2) && (buf[i] != -1)) {
140 errs++;
141 fprintf(stderr, "Process %d: buf %d is %d, should be -1\n",
142 mynod, i, buf[i]);
147 MPI_File_close(&fh);
149 MPI_Barrier(MPI_COMM_WORLD);
151 if (!mynod) {
152 #if VERBOSE
153 fprintf(stderr, "\ntesting noncontiguous in memory, contiguous in file using independent I/O\n");
154 #endif
155 MPI_File_delete(filename, MPI_INFO_NULL);
157 MPI_Barrier(MPI_COMM_WORLD);
159 MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR,
160 info, &fh);
162 /* in this case we write to either the first half or the second half
163 * of the file space, so the regions are not interleaved. this is done
164 * by leaving the file view at its default.
166 for (i=0; i<SIZE; i++) buf[i] = i + mynod*SIZE;
167 MPI_File_write_at(fh, mynod*(SIZE/2)*sizeof(int), buf, 1, newtype, &status);
169 MPI_Barrier(MPI_COMM_WORLD);
171 /* same as before; fill buffer with -1's and then read; every other
172 * value should still be -1 after the read
174 for (i=0; i<SIZE; i++) buf[i] = -1;
175 MPI_File_read_at(fh, mynod*(SIZE/2)*sizeof(int), buf, 1, newtype, &status);
177 /* verify that the buffer looks like it should */
178 for (i=0; i<SIZE; i++) {
179 if (!mynod) {
180 if ((i%2) && (buf[i] != -1)) {
181 errs++;
182 fprintf(stderr, "Process %d: buf %d is %d, should be -1\n",
183 mynod, i, buf[i]);
185 if (!(i%2) && (buf[i] != i)) {
186 errs++;
187 fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
188 mynod, i, buf[i], i);
191 else {
192 if ((i%2) && (buf[i] != i + mynod*SIZE)) {
193 errs++;
194 fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
195 mynod, i, buf[i], i + mynod*SIZE);
197 if (!(i%2) && (buf[i] != -1)) {
198 errs++;
199 fprintf(stderr, "Process %d: buf %d is %d, should be -1\n",
200 mynod, i, buf[i]);
205 MPI_File_close(&fh);
207 MPI_Barrier(MPI_COMM_WORLD);
209 if (!mynod) {
210 #if VERBOSE
211 fprintf(stderr, "\ntesting contiguous in memory, noncontiguous in file using independent I/O\n");
212 #endif
213 MPI_File_delete(filename, MPI_INFO_NULL);
215 MPI_Barrier(MPI_COMM_WORLD);
217 MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR,
218 info, &fh);
220 /* set the file view so that we have interleaved access again */
221 MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info);
223 /* this time write a contiguous buffer */
224 for (i=0; i<SIZE; i++) buf[i] = i + mynod*SIZE;
225 MPI_File_write(fh, buf, SIZE, MPI_INT, &status);
227 MPI_Barrier(MPI_COMM_WORLD);
229 /* fill buffer with -1's; this time they will all be overwritten */
230 for (i=0; i<SIZE; i++) buf[i] = -1;
231 MPI_File_read_at(fh, 0, buf, SIZE, MPI_INT, &status);
233 for (i=0; i<SIZE; i++) {
234 if (!mynod) {
235 if (buf[i] != i) {
236 errs++;
237 fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
238 mynod, i, buf[i], i);
241 else {
242 if (buf[i] != i + mynod*SIZE) {
243 errs++;
244 fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
245 mynod, i, buf[i], i + mynod*SIZE);
250 MPI_File_close(&fh);
252 MPI_Allreduce( &errs, &toterrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
253 if (mynod == 0) {
254 if( toterrs > 0) {
255 fprintf( stderr, "Found %d errors\n", toterrs );
257 else {
258 fprintf( stdout, " No Errors\n" );
261 MPI_Type_free(&newtype);
262 MPI_Info_free(&info);
263 free(buf);
264 free(filename);
265 MPI_Finalize();
266 return 0;