Exemplo n.º 1
0
/* Initialize iteration for a variable.  Just a wrapper for
 * nc_blkio_init() that makes the netCDF calls needed to initialize
 * lower-level iterator. */
int
nc_get_iter(int ncid,
	     int varid,
	     size_t bufsize,   /* size in bytes of memory buffer */
	     nciter_t **iterpp /* returned opaque iteration state */)
{
    int stat = NC_NOERR;
    nciter_t *iterp;
    nc_type vartype;
    size_t value_size = 0;      /* size in bytes of each variable element */
    int ndims;		    /* number of dimensions for variable */
    int *dimids;
    long long nvalues = 1;
    int dim;
    int chunked = 0;

    /* Caller should free this by calling nc_free_iter(iterp) */
    iterp = (nciter_t *) emalloc(sizeof(nciter_t));
    memset((void*)iterp,0,sizeof(nciter_t)); /* make sure it is initialized */

    NC_CHECK(nc_inq_varndims(ncid, varid, &ndims));

    dimids = (int *) emalloc((ndims + 1) * sizeof(int));

    iterp->dimsizes = (size_t *) emalloc((ndims + 1) * sizeof(size_t));
    iterp->chunksizes = (size_t *) emalloc((ndims + 1) * sizeof(size_t));

    NC_CHECK(nc_inq_vardimid (ncid, varid, dimids));
    for(dim = 0; dim < ndims; dim++) {
	size_t len;
	NC_CHECK(nc_inq_dimlen(ncid, dimids[dim], &len));
	nvalues *= len;
	iterp->dimsizes[dim] = len;
    }
    NC_CHECK(nc_inq_vartype(ncid, varid, &vartype));
    NC_CHECK(inq_value_size(ncid, vartype, &value_size));
#ifdef USE_NETCDF4
    {
	int contig = 1;
	if(ndims > 0) {
	    NC_CHECK(nc_inq_var_chunking(ncid, varid, &contig, NULL));
	}
	if(contig == 0) {	/* chunked */
	    NC_CHECK(nc_inq_var_chunking(ncid, varid, &contig, iterp->chunksizes));
	    chunked = 1;
	}
    }
#endif	/* USE_NETCDF4 */
    NC_CHECK(nc_blkio_init(bufsize, value_size, ndims, chunked, iterp));
    iterp->to_get = 0;
    free(dimids);
    *iterpp = iterp;
    return stat;
}
Exemplo n.º 2
0
/* Determine whether a variable named varname exists in any group in
   an open netCDF file with id ncid.  If so, return the count of how
   many matching variables were found, else return a count of 0.  The
   variable name can be absolute such as "/foo" or "/GRP1/GRP1A/foo",
   in which case there is only one group to look in, given by the path
   from the root group.  Alternatively, the variable name can be
   relative, such as "foo" or "GRPA/GRPB/foo", in which case every
   group is examined for a variable with that relative name.  */
size_t
nc_inq_varname_count(int ncid, char *varname) {
    /* 
       count = 0;
       status = nc_inq_gvarid(ncid, varname, varid);
       if (status == NC_NOERR)
          count++;
       for each subgroup gid {
          count += nc_inq_varname_count(gid, varname);
       }
       return count;
    */
    size_t count = 0;
    int varid;
    /* look in this group */
    int status = nc_inq_gvarid(ncid, varname, &varid);
#ifdef USE_NETCDF4
    int numgrps;
    int *ncids;
    int g;
#endif

    if (status == NC_NOERR)
	count++;

#ifdef USE_NETCDF4
    /* if this group has subgroups, call recursively on each of them */
    NC_CHECK( nc_inq_grps(ncid, &numgrps, NULL) );
	 
    /* Allocate memory to hold the list of group ids. */
    ncids = emalloc((numgrps + 1) * sizeof(int));
	
    /* Get the list of group ids. */
    NC_CHECK( nc_inq_grps(ncid, NULL, ncids) );
	
    /* Call this function for each group. */
    for (g = 0; g < numgrps; g++) {
	count += nc_inq_varname_count(ncids[g], varname);
    }
    free(ncids);
#endif /* USE_NETCDF4 */
    return count;    
   
}
Exemplo n.º 3
0
/* Get parent id needed to define a new group from its full name in an
 * open file identified by ncid.  Assumes all intermediate groups are
 * already defined.  */
static int
nc_inq_parid(int ncid, const char *fullname, int *locidp) {
    int stat = NC_NOERR;
    char *parent = strdup(fullname);
    char *slash = "/";		/* groupname separator */
    char *last_slash;
    if(parent == NULL) {
	NC_CHECK(NC_ENOMEM);
    }
    last_slash = strrchr(parent, '/');
    if(last_slash == parent) {	/* parent is root */
	free(parent);
	parent = strdup(slash);
    } else {
	*last_slash = '\0';	/* truncate to get parent name */
    }
    NC_CHECK(nc_inq_grp_full_ncid(ncid, parent, locidp));
       free(parent);
    return stat;
}
Exemplo n.º 4
0
/* 
 * copy a user-defined enum type in the group igrp to the group ogrp
 */
static int
copy_enum_type(int igrp, nc_type itype, int ogrp)
{
    int stat = NC_NOERR; 
    nc_type otype;
    nc_type basetype;
    size_t basesize;
    size_t nmembers;
    char name[NC_MAX_NAME];
    int i;

    NC_CHECK(nc_inq_enum(igrp, itype, name, &basetype, &basesize, &nmembers));
    NC_CHECK(nc_def_enum(ogrp, basetype, name, &otype));
    for(i = 0; i < nmembers; i++) { /* insert enum members */
	char ename[NC_MAX_NAME];
	long long val;		/* large enough to hold any integer type */
	NC_CHECK(nc_inq_enum_member(igrp, itype, i, ename, &val));
	NC_CHECK(nc_insert_enum(ogrp, otype, ename, &val));
    }
    return stat;
}
Exemplo n.º 5
0
/* 
 * Get total number of groups (including the top-level group and all
 * descendant groups, recursively) and all descendant subgroup ids
 * (including the input rootid of the start group) for a group and
 * all its descendants, in preorder.
 *
 * If grpids or numgrps is NULL, it will be ignored.  So typical use
 * is to call with grpids NULL to get numgrps, allocate enough space
 * for the group ids, then call again to get them.
 */
int
nc_inq_grps_full(int rootid, int *numgrps, int *grpids) 
{
    int stat = NC_NOERR;
    ncgiter_t *giter;		/* pointer to group iterator */
    int grpid;
    size_t count;

    NC_CHECK(nc_get_giter(rootid, &giter));
    
    count = 0;
    NC_CHECK(nc_next_giter(giter, &grpid));
    while(grpid != 0) {
	if(grpids)
	    grpids[count] = grpid;
	count++;
	NC_CHECK(nc_next_giter(giter, &grpid));
    }
    if(numgrps)
	*numgrps = count;
    nc_free_giter(giter);
    return stat;
}
Exemplo n.º 6
0
/* 
 * Get group id of next group.  On first call gets start group id,
 * subsequently returns other subgroup ids in preorder.  Returns zero
 * when no more groups left.
 */
int
nc_next_giter(ncgiter_t *iterp, int *grpidp) {
    int stat = NC_NOERR;
    int numgrps;
    int *grpids;
    int i;

    if(gs_empty(iterp)) {
	*grpidp = 0;		/* not a group, signals iterator is done */
    } else {
	*grpidp = gs_pop(iterp);
	NC_CHECK(nc_inq_grps2(*grpidp, &numgrps, NULL));
	if(numgrps > 0) {
	    grpids = (int *)emalloc(sizeof(int) * numgrps);
	    NC_CHECK(nc_inq_grps2(*grpidp, &numgrps, grpids));
	    for(i = numgrps - 1; i >= 0; i--) { /* push ids on stack in reverse order */
		gs_push(iterp, grpids[i]);
	    }
	    free(grpids);
	}
    }
    return stat;
}
Exemplo n.º 7
0
static void
pr_att(
    int ncid,
    int varid,
    const char *varname,
    int ia
    )
{
    struct ncatt att;		/* attribute */
	    
    NC_CHECK( nc_inq_attname(ncid, varid, ia, att.name) );

    Printf ("\t\t%s:%s = ", varname, att.name);

    NC_CHECK( nc_inq_att(ncid, varid, att.name, &att.type, &att.len) );

    if (att.len == 0) {	/* show 0-length attributes as empty strings */
	att.type = NC_CHAR;
	att.len = 1;
    }
    switch (att.type) {
    case NC_CHAR:
	att.string = (char *) malloc(att.len);
	if (!att.string) {
	    error("Out of memory!");
	    NC_CHECK( nc_close(ncid) );
	    return;
	}
	NC_CHECK( nc_get_att_text(ncid, varid, att.name, att.string ) );
	pr_att_string(att.len, att.string);
	free(att.string);
	break;
    default:
	att.vals = (double *) malloc(att.len * sizeof(double));
	if (!att.vals) {
	    error("Out of memory!");
	    NC_CHECK( nc_close(ncid) );
	    return;
	}
	NC_CHECK( nc_get_att_double(ncid, varid, att.name, att.vals ) );
	pr_att_vals(att.type, att.len, att.vals);
	free(att.vals);
	break;
    }
    Printf (" ;\n");
}
Exemplo n.º 8
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.º 9
0
/*
 * return 1 if varid identifies a record variable
 * else return 0
 */
int
isrecvar(int ncid, int varid)
{
    int ndims;
    int is_recvar = 0;
    int *dimids;

    NC_CHECK( nc_inq_varndims(ncid, varid, &ndims) );
#ifdef USE_NETCDF4
    if (ndims > 0) {
	int nunlimdims;
	int *recdimids;
	int dim, recdim;
	dimids = (int *) emalloc((ndims + 1) * sizeof(int));
	NC_CHECK( nc_inq_vardimid(ncid, varid, dimids) );
	NC_CHECK( nc_inq_unlimdims(ncid, &nunlimdims, NULL) );
	recdimids = (int *) emalloc((nunlimdims + 1) * sizeof(int));
	NC_CHECK( nc_inq_unlimdims(ncid, NULL, recdimids) );
	for (dim = 0; dim < ndims && is_recvar == 0; dim++) {
	    for(recdim = 0; recdim < nunlimdims; recdim++) {
		if(dimids[dim] == recdimids[recdim]) {
		    is_recvar = 1;
		    break;
		}		
	    }
	}
	free(dimids);
	free(recdimids);
    }
#else
    if (ndims > 0) {
	int recdimid;
	dimids = (int *) emalloc((ndims + 1) * sizeof(int));
	NC_CHECK( nc_inq_vardimid(ncid, varid, dimids) );
	NC_CHECK( nc_inq_unlimdim(ncid, &recdimid) );
	if(dimids[0] == recdimid)
	    is_recvar = 1;
	free(dimids);
    }
#endif /* USE_NETCDF4 */
    return is_recvar;
}
Exemplo n.º 10
0
static void
do_ncdump(const char *path, struct fspec* specp)
{
    int ndims;			/* number of dimensions */
    int nvars;			/* number of variables */
    int ngatts;			/* number of global attributes */
    int xdimid;			/* id of unlimited dimension */
    int dimid;			/* dimension id */
    int varid;			/* variable id */
    struct ncdim dims[NC_MAX_DIMS]; /* dimensions */
    size_t vdims[NC_MAX_DIMS];	/* dimension sizes for a single variable */
    struct ncvar var;		/* variable */
    struct ncatt att;		/* attribute */
    int id;			/* dimension number per variable */
    int ia;			/* attribute number */
    int iv;			/* variable number */
    int is_coord;		/* true if variable is a coordinate variable */
    int ncid;			/* netCDF id */
    vnode* vlist = 0;		/* list for vars specified with -v option */
    int nc_status;		/* return from netcdf calls */

    nc_status = nc_open(path, NC_NOWRITE, &ncid);
    if (nc_status != NC_NOERR) {
	error("%s: %s", path, nc_strerror(nc_status));
    }
    /*
     * If any vars were specified with -v option, get list of associated
     * variable ids
     */
    if (specp->nlvars > 0) {
	vlist = newvlist();	/* list for vars specified with -v option */
	for (iv=0; iv < specp->nlvars; iv++) {
	    NC_CHECK( nc_inq_varid(ncid, specp->lvars[iv], &varid) );
	    varadd(vlist, varid);
	}
    }

    /* if name not specified, derive it from path */
    if (specp->name == (char *)0) {
	specp->name = name_path (path);
    }

    Printf ("netcdf %s {\n", specp->name);
    /*
     * get number of dimensions, number of variables, number of global
     * atts, and dimension id of unlimited dimension, if any
     */
    NC_CHECK( nc_inq(ncid, &ndims, &nvars, &ngatts, &xdimid) );
    /* get dimension info */
    if (ndims > 0)
      Printf ("dimensions:\n");
    for (dimid = 0; dimid < ndims; dimid++) {
	NC_CHECK( nc_inq_dim(ncid, dimid, dims[dimid].name, &dims[dimid].size) );
	if (dimid == xdimid)
	  Printf ("\t%s = %s ; // (%ld currently)\n",dims[dimid].name,
		  "UNLIMITED", (long)dims[dimid].size);
	else
	  Printf ("\t%s = %ld ;\n", dims[dimid].name, (long)dims[dimid].size);
    }

    if (nvars > 0)
	Printf ("variables:\n");
    /* get variable info, with variable attributes */
    for (varid = 0; varid < nvars; varid++) {
	NC_CHECK( nc_inq_var(ncid, varid, var.name, &var.type, &var.ndims,
			     var.dims, &var.natts) );
	Printf ("\t%s %s", type_name(var.type), var.name);
	if (var.ndims > 0)
	  Printf ("(");
	for (id = 0; id < var.ndims; id++) {
	    Printf ("%s%s",
		    dims[var.dims[id]].name,
		    id < var.ndims-1 ? ", " : ")");
	}
	Printf (" ;\n");

	/* get variable attributes */
	for (ia = 0; ia < var.natts; ia++)
	    pr_att(ncid, varid, var.name, ia); /* print ia-th attribute */
    }


    /* get global attributes */
    if (ngatts > 0)
      Printf ("\n// global attributes:\n");
    for (ia = 0; ia < ngatts; ia++)
	pr_att(ncid, NC_GLOBAL, "", ia); /* print ia-th global attribute */
    
    if (! specp->header_only) {
	if (nvars > 0) {
	    Printf ("data:\n");
	}
	/* output variable data */
	for (varid = 0; varid < nvars; varid++) {
	    /* if var list specified, test for membership */
	    if (specp->nlvars > 0 && ! varmember(vlist, varid))
	      continue;
	    NC_CHECK( nc_inq_var(ncid, varid, var.name, &var.type, &var.ndims,
			    var.dims, &var.natts) );
	    if (specp->coord_vals) {
		/* Find out if this is a coordinate variable */
		is_coord = 0;
		for (dimid = 0; dimid < ndims; dimid++) {
		    if (strcmp(dims[dimid].name, var.name) == 0 &&
			var.ndims == 1) {
			is_coord = 1;
			break;
		    }
		}
		if (! is_coord)	/* don't get data for non-coordinate vars */
		  continue;
	    }
	    /*
	     * Only get data for variable if it is not a record variable,
	     * or if it is a record variable and at least one record has
	     * been written.
	     */
	    if (var.ndims == 0
		|| var.dims[0] != xdimid
		|| dims[xdimid].size != 0) {

		/* Collect variable's dim sizes */
		for (id = 0; id < var.ndims; id++)
		  vdims[id] = dims[var.dims[id]].size;
		var.has_fillval = 1; /* by default, but turn off for bytes */

		/* get _FillValue attribute */
		nc_status = nc_inq_att(ncid,varid,_FillValue,&att.type,&att.len);
		if(nc_status == NC_NOERR &&
		   att.type == var.type && att.len == 1) {
		    if(var.type == NC_CHAR) {
			char fillc;
			NC_CHECK( nc_get_att_text(ncid, varid, _FillValue,
						  &fillc ) );
			var.fillval = fillc;
		    } else {
			NC_CHECK( nc_get_att_double(ncid, varid, _FillValue,
						    &var.fillval) );
		    }
		} else {
		    switch (var.type) {
		    case NC_BYTE:
			/* don't do default fill-values for bytes, too risky */
			var.has_fillval = 0;
			break;
		    case NC_CHAR:
			var.fillval = NC_FILL_CHAR;
			break;
		    case NC_SHORT:
			var.fillval = NC_FILL_SHORT;
			break;
		    case NC_INT:
			var.fillval = NC_FILL_INT;
			break;
		    case NC_FLOAT:
			var.fillval = NC_FILL_FLOAT;
			break;
		    case NC_DOUBLE:
			var.fillval = NC_FILL_DOUBLE;
			break;
		    default:
			break;
		    }
		}
		if (vardata(&var, vdims, ncid, varid, specp) == -1) {
		    error("can't output data for variable %s", var.name);
		    NC_CHECK(
			nc_close(ncid) );
		    if (vlist)
			free(vlist);
		    return;
		}
	    }
	}
    }
    
    Printf ("}\n");
    NC_CHECK(
	nc_close(ncid) );
    if (vlist)
	free(vlist);
}
Exemplo n.º 11
0
/* Output the data for a single variable, in CDL syntax. */
int
vardata(
     const struct ncvar *vp,	/* variable */
     long vdims[],		/* variable dimension sizes */
     int ncid,			/* netcdf id */
     int varid,			/* variable id */
     const struct fspec* fsp	/* formatting specs */
     )
{
    long cor[NC_MAX_DIMS];	/* corner coordinates */
    long edg[NC_MAX_DIMS];	/* edges of hypercube */
    long add[NC_MAX_DIMS];      /* "odometer" increment to next "row"  */
#define VALBUFSIZ 1000
    double vals[VALBUFSIZ] ; /* aligned buffer */

    int gulp = VALBUFSIZ;

    int id;
    int ir;
    long nels;
    long ncols;
    long nrows;
    int vrank = vp->ndims;
    static int initeps = 0;

    /* printf format used to print each value */
    char *fmt = get_fmt(ncid, varid, vp->type);

    if (!initeps) {		/* make sure epsilons get initialized */
	init_epsilons();
	initeps = 1;
    }

    nels = 1;
    for (id = 0; id < vrank; id++) {
	cor[id] = 0;
	edg[id] = 1;
	nels *= vdims[id];	/* total number of values for variable */
    }

    if (vrank <= 1) {
	Printf("\n %s = ", vp->name);
	set_indent ((int)strlen(vp->name) + 4);
    } else {
	Printf("\n %s =\n  ", vp->name);
	set_indent (2);
    }

    if (vrank < 1) {
	ncols = 1;
    } else {
	ncols = vdims[vrank-1];	/* size of "row" along last dimension */
	edg[vrank-1] = vdims[vrank-1];
	for (id = 0; id < vrank; id++)
	  add[id] = 0;
	if (vrank > 1)
	  add[vrank-2] = 1;
    }
    nrows = nels/ncols;		/* number of "rows" */
    
    for (ir = 0; ir < nrows; ir++) {
	/*
	 * rather than just printing a whole row at once (which might exceed
	 * the capacity of MSDOS platforms, for example), we break each row
	 * into smaller chunks, if necessary.
	 */
	long corsav;
	int left = (int)ncols;
	boolean lastrow;

	if (vrank > 0) {
	    corsav = cor[vrank-1];
	    if (fsp->brief_data_cmnts != false
		&& vrank > 1
		&& left > 0) {	/* print brief comment with indices range */
		Printf("// %s(",vp->name);
		switch (fsp->data_lang) {
		  case LANG_C:
		    /* print brief comment with C variable indices */
		    for (id = 0; id < vrank-1; id++)
		      Printf("%lu,", (unsigned long)cor[id]);
		    if (vdims[vrank-1] == 1)
		      Printf("0");
		    else
		      Printf(" 0-%lu", (unsigned long)vdims[vrank-1]-1);
		    break;
		  case LANG_F:
		    /* print brief comment with Fortran variable indices */
		    if (vdims[vrank-1] == 1)
		      Printf("1");
		    else
		      Printf("1-%lu ", (unsigned long)vdims[vrank-1]);
		    for (id = vrank-2; id >=0 ; id--) {
			Printf(",%lu", (unsigned long)(1 + cor[id]));
		    }
		    break;
		}
		Printf(")\n    ");
		set_indent(4);
	    }
	}
	lastrow = (boolean)(ir == nrows-1);
	while (left > 0) {
	    long toget = left < gulp ? left : gulp;
	    if (vrank > 0)
	      edg[vrank-1] = toget;
	    switch(vp->type) {
	    case NC_CHAR:
		NC_CHECK(
		    ncvarget(ncid, varid, cor, edg, (char *)vals) );
	        pr_tvals(vp, toget, fmt, left > toget, lastrow,
			 (char *) vals, fsp, cor);
		break;
	    case NC_BYTE:
		NC_CHECK(
		    ncvarget(ncid, varid, cor, edg, (signed char *)vals) );
	        pr_bvals(vp, toget, fmt, left > toget, lastrow,
			 (signed char *) vals, fsp, cor);
		break;
	    case NC_SHORT:
		NC_CHECK(
		    ncvarget(ncid, varid, cor, edg, (short *)vals) );
	        pr_svals(vp, toget, fmt, left > toget, lastrow,
			 (short *) vals, fsp, cor);
		break;
	    case NC_INT:
		NC_CHECK(
		    ncvarget(ncid, varid, cor, edg, (int *)vals) );
	        pr_ivals(vp, toget, fmt, left > toget, lastrow,
			 (int *) vals, fsp, cor);
		break;
	    case NC_FLOAT:
		NC_CHECK(
		    ncvarget(ncid, varid, cor, edg, (float *)vals) );
	        pr_fvals(vp, toget, fmt, left > toget, lastrow,
			 (float *) vals, fsp, cor);
		break;
	    case NC_DOUBLE:
		NC_CHECK(
		    ncvarget(ncid, varid, cor, edg, (double *)vals) );
	        pr_dvals(vp, toget, fmt, left > toget, lastrow,
			 (double *) vals, fsp, cor);
		break;
	    default:
		error("vardata: bad type");
	    }
	    left -= toget;
	    if (vrank > 0)
	      cor[vrank-1] += toget;
	}
	if (vrank > 0)
	  cor[vrank-1] = corsav;
	if (ir < nrows-1)
	  if (!upcorner(vdims,vp->ndims,cor,add))
	    error("vardata: odometer overflowed!");
	set_indent(2);
    }

    return 0;
}
Exemplo n.º 12
0
int main(int argc, char ** argv)
{
	int ncid, dimid, varid;
	MPI_Init(&argc, &argv);
	MPI_Datatype vtype, rtype, usertype;
	MPI_Aint lb, extent;
	int userbufsz, *userbuf, *cmpbuf, i, errs=0;
	int count = 25;
	double pi = 3.14159;
	MPI_Offset start, acount;

	ncmpi_create(MPI_COMM_WORLD, "vectors.nc", NC_CLOBBER, MPI_INFO_NULL,
			&ncid);
	ncmpi_def_dim(ncid, "50k", 1024*50, &dimid);
	ncmpi_def_var(ncid, "vector", NC_DOUBLE, 1, &dimid, &varid);

	ncmpi_enddef(ncid);


	MPI_Type_vector(VECCOUNT, BLOCKLEN, STRIDE, MPI_INT, &vtype);
	MPI_Type_create_resized(vtype, 0, STRIDE*VECCOUNT*sizeof(int), &rtype);
	MPI_Type_contiguous(count, rtype, &usertype);
	MPI_Type_commit(&usertype);

	MPI_Type_free(&vtype);
	MPI_Type_free(&rtype);

	MPI_Type_get_extent(usertype, &lb, &extent);
	userbufsz = extent;
	userbuf = malloc(userbufsz);
	cmpbuf = calloc(userbufsz, 1);
	for (i=0; i< userbufsz/sizeof(int); i++) {
		userbuf[i] = pi*i;
	}


	start = 10; acount = count*12;
	ncmpi_begin_indep_data(ncid);
	ncmpi_put_vara(ncid, varid, &start, &acount, 
			userbuf, 1, usertype);

	ncmpi_close(ncid);

	NC_CHECK(ncmpi_open(MPI_COMM_WORLD, "vectors.nc", NC_NOWRITE,
				MPI_INFO_NULL, &ncid));
	ncmpi_begin_indep_data(ncid);
	NC_CHECK(ncmpi_inq_varid(ncid, "vector", &varid));
	NC_CHECK(ncmpi_get_vara(ncid, varid, &start, &acount,
			cmpbuf, 1, usertype));
	ncmpi_close(ncid);

	for (i=0; errs < 10 &&  i < acount; i++) {
		/* vector of 4,3,5, so skip 4th and 5th items of every block */
		if (i%STRIDE >= BLOCKLEN) continue;
		if (userbuf[i] != cmpbuf[i]) {
			errs++;
			fprintf(stderr, "%d: expected 0x%x got 0x%x\n", 
					i, userbuf[i], cmpbuf[i]);
		}
	}
	free(userbuf);
	free(cmpbuf);
	MPI_Type_free(&usertype);
	MPI_Finalize();
	return 0;
}
Exemplo n.º 13
0
/* Output the data for a single variable, in NcML syntax.
 *  TODO: currently not called, need option for NcML with values ... */
int
vardatax(
     const ncvar_t *vp,		/* variable */
     size_t vdims[],		/* variable dimension sizes */
     int ncid,			/* netcdf id */
     int varid			/* variable id */
     )
{
    size_t *cor;	     /* corner coordinates */
    size_t *edg;	     /* edges of hypercube */
    size_t *add;	     /* "odometer" increment to next "row"  */
    void *vals;

    int id;
    int ir;
    size_t nels;
    size_t ncols;
    size_t nrows;
    int vrank = vp->ndims;

    cor = (size_t *) emalloc((vrank + 1) * sizeof(size_t));
    edg = (size_t *) emalloc((vrank + 1) * sizeof(size_t));
    add = (size_t *) emalloc((vrank + 1) * sizeof(size_t));

    nels = 1;
    for (id = 0; id < vrank; id++) {
	cor[id] = 0;
	edg[id] = 1;
	nels *= vdims[id];	/* total number of values for variable */
    }

    printf("    <values>\n     ");
    set_indent (7);

    if (vrank < 1) {
	ncols = 1;
    } else {
	ncols = vdims[vrank-1];	/* size of "row" along last dimension */
	edg[vrank-1] = vdims[vrank-1];
	for (id = 0; id < vrank; id++)
	  add[id] = 0;
	if (vrank > 1)
	  add[vrank-2] = 1;
    }
    nrows = nels/ncols;		/* number of "rows" */
    vals = emalloc(ncols * vp->tinfo->size);

    for (ir = 0; ir < nrows; ir++) {
	size_t corsav;
	bool_t lastrow;

	if (vrank > 0) {
	    corsav = cor[vrank-1];
	}
	lastrow = (bool_t)(ir == nrows-1);

	if (vrank > 0)
	    edg[vrank-1] = ncols;
	NC_CHECK(nc_get_vara(ncid, varid, cor, edg, vals) );
	/* Test if we should treat array of chars as a string  */
	if(vp->type == NC_CHAR &&
	   (vp->fmt == 0 || STREQ(vp->fmt,"%s") || STREQ(vp->fmt,""))) {
	    pr_tvalsx(vp, ncols, 0, lastrow, (char *) vals);
	} else {
	    pr_any_valsx(vp, ncols, 0, lastrow, vals);
	}

	if (vrank > 0)
	    cor[vrank-1] += ncols;

	if (vrank > 0)
	  cor[vrank-1] = corsav;
	if (ir < nrows-1)
	  if (!upcorner(vdims,vp->ndims,cor,add))
	    error("vardata: odometer overflowed!");
	set_indent(2);
    }
    printf(" </values>\n");
    free(vals);
    free(cor);
    free(edg);
    free(add);
    return 0;
}
Exemplo n.º 14
0
/* Output the data for a single variable, in CDL syntax. */
int
vardata(
     const ncvar_t *vp,		/* variable */
     size_t vdims[],		/* variable dimension sizes */
     int ncid,			/* netcdf id */
     int varid			/* variable id */
     )
{
    size_t *cor;	     /* corner coordinates */
    size_t *edg;	     /* edges of hypercube */
    size_t *add;	     /* "odometer" increment to next "row"  */
    void *vals;

    int id;
    int ir;
    size_t nels;
    size_t ncols;
    size_t nrows;
    int vrank = vp->ndims;

    cor = (size_t *) emalloc((1 + vrank) * sizeof(size_t));
    edg = (size_t *) emalloc((1 + vrank) * sizeof(size_t));
    add = (size_t *) emalloc((1 + vrank) * sizeof(size_t));

    nels = 1;
    if(vrank == 0) { /*scalar*/
	cor[0] = 0;
	edg[0] = 1;
    } else {
	for (id = 0; id < vrank; id++) {
	    cor[id] = 0;
	    edg[id] = 1;
	    nels *= vdims[id];	/* total number of values for variable */
	}
    }
    printf("\n");
    indent_out();
    printf(" ");
    print_name(vp->name);
    if (vrank <= 1) {
	printf(" = ");
	set_indent ((int)strlen(vp->name) + 4 + indent_get());
    } else {
	printf(" =\n  ");
	set_indent (2 + indent_get());
    }

    if (vrank == 0) {
	ncols = 1;
    } else {
	ncols = vdims[vrank-1];	/* size of "row" along last dimension */
	edg[vrank-1] = ncols;
	for (id = 0; id < vrank; id++)
	  add[id] = 0;
	if (vrank > 1)
	  add[vrank-2] = 1;
    }
    nrows = nels/ncols;		/* number of "rows" */
    vals = emalloc(ncols * vp->tinfo->size);

    /* Test if we should treat array of chars as a string  */
    if(vp->type == NC_CHAR && (vp->fmt == 0 || STREQ(vp->fmt,"%s") || STREQ(vp->fmt,""))) {
	for (ir = 0; ir < nrows; ir++) {
	    if (vrank > 0) {
		if (formatting_specs.brief_data_cmnts != false && vrank > 1 && ncols > 0) {
		    annotate_brief(vp, cor, vdims);
		}
	    }
	    NC_CHECK(nc_get_vara(ncid, varid, cor, edg, vals));
	    pr_tvals(vp, ncols, (ir == nrows-1), (char *) vals, cor);
	    if (ir < nrows-1)
	      if (!upcorner(vdims, vp->ndims, cor, add))
	        error("vardata: odometer overflowed!");
	    set_indent(2);
	}
    } else {
	int level = 0;
	int rank = vp->ndims;
	int marks_pending = 0;
	NC_CHECK(print_rows(level, ncid, varid, vp, ncols, rank, vdims, cor, edg,
			    vals, marks_pending));
    }
    free(vals);
    free(cor);
    free(edg);
    free(add);

    return 0;
}
Exemplo n.º 15
0
/*  Print data values for variable varid.
 *
 * Recursive to handle possibility of variables with multiple
 * unlimited dimensions, for which the CDL syntax requires use of "{"
 * and "}" in data section to disambiguate the size of nested records
 * in a simple linear list of values.
 */
static int
print_rows(
    int level,          /* 0 at top-level, incremented for each recursive level */
    int ncid,		/* netcdf id */
    int varid,		/* variable id */
    const ncvar_t *vp,	/* variable */
    size_t ncols,	/* number of values in a row */
    int rank,	       	/* number of elements in following 3 arrays  */
    size_t vdims[],    	/* variable dimension sizes */
    size_t cor[],      	/* corner coordinates */
    size_t edg[],      	/* edges of hypercube */
    void *vals,   	/* allocated buffer for ncols values in a row */
    int marks_pending	/* number of pending closing "}" record markers */
    )
{
    int d0 = 0;
    size_t inc = 1;
    int i;
    bool_t mark_record = (level > 0 && is_unlim_dim(ncid, vp->dims[level]));
    safebuf_t *sb = sbuf_new();
    if (rank > 0)
	d0 = vdims[level];
    for(i = level + 1; i < rank; i++) {
	inc *= vdims[i];
    }
    if(mark_record) { /* the whole point of this recursion is printing these "{}" */
	lput("{");
	marks_pending++;	/* matching "}"s to emit after last "row" */
    }
    if(rank - level > 1) {     	/* this level is just d0 next levels */
	size_t *local_cor = emalloc((rank + 1) * sizeof(size_t));
	size_t *local_edg = emalloc((rank + 1) * sizeof(size_t));
	for(i = 0; i < rank; i++) {
	    local_cor[i] = cor[i];
	    local_edg[i] = edg[i];
	}
	local_cor[level] = 0;
	local_edg[level] = 1;
	for(i = 0; i < d0 - 1; i++) {
	    print_rows(level + 1, ncid, varid, vp, ncols, rank, vdims,
		       local_cor, local_edg, vals, 0);
	    local_cor[level] += 1;
	}
	print_rows(level + 1, ncid, varid, vp, ncols, rank, vdims,
		   local_cor, local_edg, vals, marks_pending);
	free(local_edg);
	free(local_cor);
    } else {			/* bottom out of recursion */
	char *valp = vals;
	bool_t lastrow;
	int j;
	if(formatting_specs.brief_data_cmnts && rank > 1) {
	    annotate_brief(vp, cor, vdims);
	}
	NC_CHECK(nc_get_vara(ncid, varid, cor, edg, (void *)valp));
	for(i=0; i < d0 - 1; i++) {
	    print_any_val(sb, vp, (void *)valp);
	    valp += vp->tinfo->size; /* next value according to type */
	    if (formatting_specs.full_data_cmnts) {
		printf("%s, ", sb->buf);
		annotate (vp, cor, i);
	    } else {
		sbuf_cat(sb, ", ");
		lput(sbuf_str(sb));
	    }
	}
	print_any_val(sb, vp, (void *)valp);
	/* determine if this is the last row */
	lastrow = true;
	for(j = 0; j < rank - 1; j++) {
	    if (cor[j] != vdims[j] - 1) {
		lastrow = false;
		break;
	    }
	}
	if (formatting_specs.full_data_cmnts) {
	    for (j = 0; j < marks_pending; j++) {
		sbuf_cat(sb, "}");
	    }
	    printf("%s", sbuf_str(sb));
	    lastdelim (0, lastrow);
	    annotate (vp, cor, i);
	} else {
	    for (j = 0; j < marks_pending; j++) {
		sbuf_cat(sb, "}");
	    }
	    lput(sbuf_str(sb));
	    lastdelim2 (0, lastrow);
	}
    }
    sbuf_free(sb);
    return NC_NOERR;
}
Exemplo n.º 16
0
/* Output the data for a single variable, in NcML syntax.
 *  TODO: currently not called, need option for NcML with values ... */
int
vardatax(
     const ncvar_t *vp,		/* variable */
     size_t vdims[],		/* variable dimension sizes */
     int ncid,			/* netcdf id */
     int varid,			/* variable id */
     const fspec_t *fsp	        /* formatting specs */
     )
{
    size_t cor[NC_MAX_DIMS];	/* corner coordinates */
    size_t edg[NC_MAX_DIMS];	/* edges of hypercube */
    size_t add[NC_MAX_DIMS];	/* "odometer" increment to next "row"  */
    size_t gulp;
    void *vals;

    int id;
    int ir;
    size_t nels;
    size_t ncols;
    size_t nrows;
    int vrank = vp->ndims;

    nels = 1;
    for (id = 0; id < vrank; id++) {
	cor[id] = 0;
	edg[id] = 1;
	nels *= vdims[id];	/* total number of values for variable */
    }

    printf("    <values>\n     ");
    set_indent (7);

    if (vrank < 1) {
	ncols = 1;
    } else {
	ncols = vdims[vrank-1];	/* size of "row" along last dimension */
	edg[vrank-1] = vdims[vrank-1];
	for (id = 0; id < vrank; id++)
	  add[id] = 0;
	if (vrank > 1)
	  add[vrank-2] = 1;
    }
    nrows = nels/ncols;		/* number of "rows" */
    gulp = ncols < VALBUFSIZ ? VALBUFSIZ : ncols;
    vals = emalloc(gulp * vp->tinfo->size);
    
    for (ir = 0; ir < nrows; ir++) {
	/*
	 * rather than just printing a whole row at once (which might
	 * exceed the capacity of some platforms), we break each row
	 * into smaller chunks, if necessary.
	 */
	size_t corsav;
	int left = (int)ncols;
	boolean lastrow;

	if (vrank > 0) {
	    corsav = cor[vrank-1];
	}
	lastrow = (boolean)(ir == nrows-1);
	while (left > 0) {
	    size_t toget = left < gulp ? left : gulp;
	    if (vrank > 0)
	      edg[vrank-1] = toget;
	    NC_CHECK(nc_get_vara(ncid, varid, cor, edg, vals) );

	    /* Test if we should treat array of chars as a string  */
	    if(vp->type == NC_CHAR && 
	       (vp->fmt == 0 || STREQ(vp->fmt,"%s") || STREQ(vp->fmt,""))) {
	        pr_tvalsx(vp, toget, left > toget, lastrow, (char *) vals);
	    } else {
	        pr_any_valsx(vp, toget, left > toget, lastrow, vals);
	    }

	    left -= toget;
	    if (vrank > 0)
	      cor[vrank-1] += toget;
	}
	if (vrank > 0)
	  cor[vrank-1] = corsav;
	if (ir < nrows-1)
	  if (!upcorner(vdims,vp->ndims,cor,add))
	    error("vardata: odometer overflowed!");
	set_indent(2);
    }
    printf(" </values>\n");
    free(vals);
    return 0;
}
Exemplo n.º 17
0
/* Output the data for a single variable, in CDL syntax. */
int
vardata(
     const ncvar_t *vp,		/* variable */
     size_t vdims[],		/* variable dimension sizes */
     int ncid,			/* netcdf id */
     int varid,			/* variable id */
     const fspec_t *fsp	        /* formatting specs */
     )
{
    size_t cor[NC_MAX_DIMS];	/* corner coordinates */
    size_t edg[NC_MAX_DIMS];	/* edges of hypercube */
    size_t add[NC_MAX_DIMS];	/* "odometer" increment to next "row"  */
    size_t gulp;
    void *vals;

    int id;
    int ir;
    size_t nels;
    size_t ncols;
    size_t nrows;
    int vrank = vp->ndims;

    nels = 1;
    for (id = 0; id < vrank; id++) {
	cor[id] = 0;
	edg[id] = 1;
	nels *= vdims[id];	/* total number of values for variable */
    }

    printf("\n");
    indent_out();
/* 	printf(" %s = ", vp->name); */
/*          or      */
/* 	printf(" %s =\n  ", vp->name); */
	printf(" ");
	print_name(vp->name);
    if (vrank <= 1) {
	printf(" = ");
	set_indent ((int)strlen(vp->name) + 4 + indent_get());
    } else {
	printf(" =\n  ");
	set_indent (2 + indent_get());
    }

    if (vrank < 1) {
	ncols = 1;
    } else {
	ncols = vdims[vrank-1];	/* size of "row" along last dimension */
	edg[vrank-1] = vdims[vrank-1];
	for (id = 0; id < vrank; id++)
	  add[id] = 0;
	if (vrank > 1)
	  add[vrank-2] = 1;
    }
    nrows = nels/ncols;		/* number of "rows" */
    gulp = ncols < VALBUFSIZ ? ncols : VALBUFSIZ;
    vals = emalloc(gulp * vp->tinfo->size);
    
    for (ir = 0; ir < nrows; ir++) {
	/*
	 * rather than just printing a whole row at once (which might
	 * exceed the capacity of some platforms), we break each row
	 * into smaller chunks, if necessary.
	 */
	size_t corsav = 0;
	int left = (int)ncols;
	boolean lastrow;

	if (vrank > 0) {
	    corsav = cor[vrank-1];
	    if (fsp->brief_data_cmnts != false
		&& vrank > 1
		&& left > 0) {	/* print brief comment with indices range */
/* 		printf("// %s(",vp->name); */
		printf("// ");
		printf(vp->name);
		printf("(");
		switch (fsp->data_lang) {
		  case LANG_C:
		    /* print brief comment with C variable indices */
		    for (id = 0; id < vrank-1; id++)
		      printf("%lu,", (unsigned long)cor[id]);
		    if (vdims[vrank-1] == 1)
		      printf("0");
		    else
		      printf(" 0-%lu", (unsigned long)vdims[vrank-1]-1);
		    break;
		  case LANG_F:
		    /* print brief comment with Fortran variable indices */
		    if (vdims[vrank-1] == 1)
		      printf("1");
		    else
		      printf("1-%lu ", (unsigned long)vdims[vrank-1]);
		    for (id = vrank-2; id >=0 ; id--) {
			printf(",%lu", (unsigned long)(1 + cor[id]));
		    }
		    break;
		}
		printf(")\n");
		indent_out();
		printf("    ");
		set_indent(4 + indent_get());
	    }
	}
	lastrow = (boolean)(ir == nrows-1);
	while (left > 0) {
	    size_t toget = left < gulp ? left : gulp;
	    if (vrank > 0)
	      edg[vrank-1] = toget;
	    NC_CHECK(nc_get_vara(ncid, varid, cor, edg, vals) );
	    /* Test if we should treat array of chars as a string  */
	    if(vp->type == NC_CHAR && 
	       (vp->fmt == 0 || STREQ(vp->fmt,"%s") || STREQ(vp->fmt,""))) {
	        pr_tvals(vp, toget, left > toget, lastrow, (char *) vals, 
			 fsp, cor);
	    } else {
	        pr_any_vals(vp, toget, left > toget, lastrow, vals, fsp, cor);
	    }

	    left -= toget;
	    if (vrank > 0)
	      cor[vrank-1] += toget;
	}
	if (vrank > 0)
	  cor[vrank-1] = corsav;
	if (ir < nrows-1)
	  if (!upcorner(vdims,vp->ndims,cor,add))
	    error("vardata: odometer overflowed!");
	set_indent(2);
    }

    free(vals);
    return 0;
}
Exemplo n.º 18
0
/* Output the data for a single variable, in CDL syntax. */
int
vardata(
     const ncvar_t *vp,		/* variable */
     size_t vdims[],		/* variable dimension sizes */
     int ncid,			/* netcdf id */
     int varid			/* variable id */
     )
{
    size_t *cor;	     /* corner coordinates */
    size_t *edg;	     /* edges of hypercube */
    size_t *add;	     /* "odometer" increment to next "row"  */
    void *vals;

    int id;
    size_t nels;
    size_t ncols;
    size_t nrows;
    int vrank = vp->ndims;

    int level = 0;
    int marks_pending = 0;

    cor = (size_t *) emalloc((1 + vrank) * sizeof(size_t));
    edg = (size_t *) emalloc((1 + vrank) * sizeof(size_t));
    add = (size_t *) emalloc((1 + vrank) * sizeof(size_t));

    nels = 1;
    if(vrank == 0) { /*scalar*/
	cor[0] = 0;
	edg[0] = 1;
    } else {
	for (id = 0; id < vrank; id++) {
	    cor[id] = 0;
	    edg[id] = 1;
	    nels *= vdims[id];	/* total number of values for variable */
	}
    }
    printf("\n");
    indent_out();
    printf(" ");
    print_name(vp->name);
    if (vrank <= 1) {
	printf(" = ");
	set_indent ((int)strlen(vp->name) + 4 + indent_get());
    } else {
	printf(" =\n  ");
	set_indent (2 + indent_get());
    }

    if (vrank == 0) {
	ncols = 1;
    } else {
	ncols = vdims[vrank-1];	/* size of "row" along last dimension */
	edg[vrank-1] = ncols;
	for (id = 0; id < vrank; id++)
	  add[id] = 0;
	if (vrank > 1)
	  add[vrank-2] = 1;
    }
    nrows = nels/ncols;		/* number of "rows" */
    vals = emalloc(ncols * vp->tinfo->size);
    
    NC_CHECK(print_rows(level, ncid, varid, vp, vdims, cor, edg, vals, marks_pending));
    free(vals);
    free(cor);
    free(edg);
    free(add);

    return 0;
}