1 #define BOOST_TEST_MODULE ReduceByKey
2 #include <algorithm>
3 #include <numeric>
4 #include <boost/test/unit_test.hpp>
5 #include <vexcl/vector.hpp>
6 #include <vexcl/scan_by_key.hpp>
7 #include "context_setup.hpp"
8 
nvidia_cl(const vex::Context & ctx)9 bool nvidia_cl(const vex::Context &ctx) {
10 #if defined(VEXCL_BACKEND_CUDA) || defined(VEXCL_BACKEND_JIT)
11     return false;
12 #else
13     return vex::Filter::Platform("NVIDIA")(ctx.device(0));
14 #endif
15 }
16 
BOOST_AUTO_TEST_CASE(sbk)17 BOOST_AUTO_TEST_CASE(sbk)
18 {
19     // NVIDIA OpenCL compiler crashes on scan_by_key kernels.
20     if (nvidia_cl(ctx)) return;
21 
22     const int n = 1000;
23 
24     std::vector<int> x = random_vector<int>(n);
25     std::vector<int> y = random_vector<int>(n);
26 
27     std::sort(x.begin(), x.end());
28 
29     std::vector<vex::backend::command_queue> queue(1, ctx.queue(0));
30 
31     vex::vector<int> ikeys(queue, x);
32     vex::vector<int> ivals(queue, y);
33     vex::vector<int> ovals(queue, n);
34 
35     vex::inclusive_scan_by_key(ikeys, ivals, ovals);
36 
37     check_sample(ovals, [&](size_t i, int v) {
38             if (i == 0)
39                 BOOST_CHECK_EQUAL(v, y[i]);
40             else if (x[i-1] == x[i])
41                 BOOST_CHECK_EQUAL(
42                     y[i],
43                     static_cast<int>(ovals[i]) - static_cast<int>(ovals[i-1])
44                     );
45             else
46                 BOOST_CHECK_EQUAL(v, y[i]);
47             });
48 
49     vex::exclusive_scan_by_key(ikeys, ivals, ovals);
50 
51     check_sample(ovals, [&](size_t i, int v) {
52             if (i == 0)
53                 BOOST_CHECK_EQUAL(v, 0);
54             else if (x[i-1] == x[i])
55                 BOOST_CHECK_EQUAL(
56                     y[i-1],
57                     static_cast<int>(ovals[i]) - static_cast<int>(ovals[i-1])
58                     );
59             else
60                 BOOST_CHECK_EQUAL(v, 0);
61             });
62 }
63 
BOOST_AUTO_TEST_CASE(sbk_tuple)64 BOOST_AUTO_TEST_CASE(sbk_tuple)
65 {
66     // NVIDIA OpenCL compiler crashes on scan_by_key kernels.
67     if (nvidia_cl(ctx)) return;
68 
69     const int n = 1000;
70 
71     std::vector<int> x1 = random_vector<int>(n);
72     std::vector<int> x2 = random_vector<int>(n);
73     std::vector<int> y  = random_vector<int>(n);
74 
75     std::sort(x1.begin(), x1.end());
76     std::sort(x2.begin(), x2.end());
77 
78     std::vector<vex::backend::command_queue> queue(1, ctx.queue(0));
79 
80     vex::vector<int> ikey1(queue, x1);
81     vex::vector<int> ikey2(queue, x2);
82     vex::vector<int> ivals(queue, y);
83     vex::vector<int> ovals(queue, n);
84 
85     VEX_FUNCTION(bool, equal, (int, a1)(int, a2)(int, b1)(int, b2),
86             return a1 == b1 && a2 == b2;
87             );
88 
89     VEX_FUNCTION(int, plus, (int, x)(int, y),
90             return x + y;
91             );
92 
93     vex::inclusive_scan_by_key(
94             boost::fusion::vector_tie(ikey1, ikey2), ivals, ovals,
95             equal, plus);
96 
97     check_sample(ovals, [&](size_t i, int v) {
98             if (i == 0)
99                 BOOST_CHECK_EQUAL(v, y[i]);
100             else if (std::make_tuple(x1[i-1], x2[i-1]) == std::make_tuple(x1[i], x2[i]))
101                 BOOST_CHECK_EQUAL(
102                     y[i],
103                     static_cast<int>(ovals[i]) - static_cast<int>(ovals[i-1])
104                     );
105             else
106                 BOOST_CHECK_EQUAL(v, y[i]);
107             });
108 
109     vex::exclusive_scan_by_key(
110             boost::fusion::vector_tie(ikey1, ikey2), ivals, ovals,
111             equal, plus);
112 
113     check_sample(ovals, [&](size_t i, int v) {
114             if (i == 0)
115                 BOOST_CHECK_EQUAL(v, 0);
116             else if (std::make_tuple(x1[i-1], x2[i-1]) == std::make_tuple(x1[i], x2[i]))
117                 BOOST_CHECK_EQUAL(
118                     y[i-1],
119                     static_cast<int>(ovals[i]) - static_cast<int>(ovals[i-1])
120                     );
121             else
122                 BOOST_CHECK_EQUAL(v, 0);
123             });
124 }
125 
126 BOOST_AUTO_TEST_SUITE_END()
127