ALPSCore reference
tensor.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1998-2018 ALPS Collaboration. See COPYRIGHT.TXT
3  * All rights reserved. Use is subject to license terms. See LICENSE.TXT
4  * For use in publications, see ACKNOWLEDGE.TXT
5  */
6 
7 #ifndef ALPS_HDF5_TENSOR_HPP_H
8 #define ALPS_HDF5_TENSOR_HPP_H
9 
10 #include <alps/hdf5/archive.hpp>
13 
14 
15 namespace alps {
16  namespace hdf5 {
17 //
18  template<typename T, std::size_t N, typename A> struct scalar_type<alps::numerics::detail::tensor_base<T, N, A> > {
20  };
21 
22  template<typename T, std::size_t N, typename A> struct has_complex_elements<alps::numerics::detail::tensor_base<T, N, A> >
23  : public has_complex_elements<typename alps::detail::remove_cvr<T>::type>
24  {};
25 
26  namespace detail {
27 
28  template<typename T, std::size_t N, typename A> struct get_extent<alps::numerics::detail::tensor_base<T, N, A> > {
29  static std::vector<std::size_t> apply(const alps::numerics::detail::tensor_base<T, N, A> & value) {
31  std::vector < std::size_t > result(value.shape().begin(), value.shape().begin() + N);
32  if (value.size()) {
33  std::vector < std::size_t > extent(get_extent(value.data()[0]));
34  for (std::size_t i = 1; i < value.size(); ++i)
35  if (!std::equal(extent.begin(), extent.end(), get_extent(value.data()[i]).begin()))
36  throw archive_error("no rectangular matrix");
37  std::copy(extent.begin(), extent.end(), std::back_inserter(result));
38  }
39  return result;
40  }
41  };
42 
43  template<typename T, std::size_t N, typename A> struct set_extent<alps::numerics::detail::tensor_base<T, N, A> > {
44  static void apply(alps::numerics::detail::tensor_base<T, N, A> & value, std::vector<std::size_t> const & size) {
47  if (N > size.size())
48  throw archive_error("invalid data size");
49  std::vector < std::size_t > extent(get_extent(value.data()[0]));
50  std::array<size_t, N> new_size;
51  std::copy(size.begin(), size.end() - extent.size(), new_size.begin());
52  value.reshape(new_size);
53  }
54  };
55 
56  template<typename T, std::size_t N, typename A> struct get_pointer<alps::numerics::detail::tensor_base<T, N, A>> {
57  static typename alps::hdf5::scalar_type<alps::numerics::detail::tensor_base<T, N, A>>::type * apply(alps::numerics::detail::tensor_base<T, N, A> & value) {
59  return get_pointer(value.storage().data(0));
60  }
61  };
62  template<typename T, std::size_t N, typename A> struct get_pointer<const alps::numerics::detail::tensor_base<T, N, A> > {
63  static typename alps::hdf5::scalar_type<alps::numerics::detail::tensor_base<T, N, A> >::type const * apply(alps::numerics::detail::tensor_base<T, N, A> const & value) {
65  return get_pointer(value.storage().data(0));
66  }
67  };
68 
69  }
70 
71  template<typename T, std::size_t N, typename S> void save(
72  archive & ar
73  , std::string const & path
74  , const alps::numerics::detail::tensor_base<T, N, S>& value
75  , std::vector<std::size_t> size = std::vector<std::size_t>()
76  , std::vector<std::size_t> chunk = std::vector<std::size_t>()
77  , std::vector<std::size_t> offset = std::vector<std::size_t>()
78  ) {
79  std::vector<std::size_t> extent = get_extent(value);
80  std::copy(extent.begin(), extent.end(), std::back_inserter(size));
81  std::copy(extent.begin(), extent.end(), std::back_inserter(chunk));
82  std::fill_n(std::back_inserter(offset), extent.size(), 0);
83  ar.write(path, get_pointer(value), size, chunk, offset);
84  }
85 
86  template<typename T, std::size_t N, typename S> void load(
87  archive & ar
88  , std::string const & path
89  , numerics::detail::tensor_base<T, N, S> & value
90  , std::vector<std::size_t> chunk = std::vector<std::size_t>()
91  , std::vector<std::size_t> offset = std::vector<std::size_t>()
92  ) {
93  if (ar.is_group(path))
94  throw invalid_path("invalid path");
95  else {
96  if (ar.is_complex(path) != is_complex<T>::value)
97  throw archive_error("no complex value in archive" + ALPS_STACKTRACE);
98  std::vector<std::size_t> size(ar.extent(path));
99  if (value.dimension() > size.size()) {
100  throw wrong_dimensions("dimensions mismatched.");
101  }
102  set_extent(value, std::vector<std::size_t>(size.begin() + chunk.size(), size.end()));
103 
104  std::copy(size.begin() + chunk.size(), size.end(), std::back_inserter(chunk));
105  std::fill_n(std::back_inserter(offset), size.size() - offset.size(), 0);
106  ar.read(path, get_pointer(value), chunk, offset);
107  }
108  }
109 
110  }
111 }
112 #endif //ALPSCORE_TENSOR_HPP_H
void load(archive &ar, std::string const &path, T &value, std::vector< std::size_t > chunk=std::vector< std::size_t >(), std::vector< std::size_t >=std::vector< std::size_t >())
Definition: archive.hpp:309
void set_extent(T &value, std::vector< std::size_t > const &size)
Definition: archive.hpp:284
std::enable_if<!is_sequence< T >::value, std::size_t >::type size(T const &)
Definition: size.hpp:20
std::vector< std::size_t > get_extent(T const &value)
Definition: archive.hpp:280
scalar_type< T >::type * get_pointer(T &value)
Definition: archive.hpp:272
std::vector< std::size_t > extent(std::string path) const
Definition: archive.cpp:291
auto read(std::string path, T *, std::vector< std::size_t >, std::vector< std::size_t >=std::vector< std::size_t >()) const -> typename std::enable_if<!is_native_type< T >::value, void >::type
Definition: archive.hpp:163
auto write(std::string path, T const *value, std::vector< std::size_t > size, std::vector< std::size_t > chunk=std::vector< std::size_t >(), std::vector< std::size_t > offset=std::vector< std::size_t >()) const -> typename std::enable_if<!is_native_type< T >::value, void >::type
Definition: archive.hpp:172
#define ALPS_STACKTRACE
Definition: stacktrace.hpp:37
traits< Acc >::result_type result(const Acc &acc)
Definition: util.hpp:53
bool is_group(std::string path) const
Definition: archive.cpp:189
bool is_complex(std::string path) const
Definition: archive.cpp:242
void save(archive &ar, std::string const &path, T const &value, std::vector< std::size_t >=std::vector< std::size_t >(), std::vector< std::size_t > chunk=std::vector< std::size_t >(), std::vector< std::size_t >=std::vector< std::size_t >())
Definition: archive.hpp:292