• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2015 Jakub Szuppe <j.szuppe@gmail.com>
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
10 
11 #define BOOST_TEST_MODULE TestReduceByKey
12 #include <boost/test/unit_test.hpp>
13 
14 #include <boost/compute/lambda.hpp>
15 #include <boost/compute/system.hpp>
16 #include <boost/compute/functional.hpp>
17 #include <boost/compute/algorithm/inclusive_scan.hpp>
18 #include <boost/compute/algorithm/reduce_by_key.hpp>
19 #include <boost/compute/container/vector.hpp>
20 
21 #include "check_macros.hpp"
22 #include "context_setup.hpp"
23 
24 namespace bc = boost::compute;
25 
BOOST_AUTO_TEST_CASE(reduce_by_key_int)26 BOOST_AUTO_TEST_CASE(reduce_by_key_int)
27 {
28 //! [reduce_by_key_int]
29 // setup keys and values
30 int keys[] = { 0, 2, -3, -3, -3, -3, -3, 4 };
31 int data[] = { 1, 1, 1, 1, 1, 2, 5, 1 };
32 
33 boost::compute::vector<int> keys_input(keys, keys + 8, queue);
34 boost::compute::vector<int> values_input(data, data + 8, queue);
35 
36 boost::compute::vector<int> keys_output(8, context);
37 boost::compute::vector<int> values_output(8, context);
38 // reduce by key
39 boost::compute::reduce_by_key(keys_input.begin(), keys_input.end(), values_input.begin(),
40                               keys_output.begin(), values_output.begin(), queue);
41 // keys_output = { 0, 2, -3, 4 }
42 // values_output = { 1, 1, 10, 1 }
43 //! [reduce_by_key_int]
44     CHECK_RANGE_EQUAL(int, 4, keys_output,   (0, 2, -3,  4));
45     CHECK_RANGE_EQUAL(int, 4, values_output, (1, 1, 10, 1));
46 }
47 
BOOST_AUTO_TEST_CASE(reduce_by_key_int_long_vector)48 BOOST_AUTO_TEST_CASE(reduce_by_key_int_long_vector)
49 {
50     size_t size = 1024;
51     bc::vector<int> keys_input(size, int(0), queue);
52     bc::vector<int> values_input(size, int(1), queue);
53 
54     bc::vector<int> keys_output(size, context);
55     bc::vector<int> values_output(size, context);
56 
57     bc::reduce_by_key(keys_input.begin(), keys_input.end(), values_input.begin(),
58                       keys_output.begin(), values_output.begin(), queue);
59 
60     CHECK_RANGE_EQUAL(int, 1, keys_output,   (0));
61     CHECK_RANGE_EQUAL(int, 1, values_output, (static_cast<int>(size)));
62 
63     keys_input[137] = 1;
64     keys_input[677] = 1;
65     keys_input[1001] = 1;
66     bc::inclusive_scan(keys_input.begin(), keys_input.end(), keys_input.begin(), queue);
67 
68     bc::reduce_by_key(keys_input.begin(), keys_input.end(), values_input.begin(),
69                       keys_output.begin(), values_output.begin(), queue);
70 
71     CHECK_RANGE_EQUAL(int, 4, keys_output,   (0, 1, 2, 3));
72     CHECK_RANGE_EQUAL(int, 4, values_output, (137, 540, 324, 23));
73 }
74 
BOOST_AUTO_TEST_CASE(reduce_by_key_empty_vector)75 BOOST_AUTO_TEST_CASE(reduce_by_key_empty_vector)
76 {
77     bc::vector<int> keys_input(context);
78     bc::vector<int> values_input(context);
79 
80     bc::vector<int> keys_output(context);
81     bc::vector<int> values_output(context);
82 
83     bc::reduce_by_key(keys_input.begin(), keys_input.end(), values_input.begin(),
84                       keys_output.begin(), values_output.begin(), queue);
85 
86     BOOST_CHECK(keys_output.empty());
87     BOOST_CHECK(values_output.empty());
88 }
89 
BOOST_AUTO_TEST_CASE(reduce_by_key_int_one_key_value)90 BOOST_AUTO_TEST_CASE(reduce_by_key_int_one_key_value)
91 {
92     int keys[] = { 22 };
93     int data[] = { -9 };
94 
95     bc::vector<int> keys_input(keys, keys + 1, queue);
96     bc::vector<int> values_input(data, data + 1, queue);
97 
98     bc::vector<int> keys_output(1, context);
99     bc::vector<int> values_output(1, context);
100 
101     bc::reduce_by_key(keys_input.begin(), keys_input.end(), values_input.begin(),
102                       keys_output.begin(), values_output.begin(), queue);
103 
104     CHECK_RANGE_EQUAL(int, 1, keys_output,   (22));
105     CHECK_RANGE_EQUAL(int, 1, values_output, (-9));
106 }
107 
BOOST_AUTO_TEST_CASE(reduce_by_key_int_min_max)108 BOOST_AUTO_TEST_CASE(reduce_by_key_int_min_max)
109 {
110     int keys[] = { 0, 2, 2, 3, 3, 3, 3, 3, 4 };
111     int data[] = { 1, 2, 1, -3, 1, 4, 2, 5, 77 };
112 
113     bc::vector<int> keys_input(keys, keys + 9, queue);
114     bc::vector<int> values_input(data, data + 9, queue);
115 
116     bc::vector<int> keys_output(9, context);
117     bc::vector<int> values_output(9, context);
118 
119     bc::reduce_by_key(keys_input.begin(), keys_input.end(), values_input.begin(),
120                       keys_output.begin(), values_output.begin(), bc::min<int>(),
121                       bc::equal_to<int>(), queue);
122 
123     CHECK_RANGE_EQUAL(int, 4, keys_output,   (0, 2, 3,  4));
124     CHECK_RANGE_EQUAL(int, 4, values_output, (1, 1, -3, 77));
125 
126     bc::reduce_by_key(keys_input.begin(), keys_input.end(), values_input.begin(),
127                       keys_output.begin(), values_output.begin(), bc::max<int>(),
128                       bc::equal_to<int>(), queue);
129 
130     CHECK_RANGE_EQUAL(int, 4, keys_output,   (0, 2, 3,  4));
131     CHECK_RANGE_EQUAL(int, 4, values_output, (1, 2, 5, 77));
132 }
133 
BOOST_AUTO_TEST_CASE(reduce_by_key_float_max)134 BOOST_AUTO_TEST_CASE(reduce_by_key_float_max)
135 {
136     int keys[] = { 0, 2, 2, 3, 3, 3, 3, 3, 4 };
137     float data[] = { 1.0, 2.0, -1.5, -3.0, 1.0, -0.24, 2, 5, 77.1 };
138 
139     bc::vector<int> keys_input(keys, keys + 9, queue);
140     bc::vector<float> values_input(data, data + 9, queue);
141 
142     bc::vector<int> keys_output(9, context);
143     bc::vector<float> values_output(9, context);
144 
145     bc::reduce_by_key(keys_input.begin(), keys_input.end(), values_input.begin(),
146                       keys_output.begin(), values_output.begin(), bc::max<float>(),
147                       queue);
148 
149     CHECK_RANGE_EQUAL(int, 4, keys_output, (0, 2, 3, 4));
150     BOOST_CHECK_CLOSE(float(values_output[0]), 1.0f, 1e-4f);
151     BOOST_CHECK_CLOSE(float(values_output[1]), 2.0f, 1e-4f);
152     BOOST_CHECK_CLOSE(float(values_output[2]), 5.0f, 1e-4f);
153     BOOST_CHECK_CLOSE(float(values_output[3]), 77.1f, 1e-4f);
154 }
155 
BOOST_AUTO_TEST_CASE(reduce_by_key_int2)156 BOOST_AUTO_TEST_CASE(reduce_by_key_int2)
157 {
158     using bc::int2_;
159 
160     int keys[] = { 0, 2, 3, 3, 3, 3, 4, 4 };
161     int2_ data[] = {
162         int2_(0, 1), int2_(-3, 2), int2_(0, 1), int2_(0, 1),
163         int2_(-3, 0), int2_(0, 0), int2_(-3, 2), int2_(-7, -2)
164     };
165 
166     bc::vector<int> keys_input(keys, keys + 8, queue);
167     bc::vector<int2_> values_input(data, data + 8, queue);
168 
169     bc::vector<int> keys_output(8, context);
170     bc::vector<int2_> values_output(8, context);
171 
172     bc::reduce_by_key(keys_input.begin(), keys_input.end(), values_input.begin(),
173                       keys_output.begin(), values_output.begin(), queue);
174 
175     CHECK_RANGE_EQUAL(int, 4, keys_output, (0, 2, 3, 4));
176     CHECK_RANGE_EQUAL(int2_, 4, values_output,
177         (int2_(0, 1), int2_(-3, 2), int2_(-3, 2), int2_(-10, 0)));
178 }
179 
BOOST_AUTO_TEST_CASE(reduce_by_key_int2_long_vector)180 BOOST_AUTO_TEST_CASE(reduce_by_key_int2_long_vector)
181 {
182     using bc::int2_;
183 
184     size_t size = 1024;
185     bc::vector<int> keys_input(size, int(0), queue);
186     bc::vector<int2_> values_input(size, int2_(1, -1), queue);
187 
188     bc::vector<int> keys_output(size, context);
189     bc::vector<int2_> values_output(size, context);
190 
191     bc::reduce_by_key(keys_input.begin(), keys_input.end(), values_input.begin(),
192                       keys_output.begin(), values_output.begin(), queue);
193 
194     CHECK_RANGE_EQUAL(int, 1, keys_output,   (0));
195     CHECK_RANGE_EQUAL(int2_, 1, values_output, (int2_(int(size), -int(size))));
196 
197     keys_input[137] = 1;
198     keys_input[677] = 1;
199     keys_input[1001] = 1;
200     bc::inclusive_scan(keys_input.begin(), keys_input.end(), keys_input.begin(), queue);
201 
202     bc::reduce_by_key(keys_input.begin(), keys_input.end(), values_input.begin(),
203                       keys_output.begin(), values_output.begin(), queue);
204 
205     CHECK_RANGE_EQUAL(int, 4, keys_output,   (0, 1, 2, 3));
206     CHECK_RANGE_EQUAL(int2_, 4, values_output,
207         (int2_(137, -137), int2_(540, -540), int2_(324, -324), int2_(23, -23)));
208 }
209 
210 BOOST_AUTO_TEST_SUITE_END()
211