13SCENARIO(
"scaling a vector with cublas",
"[math::cuda::templateCublas]" )
17 WHEN(
"type is single precision real" )
19 std::vector<float> hx;
24 for(
size_t n = 0; n < hx.size(); ++n )
27 dx.
upload( hx.data(), hx.size() );
28 REQUIRE( dx.size() == hx.size() );
30 cublasHandle_t handle;
32 stat = cublasCreate( &handle );
33 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
36 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
40 REQUIRE( hx[0] == 0 );
41 REQUIRE( hx[1] == 2 );
42 REQUIRE( hx[2] == 4 );
43 REQUIRE( hx[3] == 6 );
44 REQUIRE( hx[4] == 8 );
46 stat = cublasDestroy( handle );
48 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
51 WHEN(
"type is double precision real" )
53 std::vector<double> hx;
58 for(
size_t n = 0; n < hx.size(); ++n )
61 dx.
upload( hx.data(), hx.size() );
62 REQUIRE( dx.size() == hx.size() );
64 cublasHandle_t handle;
66 stat = cublasCreate( &handle );
67 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
70 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
74 REQUIRE( hx[0] == 0 );
75 REQUIRE( hx[1] == 2 );
76 REQUIRE( hx[2] == 4 );
77 REQUIRE( hx[3] == 6 );
78 REQUIRE( hx[4] == 8 );
80 stat = cublasDestroy( handle );
82 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
85 WHEN(
"type is single precision complex" )
87 std::vector<std::complex<float>> hx;
89 std::complex<float> alpha = 2;
92 for(
size_t n = 0; n < hx.size(); ++n )
93 hx[n] = std::complex<float>( n, n );
95 dx.
upload( hx.data(), hx.size() );
96 REQUIRE( dx.size() == hx.size() );
98 cublasHandle_t handle;
100 stat = cublasCreate( &handle );
101 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
104 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
108 REQUIRE( hx[0] == std::complex<float>( 0, 0 ) );
109 REQUIRE( hx[1] == std::complex<float>( 2, 2 ) );
110 REQUIRE( hx[2] == std::complex<float>( 4, 4 ) );
111 REQUIRE( hx[3] == std::complex<float>( 6, 6 ) );
112 REQUIRE( hx[4] == std::complex<float>( 8, 8 ) );
114 stat = cublasDestroy( handle );
116 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
119 WHEN(
"type is double precision complex" )
121 std::vector<std::complex<double>> hx;
123 std::complex<double> alpha = 2;
126 for(
size_t n = 0; n < hx.size(); ++n )
127 hx[n] = std::complex<double>( n, n );
129 dx.
upload( hx.data(), hx.size() );
130 REQUIRE( dx.size() == hx.size() );
132 cublasHandle_t handle;
134 stat = cublasCreate( &handle );
135 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
138 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
142 REQUIRE( hx[0] == std::complex<double>( 0, 0 ) );
143 REQUIRE( hx[1] == std::complex<double>( 2, 2 ) );
144 REQUIRE( hx[2] == std::complex<double>( 4, 4 ) );
145 REQUIRE( hx[3] == std::complex<double>( 6, 6 ) );
146 REQUIRE( hx[4] == std::complex<double>( 8, 8 ) );
148 stat = cublasDestroy( handle );
150 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
160SCENARIO(
"scaling and accumulating a vector with cublas",
"[math::cuda::templateCublas]" )
164 WHEN(
"type is single precision real" )
166 std::vector<float> hx, hy;
171 for(
size_t n = 0; n < hx.size(); ++n )
175 for(
size_t n = 0; n < hy.size(); ++n )
178 dx.
upload( hx.data(), hx.size() );
179 REQUIRE( dx.size() == hx.size() );
181 dy.
upload( hy.data(), hy.size() );
182 REQUIRE( dy.size() == hy.size() );
184 cublasHandle_t handle;
186 stat = cublasCreate( &handle );
187 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
190 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
194 REQUIRE( hy[0] == 1 );
195 REQUIRE( hy[1] == 3 );
196 REQUIRE( hy[2] == 5 );
197 REQUIRE( hy[3] == 7 );
198 REQUIRE( hy[4] == 9 );
200 stat = cublasDestroy( handle );
202 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
205 WHEN(
"type is double precision real" )
207 std::vector<double> hx, hy;
212 for(
size_t n = 0; n < hx.size(); ++n )
216 for(
size_t n = 0; n < hy.size(); ++n )
219 dx.
upload( hx.data(), hx.size() );
220 REQUIRE( dx.size() == hx.size() );
222 dy.
upload( hy.data(), hy.size() );
223 REQUIRE( dy.size() == hy.size() );
225 cublasHandle_t handle;
227 stat = cublasCreate( &handle );
228 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
231 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
235 REQUIRE( hy[0] == 1 );
236 REQUIRE( hy[1] == 3 );
237 REQUIRE( hy[2] == 5 );
238 REQUIRE( hy[3] == 7 );
239 REQUIRE( hy[4] == 9 );
241 stat = cublasDestroy( handle );
243 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
246 WHEN(
"type is single precision complex" )
248 std::vector<std::complex<float>> hx, hy;
250 std::complex<float> alpha = 2;
253 for(
size_t n = 0; n < hx.size(); ++n )
254 hx[n] = std::complex<float>( n, n );
257 for(
size_t n = 0; n < hy.size(); ++n )
258 hy[n] = std::complex<float>( 1, 1 );
260 dx.
upload( hx.data(), hx.size() );
261 REQUIRE( dx.size() == hx.size() );
263 dy.
upload( hy.data(), hy.size() );
264 REQUIRE( dy.size() == hy.size() );
266 cublasHandle_t handle;
268 stat = cublasCreate( &handle );
269 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
272 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
276 REQUIRE( hy[0] == std::complex<float>( 1, 1 ) );
277 REQUIRE( hy[1] == std::complex<float>( 3, 3 ) );
278 REQUIRE( hy[2] == std::complex<float>( 5, 5 ) );
279 REQUIRE( hy[3] == std::complex<float>( 7, 7 ) );
280 REQUIRE( hy[4] == std::complex<float>( 9, 9 ) );
282 stat = cublasDestroy( handle );
284 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
287 WHEN(
"type is double precision complex" )
289 std::vector<std::complex<double>> hx, hy;
291 std::complex<double> alpha = 2;
294 for(
size_t n = 0; n < hx.size(); ++n )
295 hx[n] = std::complex<double>( n, n );
298 for(
size_t n = 0; n < hy.size(); ++n )
299 hy[n] = std::complex<double>( 1, 1 );
301 dx.
upload( hx.data(), hx.size() );
302 REQUIRE( dx.size() == hx.size() );
304 dy.
upload( hy.data(), hy.size() );
305 REQUIRE( dy.size() == hy.size() );
307 cublasHandle_t handle;
309 stat = cublasCreate( &handle );
310 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
313 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
317 REQUIRE( hy[0] == std::complex<double>( 1, 1 ) );
318 REQUIRE( hy[1] == std::complex<double>( 3, 3 ) );
319 REQUIRE( hy[2] == std::complex<double>( 5, 5 ) );
320 REQUIRE( hy[3] == std::complex<double>( 7, 7 ) );
321 REQUIRE( hy[4] == std::complex<double>( 9, 9 ) );
323 stat = cublasDestroy( handle );
325 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
335SCENARIO(
"multiplying two vectors element by element",
"[math::cuda::templateCublas]" )
339 WHEN(
"both types are single precision real" )
341 std::vector<float> hx, hy;
345 for(
size_t n = 0; n < hx.size(); ++n )
349 for(
size_t n = 0; n < hy.size(); ++n )
352 dx.
upload( hx.data(), hx.size() );
353 REQUIRE( dx.size() == hx.size() );
357 REQUIRE( dy.size() == hy.size() );
360 REQUIRE( rv == cudaSuccess );
364 REQUIRE( hx[0] == 0 );
365 REQUIRE( hx[1] == 2 );
366 REQUIRE( hx[2] == 8 );
367 REQUIRE( hx[3] == 18 );
368 REQUIRE( hx[4] == 32 );
371 WHEN(
"type1 is complex-float, and type2 is float" )
373 std::vector<std::complex<float>> hx;
376 std::vector<float> hy;
380 for(
size_t n = 0; n < hx.size(); ++n )
381 hx[n] = std::complex<float>( n, n );
384 for(
size_t n = 0; n < hy.size(); ++n )
387 dx.
upload( hx.data(), hx.size() );
388 REQUIRE( dx.size() == hx.size() );
392 REQUIRE( dy.size() == hy.size() );
395 REQUIRE( rv == cudaSuccess );
399 REQUIRE( hx[0] == std::complex<float>( 0, 0 ) );
400 REQUIRE( hx[1] == std::complex<float>( 2, 2 ) );
401 REQUIRE( hx[2] == std::complex<float>( 8, 8 ) );
402 REQUIRE( hx[3] == std::complex<float>( 18, 18 ) );
403 REQUIRE( hx[4] == std::complex<float>( 32, 32 ) );
406 WHEN(
"type1 is complex-float, and type2 is complex-float" )
408 std::vector<std::complex<float>> hx;
411 std::vector<std::complex<float>> hy;
415 for(
size_t n = 0; n < hx.size(); ++n )
416 hx[n] = std::complex<float>( n, n );
419 for(
size_t n = 0; n < hy.size(); ++n )
420 hy[n] = std::complex<float>( 0, 2 * n );
422 dx.
upload( hx.data(), hx.size() );
423 REQUIRE( dx.size() == hx.size() );
427 REQUIRE( dy.size() == hy.size() );
430 REQUIRE( rv == cudaSuccess );
434 REQUIRE( hx[0] == std::complex<float>( 0, 0 ) );
435 REQUIRE( hx[1] == std::complex<float>( -2, 2 ) );
436 REQUIRE( hx[2] == std::complex<float>( -8, 8 ) );
437 REQUIRE( hx[3] == std::complex<float>( -18, 18 ) );
438 REQUIRE( hx[4] == std::complex<float>( -32, 32 ) );
441 WHEN(
"both types are double precision real" )
443 std::vector<double> hx, hy;
447 for(
size_t n = 0; n < hx.size(); ++n )
451 for(
size_t n = 0; n < hy.size(); ++n )
454 dx.
upload( hx.data(), hx.size() );
455 REQUIRE( dx.size() == hx.size() );
459 REQUIRE( dy.size() == hy.size() );
462 REQUIRE( rv == cudaSuccess );
466 REQUIRE( hx[0] == 0 );
467 REQUIRE( hx[1] == 2 );
468 REQUIRE( hx[2] == 8 );
469 REQUIRE( hx[3] == 18 );
470 REQUIRE( hx[4] == 32 );
473 WHEN(
"type1 is complex-double, and type2 is double" )
475 std::vector<std::complex<double>> hx;
478 std::vector<double> hy;
482 for(
size_t n = 0; n < hx.size(); ++n )
483 hx[n] = std::complex<double>( n, n );
486 for(
size_t n = 0; n < hy.size(); ++n )
489 dx.
upload( hx.data(), hx.size() );
490 REQUIRE( dx.size() == hx.size() );
494 REQUIRE( dy.size() == hy.size() );
497 REQUIRE( rv == cudaSuccess );
501 REQUIRE( hx[0] == std::complex<double>( 0, 0 ) );
502 REQUIRE( hx[1] == std::complex<double>( 2, 2 ) );
503 REQUIRE( hx[2] == std::complex<double>( 8, 8 ) );
504 REQUIRE( hx[3] == std::complex<double>( 18, 18 ) );
505 REQUIRE( hx[4] == std::complex<double>( 32, 32 ) );
508 WHEN(
"type1 is complex-double, and type2 is complex-double" )
510 std::vector<std::complex<double>> hx;
513 std::vector<std::complex<double>> hy;
517 for(
size_t n = 0; n < hx.size(); ++n )
518 hx[n] = std::complex<double>( n, n );
521 for(
size_t n = 0; n < hy.size(); ++n )
522 hy[n] = std::complex<double>( 1, 2 * n );
524 dx.
upload( hx.data(), hx.size() );
525 REQUIRE( dx.size() == hx.size() );
529 REQUIRE( dy.size() == hy.size() );
532 REQUIRE( rv == cudaSuccess );
536 REQUIRE( hx[0] == std::complex<double>( 0, 0 ) );
537 REQUIRE( hx[1] == std::complex<double>( -1, 3 ) );
538 REQUIRE( hx[2] == std::complex<double>( -6, 10 ) );
539 REQUIRE( hx[3] == std::complex<double>( -15, 21 ) );
540 REQUIRE( hx[4] == std::complex<double>( -28, 36 ) );
550SCENARIO(
"multiplying a vector by a matrix giving increments",
"[math::cuda::templateCublas]" )
552 GIVEN(
"a 2x2 matrix, float" )
554 WHEN(
"float precision, beta is 0" )
556 std::vector<float> hA;
559 std::vector<float> hx;
562 std::vector<float> hy;
582 dx.
upload( hx.data(), hx.size() );
592 cublasHandle_t handle;
594 stat = cublasCreate( &handle );
595 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
597 stat =
mx::cuda::cublasTgemv( handle, CUBLAS_OP_N, 2, 2, &alpha, dA(), 2, dx(), 1, &beta, dy(), 1 );
598 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
602 REQUIRE( hy[0] == 7 );
603 REQUIRE( hy[1] == 10 );
605 stat = cublasDestroy( handle );
606 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
609 WHEN(
"float precision, beta is 1, but y is all 0" )
611 std::vector<float> hA;
614 std::vector<float> hx;
617 std::vector<float> hy;
637 dx.
upload( hx.data(), hx.size() );
647 cublasHandle_t handle;
649 stat = cublasCreate( &handle );
650 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
652 stat =
mx::cuda::cublasTgemv( handle, CUBLAS_OP_N, 2, 2, &alpha, dA(), 2, dx(), 1, &beta, dy(), 1 );
653 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
657 REQUIRE( hy[0] == 7 );
658 REQUIRE( hy[1] == 10 );
660 stat = cublasDestroy( handle );
661 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
663 WHEN(
"float precision, beta is 1, y is [1,2]" )
665 std::vector<float> hA;
668 std::vector<float> hx;
671 std::vector<float> hy;
691 dx.
upload( hx.data(), hx.size() );
703 cublasHandle_t handle;
705 stat = cublasCreate( &handle );
706 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
708 stat =
mx::cuda::cublasTgemv( handle, CUBLAS_OP_N, 2, 2, &alpha, dA(), 2, dx(), 1, &beta, dy(), 1 );
709 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
713 REQUIRE( hy[0] == 8 );
714 REQUIRE( hy[1] == 12 );
716 stat = cublasDestroy( handle );
717 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
721 GIVEN(
"a 2x2 matrix, double" )
723 WHEN(
"double precision, beta is 0" )
725 std::vector<double> hA;
728 std::vector<double> hx;
731 std::vector<double> hy;
751 dx.
upload( hx.data(), hx.size() );
761 cublasHandle_t handle;
763 stat = cublasCreate( &handle );
764 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
766 stat =
mx::cuda::cublasTgemv( handle, CUBLAS_OP_N, 2, 2, &alpha, dA(), 2, dx(), 1, &beta, dy(), 1 );
767 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
771 REQUIRE( hy[0] == 7 );
772 REQUIRE( hy[1] == 10 );
774 stat = cublasDestroy( handle );
775 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
778 WHEN(
"double precision, beta is 1, but y is all 0" )
780 std::vector<double> hA;
783 std::vector<double> hx;
786 std::vector<double> hy;
806 dx.
upload( hx.data(), hx.size() );
816 cublasHandle_t handle;
818 stat = cublasCreate( &handle );
819 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
821 stat =
mx::cuda::cublasTgemv( handle, CUBLAS_OP_N, 2, 2, &alpha, dA(), 2, dx(), 1, &beta, dy(), 1 );
822 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
826 REQUIRE( hy[0] == 7 );
827 REQUIRE( hy[1] == 10 );
829 stat = cublasDestroy( handle );
830 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
832 WHEN(
"double precision, beta is 1, y is [1,2]" )
834 std::vector<double> hA;
837 std::vector<double> hx;
840 std::vector<double> hy;
860 dx.
upload( hx.data(), hx.size() );
872 cublasHandle_t handle;
874 stat = cublasCreate( &handle );
875 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
877 stat =
mx::cuda::cublasTgemv( handle, CUBLAS_OP_N, 2, 2, &alpha, dA(), 2, dx(), 1, &beta, dy(), 1 );
878 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
882 REQUIRE( hy[0] == 8 );
883 REQUIRE( hy[1] == 12 );
885 stat = cublasDestroy( handle );
886 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );