Exemplo n.º 1
0
static int
reclaim_compound(int ncid, int xtype, size_t size, size_t nfields, void* memory)
{
    int stat = NC_NOERR;
    size_t fid, offset, i, fieldsize, arraycount;
    int dimsizes[NC_MAX_VAR_DIMS];
    int ndims;
    nc_type fieldtype;
    char* p;

    /* Get info about each field in turn and reclaim it */
    for(fid=0;fid<nfields;fid++) {
        if((stat = nc_inq_compound_field(ncid,xtype,fid,NULL,&offset, &fieldtype, &ndims, dimsizes))) goto done;
        if((stat = nc_inq_type(ncid,fieldtype,NULL,&fieldsize))) goto done;
	if(ndims == 0) {ndims=1; dimsizes[0]=1;} /* fake the scalar case */
	/* compute the total number of elements in the field array */
	arraycount = 1;
	for(i=0;i<ndims;i++) arraycount *= dimsizes[i];
	for(i=0;i<arraycount;i++) {
            p = ((char*)memory) + offset + (i*fieldsize);
	    if((stat = reclaim_datar(ncid, fieldtype, p))) goto done;
	}		
    }

done:
    return stat;
}
Exemplo n.º 2
0
EXTERNL int
ncaux_reclaim_data(int ncid, int xtype, void* memory, size_t count)
{
    int stat = NC_NOERR;
    size_t typesize = 0;
    size_t i;
    Position offset;

    if(ncid < 0 || xtype < 0
       || (memory == NULL && count > 0)
       || xtype == NC_NAT)
        {stat = NC_EINVAL; goto done;}
    if(memory == NULL || count == 0)
        goto done; /* ok, do nothing */
    if((stat=nc_inq_type(ncid,xtype,NULL,&typesize))) goto done;
    offset.memory = (char*)memory; /* use char* so we can do pointer arithmetic */
    offset.offset = 0;
    for(i=0;i<count;i++) {
	if((stat=reclaim_datar(ncid,xtype,typesize,&offset))) /* reclaim one instance */
	    break;
    }

done:
    return stat;
}
Exemplo n.º 3
0
static int
reclaim_vlen(int ncid, int xtype, int basetype, Position* offset)
{
    int stat = NC_NOERR;
    size_t i, basesize;
    nc_vlen_t* vl = (nc_vlen_t*)(offset->memory+offset->offset);

    /* Get size of the basetype */
    if((stat=nc_inq_type(ncid,basetype,NULL,&basesize))) goto done;
    /* Free up each entry in the vlen list */
    if(vl->p != NULL) {
	Position voffset;
	unsigned int alignment = ncaux_type_alignment(basetype,ncid);
	voffset.memory = vl->p;
	voffset.offset = 0;
        for(i=0;i<vl->len;i++) {
	    voffset.offset = read_align(voffset.offset,alignment);
	    if((stat = reclaim_datar(ncid,basetype,basesize,&voffset))) goto done;
	}
	offset->offset += sizeof(nc_vlen_t);
	free(vl->p);
    }

done:
    return stat;
}
Exemplo n.º 4
0
/* From netCDF type in group igrp, get size in memory needed for each
 * value.  Wouldn't be needed if nc_inq_type() was a netCDF-3 function
 * too. */
static int
inq_value_size(int igrp, nc_type vartype, size_t *value_sizep) {
    int stat = NC_NOERR;

#ifdef USE_NETCDF4
    NC_CHECK(nc_inq_type(igrp, vartype, NULL, value_sizep));
#else
    switch(vartype) {
    case NC_BYTE:
	*value_sizep = sizeof(signed char);
	break;
    case NC_CHAR:
	*value_sizep = sizeof(char);
	break;
    case NC_SHORT:
	*value_sizep = sizeof(short);
	break;
    case NC_INT:
	*value_sizep = sizeof(int);
	break;
    case NC_FLOAT:
	*value_sizep = sizeof(float);
	break;
    case NC_DOUBLE:
	*value_sizep = sizeof(double);
	break;
    default:
	NC_CHECK(NC_EBADTYPE);
	break;
    }
#endif	/* USE_NETCDF4 */
    return stat;
}
Exemplo n.º 5
0
/* Return size of chunk in bytes for a variable varid in a group igrp, or 0 if
 * layout is contiguous */
static int
inq_var_chunksize(int igrp, int varid, size_t* chunksizep) {
    int stat = NC_NOERR;
    int ndims;
    size_t *chunksizes;
    int dim;
    int contig = 1;
    nc_type vartype;
    size_t value_size;
    size_t prod;

    NC_CHECK(nc_inq_vartype(igrp, varid, &vartype));
    /* from type, get size in memory needed for each value */
    NC_CHECK(nc_inq_type(igrp, vartype, NULL, &value_size));
    prod = value_size;
    NC_CHECK(nc_inq_varndims(igrp, varid, &ndims));
    chunksizes = (size_t *) emalloc((ndims + 1) * sizeof(size_t));
    if(ndims > 0) {
	NC_CHECK(nc_inq_var_chunking(igrp, varid, &contig, NULL));
    }
    if(contig == 1) {
	*chunksizep = 0;
    } else {
	NC_CHECK(nc_inq_var_chunking(igrp, varid, &contig, chunksizes));
	for(dim = 0; dim < ndims; dim++) {
	    prod *= chunksizes[dim];
	}
	*chunksizep = prod;
    }
    free(chunksizes);
    return stat;
}
Exemplo n.º 6
0
/* 
 * copy a user-defined variable length type in the group igrp to the
 * group ogrp
 */
static int
copy_vlen_type(int igrp, nc_type itype, int ogrp)
{
    int stat = NC_NOERR; 
    nc_type ibasetype;
    nc_type obasetype;		/* base type in target group */
    char name[NC_MAX_NAME];
    size_t size;
    char basename[NC_MAX_NAME];
    size_t basesize;
    nc_type vlen_type;

    NC_CHECK(nc_inq_vlen(igrp, itype, name, &size, &ibasetype));
    /* to get base type id in target group, use name of base type in
     * source group */
    NC_CHECK(nc_inq_type(igrp, ibasetype, basename, &basesize));
    stat = nc_inq_typeid(ogrp, basename, &obasetype);
    /* if no such type, create it now */
    if(stat == NC_EBADTYPE) {
	NC_CHECK(copy_type(igrp, ibasetype, ogrp));
	stat = nc_inq_typeid(ogrp, basename, &obasetype);
    }
    NC_CHECK(stat);

    /* Now we know base type exists in output and we know its type id */
    NC_CHECK(nc_def_vlen(ogrp, name, obasetype, &vlen_type));

    return stat;
}
Exemplo n.º 7
0
int test_type(int ncid, int type, char* tstring) {

  printf("\t* Testing Type %s:\t",tstring);
  if(nc_inq_type(ncid,type,NULL,NULL)) ERR;
  else printf("success.\n");

  return 0;
}
Exemplo n.º 8
0
int test_type_should_fail(int ncid, int type, char* tstring) {

  printf("\t* Testing Type (Should Fail) %s:\t",tstring);
  if(!nc_inq_type(ncid,type,NULL,NULL)) ERR;
  else printf("expected failure.\n");

  return 0;
}
Exemplo n.º 9
0
static int
computefieldinfo(struct NCAUX_CMPD* cmpd)
{
    int i;
    int status = NC_NOERR;
    size_t offset = 0;
    size_t totaldimsize;

    /* Assign the sizes for the fields */
    for(i=0;i<cmpd->nfields;i++) {
	struct NCAUX_FIELD* field = &cmpd->fields[i];
	status = nc_inq_type(cmpd->ncid,field->fieldtype,NULL,&field->size);
        if(status != NC_NOERR) goto done;
	totaldimsize = dimproduct(field->ndims,field->dimsizes);
	field->size *= totaldimsize;
    }

    for(offset=0,i=0;i<cmpd->nfields;i++) {
        struct NCAUX_FIELD* field = &cmpd->fields[i];
	int alignment = 0;
	nc_type firsttype = findfirstfield(cmpd->ncid,field->fieldtype);

        /* only support 'c' alignment for now*/
	switch (field->fieldtype) {
	case NC_OPAQUE:
	    field->alignment = 1;
	    break;
	case NC_ENUM:
            field->alignment = ncaux_type_alignment(firsttype,cmpd->ncid);
	    break;
	case NC_VLEN: /*fall thru*/
	case NC_COMPOUND:
            field->alignment = ncaux_type_alignment(firsttype,cmpd->ncid);
	    break;
	default:
            field->alignment = ncaux_type_alignment(field->fieldtype,cmpd->ncid);
	    break;

	}
        offset += getpadding(offset,alignment);
        field->offset = offset;
        offset += field->size;
    }
    cmpd->size = offset;
    cmpd->alignment = cmpd->fields[0].alignment;

done:
    return status;
}
Exemplo n.º 10
0
static int
reclaim_vlen(int ncid, int xtype, int basetype, void* memory)
{
    int stat = NC_NOERR;
    nc_vlen_t* vl = (nc_vlen_t*)memory;
    size_t i, size;

    /* Get size of the basetype */
    if((stat=nc_inq_type(ncid,basetype,NULL,&size))) goto done;
    /* Free up each entry in the vlen list */
    if(vl->p != NULL) {
	char* p = vl->p;
        for(i=0;i<vl->len;i++,p+=size)
	    if((stat = reclaim_datar(ncid,basetype,p))) goto done;
	free(vl->p);
    }

done:
    return stat;
}
Exemplo n.º 11
0
/* 
 * copy a user-defined compound type in the group igrp to the group ogrp
 */
static int
copy_compound_type(int igrp, nc_type itype, int ogrp)
{
    int stat = NC_NOERR; 
    char name[NC_MAX_NAME];
    size_t size;
    size_t nfields;
    nc_type otype;
    int fid;

    NC_CHECK(nc_inq_compound(igrp, itype, name, &size, &nfields));
    NC_CHECK(nc_def_compound(ogrp, size, name, &otype));

    for (fid = 0; fid < nfields; fid++) {
	char fname[NC_MAX_NAME];
	char ftypename[NC_MAX_NAME];
	size_t foff;
	nc_type iftype, oftype;
	int fndims;

	NC_CHECK(nc_inq_compound_field(igrp, itype, fid, fname, &foff, &iftype, &fndims, NULL));
	/* type ids in source don't necessarily correspond to same
	 * typeids in destination, so look up destination typeid by using
	 * field type name */
	NC_CHECK(nc_inq_type(igrp, iftype, ftypename, NULL));
	NC_CHECK(nc_inq_typeid(ogrp, ftypename, &oftype));
	if(fndims == 0) {
	    NC_CHECK(nc_insert_compound(ogrp, otype, fname, foff, oftype));
	} else {		/* field is array type */
	    int *fdimsizes;
	    fdimsizes = (int *) emalloc((fndims + 1) * sizeof(int));
	    stat = nc_inq_compound_field(igrp, itype, fid, NULL, NULL, NULL, 
					 NULL, fdimsizes);
	    NC_CHECK(nc_insert_array_compound(ogrp, otype, fname, foff, oftype, fndims, fdimsizes));
	    free(fdimsizes);
	}
    }
    return stat;
}
Exemplo n.º 12
0
int
ncaux_reclaim_data(int ncid, int xtype, const void* memory, size_t count)
{
    int stat = NC_NOERR;
    size_t typesize = 0;
    char* p;
    size_t i;
    
    if(ncid < 0 || xtype < 0
       || (memory == NULL && count > 0)
       || xtype == NC_NAT)
        {stat = NC_EINVAL; goto done;}
    if(memory == NULL || count == 0)
        goto done; /* ok, do nothing */
    if((stat=nc_inq_type(ncid,xtype,NULL,&typesize))) goto done;
    p = (char*)memory; /* use char* so we can do pointer arithmetic */
    for(i=0;i<count;i++,p+=typesize) {
	if((stat=reclaim_datar(ncid,xtype,p))) /* reclaim one instance */
	    break;
    }
    
done:
    return stat;
}
Exemplo n.º 13
0
static int
reclaim_compound(int ncid, int xtype, size_t cmpdsize, size_t nfields, Position* offset)
{
    int stat = NC_NOERR;
    size_t fid, fieldoffset, i, fieldsize, arraycount;
    int dimsizes[NC_MAX_VAR_DIMS];
    int ndims;
    nc_type fieldtype;
    ptrdiff_t saveoffset;

    saveoffset = offset->offset;

    /* Get info about each field in turn and reclaim it */
    for(fid=0;fid<nfields;fid++) {
	unsigned int fieldalignment;
	/* Get all relevant info about the field */
        if((stat = nc_inq_compound_field(ncid,xtype,fid,NULL,&fieldoffset, &fieldtype, &ndims, dimsizes))) goto done;
	fieldalignment = ncaux_type_alignment(fieldtype,ncid);
        if((stat = nc_inq_type(ncid,fieldtype,NULL,&fieldsize))) goto done;
	if(ndims == 0) {ndims=1; dimsizes[0]=1;} /* fake the scalar case */
	/* Align to this field */
	offset->offset = read_align(offset->offset,fieldalignment);
	/* compute the total number of elements in the field array */
	arraycount = 1;
	for(i=0;i<ndims;i++) arraycount *= dimsizes[i];
	for(i=0;i<arraycount;i++) {
	    if((stat = reclaim_datar(ncid, fieldtype, fieldsize, offset))) goto done;
	}
    }
    /* Return to beginning of the compound and move |compound| */
    offset->offset = saveoffset;
    offset->offset += cmpdsize;

done:
    return stat;
}
Exemplo n.º 14
0
/** \internal
\ingroup variables
 Most dispatch tables will use the default procedures
*/
int
NCDEFAULT_get_vars(int ncid, int varid, const size_t * start,
	    const size_t * edges, const ptrdiff_t * stride,
	    void *value0, nc_type memtype)
{
#ifdef VARS_USES_VARM
   NC* ncp;
   int stat = NC_check_id(ncid, &ncp);

   if(stat != NC_NOERR) return stat;
   return ncp->dispatch->get_varm(ncid,varid,start,edges,stride,NULL,value0,memtype);
#else
  /* Rebuilt get_vars code to simplify and avoid use of get_varm */

   int status = NC_NOERR;
   int i,simplestride,isrecvar;
   int rank;
   struct GETodometer odom;
   nc_type vartype = NC_NAT;
   NC* ncp;
   int memtypelen;
   size_t vartypelen;
   char* value = (char*)value0;
   size_t numrecs;
   size_t varshape[NC_MAX_VAR_DIMS];
   size_t mystart[NC_MAX_VAR_DIMS];
   size_t myedges[NC_MAX_VAR_DIMS];
   ptrdiff_t mystride[NC_MAX_VAR_DIMS];
   char *memptr = NULL;

   status = NC_check_id (ncid, &ncp);
   if(status != NC_NOERR) return status;

   status = nc_inq_vartype(ncid, varid, &vartype);
   if(status != NC_NOERR) return status;

   if(memtype == NC_NAT) memtype = vartype;

   /* compute the variable type size */
   status = nc_inq_type(ncid,vartype,NULL,&vartypelen);
   if(status != NC_NOERR) return status;

   if(memtype > NC_MAX_ATOMIC_TYPE)
	memtypelen = (int)vartypelen;
    else
	memtypelen = nctypelen(memtype);

   /* Check gross internal/external type compatibility */
   if(vartype != memtype) {
      /* If !atomic, the two types must be the same */
      if(vartype > NC_MAX_ATOMIC_TYPE
         || memtype > NC_MAX_ATOMIC_TYPE)
	 return NC_EBADTYPE;
      /* ok, the types differ but both are atomic */
      if(memtype == NC_CHAR || vartype == NC_CHAR)
	 return NC_ECHAR;
   }

   /* Get the variable rank */
   status = nc_inq_varndims(ncid, varid, &rank);
   if(status != NC_NOERR) return status;

   /* Get variable dimension sizes */
   isrecvar = NC_is_recvar(ncid,varid,&numrecs);
   NC_getshape(ncid,varid,rank,varshape);

   /* Optimize out using various checks */
   if (rank == 0) {
      /*
       * The variable is a scalar; consequently,
       * there s only one thing to get and only one place to put it.
       * (Why was I called?)
       */
      size_t edge1[1] = {1};
      return NC_get_vara(ncid, varid, start, edge1, value, memtype);
   }

   /* Do various checks and fixups on start/edges/stride */
   simplestride = 1; /* assume so */
   for(i=0;i<rank;i++) {
	size_t dimlen;
	mystart[i] = (start == NULL ? 0 : start[i]);
	if(edges == NULL) {
	   if(i == 0 && isrecvar)
  	      myedges[i] = numrecs - start[i];
	   else
	      myedges[i] = varshape[i] - mystart[i];
	} else
	    myedges[i] = edges[i];
	if(myedges[i] == 0)
	    return NC_NOERR; /* cannot read anything */
	mystride[i] = (stride == NULL ? 1 : stride[i]);
	if(mystride[i] <= 0
	   /* cast needed for braindead systems with signed size_t */
           || ((unsigned long) mystride[i] >= X_INT_MAX))
           return NC_ESTRIDE;
  	if(mystride[i] != 1) simplestride = 0;
        /* illegal value checks */
	dimlen = (i == 0 && isrecvar ? numrecs : varshape[i]);
        /* mystart is unsigned, never < 0 */
	if(mystart[i] >= dimlen)
	  return NC_EINVALCOORDS;
        /* myedges is unsigned, never < 0 */
	if(mystart[i] + myedges[i] > dimlen)
	  return NC_EEDGE;
   }
   if(simplestride) {
      return NC_get_vara(ncid, varid, mystart, myedges, value, memtype);
   }

   /* memptr indicates where to store the next value */
   memptr = value;

   odom_init(&odom,rank,mystart,myedges,mystride);

   /* walk the odometer to extract values */
   while(odom_more(&odom)) {
      int localstatus = NC_NOERR;
      /* Read a single value */
      localstatus = NC_get_vara(ncid,varid,odom.index,nc_sizevector1,memptr,memtype);
      /* So it turns out that when get_varm is used, all errors are
         delayed and ERANGE will be overwritten by more serious errors.
      */
      if(localstatus != NC_NOERR) {
	    if(status == NC_NOERR || localstatus != NC_ERANGE)
	       status = localstatus;
      }
      memptr += memtypelen;
      odom_next(&odom);
   }
   return status;
#endif
}
Exemplo n.º 15
0
int
main(int argc, char **argv)
{
   int mpi_namelen;
   char mpi_name[MPI_MAX_PROCESSOR_NAME];
   int mpi_size, mpi_rank;
   MPI_Comm comm = MPI_COMM_WORLD;
   MPI_Info info = MPI_INFO_NULL;
   double start_time = 0, total_time;
   int mpi_size_in;
#define NUM_TEST_TYPES 11
   nc_type test_type[NUM_TEST_TYPES] = {NC_BYTE, NC_CHAR, NC_SHORT, NC_INT, NC_FLOAT, NC_DOUBLE,
                                        NC_UBYTE, NC_USHORT, NC_UINT, NC_INT64, NC_UINT64};
   int tt, fv;
   int j, i, k, ret;

   /* Initialize MPI. */
   MPI_Init(&argc,&argv);
   MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
   MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
   MPI_Get_processor_name(mpi_name, &mpi_namelen);

   /* Must be able to evenly divide my slabs between processors. */
   if (NUM_SLABS % mpi_size)
   {
      if (!mpi_rank)
         printf("NUM_SLABS (%d) is not evenly divisible by mpi_size(%d)\n",
                NUM_SLABS, mpi_size);
      ERR;
   }

   if (!mpi_rank)
      printf("\n*** Testing parallel I/O some more.\n");

   /* Test for different fill value settings. */
   for (fv = 0; fv < NUM_FILL_TEST_RUNS; fv++)
   {
      /* Test for different netCDF types. */
      for (tt = 0; tt < NUM_TEST_TYPES; tt++)
      {
         char file_name[NC_MAX_NAME + 1];
         int fill_mode_in;
         void *data, *data_in;
         void *fill_value, *fill_value_in;
         size_t type_size;
         size_t write_start[NDIMS] = {0, 0, 1};
         size_t write_count[NDIMS] = {1, DIMSIZE, DIMSIZE - 1};
         size_t read_start[NDIMS] = {0, 0, 0};
         size_t read_count[NDIMS] = {1, DIMSIZE, DIMSIZE};
         int ncid, varid, dimids[NDIMS];
         int ndims_in, nvars_in, natts_in, unlimdimid_in;

         /* Fill values to be expected. */
         signed char byte_expected_fill_value;
         unsigned char char_expected_fill_value;
         short short_expected_fill_value;
         int int_expected_fill_value;
         float float_expected_fill_value;
         double double_expected_fill_value;
         unsigned char ubyte_expected_fill_value;
         unsigned short ushort_expected_fill_value;
         unsigned int uint_expected_fill_value;
         long long int int64_expected_fill_value;
         unsigned long long int uint64_expected_fill_value;

         /* Fill values used when writing. */
         signed char byte_fill_value = -TEST_VAL_42;
         unsigned char char_fill_value = 'x';
         short short_fill_value = TEST_VAL_42 * 100;
         int int_fill_value = TEST_VAL_42 * 1000;
         float float_fill_value = TEST_VAL_42 * 1000;
         double double_fill_value = TEST_VAL_42 * 1000;
         unsigned char ubyte_fill_value = TEST_VAL_42;
         unsigned short ushort_fill_value = TEST_VAL_42 * 100;
         unsigned int uint_fill_value = TEST_VAL_42 * 1000;
         long long int int64_fill_value = TEST_VAL_42 * 1000;
         unsigned long long int uint64_fill_value = TEST_VAL_42 * 1000;

         /* Fill values read in. */
         signed char byte_fill_value_in;
         unsigned char char_fill_value_in;
         short short_fill_value_in;
         int int_fill_value_in;
         float float_fill_value_in;
         double double_fill_value_in;
         unsigned char ubyte_fill_value_in;
         unsigned short ushort_fill_value_in;
         unsigned int uint_fill_value_in;
         long long int int64_fill_value_in;
         unsigned long long int uint64_fill_value_in;

         /* Data to write and read. */
         signed char byte_data[DIMSIZE * DIMSIZE], byte_data_in[DIMSIZE * DIMSIZE];
         unsigned char char_data[DIMSIZE * DIMSIZE], char_data_in[DIMSIZE * DIMSIZE];
         short short_data[DIMSIZE * DIMSIZE], short_data_in[DIMSIZE * DIMSIZE];
         int int_data[DIMSIZE * DIMSIZE], int_data_in[DIMSIZE * DIMSIZE];
         float float_data[DIMSIZE * DIMSIZE], float_data_in[DIMSIZE * DIMSIZE];
         double double_data[DIMSIZE * DIMSIZE], double_data_in[DIMSIZE * DIMSIZE];
         unsigned char ubyte_data[DIMSIZE * DIMSIZE], ubyte_data_in[DIMSIZE * DIMSIZE];
         unsigned short ushort_data[DIMSIZE * DIMSIZE], ushort_data_in[DIMSIZE * DIMSIZE];
         unsigned int uint_data[DIMSIZE * DIMSIZE], uint_data_in[DIMSIZE * DIMSIZE];
         long long int int64_data[DIMSIZE * DIMSIZE], int64_data_in[DIMSIZE * DIMSIZE];
         unsigned long long int uint64_data[DIMSIZE * DIMSIZE], uint64_data_in[DIMSIZE * DIMSIZE];

         if (!mpi_rank)
            printf("*** writing a %d x %d x %d file from %d processors for fill value test %d type %d...\n",
                   NUM_SLABS, DIMSIZE, DIMSIZE, mpi_size, fv, test_type[tt]);

         /* Initialize test data. */
         switch(test_type[tt])
         {
         case NC_BYTE:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               byte_data[i] = mpi_rank;
            data = byte_data;
            data_in = byte_data_in;
            byte_expected_fill_value = fv ? byte_fill_value : NC_FILL_BYTE;
            fill_value = &byte_expected_fill_value;
            fill_value_in = &byte_fill_value_in;
            break;
         case NC_CHAR:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               char_data[i] = mpi_rank;
            data = char_data;
            data_in = char_data_in;
            char_expected_fill_value = fv ? char_fill_value : NC_FILL_CHAR;
            fill_value = &char_expected_fill_value;
            fill_value_in = &char_fill_value_in;
            break;
         case NC_SHORT:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               short_data[i] = mpi_rank;
            data = short_data;
            data_in = short_data_in;
            short_expected_fill_value = fv ? short_fill_value : NC_FILL_SHORT;
            fill_value = &short_expected_fill_value;
            fill_value_in = &short_fill_value_in;
            break;
         case NC_INT:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               int_data[i] = mpi_rank;
            data = int_data;
            data_in = int_data_in;
            int_expected_fill_value = fv ? int_fill_value : NC_FILL_INT;
            fill_value = &int_expected_fill_value;
            fill_value_in = &int_fill_value_in;
            break;
         case NC_FLOAT:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               float_data[i] = mpi_rank;
            data = float_data;
            data_in = float_data_in;
            float_expected_fill_value = fv ? float_fill_value : NC_FILL_FLOAT;
            fill_value = &float_expected_fill_value;
            fill_value_in = &float_fill_value_in;
            break;
         case NC_DOUBLE:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               double_data[i] = mpi_rank;
            data = double_data;
            data_in = double_data_in;
            double_expected_fill_value = fv ? double_fill_value : NC_FILL_DOUBLE;
            fill_value = &double_expected_fill_value;
            fill_value_in = &double_fill_value_in;
            break;
         case NC_UBYTE:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               ubyte_data[i] = mpi_rank;
            data = ubyte_data;
            data_in = ubyte_data_in;
            ubyte_expected_fill_value = fv ? ubyte_fill_value : NC_FILL_UBYTE;
            fill_value = &ubyte_expected_fill_value;
            fill_value_in = &ubyte_fill_value_in;
            break;
         case NC_USHORT:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               ushort_data[i] = mpi_rank;
            data = ushort_data;
            data_in = ushort_data_in;
            ushort_expected_fill_value = fv ? ushort_fill_value : NC_FILL_USHORT;
            fill_value = &ushort_expected_fill_value;
            fill_value_in = &ushort_fill_value_in;
            break;
         case NC_UINT:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               uint_data[i] = mpi_rank;
            data = uint_data;
            data_in = uint_data_in;
            uint_expected_fill_value = fv ? uint_fill_value : NC_FILL_UINT;
            fill_value = &uint_expected_fill_value;
            fill_value_in = &uint_fill_value_in;
            break;
         case NC_INT64:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               int64_data[i] = mpi_rank;
            data = int64_data;
            data_in = int64_data_in;
            int64_expected_fill_value = fv ? int64_fill_value : NC_FILL_INT64;
            fill_value = &int64_expected_fill_value;
            fill_value_in = &int64_fill_value_in;
            break;
         case NC_UINT64:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               uint64_data[i] = mpi_rank;
            data = uint64_data;
            data_in = uint64_data_in;
            uint64_expected_fill_value = fv ? uint64_fill_value : NC_FILL_UINT64;
            fill_value = &uint64_expected_fill_value;
            fill_value_in = &uint64_fill_value_in;
            break;
         }

         /* Create a file name. */
         sprintf(file_name, "%s_type_%d_fv_%d.nc", TEST_NAME, test_type[tt], fv);

         /* Create a parallel netcdf-4 file. */
         if (nc_create_par(file_name, NC_NETCDF4, comm, info, &ncid)) ERR;

         /* Get the type len. */
         if (nc_inq_type(ncid, test_type[tt], NULL, &type_size)) ERR;

         /* A global attribute holds the number of processors that created
          * the file. */
         if (nc_put_att_int(ncid, NC_GLOBAL, "num_processors", NC_INT, 1, &mpi_size)) ERR;

         /* Create three dimensions. */
         if (nc_def_dim(ncid, DIM1_NAME, NUM_SLABS, dimids)) ERR;
         if (nc_def_dim(ncid, DIM2_NAME, DIMSIZE, &dimids[1])) ERR;
         if (nc_def_dim(ncid, DIM3_NAME, DIMSIZE, &dimids[2])) ERR;

         /* Create one var. */
         if (nc_def_var(ncid, VAR_NAME, test_type[tt], NDIMS, dimids, &varid)) ERR;
         if (nc_put_att_int(ncid, varid, "var_num_processors", NC_INT, 1, &mpi_size)) ERR;
         if (fv == 1)
         {
            if (nc_def_var_fill(ncid, varid, NC_FILL, fill_value)) ERR;
            if (nc_inq_var_fill(ncid, varid, &fill_mode_in, fill_value_in)) ERR;
            if (fill_mode_in != NC_FILL) ERR;
            if (memcmp(fill_value_in, fill_value, type_size)) ERR;
         }
         else if (fv == 2)
         {
            if (nc_def_var_fill(ncid, varid, NC_NOFILL, NULL)) ERR;
            if (nc_inq_var_fill(ncid, varid, &fill_mode_in, NULL)) ERR;
            if (!fill_mode_in) ERR; /* nofill will be true */
         }

         /* Write metadata to file. */
         if (nc_enddef(ncid)) ERR;

         /* Change access mode to collective, then back to independent. */
         if (nc_var_par_access(ncid, varid, NC_COLLECTIVE)) ERR;
         if (nc_var_par_access(ncid, varid, NC_INDEPENDENT)) ERR;

         if (!mpi_rank)
            start_time = MPI_Wtime();

         /* Write all the slabs this process is responsible for. */
         for (i = 0; i < NUM_SLABS / mpi_size; i++)
         {
            write_start[0] = NUM_SLABS / mpi_size * mpi_rank + i;

            /* Write one slab of data. Due to start/count settings,
             * every 16th value will be a fill value. */
            if (nc_put_vara(ncid, varid, write_start, write_count, data)) ERR;
         }

         /* On rank 0, keep track of time. */
         if (!mpi_rank)
         {
            total_time = MPI_Wtime() - start_time;
            printf("%d\t%g\t%g\n", mpi_size, total_time, DIMSIZE * DIMSIZE * NUM_SLABS *
                   sizeof(int) / total_time);
         }

         /* Close the netcdf file. */
         if (nc_close(ncid)) ERR;

         /* Reopen the file and check it. */
         if ((ret = nc_open_par(file_name, NC_NOWRITE, comm, info, &ncid))) ERR;
         if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
         if (ndims_in != NDIMS || nvars_in != 1 || natts_in != 1 ||
             unlimdimid_in != -1) ERR;

         /* Check the attributes. */
         if (nc_get_att_int(ncid, NC_GLOBAL, "num_processors", &mpi_size_in)) ERR;
         if (mpi_size_in != mpi_size) ERR;
         if (nc_get_att_int(ncid, 0, "var_num_processors", &mpi_size_in)) ERR;
         if (mpi_size_in != mpi_size) ERR;
         if (fv == 1)
         {
            if (nc_inq_var_fill(ncid, varid, &fill_mode_in, fill_value_in)) ERR;
            if (fill_mode_in != NC_FILL) ERR;
            if (memcmp(fill_value_in, fill_value, type_size)) ERR;
         }

         /* Read all the slabs this process is responsible for. */
         for (i = 0; i < NUM_SLABS / mpi_size; i++)
         {
            read_start[0] = NUM_SLABS / mpi_size * mpi_rank + i;
            /* printf("mpi_rank %d i %d read_start[0] %ld\n", mpi_rank, i, read_start[0]); */

            /* Read one slab of data. */
            if (nc_get_vara(ncid, varid, read_start, read_count, data_in)) ERR;

            /* Check data.  For the third fill value test, fill is
             * turned off. So don't bother testing the values where k
             * is zero. */
            /* printf("mpi_rank %d fv %d i %d j %d k %d int_data_in[j * k] %d int_expected_fill_value %d " */
            /*        "expected_value %d\n", mpi_rank, fv, i, j, k, int_data_in[j * k], */
            /*        int_expected_fill_value, expected_value); */
            switch (test_type[tt])
            {
            case NC_BYTE:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (byte_data_in[j * DIMSIZE + k] != (signed char)(k ? mpi_rank : byte_expected_fill_value)) ERR;
               break;
            case NC_SHORT:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (short_data_in[j * DIMSIZE + k] != (short)(k ? mpi_rank : short_expected_fill_value)) ERR;
               break;
            case NC_INT:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (int_data_in[j * DIMSIZE + k] != (int)(k ? mpi_rank : int_expected_fill_value)) ERR;
               break;
            case NC_FLOAT:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (float_data_in[j * DIMSIZE + k] != (float)(k ? mpi_rank : float_expected_fill_value)) ERR;
               break;
            case NC_DOUBLE:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (double_data_in[j * DIMSIZE + k] != (double)(k ? mpi_rank : double_expected_fill_value)) ERR;
               break;
            case NC_UBYTE:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (ubyte_data_in[j * DIMSIZE + k] != (unsigned char)(k ? mpi_rank : ubyte_expected_fill_value)) ERR;
               break;
            case NC_USHORT:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (ushort_data_in[j * DIMSIZE + k] != (unsigned short)(k ? mpi_rank : ushort_expected_fill_value)) ERR;
               break;
            case NC_UINT:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (uint_data_in[j * DIMSIZE + k] != (unsigned int)(k ? mpi_rank : uint_expected_fill_value)) ERR;
               break;
            case NC_INT64:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (int64_data_in[j * DIMSIZE + k] != (long long int)(k ? mpi_rank : int64_expected_fill_value)) ERR;
               break;
            case NC_UINT64:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (uint64_data_in[j * DIMSIZE + k] != (unsigned long long int)(k ? mpi_rank : uint64_expected_fill_value)) ERR;
               break;
            }
         } /* next slab */

         /* Close the netcdf file. */
         if (nc_close(ncid))  ERR;

         if (!mpi_rank)
            SUMMARIZE_ERR;
      } /* next test type */
   } /* next fill value test run */

   /* Shut down MPI. */
   MPI_Finalize();

   if (!mpi_rank)
      FINAL_RESULTS;
   return 0;
}
Exemplo n.º 16
0
/* Copy a netCDF file, changing cmode if desired. */
static
int copy_file(char *file_name_in, char *file_name_out, int cmode_out,
	      int *chunking, int *deflate)
{
   int ncid_in, ncid_out;
   int natts, nvars, ndims, unlimdimid;
   char name[NC_MAX_NAME + 1];
   size_t len;
   int a, v, d;

   if (nc_open(file_name_in, NC_NOWRITE, &ncid_in)) ERR;
   if (nc_create(file_name_out, cmode_out, &ncid_out)) ERR;
      
   if (nc_inq(ncid_in, &ndims, &nvars, &natts, &unlimdimid)) ERR;

   /* Copy dims. */
   for (d = 0; d < ndims; d++)
   {
      if (nc_inq_dim(ncid_in, d, name, &len)) ERR;
      if (nc_def_dim(ncid_out, name, len, NULL)) ERR;
   }

   /* Copy global atts. */
   for (a = 0; a < natts; a++)
   {
      if (nc_inq_attname(ncid_in, NC_GLOBAL, a, name)) ERR;
      if (nc_copy_att(ncid_in, NC_GLOBAL, name, ncid_out, NC_GLOBAL)) ERR;
   }

   /* Copy the variable metadata. */
   for (v = 0; v < nvars; v++)
   {
      char name[NC_MAX_NAME + 1];
      char att_name[NC_MAX_NAME + 1];
      nc_type xtype;
      int ndims, dimids[NC_MAX_VAR_DIMS], natts;
      int varid_out;
      int a;
      int retval = NC_NOERR;

      /* Learn about this var. */
      if ((retval = nc_inq_var(ncid_in, v, name, &xtype, &ndims, dimids, &natts)))
	 return retval;

      /* Create the output var. */
      if (nc_def_var(ncid_out, name, xtype, ndims, dimids, &varid_out)) ERR;

      /* Except for 1D vars, sent chunking and compression. */
      if (ndims != 1)
      {
	 if (chunking)
	    if (nc_def_var_chunking(ncid_out, v, NC_CHUNKED, chunking)) ERR;
	 if (deflate)
	    if (nc_def_var_deflate(ncid_out, v, NC_NOSHUFFLE, *deflate, *deflate)) ERR;
      }

      /* Copy the attributes. */
      for (a=0; a<natts; a++)
      {
	 if (nc_inq_attname(ncid_in, v, a, att_name)) ERR;
	 if (nc_copy_att(ncid_in, v, att_name, ncid_out, varid_out)) ERR;
      }
   }

   /* Copy the variable data. */
   for (v = 0; v < nvars; v++)
   {
      char name[NC_MAX_NAME + 1];
      nc_type xtype;
      int ndims, dimids[NC_MAX_VAR_DIMS], natts, real_ndims;
      int d;
      void *data = NULL;
      size_t *count = NULL, *start = NULL;
      size_t reclen = 1;
      size_t *dimlen = NULL;
      int retval = NC_NOERR;
      size_t type_size;
      char type_name[NC_MAX_NAME+1];

      /* Learn about this var. */
      if ((retval = nc_inq_var(ncid_in, v, name, &xtype, &ndims, dimids, &natts)))
	 return retval;

      /* Later on, we will need to know the size of this type. */
      if ((retval = nc_inq_type(ncid_in, xtype, type_name, &type_size)))
	 return retval;
      LOG((3, "type %s has size %d", type_name, type_size));

      /* Allocate memory for our start and count arrays. If ndims = 0
	 this is a scalar, which I will treat as a 1-D array with one
	 element. */
      real_ndims = ndims ? ndims : 1;
      if (!(start = nc_malloc(real_ndims * sizeof(size_t))))
	 BAIL(NC_ENOMEM);
      if (!(count = nc_malloc(real_ndims * sizeof(size_t))))
	 BAIL(NC_ENOMEM);

      /* The start array will be all zeros, except the first element,
	 which will be the record number. Count will be the dimension
	 size, except for the first element, which will be one, because
	 we will copy one record at a time. For this we need the var
	 shape. */
      if (!(dimlen = nc_malloc(real_ndims * sizeof(size_t))))
	 BAIL(NC_ENOMEM);

      /* Find out how much data. */
      for (d=0; d<ndims; d++)
      {
	 if ((retval = nc_inq_dimlen(ncid_in, dimids[d], &dimlen[d])))
	    BAIL(retval);
	 LOG((4, "nc_copy_var: there are %d data", dimlen[d]));
      }

      /* If this is really a scalar, then set the dimlen to 1. */
      if (ndims == 0)
	 dimlen[0] = 1;

      for (d=0; d<real_ndims; d++)
      {
	 start[d] = 0;
	 count[d] = d ? dimlen[d] : 1;
	 if (d) reclen *= dimlen[d];
      }

      /* If there are no records, we're done. */
      if (!dimlen[0])
	 goto exit;

      /* Allocate memory for one record. */
      if (!(data = nc_malloc(reclen * type_size)))
	 return NC_ENOMEM;
   
      /* Copy the var data one record at a time. */
      for (start[0]=0; !retval && start[0]<(size_t)dimlen[0]; start[0]++)
      {
	 if (nc_get_vara(ncid_in, v, start, count, data)) ERR;
	 if (nc_put_vara(ncid_out, v, start, count, data)) ERR;
      }
    
     exit:
      if (data) nc_free(data);
      if (dimlen) nc_free(dimlen);
      if (start) nc_free(start);
      if (count) nc_free(count);

   }

   if (nc_close(ncid_in)) ERR;
   if (nc_close(ncid_out)) ERR;

   return NC_NOERR;
}
Exemplo n.º 17
0
static int
NC_meta_create_type1(int ncid, nc_type xtype,
		    MetaNode* root, MetaNode** typenodep)
{
    int ncstat = NC_NOERR;
    int i;
    MetaNode* node;
    nc_meta metatype = NC_NAT;

    /* Determine the top-level type for xtype */
    ncstat = mapnctype(ncid,xtype,&metatype);
    if(ncstat != NC_NOERR) goto done;    

    node = NC_meta_alloc(metatype);
    node->ncid = ncid;
    node->xtype = xtype;

    switch (node->nodeclass) {

    case NC_ATOMIC:
	ncstat = nc_inq_type(ncid,xtype,node->name,&node->size);
	if(ncstat != NC_NOERR) goto fail;
	break;

    case NC_OPAQUE:
	ncstat = nc_inq_opaque(ncid,xtype,node->name,&node->size);
	if(ncstat != NC_NOERR) goto fail;
	break;

    case NC_ENUM:
	ncstat = nc_inq_enum(ncid,xtype,node->name,&node->basetype,
				 &node->size,&node->nelems);
	if(ncstat != NC_NOERR) goto fail;
	/* Now, create and fill in the enum constants */
        node->econsts  = (struct MetaEconst*)calloc(node->nelems,
                                                    sizeof(struct MetaEconst));
	if(node->econsts == NULL) {ncstat = NC_ENOMEM;goto fail;}
	for(i=0;i<node->nelems;i++) {
	    struct MetaEconst* econst = node->consts+i;
	    ncstat = nc_inq_enum_member(ncid,xtype,i,
                                           econst->name,
                                           (void*)econst->value);
  	    if(ncstat != NC_NOERR) goto fail;
        }
	break;

    case NC_COMPOUND:
	ncstat = nc_inq_compound(ncid,xtype,node->name,&node->size,
				 &node->nelems);
	if(ncstat != NC_NOERR) goto fail;
	/* Now, create and fill in the fields */
        node->compound.fields = nc_meta_allocn(NC_FIELD,node->nelems);
	if(node->compound.fields == NULL) {ncstat = NC_ENOMEM;goto fail;}
	for(i=0;i<node->nelems;i++) {
	    MetaNode* field = node->compound.fields+i;
	    nc_type basetype;
	    ncstat = nc_inq_compound_field(ncid,xtype,i,
                                           field->name,
                                           &field->offset,
                                           &basetype,
					   &field->ndims,
					   field->dims);
  	    if(ncstat != NC_NOERR) goto fail;
	    /* create basetype */
	    ncstat = NC_meta_create_type(ncid,basetype,root,&field->basetype);
  	    if(ncstat != NC_NOERR) goto fail;
        }
	break;

    case NC_VLEN: {
        nc_type basetype;
	ncstat = nc_inq_vlen(ncid,xtype,node->name,&node->size,&basetype);
	if(ncstat != NC_NOERR) goto fail;
	/* create basetype */
	ncstat = NC_meta_create_type(ncid,basetype,root,&node->basetype);
  	if(ncstat != NC_NOERR) goto fail;
	} break;

    case NC_GROUP: {
	nc_type* typeids;
	ncstat = nc_inq_typeids(ncid,&node->nelems,NULL);
	if(ncstat != NC_NOERR) goto fail;
	typeids = (nc_type*)calloc(node->nelems,sizeof(nc_type));
	if(typeids == NULL) {ncstat = NC_ENOMEM; goto fail;}
	ncstat = nc_inq_typeids(ncid,&node->nelems,typeids);
	if(ncstat != NC_NOERR) goto fail;
	break;

    default: abort();
    }        
}

static int
mapnctype(int ncid, nc_type xtype, nc_meta* metatypep)
{
    int ncstat = NC_NOERR;
    if(metatypep == NULL) goto done;
    if(xtype <= NC_MAX_ATOMIC_TYPE) goto done;
    ncstat = nc_inq_user_type(ncid,xtype,NULL,NULL,NULL,NULL,metatypep);
done:
    return ncstat;
}