Skip to content

Commit a5a75b5

Browse files
committed
add hindexed_fsize.c
1 parent 35bfa60 commit a5a75b5

File tree

1 file changed

+176
-0
lines changed

1 file changed

+176
-0
lines changed

hindexed_fsize.c

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2+
*
3+
* Copyright (C) 2024, Northwestern University
4+
* See COPYRIGHT notice in top-level directory.
5+
*
6+
* This program tests collective write using a file datatype constructed from
7+
* multiple subarray datatypes concatenated by MPI_Type_create_hindexed(). Each
8+
* variable is partitioned among processes in a 2D block-block fashion. At the
9+
* end, it checks the file size whether or not it is expected.
10+
*
11+
* This program is the same as indexed_fsize.c, except it calls
12+
* MPI_Type_create_hindexed(), while indexed_fsize.c.c calls
13+
* MPI_Type_hindexed().
14+
*
15+
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
16+
17+
#include <stdio.h>
18+
#include <stdlib.h>
19+
#include <string.h>
20+
#include <unistd.h>
21+
#include <fcntl.h>
22+
#include <sys/types.h>
23+
24+
#include <mpi.h>
25+
26+
#define ERR \
27+
if (err != MPI_SUCCESS) { \
28+
int errorStringLen; \
29+
char errorString[MPI_MAX_ERROR_STRING]; \
30+
MPI_Error_string(err, errorString, &errorStringLen); \
31+
printf("Error at line %d: %s\n",__LINE__,errorString); \
32+
nerrs++; \
33+
goto err_out; \
34+
}
35+
36+
static void
37+
usage(char *argv0)
38+
{
39+
char *help =
40+
"Usage: %s [-hqrc | -n num | -l len ] -f file_name\n"
41+
" [-h] Print this help\n"
42+
" [-q] quiet mode\n"
43+
" [-n num] number of variables to be written\n"
44+
" [-l len] length of local X and Y dimension sizes\n"
45+
" -f filename: output file name\n";
46+
fprintf(stderr, help, argv0);
47+
}
48+
49+
/*----< main() >------------------------------------------------------------*/
50+
int main(int argc, char **argv)
51+
{
52+
extern int optind;
53+
extern char *optarg;
54+
char filename[256], *buf;
55+
int i, rank, nprocs, err, nerrs=0, verbose, omode, nvars, len;
56+
int psizes[2], sizes[2], subsizes[2], starts[2], *blks;
57+
MPI_Aint *disp;
58+
MPI_Datatype subType, fileType;
59+
MPI_File fh;
60+
MPI_Status status;
61+
MPI_Info info=MPI_INFO_NULL;
62+
63+
MPI_Init(&argc,&argv);
64+
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
65+
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
66+
67+
verbose = 1;
68+
nvars = 2; /* default number of variables */
69+
len = 10; /* default dimension size */
70+
filename[0] = '\0';
71+
72+
/* get command-line arguments */
73+
while ((i = getopt(argc, argv, "hqn:l:f:")) != EOF)
74+
switch(i) {
75+
case 'q': verbose = 0;
76+
break;
77+
case 'n': nvars = atoi(optarg);
78+
break;
79+
case 'l': len = atoi(optarg);
80+
break;
81+
case 'f': strcpy(filename, optarg);
82+
break;
83+
case 'h':
84+
default: if (rank==0) usage(argv[0]);
85+
MPI_Finalize();
86+
return 1;
87+
}
88+
89+
if (filename[0] == '\0') {
90+
if (rank==0) usage(argv[0]);
91+
MPI_Finalize();
92+
return 1;
93+
}
94+
95+
if (verbose && rank == 0) {
96+
printf("Number of MPI processes: %d\n",nprocs);
97+
printf("Number of varaibles: %d\n",nvars);
98+
printf("Each subarray is of size: %d x %d (int) = %zd\n",
99+
len, len, sizeof(int)*len*len);
100+
}
101+
102+
/* calculate number of processes along each dimension */
103+
psizes[0] = psizes[1] = 0;
104+
err = MPI_Dims_create(nprocs, 2, psizes); ERR
105+
106+
if (verbose)
107+
printf("%d: 2D rank IDs: %d, %d\n",rank,rank/psizes[1], rank%psizes[1]);
108+
109+
/* create a subarray datatype */
110+
sizes[0] = len * psizes[0];
111+
sizes[1] = len * psizes[1];
112+
subsizes[0] = len;
113+
subsizes[1] = len;
114+
starts[0] = len * (rank / psizes[1]);
115+
starts[1] = len * (rank % psizes[1]);
116+
err = MPI_Type_create_subarray(2, sizes, subsizes, starts, MPI_ORDER_C,
117+
MPI_BYTE, &subType); ERR
118+
119+
if (verbose)
120+
printf("%d: sizes=%d %d subsizes=%d %d starts=%d %d\n",rank,
121+
sizes[0],sizes[1], subsizes[0],subsizes[1], starts[0],starts[1]);
122+
123+
/* concatenate nvars subTypes into fileType */
124+
disp = (MPI_Aint*) malloc(sizeof(MPI_Aint) * nvars);
125+
blks = (int*) malloc(sizeof(int) * nvars);
126+
for (i=0; i<nvars; i++) {
127+
disp[i] = (MPI_Aint)i * sizes[0] * sizes[1];
128+
blks[i] = 1;
129+
}
130+
err = MPI_Type_create_hindexed(nvars, blks, disp, subType, &fileType); ERR
131+
err = MPI_Type_commit(&fileType); ERR
132+
133+
err = MPI_Type_free(&subType); ERR
134+
free(disp);
135+
free(blks);
136+
137+
/* allocate I/O buffers */
138+
buf = (char*)malloc(nvars * len * len);
139+
140+
/* open file and truncate it to zero sized */
141+
omode = MPI_MODE_CREATE | MPI_MODE_RDWR;
142+
err = MPI_File_open(MPI_COMM_WORLD, "dummy", omode, info, &fh); ERR
143+
err = MPI_File_set_size(fh, 0); ERR
144+
145+
/* set the file view */
146+
err = MPI_File_set_view(fh, 0, MPI_BYTE, fileType, "native", info); ERR
147+
err = MPI_Type_free(&fileType); ERR
148+
149+
/* write to the file */
150+
err = MPI_File_write_all(fh, buf, len*len*nvars, MPI_BYTE, &status); ERR
151+
152+
/* flush and close the file */
153+
err = MPI_Barrier(MPI_COMM_WORLD); ERR
154+
err = MPI_File_sync(fh); ERR
155+
err = MPI_Barrier(MPI_COMM_WORLD); ERR
156+
err = MPI_File_close(&fh); ERR
157+
err = MPI_Barrier(MPI_COMM_WORLD); ERR
158+
159+
/* check file size */
160+
if (rank == 0) {
161+
int fd = open("dummy", O_RDONLY, 0600);
162+
off_t fsize = lseek(fd, 0, SEEK_END);
163+
off_t expected = len * len * nvars * nprocs;
164+
if (fsize != expected)
165+
printf("Error: expecting file size %lld, but got %lld\n", expected, fsize);
166+
else
167+
printf("Test passed\n");
168+
close(fd);
169+
}
170+
free(buf);
171+
172+
err_out:
173+
MPI_Finalize();
174+
return (nerrs > 0);
175+
}
176+

0 commit comments

Comments
 (0)