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