Skip to content

Commit 4787cea

Browse files
committed
Add dedicated HistogramFunctor kernel
1 parent 9c97f38 commit 4787cea

File tree

3 files changed

+111
-38
lines changed

3 files changed

+111
-38
lines changed

dpnp/backend/extensions/statistics/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ set_target_properties(
6767

6868
target_include_directories(
6969
${python_module_name}
70-
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../common
70+
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../ ${CMAKE_CURRENT_SOURCE_DIR}/../common
7171
)
7272

7373
# treat below headers as system to suppress the warnings there during the build

dpnp/backend/extensions/statistics/histogram_common.hpp

Lines changed: 11 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,15 @@
2828

2929
#pragma once
3030

31+
#include <cstddef>
32+
#include <cstdint>
33+
#include <optional>
34+
#include <type_traits>
35+
3136
#include <sycl/sycl.hpp>
3237

3338
#include "ext/common.hpp"
39+
#include "kernels/statistics/histogram.hpp"
3440

3541
namespace dpctl::tensor
3642
{
@@ -277,9 +283,6 @@ bool check_in_bounds(const dT &val, const dT &min, const dT &max)
277283
return !_less(val, min) && !_less(max, val) && !IsNan<dT>::isnan(val);
278284
}
279285

280-
template <typename T, typename HistImpl, typename Edges, typename Weights>
281-
class histogram_kernel;
282-
283286
template <typename T, typename HistImpl, typename Edges, typename Weights>
284287
void submit_histogram(const T *in,
285288
const size_t size,
@@ -291,41 +294,12 @@ void submit_histogram(const T *in,
291294
sycl::nd_range<1> nd_range,
292295
sycl::handler &cgh)
293296
{
294-
cgh.parallel_for<histogram_kernel<T, HistImpl, Edges, Weights>>(
295-
nd_range, [=](sycl::nd_item<1> item) {
296-
auto id = item.get_group_linear_id();
297-
auto lid = item.get_local_linear_id();
298-
auto group = item.get_group();
299-
auto local_size = item.get_local_range(0);
300-
301-
hist.init(item);
302-
edges.init(item);
303-
304-
if constexpr (HistImpl::sync_after_init || Edges::sync_after_init) {
305-
sycl::group_barrier(group, sycl::memory_scope::work_group);
306-
}
307-
308-
auto bounds = edges.get_bounds();
309-
310-
for (uint32_t i = 0; i < WorkPI; ++i) {
311-
auto data_idx = id * WorkPI * local_size + i * local_size + lid;
312-
if (data_idx < size) {
313-
auto *d = &in[data_idx * dims];
314-
315-
if (edges.in_bounds(d, bounds)) {
316-
auto bin = edges.get_bin(item, d, bounds);
317-
auto weight = weights.get(data_idx);
318-
hist.add(item, bin, weight);
319-
}
320-
}
321-
}
322-
323-
if constexpr (HistImpl::sync_before_finalize) {
324-
sycl::group_barrier(group, sycl::memory_scope::work_group);
325-
}
297+
using HistogramKernel =
298+
dpnp::kernels::histogram::HistogramFunctor<T, HistImpl, Edges, Weights>;
326299

327-
hist.finalize(item);
328-
});
300+
cgh.parallel_for<HistogramKernel>(
301+
nd_range,
302+
HistogramKernel(in, size, dims, WorkPI, hist, edges, weights));
329303
}
330304

331305
void validate(const usm_ndarray &sample,
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
//*****************************************************************************
2+
// Copyright (c) 2026, Intel Corporation
3+
// All rights reserved.
4+
//
5+
// Redistribution and use in source and binary forms, with or without
6+
// modification, are permitted provided that the following conditions are met:
7+
// - Redistributions of source code must retain the above copyright notice,
8+
// this list of conditions and the following disclaimer.
9+
// - Redistributions in binary form must reproduce the above copyright notice,
10+
// this list of conditions and the following disclaimer in the documentation
11+
// and/or other materials provided with the distribution.
12+
// - Neither the name of the copyright holder nor the names of its contributors
13+
// may be used to endorse or promote products derived from this software
14+
// without specific prior written permission.
15+
//
16+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20+
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26+
// THE POSSIBILITY OF SUCH DAMAGE.
27+
//*****************************************************************************
28+
29+
#pragma once
30+
31+
#include <cstddef>
32+
#include <cstdint>
33+
34+
#include <sycl/sycl.hpp>
35+
36+
namespace dpnp::kernels::histogram
37+
{
38+
template <typename T, typename HistImpl, typename Edges, typename Weights>
39+
class HistogramFunctor
40+
{
41+
private:
42+
const T *in = nullptr;
43+
const std::size_t size;
44+
const std::size_t dims;
45+
const std::uint32_t WorkPI;
46+
const HistImpl hist;
47+
const Edges edges;
48+
const Weights weights;
49+
50+
public:
51+
HistogramFunctor(const T *in_,
52+
const std::size_t size_,
53+
const std::size_t dims_,
54+
const std::uint32_t WorkPI_,
55+
const HistImpl &hist_,
56+
const Edges &edges_,
57+
const Weights &weights_)
58+
: in(in_), size(size_), dims(dims_), WorkPI(WorkPI_), hist(hist_),
59+
edges(edges_), weights(weights_)
60+
{
61+
}
62+
63+
void operator()(sycl::nd_item<1> item) const
64+
{
65+
auto id = item.get_group_linear_id();
66+
auto lid = item.get_local_linear_id();
67+
auto group = item.get_group();
68+
auto local_size = item.get_local_range(0);
69+
70+
hist.init(item);
71+
edges.init(item);
72+
73+
if constexpr (HistImpl::sync_after_init || Edges::sync_after_init) {
74+
sycl::group_barrier(group, sycl::memory_scope::work_group);
75+
}
76+
77+
auto bounds = edges.get_bounds();
78+
79+
for (uint32_t i = 0; i < WorkPI; ++i) {
80+
auto data_idx = id * WorkPI * local_size + i * local_size + lid;
81+
if (data_idx < size) {
82+
auto *d = &in[data_idx * dims];
83+
84+
if (edges.in_bounds(d, bounds)) {
85+
auto bin = edges.get_bin(item, d, bounds);
86+
auto weight = weights.get(data_idx);
87+
hist.add(item, bin, weight);
88+
}
89+
}
90+
}
91+
92+
if constexpr (HistImpl::sync_before_finalize) {
93+
sycl::group_barrier(group, sycl::memory_scope::work_group);
94+
}
95+
96+
hist.finalize(item);
97+
}
98+
};
99+
} // namespace dpnp::kernels::histogram

0 commit comments

Comments
 (0)