• 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 TestStridedIterator
12 #include <boost/test/unit_test.hpp>
13 
14 #include <iterator>
15 
16 #include <boost/type_traits.hpp>
17 #include <boost/static_assert.hpp>
18 
19 #include <boost/compute/algorithm/copy.hpp>
20 #include <boost/compute/container/vector.hpp>
21 #include <boost/compute/iterator/buffer_iterator.hpp>
22 #include <boost/compute/iterator/strided_iterator.hpp>
23 
24 #include "check_macros.hpp"
25 #include "context_setup.hpp"
26 
27 namespace bc = boost::compute;
28 
BOOST_AUTO_TEST_CASE(value_type)29 BOOST_AUTO_TEST_CASE(value_type)
30 {
31     BOOST_STATIC_ASSERT((
32         boost::is_same<
33             boost::compute::strided_iterator<
34                 boost::compute::buffer_iterator<int>
35             >::value_type,
36             int
37         >::value
38     ));
39     BOOST_STATIC_ASSERT((
40         boost::is_same<
41             boost::compute::strided_iterator<
42                 boost::compute::buffer_iterator<float>
43             >::value_type,
44             float
45         >::value
46     ));
47 }
48 
BOOST_AUTO_TEST_CASE(base_type)49 BOOST_AUTO_TEST_CASE(base_type)
50 {
51     BOOST_STATIC_ASSERT((
52         boost::is_same<
53             boost::compute::strided_iterator<
54                 boost::compute::buffer_iterator<int>
55             >::base_type,
56             boost::compute::buffer_iterator<int>
57         >::value
58     ));
59 }
60 
BOOST_AUTO_TEST_CASE(distance)61 BOOST_AUTO_TEST_CASE(distance)
62 {
63     int data[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
64     boost::compute::vector<int> vec(data, data + 8, queue);
65 
66     BOOST_CHECK_EQUAL(
67          std::distance(
68              boost::compute::make_strided_iterator(vec.begin(), 1),
69              boost::compute::make_strided_iterator(vec.end(), 1)
70          ),
71          std::ptrdiff_t(8)
72     );
73     BOOST_CHECK_EQUAL(
74         std::distance(
75             boost::compute::make_strided_iterator(vec.begin(), 2),
76             boost::compute::make_strided_iterator(vec.end(), 2)
77         ),
78         std::ptrdiff_t(4)
79     );
80 
81     BOOST_CHECK_EQUAL(
82         std::distance(
83             boost::compute::make_strided_iterator(vec.begin(), 3),
84             boost::compute::make_strided_iterator(vec.begin()+6, 3)
85         ),
86         std::ptrdiff_t(2)
87     );
88 }
89 
BOOST_AUTO_TEST_CASE(copy)90 BOOST_AUTO_TEST_CASE(copy)
91 {
92     boost::compute::int_ data[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
93     boost::compute::vector<boost::compute::int_> vec(data, data + 8, queue);
94 
95     boost::compute::vector<boost::compute::int_> result(4, context);
96 
97     // copy every other element to result
98     boost::compute::copy(
99         boost::compute::make_strided_iterator(vec.begin(), 2),
100         boost::compute::make_strided_iterator(vec.end(), 2),
101         result.begin(),
102         queue
103     );
104     CHECK_RANGE_EQUAL(boost::compute::int_, 4, result, (1, 3, 5, 7));
105 
106     // copy every 3rd element to result
107     boost::compute::copy(
108         boost::compute::make_strided_iterator(vec.begin(), 3),
109         boost::compute::make_strided_iterator(vec.begin()+9, 3),
110         result.begin(),
111         queue
112     );
113     CHECK_RANGE_EQUAL(boost::compute::int_, 3, result, (1, 4, 7));
114 }
115 
BOOST_AUTO_TEST_CASE(make_strided_iterator_end)116 BOOST_AUTO_TEST_CASE(make_strided_iterator_end)
117 {
118     boost::compute::int_ data[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
119     boost::compute::vector<boost::compute::int_> vec(data, data + 8, queue);
120 
121     // stride equals 3
122     typedef boost::compute::vector<boost::compute::int_>::iterator IterType;
123     boost::compute::strided_iterator<IterType> end =
124         boost::compute::make_strided_iterator_end(vec.begin(),
125                                                   vec.end(),
126                                                   3);
127 
128     // end should be vec.begin() + 9 which is one step after last element
129     // accessible through strided_iterator, i.e. vec.begin()+6
130     BOOST_CHECK(boost::compute::make_strided_iterator(vec.begin()+9, 3) ==
131                 end);
132 
133     // stride equals 2
134     end = boost::compute::make_strided_iterator_end(vec.begin(),
135                                                     vec.end(),
136                                                     2);
137     // end should be vec.end(), because vector size is divisible by 2
138     BOOST_CHECK(boost::compute::make_strided_iterator(vec.end(), 2) == end);
139 
140     // stride equals 1000
141     end = boost::compute::make_strided_iterator_end(vec.begin(),
142                                                     vec.end(),
143                                                     1000);
144     // end should be vec.begin() + 1000, because stride > vector size
145     BOOST_CHECK(boost::compute::make_strided_iterator(vec.begin()+1000, 1000) ==
146                 end);
147 
148 
149     // test boost::compute::make_strided_iterator_end with copy(..)
150 
151     boost::compute::vector<boost::compute::int_> result(4, context);
152 
153     // copy every other element to result
154     boost::compute::copy(
155         boost::compute::make_strided_iterator(vec.begin()+1, 2),
156         boost::compute::make_strided_iterator_end(vec.begin()+1, vec.end(), 2),
157         result.begin(),
158         queue
159     );
160     CHECK_RANGE_EQUAL(boost::compute::int_, 4, result, (2, 4, 6, 8));
161 }
162 
BOOST_AUTO_TEST_CASE(iterator_tag)163 BOOST_AUTO_TEST_CASE(iterator_tag)
164 {
165     typedef bc::buffer_iterator<bc::float_> i_type;
166 
167     BOOST_STATIC_ASSERT((
168         boost::is_same<
169             std::iterator_traits<
170                 i_type
171             >::iterator_category,
172             std::iterator_traits<
173                 bc::strided_iterator<i_type>
174             >::iterator_category
175         >::value
176     ));
177 }
178 
BOOST_AUTO_TEST_CASE(std_distance)179 BOOST_AUTO_TEST_CASE(std_distance)
180 {
181     bc::vector<bc::float_> vec(
182         size_t(300),
183         bc::float_(1.1f),
184         queue
185     );
186 
187     bc::strided_iterator<bc::buffer_iterator<bc::float_> > begin(vec.begin(), 1);
188     bc::strided_iterator<bc::buffer_iterator<bc::float_> > end(vec.end(), 1);
189 
190     BOOST_CHECK_EQUAL(std::distance(begin, end),  300);
191     BOOST_CHECK_EQUAL(std::distance(end, begin), -300);
192 }
193 
194 BOOST_AUTO_TEST_SUITE_END()
195