Skip to content

Commit 9a6439b

Browse files
committed
Test when size of fileview datatype is multiple of user buffer datatype
1 parent 56591cf commit 9a6439b

File tree

1 file changed

+207
-0
lines changed

1 file changed

+207
-0
lines changed

tests/ntimes_buftype.c

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2+
*
3+
* Copyright (C) 2024, Northwestern University
4+
*
5+
* This program tests collective write and read calls using a fileview datatype
6+
* of size that is a multiple of buffer datatype size.
7+
*
8+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
9+
10+
#include <stdio.h>
11+
#include <stdlib.h>
12+
#include <string.h> /* strcpy() */
13+
#include <unistd.h> /* getopt() */
14+
15+
#include <mpi.h>
16+
17+
#define ERR \
18+
if (err != MPI_SUCCESS) { \
19+
int errorStringLen; \
20+
char errorString[MPI_MAX_ERROR_STRING]; \
21+
MPI_Error_string(err, errorString, &errorStringLen); \
22+
printf("Error at line %d: %s\n",__LINE__,errorString); \
23+
nerrs++; \
24+
goto err_out; \
25+
}
26+
27+
static void
28+
usage(char *argv0)
29+
{
30+
char *help =
31+
"Usage: %s [-hq | -l len | -n num] -f file_name\n"
32+
" [-h] Print this help\n"
33+
" [-q] quiet mode\n"
34+
" [-l len] length of local X and Y dimension sizes\n"
35+
" [-n num] number of file datatype to be written\n"
36+
" -f filename: output file name\n";
37+
fprintf(stderr, help, argv0);
38+
}
39+
40+
/*----< main() >------------------------------------------------------------*/
41+
int main(int argc, char **argv)
42+
{
43+
extern int optind;
44+
extern char *optarg;
45+
char filename[256];
46+
int i, j, k, err, nerrs=0, rank, nprocs, mode, verbose=1, ntimes, len;
47+
int psizes[2], gsizes[2], subsizes[2], starts[2], lsizes[2];
48+
int local_rank[2], *buf=NULL, type_size, gap, max_nerrs;
49+
double timing, max_timing;
50+
MPI_Aint lb, displace[2], extent;
51+
MPI_Datatype bufType, fileType;
52+
MPI_File fh;
53+
MPI_Status status;
54+
MPI_Info info = MPI_INFO_NULL;
55+
56+
MPI_Init(&argc,&argv);
57+
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
58+
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
59+
60+
ntimes = 2;
61+
len = 100; /* default dimension size */
62+
gap = 4; /* gap between 2 blocks in bufType */
63+
filename[0] = '\0';
64+
65+
/* get command-line arguments */
66+
while ((i = getopt(argc, argv, "hql:n:f:")) != EOF)
67+
switch(i) {
68+
case 'q': verbose = 0;
69+
break;
70+
case 'n': ntimes = atoi(optarg);
71+
break;
72+
case 'l': len = atoi(optarg);
73+
break;
74+
case 'f': strcpy(filename, optarg);
75+
break;
76+
case 'h':
77+
default: if (rank==0) usage(argv[0]);
78+
MPI_Finalize();
79+
return 1;
80+
}
81+
82+
if (filename[0] == '\0') {
83+
if (rank==0) usage(argv[0]);
84+
MPI_Finalize();
85+
return 1;
86+
}
87+
88+
if (verbose && rank == 0) {
89+
printf("Creating a buffer datatype consisting of %d blocks\n",ntimes);
90+
printf("Each block is of size %d x %d (int)= %zd\n",
91+
len,len,len*len*sizeof(int));
92+
printf("Gap between two consecutive blocks is %d ints\n", gap);
93+
}
94+
95+
/* calculate number of processes along each dimension */
96+
psizes[0] = psizes[1] = 0;
97+
MPI_Dims_create(nprocs, 2, psizes);
98+
if (verbose && rank == 0)
99+
printf("process dimension psizes = %d %d\n", psizes[0], psizes[1]);
100+
101+
/* find its local rank IDs along each dimension */
102+
local_rank[0] = rank / psizes[1];
103+
local_rank[1] = rank % psizes[1];
104+
if (verbose)
105+
printf("rank %2d: local rank = %d %d\n",
106+
rank,local_rank[0],local_rank[1]);
107+
108+
/* create fileview data type */
109+
gsizes[0] = len * psizes[0] * ntimes; /* global array size */
110+
gsizes[1] = len * psizes[1];
111+
if (verbose && rank == 0)
112+
printf("global variable shape: %d %d\n", gsizes[0],gsizes[1]);
113+
114+
starts[0] = local_rank[0] * len * ntimes;
115+
starts[1] = local_rank[1] * len;
116+
subsizes[0] = len * ntimes;
117+
subsizes[1] = len;
118+
err = MPI_Type_create_subarray(2, gsizes, subsizes, starts, MPI_ORDER_C,
119+
MPI_INT, &fileType);
120+
ERR
121+
err = MPI_Type_commit(&fileType); ERR
122+
123+
MPI_Type_size(fileType, &type_size);
124+
lb = 0;
125+
MPI_Type_get_extent(fileType, &lb, &extent);
126+
if (verbose && rank == 0)
127+
printf("file type size = %d extent = %ld\n", type_size, extent);
128+
129+
/* create a datatype consists of 2 blocks, with a gap in between. The size
130+
* of data type should be equal to len*len * sizeof(int).
131+
*/
132+
lsizes[0] = lsizes[1] = len * len / 2;
133+
displace[0] = 0;
134+
displace[1] = (lsizes[0] + gap)* sizeof(int);
135+
err = MPI_Type_create_hindexed(2, lsizes, displace, MPI_INT, &bufType);
136+
ERR
137+
err = MPI_Type_commit(&bufType); ERR
138+
139+
/* allocate I/O buffer */
140+
MPI_Type_size(bufType, &type_size);
141+
lb = 0;
142+
MPI_Type_get_extent(bufType, &lb, &extent);
143+
if (verbose && rank == 0)
144+
printf("buffer type size = %d extent = %ld\n", type_size, extent);
145+
146+
buf = (int*) calloc(extent * ntimes, sizeof(int));
147+
j = 0;
148+
for (k=0; k<ntimes; k++) {
149+
for (i=0; i<lsizes[0]; i++, j++) buf[j] = 17 + rank + j;
150+
j += gap;
151+
for (i=0; i<lsizes[1]; i++, j++) buf[j] = 17 + rank + j;
152+
}
153+
154+
/* open file */
155+
mode = MPI_MODE_CREATE | MPI_MODE_RDWR;
156+
err = MPI_File_open(MPI_COMM_WORLD, filename, mode, info, &fh); ERR
157+
158+
/* set the file view */
159+
err = MPI_File_set_view(fh, 0, MPI_BYTE, fileType, "native", info);
160+
ERR
161+
162+
/* write to the file */
163+
MPI_Barrier(MPI_COMM_WORLD);
164+
timing = MPI_Wtime();
165+
err = MPI_File_write_all(fh, buf, ntimes, bufType, &status); ERR
166+
167+
for (i=0; i<len*len; i++) buf[i] = 0;
168+
err = MPI_File_seek(fh, 0, MPI_SEEK_SET); ERR
169+
err = MPI_File_read_all(fh, buf, ntimes, bufType, &status); ERR
170+
timing = MPI_Wtime() - timing;
171+
172+
j = 0;
173+
for (k=0; k<ntimes; k++) {
174+
for (i=0; i<lsizes[0]; i++, j++) {
175+
int exp = 17 + rank + j;
176+
if (buf[j] != exp) {
177+
printf("Error: buf[%d] expect %d but got %d\n", j, exp, buf[j]);
178+
nerrs++;
179+
break;
180+
}
181+
}
182+
j += gap;
183+
for (i=0; i<lsizes[1]; i++, j++) {
184+
int exp = 17 + rank + j;
185+
if (buf[j] != exp) {
186+
printf("Error: buf[%d] expect %d but got %d\n", j, exp, buf[j]);
187+
nerrs++;
188+
break;
189+
}
190+
}
191+
}
192+
193+
err = MPI_File_close(&fh); ERR
194+
err = MPI_Type_free(&bufType); ERR
195+
err = MPI_Type_free(&fileType); ERR
196+
free(buf);
197+
198+
MPI_Allreduce(&nerrs, &max_nerrs, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
199+
MPI_Reduce(&timing, &max_timing, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
200+
if (max_nerrs == 0 && rank == 0)
201+
printf("Time of collective write and read = %.2f sec\n", max_timing);
202+
203+
err_out:
204+
MPI_Finalize();
205+
return (nerrs > 0);
206+
}
207+

0 commit comments

Comments
 (0)