Skip to content

Commit 18499ae

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

File tree

1 file changed

+205
-0
lines changed

1 file changed

+205
-0
lines changed

tests/ntimes_filetype.c

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2+
*
3+
* Copyright (C) 2024, Northwestern University
4+
*
5+
* This program tests collective write and read calls using a user buffer
6+
* datatype whose size is a multiple of the fileview 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;
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]; /* 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;
115+
starts[1] = local_rank[1] * len;
116+
subsizes[0] = len;
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);
122+
ERR
123+
124+
MPI_Type_size(fileType, &type_size);
125+
lb = 0;
126+
MPI_Type_get_extent(fileType, &lb, &extent);
127+
if (verbose && rank == 0)
128+
printf("file type size = %d extent = %ld\n", type_size, extent);
129+
130+
/* create a datatype consists of ntimes blocks, with a gap in between.
131+
* Each block is of size the same as fileType size.
132+
*/
133+
lsizes = (int*) malloc(ntimes * sizeof(int));
134+
for (i=0; i<ntimes; i++) {
135+
lsizes[i] = len * len;
136+
displace[i] = (len * len + gap) * sizeof(int) * i;
137+
}
138+
err = MPI_Type_create_hindexed(ntimes, lsizes, displace, MPI_INT, &bufType);
139+
ERR
140+
err = MPI_Type_commit(&bufType); ERR
141+
free(lsizes);
142+
143+
/* allocate I/O buffer */
144+
MPI_Type_size(bufType, &type_size);
145+
lb = 0;
146+
MPI_Type_get_extent(bufType, &lb, &extent);
147+
if (verbose && rank == 0)
148+
printf("buffer type size = %d extent = %ld\n", type_size, extent);
149+
150+
buf = (int*) malloc(extent * sizeof(int));
151+
k = 0;
152+
for (i=0; i<ntimes; i++) {
153+
for (j=0; j<len*len; j++, k++) buf[k] = 17 + rank + k;
154+
k += gap;
155+
}
156+
157+
/* open file */
158+
mode = MPI_MODE_CREATE | MPI_MODE_RDWR;
159+
err = MPI_File_open(MPI_COMM_WORLD, filename, mode, info, &fh); ERR
160+
161+
/* set the file view */
162+
err = MPI_File_set_view(fh, 0, MPI_BYTE, fileType, "native", info);
163+
ERR
164+
165+
/* write to the file */
166+
MPI_Barrier(MPI_COMM_WORLD);
167+
timing = MPI_Wtime();
168+
err = MPI_File_write_all(fh, buf, 1, bufType, &status); ERR
169+
170+
for (i=0; i<extent; i++) buf[i] = 0;
171+
172+
err = MPI_File_seek(fh, 0, MPI_SEEK_SET); ERR
173+
err = MPI_File_read_all(fh, buf, 1, bufType, &status); ERR
174+
timing = MPI_Wtime() - timing;
175+
176+
/* check contents of read buffer */
177+
k = 0;
178+
for (i=0; i<ntimes; i++) {
179+
for (j=0; j<len*len; j++, k++) {
180+
int exp = 17 + rank + k;
181+
if (buf[k] != exp) {
182+
printf("Error: buf[%d] expect %d but got %d\n", k, exp, buf[k]);
183+
nerrs++;
184+
i = ntimes;
185+
break;
186+
}
187+
}
188+
k += gap;
189+
}
190+
191+
err = MPI_File_close(&fh); ERR
192+
err = MPI_Type_free(&bufType); ERR
193+
err = MPI_Type_free(&fileType); ERR
194+
free(buf);
195+
196+
MPI_Allreduce(&nerrs, &max_nerrs, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
197+
MPI_Reduce(&timing, &max_timing, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
198+
if (max_nerrs == 0 && rank == 0)
199+
printf("Time of collective write and read = %.2f sec\n", max_timing);
200+
201+
err_out:
202+
MPI_Finalize();
203+
return (nerrs > 0);
204+
}
205+

0 commit comments

Comments
 (0)