/* We examine all of Silo's data by traversing the all the "simple" arrays in the file. Ultimately, the data associated with all of Silo's abstract objects, excpet for object headers, is implemented in terms of simple arrays. This function finds all the simple arrays in the current dir and for each float or double array, reads it and examines it for NaNs. To avoid constantly allocating and freeing the buffers for arrays, we simply keep a growing buffer that grows to the largest array in the file and is freed only upon exit. We use Silo's non-allocating simple array read function. To make the loops for checking a NaN as fast as possible, we have two versions of the loop, one where progress is checked and one where progress is not checked. We first examine all the simple arrays in the current dir, then we loop over subdirs and recurse */ static void scanSiloDir(DBfile *siloFile, char *theDir) { char **dirNames; int i,nDirs,nObjects; DBtoc *toc; DBNewToc(siloFile); toc = DBGetToc(siloFile); if (toc == NULL) return ; nObjects = toc->nvar + toc->ndir; if (!nObjects) return ; /* process the simple arrays in this dir */ for (i = 0; i < toc->nvar; i++) { char *varName = toc->var_names[i]; int n = DBGetVarLength(siloFile, varName); int dbType = DBGetVarType(siloFile, varName); int j; if (!disableVerbose) { if (dbType == DB_FLOAT || dbType == DB_DOUBLE) printf("CHECKING array %-56s\r", varName); else printf("skipping array %-56s\r", varName); } /* for float arrays */ if (dbType == DB_FLOAT) { /* increase allocated buffer if necessary */ if (n*sizeof(float) > fBufSize) { if (fBuf != NULL) free(fBuf); fBuf = (float *) malloc(n * sizeof(float)); fBufSize = n; } DBReadVar(siloFile, varName, fBuf); if (disableProgress) { for (j = 0; j < n; j++) if (!IS_VALID_FLOAT(fBuf[j])) handleInvalidValue(theDir, varName, j, (double) fBuf[j]); } else { for (j = 0; j < n; j++) { if (!IS_VALID_FLOAT(fBuf[j])) handleInvalidValue(theDir, varName, j, (double) fBuf[j]); updateProgress(sizeof(float)); } } } /* for double arrays */ if (dbType == DB_DOUBLE) { /* increase allocated buffer if necessary */ if (n*sizeof(double) > dBufSize) { if (dBuf != NULL) free(dBuf); dBuf = (double *) malloc(n * sizeof(double)); dBufSize = n; } DBReadVar(siloFile, varName, dBuf); if (disableProgress) { for (j = 0; j < n; j++) if (!IS_VALID_DOUBLE(dBuf[j])) handleInvalidValue(theDir, varName, j, dBuf[j]); } else { for (j = 0; j < n; j++) { if (!IS_VALID_DOUBLE(dBuf[j])) handleInvalidValue(theDir, varName, j, dBuf[j]); updateProgress(sizeof(double)); } } } } /* for i */ /* save off the dir-stuff out of the toc so we don't loose it during the recursions */ nDirs = toc->ndir; dirNames = (char **) malloc(nDirs * sizeof(char*)); for (i = 0; i < nDirs; i++) { dirNames[i] = (char *) malloc(strlen(toc->dir_names[i])+1); strcpy(dirNames[i], toc->dir_names[i]); } /* recurse on any subdirs */ for (i = 0; i < nDirs; i++) { DBSetDir(siloFile, dirNames[i]); scanSiloDir(siloFile, dirNames[i]); DBSetDir(siloFile, ".."); free(dirNames[i]); } /* free the dir-stuff we set aside */ free(dirNames); }
void perform_merge( hpx::lcos::local::channel<void>& sync , DBfile* file , std::vector<std::string> const& directory_names , std::string const& variable_name , boost::uint64_t& step , double& time ) { // {{{ for (boost::uint64_t level = 0; level < directory_names.size(); ++level) { int error = DBSetDir(file, directory_names[level].c_str()); OCTOPUS_ASSERT(error == 0); // Get a list of all the meshes and variables in that directory. DBtoc* contents = DBGetToc(file); // Make the mesh and variable names. boost::ptr_vector<char> mesh_names(contents->nqmesh); boost::ptr_vector<char> variable_names(contents->nqmesh); double grid_dim = config().spatial_domain; for (boost::uint64_t i = 1; i < level; ++i) grid_dim *= 0.5; for (boost::uint64_t j = 0; j < boost::uint64_t(contents->nqmesh); ++j) { std::string tmp; /////////////////////////////////////////////////////////////////// tmp = directory_names[level]; tmp += "/"; tmp += contents->qmesh_names[j]; // The extra character is for the terminating byte. mesh_names.push_back(new char[tmp.size() + 1]); std::strcpy(&mesh_names[j], tmp.c_str()); /////////////////////////////////////////////////////////////////// tmp = directory_names[level]; tmp += "/"; tmp += contents->qvar_names[j]; // The extra character is for the terminating byte. variable_names.push_back(new char[tmp.size() + 1]); std::strcpy(&variable_names[j], tmp.c_str()); } // when we change directories below, "contents" will go out of scope boost::uint64_t nqmesh = contents->nqmesh; error = DBSetDir(file, "/"); OCTOPUS_ASSERT(error == 0); std::string multi_mesh_name = boost::str( boost::format("mesh_level_%1%") % level); std::string multi_variable_name = boost::str( boost::format("%1%_level_%2%") % variable_name % level); { DBoptlist* optlist = DBMakeOptlist(4); DBObjectType type1 = DB_QUADRECT; DBAddOption(optlist, DBOPT_MB_BLOCK_TYPE, &type1); DBAddOption(optlist, DBOPT_CYCLE, &step); DBAddOption(optlist, DBOPT_DTIME, &time); error = DBPutMultimesh(file , multi_mesh_name.c_str() , nqmesh , mesh_names.c_array() , NULL, optlist); OCTOPUS_ASSERT(error == 0); } { DBoptlist* optlist = DBMakeOptlist(4); DBObjectType type1 = DB_QUADVAR; DBAddOption(optlist, DBOPT_MB_BLOCK_TYPE, &type1); DBAddOption(optlist, DBOPT_CYCLE, &step); DBAddOption(optlist, DBOPT_DTIME, &time); int type2 = DB_ROWMAJOR; DBAddOption(optlist, DBOPT_MAJORORDER, &type2); error = DBPutMultivar(file , multi_variable_name.c_str() , nqmesh , variable_names.c_array() , NULL, optlist); OCTOPUS_ASSERT(error == 0); } } sync.post(); } // }}}
/*------------------------------------------------------------------------- * Function: test_dirs * * Purpose: Test directory operations * * Return: Success: 0 * * Failure: number of errors * * Programmer: Robb Matzke * Wednesday, February 10, 1999 * * Modifications: * Robb Matzke, 2000-01-12 * Changed hyphens to underscores in object names because silo * now fails when underscores are present in the name. *------------------------------------------------------------------------- */ static int test_dirs(DBfile *dbfile) { int nerrors=0; char curdir[1024]; static int in[1]={911}, value[1]={0}; static int dims[1]={1}; puts("=== Directories ==="); /* Make some directories */ if (DBMkDir(dbfile, "dir1")<0) { puts("DBMkDir(dir1) failed"); nerrors++; } if (DBMkDir(dbfile, "dir1/d1a")<0) { puts("DBMkDir(dir1/d1a) failed"); nerrors++; } if (DBMkDir(dbfile, "/dir1/d1b")<0) { puts("DBMkDir(dir1/d1b) failed"); nerrors++; } if (DBMkDir(dbfile, "/dir1/d1c/")<0) { puts("DBMkDir(dir1/d1c) failed"); nerrors++; } if (DBMkdir(dbfile, "//dir2//")<0) { puts("DBMkDir(dir2) failed"); nerrors++; } /* Set the CWD to /dir1/d1c and write a variable */ if (DBSetDir(dbfile, "//dir1//d1c//")<0) { puts("DBSetDir(/dir1/d1c) failed"); nerrors++; } if (DBWrite(dbfile, "d1c_A", value, dims, 1, DB_INT)<0) { puts("DBWrite(d1c_A) failed"); nerrors++; } if (DBGetDir(dbfile, curdir)<0 || strcmp(curdir, "/dir1/d1c")) { puts("DBGetDir() failed"); nerrors++; } if (DBReadVar(dbfile, "../d1c/..//..////dir1/d1c//d1c_A", in)<0 || in[0]!=value[0]) { puts("DBReadVar(d1c_A) failed"); nerrors++; } /* Test table of contents */ if (NULL==DBGetToc(dbfile)) { puts("DBGetToc() failed"); nerrors++; } /* Set CWD to top */ if (DBSetDir(dbfile, "/")<0) { puts("DBSetDir(/) failed"); nerrors++; } if (DBGetDir(dbfile, curdir)<0 || strcmp(curdir, "/")) { puts("DBetDir() failed"); nerrors++; } return nerrors; }
Databox *ReadSilo(char *filename, double default_value) { #ifdef HAVE_SILO Databox *v; double X, Y, Z; int NX, NY, NZ; double DX, DY, DZ; int x, y, z; int nx, ny, nz; int j, k; double *ptr; int err = -1; DBfile *db; double epsi = 1.0E-16; char *current_path = NULL; char *path = NULL; char *slash = strchr(filename, '/'); float *localcoords[3]; if(slash) { path = (char *)malloc(MAXPATHLEN); strncpy(path, filename, slash - filename); path[slash - filename] = 0; filename = strdup(slash + 1); } else { filename = strdup(filename); } if(path) { current_path = (char *)malloc(MAXPATHLEN); getwd(current_path); chdir(path); } // db = DBOpen(filename, DB_PDB, DB_READ); db = DBOpen(filename, DB_UNKNOWN, DB_READ); if(db == NULL) { printf("Failed to open SILO file %s\n", filename); return NULL; } double origin[3]; err = DBReadVar(db, "origin", &origin); if(err < 0) { printf("Failed to read meta data\n"); return NULL; } X = origin[0]; Y = origin[1]; Z = origin[2]; int size[3]; err = DBReadVar(db, "size", &size); if(err < 0) { printf("Failed to read meta data\n"); return NULL; } NX = size[0]; NY = size[1]; NZ = size[2]; double delta[3]; err = DBReadVar(db, "delta", &delta); if(err < 0) { printf("Failed to read meta data\n"); return NULL; } DX = delta[0]; DY = delta[1]; DZ = delta[2]; /* create the new databox structure */ if ((v = NewDataboxDefault(NX, NY, NZ, X, Y, Z, DX, DY, DZ, default_value)) == NULL) { return((Databox *)NULL); } DBtoc *toc = DBGetToc(db); if ( toc == NULL ) { printf("Error: Silo get get TOC failed for %s\n", filename); return NULL; } char **multivar_names = toc -> multivar_names; int nmultivar = toc -> nmultivar; /* Check to see if file has a multivar in it to determine file format being used */ if(nmultivar == 0) { DBquadvar *var = DBGetQuadvar(db, "variable"); if(var == NULL) { printf("Error: Silo failed to get quadvar %s \n", "variable"); return NULL; } memcpy(DataboxCoeff(v, 0, 0, 0), var -> vals[0], NX*NY*NZ * sizeof(double)); DBFreeQuadvar(var); } else { DBmultivar *multivar = DBGetMultivar(db, multivar_names[0]); if ( multivar == NULL ) { printf("Error: Silo get multivar failed for %s\n", multivar_names[0]); return NULL; } int nvars = multivar -> nvars; char **varnames = multivar -> varnames; int i; int m; for(m = 0; m < nvars; m++) { char *proc_filename; char *seperator = ":"; proc_filename = strtok(varnames[m], seperator); char *proc_varname; proc_varname = strtok(NULL, seperator); /* printf("multivar nvar: %d \n", nvars); printf("multivar proc_varname: %s \n", proc_varname); printf("multivar proc_filename: %s \n", proc_filename); */ if(proc_filename == NULL) { printf("Error malformed multivar name %s in SILO file \n", varnames[m]); return NULL; } DBfile *proc_db; // proc_db = DBOpen(proc_filename, DB_PDB, DB_READ); proc_db = DBOpen(proc_filename, DB_UNKNOWN, DB_READ); if(db == NULL) { printf("Failed to open SILO file %s\n", filename); return NULL; } if(proc_varname == NULL) { printf("Error malformed multivar name %s in SILO file \n", varnames[m]); return NULL; } DBquadvar *var = DBGetQuadvar(proc_db, proc_varname); if(var == NULL) { printf("Error: Silo failed to get quadvar %s \n", varnames[m]); return NULL; } /* now we need to get the mesh, for PMPIO compat */ DBquadmesh *mesh = DBGetQuadmesh(proc_db, var -> meshname); if(mesh == NULL) { printf("Error: Silo failed to get quadmesh %s \n", varnames[m]); return NULL; } nx = var -> dims[0]; ny = var -> dims[1]; nz = var -> dims[2]; /* Casting here is a dangerous */ localcoords[0] = (float *)mesh -> coords[0]; localcoords[1] = (float *)mesh -> coords[1]; localcoords[2] = (float *)mesh -> coords[2]; int index_origin[3]; err = DBReadVar(proc_db, "index_origin", &index_origin); if(err < 0) { printf("Failed to read meta data\n"); return NULL; } /* becuase of multi or single file compatibility we need to * grab the actual mesh from that variable. Then we need to * determine the origin from the mesh[0][0], [1][0] and [2][0] * divided by DX, DY and DZ since there are multiple origins * in a single file and this is now ambiguous. */ x = index_origin[0]; y = index_origin[1]; z = index_origin[2]; x = round( (localcoords[0][0] - (X - DX / 2.0)) / DX); y = round( (localcoords[1][0] - (Y - DY / 2.0)) / DY); z = round( (localcoords[2][0] - (Z - DZ / 2.0)) / DZ); int index = 0; double *vals = (double *)var -> vals[0]; for (k = 0; k < nz; k++) { for (j = 0; j < ny; j++) { for (i = 0; i < nx; i++) { ptr = DataboxCoeff(v, x + i, y + j, z + k); *ptr = vals[index]; index++; } } } DBFreeQuadvar(var); DBClose(proc_db); } DBFreeMultivar(multivar); } DBClose(db); if(path) { free(path); } if(current_path) { chdir(current_path); free(current_path); } free(filename); /* free(localcoords[0]); free(localcoords[1]); free(localcoords[2]); */ return v; #else #endif }