From b78688afe17f0798e0627c01404a5dfb127c8176 Mon Sep 17 00:00:00 2001 From: Henry Fredrick Schreiner Date: Tue, 17 Dec 2019 17:55:15 -0500 Subject: [PATCH 1/2] Use integer fill for integer storages (avoid a conversion to double) --- include/bh_python/fill.hpp | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/include/bh_python/fill.hpp b/include/bh_python/fill.hpp index d2262f62d..78773ec9c 100644 --- a/include/bh_python/fill.hpp +++ b/include/bh_python/fill.hpp @@ -101,8 +101,8 @@ using arg_t = variant::variant, int, c_array_t, std::string>; - -using weight_t = variant::variant>; +template +using weight_t = variant::variant>; inline auto get_vargs(const vector_axis_variant& axes, const py::args& args) { if(args.size() != axes.size()) @@ -131,25 +131,26 @@ inline auto get_vargs(const vector_axis_variant& axes, const py::args& args) { return vargs; } -inline auto get_weight(py::kwargs& kwargs) { +template +auto get_weight(py::kwargs& kwargs) { // default constructed as monostate to indicate absence of weight - variant::variant> weight; + weight_t weight; auto w = optional_arg(kwargs, "weight"); if(!w.is_none()) { - if(is_value(w)) - weight = py::cast(w); + if(is_value(w)) + weight = py::cast(w); else - weight = py::cast>(w); + weight = py::cast>(w); } return weight; } // for accumulators that accept a weight -template +template void fill_impl(bh::detail::accumulator_traits_holder, Histogram& h, const VArgs& vargs, - const weight_t& weight, + const weight_t& weight, py::kwargs& kwargs) { none_only_arg(kwargs, "sample"); finalize_args(kwargs); @@ -163,11 +164,11 @@ void fill_impl(bh::detail::accumulator_traits_holder, } // for accumulators that accept a weight and a double -template +template void fill_impl(bh::detail::accumulator_traits_holder, Histogram& h, const VArgs& vargs, - const weight_t& weight, + const weight_t& weight, py::kwargs& kwargs) { auto s = required_arg(kwargs, "sample"); finalize_args(kwargs); @@ -192,10 +193,14 @@ void fill_impl(bh::detail::accumulator_traits_holder, template Histogram& fill(Histogram& self, py::args args, py::kwargs kwargs) { using value_type = typename Histogram::value_type; - detail::fill_impl(bh::detail::accumulator_traits{}, - self, - detail::get_vargs(bh::unsafe_access::axes(self), args), - detail::get_weight(kwargs), - kwargs); + using weight_type + = boost::mp11::mp_if_c::value, int, double>; + + detail::fill_impl( + bh::detail::accumulator_traits{}, + self, + detail::get_vargs(bh::unsafe_access::axes(self), args), + detail::get_weight(kwargs), + kwargs); return self; } From 7278aa84b1563c2c02c0290174f47dec8464f086 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 9 Feb 2021 12:44:44 -0500 Subject: [PATCH 2/2] wip: still convering --- src/boost_histogram/_internal/hist.py | 8 ++++---- src/boost_histogram/_internal/sig_tools.py | 1 + tests/test_histogram.py | 6 ++++++ tests/test_numpy_interface.py | 4 ++-- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/boost_histogram/_internal/hist.py b/src/boost_histogram/_internal/hist.py index a66dff0dc..4cf4902d4 100644 --- a/src/boost_histogram/_internal/hist.py +++ b/src/boost_histogram/_internal/hist.py @@ -44,7 +44,7 @@ def _fill_cast(value, inner=False): """ - Convert to NumPy arrays. Some buffer objects do not get converted by forcecast. + Convert to NumPy arrays; must be c-order dense arrays to work. If not called by itself (inner=False), then will work through one level of tuple/list. """ if value is None or isinstance(value, string_types + (bytes,)): @@ -340,9 +340,9 @@ def fill(self, *args, **kwargs): # noqa: C901 ---------- *args : Union[Array[float], Array[int], Array[str], float, int, str] Provide one value or array per dimension. - weight : List[Union[Array[float], Array[int], Array[str], float, int, str]]] - Provide weights (only if the histogram storage supports it) - sample : List[Union[Array[float], Array[int], Array[str], float, int, str]]] + weight : List[Union[Array[float], Array[int], float, int]]] + Provide weights (float only if the histogram storage supports it) + sample : List[Union[Array[float], Array[int], float, int]]] Provide samples (only if the histogram storage supports it) threads : Optional[int] Fill with threads. Defaults to None, which does not activate diff --git a/src/boost_histogram/_internal/sig_tools.py b/src/boost_histogram/_internal/sig_tools.py index f166d72e6..5ab80b187 100644 --- a/src/boost_histogram/_internal/sig_tools.py +++ b/src/boost_histogram/_internal/sig_tools.py @@ -15,6 +15,7 @@ def inject_signature(sig, locals=None): # type: (str, Optional[Dict[str, Any]]) -> Any def wrap(f): return f + return wrap diff --git a/tests/test_histogram.py b/tests/test_histogram.py index 32676a230..eb49984e6 100644 --- a/tests/test_histogram.py +++ b/tests/test_histogram.py @@ -73,6 +73,12 @@ def test_copy(): assert id(b) != id(c) +def test_fill_int_storage_with_floats(): + h = bh.Histogram(bh.axis.Regular(10,-1,1), storage=bh.storage.Int64()) + h.fill([.3,.4,.5], weight=[1, 3, 2]) + h.fill([.3,.4,.5], weight=[.1, .3, .2]) + + def test_fill_int_1d(): h = bh.Histogram(bh.axis.Integer(-1, 2)) diff --git a/tests/test_numpy_interface.py b/tests/test_numpy_interface.py index e290a5651..e85bf69c0 100644 --- a/tests/test_numpy_interface.py +++ b/tests/test_numpy_interface.py @@ -31,9 +31,9 @@ {"bins": 10}, {"bins": "auto" if np113 else 20}, {"range": (0, 5), "bins": 30}, - {"range": np.array((0, 5), dtype=np.float), "bins": np.int32(30)}, + {"range": np.array((0, 5), dtype=float), "bins": np.int32(30)}, {"range": np.array((0, 3), dtype=np.double), "bins": np.uint32(10)}, - {"range": np.array((0, 10), dtype=np.int), "bins": np.int8(30)}, + {"range": np.array((0, 10), dtype=int), "bins": np.int8(30)}, {"bins": [0, 1, 1.2, 1.3, 4, 21]}, )