diff --git a/tests/ntimes_filetype.c b/tests/ntimes_filetype.c new file mode 100644 index 0000000..25744d1 --- /dev/null +++ b/tests/ntimes_filetype.c @@ -0,0 +1,206 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Copyright (C) 2024, Northwestern University + * + * This program tests collective write and read calls using a user buffer + * datatype whose size is a multiple of the fileview datatype size. + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include +#include +#include /* strcpy() */ +#include /* getopt() */ + +#include + +#define ERR \ + if (err != MPI_SUCCESS) { \ + int errorStringLen; \ + char errorString[MPI_MAX_ERROR_STRING]; \ + MPI_Error_string(err, errorString, &errorStringLen); \ + printf("Error at line %d: %s\n",__LINE__,errorString); \ + nerrs++; \ + goto err_out; \ + } + +static void +usage(char *argv0) +{ + char *help = + "Usage: %s [-hq | -l len | -n num] -f file_name\n" + " [-h] Print this help\n" + " [-q] quiet mode\n" + " [-l len] length of local X and Y dimension sizes\n" + " [-n num] number of file datatype to be written\n" + " -f filename: output file name\n"; + fprintf(stderr, help, argv0); +} + +/*----< main() >------------------------------------------------------------*/ +int main(int argc, char **argv) +{ + extern int optind; + extern char *optarg; + char filename[256]; + int i, j, k, err, nerrs=0, rank, nprocs, mode, verbose=1, ntimes, len; + int psizes[2], gsizes[2], subsizes[2], starts[2], *lsizes; + int fd, local_rank[2], *buf=NULL, *buf_ptr, type_size, gap, max_nerrs; + double timing, max_timing; + MPI_Aint lb, displace[2], extent; + MPI_Datatype bufType, fileType; + MPI_File fh; + MPI_Offset off; + MPI_Status status; + MPI_Info info = MPI_INFO_NULL; + + MPI_Init(&argc,&argv); + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + ntimes = 2; + len = 100; /* default dimension size */ + gap = 4; /* gap between 2 blocks in bufType */ + filename[0] = '\0'; + + /* get command-line arguments */ + while ((i = getopt(argc, argv, "hql:n:f:")) != EOF) + switch(i) { + case 'q': verbose = 0; + break; + case 'n': ntimes = atoi(optarg); + break; + case 'l': len = atoi(optarg); + break; + case 'f': strcpy(filename, optarg); + break; + case 'h': + default: if (rank==0) usage(argv[0]); + MPI_Finalize(); + return 1; + } + + if (filename[0] == '\0') { + if (rank==0) usage(argv[0]); + MPI_Finalize(); + return 1; + } + + if (verbose && rank == 0) { + printf("Creating a buffer datatype consisting of %d blocks\n",ntimes); + printf("Each block is of size %d x %d (int) = %zd\n", + len, len, len*len*sizeof(int)); + printf("Gap between two consecutive blocks is %d ints\n", gap); + } + + /* calculate number of processes along each dimension */ + psizes[0] = psizes[1] = 0; + MPI_Dims_create(nprocs, 2, psizes); + if (verbose && rank == 0) + printf("process dimension psizes = %d %d\n", psizes[0], psizes[1]); + + /* find its local rank IDs along each dimension */ + local_rank[0] = rank / psizes[1]; + local_rank[1] = rank % psizes[1]; + if (verbose) + printf("rank %2d: local rank = %d %d\n", + rank,local_rank[0],local_rank[1]); + + /* create fileview data type */ + gsizes[0] = len * psizes[0]; /* global array size */ + gsizes[1] = len * psizes[1]; + if (verbose && rank == 0) + printf("global variable shape: %d %d\n", gsizes[0],gsizes[1]); + + starts[0] = local_rank[0] * len; + starts[1] = local_rank[1] * len; + subsizes[0] = len; + subsizes[1] = len; + err = MPI_Type_create_subarray(2, gsizes, subsizes, starts, MPI_ORDER_C, + MPI_INT, &fileType); + ERR + err = MPI_Type_commit(&fileType); + ERR + + MPI_Type_size(fileType, &type_size); + lb = 0; + MPI_Type_get_extent(fileType, &lb, &extent); + if (verbose && rank == 0) + printf("file type size = %d extent = %ld\n", type_size, extent); + + /* create a datatype consists of ntimes blocks, with a gap in between. + * Each block is of size the same as fileType size. + */ + lsizes = (int*) malloc(ntimes * sizeof(int)); + for (i=0; i 0); +} +