1 #include <unittest/unittest.h>
2 #include <thrust/copy.h>
3
4 #include <list>
5 #include <iterator>
6 #include <thrust/sequence.h>
7 #include <thrust/iterator/zip_iterator.h>
8 #include <thrust/iterator/counting_iterator.h>
9 #include <thrust/iterator/constant_iterator.h>
10 #include <thrust/iterator/discard_iterator.h>
11 #include <thrust/iterator/retag.h>
12
TestCopyNFromConstIterator(void)13 void TestCopyNFromConstIterator(void)
14 {
15 typedef int T;
16
17 std::vector<T> v(5);
18 v[0] = 0; v[1] = 1; v[2] = 2; v[3] = 3; v[4] = 4;
19
20 std::vector<int>::const_iterator begin = v.begin();
21
22 // copy to host_vector
23 thrust::host_vector<T> h(5, (T) 10);
24 thrust::host_vector<T>::iterator h_result = thrust::copy_n(begin, h.size(), h.begin());
25 ASSERT_EQUAL(h[0], 0);
26 ASSERT_EQUAL(h[1], 1);
27 ASSERT_EQUAL(h[2], 2);
28 ASSERT_EQUAL(h[3], 3);
29 ASSERT_EQUAL(h[4], 4);
30 ASSERT_EQUAL_QUIET(h_result, h.end());
31
32 // copy to device_vector
33 thrust::device_vector<T> d(5, (T) 10);
34 thrust::device_vector<T>::iterator d_result = thrust::copy_n(begin, d.size(), d.begin());
35 ASSERT_EQUAL(d[0], 0);
36 ASSERT_EQUAL(d[1], 1);
37 ASSERT_EQUAL(d[2], 2);
38 ASSERT_EQUAL(d[3], 3);
39 ASSERT_EQUAL(d[4], 4);
40 ASSERT_EQUAL_QUIET(d_result, d.end());
41 }
42 DECLARE_UNITTEST(TestCopyNFromConstIterator);
43
TestCopyNToDiscardIterator(void)44 void TestCopyNToDiscardIterator(void)
45 {
46 typedef int T;
47
48 thrust::host_vector<T> h_input(5, 1);
49 thrust::device_vector<T> d_input = h_input;
50
51 // copy from host_vector
52 thrust::discard_iterator<> h_result =
53 thrust::copy_n(h_input.begin(), h_input.size(), thrust::make_discard_iterator());
54
55 // copy from device_vector
56 thrust::discard_iterator<> d_result =
57 thrust::copy_n(d_input.begin(), d_input.size(), thrust::make_discard_iterator());
58
59 thrust::discard_iterator<> reference(5);
60
61 ASSERT_EQUAL_QUIET(reference, h_result);
62 ASSERT_EQUAL_QUIET(reference, d_result);
63 }
64 DECLARE_UNITTEST(TestCopyNToDiscardIterator);
65
66 template <class Vector>
TestCopyNMatchingTypes(void)67 void TestCopyNMatchingTypes(void)
68 {
69 typedef typename Vector::value_type T;
70
71 Vector v(5);
72 v[0] = 0; v[1] = 1; v[2] = 2; v[3] = 3; v[4] = 4;
73
74 // copy to host_vector
75 thrust::host_vector<T> h(5, (T) 10);
76 typename thrust::host_vector<T>::iterator h_result = thrust::copy_n(v.begin(), v.size(), h.begin());
77 ASSERT_EQUAL(h[0], 0);
78 ASSERT_EQUAL(h[1], 1);
79 ASSERT_EQUAL(h[2], 2);
80 ASSERT_EQUAL(h[3], 3);
81 ASSERT_EQUAL(h[4], 4);
82 ASSERT_EQUAL_QUIET(h_result, h.end());
83
84 // copy to device_vector
85 thrust::device_vector<T> d(5, (T) 10);
86 typename thrust::device_vector<T>::iterator d_result = thrust::copy_n(v.begin(), v.size(), d.begin());
87 ASSERT_EQUAL(d[0], 0);
88 ASSERT_EQUAL(d[1], 1);
89 ASSERT_EQUAL(d[2], 2);
90 ASSERT_EQUAL(d[3], 3);
91 ASSERT_EQUAL(d[4], 4);
92 ASSERT_EQUAL_QUIET(d_result, d.end());
93 }
94 DECLARE_VECTOR_UNITTEST(TestCopyNMatchingTypes);
95
96 template <class Vector>
TestCopyNMixedTypes(void)97 void TestCopyNMixedTypes(void)
98 {
99 Vector v(5);
100 v[0] = 0; v[1] = 1; v[2] = 2; v[3] = 3; v[4] = 4;
101
102 // copy to host_vector with different type
103 thrust::host_vector<float> h(5, (float) 10);
104 typename thrust::host_vector<float>::iterator h_result = thrust::copy_n(v.begin(), v.size(), h.begin());
105
106 ASSERT_EQUAL(h[0], 0);
107 ASSERT_EQUAL(h[1], 1);
108 ASSERT_EQUAL(h[2], 2);
109 ASSERT_EQUAL(h[3], 3);
110 ASSERT_EQUAL(h[4], 4);
111 ASSERT_EQUAL_QUIET(h_result, h.end());
112
113 // copy to device_vector with different type
114 thrust::device_vector<float> d(5, (float) 10);
115 typename thrust::device_vector<float>::iterator d_result = thrust::copy_n(v.begin(), v.size(), d.begin());
116 ASSERT_EQUAL(d[0], 0);
117 ASSERT_EQUAL(d[1], 1);
118 ASSERT_EQUAL(d[2], 2);
119 ASSERT_EQUAL(d[3], 3);
120 ASSERT_EQUAL(d[4], 4);
121 ASSERT_EQUAL_QUIET(d_result, d.end());
122 }
123 DECLARE_INTEGRAL_VECTOR_UNITTEST(TestCopyNMixedTypes);
124
125
TestCopyNVectorBool(void)126 void TestCopyNVectorBool(void)
127 {
128 std::vector<bool> v(3);
129 v[0] = true; v[1] = false; v[2] = true;
130
131 thrust::host_vector<bool> h(3);
132 thrust::device_vector<bool> d(3);
133
134 thrust::copy_n(v.begin(), v.size(), h.begin());
135 thrust::copy_n(v.begin(), v.size(), d.begin());
136
137 ASSERT_EQUAL(h[0], true);
138 ASSERT_EQUAL(h[1], false);
139 ASSERT_EQUAL(h[2], true);
140
141 ASSERT_EQUAL(d[0], true);
142 ASSERT_EQUAL(d[1], false);
143 ASSERT_EQUAL(d[2], true);
144 }
145 DECLARE_UNITTEST(TestCopyNVectorBool);
146
147
148 template <class Vector>
TestCopyNListTo(void)149 void TestCopyNListTo(void)
150 {
151 typedef typename Vector::value_type T;
152
153 // copy from list to Vector
154 std::list<T> l;
155 l.push_back(0);
156 l.push_back(1);
157 l.push_back(2);
158 l.push_back(3);
159 l.push_back(4);
160
161 Vector v(l.size());
162
163 typename Vector::iterator v_result = thrust::copy_n(l.begin(), l.size(), v.begin());
164
165 ASSERT_EQUAL(v[0], T(0));
166 ASSERT_EQUAL(v[1], T(1));
167 ASSERT_EQUAL(v[2], T(2));
168 ASSERT_EQUAL(v[3], T(3));
169 ASSERT_EQUAL(v[4], T(4));
170 ASSERT_EQUAL_QUIET(v_result, v.end());
171
172 l.clear();
173
174 thrust::copy_n(v.begin(), v.size(), std::back_insert_iterator< std::list<T> >(l));
175
176 ASSERT_EQUAL(l.size(), 5lu);
177
178 typename std::list<T>::const_iterator iter = l.begin();
179 ASSERT_EQUAL(*iter, T(0)); iter++;
180 ASSERT_EQUAL(*iter, T(1)); iter++;
181 ASSERT_EQUAL(*iter, T(2)); iter++;
182 ASSERT_EQUAL(*iter, T(3)); iter++;
183 ASSERT_EQUAL(*iter, T(4)); iter++;
184 }
185 DECLARE_VECTOR_UNITTEST(TestCopyNListTo);
186
187
188 template <typename Vector>
TestCopyNCountingIterator(void)189 void TestCopyNCountingIterator(void)
190 {
191 typedef typename Vector::value_type T;
192
193 thrust::counting_iterator<T> iter(1);
194
195 Vector vec(4);
196
197 thrust::copy_n(iter, 4, vec.begin());
198
199 ASSERT_EQUAL(vec[0], T(1));
200 ASSERT_EQUAL(vec[1], T(2));
201 ASSERT_EQUAL(vec[2], T(3));
202 ASSERT_EQUAL(vec[3], T(4));
203 }
204 DECLARE_INTEGRAL_VECTOR_UNITTEST(TestCopyNCountingIterator);
205
206 template <typename Vector>
TestCopyNZipIterator(void)207 void TestCopyNZipIterator(void)
208 {
209 typedef typename Vector::value_type T;
210
211 Vector v1(3); v1[0] = 1; v1[1] = 2; v1[2] = 3;
212 Vector v2(3); v2[0] = 4; v2[1] = 5; v2[2] = 6;
213 Vector v3(3, T(0));
214 Vector v4(3, T(0));
215
216 thrust::copy_n(thrust::make_zip_iterator(thrust::make_tuple(v1.begin(),v2.begin())),
217 3,
218 thrust::make_zip_iterator(thrust::make_tuple(v3.begin(),v4.begin())));
219
220 ASSERT_EQUAL(v1, v3);
221 ASSERT_EQUAL(v2, v4);
222 };
223 DECLARE_VECTOR_UNITTEST(TestCopyNZipIterator);
224
225 template <typename Vector>
TestCopyNConstantIteratorToZipIterator(void)226 void TestCopyNConstantIteratorToZipIterator(void)
227 {
228 typedef typename Vector::value_type T;
229
230 Vector v1(3, T(0));
231 Vector v2(3, T(0));
232
233 thrust::copy_n(thrust::make_constant_iterator(thrust::tuple<T,T>(4,7)),
234 v1.size(),
235 thrust::make_zip_iterator(thrust::make_tuple(v1.begin(),v2.begin())));
236
237 ASSERT_EQUAL(v1[0], T(4));
238 ASSERT_EQUAL(v1[1], T(4));
239 ASSERT_EQUAL(v1[2], T(4));
240 ASSERT_EQUAL(v2[0], T(7));
241 ASSERT_EQUAL(v2[1], T(7));
242 ASSERT_EQUAL(v2[2], T(7));
243 };
244 DECLARE_VECTOR_UNITTEST(TestCopyNConstantIteratorToZipIterator);
245
246 template<typename InputIterator, typename Size, typename OutputIterator>
copy_n(my_system & system,InputIterator,Size,OutputIterator result)247 OutputIterator copy_n(my_system &system, InputIterator, Size, OutputIterator result)
248 {
249 system.validate_dispatch();
250 return result;
251 }
252
TestCopyNDispatchExplicit()253 void TestCopyNDispatchExplicit()
254 {
255 thrust::device_vector<int> vec(1);
256
257 my_system sys(0);
258 thrust::copy_n(sys,
259 vec.begin(),
260 1,
261 vec.begin());
262
263 ASSERT_EQUAL(true, sys.is_valid());
264 }
265 DECLARE_UNITTEST(TestCopyNDispatchExplicit);
266
267
268 template<typename InputIterator, typename Size, typename OutputIterator>
copy_n(my_tag,InputIterator,Size,OutputIterator result)269 OutputIterator copy_n(my_tag, InputIterator, Size, OutputIterator result)
270 {
271 *result = 13;
272 return result;
273 }
274
TestCopyNDispatchImplicit()275 void TestCopyNDispatchImplicit()
276 {
277 thrust::device_vector<int> vec(1);
278
279 thrust::copy_n(thrust::retag<my_tag>(vec.begin()),
280 1,
281 thrust::retag<my_tag>(vec.begin()));
282
283 ASSERT_EQUAL(13, vec.front());
284 }
285 DECLARE_UNITTEST(TestCopyNDispatchImplicit);
286
287