#include "VPICHeader.h" ////////////////////////////////////////////////////////////////////////////// // // Header information for every complete file where each time step has // a file for each processor which ran the original application // ////////////////////////////////////////////////////////////////////////////// VPICHeader::VPICHeader() { this->headerSize = 123; } VPICHeader::~VPICHeader() { } ////////////////////////////////////////////////////////////////////////////// // // Read the header including consistency information and size information // Return the header size in bytes if successful // ////////////////////////////////////////////////////////////////////////////// int VPICHeader::readHeader(FILE* filePtr) { // Consistency check to see if file can be read on this machine int consistent = parseBoilerPlate(filePtr); if (consistent == 0) { cerr << "Data file is not consistent on this machine" << endl; } // Version and dump type fread(&this->version, sizeof(int), 1, filePtr); fread(&this->dumpType, sizeof(int), 1, filePtr); if (this->dumpType != VPIC_FIELD && this->dumpType != VPIC_HYDRO) cerr << "Bad VPIC dump type (not field or hydro)" << endl; // Information fread(&this->dumpTime, sizeof(int), 1, filePtr); fread(this->gridSize, sizeof(int), DIMENSION, filePtr); fread(&this->deltaTime, sizeof(float), 1, filePtr); fread(this->gridStep, sizeof(float), DIMENSION, filePtr); fread(this->gridOrigin, sizeof(float), DIMENSION, filePtr); fread(&this->cvac, sizeof(float), 1, filePtr); fread(&this->epsilon, sizeof(float), 1, filePtr); fread(&this->damp, sizeof(float), 1, filePtr); fread(&this->rank, sizeof(int), 1, filePtr); fread(&this->totalRank, sizeof(int), 1, filePtr); fread(&this->spid, sizeof(int), 1, filePtr); fread(&this->spqm, sizeof(float), 1, filePtr); // Array size/dimension fread(&this->recordSize, sizeof(int), 1, filePtr); fread(&this->numberOfDimensions, sizeof(int), 1, filePtr); fread(this->ghostSize, sizeof(int), DIMENSION, filePtr); return this->headerSize; } ////////////////////////////////////////////////////////////////////////////// // // Read the first 23 bytes of the file to verify the word boundaries, // sizes of numerical types, and endianness // // 5 bytes of sizes for long, short, int, real, double (8,2,4,4,8) // 2 bytes where the hex word spells "cafe" // 4 bytes where the hex word spells "deadbeef" // 4 bytes of real with value 1.0 // 8 bytes of double with value 1.0 // // With UNIX octal dump utility do: // od -b (to see sizes) // od -h -j 5 (to see hex "words") // od -f -j 11 (to see real 1.0) // od -F -j 15 (to see double 1.0) // ////////////////////////////////////////////////////////////////////////////// int VPICHeader::parseBoilerPlate(FILE* fp) { char byteSize[5]; short int cafe; int deadbeef; float floatone; double doubleone; fread(byteSize, sizeof(char), 5, fp); if (byteSize[0] != sizeof(long long) || byteSize[1] != sizeof(short) || byteSize[2] != sizeof(int) || byteSize[3] != sizeof(float) || byteSize[4] != sizeof(double)) { cerr << "Numerical type byte sizes do not match:" << endl; cerr << "long: " << (short) byteSize[0] << " != " << sizeof(long long) << endl; cerr << "short: " << (short) byteSize[1] << " != " << sizeof(short) << endl; cerr << "int: " << (short) byteSize[2] << " != " << sizeof(int) << endl; cerr << "float: " << (short) byteSize[3] << " != " << sizeof(float) << endl; cerr << "double: " << (short) byteSize[4] << " != " << sizeof(double) << endl; return 0; } fread(&cafe, sizeof(short int), 1, fp); if (cafe != (short int) 0xcafe) { cerr << "Endianness does not match" << endl; return 0; } fread(&deadbeef, sizeof(int), 1, fp); if (deadbeef != (int) 0xdeadbeef) { cerr << "Endianness does not match" << endl; return 0; } fread(&floatone, sizeof(float), 1, fp); if (floatone != 1.0) { cerr << "Could not locate float 1.0" << endl; return 0; } fread(&doubleone, sizeof(double), 1, fp); if (doubleone != 1.0) { cerr << "Could not locate double 1.0" << endl; return 0; } return 1; } ////////////////////////////////////////////////////////////////////////////// // // Access methods // ////////////////////////////////////////////////////////////////////////////// void VPICHeader::getGridSize(int gridsize[]) { for (int dim = 0; dim < DIMENSION; dim++) gridsize[dim] = this->gridSize[dim]; } void VPICHeader::getGhostSize(int ghostsize[]) { for (int dim = 0; dim < DIMENSION; dim++) ghostsize[dim] = this->ghostSize[dim]; } void VPICHeader::getOrigin(float origin[]) { for (int dim = 0; dim < DIMENSION; dim++) origin[dim] = this->gridOrigin[dim]; } void VPICHeader::getStep(float step[]) { for (int dim = 0; dim < DIMENSION; dim++) step[dim] = this->gridStep[dim]; } ////////////////////////////////////////////////////////////////////////////// // // Print header information // ////////////////////////////////////////////////////////////////////////////// void VPICHeader::PrintSelf(ostream& os, int vpicNotUsed(indent)) { os << "Version: " << this->version << endl; if (this->dumpType == VPIC_FIELD) os << "Dump type: VPIC FIELD DATA" << endl; else os << "Dump type: VPIC HYDRO DATA" << endl; os << "step: " << this->dumpTime << endl; for (int i = 0; i < DIMENSION; i++) os << "Grid size[" << i << "]: " << this->gridSize[i] << endl; os << "Delta time: " << this->deltaTime << endl; for (int i = 0; i < DIMENSION; i++) os << "Delta grid[" << i << "]: " << this->gridStep[i] << endl; for (int i = 0; i < DIMENSION; i++) os << "Origin grid[" << i << "]: " << this->gridOrigin[i] << endl; os << "cvac: " << this->cvac << endl; os << "epsilon: " << this->epsilon << endl; os << "damp: " << this->damp << endl; os << "Rank: " << this->rank << endl; os << "Total ranks: " << this->totalRank << endl; os << "spid: " << this->spid << endl; os << "spqm: " << this->spqm << endl; os << "Record size: " << this->recordSize << endl; os << "Number of dimensions: " << this->numberOfDimensions << endl; for (int i = 0; i < DIMENSION; i++) { os << "Ghost grid size[" << i << "]: " << this->ghostSize[i] << endl; } }