mirror of
https://github.com/paboyle/Grid.git
synced 2024-11-10 07:55:35 +00:00
Added Xml IO (has one deficiency: the format for multi-dimensional data is flat)
This commit is contained in:
parent
31e40c26fa
commit
9288019789
@ -172,7 +172,7 @@ namespace Grid {
|
||||
template <typename ETensor, typename Lambda>
|
||||
typename std::enable_if<EigenIO::is_tensor_of_scalar<ETensor>::value, void>::type
|
||||
for_all_do_lambda( Lambda lambda, typename ETensor::Scalar &scalar, typename ETensor::Index &Seq,
|
||||
std::array<std::size_t, ETensor::NumIndices + EigenIO::Traits<typename ETensor::Scalar>::rank_non_trivial> &MyIndex)
|
||||
std::array<std::size_t, ETensor::NumIndices + EigenIO::Traits<typename ETensor::Scalar>::rank> &MyIndex)
|
||||
{
|
||||
lambda( scalar, Seq++, MyIndex );
|
||||
}
|
||||
@ -180,8 +180,8 @@ namespace Grid {
|
||||
// for_all helper function to call the lambda
|
||||
template <typename ETensor, typename Lambda>
|
||||
typename std::enable_if<EigenIO::is_tensor_of_container<ETensor>::value, void>::type
|
||||
for_all_do_lambda( Lambda lambda, typename ETensor::Scalar &scalar, typename ETensor::Index Seq,
|
||||
std::array<std::size_t, ETensor::NumIndices + EigenIO::Traits<typename ETensor::Scalar>::rank_non_trivial> &MyIndex)
|
||||
for_all_do_lambda( Lambda lambda, typename ETensor::Scalar &scalar, typename ETensor::Index &Seq,
|
||||
std::array<std::size_t, ETensor::NumIndices + EigenIO::Traits<typename ETensor::Scalar>::rank> &MyIndex)
|
||||
{
|
||||
using Scalar = typename ETensor::Scalar; // This could be a Container - we'll check later
|
||||
const auto InnerRank = EigenIO::Traits<Scalar>::rank_non_trivial;
|
||||
@ -190,7 +190,7 @@ namespace Grid {
|
||||
lambda(Source, Seq++, MyIndex );
|
||||
// Now increment SubIndex
|
||||
for( auto i = InnerRank - 1; i != -1 && ++MyIndex[rank + i] == EigenIO::Traits<Scalar>::DimensionNT(i); i-- )
|
||||
MyIndex[i] = 0;
|
||||
MyIndex[rank + i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,7 +206,7 @@ namespace Grid {
|
||||
assert( NumScalars > 0 );
|
||||
using Index = typename ETensor::Index;
|
||||
Index ScalarElementCount{1};
|
||||
const auto InnerRank = EigenIO::Traits<Scalar>::rank_non_trivial;
|
||||
const auto InnerRank = EigenIO::Traits<Scalar>::rank;
|
||||
const auto rank{ETensor::NumIndices};
|
||||
std::array<std::size_t, rank + InnerRank> Dims;
|
||||
for(auto i = 0; i < rank; i++ ) {
|
||||
@ -218,11 +218,11 @@ namespace Grid {
|
||||
}
|
||||
// Check that the number of containers is correct ... and we didn't lose anything in conversions
|
||||
assert( NumScalars == ScalarElementCount );
|
||||
// If the Scalar is actually a container, add the inner Scalar's non-trivial dimensions
|
||||
// If the Scalar is actually a container, add the inner Scalar's dimensions
|
||||
size_t InnerScalarCount{1};
|
||||
for(auto i = 0; i < InnerRank; i++ ) {
|
||||
auto dim = EigenIO::Traits<Scalar>::DimensionNT(i);
|
||||
assert( dim > 1 );
|
||||
auto dim = EigenIO::Traits<Scalar>::Dimension(i);
|
||||
assert( dim > 0 );
|
||||
Dims[rank + i] = static_cast<std::size_t>(dim);
|
||||
assert( Dims[rank + i] == dim ); // check we didn't lose anything in the conversion
|
||||
InnerScalarCount *= dim;
|
||||
@ -242,11 +242,12 @@ namespace Grid {
|
||||
} else {
|
||||
for( auto i = 0; i < rank && ++MyIndex[i] == Dims[i]; i++ )
|
||||
MyIndex[i] = 0;
|
||||
Seq = 0;
|
||||
size_t NewSeq = 0;
|
||||
for( auto i = 0; i < rank + InnerRank ; i++ ) {
|
||||
Seq *= Dims[i];
|
||||
Seq += MyIndex[i];
|
||||
NewSeq *= Dims[i];
|
||||
NewSeq += MyIndex[i];
|
||||
}
|
||||
Seq = static_cast<Index>( NewSeq );
|
||||
}
|
||||
pScalar++;
|
||||
}
|
||||
@ -271,7 +272,7 @@ namespace Grid {
|
||||
{
|
||||
using Traits = EigenIO::Traits<typename ETensor::Scalar>;
|
||||
using scalar_type = typename Traits::scalar_type;
|
||||
for_all( ET, [&](scalar_type &c, typename ETensor::Index n, const std::array<size_t, ETensor::NumIndices + Traits::rank_non_trivial> &Dims ) {
|
||||
for_all( ET, [&](scalar_type &c, typename ETensor::Index n, const std::array<size_t, ETensor::NumIndices + Traits::rank> &Dims ) {
|
||||
c = Inc * static_cast<typename RealType<scalar_type>::type>(n);
|
||||
} );
|
||||
}
|
||||
@ -291,7 +292,7 @@ namespace Grid {
|
||||
std::cout << pName;
|
||||
for( auto i = 0 ; i < rank; i++ ) std::cout << "[" << dims[i] << "]";
|
||||
std::cout << " in memory order:" << std::endl;
|
||||
for_all( t, [&](typename Traits::scalar_type &c, typename T::Index index, const std::array<size_t, T::NumIndices + Traits::rank_non_trivial> &Dims ){
|
||||
for_all( t, [&](typename Traits::scalar_type &c, typename T::Index index, const std::array<size_t, T::NumIndices + Traits::rank> &Dims ){
|
||||
std::cout << " ";
|
||||
for( auto dim : Dims )
|
||||
std::cout << "[" << dim << "]";
|
||||
|
@ -57,6 +57,8 @@ namespace Grid
|
||||
void writeDefault(const std::string &s, const U &x);
|
||||
template <typename U>
|
||||
void writeDefault(const std::string &s, const std::vector<U> &x);
|
||||
template <typename U>
|
||||
void writeMultiDim(const std::string &s, const std::vector<size_t> & Dimensions, const U * pDataRowMajor, size_t NumElements);
|
||||
std::string docString(void);
|
||||
std::string string(void);
|
||||
private:
|
||||
@ -79,6 +81,8 @@ namespace Grid
|
||||
void readDefault(const std::string &s, U &output);
|
||||
template <typename U>
|
||||
void readDefault(const std::string &s, std::vector<U> &output);
|
||||
template <typename U>
|
||||
void readMultiDim(const std::string &s, std::vector<U> &buf, std::vector<size_t> &dim);
|
||||
void readCurrentSubtree(std::string &s);
|
||||
private:
|
||||
void checkParse(const pugi::xml_parse_result &result, const std::string name);
|
||||
@ -120,15 +124,28 @@ namespace Grid
|
||||
|
||||
template <typename U>
|
||||
void XmlWriter::writeDefault(const std::string &s, const std::vector<U> &x)
|
||||
{
|
||||
std::vector<size_t> dims(1);
|
||||
dims[0] = x.size();
|
||||
writeMultiDim(s, dims, &x[0], dims[0]);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void XmlWriter::writeMultiDim(const std::string &s, const std::vector<size_t> & Dimensions, const U * pDataRowMajor, size_t NumElements)
|
||||
{
|
||||
push(s);
|
||||
for (auto &x_i: x)
|
||||
if( Dimensions.size() > 1 )
|
||||
{
|
||||
write("elem", x_i);
|
||||
for( auto d : Dimensions )
|
||||
write("dim", d);
|
||||
}
|
||||
while (NumElements--)
|
||||
{
|
||||
write("elem", *pDataRowMajor++);
|
||||
}
|
||||
pop();
|
||||
}
|
||||
|
||||
|
||||
// Reader template implementation ////////////////////////////////////////////
|
||||
template <typename U>
|
||||
void XmlReader::readDefault(const std::string &s, U &output)
|
||||
@ -145,25 +162,39 @@ namespace Grid
|
||||
template <typename U>
|
||||
void XmlReader::readDefault(const std::string &s, std::vector<U> &output)
|
||||
{
|
||||
std::string buf;
|
||||
unsigned int i = 0;
|
||||
|
||||
std::vector<size_t> dims;
|
||||
readMultiDim(s, output, dims);
|
||||
assert( dims.size() == 1 && dims[0] == output.size() && "XmlIO: Expected 1D vector" );
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void XmlReader::readMultiDim(const std::string &s, std::vector<U> &buf, std::vector<size_t> &dim)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
unsigned int Rank = 0;
|
||||
if (!push(s))
|
||||
{
|
||||
std::cout << GridLogWarning << "XML: cannot open node '" << s << "'";
|
||||
std::cout << std::endl;
|
||||
|
||||
return;
|
||||
} else {
|
||||
while (node_.child("dim"))
|
||||
{
|
||||
dim.resize(Rank + 1);
|
||||
read("dim", dim[Rank]);
|
||||
node_.child("dim").set_name("dim-done");
|
||||
Rank++;
|
||||
}
|
||||
while (node_.child("elem"))
|
||||
{
|
||||
buf.resize(i + 1);
|
||||
read("elem", buf[i]);
|
||||
node_.child("elem").set_name("elem-done");
|
||||
i++;
|
||||
}
|
||||
pop();
|
||||
if( Rank == 0 )
|
||||
dim.push_back(i);
|
||||
}
|
||||
while (node_.child("elem"))
|
||||
{
|
||||
output.resize(i + 1);
|
||||
read("elem", output[i]);
|
||||
node_.child("elem").set_name("elem-done");
|
||||
i++;
|
||||
}
|
||||
pop();
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
@ -86,7 +86,7 @@ void ioTest(const std::string &filename, const O &object, const std::string &nam
|
||||
// writer needs to be destroyed so that writing physically happens
|
||||
{
|
||||
W writer(filename);
|
||||
|
||||
writer.setPrecision(std::numeric_limits<double>::digits10 + 1);
|
||||
write(writer, tag , object);
|
||||
}
|
||||
|
||||
@ -141,14 +141,14 @@ public:
|
||||
, tensorRank3(7,3,2)
|
||||
, atensor_9_4_2(3)
|
||||
{
|
||||
Grid_complex<double> Flag{1,-3.1415927};
|
||||
//Grid_complex<double> Flag{1,-3.1415927}; // Gives errors on readback for text types
|
||||
Grid_complex<double> Flag{1,-1};
|
||||
SequentialInit(Perambulator, Flag);
|
||||
SequentialInit(Perambulator2, Flag);
|
||||
SequentialInit(tensorRank5UShort);
|
||||
SequentialInit(tensorRank3, Flag);
|
||||
SequentialInit(tensor_9_4_2, Flag);
|
||||
for( auto &t : atensor_9_4_2 )
|
||||
SequentialInit(t, Flag);
|
||||
for( auto &t : atensor_9_4_2 ) SequentialInit(t, Flag);
|
||||
SequentialInit( MyLSCTensor );
|
||||
}
|
||||
};
|
||||
@ -295,6 +295,8 @@ int main(int argc,char **argv)
|
||||
std::cout << "\n==== detailed Hdf5 tensor tests (Grid::EigenIO)" << std::endl;
|
||||
EigenHdf5IOTest<Hdf5Writer, Hdf5Reader>(".h5");
|
||||
#endif
|
||||
std::cout << "\n==== detailed xml tensor tests (Grid::EigenIO)" << std::endl;
|
||||
EigenHdf5IOTest<XmlWriter, XmlReader>(".xml");
|
||||
std::cout << "\n==== detailed binary tensor tests (Grid::EigenIO)" << std::endl;
|
||||
EigenHdf5IOTest<BinaryWriter, BinaryReader>(".bin");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user