4
4
// SPDX-License-Identifier: MIT
5
5
// =============================================================
6
6
7
- # include < oneapi/dpl/execution >
7
+ // oneDPL headers should be included before standard headers
8
8
#include < oneapi/dpl/algorithm>
9
+ #include < oneapi/dpl/execution>
9
10
#include < oneapi/dpl/numeric>
11
+
10
12
#include < CL/sycl.hpp>
11
- #include < random>
12
13
#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>
17
15
18
16
// Dense algorithm stores all the bins, even if bin has 0 entries
19
17
// input array [4,4,1,0,1,2]
24
22
25
23
void dense_histogram (std::vector<uint64_t > &input) {
26
24
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)};
29
26
30
27
// Combine the equal values together
31
28
std::sort (oneapi::dpl::execution::dpcpp_default,
@@ -37,8 +34,7 @@ void dense_histogram(std::vector<uint64_t> &input) {
37
34
sycl::host_accessor histogram (histogram_buf, sycl::read_only);
38
35
num_bins = histogram[N - 1 ] + 1 ;
39
36
}
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)};
42
38
auto val_begin = oneapi::dpl::counting_iterator<int >{0 };
43
39
44
40
// Determine the end of each bin of value
@@ -51,11 +47,11 @@ void dense_histogram(std::vector<uint64_t> &input) {
51
47
std::adjacent_difference (oneapi::dpl::execution::dpcpp_default,
52
48
oneapi::dpl::begin (histogram_new_buf),
53
49
oneapi::dpl::end (histogram_new_buf),
54
- oneapi::dpl::begin (bins ));
50
+ oneapi::dpl::begin (histogram_new_buf ));
55
51
56
- std::cout << " Dense Histogram:\n " ;
52
+ std::cout << " success for Dense Histogram:\n " ;
57
53
{
58
- sycl::host_accessor histogram_new (bins , sycl::read_only);
54
+ sycl::host_accessor histogram_new (histogram_new_buf , sycl::read_only);
59
55
std::cout << " [" ;
60
56
for (int i = 0 ; i < num_bins; i++) {
61
57
std::cout << " (" << i << " , " << histogram_new[i] << " ) " ;
@@ -66,64 +62,60 @@ void dense_histogram(std::vector<uint64_t> &input) {
66
62
67
63
void sparse_histogram (std::vector<uint64_t > &input) {
68
64
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)};
71
66
72
67
// Combine the equal values together
73
68
std::sort (oneapi::dpl::execution::dpcpp_default,
74
69
oneapi::dpl::begin (histogram_buf), oneapi::dpl::end (histogram_buf));
75
70
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)};
86
77
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)};
88
79
std::fill (oneapi::dpl::execution::dpcpp_default,
89
80
oneapi::dpl::begin (_const_buf), oneapi::dpl::end (_const_buf), 1 );
90
81
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
+
91
85
// Find the count of each value
92
- oneapi::dpl::reduce_by_segment (
86
+ const auto result = oneapi::dpl::reduce_by_segment (
93
87
oneapi::dpl::execution::dpcpp_default, oneapi::dpl::begin (histogram_buf),
94
88
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);
97
94
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);
99
98
std::cout << " [" ;
100
99
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
+ << " ) " ;
105
102
}
106
103
std::cout << " ]\n " ;
107
104
}
108
105
109
106
int main (void ) {
110
107
const int N = 1000 ;
111
- std::vector<uint64_t > input, dense, sparse ;
108
+ std::vector<uint64_t > input;
112
109
srand ((unsigned )time (0 ));
113
110
// initialize the input array with randomly generated values between 0 and 9
114
111
for (int i = 0 ; i < N; i++) input.push_back (rand () % 9 );
115
112
116
113
// 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,
118
115
// which shows the difference between sparse and dense algorithm output
119
116
for (int i = 0 ; i < N; i++)
120
117
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);
128
120
return 0 ;
129
121
}
0 commit comments