1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
3 * (C) 2001 by Argonne National Laboratory.
4 * See COPYRIGHT in top-level directory.
11 /* tests noncontiguous reads/writes using independent I/O */
16 int main(int argc
, char **argv
)
18 int *buf
, i
, mynod
, nprocs
, len
, b
[3];
24 MPI_Datatype typevec
, newtype
, t
[3];
27 MPI_Init(&argc
,&argv
);
28 MPI_Comm_size(MPI_COMM_WORLD
, &nprocs
);
29 MPI_Comm_rank(MPI_COMM_WORLD
, &mynod
);
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) */
40 while ((i
< argc
) && strcmp("-fname", *argv
)) {
45 fprintf(stderr
, "\n*# Usage: noncontig -fname filename\n\n");
46 MPI_Abort(MPI_COMM_WORLD
, 1);
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
);
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
69 b
[0] = b
[1] = b
[2] = 1;
71 d
[1] = mynod
*sizeof(int);
72 d
[2] = SIZE
*sizeof(int);
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");
90 fprintf(stderr
, "\ntesting noncontiguous in memory, noncontiguous in file using independent I/O\n");
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
,
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
++) {
122 if ((i
%2) && (buf
[i
] != -1)) {
124 fprintf(stderr
, "Process %d: buf %d is %d, should be -1\n",
127 if (!(i
%2) && (buf
[i
] != i
)) {
129 fprintf(stderr
, "Process %d: buf %d is %d, should be %d\n",
130 mynod
, i
, buf
[i
], i
);
134 if ((i
%2) && (buf
[i
] != i
+ mynod
*SIZE
)) {
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)) {
141 fprintf(stderr
, "Process %d: buf %d is %d, should be -1\n",
149 MPI_Barrier(MPI_COMM_WORLD
);
153 fprintf(stderr
, "\ntesting noncontiguous in memory, contiguous in file using independent I/O\n");
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
,
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
++) {
180 if ((i
%2) && (buf
[i
] != -1)) {
182 fprintf(stderr
, "Process %d: buf %d is %d, should be -1\n",
185 if (!(i
%2) && (buf
[i
] != i
)) {
187 fprintf(stderr
, "Process %d: buf %d is %d, should be %d\n",
188 mynod
, i
, buf
[i
], i
);
192 if ((i
%2) && (buf
[i
] != i
+ mynod
*SIZE
)) {
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)) {
199 fprintf(stderr
, "Process %d: buf %d is %d, should be -1\n",
207 MPI_Barrier(MPI_COMM_WORLD
);
211 fprintf(stderr
, "\ntesting contiguous in memory, noncontiguous in file using independent I/O\n");
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
,
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
++) {
237 fprintf(stderr
, "Process %d: buf %d is %d, should be %d\n",
238 mynod
, i
, buf
[i
], i
);
242 if (buf
[i
] != i
+ mynod
*SIZE
) {
244 fprintf(stderr
, "Process %d: buf %d is %d, should be %d\n",
245 mynod
, i
, buf
[i
], i
+ mynod
*SIZE
);
252 MPI_Allreduce( &errs
, &toterrs
, 1, MPI_INT
, MPI_SUM
, MPI_COMM_WORLD
);
255 fprintf( stderr
, "Found %d errors\n", toterrs
);
258 fprintf( stdout
, " No Errors\n" );
261 MPI_Type_free(&newtype
);
262 MPI_Info_free(&info
);