Skip to content

Commit 457664f

Browse files
Fix errors in histogram example (oneapi-src#1011)
* Fix errors in histogram example * Copy example 1:1 from https://github.com/oneapi-src/oneDPL/tree/main/examples/histogram
1 parent e8f4ebe commit 457664f

File tree

1 file changed

+35
-43
lines changed
  • DirectProgramming/DPC++/ParallelPatterns/histogram/src

1 file changed

+35
-43
lines changed

DirectProgramming/DPC++/ParallelPatterns/histogram/src/main.cpp

Lines changed: 35 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,14 @@
44
// SPDX-License-Identifier: MIT
55
// =============================================================
66

7-
#include <oneapi/dpl/execution>
7+
// oneDPL headers should be included before standard headers
88
#include <oneapi/dpl/algorithm>
9+
#include <oneapi/dpl/execution>
910
#include <oneapi/dpl/numeric>
11+
1012
#include <CL/sycl.hpp>
11-
#include <random>
1213
#include <iostream>
13-
14-
// dpc_common.hpp can be found in the dev-utilities include folder.
15-
// e.g., $ONEAPI_ROOT/dev-utilities//include/dpc_common.hpp
16-
#include "dpc_common.hpp"
14+
#include <random>
1715

1816
// Dense algorithm stores all the bins, even if bin has 0 entries
1917
// input array [4,4,1,0,1,2]
@@ -24,8 +22,7 @@
2422

2523
void dense_histogram(std::vector<uint64_t> &input) {
2624
const int N = input.size();
27-
cl::sycl::buffer<uint64_t, 1> histogram_buf{input.data(),
28-
cl::sycl::range<1>(N)};
25+
sycl::buffer<uint64_t> histogram_buf{input.data(), sycl::range<1>(N)};
2926

3027
// Combine the equal values together
3128
std::sort(oneapi::dpl::execution::dpcpp_default,
@@ -37,8 +34,7 @@ void dense_histogram(std::vector<uint64_t> &input) {
3734
sycl::host_accessor histogram(histogram_buf, sycl::read_only);
3835
num_bins = histogram[N - 1] + 1;
3936
}
40-
cl::sycl::buffer<uint64_t, 1> histogram_new_buf{cl::sycl::range<1>(num_bins)};
41-
cl::sycl::buffer<uint64_t, 1> bins{cl::sycl::range<1>(num_bins)};
37+
sycl::buffer<uint64_t> histogram_new_buf{sycl::range<1>(num_bins)};
4238
auto val_begin = oneapi::dpl::counting_iterator<int>{0};
4339

4440
// Determine the end of each bin of value
@@ -51,11 +47,11 @@ void dense_histogram(std::vector<uint64_t> &input) {
5147
std::adjacent_difference(oneapi::dpl::execution::dpcpp_default,
5248
oneapi::dpl::begin(histogram_new_buf),
5349
oneapi::dpl::end(histogram_new_buf),
54-
oneapi::dpl::begin(bins));
50+
oneapi::dpl::begin(histogram_new_buf));
5551

56-
std::cout << "Dense Histogram:\n";
52+
std::cout << "success for Dense Histogram:\n";
5753
{
58-
sycl::host_accessor histogram_new(bins, sycl::read_only);
54+
sycl::host_accessor histogram_new(histogram_new_buf, sycl::read_only);
5955
std::cout << "[";
6056
for (int i = 0; i < num_bins; i++) {
6157
std::cout << "(" << i << ", " << histogram_new[i] << ") ";
@@ -66,64 +62,60 @@ void dense_histogram(std::vector<uint64_t> &input) {
6662

6763
void sparse_histogram(std::vector<uint64_t> &input) {
6864
const int N = input.size();
69-
cl::sycl::buffer<uint64_t, 1> histogram_buf{input.data(),
70-
cl::sycl::range<1>(N)};
65+
sycl::buffer<uint64_t> histogram_buf{input.data(), sycl::range<1>(N)};
7166

7267
// Combine the equal values together
7368
std::sort(oneapi::dpl::execution::dpcpp_default,
7469
oneapi::dpl::begin(histogram_buf), oneapi::dpl::end(histogram_buf));
7570

76-
auto num_bins = std::transform_reduce(
77-
oneapi::dpl::execution::dpcpp_default, oneapi::dpl::begin(histogram_buf),
78-
oneapi::dpl::end(histogram_buf) - 1, oneapi::dpl::begin(histogram_buf) + 1, 1,
79-
std::plus<int>(), std::not_equal_to<int>());
80-
81-
// Create new buffer to store the unique values and their count
82-
cl::sycl::buffer<uint64_t, 1> histogram_values_buf{
83-
cl::sycl::range<1>(num_bins)};
84-
cl::sycl::buffer<uint64_t, 1> histogram_counts_buf{
85-
cl::sycl::range<1>(num_bins)};
71+
// Create new buffer to store the unique valuesand their count;
72+
// oneapi::dpl::reduce_by_segment requires a sufficient buffer size(for worst case).
73+
// TODO: To consider usage of just 'sort' and 'transform_reduce' for calculate
74+
// a final result.There is a guess that such approach is more effective.
75+
sycl::buffer<uint64_t> histogram_values_buf{sycl::range<1>(N)};
76+
sycl::buffer<uint64_t> histogram_counts_buf{sycl::range<1>(N)};
8677

87-
cl::sycl::buffer<uint64_t, 1> _const_buf{cl::sycl::range<1>(N)};
78+
sycl::buffer<uint64_t> _const_buf{sycl::range<1>(N)};
8879
std::fill(oneapi::dpl::execution::dpcpp_default,
8980
oneapi::dpl::begin(_const_buf), oneapi::dpl::end(_const_buf), 1);
9081

82+
auto histogram_values_buf_begin = oneapi::dpl::begin(histogram_values_buf);
83+
auto histogram_counts_buf_begin = oneapi::dpl::begin(histogram_counts_buf);
84+
9185
// Find the count of each value
92-
oneapi::dpl::reduce_by_segment(
86+
const auto result = oneapi::dpl::reduce_by_segment(
9387
oneapi::dpl::execution::dpcpp_default, oneapi::dpl::begin(histogram_buf),
9488
oneapi::dpl::end(histogram_buf), oneapi::dpl::begin(_const_buf),
95-
oneapi::dpl::begin(histogram_values_buf),
96-
oneapi::dpl::begin(histogram_counts_buf));
89+
histogram_values_buf_begin,
90+
histogram_counts_buf_begin);
91+
92+
const auto num_bins = result.first - histogram_values_buf_begin;
93+
assert(num_bins == result.second - histogram_counts_buf_begin);
9794

98-
std::cout << "Sparse Histogram:\n";
95+
std::cout << "success for Sparse Histogram:\n";
96+
sycl::host_accessor histogram_value(histogram_values_buf, sycl::read_only);
97+
sycl::host_accessor histogram_count(histogram_counts_buf, sycl::read_only);
9998
std::cout << "[";
10099
for (int i = 0; i < num_bins; i++) {
101-
sycl::host_accessor histogram_value(histogram_values_buf, sycl::read_only);
102-
sycl::host_accessor histogram_count(histogram_counts_buf, sycl::read_only);
103-
std::cout << "(" << histogram_value[i] << ", " << histogram_count[i]
104-
<< ") ";
100+
std::cout << "(" << histogram_value[i] << ", " << histogram_count[i]
101+
<< ") ";
105102
}
106103
std::cout << "]\n";
107104
}
108105

109106
int main(void) {
110107
const int N = 1000;
111-
std::vector<uint64_t> input, dense, sparse;
108+
std::vector<uint64_t> input;
112109
srand((unsigned)time(0));
113110
// initialize the input array with randomly generated values between 0 and 9
114111
for (int i = 0; i < N; i++) input.push_back(rand() % 9);
115112

116113
// replacing all input entries of "4" with random number between 1 and 3
117-
// this is to ensure that we have atleast one entry with zero-bin size,
114+
// this is to ensure that we have at least one entry with zero-bin size,
118115
// which shows the difference between sparse and dense algorithm output
119116
for (int i = 0; i < N; i++)
120117
if (input[i] == 4) input[i] = rand() % 3;
121-
std::cout << "Input:\n";
122-
for (int i = 0; i < N; i++) std::cout << input[i] << " ";
123-
std::cout << "\n";
124-
dense = input;
125-
dense_histogram(dense);
126-
sparse = input;
127-
sparse_histogram(sparse);
118+
dense_histogram(input);
119+
sparse_histogram(input);
128120
return 0;
129121
}

0 commit comments

Comments
 (0)