• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@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 TestZipIterator
12 #include <boost/test/unit_test.hpp>
13 
14 #include <boost/type_traits.hpp>
15 #include <boost/static_assert.hpp>
16 #include <boost/tuple/tuple_io.hpp>
17 #include <boost/tuple/tuple_comparison.hpp>
18 
19 #include <boost/compute/functional.hpp>
20 #include <boost/compute/algorithm/copy.hpp>
21 #include <boost/compute/algorithm/transform.hpp>
22 #include <boost/compute/container/vector.hpp>
23 #include <boost/compute/iterator/constant_iterator.hpp>
24 #include <boost/compute/iterator/zip_iterator.hpp>
25 #include <boost/compute/types/tuple.hpp>
26 
27 #include "check_macros.hpp"
28 #include "context_setup.hpp"
29 
30 namespace compute = boost::compute;
31 
BOOST_AUTO_TEST_CASE(value_type)32 BOOST_AUTO_TEST_CASE(value_type)
33 {
34     BOOST_STATIC_ASSERT((
35         boost::is_same<
36             boost::compute::zip_iterator<
37                 boost::tuple<
38                     boost::compute::buffer_iterator<float>,
39                     boost::compute::buffer_iterator<int>
40                 >
41             >::value_type,
42             boost::tuple<float, int>
43         >::value
44     ));
45 }
46 
BOOST_AUTO_TEST_CASE(distance)47 BOOST_AUTO_TEST_CASE(distance)
48 {
49     boost::compute::vector<char> char_vector(5, context);
50     boost::compute::vector<int> int_vector(5, context);
51 
52     BOOST_CHECK_EQUAL(
53         std::distance(
54             boost::compute::make_zip_iterator(
55                 boost::make_tuple(
56                     char_vector.begin(),
57                     int_vector.begin()
58                 )
59             ),
60             boost::compute::make_zip_iterator(
61                 boost::make_tuple(
62                     char_vector.end(),
63                     int_vector.end()
64                 )
65             )
66         ),
67         ptrdiff_t(5)
68     );
69 
70     BOOST_CHECK_EQUAL(
71         std::distance(
72             boost::compute::make_zip_iterator(
73                 boost::make_tuple(
74                     char_vector.begin(),
75                     int_vector.begin()
76                 )
77             ) + 1,
78             boost::compute::make_zip_iterator(
79                 boost::make_tuple(
80                     char_vector.end(),
81                     int_vector.end()
82                 )
83             ) - 1
84         ),
85         ptrdiff_t(3)
86     );
87 
88     BOOST_CHECK_EQUAL(
89         std::distance(
90             boost::compute::make_zip_iterator(
91                 boost::make_tuple(
92                     char_vector.begin() + 2,
93                     int_vector.begin() + 2
94                 )
95             ),
96             boost::compute::make_zip_iterator(
97                 boost::make_tuple(
98                     char_vector.end() - 1,
99                     int_vector.end() - 1
100                 )
101             )
102         ),
103         ptrdiff_t(2)
104     );
105 }
106 
BOOST_AUTO_TEST_CASE(copy)107 BOOST_AUTO_TEST_CASE(copy)
108 {
109     // create three separate vectors of three different types
110     char char_data[] = { 'x', 'y', 'z' };
111     boost::compute::vector<char> char_vector(char_data, char_data + 3, queue);
112 
113     int int_data[] = { 4, 7, 9 };
114     boost::compute::vector<int> int_vector(int_data, int_data + 3, queue);
115 
116     float float_data[] = { 3.2f, 4.5f, 7.6f };
117     boost::compute::vector<float> float_vector(float_data, float_data + 3, queue);
118 
119     // zip all three vectors into a single tuple vector
120     boost::compute::vector<boost::tuple<char, int, float> > tuple_vector(3, context);
121 
122     boost::compute::copy(
123         boost::compute::make_zip_iterator(
124             boost::make_tuple(
125                 char_vector.begin(),
126                 int_vector.begin(),
127                 float_vector.begin()
128             )
129         ),
130         boost::compute::make_zip_iterator(
131             boost::make_tuple(
132                 char_vector.end(),
133                 int_vector.end(),
134                 float_vector.end()
135             )
136         ),
137         tuple_vector.begin(),
138         queue
139     );
140 
141     // copy tuple vector to host
142     std::vector<boost::tuple<char, int, float> > host_vector(3);
143 
144     boost::compute::copy(
145         tuple_vector.begin(),
146         tuple_vector.end(),
147         host_vector.begin(),
148         queue
149     );
150 
151     // check tuple values
152     BOOST_CHECK_EQUAL(host_vector[0], boost::make_tuple('x', 4, 3.2f));
153     BOOST_CHECK_EQUAL(host_vector[1], boost::make_tuple('y', 7, 4.5f));
154     BOOST_CHECK_EQUAL(host_vector[2], boost::make_tuple('z', 9, 7.6f));
155 }
156 
BOOST_AUTO_TEST_CASE(zip_iterator_get)157 BOOST_AUTO_TEST_CASE(zip_iterator_get)
158 {
159     int data1[] = { 0, 2, 4, 6, 8 };
160     int data2[] = { 1, 3, 5, 7, 9 };
161 
162     compute::vector<int> input1(data1, data1 + 5, queue);
163     compute::vector<int> input2(data2, data2 + 5, queue);
164     compute::vector<int> output(5, context);
165 
166     // extract first component from (input1)
167     compute::transform(
168         compute::make_zip_iterator(
169             boost::make_tuple(input1.begin())
170         ),
171         compute::make_zip_iterator(
172             boost::make_tuple(input1.end())
173         ),
174         output.begin(),
175         compute::get<0>(),
176         queue
177     );
178     CHECK_RANGE_EQUAL(int, 5, output, (0, 2, 4, 6, 8));
179 
180     // extract first component from (input2, input1)
181     compute::transform(
182         compute::make_zip_iterator(
183             boost::make_tuple(input2.begin(), input1.begin())
184         ),
185         compute::make_zip_iterator(
186             boost::make_tuple(input2.end(), input1.end())
187         ),
188         output.begin(),
189         compute::get<0>(),
190         queue
191     );
192     CHECK_RANGE_EQUAL(int, 5, output, (1, 3, 5, 7, 9));
193 
194     // extract second component from (input1, input2, input1)
195     compute::transform(
196         compute::make_zip_iterator(
197             boost::make_tuple(input1.begin(), input2.begin(), input1.begin())
198         ),
199         compute::make_zip_iterator(
200             boost::make_tuple(input1.end(), input2.end(), input1.end())
201         ),
202         output.begin(),
203         compute::get<1>(),
204         queue
205     );
206     CHECK_RANGE_EQUAL(int, 5, output, (1, 3, 5, 7, 9));
207 }
208 
BOOST_AUTO_TEST_CASE(zip_constant_iterator)209 BOOST_AUTO_TEST_CASE(zip_constant_iterator)
210 {
211     compute::vector<int> result(4, context);
212 
213     compute::transform(
214         compute::make_zip_iterator(
215             boost::make_tuple(
216                 compute::make_constant_iterator(7)
217             )
218         ),
219         compute::make_zip_iterator(
220             boost::make_tuple(
221                 compute::make_constant_iterator(7, result.size())
222             )
223         ),
224         result.begin(),
225         compute::get<0>(),
226         queue
227     );
228 
229     CHECK_RANGE_EQUAL(int, 4, result, (7, 7, 7, 7));
230 }
231 
232 BOOST_AUTO_TEST_SUITE_END()
233