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;
}
예제 #2
0
// 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;
}
예제 #3
0
파일: load.c 프로젝트: live-clones/pnetcdf
/* 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);
}
예제 #4
0
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;
}
예제 #5
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;
}