Commit 72990c0d authored by Siqi Ling's avatar Siqi Ling
Browse files

arh3.0 finished with test_suit test_arh_3.0

parent dfd9bc02
......@@ -842,7 +842,7 @@ namespace AMDiS {
std::cout << "(" << elCoords[i][0] << ", " << elCoords[i][1]<< ", " << elCoords[i][2] << ") ";
std::cout << "another is: ";
std::cout << "(" << coords[el->getIndex()][i][0] << ", " << coords[el->getIndex()][i][1]
<< ". " << coords[el->getIndex()][i][2] << ")\n";
<< ", " << coords[el->getIndex()][i][2] << ")\n";
break;
default:
ERROR_EXIT("What is this?\n");
......
......@@ -145,7 +145,7 @@ namespace AMDiS { namespace io {
uint32_t nValueVectors = 0;
detail::firstRead(file);
detail::firstRead(file, "sarh", MAJOR, MINOR);
long pos = file.tellg();
file.seekg(pos + 16);
file.read(reinterpret_cast<char*>(&nValueVectors), 4);
......@@ -176,7 +176,7 @@ namespace AMDiS { namespace io {
("Cannot open file %s\n", filename.c_str());
uint32_t headerLen = 0;
detail::firstRead(file);
detail::firstRead(file, "sarh", MAJOR, MINOR);
file.read(reinterpret_cast<char*>(&headerLen), 4);
file.close();
......@@ -212,7 +212,7 @@ namespace AMDiS { namespace io {
file.read(reinterpret_cast<char*>(&minor), 1);
file.close();
return (typeId == "arh2" && major == MAJOR && minor <= MINOR) ? true : false;
return (typeId == "sarh" && major == MAJOR && minor <= MINOR) ? true : false;
}
void readMeta(string filename,
......
......@@ -23,8 +23,8 @@ namespace AMDiS { namespace io {
**/
namespace Arh2Reader
{
const uint8_t MAJOR = 2;
const uint8_t MINOR = 1;
const uint8_t MAJOR = 3;
const uint8_t MINOR = 0;
/**
* \brief Read MeshStructure, refine the mesh and read dof values to sysVec by order.
......
......@@ -14,9 +14,7 @@ namespace AMDiS { namespace io {
* ARH-files.
**/
namespace Arh2Writer
{
const uint8_t MAJOR = 2;
const uint8_t MINOR = 1;
{
/**
* \brief write the meshstructure and the dof values of DOFVectors in sysVec
......@@ -45,57 +43,69 @@ namespace AMDiS { namespace io {
*/
inline void writeFile(SystemVector *sysVec,
std::string filename,
bool writeParallel = true)
bool writeParallel = true,
Cpsformat cps = NONE,
std::string dataformat = "SF64")
{
std::vector<DOFVector<double>*> vecs;
for (int i = 0; i < sysVec->getSize(); i++)
vecs.push_back(sysVec->getDOFVector(i));
detail::write(filename, NULL, vecs, writeParallel);
detail::write(filename, NULL, vecs, writeParallel, cps, dataformat);
}
inline void writeFile(SystemVector &sysVec,
std::string filename,
bool writeParallel = true)
bool writeParallel = true,
Cpsformat cps = NONE,
std::string dataformat = "SF64")
{
writeFile(&sysVec, filename, writeParallel);
writeFile(&sysVec, filename, writeParallel, cps, dataformat);
}
/// write the meshstructure and the dof values of DOFVectors in vec0
/// the behavior is equal to writeFile(SystemVector* sysVec, string filename).
inline void writeFile(DOFVector<double>* vec0,
std::string filename,
bool writeParallel = true)
bool writeParallel = true,
Cpsformat cps = NONE,
std::string dataformat = "SF64")
{
std::vector<DOFVector<double>*> vecs;
vecs.push_back(vec0);
detail::write(filename, NULL, vecs, writeParallel);
detail::write(filename, NULL, vecs, writeParallel, cps, dataformat);
}
/// write the meshstructure and the dof values of DOFVectors in vec0
/// the behavior is equal to writeFile(SystemVector* sysVec, string filename).
inline void writeFile(DOFVector<double>& vec0,
std::string filename,
bool writeParallel = true)
bool writeParallel = true,
Cpsformat cps = NONE,
std::string dataformat = "SF64")
{
writeFile(&vec0, filename, writeParallel);
writeFile(&vec0, filename, writeParallel, cps, dataformat);
}
/// write the meshstructure and the dof values of DOFVectors in vecs
/// the behavior is equal to writeFile(SystemVector* sysVec, string filename).
inline void writeFile(std::vector<DOFVector<double>*> vecs,
std::string filename,
bool writeParallel = true)
bool writeParallel = true,
Cpsformat cps = NONE,
std::string dataformat = "SF64")
{
detail::write(filename, NULL, vecs, writeParallel);
detail::write(filename, NULL, vecs, writeParallel, cps, dataformat);
}
/// write the meshstructure of the mesh to arh file.
inline void writeFile(Mesh *mesh,
std::string filename,
bool writeParallel = true)
bool writeParallel = true,
Cpsformat cps = NONE,
std::string dataformat = "SF64")
{
std::vector<DOFVector<double>*> vecs;
detail::write(filename, mesh, vecs, writeParallel);
detail::write(filename, mesh, vecs, writeParallel, cps, dataformat);
}
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
......
......@@ -6,12 +6,14 @@
#include "SystemVector.h"
#include "Debug.h"
#include "../Arh2Reader.h"
#include "Arh2Writer.h"
#include <boost/filesystem.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/copy.hpp>
#ifdef HAVE_COMPRESSION
#include <boost/iostreams/filter/zlib.hpp>
#include <boost/iostreams/filter/bzip2.hpp>
#endif
namespace AMDiS { namespace io {
......@@ -23,27 +25,27 @@ namespace AMDiS { namespace io {
namespace detail
{
uint8_t firstRead(ifstream& file)
void firstRead(ifstream& file, string id, uint8_t major, uint8_t minor)
{
FUNCNAME("Arh2Reader::detail::firstRead");
uint8_t major_ = 0;
uint8_t minor_ = 0;
string typeId(4, ' ');
uint8_t major = 0, minor = 0;
file.read(const_cast<char*>(typeId.data()), 4);
TEST_EXIT(typeId == "arh2")
TEST_EXIT(typeId == id)
("Cannot read Arh2 format: this file is not \"arh2\" format.\n");
file.read(reinterpret_cast<char*>(&major), 1);
TEST_EXIT(major == AMDiS::io::Arh2Reader::MAJOR)
file.read(reinterpret_cast<char*>(&major_), 1);
TEST_EXIT(major == major_)
("Cannot read Arh2 format: Arh2Reader major version is %i, the file major version is %i. \n",
AMDiS::io::Arh2Reader::MAJOR, major);
major, major_);
file.read(reinterpret_cast<char*>(&minor), 1);
TEST_EXIT(minor <= AMDiS::io::Arh2Reader::MINOR)
file.read(reinterpret_cast<char*>(&minor_), 1);
TEST_EXIT(minor <= minor_)
("Cannot read Arh2 format: Arh2Reader minor version is %i is smaller than the file minor version %i.\n",
AMDiS::io::Arh2Reader::MINOR, minor);
return minor;
minor, minor_);
}
void setDofValues(int macroElIndex, Mesh *mesh,
......@@ -192,6 +194,8 @@ namespace AMDiS { namespace io {
bool byName)
{
FUNCNAME("Arh2Reader::detail::read()");
using namespace ::AMDiS::io::Arh2Writer;
// Get set of all macro elements in mesh.
std::set<int> macroInMesh;
......@@ -217,20 +221,17 @@ namespace AMDiS { namespace io {
file.open(filename.c_str(), ios::in | ios::binary);
TEST_EXIT(file.is_open())
("Cannot open file %s\n", filename.c_str());
file.seekg (0, file.end);
int fileSize = file.tellg();
file.seekg (0, file.beg);
string cps = "null";
Cpsformat cps = NONE;
uint32_t headerLen = 0;
uint32_t nMacroElements = 0;
uint32_t nValueVectors = 0;
uint32_t nFeSpaces = 0;
uint32_t dim = 0, dow = 0;
int cpsflag = 0;
// Read fixed header
uint8_t minor = firstRead(file);
firstRead(file, "sarh", MAJOR, MINOR);
file.read(reinterpret_cast<char*>(&headerLen), 4);
file.read(reinterpret_cast<char*>(&dow), 4);
......@@ -238,15 +239,16 @@ namespace AMDiS { namespace io {
file.read(reinterpret_cast<char*>(&nFeSpaces), 4);
file.read(reinterpret_cast<char*>(&nValueVectors), 4);
file.read(reinterpret_cast<char*>(&nMacroElements), 4);
if(minor >= 1)
file.read(const_cast<char*>(cps.data()), 4);
file.read(reinterpret_cast<char*>(&cpsflag), 4);
cps = static_cast<Cpsformat>(cpsflag);
#ifdef HAVE_COMPRESSION
TEST_EXIT(cps == "null" || cps == "zlib")
("Cannot read Arh2 file. Currently only support zlib compression.\n");
TEST_EXIT(cps == ZLIB ||
cps == BZIP2 ||
cps == NONE)
("Cannot read Arh2 file. Currently only support zlib and bzip2 compression.\n");
#else
TEST_EXIT(cps == "null")
TEST_EXIT(cps == NONE)
("HAVE_COMPRESSION OFF. Cannot read compressed Arh2 file.\n");
#endif
......@@ -258,25 +260,39 @@ namespace AMDiS { namespace io {
("File %s has %d vector(s), which is less than the number of DOFVectors %i in vecs!\n",
filename.c_str(), nValueVectors, vecs.size());
vector<int> vecsNameLen(0);
vector<string> vecsName(0);
vector<int> vecsFeSpaceNum(0);
vector<int> vecsNameLen;
vector<string> vecsName;
vector<int> filesNameLen;
vector<string> filesName;
vector<int> vecsFeSpaceNum;
vector<string> dataformat;
vector<int> macroElIndex(nMacroElements);
vector<int> macroElSize(nMacroElements);
vector<pair<int,int> > macroElSize(nMacroElements); // pos, uncompressed size
int fileSize = 0;
vector<vector<int> > feSpaceDOFs(0);
vector<vector<int> > feSpaceDOFs;
vector<string> AFEDfileName(nFeSpaces);
vector<int> perDOFs(4, 0);
vector<vector<int> > sortedFeSpaces(nFeSpaces);
// Read macro table
for(unsigned int i = 0; i < nMacroElements; i++)
for(size_t i = 0; i < nMacroElements; i++)
{
file.read(reinterpret_cast<char*>(&macroElIndex[i]), 4);
file.read(reinterpret_cast<char*>(&macroElSize[i]), 4);
file.read(reinterpret_cast<char*>(&macroElSize[i].first), 4);
file.read(reinterpret_cast<char*>(&macroElSize[i].second), 4);
}
file.seekg(4, ios_base::cur);
file.read(reinterpret_cast<char*>(&fileSize), 4);
file.seekg(4, ios_base::cur);
// Read feSpace table
for(unsigned int i = 0; i < nFeSpaces; i++)
for(size_t i = 0; i < nFeSpaces; i++)
{
uint32_t tmpInt = 0;
file.read(reinterpret_cast<char*>(&tmpInt), 4);
file.read(const_cast<char*>(AFEDfileName[i].data()), tmpInt);
for(int j = 0; j < 4; j++)
{
file.read(reinterpret_cast<char*>(&perDOFs[j]), 4);
......@@ -284,7 +300,7 @@ namespace AMDiS { namespace io {
feSpaceDOFs.push_back(perDOFs);
}
// Read value table
for(unsigned int i = 0; i < nValueVectors; i++)
for(size_t i = 0; i < nValueVectors; i++)
{
string tmpString("");
uint32_t tmpInt = 0;
......@@ -296,6 +312,9 @@ namespace AMDiS { namespace io {
file.read(reinterpret_cast<char*>(&tmpInt), 4);
sortedFeSpaces[tmpInt].push_back(i);
vecsFeSpaceNum.push_back(tmpInt);
tmpString.resize(4, ' ');
file.read(const_cast<char*>(tmpString.data()), 4);
dataformat.push_back(tmpString);
}
// Adjust and check vecs
if(byName)
......@@ -311,27 +330,28 @@ namespace AMDiS { namespace io {
if(!tmpVecs[k])
break;
unsigned int i;
size_t i;
TEST_EXIT(tmpVecs[k]->getFeSpace()->getAdmin())
("Vecs number %i has no DOFAdmin. Should not happen.\n", k);
DimVec<int>* nDOF = tmpVecs[k]->getFeSpace()->getBasisFcts()->getNumberOfDofs();
for(i = 0; i < nValueVectors; i++)
{
if(tmpVecs[k]->getName() != vecsName[i])
{
for(i = 0; i < nValueVectors; i++) {
if(tmpVecs[k]->getName() != vecsName[i])
continue;
}
int j;
for(j = 0; j < nDOF->getSize(); j++)
{
if((*nDOF)[j] != feSpaceDOFs[vecsFeSpaceNum[i]][j])
{
break;
bool matchdof = true;
if ((*nDOF)[0] != feSpaceDOFs[vecsFeSpaceNum[i]][3])
matchdof = false;
else {
for(size_t j = 1; j < nDOF->getSize(); j++) {
if((*nDOF)[j] != feSpaceDOFs[vecsFeSpaceNum[i]][j-1]){
matchdof = false;
break;
}
}
}
if(j == nDOF->getSize())
{
if(matchdof) {
vecs[i] = tmpVecs[k];
break;
}
......@@ -343,43 +363,51 @@ namespace AMDiS { namespace io {
}
else
{
for(size_t i = 0; i < vecs.size(); i++)
{
if(vecs[i])
{
for(size_t i = 0; i < vecs.size(); i++) {
if(vecs[i]) {
TEST_EXIT(vecs[i]->getFeSpace()->getAdmin())
("Vecs number %i has no DOFAdmin. Should not happen.\n", i);
DimVec<int>* nDOF = vecs[i]->getFeSpace()->getBasisFcts()->getNumberOfDofs();
for(int j = 0; j < nDOF->getSize(); j++)
{
TEST_EXIT((*nDOF)[j] == feSpaceDOFs[vecsFeSpaceNum[i]][j])
TEST_EXIT((*nDOF)[0] == feSpaceDOFs[vecsFeSpaceNum[i]][3])
("The fespace of vec number %i is not equal to the correspond fespace.\n", i+1);
for(size_t j = 1; j < nDOF->getSize(); j++)
TEST_EXIT((*nDOF)[j] == feSpaceDOFs[vecsFeSpaceNum[i]][j-1])
("The fespace of vec number %i is not equal to the correspond fespace.\n", i+1);
}
}
}
}
// Read data: meshstructure and dof values
for (unsigned int i = 0; i < nMacroElements; i++) {
for (size_t i = 0; i < nMacroElements; i++) {
stringstream dataStream(ios::out | ios::in | ios::binary);
int size = 0;
if(minor >= 1)
size = macroElSize[i];
else
size = (i != nMacroElements - 1) ? macroElSize[i + 1] - macroElSize[i] : fileSize - macroElSize[i];
int size = (i == nMacroElements - 1) ? fileSize - macroElSize[i].first
: (macroElSize[i+1].first - macroElSize[i].first);
char* buffer = new char[size];
file.read(buffer, size);
dataStream.write(buffer, size);
delete[] buffer;
#ifdef HAVE_COMPRESSION
if(cps == "zlib") {
stringstream tmp(ios::out | ios::in);
boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
in.push(boost::iostreams::zlib_decompressor());
in.push(dataStream);
boost::iostreams::copy(in, tmp);
dataStream.str(tmp.str());
stringstream tmp(ios::out | ios::in);
boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
switch(cps)
{
case ZLIB:
in.push(boost::iostreams::zlib_decompressor());
break;
case BZIP2:
in.push(boost::iostreams::bzip2_decompressor());
break;
case NONE:
break;
default:
MSG("NOT correct compression flag.\n");
}
in.push(dataStream);
boost::iostreams::copy(in, tmp);
dataStream.str(tmp.str());
#endif
uint32_t nStructureCodes = 0;
uint32_t codeSize = 0;
......@@ -406,7 +434,7 @@ namespace AMDiS { namespace io {
for(size_t k = 0; k < sortedFeSpaces[j].size(); k++)
{
values[valuePos + k].resize(nValuesPerVector);
dataStream.read(reinterpret_cast<char*>(&(values[valuePos + k][0])), 8 * nValuesPerVector);
readValues(dataStream, dataformat[valuePos + k], values[valuePos + k]);
}
valuePos += sortedFeSpaces[j].size();
}
......@@ -419,9 +447,64 @@ namespace AMDiS { namespace io {
}
}
}
file.close();
delete refManager;
}
void readValues(stringstream& file,
string dataformat,
vector<double>& values)
{
using namespace ::AMDiS::io::Arh2Writer;
std::map<string,Valformat>::const_iterator it = dataformatMap.find(dataformat);
TEST_EXIT(it != dataformatMap.end())("Wrong data format.\n");
switch(it->second) {
case SI08:
readValues<int8_t>(file, values);
break;
case SI16:
readValues<int16_t>(file, values);
break;
case SI32:
readValues<int32_t>(file, values);
break;
case SI64:
readValues<int64_t>(file, values);
break;
case UI08:
readValues<uint8_t>(file, values);
break;
case UI16:
readValues<uint16_t>(file, values);
break;
case UI32:
readValues<uint32_t>(file, values);
break;
case UI64:
readValues<uint64_t>(file, values);
break;
case SF32:
readValues<float>(file, values);
break;
case SF64:
readValues<double>(file, values);
break;
default:
ERROR_EXIT("Wrong data format.\n");
}
}
template<typename T>
void readValues(stringstream& file, vector<double>& values)
{
int size = values.size();
T data[size];
file.read(reinterpret_cast<char*>(&data[0]), sizeof(T) * size);
for (size_t i = 0; i < size; i++)
values[i] = static_cast<double>(data[i]);
}
void readFile(string filename, Mesh *mesh,
vector<DOFVector<double>*> vecs,
......@@ -475,46 +558,55 @@ namespace AMDiS { namespace io {
ERROR_EXIT("Reading parallel ARH files in sequential computations requires to specify the number of nodes on which the ARH file was created!\n");
#endif
} else {
string parhfn = name + ".parh", filenameType = "";
int nProcs_ = 0, nMacros_ = 0, nMacros = 0;
vector<int> partition;
// check if there are no more or less files as nProcs
int n = 0;
for (; n < nProcs + 1; n++) {
string fn = name + "-p" + boost::lexical_cast<string>(n) + "-.arh";
if(!boost::filesystem::exists(fn)) break;
bool parh = boost::filesystem::exists(parhfn);
if (parh)
readParallelFile(parhfn, filenameType, partition, nProcs_, nMacros_);
else {
for (; nProcs_ < nProcs + 1; nProcs_++) {
string fn = name + "-p" + boost::lexical_cast<string>(nProcs_) + "-.arh";
if(!boost::filesystem::exists(fn)) break;
}
}
TEST_EXIT(n == nProcs)
("Number of arh files doesn't match number of processors \n");
TEST_EXIT(nProcs_ == nProcs)
("Number of arh files doesn't match number of processors: %d vs %d\n", nProcs_, nProcs);
//
// Some test should be checked. This is because of the variation of the
// number of macro elements per processor:
//
// There should be at least 10 macro Elements per processor, therefore:
// nMacroElements * 2^gr >= nProcs * 10
// => gr = log_2(nProcs * 10 / nMacroElements)
int allMacros = mesh->getNumberOfMacros();
int allMacrosFromProcFiles = 0;
if (!parh) {
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
if(MPI::COMM_WORLD.Get_rank() == 0)
#endif
for(int i = 0; i < nProcs; i++)
nMacros_ += readNumOfMacrosFromSgArh(filename, i);
}
nMacros = mesh->getNumberOfMacros();
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
int sendValue = static_cast<int>(mesh->getNumberOfMacros());
MPI::COMM_WORLD.Allreduce(&sendValue, &allMacros, 1, MPI_INT, MPI_SUM);
if(MPI::COMM_WORLD.Get_rank() == 0) {
Parallel::mpi::globalAdd(nMacros);
if(MPI::COMM_WORLD.Get_rank() == 0)
#endif
for(int i = 0; i < nProcs; i++) {
allMacrosFromProcFiles += readNumOfMacrosFromSgArh(filename, i);
TEST_EXIT(nMacros == nMacros_)
("Number of macro elements in parallel ARH files doesn't match to the current runtime. %d vs %d\n",
nMacros, nMacros_);
if (!parh) {
for (int i = 0; i < nProcs; i++) {
string procFilename = name + "-p" + lexical_cast<string>(i) + "-.arh";
read(procFilename, mesh, vecs, byName);
}
} else {
std::set<int> needFiles;
deque<MacroElement*>::iterator it = mesh->firstMacroElement();
for (;it != mesh->endOfMacroElements(); it++)
needFiles.insert(partition[(*it)->getIndex()]);
TEST_EXIT(allMacros == allMacrosFromProcFiles)
("Number of macro elements in parallel ARH files doesn't match to the current runtime.\n");
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
}
#endif
for (int i = 0; i < nProcs; i++) {
string procFilename = name + "-p" + lexical_cast<string>(i) + "-.arh";
read(procFilename, mesh, vecs, byName);
MSG("ARH file read from: %s\n", procFilename.c_str());
std::set<int>::iterator it2 = needFiles.begin();
for (;it2 != needFiles.end(); it2++) {
string procFilename = name + "-p" + lexical_cast<string>(*it2) + "-.arh";
read(procFilename, mesh, vecs, byName);
}
}
}
} else {
......@@ -526,23 +618,22 @@ namespace AMDiS { namespace io {
void readMetaFromSgArh(std::string filename, int nProc,
std::vector< std::set<std::pair<int, int> > >& data)
{