/********************************************************************* * * Copyright (C) 2014, Northwestern University and Argonne National Laboratory * See COPYRIGHT notice in top-level directory. * *********************************************************************/ /* $Id$ */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This example shows how to use a single call of NcmpiVar::putVarn_all() * to write a sequence of one-element requests with arbitrary array indices. * * The compile and run commands are given below, together with an ncmpidump of * the output file. * * % mpicxx -O2 -o put_varn_float put_varn_float.cpp -lpnetcdf * % mpiexec -n 4 ./put_varn_float /pvfs2/wkliao/testfile.nc * % ncmpidump /pvfs2/wkliao/testfile.nc * netcdf testfile { * // file format: CDF-5 (big variables) * dimensions: * Y = 4 ; * X = 10 ; * variables: * int var(Y, X) ; * data: * * var = * 3, 3, 3, 1, 1, 0, 0, 2, 1, 1, * 0, 2, 2, 2, 3, 1, 1, 2, 2, 2, * 1, 1, 2, 3, 3, 3, 0, 0, 1, 1, * 0, 0, 0, 2, 1, 1, 1, 3, 3, 3 ; * } * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include using namespace std; #include /* strcpy(), strncpy() */ #include /* getopt() */ #include using namespace PnetCDF; using namespace PnetCDF::exceptions; #define NY 4 #define NX 10 #define NDIMS 2 static void usage(char *argv0) { cerr << "Usage: %s [-h] | [-q] [file_name]\n" " [-h] Print help\n" " [-q] Quiet mode (reports when fail)\n" " [filename] output netCDF file name\n" << argv0; } int main(int argc, char** argv) { extern int optind; char filename[256]; int i, verbose=1, rank, nprocs, num_reqs; float *buffer; MPI_Offset **starts=NULL; 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, "hq")) != EOF) switch(i) { case 'q': verbose = 0; 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]); if (nprocs != 4 && rank == 0 && verbose) printf("Warning: this program is intended to run on 4 processes\n"); try { /* create a new file for writing -------------------------------------*/ NcmpiFile nc(MPI_COMM_WORLD, filename, NcmpiFile::replace, NcmpiFile::classic); /* define dimensions Y and X */ vector dimid(2); dimid[0] = nc.addDim("Y", NY); dimid[1] = nc.addDim("X", NX); /* define a 2D variable of integer type */ NcmpiVar var = nc.addVar("var", ncmpiFloat, dimid); /* pick arbitrary numbers of requests for 4 processes */ num_reqs = 0; if (rank == 0) num_reqs = 8; else if (rank == 1) num_reqs = 13; else if (rank == 2) num_reqs = 9; else if (rank == 3) num_reqs = 10; if (num_reqs > 0) { starts = (MPI_Offset**)malloc(num_reqs* sizeof(MPI_Offset*)); starts[0] = (MPI_Offset*) calloc(num_reqs*NDIMS, sizeof(MPI_Offset)); for (i=1; i 0) { free(starts[0]); free(starts); } /* file is close implicitly */ } catch(NcmpiException& e) { cout << e.what() << " error code=" << e.errorCode() << " Error!\n"; return 1; } /* check if there is any PnetCDF internal malloc residue */ MPI_Offset malloc_size, sum_size; int err = ncmpi_inq_malloc_size(&malloc_size); if (err == NC_NOERR) { MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD); if (rank == 0 && sum_size > 0) printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n", sum_size); } MPI_Finalize(); return 0; }