FORTRAN_API int FORT_CALL nfmpi_put_vara_double_all_ ( int *v1, int *v2, MPI_Offset v3[], MPI_Offset v4[], double*v5 ){ int ierr; int l2 = *v2 - 1; MPI_Offset *l3 = 0; MPI_Offset *l4 = 0; { int ln = ncmpixVardim(*v1,*v2-1); if (ln > 0) { int li; l3 = (MPI_Offset *)malloc( ln * sizeof(MPI_Offset) ); for (li=0; li<ln; li++) l3[li] = v3[ln-1-li] - 1; } else if (ln < 0) { /* Error return */ ierr = ln; return ierr; } } { int ln = ncmpixVardim(*v1,*v2-1); if (ln > 0) { int li; l4 = (MPI_Offset *)malloc( ln * sizeof(MPI_Offset) ); for (li=0; li<ln; li++) l4[li] = v4[ln-1-li]; } else if (ln < 0) { /* Error return */ ierr = ln; return ierr; } } ierr = ncmpi_put_vara_double_all( *v1, l2, l3, l4, v5 ); if (l3) { free(l3); } if (l4) { free(l4); } return ierr; }
// Traj_NcEnsemble::writeArray() // TODO RemdValues int Traj_NcEnsemble::writeArray(int set, FramePtrArray const& Farray) { # ifdef HAS_PNETCDF MPI_Offset pstart_[4]; MPI_Offset pcount_[4]; # define start_ pstart_ # define count_ pcount_ # endif start_[0] = ncframe_; // Frame start_[2] = 0; // Atoms start_[3] = 0; // XYZ count_[0] = 1; // Frame count_[1] = 1; // Ensemble count_[3] = 3; // XYZ for (int member = ensembleStart_; member != ensembleEnd_; member++) { //rprintf("DEBUG: Writing set %i, member %i\n", set+1, member); # ifdef MPI Frame* frm = Farray[0]; # else Frame* frm = Farray[member]; # endif start_[1] = member; // Ensemble count_[2] = Ncatom(); // Atoms // Write Coords //DebugIndices(); // DEBUG DoubleToFloat(Coord_, frm->xAddress()); # ifdef HAS_PNETCDF if (ncmpi_put_vara_float_all(ncid_, coordVID_, start_, count_, Coord_)) # else if (NC::CheckErr(nc_put_vara_float(ncid_, coordVID_, start_, count_, Coord_))) # endif { mprinterr("Error: Netcdf Writing coords frame %i\n", set+1); return 1; } // Write velocity. if (velocityVID_ != -1) { DoubleToFloat(Coord_, frm->vAddress()); # ifdef HAS_PNETCDF if (ncmpi_put_vara_float_all(ncid_, velocityVID_, start_, count_, Coord_)) # else if (NC::CheckErr(nc_put_vara_float(ncid_, velocityVID_, start_, count_, Coord_)) ) # endif { mprinterr("Error: Netcdf writing velocity frame %i\n", set+1); return 1; } } // Write box if (cellLengthVID_ != -1) { count_[2] = 3; # ifdef HAS_PNETCDF if (ncmpi_put_vara_double_all(ncid_,cellLengthVID_,start_,count_,frm->bAddress())) # else if (NC::CheckErr(nc_put_vara_double(ncid_,cellLengthVID_,start_,count_,frm->bAddress())) ) # endif { mprinterr("Error: Writing cell lengths frame %i.\n", set+1); return 1; } # ifdef HAS_PNETCDF if (ncmpi_put_vara_double_all(ncid_,cellAngleVID_,start_,count_,frm->bAddress()+3)) # else if (NC::CheckErr(nc_put_vara_double(ncid_,cellAngleVID_,start_,count_,frm->bAddress()+3))) # endif { mprinterr("Error: Writing cell angles frame %i.\n", set+1); return 1; } } // Write temperature if (TempVID_!=-1) { # ifdef HAS_PNETCDF if (ncmpi_put_vara_double_all(ncid_,TempVID_,start_,count_,frm->tAddress())) # else if (NC::CheckErr(nc_put_vara_double(ncid_,TempVID_,start_,count_,frm->tAddress()))) # endif { mprinterr("Error: Writing temperature frame %i.\n", set+1); return 1; } } // Write indices if (indicesVID_ != -1) { count_[2] = remd_dimension_; # ifdef HAS_PNETCDF if (ncmpi_put_vara_int_all(ncid_,indicesVID_,start_,count_,frm->iAddress())) # else if (NC::CheckErr(nc_put_vara_int(ncid_,indicesVID_,start_,count_,frm->iAddress()))) # endif { mprinterr("Error: Writing indices frame %i.\n", set+1); return 1; } } } # ifdef HAS_PNETCDF //ncmpi_sync(ncid_); # else nc_sync(ncid_); // Necessary after every write?? # endif ++ncframe_; # ifdef HAS_PNETCDF // DEBUG # undef start_ # undef count_ # endif return 0; }
/* write out variable's data from in-memory structure */ void load_netcdf(void *rec_start) { int i, idim; int stat = NC_NOERR; MPI_Offset *start, *count; char *charvalp = NULL; short *shortvalp = NULL; int *intvalp = NULL; float *floatvalp = NULL; double *doublevalp = NULL; unsigned char *ubytevalp = NULL; unsigned short *ushortvalp = NULL; unsigned int *uintvalp = NULL; long long *int64valp = NULL; unsigned long long *uint64valp = NULL; MPI_Offset total_size; /* load values into variable */ switch (vars[varnum].type) { case NC_CHAR: case NC_BYTE: charvalp = (char *) rec_start; break; case NC_SHORT: shortvalp = (short *) rec_start; break; case NC_INT: intvalp = (int *) rec_start; break; case NC_FLOAT: floatvalp = (float *) rec_start; break; case NC_DOUBLE: doublevalp = (double *) rec_start; break; case NC_UBYTE: ubytevalp = (unsigned char *) rec_start; break; case NC_USHORT: ushortvalp = (unsigned short *) rec_start; break; case NC_UINT: uintvalp = (unsigned int *) rec_start; break; case NC_INT64: int64valp = (long long *) rec_start; break; case NC_UINT64: uint64valp = (unsigned long long *) rec_start; break; default: derror("Unhandled type %d\n", vars[varnum].type); break; } start = (MPI_Offset*) malloc(vars[varnum].ndims * 2 * sizeof(MPI_Offset)); count = start + vars[varnum].ndims; if (vars[varnum].ndims > 0) { /* initialize start to upper left corner (0,0,0,...) */ start[0] = 0; if (vars[varnum].dims[0] == rec_dim) { count[0] = vars[varnum].nrecs; } else { count[0] = dims[vars[varnum].dims[0]].size; } } for (idim = 1; idim < vars[varnum].ndims; idim++) { start[idim] = 0; count[idim] = dims[vars[varnum].dims[idim]].size; } total_size = nctypesize(vars[varnum].type); for (idim=0; idim<vars[varnum].ndims; idim++) total_size *= count[idim]; /* If the total put size is more than 2GB, then put one subarray at a time. * Here the subarray is from 1, 2, ... ndims, except 0. * This is not a perfect solution. To be improved. */ if (total_size > INT_MAX) { MPI_Offset nchunks=count[0]; MPI_Offset subarray_nelems=1; for (idim=1; idim<vars[varnum].ndims; idim++) subarray_nelems *= count[idim]; count[0] = 1; switch (vars[varnum].type) { case NC_BYTE: for (i=0; i<nchunks; i++) { start[0] = i; stat = ncmpi_put_vara_schar_all(ncid, varnum, start, count, (signed char *)charvalp); check_err(stat, "ncmpi_put_vara_schar_all", __func__, __LINE__, __FILE__); charvalp += subarray_nelems; } break; case NC_CHAR: for (i=0; i<nchunks; i++) { start[0] = i; stat = ncmpi_put_vara_text_all(ncid, varnum, start, count, charvalp); check_err(stat, "ncmpi_put_vara_text_all", __func__, __LINE__, __FILE__); charvalp += subarray_nelems; } break; case NC_SHORT: for (i=0; i<nchunks; i++) { start[0] = i; stat = ncmpi_put_vara_short_all(ncid, varnum, start, count, shortvalp); check_err(stat, "ncmpi_put_vara_short_all", __func__, __LINE__, __FILE__); shortvalp += subarray_nelems; } break; case NC_INT: for (i=0; i<nchunks; i++) { start[0] = i; stat = ncmpi_put_vara_int_all(ncid, varnum, start, count, intvalp); check_err(stat, "ncmpi_put_vara_int_all", __func__, __LINE__, __FILE__); intvalp += subarray_nelems; } break; case NC_FLOAT: for (i=0; i<nchunks; i++) { start[0] = i; stat = ncmpi_put_vara_float_all(ncid, varnum, start, count, floatvalp); check_err(stat, "ncmpi_put_vara_float_all", __func__, __LINE__, __FILE__); floatvalp += subarray_nelems; } break; case NC_DOUBLE: for (i=0; i<nchunks; i++) { start[0] = i; stat = ncmpi_put_vara_double_all(ncid, varnum, start, count, doublevalp); check_err(stat, "ncmpi_put_vara_double_all", __func__, __LINE__, __FILE__); doublevalp += subarray_nelems; } break; case NC_UBYTE: for (i=0; i<nchunks; i++) { start[0] = i; stat = ncmpi_put_vara_uchar_all(ncid, varnum, start, count, ubytevalp); check_err(stat, "ncmpi_put_vara_uchar_all", __func__, __LINE__, __FILE__); ubytevalp += subarray_nelems; } break; case NC_USHORT: for (i=0; i<nchunks; i++) { start[0] = i; stat = ncmpi_put_vara_ushort_all(ncid, varnum, start, count, ushortvalp); check_err(stat, "ncmpi_put_vara_ushort_all", __func__, __LINE__, __FILE__); ushortvalp += subarray_nelems; } break; case NC_UINT: for (i=0; i<nchunks; i++) { start[0] = i; stat = ncmpi_put_vara_uint_all(ncid, varnum, start, count, uintvalp); check_err(stat, "ncmpi_put_vara_uint_all", __func__, __LINE__, __FILE__); uintvalp += subarray_nelems; } break; case NC_INT64: for (i=0; i<nchunks; i++) { start[0] = i; stat = ncmpi_put_vara_longlong_all(ncid, varnum, start, count, int64valp); check_err(stat, "ncmpi_put_vara_longlong_all", __func__, __LINE__, __FILE__); int64valp += subarray_nelems; } break; case NC_UINT64: for (i=0; i<nchunks; i++) { start[0] = i; stat = ncmpi_put_vara_ulonglong_all(ncid, varnum, start, count, uint64valp); check_err(stat, "ncmpi_put_vara_ulonglong_all", __func__, __LINE__, __FILE__); uint64valp += subarray_nelems; } break; default: derror("Unhandled type %d\n", vars[varnum].type); break; } } else { switch (vars[varnum].type) { case NC_BYTE: stat = ncmpi_put_vara_schar_all(ncid, varnum, start, count, (signed char *)charvalp); check_err(stat, "ncmpi_put_vara_schar_all", __func__, __LINE__, __FILE__); break; case NC_CHAR: stat = ncmpi_put_vara_text_all(ncid, varnum, start, count, charvalp); check_err(stat, "ncmpi_put_vara_text_all", __func__, __LINE__, __FILE__); break; case NC_SHORT: stat = ncmpi_put_vara_short_all(ncid, varnum, start, count, shortvalp); check_err(stat, "ncmpi_put_vara_short_all", __func__, __LINE__, __FILE__); break; case NC_INT: stat = ncmpi_put_vara_int_all(ncid, varnum, start, count, intvalp); check_err(stat, "ncmpi_put_vara_int_all", __func__, __LINE__, __FILE__); break; case NC_FLOAT: stat = ncmpi_put_vara_float_all(ncid, varnum, start, count, floatvalp); check_err(stat, "ncmpi_put_vara_float_all", __func__, __LINE__, __FILE__); break; case NC_DOUBLE: stat = ncmpi_put_vara_double_all(ncid, varnum, start, count, doublevalp); check_err(stat, "ncmpi_put_vara_double_all", __func__, __LINE__, __FILE__); break; case NC_UBYTE: stat = ncmpi_put_vara_uchar_all(ncid, varnum, start, count, ubytevalp); check_err(stat, "ncmpi_put_vara_uchar_all", __func__, __LINE__, __FILE__); break; case NC_USHORT: stat = ncmpi_put_vara_ushort_all(ncid, varnum, start, count, ushortvalp); check_err(stat, "ncmpi_put_vara_ushort_all", __func__, __LINE__, __FILE__); break; case NC_UINT: stat = ncmpi_put_vara_uint_all(ncid, varnum, start, count, uintvalp); check_err(stat, "ncmpi_put_vara_uint_all", __func__, __LINE__, __FILE__); break; case NC_INT64: stat = ncmpi_put_vara_longlong_all(ncid, varnum, start, count, int64valp); check_err(stat, "ncmpi_put_vara_longlong_all", __func__, __LINE__, __FILE__); break; case NC_UINT64: stat = ncmpi_put_vara_ulonglong_all(ncid, varnum, start, count, uint64valp); check_err(stat, "ncmpi_put_vara_ulonglong_all", __func__, __LINE__, __FILE__); break; default: derror("Unhandled type %d\n", vars[varnum].type); break; } } free(start); }
int main(int argc, char **argv) { int i, j; int status; int ncid1, ncid2; int ndims, nvars, ngatts, unlimdimid; char name[NC_MAX_NAME]; nc_type type, vartypes[NC_MAX_VARS]; MPI_Offset attlen; MPI_Offset dimlen, shape[NC_MAX_VAR_DIMS], varsize, start[NC_MAX_VAR_DIMS]; void *valuep; int dimids[NC_MAX_DIMS], varids[NC_MAX_VARS]; int vardims[NC_MAX_VARS][NC_MAX_VAR_DIMS/16]; /* divided by 16 due to my memory limitation */ int varndims[NC_MAX_VARS], varnatts[NC_MAX_VARS]; int isRecvar; params opts; int rank; int nprocs; MPI_Comm comm = MPI_COMM_WORLD; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) fprintf(stderr, "Testing read ... "); parse_read_args(argc, argv, rank, &opts); /********** START OF NETCDF ACCESS **************/ /* Read a netCDF file and write it out to another file */ /** * Open the input dataset - ncid1: * File name: "../data/test_float.nc" * Dataset API: Collective * And create the output dataset - ncid2: * File name: "testread.nc" * Dataset API: Collective */ status = ncmpi_open(comm, opts.infname, 0, MPI_INFO_NULL, &ncid1); if (status != NC_NOERR) handle_error(status); status = ncmpi_create(comm, opts.outfname, NC_CLOBBER, MPI_INFO_NULL, &ncid2); if (status != NC_NOERR) handle_error(status); /** * Inquire the dataset definitions of input dataset AND * Add dataset definitions for output dataset. */ status = ncmpi_inq(ncid1, &ndims, &nvars, &ngatts, &unlimdimid); if (status != NC_NOERR) handle_error(status); /* Inquire global attributes, assume CHAR attributes. */ for (i = 0; i < ngatts; i++) { status = ncmpi_inq_attname(ncid1, NC_GLOBAL, i, name); if (status != NC_NOERR) handle_error(status); status = ncmpi_inq_att (ncid1, NC_GLOBAL, name, &type, &attlen); if (status != NC_NOERR) handle_error(status); switch (type) { case NC_CHAR: valuep = (void *)malloc(attlen * sizeof(char)); status = ncmpi_get_att_text(ncid1, NC_GLOBAL, name, valuep); if (status != NC_NOERR) handle_error(status); status = ncmpi_put_att_text (ncid2, NC_GLOBAL, name, attlen, (char *)valuep); if (status != NC_NOERR) handle_error(status); free(valuep); break; case NC_SHORT: valuep = (void *)malloc(attlen * sizeof(short)); status = ncmpi_get_att_short(ncid1, NC_GLOBAL, name, valuep); if (status != NC_NOERR) handle_error(status); status = ncmpi_put_att_short (ncid2, NC_GLOBAL, name, type, attlen, (short *)valuep); if (status != NC_NOERR) handle_error(status); free(valuep); break; case NC_INT: valuep = (void *)malloc(attlen * sizeof(int)); status = ncmpi_get_att_int(ncid1, NC_GLOBAL, name, valuep); if (status != NC_NOERR) handle_error(status); status = ncmpi_put_att_int (ncid2, NC_GLOBAL, name, type, attlen, (int *)valuep); if (status != NC_NOERR) handle_error(status); free(valuep); break; case NC_FLOAT: valuep = (void *)malloc(attlen * sizeof(float)); status = ncmpi_get_att_float(ncid1, NC_GLOBAL, name, valuep); if (status != NC_NOERR) handle_error(status); status = ncmpi_put_att_float (ncid2, NC_GLOBAL, name, type, attlen, (float *)valuep); if (status != NC_NOERR) handle_error(status); free(valuep); break; case NC_DOUBLE: valuep = (void *)malloc(attlen * sizeof(double)); status = ncmpi_get_att_double(ncid1, NC_GLOBAL, name, valuep); if (status != NC_NOERR) handle_error(status); status = ncmpi_put_att_double (ncid2, NC_GLOBAL, name, type, attlen, (double *)valuep); if (status != NC_NOERR) handle_error(status); free(valuep); break; default: ; /* TODO: handle unexpected types */ } } /* Inquire dimension */ for (i = 0; i < ndims; i++) { status = ncmpi_inq_dim(ncid1, i, name, &dimlen); if (status != NC_NOERR) handle_error(status); if (i == unlimdimid) dimlen = NC_UNLIMITED; status = ncmpi_def_dim(ncid2, name, dimlen, dimids+i); if (status != NC_NOERR) handle_error(status); } /* Inquire variables */ for (i = 0; i < nvars; i++) { status = ncmpi_inq_var (ncid1, i, name, vartypes+i, varndims+i, vardims[i], varnatts+i); if (status != NC_NOERR) handle_error(status); status = ncmpi_def_var(ncid2, name, vartypes[i], varndims[i], vardims[i], varids+i); if (status != NC_NOERR) handle_error(status); /* var attributes, assume CHAR attributes */ for (j = 0; j < varnatts[i]; j++) { status = ncmpi_inq_attname(ncid1, i, j, name); if (status != NC_NOERR) handle_error(status); status = ncmpi_inq_att (ncid1, i, name, &type, &attlen); if (status != NC_NOERR) handle_error(status); switch (type) { case NC_CHAR: valuep = (void *)malloc(attlen * sizeof(char)); status = ncmpi_get_att_text(ncid1, i, name, valuep); if (status != NC_NOERR) handle_error(status); status = ncmpi_put_att_text (ncid2, varids[i], name, attlen, (char *)valuep); if (status != NC_NOERR) handle_error(status); free(valuep); break; case NC_SHORT: valuep = (void *)malloc(attlen * sizeof(short)); status = ncmpi_get_att_short(ncid1, i, name, valuep); if (status != NC_NOERR) handle_error(status); status = ncmpi_put_att_short (ncid2, varids[i], name, type, attlen, (short *)valuep); if (status != NC_NOERR) handle_error(status); free(valuep); break; case NC_INT: valuep = (void *)malloc(attlen * sizeof(int)); status = ncmpi_get_att_int(ncid1, i, name, valuep); if (status != NC_NOERR) handle_error(status); status = ncmpi_put_att_int (ncid2, varids[i], name, type, attlen, (int *)valuep); if (status != NC_NOERR) handle_error(status); free(valuep); break; case NC_FLOAT: valuep = (void *)malloc(attlen * sizeof(float)); status = ncmpi_get_att_float(ncid1, i, name, valuep); if (status != NC_NOERR) handle_error(status); status = ncmpi_put_att_float (ncid2, varids[i], name, type, attlen, (float *)valuep); if (status != NC_NOERR) handle_error(status); free(valuep); break; case NC_DOUBLE: valuep = (void *)malloc(attlen * sizeof(double)); status = ncmpi_get_att_double(ncid1, i, name, valuep); if (status != NC_NOERR) handle_error(status); status = ncmpi_put_att_double (ncid2, varids[i], name, type, attlen, (double *)valuep); if (status != NC_NOERR) handle_error(status); free(valuep); break; default: ; /* TODO: handle unexpected types */ } } } /** * End Define Mode (switch to data mode) for output dataset * Dataset API: Collective */ status = ncmpi_enddef(ncid2); if (status != NC_NOERR) handle_error(status); /** * Read data of variables from input dataset * (ONLY DEAL WITH: NC_INT, NC_FLOAT, NC_DOUBLE for now) * Write the data out to the corresponding variables in the output dataset * * Data Partition (Assume 4 processors): * square: 2-D, (Block, *), 25*100 from 100*100 * cube: 3-D, (Block, *, *), 25*100*100 from 100*100*100 * xytime: 3-D, (Block, *, *), 25*100*100 from 100*100*100 * time: 1-D, Block-wise, 25 from 100 * * Data Mode API: collective */ for (i = 0; i < NC_MAX_VAR_DIMS; i++) start[i] = 0; for (i = 0; i < nvars; i++) { isRecvar = 0; varsize = 1; for (j = 0; j < varndims[i]; j++) { status = ncmpi_inq_dim(ncid1, vardims[i][j], name, shape + j); if (status != NC_NOERR) handle_error(status); if (j == 0) { shape[j] /= nprocs; start[j] = shape[j] * rank; } varsize *= shape[j]; if (vardims[i][j] == unlimdimid) isRecvar = 1; } switch (vartypes[i]) { case NC_CHAR: break; case NC_SHORT: valuep = (void *)malloc(varsize * sizeof(short)); status = ncmpi_get_vara_short_all(ncid1, i, start, shape, (short *)valuep); if (status != NC_NOERR) handle_error(status); status = ncmpi_put_vara_short_all(ncid2, varids[i], start, shape, (short *)valuep); if (status != NC_NOERR) handle_error(status); free(valuep); break; case NC_INT: valuep = (void *)malloc(varsize * sizeof(int)); status = ncmpi_get_vara_int_all(ncid1, i, start, shape, (int *)valuep); if (status != NC_NOERR) handle_error(status); status = ncmpi_put_vara_int_all(ncid2, varids[i], start, shape, (int *)valuep); if (status != NC_NOERR) handle_error(status); free(valuep); break; case NC_FLOAT: valuep = (void *)malloc(varsize * sizeof(float)); status = ncmpi_get_vara_float_all(ncid1, i, start, shape, (float *)valuep); if (status != NC_NOERR) handle_error(status); status = ncmpi_put_vara_float_all(ncid2, varids[i], start, shape, (float *)valuep); if (status != NC_NOERR) handle_error(status); free(valuep); break; case NC_DOUBLE: valuep = (void *)malloc(varsize * sizeof(double)); status = ncmpi_get_vara_double_all(ncid1, i, start, shape, (double *)valuep); if (status != NC_NOERR) handle_error(status); status = ncmpi_put_vara_double_all(ncid2, varids[i], start, shape, (double *)valuep); if (status != NC_NOERR) handle_error(status); free(valuep); break; default: ; /* TODO: handle unexpected types */ } } /** * Close the datasets * Dataset API: collective */ status = ncmpi_close(ncid1); if (status != NC_NOERR) handle_error(status); status = ncmpi_close(ncid2); if (status != NC_NOERR) handle_error(status); /******************* END OF NETCDF ACCESS ****************/ if (rank == 0) fprintf(stderr, "OK\nInput file %s copied to: %s!\n", opts.infname, opts.outfname); MPI_Finalize(); return 0; }
int main(int argc, char **argv) { int i, j, k; int status; int ncid; int dimid1, dimid2, dimid3, udimid; int square_dim[2], cube_dim[3], xytime_dim[3], time_dim[1]; MPI_Offset square_start[2], cube_start[3] = {0, 0, 0}; MPI_Offset square_count[2] = {50, 50}, cube_count[3] = {100, 50, 50}; MPI_Offset square_stride[2] = {2, 2}; MPI_Offset xytime_start[3] = {0, 0, 0}; MPI_Offset xytime_count[3] = {100, 50, 50}; MPI_Offset time_start[1], time_count[1] = {25}; int square_id, cube_id, xytime_id, time_id; static char title[] = "example netCDF dataset"; static char description[] = "2-D integer array"; double data[100][50][50], buffer[100]; double stride_2d_data[50][50]; int rank; int nprocs; MPI_Comm comm = MPI_COMM_WORLD; params opts; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) fprintf(stderr, "Testing write ... "); parse_write_args(argc, argv, rank, &opts); /********** START OF NETCDF ACCESS **************/ /** * Create the dataset * File name: "testwrite.nc" * Dataset API: Collective */ status = ncmpi_create(comm, opts.outfname, NC_CLOBBER, MPI_INFO_NULL, &ncid); if (status != NC_NOERR) handle_error(status); /** * Create a global attribute: * :title = "example netCDF dataset"; */ status = ncmpi_put_att_text (ncid, NC_GLOBAL, "title", strlen(title), title); if (status != NC_NOERR) handle_error(status); /** * Add 4 pre-defined dimensions: * x = 100, y = 100, z = 100, time = NC_UNLIMITED */ status = ncmpi_def_dim(ncid, "x", 100L, &dimid1); if (status != NC_NOERR) handle_error(status); status = ncmpi_def_dim(ncid, "y", 100L, &dimid2); if (status != NC_NOERR) handle_error(status); status = ncmpi_def_dim(ncid, "z", 100L, &dimid3); if (status != NC_NOERR) handle_error(status); status = ncmpi_def_dim(ncid, "time", NC_UNLIMITED, &udimid); if (status != NC_NOERR) handle_error(status); /** * Define the dimensionality and then add 4 variables: * square(x, y), cube(x,y,z), time(time), xytime(time, x, y) */ square_dim[0] = cube_dim[0] = xytime_dim[1] = dimid1; square_dim[1] = cube_dim[1] = xytime_dim[2] = dimid2; cube_dim[2] = dimid3; xytime_dim[0] = udimid; time_dim[0] = udimid; status = ncmpi_def_var (ncid, "square", NC_DOUBLE, 2, square_dim, &square_id); if (status != NC_NOERR) handle_error(status); status = ncmpi_def_var (ncid, "cube", NC_DOUBLE, 3, cube_dim, &cube_id); if (status != NC_NOERR) handle_error(status); status = ncmpi_def_var (ncid, "time", NC_DOUBLE, 1, time_dim, &time_id); if (status != NC_NOERR) handle_error(status); status = ncmpi_def_var (ncid, "xytime", NC_DOUBLE, 3, xytime_dim, &xytime_id); if (status != NC_NOERR) handle_error(status); /** * Add an attribute for variable: * square: decsription = "2-D integer array" */ status = ncmpi_put_att_text (ncid, square_id, "description", strlen(description), description); if (status != NC_NOERR) handle_error(status); /** * End Define Mode (switch to data mode) * Dataset API: Collective */ status = ncmpi_enddef(ncid); if (status != NC_NOERR) handle_error(status); /** * Data Partition (Assume 4 processors): * square: 2-D, (Cyclic, Cyclic), 50*50 from 100*100, strided access * cube: 3-D, (*, Block, Block), 100*50*50 from 100*100*100 * xytime: 3-D, (*, Block, Block), 100*50*50 from 100*100*100 * time: 1-D, Block-wise, 25 from 100 */ /* square_start[0] = */ cube_start[1] = xytime_start[1] = (rank/2) * 50; /* square_start[1] = */ cube_start[2] = xytime_start[2] = (rank%2) * 50; time_start[0] = (rank%4) * 25; square_start[0] = rank/2; square_start[1] = rank%2; /** * Packing data in the buffer */ /* Data for variable: time */ for ( i = time_start[0]; i < time_start[0] + time_count[0]; i++ ) buffer[i - time_start[0]] = i; /* Data for variable: cube and xytime */ for ( i = 0; i < 100; i++ ) for ( j = cube_start[1]; j < cube_start[1]+cube_count[1]; j++ ) for ( k = cube_start[2]; k < cube_start[2]+cube_count[2]; k++ ) data[i][j-cube_start[1]][k-cube_start[2]] = i*100*100 + j*100 + k; /* Data for variable: square */ for ( i = 0; i < 50; i ++ ) for ( j = 0; j < 50; j++ ) stride_2d_data[i][j] = (2*i + rank/2)*100 + (2*j + rank%2); /** * Write data into variables: square, cube, time and xytime * Access Method: subarray * Data Mode API: collective */ status = ncmpi_put_vars_double_all(ncid, square_id, square_start, square_count, square_stride, &stride_2d_data[0][0]); if (status != NC_NOERR) handle_error(status); status = ncmpi_put_vara_double_all(ncid, cube_id, cube_start, cube_count, &data[0][0][0]); if (status != NC_NOERR) handle_error(status); status = ncmpi_put_vara_double_all(ncid, time_id, time_start, time_count, (void *)buffer); if (status != NC_NOERR) handle_error(status); status = ncmpi_put_vara_double_all(ncid, xytime_id, xytime_start, xytime_count, &data[0][0][0]); if (status != NC_NOERR) handle_error(status); /** * Close the dataset * Dataset API: collective */ status = ncmpi_close(ncid); if (status != NC_NOERR) handle_error(status); /******************* END OF NETCDF ACCESS ****************/ if (rank == 0) fprintf(stderr, "OK\nFile written to: %s!\n", opts.outfname); MPI_Finalize(); return 0; }