1 /* =========================================================================
2 Copyright (c) 2010-2016, Institute for Microelectronics,
3 Institute for Analysis and Scientific Computing,
4 TU Wien.
5 Portions of this software are copyright by UChicago Argonne, LLC.
6
7 -----------------
8 ViennaCL - The Vienna Computing Library
9 -----------------
10
11 Project Head: Karl Rupp rupp@iue.tuwien.ac.at
12
13 (A list of authors and contributors can be found in the PDF manual)
14
15 License: MIT (X11), see file LICENSE in the base directory
16 ============================================================================= */
17
18
19 /** \file tests/src/vector_convert.cpp Tests conversion between vectors with different numeric type
20 * \test Tests conversion between vectors with different numeric type
21 **/
22
23 //
24 // *** System
25 //
26 #include <iostream>
27 #include <iomanip>
28 #include <vector>
29
30
31 //
32 // *** ViennaCL
33 //
34 //#define VIENNACL_DEBUG_ALL
35 #include "viennacl/vector.hpp"
36 #include "viennacl/vector_proxy.hpp"
37
38
39 template<typename NumericT, typename VectorT>
check(std::vector<NumericT> const & std_dest,std::size_t start_dest,std::size_t inc_dest,std::size_t size_dest,VectorT const & vcl_dest)40 int check(std::vector<NumericT> const & std_dest, std::size_t start_dest, std::size_t inc_dest, std::size_t size_dest,
41 VectorT const & vcl_dest)
42 {
43 std::vector<NumericT> tempvec(vcl_dest.size());
44 viennacl::copy(vcl_dest, tempvec);
45
46 for (std::size_t i=0; i < size_dest; ++i)
47 {
48 if ( std_dest[start_dest + i * inc_dest] < tempvec[i]
49 || std_dest[start_dest + i * inc_dest] > tempvec[i])
50 {
51 std::cerr << "Failure at index " << i << ": STL value " << std_dest[start_dest + i * inc_dest] << ", ViennaCL value " << tempvec[i] << std::endl;
52 return EXIT_FAILURE;
53 }
54 }
55
56 return EXIT_SUCCESS;
57 }
58
59
60 //
61 // -------------------------------------------------------------
62 //
63 template<typename STLVectorT1, typename STLVectorT2, typename ViennaCLVectorT1, typename ViennaCLVectorT2 >
test(STLVectorT1 & std_src,std::size_t start_src,std::size_t inc_src,std::size_t size_src,STLVectorT2 & std_dest,std::size_t start_dest,std::size_t inc_dest,std::size_t size_dest,ViennaCLVectorT1 const & vcl_src,ViennaCLVectorT2 & vcl_dest)64 int test(STLVectorT1 & std_src, std::size_t start_src, std::size_t inc_src, std::size_t size_src,
65 STLVectorT2 & std_dest, std::size_t start_dest, std::size_t inc_dest, std::size_t size_dest,
66 ViennaCLVectorT1 const & vcl_src, ViennaCLVectorT2 & vcl_dest)
67 {
68 assert(size_src == size_dest && bool("Size mismatch for STL vectors"));
69 assert(vcl_src.size() == vcl_dest.size() && bool("Size mismatch for ViennaCL vectors"));
70 assert(size_src == vcl_src.size() && bool("Size mismatch for STL and ViennaCL vectors"));
71
72 typedef typename STLVectorT2::value_type DestNumericT;
73
74 for (std::size_t i=0; i<size_src; ++i)
75 std_dest[start_dest + i * inc_dest] = static_cast<DestNumericT>(std_src[start_src + i * inc_src]);
76
77 vcl_dest = vcl_src; // here is the conversion taking place
78
79 if (check(std_dest, start_dest, inc_dest, size_dest, vcl_dest) != EXIT_SUCCESS)
80 return EXIT_FAILURE;
81
82 viennacl::vector<DestNumericT> x(vcl_src);
83 if (check(std_dest, start_dest, inc_dest, size_dest, x) != EXIT_SUCCESS)
84 return EXIT_FAILURE;
85
86 // --------------------------------------------------------------------------
87 return EXIT_SUCCESS;
88 }
89
type_string(unsigned int)90 inline std::string type_string(unsigned int) { return "unsigned int"; }
type_string(int)91 inline std::string type_string(int) { return "int"; }
type_string(unsigned long)92 inline std::string type_string(unsigned long) { return "unsigned long"; }
type_string(long)93 inline std::string type_string(long) { return "long"; }
type_string(float)94 inline std::string type_string(float) { return "float"; }
type_string(double)95 inline std::string type_string(double) { return "double"; }
96
97 template<typename FromNumericT, typename ToNumericT>
test()98 int test()
99 {
100 int retval = EXIT_SUCCESS;
101
102 std::cout << std::endl;
103 std::cout << "-----------------------------------------------" << std::endl;
104 std::cout << std::endl;
105 std::cout << "Conversion test from " << type_string(FromNumericT()) << " to " << type_string(ToNumericT()) << std::endl;
106 std::cout << std::endl;
107
108 std::size_t full_size = 12345;
109 std::size_t small_size = full_size / 4;
110 //
111 // Set up STL objects
112 //
113 std::vector<FromNumericT> std_src(full_size);
114 std::vector<ToNumericT> std_dest(std_src.size());
115
116 for (std::size_t i=0; i<std_src.size(); ++i)
117 std_src[i] = FromNumericT(1.0) + FromNumericT(i);
118
119 //
120 // Set up ViennaCL objects
121 //
122 viennacl::vector<FromNumericT> vcl_src(std_src.size());
123 viennacl::vector<ToNumericT> vcl_dest(std_src.size());
124
125 viennacl::copy(std_src, vcl_src);
126
127 viennacl::vector<FromNumericT> vcl_src_small(small_size);
128 viennacl::copy(std_src.begin(), std_src.begin() + typename std::vector<FromNumericT>::difference_type(small_size), vcl_src_small.begin());
129 viennacl::vector<ToNumericT> vcl_dest_small(small_size);
130
131 std::size_t r1_start = 1 + vcl_src.size() / 4;
132 std::size_t r1_stop = 1 + 2 * vcl_src.size() / 4;
133 viennacl::range vcl_r1(r1_start, r1_stop);
134
135 std::size_t r2_start = 2 * vcl_src.size() / 4;
136 std::size_t r2_stop = 3 * vcl_src.size() / 4;
137 viennacl::range vcl_r2(r2_start, r2_stop);
138
139 viennacl::vector_range< viennacl::vector<FromNumericT> > vcl_range_src(vcl_src, vcl_r1);
140 viennacl::vector_range< viennacl::vector<ToNumericT> > vcl_range_dest(vcl_dest, vcl_r2);
141
142
143
144 std::size_t s1_start = 1 + vcl_src.size() / 5;
145 std::size_t s1_inc = 3;
146 std::size_t s1_size = vcl_src.size() / 4;
147 viennacl::slice vcl_s1(s1_start, s1_inc, s1_size);
148
149 std::size_t s2_start = 2 * vcl_dest.size() / 5;
150 std::size_t s2_inc = 2;
151 std::size_t s2_size = vcl_dest.size() / 4;
152 viennacl::slice vcl_s2(s2_start, s2_inc, s2_size);
153
154 viennacl::vector_slice< viennacl::vector<FromNumericT> > vcl_slice_src(vcl_src, vcl_s1);
155 viennacl::vector_slice< viennacl::vector<ToNumericT> > vcl_slice_dest(vcl_dest, vcl_s2);
156
157 //
158 // Now start running tests for vectors, ranges and slices:
159 //
160
161 std::cout << " ** vcl_src = vector, vcl_dest = vector **" << std::endl;
162 retval = test(std_src, 0, 1, std_src.size(),
163 std_dest, 0, 1, std_dest.size(),
164 vcl_src, vcl_dest);
165 if (retval != EXIT_SUCCESS)
166 return EXIT_FAILURE;
167
168 std::cout << " ** vcl_src = vector, vcl_dest = range **" << std::endl;
169 retval = test(std_src, 0, 1, small_size,
170 std_dest, r2_start, 1, r2_stop - r2_start,
171 vcl_src_small, vcl_range_dest);
172 if (retval != EXIT_SUCCESS)
173 return EXIT_FAILURE;
174
175 std::cout << " ** vcl_src = vector, vcl_dest = slice **" << std::endl;
176 retval = test(std_src, 0, 1, small_size,
177 std_dest, s2_start, s2_inc, s2_size,
178 vcl_src_small, vcl_slice_dest);
179 if (retval != EXIT_SUCCESS)
180 return EXIT_FAILURE;
181
182 ///////
183
184 std::cout << " ** vcl_src = range, vcl_dest = vector **" << std::endl;
185 retval = test(std_src, r1_start, 1, r1_stop - r1_start,
186 std_dest, 0, 1, small_size,
187 vcl_range_src, vcl_dest_small);
188 if (retval != EXIT_SUCCESS)
189 return EXIT_FAILURE;
190
191 std::cout << " ** vcl_src = range, vcl_dest = range **" << std::endl;
192 retval = test(std_src, r1_start, 1, r1_stop - r1_start,
193 std_dest, r2_start, 1, r2_stop - r2_start,
194 vcl_range_src, vcl_range_dest);
195 if (retval != EXIT_SUCCESS)
196 return EXIT_FAILURE;
197
198 std::cout << " ** vcl_src = range, vcl_dest = slice **" << std::endl;
199 retval = test(std_src, r1_start, 1, r1_stop - r1_start,
200 std_dest, s2_start, s2_inc, s2_size,
201 vcl_range_src, vcl_slice_dest);
202 if (retval != EXIT_SUCCESS)
203 return EXIT_FAILURE;
204
205 ///////
206
207 std::cout << " ** vcl_src = slice, vcl_dest = vector **" << std::endl;
208 retval = test(std_src, s1_start, s1_inc, s1_size,
209 std_dest, 0, 1, small_size,
210 vcl_slice_src, vcl_dest_small);
211 if (retval != EXIT_SUCCESS)
212 return EXIT_FAILURE;
213
214 std::cout << " ** vcl_src = slice, vcl_dest = range **" << std::endl;
215 retval = test(std_src, s1_start, s1_inc, s1_size,
216 std_dest, r2_start, 1, r2_stop - r2_start,
217 vcl_slice_src, vcl_range_dest);
218 if (retval != EXIT_SUCCESS)
219 return EXIT_FAILURE;
220
221 std::cout << " ** vcl_src = slice, vcl_dest = slice **" << std::endl;
222 retval = test(std_src, s1_start, s1_inc, s1_size,
223 std_dest, s2_start, s2_inc, s2_size,
224 vcl_slice_src, vcl_slice_dest);
225 if (retval != EXIT_SUCCESS)
226 return EXIT_FAILURE;
227
228 return EXIT_SUCCESS;
229 }
230
231
232
233 //
234 // -------------------------------------------------------------
235 //
main()236 int main()
237 {
238 std::cout << std::endl;
239 std::cout << "----------------------------------------------" << std::endl;
240 std::cout << "----------------------------------------------" << std::endl;
241 std::cout << "## Test :: Type conversion test for vectors " << std::endl;
242 std::cout << "----------------------------------------------" << std::endl;
243 std::cout << "----------------------------------------------" << std::endl;
244 std::cout << std::endl;
245
246 int retval = EXIT_SUCCESS;
247
248 //
249 // from int
250 //
251 retval = test<int, int>();
252 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
253 else return retval;
254
255 retval = test<int, unsigned int>();
256 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
257 else return retval;
258
259 retval = test<int, long>();
260 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
261 else return retval;
262
263 retval = test<int, unsigned long>();
264 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
265 else return retval;
266
267 retval = test<int, float>();
268 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
269 else return retval;
270
271 retval = test<int, unsigned long>();
272 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
273 else return retval;
274
275 #ifdef VIENNACL_WITH_OPENCL
276 if ( viennacl::ocl::current_device().double_support() )
277 #endif
278 {
279 retval = test<int, double>();
280 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
281 else return retval;
282 }
283
284
285 //
286 // from unsigned int
287 //
288 retval = test<unsigned int, int>();
289 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
290 else return retval;
291
292 retval = test<unsigned int, unsigned int>();
293 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
294 else return retval;
295
296 retval = test<unsigned int, long>();
297 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
298 else return retval;
299
300 retval = test<unsigned int, unsigned long>();
301 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
302 else return retval;
303
304 retval = test<unsigned int, float>();
305 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
306 else return retval;
307
308 retval = test<unsigned int, unsigned long>();
309 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
310 else return retval;
311
312 #ifdef VIENNACL_WITH_OPENCL
313 if ( viennacl::ocl::current_device().double_support() )
314 #endif
315 {
316 retval = test<unsigned int, double>();
317 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
318 else return retval;
319 }
320
321
322 //
323 // from long
324 //
325 retval = test<long, int>();
326 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
327 else return retval;
328
329 retval = test<long, unsigned int>();
330 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
331 else return retval;
332
333 retval = test<long, long>();
334 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
335 else return retval;
336
337 retval = test<long, unsigned long>();
338 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
339 else return retval;
340
341 retval = test<long, float>();
342 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
343 else return retval;
344
345 retval = test<long, unsigned long>();
346 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
347 else return retval;
348
349 #ifdef VIENNACL_WITH_OPENCL
350 if ( viennacl::ocl::current_device().double_support() )
351 #endif
352 {
353 retval = test<long, double>();
354 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
355 else return retval;
356 }
357
358
359 //
360 // from unsigned long
361 //
362 retval = test<unsigned long, int>();
363 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
364 else return retval;
365
366 retval = test<unsigned long, unsigned int>();
367 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
368 else return retval;
369
370 retval = test<unsigned long, long>();
371 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
372 else return retval;
373
374 retval = test<unsigned long, unsigned long>();
375 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
376 else return retval;
377
378 retval = test<unsigned long, float>();
379 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
380 else return retval;
381
382 retval = test<unsigned long, unsigned long>();
383 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
384 else return retval;
385
386 #ifdef VIENNACL_WITH_OPENCL
387 if ( viennacl::ocl::current_device().double_support() )
388 #endif
389 {
390 retval = test<unsigned long, double>();
391 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
392 else return retval;
393 }
394
395 //
396 // from float
397 //
398 retval = test<float, int>();
399 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
400 else return retval;
401
402 retval = test<float, unsigned int>();
403 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
404 else return retval;
405
406 retval = test<float, long>();
407 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
408 else return retval;
409
410 retval = test<float, unsigned long>();
411 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
412 else return retval;
413
414 retval = test<float, float>();
415 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
416 else return retval;
417
418 retval = test<float, unsigned long>();
419 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
420 else return retval;
421
422 #ifdef VIENNACL_WITH_OPENCL
423 if ( viennacl::ocl::current_device().double_support() )
424 #endif
425 {
426 retval = test<float, double>();
427 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
428 else return retval;
429 }
430
431 //
432 // from double
433 //
434 #ifdef VIENNACL_WITH_OPENCL
435 if ( viennacl::ocl::current_device().double_support() )
436 #endif
437 {
438 retval = test<double, int>();
439 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
440 else return retval;
441
442 retval = test<double, unsigned int>();
443 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
444 else return retval;
445
446 retval = test<double, long>();
447 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
448 else return retval;
449
450 retval = test<double, unsigned long>();
451 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
452 else return retval;
453
454 retval = test<double, float>();
455 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
456 else return retval;
457
458 retval = test<double, unsigned long>();
459 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
460 else return retval;
461
462 retval = test<double, double>();
463 if ( retval == EXIT_SUCCESS ) std::cout << "# Test passed" << std::endl;
464 else return retval;
465 }
466
467
468 std::cout << std::endl;
469 std::cout << "------- Test completed --------" << std::endl;
470 std::cout << std::endl;
471
472 return retval;
473 }
474