/********************************************************************* * * Copyright (C) 2012, Northwestern University and Argonne National Laboratory * See COPYRIGHT notice in top-level directory. * *********************************************************************/ /* $Id$ */ /* This example is similar to collective_write.c but using nonblocking APIs. * It creates a netcdf file in CD-5 format and writes a number of * 3D integer non-record variables. The measured write bandwidth is reported * at the end. Usage: (for example) * To compile: * mpicc -O2 nonblocking_write.c -o nonblocking_write -lpnetcdf * To run: * mpiexec -n num_processes ./nonblocking_write [filename] [len] * where len decides the size of each local array, which is len x len x len. * So, each non-record variable is of size len*len*len * nprocs * sizeof(int) * All variables are partitioned among all processes in a 3D * block-block-block fashion. Below is an example standard output from * command: * mpiexec -n 32 ./nonblocking_write /pvfs2/wkliao/testfile.nc 100 * * MPI hint: cb_nodes = 2 * MPI hint: cb_buffer_size = 16777216 * MPI hint: striping_factor = 32 * MPI hint: striping_unit = 1048576 * Local array size 100 x 100 x 100 integers, size = 3.81 MB * Global array size 400 x 400 x 200 integers, write size = 0.30 GB * procs Global array size exec(sec) write(MB/s) * ------- ------------------ --------- ----------- * 32 400 x 400 x 200 6.67 45.72 */ #include #include #include /* strcpy(), strncpy() */ #include /* getopt() */ #include #include #define NDIMS 3 #define NUM_VARS 10 #define ERR {if(err!=NC_NOERR){printf("Error at line %d in %s: %s\n", __LINE__,__FILE__, ncmpi_strerror(err));nerrs++;}} static void usage(char *argv0) { char *help = "Usage: %s [-h] | [-q] [-l len] [file_name]\n" " [-h] Print help\n" " [-q] Quiet mode (reports when fail)\n" " [-l len] size of each dimension of the local array\n" " [filename] output netCDF file name\n"; fprintf(stderr, help, argv0); } /*----< print_info() >------------------------------------------------------*/ static void print_info(MPI_Info *info_used) { int flag; char info_cb_nodes[64], info_cb_buffer_size[64]; char info_striping_factor[64], info_striping_unit[64]; strcpy(info_cb_nodes, "undefined"); strcpy(info_cb_buffer_size, "undefined"); strcpy(info_striping_factor, "undefined"); strcpy(info_striping_unit, "undefined"); MPI_Info_get(*info_used, "cb_nodes", 64, info_cb_nodes, &flag); MPI_Info_get(*info_used, "cb_buffer_size", 64, info_cb_buffer_size, &flag); MPI_Info_get(*info_used, "striping_factor", 64, info_striping_factor, &flag); MPI_Info_get(*info_used, "striping_unit", 64, info_striping_unit, &flag); printf("MPI hint: cb_nodes = %s\n", info_cb_nodes); printf("MPI hint: cb_buffer_size = %s\n", info_cb_buffer_size); printf("MPI hint: striping_factor = %s\n", info_striping_factor); printf("MPI hint: striping_unit = %s\n", info_striping_unit); } /*----< main() >------------------------------------------------------------*/ int main(int argc, char **argv) { extern int optind; int i, j, verbose=1, err, nerrs=0; int nprocs, len=0, *buf[NUM_VARS], bufsize, rank; int gsizes[NDIMS], psizes[NDIMS]; double write_timing, max_write_timing, write_bw; char filename[256], str[512]; int ncid, dimids[NDIMS], varids[NUM_VARS], req[NUM_VARS], st[NUM_VARS]; MPI_Offset starts[NDIMS], counts[NDIMS], write_size, sum_write_size; MPI_Offset bbufsize; MPI_Info info, info_used; MPI_Init(&argc,&argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); /* get command-line arguments */ while ((i = getopt(argc, argv, "hql:")) != EOF) switch(i) { case 'q': verbose = 0; break; case 'l': len = atoi(optarg); break; case 'h': default: if (rank==0) usage(argv[0]); MPI_Finalize(); return 1; } if (argv[optind] == NULL) strcpy(filename, "testfile.nc"); else snprintf(filename, 256, "%s", argv[optind]); len = (len <= 0) ? 10 : len; for (i=0; i 0) printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n", sum_size); } MPI_Finalize(); return (nerrs > 0); }