ALPSCore reference
pair.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_STD_PAIR
8 #define ALPS_HDF5_STD_PAIR
9 
10 #include <alps/hdf5/archive.hpp>
11 #include <alps/utilities/cast.hpp>
13 
14 #include <utility>
15 
16 namespace alps {
17  namespace hdf5 {
18 
19  template <typename T, typename U> void save(
20  archive & ar
21  , std::string const & path
22  , std::pair<T, U> const & value
23  , std::vector<std::size_t> /*size*/ = std::vector<std::size_t>()
24  , std::vector<std::size_t> /*chunk*/ = std::vector<std::size_t>()
25  , std::vector<std::size_t> /*offset*/ = std::vector<std::size_t>()
26  ) {
27  save(ar, ar.complete_path(path) + "/0", value.first);
28  if (has_complex_elements<typename alps::detail::remove_cvr<T>::type>::value)
29  ar.set_complex(ar.complete_path(path) + "/0");
30  save(ar, ar.complete_path(path) + "/1", value.second);
31  if (has_complex_elements<typename alps::detail::remove_cvr<U>::type>::value)
32  ar.set_complex(ar.complete_path(path) + "/1");
33  }
34 
35  template <typename T, typename U> void load(
36  archive & ar
37  , std::string const & path
38  , std::pair<T, U> & value
39  , std::vector<std::size_t> /*chunk*/ = std::vector<std::size_t>()
40  , std::vector<std::size_t> /*offset*/ = std::vector<std::size_t>()
41  ) {
42  try {
43  load(ar, ar.complete_path(path) + "/0", value.first);
44  load(ar, ar.complete_path(path) + "/1", value.second);
45  } catch (path_not_found exc) {
46  load(ar, ar.complete_path(path) + "/first", value.first);
47  load(ar, ar.complete_path(path) + "/second", value.second);
48  }
49  }
50 
51  template<typename T> struct scalar_type<std::pair<T *, std::vector<std::size_t> > > {
53  };
54 
55  template<typename T> struct is_content_continuous<std::pair<T *, std::vector<std::size_t> > >
56  : public is_continuous<T>
57  {};
58 
59  template<typename T> struct has_complex_elements<std::pair<T *, std::vector<std::size_t> > >
60  : public has_complex_elements<typename alps::detail::remove_cvr<T>::type>
61  {};
62 
63  namespace detail {
64 
65  template<typename T> struct get_extent<std::pair<T *, std::vector<std::size_t> > > {
66  static std::vector<std::size_t> apply(std::pair<T *, std::vector<std::size_t> > const & value) {
68  std::vector<std::size_t> extent(value.second);
69  std::vector<std::size_t> size(value.second.size() ? get_extent(*value.first) : std::vector<std::size_t>());
70  if (!is_continuous<T>::value && value.second.size()) {
71  for (std::size_t i = 1; i < std::accumulate(value.second.begin(), value.second.end(), std::size_t(1), std::multiplies<std::size_t>()); ++i)
72  if (!std::equal(size.begin(), size.end(), get_extent(value.first[i]).begin()))
73  throw archive_error("no rectengual matrix" + ALPS_STACKTRACE);
74  }
75  std::copy(size.begin(), size.end(), std::back_inserter(extent));
76  return extent;
77  }
78  };
79 
80  template<typename T> struct set_extent<std::pair<T *, std::vector<std::size_t> > > {
81  static void apply(std::pair<T *, std::vector<std::size_t> > & value, std::vector<std::size_t> const & size) {
83  if (value.second.size() > size.size() || !std::equal(value.second.begin(), value.second.end(), size.begin()))
84  throw archive_error("invalid data size" + ALPS_STACKTRACE);
85  if (!is_continuous<T>::value && value.second.size() && value.second.size() < size.size())
86  for (std::size_t i = 0; i < std::accumulate(value.second.begin(), value.second.end(), std::size_t(1), std::multiplies<std::size_t>()); ++i)
87  set_extent(value.first[i], std::vector<std::size_t>(size.begin() + value.second.size(), size.end()));
88  }
89  };
90 
91  template<typename T> struct is_vectorizable<std::pair<T *, std::vector<std::size_t> > > {
92  static bool apply(std::pair<T *, std::vector<std::size_t> > const & value) {
95  std::vector<std::size_t> size(get_extent(*value.first));
96  for (std::size_t i = 1; i < std::accumulate(value.second.begin(), value.second.end(), std::size_t(1), std::multiplies<std::size_t>()); ++i)
97  if (!is_vectorizable(value.first[i]) || !std::equal(size.begin(), size.end(), get_extent(value.first[i]).begin()))
98  return false;
99  return true;
100  }
101  };
102 
103  template<typename T> struct get_pointer<std::pair<T *, std::vector<std::size_t> > > {
104  static typename alps::hdf5::scalar_type<std::pair<T *, std::vector<std::size_t> > >::type * apply(std::pair<T *, std::vector<std::size_t> > & value) {
106  return get_pointer(*value.first);
107  }
108  };
109 
110  template<typename T> struct get_pointer<std::pair<T *, std::vector<std::size_t> > const> {
111  static typename alps::hdf5::scalar_type<std::pair<T *, std::vector<std::size_t> > >::type const * apply(std::pair<T *, std::vector<std::size_t> > const & value) {
113  return get_pointer(*value.first);
114  }
115  };
116 
117  }
118 
119  template<typename T> void save(
120  archive & ar
121  , std::string const & path
122  , std::pair<T *, std::vector<std::size_t> > const & value
123  , std::vector<std::size_t> size = std::vector<std::size_t>()
124  , std::vector<std::size_t> chunk = std::vector<std::size_t>()
125  , std::vector<std::size_t> offset = std::vector<std::size_t>()
126  ) {
128  std::vector<std::size_t> extent(get_extent(value));
129  std::copy(extent.begin(), extent.end(), std::back_inserter(size));
130  std::copy(extent.begin(), extent.end(), std::back_inserter(chunk));
131  std::fill_n(std::back_inserter(offset), extent.size(), 0);
132  ar.write(path, get_pointer(value), size, chunk, offset);
133  } else if (value.second.size() == 0)
134  ar.write(path, static_cast<int const *>(NULL), std::vector<std::size_t>());
135  else if (is_vectorizable(value)) {
136  std::copy(value.second.begin(), value.second.end(), std::back_inserter(size));
137  std::fill_n(std::back_inserter(chunk), value.second.size(), 1);
138  for (
139  std::size_t i = 0;
140  i < std::accumulate(value.second.begin(), value.second.end(), std::size_t(1), std::multiplies<std::size_t>());
141  ++i
142  ) {
143  std::vector<std::size_t> local_offset(offset);
144  local_offset.push_back(
145  i / std::accumulate(value.second.begin() + 1, value.second.end(), std::size_t(1), std::multiplies<std::size_t>())
146  );
147  for (std::vector<std::size_t>::const_iterator it = value.second.begin() + 1; it != value.second.end(); ++it)
148  local_offset.push_back((i % std::accumulate(
149  it, value.second.end(), std::size_t(1), std::multiplies<std::size_t>()
150  )) / std::accumulate(
151  it + 1, value.second.end(), std::size_t(1), std::multiplies<std::size_t>()
152  ));
153  save(ar, path, value.first[i], size, chunk, local_offset);
154  }
155  } else {
156  if (path.find_last_of('@') != std::string::npos)
157  throw archive_error("attributes needs to be vectorizable: " + path + ALPS_STACKTRACE);
158  if (ar.is_data(path))
159  ar.delete_data(path);
160  offset = std::vector<std::size_t>(value.second.size(), 0);
161  do {
162  std::size_t last = offset.size() - 1, pos = 0;
163  std::string location = "";
164  for (std::vector<std::size_t>::const_iterator it = offset.begin(); it != offset.end(); ++it) {
165  location += "/" + cast<std::string>(*it);
166  pos += *it * std::accumulate(
167  value.second.begin() + (it - offset.begin()) + 1,
168  value.second.end(),
169  std::size_t(1),
170  std::multiplies<std::size_t>()
171  );
172  }
173  save(ar, path + location, value.first[pos]);
174  if (offset[last] + 1 == value.second[last] && last) {
175  for (pos = last; ++offset[pos] == value.second[pos] && pos; --pos);
176  for (++pos; pos <= last; ++pos)
177  offset[pos] = 0;
178  } else
179  ++offset[last];
180  } while (offset[0] < value.second[0]);
181  }
182  }
183 
184  template<typename T> void load(
185  archive & ar
186  , std::string const & path
187  , std::pair<T *, std::vector<std::size_t> > & value
188  , std::vector<std::size_t> chunk = std::vector<std::size_t>()
189  , std::vector<std::size_t> offset = std::vector<std::size_t>()
190  ) {
191  if (ar.is_group(path)) {
192  offset = std::vector<std::size_t>(value.second.size(), 0);
193  do {
194  std::size_t last = offset.size() - 1, pos = 0;
195  std::string location = "";
196  for (std::vector<std::size_t>::const_iterator it = offset.begin(); it != offset.end(); ++it) {
197  location += "/" + cast<std::string>(*it);
198  pos += *it * std::accumulate(
199  value.second.begin() + (it - offset.begin()) + 1,
200  value.second.end(),
201  std::size_t(1),
202  std::multiplies<std::size_t>()
203  );
204  }
205  load(ar, path + location, value.first[pos]);
206  if (offset[last] + 1 == value.second[last] && last) {
207  for (pos = last; ++offset[pos] == value.second[pos] && pos; --pos);
208  for (++pos; pos <= last; ++pos)
209  offset[pos] = 0;
210  } else
211  ++offset[last];
212  } while (offset[0] < value.second[0]);
213  } else {
214  std::vector<std::size_t> size(ar.extent(path));
215  set_extent(value, std::vector<std::size_t>(size.begin() + chunk.size(), size.end()));
217  std::copy(size.begin(), size.end(), std::back_inserter(chunk));
218  std::fill_n(std::back_inserter(offset), size.size(), 0);
219  ar.read(path, get_pointer(value), chunk, offset);
220  } else if (value.second.size()) {
221  std::fill_n(std::back_inserter(chunk), value.second.size(), 1);
222  for (
223  std::size_t i = 0;
224  i < std::accumulate(value.second.begin(), value.second.end(), std::size_t(1), std::multiplies<std::size_t>());
225  ++i
226  ) {
227  std::vector<std::size_t> local_offset(offset);
228  local_offset.push_back(
229  i / std::accumulate(value.second.begin() + 1, value.second.end(), std::size_t(1), std::multiplies<std::size_t>())
230  );
231  for (std::vector<std::size_t>::iterator it = value.second.begin() + 1; it != value.second.end(); ++it)
232  local_offset.push_back((i % std::accumulate(
233  it, value.second.end(), std::size_t(1), std::multiplies<std::size_t>()
234  )) / std::accumulate(
235  it + 1, value.second.end(), std::size_t(1), std::multiplies<std::size_t>()
236  ));
237  load(ar, path, value.first[i], chunk, local_offset);
238  }
239  }
240  }
241  }
242  }
243 }
244 
245 #endif
246 
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
bool is_vectorizable(T const &value)
Definition: archive.hpp:288
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
bool is_data(std::string path) const
Definition: archive.cpp:170
STL namespace.
std::vector< std::size_t > get_extent(T const &value)
Definition: archive.hpp:280
void delete_data(std::string path) const
Definition: archive.cpp:364
scalar_type< T >::type * get_pointer(T &value)
Definition: archive.hpp:272
scalar_type< typename alps::detail::remove_cvr< T >::type >::type type
Definition: pair.hpp:52
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
void set_complex(std::string path)
Definition: archive.cpp:397
#define ALPS_STACKTRACE
Definition: stacktrace.hpp:37
bool is_group(std::string path) const
Definition: archive.cpp:189
std::string complete_path(std::string path) const
Definition: archive.cpp:153
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