Skip to content

Commit 131ed04

Browse files
committed
many size_of improvements
- introduced size_of for std::vector, boost::container::small_vector, Range1, Range, TiledRange1, TiledRange - improved/fixed size_of(Tensor) and size_of(SparseShape) - stronger unit test for size_of(DistArray)
1 parent ae717e2 commit 131ed04

File tree

9 files changed

+155
-11
lines changed

9 files changed

+155
-11
lines changed

src/TiledArray/dist_array.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,8 +1743,9 @@ class DistArray : public madness::archive::ParallelSerializableObject {
17431743

17441744
}; // class DistArray
17451745

1746-
/// \return the number of bytes used by \p t in this rank's memory space
1747-
/// `S`
1746+
/// \return the approximate number of bytes used by \p t in this rank's
1747+
/// memory space `S`
1748+
/// \note this does not account for the TiledRange and some other metadata
17481749
template <MemorySpace S, typename Tile, typename Policy>
17491750
std::size_t size_of(const DistArray<Tile, Policy>& da) {
17501751
std::size_t result = 0;

src/TiledArray/range.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define TILEDARRAY_RANGE_H__INCLUDED
2222

2323
#include <TiledArray/permutation.h>
24+
#include <TiledArray/platform.h>
2425
#include <TiledArray/range1.h>
2526
#include <TiledArray/range_iterator.h>
2627
#include <TiledArray/size_array.h>
@@ -1247,6 +1248,20 @@ class Range {
12471248
return ordinal(last) - ordinal(first);
12481249
}
12491250

1251+
template <MemorySpace S>
1252+
friend constexpr std::size_t size_of(const Range& r) {
1253+
std::size_t sz = 0;
1254+
if constexpr (S == MemorySpace::Host) {
1255+
sz += sizeof(r);
1256+
}
1257+
// correct for optional dynamic allocation of datavec_
1258+
if constexpr (S == MemorySpace::Host) {
1259+
sz -= sizeof(r.datavec_);
1260+
}
1261+
sz += size_of<S>(r.datavec_);
1262+
return sz;
1263+
}
1264+
12501265
}; // class Range
12511266

12521267
// lift Range::index_type and Range::index_view_type into user-land

src/TiledArray/range1.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <boost/iterator/iterator_facade.hpp>
2727

2828
#include <TiledArray/error.h>
29+
#include <TiledArray/platform.h>
2930

3031
namespace TiledArray {
3132

@@ -138,7 +139,7 @@ struct Range1 {
138139
/// \brief dereferences this iterator
139140
/// \return const reference to the current index
140141
const auto& dereference() const { return v; }
141-
};
142+
}; // class Iterator
142143
friend class Iterator;
143144

144145
typedef Iterator const_iterator; ///< Iterator type
@@ -201,6 +202,15 @@ struct Range1 {
201202
void serialize(Archive& ar) const {
202203
ar & first & second;
203204
}
205+
206+
template <MemorySpace S>
207+
friend constexpr std::size_t size_of(const Range1& r) {
208+
std::size_t sz = 0;
209+
if constexpr (S == MemorySpace::Host) {
210+
sz += sizeof(r);
211+
}
212+
return sz;
213+
}
204214
};
205215

206216
inline bool operator==(const Range1& x, const Range1& y) {

src/TiledArray/sparse_shape.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1734,7 +1734,19 @@ typename SparseShape<T>::value_type SparseShape<T>::threshold_ =
17341734

17351735
template <MemorySpace S, typename T>
17361736
std::size_t size_of(const SparseShape<T>& shape) {
1737-
return size_of<S>(shape.tile_norms_);
1737+
std::size_t sz = 0;
1738+
if constexpr (S == MemorySpace::Host) {
1739+
sz += sizeof(shape);
1740+
}
1741+
// account for dynamically-allocated content
1742+
if constexpr (S == MemorySpace::Host) {
1743+
sz -= sizeof(shape.tile_norms_);
1744+
}
1745+
sz += size_of<S>(shape.tile_norms_);
1746+
if (shape.tile_norms_unscaled_) {
1747+
sz += size_of<S>(*(shape.tile_norms_unscaled_));
1748+
}
1749+
return sz;
17381750
}
17391751

17401752
/// Add the shape to an output stream

src/TiledArray/tensor/tensor.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2779,17 +2779,21 @@ class Tensor {
27792779

27802780
/// \return the number of bytes used by \p t in memory space
27812781
/// `S`
2782-
/// \warning footprint of Range is approximated, will not be exact for
2783-
/// tensor orders highers than `TA_MAX_SOO_RANK_METADATA`
27842782
template <MemorySpace S, typename T, typename A>
27852783
std::size_t size_of(const Tensor<T, A>& t) {
27862784
std::size_t result = 0;
27872785
if constexpr (S == MemorySpace::Host) {
27882786
result += sizeof(t);
27892787
}
2788+
// correct for optional dynamic allocation of Range
2789+
if constexpr (S == MemorySpace::Host) {
2790+
result -= sizeof(Range);
2791+
}
2792+
result += size_of<S>(t.range());
2793+
27902794
if (allocates_memory_space<S>(A{})) {
27912795
if (!t.empty()) {
2792-
if constexpr (is_constexpr_size_of_v<S, Tensor<T, A>>) {
2796+
if constexpr (is_constexpr_size_of_v<S, T>) {
27932797
result += t.size() * sizeof(T);
27942798
} else {
27952799
result += std::accumulate(

src/TiledArray/tiled_range.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,24 @@ class TiledRange {
398398
range_type elements_range_; ///< Range of element indices
399399
Ranges ranges_; ///< tiled (1d) range, aka TiledRange1, for each mode
400400
///< `*this` is a direct product of these tilings
401+
402+
template <MemorySpace S>
403+
friend constexpr std::size_t size_of(const TiledRange& r) {
404+
std::size_t sz = 0;
405+
if constexpr (S == MemorySpace::Host) {
406+
sz += sizeof(r);
407+
}
408+
// correct for optional dynamic allocation of range_ and elements_range_
409+
if constexpr (S == MemorySpace::Host) {
410+
sz -= sizeof(r.range_);
411+
sz -= sizeof(r.elements_range_);
412+
sz -= sizeof(r.ranges_);
413+
}
414+
sz += size_of<S>(r.range_);
415+
sz += size_of<S>(r.elements_range_);
416+
sz += size_of<S>(r.ranges_);
417+
return sz;
418+
}
401419
};
402420

403421
/// TiledRange permutation operator.

src/TiledArray/tiled_range1.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <TiledArray/config.h>
2424

2525
#include <TiledArray/error.h>
26+
#include <TiledArray/platform.h>
2627
#include <TiledArray/range1.h>
2728
#include <TiledArray/type_traits.h>
2829
#include <TiledArray/utility.h>
@@ -493,6 +494,27 @@ class TiledRange1 {
493494
mutable std::shared_ptr<const index1_type[]>
494495
elem2tile_; ///< maps element index to tile index (memoized data).
495496

497+
template <MemorySpace S>
498+
friend constexpr std::size_t size_of(const TiledRange1& r) {
499+
std::size_t sz = 0;
500+
if constexpr (S == MemorySpace::Host) {
501+
sz += sizeof(r);
502+
}
503+
// correct for optional dynamic allocation of range_ and elements_range_
504+
if constexpr (S == MemorySpace::Host) {
505+
sz -= sizeof(r.range_);
506+
sz -= sizeof(r.elements_range_);
507+
sz -= sizeof(r.tiles_ranges_);
508+
}
509+
sz += size_of<S>(r.range_);
510+
sz += size_of<S>(r.elements_range_);
511+
sz += size_of<S>(r.tiles_ranges_);
512+
if (r.elem2tile_) {
513+
sz += r.elements_range_.extent() * sizeof(index1_type);
514+
}
515+
return sz;
516+
}
517+
496518
}; // class TiledRange1
497519

498520
/// Exchange the data of the two given ranges.

src/TiledArray/util/vector.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include <TiledArray/utility.h>
4646
#include <madness/world/archive.h>
4747
#include "TiledArray/error.h"
48+
#include "TiledArray/platform.h"
4849

4950
namespace TiledArray {
5051

@@ -55,6 +56,66 @@ using vector = std::vector<T>;
5556
template <typename T, std::size_t N = TA_MAX_SOO_RANK_METADATA>
5657
using svector = boost::container::small_vector<T, N>;
5758

59+
} // namespace container
60+
61+
// size_of etc.
62+
63+
template <MemorySpace S, typename T, typename A>
64+
constexpr std::size_t size_of(const std::vector<T, A>& t) {
65+
std::size_t sz = 0;
66+
if constexpr (S == MemorySpace::Host) {
67+
sz += sizeof(t);
68+
}
69+
if constexpr (allocates_memory_space<S>(t.get_allocator())) {
70+
if constexpr (is_constexpr_size_of_v<S, T>) {
71+
sz += sizeof(T) * t.capacity();
72+
} else {
73+
sz += std::accumulate(
74+
t.begin(), t.end(), std::size_t{0},
75+
[](const std::size_t s, const T& t) { return s + size_of<S>(t); });
76+
sz += (t.capacity() - t.size()) * sizeof(T);
77+
}
78+
}
79+
return sz;
80+
}
81+
82+
template <MemorySpace S, typename T, typename VoidAlloc, typename Options>
83+
constexpr bool allocates_memory_space(
84+
const boost::container::small_vector_allocator<T, VoidAlloc, Options>& a) {
85+
return S == MemorySpace::Host;
86+
}
87+
88+
template <MemorySpace S, typename T, std::size_t N, typename A>
89+
constexpr std::size_t size_of(
90+
const boost::container::small_vector<T, N, A>& t) {
91+
std::size_t sz = 0;
92+
if constexpr (S == MemorySpace::Host) {
93+
sz += sizeof(t);
94+
}
95+
if (allocates_memory_space<S>(t.get_allocator())) {
96+
std::size_t data_sz = 0;
97+
if constexpr (is_constexpr_size_of_v<S, T>) {
98+
data_sz += sizeof(T) * t.capacity();
99+
} else {
100+
data_sz += std::accumulate(
101+
t.begin(), t.end(), std::size_t{0},
102+
[](const std::size_t s, const T& t) { return s + size_of<S>(t); });
103+
data_sz += (t.capacity() - t.size()) * sizeof(T);
104+
}
105+
if (t.capacity() > N ||
106+
S != MemorySpace::Host) { // dynamically allocated buffer => account
107+
// for tne entirety of data_sz
108+
sz += data_sz;
109+
} else { // data in internal buffer => account for the
110+
// dynamically-allocated part of data_sz
111+
sz += (data_sz - t.capacity() * sizeof(T));
112+
}
113+
}
114+
return sz;
115+
}
116+
117+
namespace container {
118+
58119
template <typename Range>
59120
std::enable_if_t<detail::is_integral_range_v<Range> &&
60121
detail::is_sized_range_v<Range>,

tests/dist_array.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,10 +1000,11 @@ BOOST_AUTO_TEST_CASE(size_of) {
10001000

10011001
auto sz0 = TiledArray::size_of<MemorySpace::Host>(array);
10021002
world.gop.sum(sz0);
1003-
if (world.size() == 1)
1004-
BOOST_REQUIRE(sz0 == 56688);
1005-
else
1006-
BOOST_REQUIRE(sz0 > 56688);
1003+
const auto sz0_expected =
1004+
/* size on 1 rank */ 56728 +
1005+
/* size of shape on ranks 1 ... N-1 */ (world.size() - 1) *
1006+
TiledArray::size_of<MemorySpace::Host>(array.shape());
1007+
BOOST_REQUIRE(sz0 == sz0_expected);
10071008
}
10081009

10091010
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)