int ex_get_partial_one_attr( int exoid, ex_entity_type obj_type, ex_entity_id obj_id, int64_t start_num, int64_t num_ent, int attrib_index, void* attrib ) { int status; int attrid, obj_id_ndx; int temp; size_t num_entries_this_obj, num_attr; size_t start[2], count[2]; ptrdiff_t stride[2]; char errmsg[MAX_ERR_LENGTH]; const char* dnumobjent; const char* dnumobjatt; const char* vattrbname; exerrval = 0; /* clear error code */ if (num_ent == 0) return 0; /* Determine index of obj_id in vobjids array */ if (obj_type != EX_NODAL) { obj_id_ndx = ex_id_lkup(exoid,obj_type,obj_id); if (exerrval != 0) { if (exerrval == EX_NULLENTITY) { sprintf(errmsg, "Warning: no attributes found for NULL %s %"PRId64" in file id %d", ex_name_of_object(obj_type),obj_id,exoid); ex_err("ex_get_partial_one_attr",errmsg,EX_NULLENTITY); return (EX_WARN); /* no attributes for this object */ } else { sprintf(errmsg, "Warning: failed to locate %s id%"PRId64" in id array in file id %d", ex_name_of_object(obj_type),obj_id, exoid); ex_err("ex_get_partial_one_attr",errmsg,exerrval); return (EX_WARN); } } } switch (obj_type) { case EX_SIDE_SET: dnumobjent = DIM_NUM_SIDE_SS(obj_id_ndx); dnumobjatt = DIM_NUM_ATT_IN_SS(obj_id_ndx); vattrbname = VAR_SSATTRIB(obj_id_ndx); break; case EX_NODE_SET: dnumobjent = DIM_NUM_NOD_NS(obj_id_ndx); dnumobjatt = DIM_NUM_ATT_IN_NS(obj_id_ndx); vattrbname = VAR_NSATTRIB(obj_id_ndx); break; case EX_EDGE_SET: dnumobjent = DIM_NUM_EDGE_ES(obj_id_ndx); dnumobjatt = DIM_NUM_ATT_IN_ES(obj_id_ndx); vattrbname = VAR_ESATTRIB(obj_id_ndx); break; case EX_FACE_SET: dnumobjent = DIM_NUM_FACE_FS(obj_id_ndx); dnumobjatt = DIM_NUM_ATT_IN_FS(obj_id_ndx); vattrbname = VAR_FSATTRIB(obj_id_ndx); break; case EX_ELEM_SET: dnumobjent = DIM_NUM_ELE_ELS(obj_id_ndx); dnumobjatt = DIM_NUM_ATT_IN_ELS(obj_id_ndx); vattrbname = VAR_ELSATTRIB(obj_id_ndx); break; case EX_NODAL: dnumobjent = DIM_NUM_NODES; dnumobjatt = DIM_NUM_ATT_IN_NBLK; vattrbname = VAR_NATTRIB; break; case EX_EDGE_BLOCK: dnumobjent = DIM_NUM_ED_IN_EBLK(obj_id_ndx); dnumobjatt = DIM_NUM_ATT_IN_EBLK(obj_id_ndx); vattrbname = VAR_EATTRIB(obj_id_ndx); break; case EX_FACE_BLOCK: dnumobjent = DIM_NUM_FA_IN_FBLK(obj_id_ndx); dnumobjatt = DIM_NUM_ATT_IN_FBLK(obj_id_ndx); vattrbname = VAR_FATTRIB(obj_id_ndx); break; case EX_ELEM_BLOCK: dnumobjent = DIM_NUM_EL_IN_BLK(obj_id_ndx); dnumobjatt = DIM_NUM_ATT_IN_BLK(obj_id_ndx); vattrbname = VAR_ATTRIB(obj_id_ndx); break; default: exerrval = 1005; sprintf(errmsg, "Internal Error: unrecognized object type in switch: %d in file id %d", obj_type,exoid); ex_err("ex_get_partial_one_attr",errmsg,EX_MSG); return (EX_FATAL); /* number of attributes not defined */ } /* inquire id's of previously defined dimensions */ if (ex_get_dimension(exoid, dnumobjent,"entries", &num_entries_this_obj, &temp, "ex_get_partial_one_attr") != NC_NOERR) return EX_FATAL; if (start_num + num_ent -1 > num_entries_this_obj) { exerrval = EX_BADPARAM; sprintf(errmsg, "Error: start index (%"PRId64") + count (%"PRId64") is larger than total number of entities (%"ST_ZU") in file id %d", start_num, num_ent, num_entries_this_obj, exoid); ex_err("ex_get_partial_one_attr",errmsg,exerrval); return (EX_FATAL); } if (ex_get_dimension(exoid, dnumobjatt,"attributes", &num_attr, &temp, "ex_get_partial_one_attr") != NC_NOERR) return EX_FATAL; if (attrib_index < 1 || attrib_index > (int)num_attr) { exerrval = EX_FATAL; sprintf(errmsg, "Error: Invalid attribute index specified: %d. Valid range is 1 to %d for %s %"PRId64" in file id %d", attrib_index, (int)num_attr, ex_name_of_object(obj_type), obj_id, exoid); ex_err("ex_get_partial_one_attr",errmsg,exerrval); return (EX_FATAL); } if ((status = nc_inq_varid(exoid, vattrbname, &attrid)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to locate attributes for %s %"PRId64" in file id %d", ex_name_of_object(obj_type),obj_id,exoid); ex_err("ex_get_partial_one_attr",errmsg,exerrval); return (EX_FATAL); } /* read in the attributes */ start[0] = start_num-1; start[1] = attrib_index-1; count[0] = num_ent; count[1] = 1; stride[0] = 1; stride[1] = num_attr; if (ex_comp_ws(exoid) == 4) { status = nc_get_vars_float(exoid, attrid, start, count, stride, attrib); } else { status = nc_get_vars_double(exoid, attrid, start, count, stride, attrib); } if (status != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to get attribute %d for %s %"PRId64" in file id %d", attrib_index, ex_name_of_object(obj_type), obj_id,exoid); ex_err("ex_get_partial_one_attr",errmsg,exerrval); return (EX_FATAL); } return(EX_NOERR); }
int nc3d_getvarmx(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t* stride, const ptrdiff_t* map, void* data, nc_type dsttype0) { NCerror ncstat = NC_NOERR; int i; NC* drno; NC* substrate; NC3_INFO* substrate3; NCDAPCOMMON* dapcomm; NC_var* var; CDFnode* cdfvar; /* cdf node mapping to var*/ NClist* varnodes; nc_type dsttype; size_t externsize; size_t dimsizes[NC_MAX_VAR_DIMS]; Dapodometer* odom = NULL; unsigned int ncrank; NClist* ncdims = NULL; size_t nelems; #ifdef NEWVARM char* localcopy; /* of whole variable */ #endif ncstat = NC_check_id(ncid, (NC**)&drno); if(ncstat != NC_NOERR) goto done; dapcomm = (NCDAPCOMMON*)drno->dispatchdata; ncstat = NC_check_id(drno->substrate, &substrate); if(ncstat != NC_NOERR) goto done; substrate3 = (NC3_INFO*)drno->dispatchdata; var = NC_lookupvar(substrate3,varid); if(var == NULL) {ncstat = NC_ENOTVAR; goto done;} /* Locate var node via varid */ varnodes = dapcomm->cdf.ddsroot->tree->varnodes; for(i=0;i<nclistlength(varnodes);i++) { CDFnode* node = (CDFnode*)nclistget(varnodes,i); if(node->array.basevar == NULL && node->nctype == NC_Atomic && node->ncid == varid) { cdfvar = node; break; } } ASSERT((cdfvar != NULL)); ASSERT((strcmp(cdfvar->ncfullname,var->name->cp)==0)); if(nclistlength(cdfvar->array.dimsetplus) == 0) { /* The variable is a scalar; consequently, there is only one thing to get and only one place to put it. */ /* recurse with additional parameters */ return THROW(nc3d_getvarx(ncid,varid, NULL,NULL,NULL, data,dsttype0)); } dsttype = (dsttype0); /* Default to using the inquiry type for this var*/ if(dsttype == NC_NAT) dsttype = cdfvar->externaltype; /* Validate any implied type conversion*/ if(cdfvar->etype != dsttype && dsttype == NC_CHAR) { /* The only disallowed conversion is to/from char and non-byte numeric types*/ switch (cdfvar->etype) { case NC_STRING: case NC_URL: case NC_CHAR: case NC_BYTE: case NC_UBYTE: break; default: return THROW(NC_ECHAR); } } externsize = nctypesizeof(dsttype); /* Accumulate the dimension sizes and the total # of elements */ ncdims = cdfvar->array.dimsetall; ncrank = nclistlength(ncdims); nelems = 1; /* also Compute the number of elements being retrieved */ for(i=0;i<ncrank;i++) { CDFnode* dim = (CDFnode*)nclistget(ncdims,i); dimsizes[i] = dim->dim.declsize; nelems *= edges[i]; } /* Originally, this code repeatedly extracted single values using get_var1. In an attempt to improve performance, I have converted to reading the whole variable at once and walking it locally. */ #ifdef NEWVARM localcopy = (char*)malloc(nelems*externsize); /* We need to use the varieties of get_vars in order to properly do conversion to the external type */ switch (dsttype) { case NC_CHAR: ncstat = nc_get_vars_text(ncid,varid,start, edges, stride, (char*)localcopy); break; case NC_BYTE: ncstat = nc_get_vars_schar(ncid,varid,start, edges, stride, (signed char*)localcopy); break; case NC_SHORT: ncstat = nc_get_vars_short(ncid,varid, start, edges, stride, (short*)localcopy); break; case NC_INT: ncstat = nc_get_vars_int(ncid,varid,start, edges, stride, (int*)localcopy); break; case NC_FLOAT: ncstat = nc_get_vars_float(ncid,varid,start, edges, stride, (float*)localcopy); break; case NC_DOUBLE: ncstat = nc_get_vars_double(ncid,varid, start, edges, stride, (double*)localcopy); break; default: break; } odom = dapodom_new(ncrank,start,edges,stride,NULL); /* Walk the local copy */ for(i=0;i<nelems;i++) { size_t voffset = dapodom_varmcount(odom,map,dimsizes); void* dataoffset = (void*)(((char*)data) + (externsize*voffset)); char* localpos = (localcopy + externsize*i); /* extract the indexset'th value from local copy */ memcpy(dataoffset,(void*)localpos,externsize); /* fprintf(stderr,"new: %lu -> %lu %f\n", (unsigned long)(i), (unsigned long)voffset, *(float*)localpos); */ dapodom_next(odom); } #else odom = dapodom_new(ncrank,start,edges,stride,NULL); while(dapodom_more(odom)) { size_t* indexset = odom->index; size_t voffset = dapodom_varmcount(odom,map,dimsizes); char internalmem[128]; char externalmem[128]; void* dataoffset = (void*)(((char*)data) + (externsize*voffset)); /* get the indexset'th value using variable's internal type */ ncstat = nc_get_var1(ncid,varid,indexset,(void*)&internalmem); if(ncstat != NC_NOERR) goto done; /* Convert to external type */ ncstat = dapconvert3(cdfvar->etype,dsttype,externalmem,internalmem); if(ncstat != NC_NOERR) goto done; memcpy(dataoffset,(void*)externalmem,externsize); /* fprintf(stderr,"old: %lu -> %lu %f\n", (unsigned long)dapodom_count(odom), (unsigned long)voffset, *(float*)externalmem); */ dapodom_next(odom); } #endif done: return ncstat; }