7 #ifndef ALPS_HDF5_BOOST_MULTI_ARRAY_HPP 8 #define ALPS_HDF5_BOOST_MULTI_ARRAY_HPP 14 #include <boost/multi_array.hpp> 19 template<
typename T, std::
size_t N,
typename A>
struct scalar_type<
boost::multi_array<T, N, A> > {
42 template<
typename T, std::
size_t N,
typename A>
struct get_extent<boost::multi_array<T, N, A> > {
43 static std::vector<std::size_t> apply(boost::multi_array<T, N, A>
const & value) {
45 std::vector<std::size_t>
result(value.shape(), value.shape() + boost::multi_array<T, N, A>::dimensionality);
46 if (value.num_elements()) {
47 std::vector<std::size_t> extent(
get_extent(*value.data()));
48 for (std::size_t i = 1; i < value.num_elements(); ++i)
49 if (!std::equal(extent.begin(), extent.end(),
get_extent(value.data()[i]).begin()))
51 std::copy(extent.begin(), extent.end(), std::back_inserter(
result));
60 template<
typename T, std::
size_t N,
typename A>
struct set_extent<boost::multi_array<T, N, A> > {
61 static void apply(boost::multi_array<T, N, A> & value, std::vector<std::size_t>
const &
size) {
63 if (boost::multi_array<T, N, A>::dimensionality > size.size())
65 if (!std::equal(value.shape(), value.shape() + boost::multi_array<T, N, A>::dimensionality, size.begin())) {
66 typename boost::multi_array<T, N, A>::extent_gen extents;
67 gen_extent(value, extents, size);
70 for (std::size_t i = 0; i < value.num_elements(); ++i)
71 set_extent(value.data()[i], std::vector<std::size_t>(size.begin() + boost::multi_array<T, N, A>::dimensionality, size.end()));
74 template<std::
size_t M>
static void gen_extent(boost::multi_array<T, N, A> & value, boost::detail::multi_array::extent_gen<M> extents, std::vector<std::size_t>
const & size) {
75 gen_extent(value, extents[size.front()], std::vector<std::size_t>(size.begin() + 1, size.end()));
77 static void gen_extent(boost::multi_array<T, N, A> & value,
typename boost::detail::multi_array::extent_gen<N> extents, std::vector<std::size_t>
const & ) {
78 value.resize(extents);
85 template<
typename T, std::
size_t N,
typename A>
struct is_vectorizable<boost::multi_array<T, N, A> > {
86 static bool apply(boost::multi_array<T, N, A>
const & value) {
90 for (std::size_t i = 1; i < value.num_elements(); ++i)
100 template<
typename T, std::
size_t N,
typename A>
struct get_pointer<boost::multi_array<T, N, A> > {
110 template<
typename T, std::
size_t N,
typename A>
struct get_pointer<boost::multi_array<T, N, A> const> {
122 template<
typename T, std::
size_t N,
typename A>
void save(
124 , std::string
const & path
125 , boost::multi_array<T, N, A>
const & value
126 , std::vector<std::size_t>
size = std::vector<std::size_t>()
127 , std::vector<std::size_t> chunk = std::vector<std::size_t>()
128 , std::vector<std::size_t> offset = std::vector<std::size_t>()
131 std::vector<std::size_t> extent(
get_extent(value));
132 std::copy(extent.begin(), extent.end(), std::back_inserter(
size));
133 std::copy(extent.begin(), extent.end(), std::back_inserter(chunk));
134 std::fill_n(std::back_inserter(offset), extent.size(), 0);
137 std::copy(value.shape(), value.shape() + boost::multi_array<T, N, A>::dimensionality, std::back_inserter(
size));
138 std::fill_n(std::back_inserter(chunk), value.num_elements(), 1);
139 for (std::size_t i = 1; i < value.num_elements(); ++i) {
140 std::vector<std::size_t> local_offset(offset);
141 local_offset.push_back(i / value.num_elements() * *value.shape());
143 typename boost::multi_array<T, N, A>::size_type
const * it = value.shape() + 1;
144 it != value.shape() + boost::multi_array<T, N, A>::dimensionality;
147 local_offset.push_back((i % std::accumulate(
148 it, value.shape() + boost::multi_array<T, N, A>::dimensionality, std::size_t(1), std::multiplies<std::size_t>()
149 )) / std::accumulate(
150 it + 1, value.shape() + boost::multi_array<T, N, A>::dimensionality, std::size_t(1), std::multiplies<std::size_t>()
152 save(ar, path, value.data()[i],
size, chunk, local_offset);
168 template<
typename T, std::
size_t N,
typename A>
void load(
170 , std::string
const & path
171 , boost::multi_array<T, N, A> & value
172 , std::vector<std::size_t> chunk = std::vector<std::size_t>()
173 , std::vector<std::size_t> offset = std::vector<std::size_t>()
180 std::vector<std::size_t>
size(ar.
extent(path));
181 if (boost::multi_array<T, N, A>::dimensionality <=
size.size())
184 std::copy(
size.begin() + chunk.size(),
size.end(), std::back_inserter(chunk));
185 std::fill_n(std::back_inserter(offset),
size.size() - offset.size(), 0);
188 std::fill_n(std::back_inserter(chunk), value.num_elements(), 1);
189 for (std::size_t i = 1; i < value.num_elements(); ++i) {
190 std::vector<std::size_t> local_offset(offset);
191 local_offset.push_back(i / value.num_elements() * *value.shape());
193 typename boost::multi_array<T, N, A>::size_type
const * it = value.shape() + 1;
194 it != value.shape() + boost::multi_array<T, N, A>::dimensionality;
197 local_offset.push_back((i % std::accumulate(
198 it, value.shape() + boost::multi_array<T, N, A>::dimensionality, std::size_t(1), std::multiplies<std::size_t>()
199 )) / std::accumulate(
200 it + 1, value.shape() + boost::multi_array<T, N, A>::dimensionality, std::size_t(1), std::multiplies<std::size_t>()
202 load(ar, path, value.data()[i], chunk, local_offset);
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 >())
bool is_vectorizable(T const &value)
void set_extent(T &value, std::vector< std::size_t > const &size)
std::enable_if<!is_sequence< T >::value, std::size_t >::type size(T const &)
scalar_type< typename boost::remove_reference< typename boost::remove_cv< T >::type >::type >::type type
std::vector< std::size_t > get_extent(T const &value)
scalar_type< T >::type * get_pointer(T &value)
std::vector< std::size_t > extent(std::string path) const
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
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
traits< Acc >::result_type result(const Acc &acc)
bool is_group(std::string path) const
bool is_complex(std::string path) const
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 >())