31#ifndef GRID_SERIALISATION_ABSTRACT_READER_H
32#define GRID_SERIALISATION_ABSTRACT_READER_H
43 template<
typename T,
typename V =
void>
struct is_complex :
public std::false_type {};
46 std::enable_if< ::Grid::is_complex< T >::value>
::type> :
public std::true_type {};
48 std::enable_if<!::Grid::is_complex<std::complex<T>>::value>
::type> :
public std::true_type {};
51 template<
typename T,
typename V =
void>
struct is_scalar :
public std::false_type {};
52 template<
typename T>
struct is_scalar<T, typename std::enable_if<std::is_arithmetic<T>::value || is_complex<T>::value>
::type> :
public std::true_type {};
55 template<
typename T>
struct is_tensor : std::integral_constant<bool,
56 std::is_base_of<Eigen::TensorBase<T, Eigen::ReadOnlyAccessors>, T>::value> {};
60 template<
typename T>
struct is_tensor_of_scalar<T, typename std::enable_if<is_tensor<T>::value && is_scalar<typename T::Scalar>::value>
::type> :
public std::true_type {};
64 template<
typename T>
struct is_tensor_of_container<T, typename std::enable_if<is_tensor<T>::value && isGridTensor<typename T::Scalar>::value>
::type> :
public std::true_type {};
69 template<
typename T,
typename V =
void>
struct Traits {};
71 template<
typename T>
struct Traits<T, typename std::enable_if<is_tensor_of_scalar<T>::value>
::type>
77 template<
typename T>
struct Traits<T, typename std::enable_if<is_tensor_of_container<T>::value>
::type> {
82 static constexpr int Rank = BaseTraits::Rank;
83 static constexpr std::size_t
count = BaseTraits::count;
84 static constexpr int Dimension(
int dim) {
return BaseTraits::Dimension(dim); }
89 template<
typename Scalar_,
typename Dimensions_,
int Options_,
typename IndexType>
90 struct is_tensor_fixed<Eigen::TensorFixedSize<Scalar_, Dimensions_, Options_, IndexType>>
91 :
public std::true_type {};
92 template<
typename T>
struct is_tensor_fixed<Eigen::TensorMap<T>> :
public std::true_type {};
97 && !is_tensor_fixed<T>::value>
::type> :
public std::true_type {};
100 template <
typename ET>
101 inline typename std::enable_if<is_tensor<ET>::value,
const typename ET::Index>
::type
103 template <
typename ET>
104 inline typename std::enable_if<is_tensor_of_scalar<ET>::value,
const typename ET::Scalar *>
::type
106 template <
typename ET>
107 inline typename std::enable_if<is_tensor_of_scalar<ET>::value,
typename ET::Scalar *>
::type
109 template <
typename ET>
110 inline typename std::enable_if<is_tensor_of_container<ET>::value,
const typename Traits<ET>::scalar_type *>
::type
112 template <
typename ET>
113 inline typename std::enable_if<is_tensor_of_container<ET>::value,
typename Traits<ET>::scalar_type *>
::type
126 template <
typename T>
132 void push(
const std::string &s);
134 template <
typename U>
135 typename std::enable_if<std::is_base_of<Serializable, U>::value>
::type
136 write(
const std::string& s,
const U &output);
137 template <
typename U>
139 write(
const std::string& s,
const U &output);
140 template <
typename U>
142 template <
typename U,
int N>
144 template <
typename U,
int N>
146 template <
typename ETensor>
147 typename std::enable_if<EigenIO::is_tensor<ETensor>::value>
::type
148 write(
const std::string &s,
const ETensor &output);
150 template <
typename S>
151 inline typename std::enable_if<EigenIO::is_scalar<S>::value,
void>
::type
157 template <
typename S>
158 inline typename std::enable_if<isGridTensor<S>::value,
void>
::type
176 template <
typename T>
182 bool push(
const std::string &s);
184 template <
typename U>
185 typename std::enable_if<std::is_base_of<Serializable, U>::value,
void>
::type
186 read(
const std::string& s,
U &output);
187 template <
typename U>
188 typename std::enable_if<!std::is_base_of<Serializable, U>::value
190 read(
const std::string& s,
U &output);
191 template <
typename U>
193 template <
typename U,
int N>
195 template <
typename U,
int N>
197 template <
typename ETensor>
198 typename std::enable_if<EigenIO::is_tensor<ETensor>::value,
void>
::type
199 read(
const std::string &s, ETensor &output);
200 template <
typename ETensor>
201 typename std::enable_if<EigenIO::is_tensor_fixed<ETensor>::value,
void>
::type
202 Reshape(ETensor &t,
const std::array<typename ETensor::Index, ETensor::NumDimensions> &dims );
203 template <
typename ETensor>
204 typename std::enable_if<EigenIO::is_tensor_variable<ETensor>::value,
void>
::type
205 Reshape(ETensor &t,
const std::array<typename ETensor::Index, ETensor::NumDimensions> &dims );
208 template <
typename S>
209 inline typename std::enable_if<EigenIO::is_scalar<S>::value,
void>
::type
215 template <
typename S>
216 inline typename std::enable_if<isGridTensor<S>::value,
void>
::type
224 template <
typename U>
239 template <
typename T>
242 upcast =
static_cast<T *
>(
this);
245 template <
typename T>
251 template <
typename T>
257 template <
typename T>
258 template <
typename U>
259 typename std::enable_if<std::is_base_of<Serializable, U>::value,
void>
::type
262 U::write(*
this, s, output);
265 template <
typename T>
266 template <
typename U>
267 typename std::enable_if<!std::is_base_of<Serializable, U>::value
271 upcast->writeDefault(s, output);
275 template <
typename T>
276 template <
typename U>
282 template <
typename T>
283 template <
typename U,
int N>
289 template <
typename T>
290 template <
typename U,
int N>
297 template <
typename T>
298 template <
typename ETensor>
299 typename std::enable_if<EigenIO::is_tensor<ETensor>::value,
void>
::type
302 using Index =
typename ETensor::Index;
303 using Container =
typename ETensor::Scalar;
305 using Scalar =
typename Traits::scalar_type;
306 constexpr unsigned int TensorRank{ETensor::NumIndices};
307 constexpr unsigned int ContainerRank{Traits::Rank};
308 constexpr unsigned int TotalRank{TensorRank + ContainerRank};
309 const Index NumElements{output.size()};
310 assert( NumElements > 0 );
313 std::vector<std::size_t> TotalDims(TotalRank);
314 for(
auto i = 0; i < TensorRank; i++ ) {
315 auto dim = output.dimension(i);
316 TotalDims[i] =
static_cast<size_t>(dim);
317 assert( TotalDims[i] == dim );
319 for(
auto i = 0; i < ContainerRank; i++ )
320 TotalDims[TensorRank + i] = Traits::Dimension(i);
323 const bool CopyData{NumElements > 1 &&
static_cast<int>( ETensor::Layout ) !=
static_cast<int>( Eigen::StorageOptions::RowMajor )};
324 const Scalar * pWriteBuffer;
325 std::vector<Scalar> CopyBuffer;
326 const Index TotalNumElements = NumElements * Traits::count;
331 CopyBuffer.resize( TotalNumElements );
332 Scalar * pCopy = &CopyBuffer[0];
333 pWriteBuffer = pCopy;
334 std::array<Index, TensorRank> MyIndex;
335 for(
auto &idx : MyIndex ) idx = 0;
336 for(
auto n = 0; n < NumElements; n++ ) {
337 const Container & c = output( MyIndex );
340 for(
int i = output.NumDimensions - 1; i >= 0 && ++MyIndex[i] == output.dimension(i); i-- )
344 upcast->template writeMultiDim<Scalar>(s, TotalDims, pWriteBuffer, TotalNumElements);
347 template <
typename T>
353 template <
typename T>
359 template <
typename T>
365 template <
typename T>
372 template <
typename T>
375 upcast =
static_cast<T *
>(
this);
378 template <
typename T>
384 template <
typename T>
390 template <
typename T>
391 template <
typename U>
392 typename std::enable_if<std::is_base_of<Serializable, U>::value,
void>
::type
395 U::read(*
this, s, output);
398 template <
typename T>
399 template <
typename U>
400 typename std::enable_if<!std::is_base_of<Serializable, U>::value
404 upcast->readDefault(s, output);
407 template <
typename T>
408 template <
typename U>
413 upcast->readDefault(s, v);
417 template <
typename T>
418 template <
typename U,
int N>
423 upcast->readDefault(s, v);
427 template <
typename T>
428 template <
typename U,
int N>
433 upcast->readDefault(s, v);
437 template <
typename T>
438 template <
typename ETensor>
439 typename std::enable_if<EigenIO::is_tensor<ETensor>::value,
void>
::type
442 using Index =
typename ETensor::Index;
443 using Container =
typename ETensor::Scalar;
445 using Scalar =
typename Traits::scalar_type;
446 constexpr unsigned int TensorRank{ETensor::NumIndices};
447 constexpr unsigned int ContainerRank{Traits::Rank};
448 constexpr unsigned int TotalRank{TensorRank + ContainerRank};
449 using ETDims = std::array<Index, TensorRank>;
452 std::vector<std::size_t> dimData;
453 std::vector<Scalar> buf;
454 upcast->readMultiDim( s, buf, dimData );
455 assert(dimData.size() == TotalRank &&
"EigenIO: Tensor rank mismatch" );
457 std::size_t NumContainers = 1;
458 for(
auto i = 0 ; i < TensorRank ; i++ )
459 NumContainers *= dimData[i];
461 std::size_t ElementsPerContainer = 1;
462 for(
auto i = 0 ; i < ContainerRank ; i++ ) {
463 assert( dimData[TensorRank+i] == Traits::Dimension(i) &&
"Tensor Container dimensions don't match data" );
464 ElementsPerContainer *= dimData[TensorRank+i];
466 assert( NumContainers * ElementsPerContainer == buf.size() &&
"EigenIO: Number of elements != product of dimensions" );
468 const auto & dims = output.dimensions();
469 bool bShapeOK = (output.data() !=
nullptr);
470 for(
auto i = 0; bShapeOK && i < TensorRank ; i++ )
471 if( dims[i] != dimData[i] )
476 for(
auto i = 0 ; i < TensorRank ; i++ )
477 MyIndex[i] = dimData[i];
481 for(
auto &d : MyIndex ) d = 0;
482 const Scalar * pSource = &buf[0];
483 for( std::size_t n = 0 ; n < NumContainers ; n++ ) {
484 Container & c = output( MyIndex );
487 for(
int i = TensorRank - 1; i != -1 && ++MyIndex[i] == dims[i]; i-- )
490 assert( pSource == &buf[NumContainers * ElementsPerContainer] );
493 template <
typename T>
494 template <
typename ETensor>
495 typename std::enable_if<EigenIO::is_tensor_fixed<ETensor>::value,
void>
::type
496 Reader<T>::Reshape(ETensor &t,
const std::array<typename ETensor::Index, ETensor::NumDimensions> &dims )
498 assert( 0 &&
"EigenIO: Fixed tensor dimensions can't be changed" );
501 template <
typename T>
502 template <
typename ETensor>
503 typename std::enable_if<EigenIO::is_tensor_variable<ETensor>::value,
void>
::type
504 Reader<T>::Reshape(ETensor &t,
const std::array<typename ETensor::Index, ETensor::NumDimensions> &dims )
508 assert(omp_in_parallel()==0 &&
"Deserialisation which resizes Eigen tensor must happen from primary thread");
516 template <
typename T>
517 template <
typename U>
520 std::istringstream is(s);
522 is.exceptions(std::ios::failbit);
525 is >> std::boolalpha >> output;
527 catch(std::ios_base::failure &e)
529 std::cerr <<
"numerical conversion failure on '" << s <<
"' ";
530 std::cerr <<
"(typeid: " <<
typeid(
U).name() <<
")" << std::endl;
539 template <
typename T>
544 template <
typename T>
555 template <
typename T1,
typename T2>
561 template <
typename T1,
typename T2>
565 bool bReturnValue = (T1::NumIndices == T2::NumIndices);
566 for(
auto i = 0 ; bReturnValue && i < T1::NumIndices ; i++ )
567 bReturnValue = ( lhs.dimension(i) == rhs.dimension(i) );
569 Eigen::Tensor<bool, 0, T1::Options> bResult = (lhs == rhs).all();
570 bReturnValue = bResult(0);
575 template <
typename T>
576 static inline typename std::enable_if<EigenIO::is_tensor<T>::value,
bool>
::type
578 const auto NumElements = lhs.size();
579 bool bResult = ( NumElements == rhs.size() );
580 for(
auto i = 0 ; i < NumElements && bResult ; i++ )
585 template <
typename T>
586 static inline typename std::enable_if<!EigenIO::is_tensor<T>::value,
void>
::type
591 template <
typename T>
592 static inline typename std::enable_if<EigenIO::is_tensor<T>::value,
void>
::type
594 using Index =
typename T::Index;
595 const Index NumElements{
object.size()};
596 assert( NumElements > 0 );
599 for(
int i = 0; i < T::NumIndices; i++ ) {
600 Index dim =
object.dimension(i);
606 assert( count == NumElements &&
"Number of elements doesn't match tensor dimensions" );
608 const typename T::Scalar * p =
object.data();
609 for(
Index i = 0; i < count; i++ ) {
619 template <
typename T>
624 template <
typename T>
627 w.
push(std::string(s));
630 template <
typename T>
636 template <
typename T,
typename U>
643 template <
typename T>
649 template <
typename T>
652 return r.
push(std::string(s));
655 template <
typename T>
661 template <
typename T,
typename U>
std::complex< T > complex
static INTERNAL_PRECISION U
std::enable_if< isGridTensor< S >::value, void >::type copyScalars(S &Dest, const typename GridTypeMapper< S >::scalar_type *&pSource)
void fromString(U &output, const std::string &s)
std::enable_if< EigenIO::is_scalar< S >::value, void >::type copyScalars(S &Dest, const S *&pSource)
std::enable_if< EigenIO::is_tensor_variable< ETensor >::value, void >::type Reshape(ETensor &t, const std::array< typename ETensor::Index, ETensor::NumDimensions > &dims)
std::enable_if<!std::is_base_of< Serializable, U >::value &&!EigenIO::is_tensor< U >::value, void >::type read(const std::string &s, U &output)
std::enable_if< EigenIO::is_tensor_fixed< ETensor >::value, void >::type Reshape(ETensor &t, const std::array< typename ETensor::Index, ETensor::NumDimensions > &dims)
virtual ~Reader(void)=default
std::enable_if< std::is_base_of< Serializable, U >::value, void >::type read(const std::string &s, U &output)
bool push(const std::string &s)
static std::enable_if< EigenIO::is_tensor< T >::value, void >::type WriteMember(std::ostream &os, const T &object)
static void read(Reader< T > &RD, const std::string &s, Serializable &obj)
static std::enable_if<!EigenIO::is_tensor< T1 >::value||!EigenIO::is_tensor< T2 >::value, bool >::type CompareMember(const T1 &lhs, const T2 &rhs)
static void write(Writer< T > &WR, const std::string &s, const Serializable &obj)
friend std::ostream & operator<<(std::ostream &os, const Serializable &obj)
static std::enable_if<!EigenIO::is_tensor< T >::value, void >::type WriteMember(std::ostream &os, const T &object)
static std::enable_if< EigenIO::is_tensor< T1 >::value &&EigenIO::is_tensor< T2 >::value, bool >::type CompareMember(const T1 &lhs, const T2 &rhs)
static std::enable_if< EigenIO::is_tensor< T >::value, bool >::type CompareMember(const std::vector< T > &lhs, const std::vector< T > &rhs)
std::enable_if< EigenIO::is_scalar< S >::value, void >::type copyScalars(S *&pCopy, const S &Source)
std::enable_if< std::is_base_of< Serializable, U >::value >::type write(const std::string &s, const U &output)
std::enable_if< isGridTensor< S >::value, void >::type copyScalars(typename GridTypeMapper< S >::scalar_type *&pCopy, const S &Source)
void push(const std::string &s)
unsigned int getPrecision(void)
void setPrecision(const unsigned int prec)
void scientificFormat(const bool set)
std::enable_if<!std::is_base_of< Serializable, U >::value &&!EigenIO::is_tensor< U >::value >::type write(const std::string &s, const U &output)
virtual ~Writer(void)=default
std::enable_if< is_tensor< ET >::value, consttypenameET::Index >::type getScalarCount(const ET &eigenTensor)
std::enable_if< is_tensor_of_scalar< ET >::value, consttypenameET::Scalar * >::type getFirstScalar(const ET &eigenTensor)
std::uint64_t EigenResizeCounter
void read(Reader< T > &r, const std::string &s, U &output)
TensorToVec< T >::type tensorToVec(const T &t)
void push(Writer< T > &w, const std::string &s)
void write(Writer< T > &w, const std::string &s, const U &output)
void vecToTensor(T &t, const typename TensorToVec< T >::type &v)
static constexpr bool is_complex
static constexpr std::size_t count
static constexpr int TensorLevel
static constexpr int Dimension(int dim)
typename BaseTraits::scalar_type scalar_type
GridTypeMapper< typename T::Scalar > BaseTraits
static constexpr int Rank
typename T::Scalar scalar_type
static constexpr bool is_complex