define maximum capacity for internal buffers

This commit is contained in:
Hans Dembinski 2018-11-15 21:12:01 +01:00
parent 0569d4c0b6
commit 3076fc21b9
6 changed files with 67 additions and 15 deletions

View File

@ -10,10 +10,10 @@
{
"ClangFormat":
{
"style": "File",
"style": "File",
"format_on_save": true
},
"trim_trailing_white_space_on_save": false,
"trim_trailing_white_space_on_save": true,
"ensure_newline_at_eof_on_save": false,
},
"build_systems":

View File

@ -12,6 +12,7 @@
#include <boost/assert.hpp>
#include <boost/histogram/detail/axes.hpp>
#include <boost/histogram/detail/index_mapper.hpp>
#include <boost/histogram/detail/is_set.hpp>
#include <boost/histogram/histogram_fwd.hpp>
#include <boost/histogram/unsafe_access.hpp>
#include <boost/mp11.hpp>
@ -22,11 +23,19 @@ namespace boost {
namespace histogram {
namespace algorithm {
/// Returns a lower-dimensional histogram
// TODO: make generic reduce, which can sum over axes, shrink, rebin
/**
Returns a lower-dimensional histogram, summing over removed axes.
Arguments are the source histogram and compile-time numbers, representing the indices of
axes that are kept. Returns a new histogram which only contains the subset of axes.
The source histogram is summed over the removed axes.
*/
template <typename A, typename S, std::size_t I, typename... Ns>
auto project(const histogram<A, S>& h, mp11::mp_size_t<I> n, Ns... ns) {
// TODO: check that n's are unique
using LN = mp11::mp_list<mp11::mp_size_t<I>, Ns...>;
static_assert(mp11::mp_is_set<LN>::value, "indices must be unique");
const auto& axes = unsafe_access::axes(h);
auto r_axes = detail::make_sub_axes(axes, n, ns...);
@ -61,12 +70,16 @@ auto project(const histogram<A, S>& h, mp11::mp_size_t<I> n, Ns... ns) {
return r_h;
}
/// Returns a lower-dimensional histogram
/**
Returns a lower-dimensional histogram, summing over removed axes.
This version accepts an iterator range that represents the indices which are kept.
*/
template <typename A, typename S, typename Iterator,
typename = detail::requires_axis_vector<A>,
typename = detail::requires_iterator<Iterator>>
auto project(const histogram<A, S>& h, Iterator begin, Iterator end) {
// TODO: check that n's are unique
BOOST_ASSERT_MSG(detail::is_set(begin, end), "indices must be unique");
using H = histogram<A, S>;
const auto& axes = unsafe_access::axes(h);

View File

@ -7,17 +7,20 @@
#ifndef BOOST_HISTOGRAM_DETAIL_INDEX_MAPPER_HPP
#define BOOST_HISTOGRAM_DETAIL_INDEX_MAPPER_HPP
#include <array>
#include <boost/container/static_vector.hpp>
#include <boost/histogram/histogram_fwd.hpp>
#include <cstddef>
namespace boost {
namespace histogram {
namespace detail {
class index_mapper : public std::array<std::pair<std::size_t, std::size_t>, 32> {
class index_mapper
: public boost::container::static_vector<std::pair<std::size_t, std::size_t>,
axis::limit> {
public:
std::size_t first = 0, second = 0, ntotal = 1;
index_mapper(std::size_t n) : dims_end(begin() + n) {}
using static_vector<std::pair<std::size_t, std::size_t>, axis::limit>::static_vector;
bool next() {
++first;
@ -31,11 +34,6 @@ public:
}
return first < ntotal;
}
iterator end() { return dims_end; }
private:
iterator dims_end;
};
} // namespace detail
} // namespace histogram

View File

@ -0,0 +1,30 @@
// Copyright 2018 Hans Dembinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_HISTOGRAM_DETAIL_IS_SET_HPP
#define BOOST_HISTOGRAM_DETAIL_IS_SET_HPP
#include <algorithm>
#include <boost/container/static_vector.hpp>
#include <boost/histogram/detail/meta.hpp>
#include <boost/histogram/histogram_fwd.hpp>
namespace boost {
namespace histogram {
namespace detail {
template <class Iterator>
bool is_set(Iterator begin, Iterator end) {
using T = iterator_value_type<Iterator>;
boost::container::static_vector<T, axis::limit> v(begin, end);
std::sort(v.begin(), v.end());
auto end2 = std::unique(v.begin(), v.end());
return static_cast<std::size_t>(std::distance(v.begin(), end2)) == v.size();
}
} // namespace detail
} // namespace histogram
} // namespace boost
#endif

View File

@ -7,12 +7,23 @@
#ifndef BOOST_HISTOGRAM_HISTOGRAM_FWD_HPP
#define BOOST_HISTOGRAM_HISTOGRAM_FWD_HPP
#include <boost/config.hpp>
#include <boost/container/container_fwd.hpp>
namespace boost {
namespace histogram {
namespace axis {
/* Most of the histogram code is generic and works for any number of axes. Buffers with a
* fixed maximum capacity are used in some places, which have a size equal to the rank of
* a histogram. The buffers are statically allocated to improve performance, which means
* that they need a preset maximum capacity. 48 seems like a safe upper limit for the rank
* (you can nevertheless increase it here if necessary): the simplest non-trivial axis has
* 2 bins; even if counters are used which need only a byte of storage per bin, this still
* corresponds to 256 TB of storage.
*/
BOOST_ATTRIBUTE_UNUSED static constexpr unsigned limit = 48;
struct null_type {}; /// empty meta data type
enum class option_type {

View File

@ -282,7 +282,7 @@ struct storage_adaptor : detail::storage_augmentation<T> {
storage_adaptor& operator/=(const double x) { return operator*=(1.0 / x); }
template <typename U, typename = detail::requires_storage<U>>
template <typename U>
bool operator==(const U& u) const {
const auto n = this->size();
if (n != u.size()) return false;