Skip to content

Commit a9f0f9b

Browse files
committed
[hist] Count bins as std::uint64_t
This is semantically more correct because for sparse histograms, not all bins have to be allocated in memory. For RRegularAxis, it also makes the member definition portable across platforms with different widths of std::size_t.
1 parent a075a71 commit a9f0f9b

File tree

12 files changed

+69
-49
lines changed

12 files changed

+69
-49
lines changed

hist/histv7/inc/ROOT/RAxes.hxx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <array>
1515
#include <cassert>
1616
#include <cstddef>
17+
#include <cstdint>
1718
#include <stdexcept>
1819
#include <tuple>
1920
#include <type_traits>
@@ -64,9 +65,9 @@ public:
6465
/// It is the product of each dimension's total number of bins.
6566
///
6667
/// \return the total number of bins
67-
std::size_t ComputeTotalNBins() const
68+
std::uint64_t ComputeTotalNBins() const
6869
{
69-
std::size_t totalNBins = 1;
70+
std::uint64_t totalNBins = 1;
7071
for (auto &&axis : fAxes) {
7172
if (auto *regular = std::get_if<RRegularAxis>(&axis)) {
7273
totalNBins *= regular->GetTotalNBins();
@@ -155,7 +156,7 @@ public:
155156
if (N != fAxes.size()) {
156157
throw std::invalid_argument("invalid number of indices passed to ComputeGlobalIndex");
157158
}
158-
std::size_t globalIndex = 0;
159+
std::uint64_t globalIndex = 0;
159160
for (std::size_t i = 0; i < N; i++) {
160161
const auto &index = indices[i];
161162
const auto &axis = fAxes[i];

hist/histv7/inc/ROOT/RBinIndex.hxx

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <cassert>
99
#include <cstddef>
10+
#include <cstdint>
1011

1112
namespace ROOT {
1213
namespace Experimental {
@@ -20,21 +21,25 @@ Objects of this type should be passed by value.
2021
Feedback is welcome!
2122
*/
2223
class RBinIndex final {
23-
static constexpr std::size_t UnderflowIndex = -3;
24-
static constexpr std::size_t OverflowIndex = -2;
25-
static constexpr std::size_t InvalidIndex = -1;
24+
static constexpr std::uint64_t UnderflowIndex = -3;
25+
static constexpr std::uint64_t OverflowIndex = -2;
26+
static constexpr std::uint64_t InvalidIndex = -1;
2627

27-
std::size_t fIndex = InvalidIndex;
28+
// We use std::uint64_t instead of std::size_t for the index because for sparse histograms, not all bins have to be
29+
// allocated in memory. However, we require that the index has at least that size.
30+
static_assert(sizeof(std::uint64_t) >= sizeof(std::size_t), "index type not large enough to address all bins");
31+
32+
std::uint64_t fIndex = InvalidIndex;
2833

2934
public:
3035
/// Construct an invalid bin index.
3136
RBinIndex() = default;
3237

3338
/// Construct a bin index for a normal bin.
34-
RBinIndex(std::size_t index) : fIndex(index) { assert(IsNormal()); }
39+
RBinIndex(std::uint64_t index) : fIndex(index) { assert(IsNormal()); }
3540

3641
/// Return the index for a normal bin.
37-
std::size_t GetIndex() const
42+
std::uint64_t GetIndex() const
3843
{
3944
assert(IsNormal());
4045
return fIndex;
@@ -48,13 +53,13 @@ public:
4853
bool IsOverflow() const { return fIndex == OverflowIndex; }
4954
bool IsInvalid() const { return fIndex == InvalidIndex; }
5055

51-
RBinIndex &operator+=(std::size_t a)
56+
RBinIndex &operator+=(std::uint64_t a)
5257
{
5358
if (!IsNormal()) {
5459
// Arithmetic operations on special values go to InvalidIndex.
5560
fIndex = InvalidIndex;
5661
} else {
57-
std::size_t old = fIndex;
62+
std::uint64_t old = fIndex;
5863
fIndex += a;
5964
if (fIndex < old || !IsNormal()) {
6065
// The addition wrapped around, go to InvalidIndex.
@@ -64,7 +69,7 @@ public:
6469
return *this;
6570
}
6671

67-
RBinIndex operator+(std::size_t a) const
72+
RBinIndex operator+(std::uint64_t a) const
6873
{
6974
RBinIndex ret = *this;
7075
ret += a;
@@ -84,7 +89,7 @@ public:
8489
return old;
8590
}
8691

87-
RBinIndex &operator-=(std::size_t a)
92+
RBinIndex &operator-=(std::uint64_t a)
8893
{
8994
if (!IsNormal()) {
9095
// Arithmetic operations on special values go to InvalidIndex.
@@ -98,7 +103,7 @@ public:
98103
return *this;
99104
}
100105

101-
RBinIndex operator-(std::size_t a) const
106+
RBinIndex operator-(std::uint64_t a) const
102107
{
103108
RBinIndex ret = *this;
104109
ret -= a;

hist/histv7/inc/ROOT/RBinIndexRange.hxx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include "RBinIndex.hxx"
99

1010
#include <cassert>
11-
#include <cstddef>
11+
#include <cstdint>
1212
#include <iterator>
1313

1414
namespace ROOT {
@@ -17,7 +17,7 @@ namespace Experimental {
1717
// forward declarations for friend declaration
1818
class RBinIndexRange;
1919
namespace Internal {
20-
static RBinIndexRange CreateBinIndexRange(RBinIndex begin, RBinIndex end, std::size_t nNormalBins);
20+
static RBinIndexRange CreateBinIndexRange(RBinIndex begin, RBinIndex end, std::uint64_t nNormalBins);
2121
} // namespace Internal
2222

2323
/**
@@ -40,14 +40,14 @@ for (auto index : axis.GetFullRange()) {
4040
Feedback is welcome!
4141
*/
4242
class RBinIndexRange final {
43-
friend RBinIndexRange Internal::CreateBinIndexRange(RBinIndex, RBinIndex, std::size_t);
43+
friend RBinIndexRange Internal::CreateBinIndexRange(RBinIndex, RBinIndex, std::uint64_t);
4444

4545
/// The begin of the range (inclusive)
4646
RBinIndex fBegin;
4747
/// The end of the range (exclusive)
4848
RBinIndex fEnd;
4949
/// The number of normal bins, after which iteration advances to RBinIndex::Overflow()
50-
std::size_t fNNormalBins = 0;
50+
std::uint64_t fNNormalBins = 0;
5151

5252
public:
5353
/// Construct an invalid bin index range.
@@ -69,7 +69,7 @@ public:
6969
/// The current bin index
7070
RBinIndex fIndex;
7171
/// The number of normal bins, after which iteration advances to RBinIndex::Overflow()
72-
std::size_t fNNormalBins = 0;
72+
std::uint64_t fNNormalBins = 0;
7373

7474
public:
7575
using difference_type = std::ptrdiff_t;
@@ -79,7 +79,7 @@ public:
7979
using iterator_category = std::input_iterator_tag;
8080

8181
RIterator() = default;
82-
RIterator(RBinIndex index, std::size_t nNormalBins) : fIndex(index), fNNormalBins(nNormalBins) {}
82+
RIterator(RBinIndex index, std::uint64_t nNormalBins) : fIndex(index), fNNormalBins(nNormalBins) {}
8383

8484
RIterator &operator++()
8585
{
@@ -130,7 +130,7 @@ namespace Internal {
130130
/// \param[in] begin the begin of the bin index range (inclusive)
131131
/// \param[in] end the end of the bin index range (exclusive)
132132
/// \param[in] nNormalBins the number of normal bins, after which iteration advances to RBinIndex::Overflow()
133-
static RBinIndexRange CreateBinIndexRange(RBinIndex begin, RBinIndex end, std::size_t nNormalBins)
133+
static RBinIndexRange CreateBinIndexRange(RBinIndex begin, RBinIndex end, std::uint64_t nNormalBins)
134134
{
135135
RBinIndexRange range;
136136
range.fBegin = begin;

hist/histv7/inc/ROOT/RCategoricalAxis.hxx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <cassert>
1313
#include <cstddef>
14+
#include <cstdint>
1415
#include <stdexcept>
1516
#include <string>
1617
#include <string_view>
@@ -69,8 +70,8 @@ public:
6970
}
7071
}
7172

72-
std::size_t GetNNormalBins() const { return fCategories.size(); }
73-
std::size_t GetTotalNBins() const { return fEnableOverflowBin ? fCategories.size() + 1 : fCategories.size(); }
73+
std::uint64_t GetNNormalBins() const { return fCategories.size(); }
74+
std::uint64_t GetTotalNBins() const { return fEnableOverflowBin ? fCategories.size() + 1 : fCategories.size(); }
7475
const std::vector<std::string> &GetCategories() const { return fCategories; }
7576
bool HasOverflowBin() const { return fEnableOverflowBin; }
7677

@@ -118,7 +119,7 @@ public:
118119
return {0, false};
119120
}
120121
assert(index.IsNormal());
121-
std::size_t bin = index.GetIndex();
122+
std::uint64_t bin = index.GetIndex();
122123
return {bin, bin < fCategories.size()};
123124
}
124125

hist/histv7/inc/ROOT/RHist.hxx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
#include <array>
1414
#include <cassert>
15+
#include <cstddef>
16+
#include <cstdint>
1517
#include <stdexcept>
1618
#include <tuple>
1719
#include <utility>
@@ -72,10 +74,11 @@ public:
7274
/// \param[in] nNormalBins the number of normal bins, must be > 0
7375
/// \param[in] interval the axis interval (lower end inclusive, upper end exclusive)
7476
/// \par See also
75-
/// the
76-
/// \ref RRegularAxis::RRegularAxis(std::size_t nNormalBins, std::pair<double, double> interval, bool enableFlowBins)
77-
/// "constructor of RRegularAxis"
78-
RHist(std::size_t nNormalBins, std::pair<double, double> interval) : RHist({RRegularAxis(nNormalBins, interval)}) {}
77+
/// the \ref RRegularAxis::RRegularAxis(std::uint64_t nNormalBins, std::pair<double, double> interval, bool
78+
/// enableFlowBins) "constructor of RRegularAxis"
79+
RHist(std::uint64_t nNormalBins, std::pair<double, double> interval) : RHist({RRegularAxis(nNormalBins, interval)})
80+
{
81+
}
7982

8083
/// The copy constructor is deleted.
8184
///
@@ -104,7 +107,7 @@ public:
104107

105108
const std::vector<RAxisVariant> &GetAxes() const { return fEngine.GetAxes(); }
106109
std::size_t GetNDimensions() const { return fEngine.GetNDimensions(); }
107-
std::size_t GetTotalNBins() const { return fEngine.GetTotalNBins(); }
110+
std::uint64_t GetTotalNBins() const { return fEngine.GetTotalNBins(); }
108111

109112
std::uint64_t GetNEntries() const { return fStats.GetNEntries(); }
110113
/// \copydoc RHistStats::ComputeNEffectiveEntries()

hist/histv7/inc/ROOT/RHistAutoAxisFiller.hxx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <algorithm>
1313
#include <cmath>
1414
#include <cstddef>
15+
#include <cstdint>
1516
#include <limits>
1617
#include <optional>
1718
#include <stdexcept>
@@ -53,7 +54,7 @@ private:
5354
std::optional<RHist<BinContentType>> fHist;
5455

5556
/// The number of normal bins
56-
std::size_t fNNormalBins;
57+
std::uint64_t fNNormalBins;
5758
/// The maximum buffer size until Flush() is automatically called
5859
std::size_t fMaxBufferSize;
5960
/// The fraction of the axis interval to use as margin
@@ -74,7 +75,8 @@ public:
7475
/// \param[in] nNormalBins the number of normal bins, must be > 0
7576
/// \param[in] maxBufferSize the maximum buffer size, must be > 0
7677
/// \param[in] marginFraction the fraction of the axis interval to use as margin, must be > 0
77-
explicit RHistAutoAxisFiller(std::size_t nNormalBins, std::size_t maxBufferSize = 1024, double marginFraction = 0.05)
78+
explicit RHistAutoAxisFiller(std::uint64_t nNormalBins, std::size_t maxBufferSize = 1024,
79+
double marginFraction = 0.05)
7880
: fNNormalBins(nNormalBins), fMaxBufferSize(maxBufferSize), fMarginFraction(marginFraction)
7981
{
8082
if (nNormalBins == 0) {
@@ -88,7 +90,7 @@ public:
8890
}
8991
}
9092

91-
std::size_t GetNNormalBins() const { return fNNormalBins; }
93+
std::uint64_t GetNNormalBins() const { return fNNormalBins; }
9294
std::size_t GetMaxBufferSize() const { return fMaxBufferSize; }
9395
double GetMarginFraction() const { return fMarginFraction; }
9496

hist/histv7/inc/ROOT/RHistEngine.hxx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
#include <array>
1616
#include <cassert>
17+
#include <cstddef>
18+
#include <cstdint>
1719
#include <stdexcept>
1820
#include <tuple>
1921
#include <type_traits>
@@ -87,10 +89,9 @@ public:
8789
/// \param[in] nNormalBins the number of normal bins, must be > 0
8890
/// \param[in] interval the axis interval (lower end inclusive, upper end exclusive)
8991
/// \par See also
90-
/// the
91-
/// \ref RRegularAxis::RRegularAxis(std::size_t nNormalBins, std::pair<double, double> interval, bool enableFlowBins)
92-
/// "constructor of RRegularAxis"
93-
RHistEngine(std::size_t nNormalBins, std::pair<double, double> interval)
92+
/// the \ref RRegularAxis::RRegularAxis(std::uint64_t nNormalBins, std::pair<double, double> interval, bool
93+
/// enableFlowBins) "constructor of RRegularAxis"
94+
RHistEngine(std::uint64_t nNormalBins, std::pair<double, double> interval)
9495
: RHistEngine({RRegularAxis(nNormalBins, interval)})
9596
{
9697
}
@@ -119,7 +120,7 @@ public:
119120

120121
const std::vector<RAxisVariant> &GetAxes() const { return fAxes.Get(); }
121122
std::size_t GetNDimensions() const { return fAxes.GetNDimensions(); }
122-
std::size_t GetTotalNBins() const { return fBinContents.size(); }
123+
std::uint64_t GetTotalNBins() const { return fBinContents.size(); }
123124

124125
/// Get the content of a single bin.
125126
///

hist/histv7/inc/ROOT/RHistStats.hxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "RWeight.hxx"
1111

1212
#include <cmath>
13+
#include <cstddef>
1314
#include <cstdint>
1415
#include <stdexcept>
1516
#include <tuple>

hist/histv7/inc/ROOT/RLinearizedIndex.hxx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define ROOT_RLinearizedIndex
77

88
#include <cstddef>
9+
#include <cstdint>
910

1011
namespace ROOT {
1112
namespace Experimental {
@@ -19,7 +20,11 @@ For example, when an argument is outside the axis and underflow / overflow bins
1920
Feedback is welcome!
2021
*/
2122
struct RLinearizedIndex final {
22-
std::size_t fIndex = 0;
23+
// We use std::uint64_t instead of std::size_t for the index because for sparse histograms, not all bins have to be
24+
// allocated in memory. However, we require that the index has at least that size.
25+
static_assert(sizeof(std::uint64_t) >= sizeof(std::size_t), "index type not large enough to address all bins");
26+
27+
std::uint64_t fIndex = 0;
2328
bool fValid = false;
2429
};
2530

hist/histv7/inc/ROOT/RRegularAxis.hxx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#include "RLinearizedIndex.hxx"
1111

1212
#include <cassert>
13-
#include <cstddef>
13+
#include <cstdint>
1414
#include <stdexcept>
1515
#include <string>
1616
#include <utility>
@@ -40,7 +40,7 @@ public:
4040

4141
private:
4242
/// The number of normal bins
43-
std::size_t fNNormalBins;
43+
std::uint64_t fNNormalBins;
4444
/// The lower end of the axis interval
4545
double fLow;
4646
/// The upper end of the axis interval
@@ -56,7 +56,7 @@ public:
5656
/// \param[in] nNormalBins the number of normal bins, must be > 0
5757
/// \param[in] interval the axis interval (lower end inclusive, upper end exclusive)
5858
/// \param[in] enableFlowBins whether to enable underflow and overflow bins
59-
RRegularAxis(std::size_t nNormalBins, std::pair<double, double> interval, bool enableFlowBins = true)
59+
RRegularAxis(std::uint64_t nNormalBins, std::pair<double, double> interval, bool enableFlowBins = true)
6060
: fNNormalBins(nNormalBins), fLow(interval.first), fHigh(interval.second), fEnableFlowBins(enableFlowBins)
6161
{
6262
if (nNormalBins == 0) {
@@ -69,8 +69,8 @@ public:
6969
fInvBinWidth = nNormalBins / (fHigh - fLow);
7070
}
7171

72-
std::size_t GetNNormalBins() const { return fNNormalBins; }
73-
std::size_t GetTotalNBins() const { return fEnableFlowBins ? fNNormalBins + 2 : fNNormalBins; }
72+
std::uint64_t GetNNormalBins() const { return fNNormalBins; }
73+
std::uint64_t GetTotalNBins() const { return fEnableFlowBins ? fNNormalBins + 2 : fNNormalBins; }
7474
double GetLow() const { return fLow; }
7575
double GetHigh() const { return fHigh; }
7676
bool HasFlowBins() const { return fEnableFlowBins; }
@@ -100,7 +100,7 @@ public:
100100
return {fNNormalBins + 1, fEnableFlowBins};
101101
}
102102

103-
std::size_t bin = (x - fLow) * fInvBinWidth;
103+
std::uint64_t bin = (x - fLow) * fInvBinWidth;
104104
if (bin >= fNNormalBins) {
105105
bin = fNNormalBins - 1;
106106
}
@@ -124,7 +124,7 @@ public:
124124
return {0, false};
125125
}
126126
assert(index.IsNormal());
127-
std::size_t bin = index.GetIndex();
127+
std::uint64_t bin = index.GetIndex();
128128
return {bin, bin < fNNormalBins};
129129
}
130130

0 commit comments

Comments
 (0)