mirror of
https://github.com/paboyle/Grid.git
synced 2024-11-10 07:55:35 +00:00
Implemented perambulator read/write ... but in binary format. Will switch to Hdf5 when I have Antonins feedback
This commit is contained in:
parent
caabbcd951
commit
8865bf5d7c
@ -201,28 +201,139 @@ inline GridCartesian * MakeLowerDimGrid( GridCartesian * gridHD )
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
template<typename Scalar_, int NumIndices_>
|
template<typename Scalar_, int NumIndices_>
|
||||||
class Perambulator : public Eigen::Tensor<Scalar_, NumIndices_, Eigen::RowMajor | Eigen::DontAlign>
|
class NamedTensor : public Eigen::Tensor<Scalar_, NumIndices_, Eigen::RowMajor | Eigen::DontAlign>
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
public:
|
public:
|
||||||
|
typedef Eigen::Tensor<Scalar_, NumIndices_, Eigen::RowMajor | Eigen::DontAlign> ET;
|
||||||
std::array<std::string,NumIndices_> IndexNames;
|
std::array<std::string,NumIndices_> IndexNames;
|
||||||
public:
|
public:
|
||||||
template<typename... IndexTypes>
|
template<typename... IndexTypes>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Perambulator(std::array<std::string,NumIndices_> &IndexNames_, Eigen::Index firstDimension, IndexTypes... otherDimensions)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE NamedTensor(std::array<std::string,NumIndices_> &IndexNames_, Eigen::Index firstDimension, IndexTypes... otherDimensions)
|
||||||
: IndexNames{IndexNames_}, Eigen::Tensor<Scalar_, NumIndices_, Eigen::RowMajor | Eigen::DontAlign>(firstDimension, otherDimensions...)
|
: IndexNames{IndexNames_}, Eigen::Tensor<Scalar_, NumIndices_, Eigen::RowMajor | Eigen::DontAlign>(firstDimension, otherDimensions...)
|
||||||
{
|
{
|
||||||
// The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
|
// The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
|
||||||
EIGEN_STATIC_ASSERT(sizeof...(otherDimensions) + 1 == NumIndices_, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
EIGEN_STATIC_ASSERT(sizeof...(otherDimensions) + 1 == NumIndices_, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void WriteTemporary(const std::string &FileName){}
|
|
||||||
|
|
||||||
// Share data for timeslices we calculated with other nodes
|
// Share data for timeslices we calculated with other nodes
|
||||||
inline void SliceShare( GridCartesian * gridLowDim, GridCartesian * gridHighDim ) {
|
inline void SliceShare( GridCartesian * gridLowDim, GridCartesian * gridHighDim ) {
|
||||||
Grid::SliceShare( gridLowDim, gridHighDim, this->data(), (int) (this->size() * sizeof(Scalar_)));
|
Grid::SliceShare( gridLowDim, gridHighDim, this->data(), (int) (this->size() * sizeof(Scalar_)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// load and save - not virtual - probably all changes
|
||||||
|
inline void load(const std::string filename);
|
||||||
|
inline void save(const std::string filename) const;
|
||||||
|
inline void ReadTemporary(const std::string filename);
|
||||||
|
inline void WriteTemporary(const std::string filename) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
Save NamedTensor binary format
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
template<typename Scalar_, int NumIndices_>
|
||||||
|
void NamedTensor<Scalar_, NumIndices_>::WriteTemporary(const std::string filename) const {
|
||||||
|
std::cout << GridLogMessage << "Writing NamedTensor to \"" << filename << "\"" << std::endl;
|
||||||
|
std::ofstream w(filename, std::ios::binary);
|
||||||
|
// total number of elements
|
||||||
|
uint32_t ul = htonl( static_cast<uint32_t>( this->size() ) );
|
||||||
|
w.write(reinterpret_cast<const char *>(&ul), sizeof(ul));
|
||||||
|
// number of dimensions
|
||||||
|
uint16_t us = htons( static_cast<uint16_t>( this->NumIndices ) );
|
||||||
|
w.write(reinterpret_cast<const char *>(&us), sizeof(us));
|
||||||
|
// dimensions together with names
|
||||||
|
int d = 0;
|
||||||
|
for( auto dim : this->dimensions() ) {
|
||||||
|
// size of this dimension
|
||||||
|
us = htons( static_cast<uint16_t>( dim ) );
|
||||||
|
w.write(reinterpret_cast<const char *>(&us), sizeof(us));
|
||||||
|
// length of this dimension name
|
||||||
|
us = htons( static_cast<uint16_t>( IndexNames[d].size() ) );
|
||||||
|
w.write(reinterpret_cast<const char *>(&us), sizeof(us));
|
||||||
|
// dimension name
|
||||||
|
w.write(IndexNames[d].c_str(), IndexNames[d].size());
|
||||||
|
d++;
|
||||||
|
}
|
||||||
|
// Actual data
|
||||||
|
w.write(reinterpret_cast<const char *>(this->data()),(int) (this->size() * sizeof(Scalar_)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
Load NamedTensor binary format
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
template<typename Scalar_, int NumIndices_>
|
||||||
|
void NamedTensor<Scalar_, NumIndices_>::ReadTemporary(const std::string filename) {
|
||||||
|
std::cout << GridLogMessage << "Reading NamedTensor from \"" << filename << "\"" << std::endl;
|
||||||
|
std::ifstream r(filename, std::ios::binary);
|
||||||
|
// total number of elements
|
||||||
|
uint32_t ul;
|
||||||
|
r.read(reinterpret_cast<char *>(&ul), sizeof(ul));
|
||||||
|
assert( this->size() == ntohl( ul ) && "Error: total number of elements" );
|
||||||
|
// number of dimensions
|
||||||
|
uint16_t us;
|
||||||
|
r.read(reinterpret_cast<char *>(&us), sizeof(us));
|
||||||
|
assert( this->NumIndices == ntohs( us ) && "Error: number of dimensions" );
|
||||||
|
// dimensions together with names
|
||||||
|
int d = 0;
|
||||||
|
for( auto dim : this->dimensions() ) {
|
||||||
|
// size of dimension
|
||||||
|
r.read(reinterpret_cast<char *>(&us), sizeof(us));
|
||||||
|
assert( dim == ntohs( us ) && "size of dimension" );
|
||||||
|
// length of dimension name
|
||||||
|
r.read(reinterpret_cast<char *>(&us), sizeof(us));
|
||||||
|
size_t l = ntohs( us );
|
||||||
|
assert( l == IndexNames[d].size() && "length of dimension name" );
|
||||||
|
// dimension name
|
||||||
|
std::string s( l, '?' );
|
||||||
|
r.read(&s[0], l);
|
||||||
|
assert( s == IndexNames[d] && "dimension name" );
|
||||||
|
d++;
|
||||||
|
}
|
||||||
|
// Actual data
|
||||||
|
r.read(reinterpret_cast<char *>(this->data()),(int) (this->size() * sizeof(Scalar_)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
Save NamedTensor Hdf5 format
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
template<typename Scalar_, int NumIndices_>
|
||||||
|
void NamedTensor<Scalar_, NumIndices_>::save(const std::string filename) const {
|
||||||
|
std::cout << GridLogMessage << "Writing NamedTensor to \"" << filename << "\"" << std::endl;
|
||||||
|
#ifndef HAVE_HDF5
|
||||||
|
std::cout << GridErrorMessage << "Error: I/O for NamedTensor requires HDF5" << std::endl;
|
||||||
|
#else
|
||||||
|
Hdf5Writer w(filename);
|
||||||
|
//w << this->NumIndices << this->dimensions() << this->IndexNames;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
Load NamedTensor Hdf5 format
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
template<typename Scalar_, int NumIndices_>
|
||||||
|
void NamedTensor<Scalar_, NumIndices_>::load(const std::string filename) {
|
||||||
|
std::cout << GridLogMessage << "Reading NamedTensor from \"" << filename << "\"" << std::endl;
|
||||||
|
#ifndef HAVE_HDF5
|
||||||
|
std::cout << GridErrorMessage << "Error: I/O for NamedTensor requires HDF5" << std::endl;
|
||||||
|
#else
|
||||||
|
Hdf5Reader r(filename);
|
||||||
|
typename ET::Dimensions d;
|
||||||
|
std::array<std::string,NumIndices_> n;
|
||||||
|
//r >> this->NumIndices >> d >> n;
|
||||||
|
//this->IndexNames = n;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
Perambulator object
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
template<typename Scalar_, int NumIndices_>
|
||||||
|
using Perambulator = NamedTensor<Scalar_, NumIndices_>;
|
||||||
|
|
||||||
/*************************************************************************************
|
/*************************************************************************************
|
||||||
|
|
||||||
Rotate eigenvectors into our phase convention
|
Rotate eigenvectors into our phase convention
|
||||||
|
@ -252,16 +252,16 @@ bool bNumber( int &ri, const char * & pstr, bool bGobbleWhiteSpace = true )
|
|||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
typedef Eigen::Tensor<Complex,3,Eigen::RowMajor | Eigen::DontAlign> MyTensor;
|
typedef Grid::Hadrons::MDistil::NamedTensor<Complex,3> MyTensor;
|
||||||
|
|
||||||
void DebugShowTensor(MyTensor &x)
|
void DebugShowTensor(MyTensor &x, const char * n)
|
||||||
{
|
{
|
||||||
const MyTensor::Index s{x.size()};
|
const MyTensor::Index s{x.size()};
|
||||||
std::cout << "x.size() = " << s << std::endl;
|
std::cout << n << ".size() = " << s << std::endl;
|
||||||
std::cout << "x.NumDimensions = " << x.NumDimensions << " (TensorBase)" << std::endl;
|
std::cout << n << ".NumDimensions = " << x.NumDimensions << " (TensorBase)" << std::endl;
|
||||||
std::cout << "x.NumIndices = " << x.NumIndices << std::endl;
|
std::cout << n << ".NumIndices = " << x.NumIndices << std::endl;
|
||||||
const MyTensor::Dimensions & d{x.dimensions()};
|
const MyTensor::Dimensions & d{x.dimensions()};
|
||||||
std::cout << "d.size() = " << d.size() << std::endl;
|
std::cout << n << ".dimensions().size() = " << d.size() << std::endl;
|
||||||
std::cout << "Dimensions are ";
|
std::cout << "Dimensions are ";
|
||||||
for(auto i : d ) std::cout << "[" << i << "]";
|
for(auto i : d ) std::cout << "[" << i << "]";
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
@ -287,24 +287,30 @@ void DebugShowTensor(MyTensor &x)
|
|||||||
Complex * p = x.data();
|
Complex * p = x.data();
|
||||||
for( auto i = 0 ; i < s ; i++ ) {
|
for( auto i = 0 ; i < s ; i++ ) {
|
||||||
if( i ) std::cout << ", ";
|
if( i ) std::cout << ", ";
|
||||||
std::cout << "x.data()[" << i << "]=" << * p++;
|
std::cout << n << ".data()[" << i << "]=" << * p++;
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DebugEigenTest()
|
bool DebugEigenTest()
|
||||||
{
|
{
|
||||||
MyTensor x(2,3,4);
|
const char pszTestFileName[] = "test_tensor.bin";
|
||||||
DebugShowTensor(x);
|
|
||||||
// Test initialisation of an array of strings
|
|
||||||
std::array<std::string,3> as={"Alpha", "Beta", "Gamma"};
|
std::array<std::string,3> as={"Alpha", "Beta", "Gamma"};
|
||||||
|
MyTensor x(as, 2,3,4);
|
||||||
|
DebugShowTensor(x, "x");
|
||||||
|
x.WriteTemporary(pszTestFileName);
|
||||||
|
// Test initialisation of an array of strings
|
||||||
for( auto a : as )
|
for( auto a : as )
|
||||||
std::cout << a << std::endl;
|
std::cout << a << std::endl;
|
||||||
Grid::Hadrons::MDistil::Perambulator<Complex,3> p{as,2,7,2};
|
Grid::Hadrons::MDistil::Perambulator<Complex,3> p{as,2,7,2};
|
||||||
DebugShowTensor(p);
|
DebugShowTensor(p, "p");
|
||||||
std::cout << "p.IndexNames follow" << std::endl;
|
std::cout << "p.IndexNames follow" << std::endl;
|
||||||
for( auto a : p.IndexNames )
|
for( auto a : p.IndexNames )
|
||||||
std::cout << a << std::endl;
|
std::cout << a << std::endl;
|
||||||
|
// Now see whether we can read a tensor back
|
||||||
|
MyTensor y(as, 2,3,4);
|
||||||
|
y.ReadTemporary(pszTestFileName);
|
||||||
|
DebugShowTensor(y, "y");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user