15TEST_CASE(
"scaling a vector with cublas",
"[math::cuda::templateCublas]" )
17 if( !mxlibTest::cudaDeviceAvailable() )
19 WARN(
"CUDA runtime is available but no CUDA device is present" );
25 WHEN(
"type is single precision real" )
27 std::vector<float> hx;
28 mx::cuda::cudaPtr<float> dx;
32 for(
size_t n = 0; n < hx.size(); ++n )
35 dx.upload( hx.data(), hx.size() );
36 REQUIRE( dx.size() == hx.size() );
38 cublasHandle_t handle;
40 stat = cublasCreate( &handle );
41 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
43 stat = mx::cuda::cublasTscal( handle, dx.size(), &alpha, dx(), 1 );
44 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
46 dx.download( hx.data() );
48 REQUIRE( hx[0] == 0 );
49 REQUIRE( hx[1] == 2 );
50 REQUIRE( hx[2] == 4 );
51 REQUIRE( hx[3] == 6 );
52 REQUIRE( hx[4] == 8 );
54 stat = cublasDestroy( handle );
56 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
59 WHEN(
"type is double precision real" )
61 std::vector<double> hx;
62 mx::cuda::cudaPtr<double> dx;
66 for(
size_t n = 0; n < hx.size(); ++n )
69 dx.upload( hx.data(), hx.size() );
70 REQUIRE( dx.size() == hx.size() );
72 cublasHandle_t handle;
74 stat = cublasCreate( &handle );
75 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
77 stat = mx::cuda::cublasTscal( handle, dx.size(), &alpha, dx(), 1 );
78 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
80 dx.download( hx.data() );
82 REQUIRE( hx[0] == 0 );
83 REQUIRE( hx[1] == 2 );
84 REQUIRE( hx[2] == 4 );
85 REQUIRE( hx[3] == 6 );
86 REQUIRE( hx[4] == 8 );
88 stat = cublasDestroy( handle );
90 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
93 WHEN(
"type is single precision complex" )
95 std::vector<std::complex<float>> hx;
96 mx::cuda::cudaPtr<std::complex<float>> dx;
97 std::complex<float> alpha = 2;
100 for(
size_t n = 0; n < hx.size(); ++n )
101 hx[n] = std::complex<float>( n, n );
103 dx.upload( hx.data(), hx.size() );
104 REQUIRE( dx.size() == hx.size() );
106 cublasHandle_t handle;
108 stat = cublasCreate( &handle );
109 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
111 stat = mx::cuda::cublasTscal( handle, dx.size(), (cuComplex *)&alpha, dx(), 1 );
112 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
114 dx.download( hx.data() );
116 REQUIRE( hx[0] == std::complex<float>( 0, 0 ) );
117 REQUIRE( hx[1] == std::complex<float>( 2, 2 ) );
118 REQUIRE( hx[2] == std::complex<float>( 4, 4 ) );
119 REQUIRE( hx[3] == std::complex<float>( 6, 6 ) );
120 REQUIRE( hx[4] == std::complex<float>( 8, 8 ) );
122 stat = cublasDestroy( handle );
124 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
127 WHEN(
"type is double precision complex" )
129 std::vector<std::complex<double>> hx;
130 mx::cuda::cudaPtr<std::complex<double>> dx;
131 std::complex<double> alpha = 2;
134 for(
size_t n = 0; n < hx.size(); ++n )
135 hx[n] = std::complex<double>( n, n );
137 dx.upload( hx.data(), hx.size() );
138 REQUIRE( dx.size() == hx.size() );
140 cublasHandle_t handle;
142 stat = cublasCreate( &handle );
143 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
145 stat = mx::cuda::cublasTscal( handle, dx.size(), (cuDoubleComplex *)&alpha, dx(), 1 );
146 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
148 dx.download( hx.data() );
150 REQUIRE( hx[0] == std::complex<double>( 0, 0 ) );
151 REQUIRE( hx[1] == std::complex<double>( 2, 2 ) );
152 REQUIRE( hx[2] == std::complex<double>( 4, 4 ) );
153 REQUIRE( hx[3] == std::complex<double>( 6, 6 ) );
154 REQUIRE( hx[4] == std::complex<double>( 8, 8 ) );
156 stat = cublasDestroy( handle );
158 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
170TEST_CASE(
"scaling and accumulating a vector with cublas",
"[math::cuda::templateCublas]" )
172 if( !mxlibTest::cudaDeviceAvailable() )
174 WARN(
"CUDA runtime is available but no CUDA device is present" );
180 WHEN(
"type is single precision real" )
182 std::vector<float> hx, hy;
183 mx::cuda::cudaPtr<float> dx, dy;
187 for(
size_t n = 0; n < hx.size(); ++n )
191 for(
size_t n = 0; n < hy.size(); ++n )
194 dx.upload( hx.data(), hx.size() );
195 REQUIRE( dx.size() == hx.size() );
197 dy.upload( hy.data(), hy.size() );
198 REQUIRE( dy.size() == hy.size() );
200 cublasHandle_t handle;
202 stat = cublasCreate( &handle );
203 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
205 stat = mx::cuda::cublasTaxpy( handle, dx.size(), &alpha, dx(), 1, dy(), 1 );
206 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
208 dy.download( hy.data() );
210 REQUIRE( hy[0] == 1 );
211 REQUIRE( hy[1] == 3 );
212 REQUIRE( hy[2] == 5 );
213 REQUIRE( hy[3] == 7 );
214 REQUIRE( hy[4] == 9 );
216 stat = cublasDestroy( handle );
218 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
221 WHEN(
"type is double precision real" )
223 std::vector<double> hx, hy;
224 mx::cuda::cudaPtr<double> dx, dy;
228 for(
size_t n = 0; n < hx.size(); ++n )
232 for(
size_t n = 0; n < hy.size(); ++n )
235 dx.upload( hx.data(), hx.size() );
236 REQUIRE( dx.size() == hx.size() );
238 dy.upload( hy.data(), hy.size() );
239 REQUIRE( dy.size() == hy.size() );
241 cublasHandle_t handle;
243 stat = cublasCreate( &handle );
244 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
246 stat = mx::cuda::cublasTaxpy( handle, dx.size(), &alpha, dx(), 1, dy(), 1 );
247 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
249 dy.download( hy.data() );
251 REQUIRE( hy[0] == 1 );
252 REQUIRE( hy[1] == 3 );
253 REQUIRE( hy[2] == 5 );
254 REQUIRE( hy[3] == 7 );
255 REQUIRE( hy[4] == 9 );
257 stat = cublasDestroy( handle );
259 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
262 WHEN(
"type is single precision complex" )
264 std::vector<std::complex<float>> hx, hy;
265 mx::cuda::cudaPtr<std::complex<float>> dx, dy;
266 std::complex<float> alpha = 2;
269 for(
size_t n = 0; n < hx.size(); ++n )
270 hx[n] = std::complex<float>( n, n );
273 for(
size_t n = 0; n < hy.size(); ++n )
274 hy[n] = std::complex<float>( 1, 1 );
276 dx.upload( hx.data(), hx.size() );
277 REQUIRE( dx.size() == hx.size() );
279 dy.upload( hy.data(), hy.size() );
280 REQUIRE( dy.size() == hy.size() );
282 cublasHandle_t handle;
284 stat = cublasCreate( &handle );
285 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
287 stat = mx::cuda::cublasTaxpy( handle, dx.size(), (cuComplex *)&alpha, dx(), 1, dy(), 1 );
288 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
290 dy.download( hy.data() );
292 REQUIRE( hy[0] == std::complex<float>( 1, 1 ) );
293 REQUIRE( hy[1] == std::complex<float>( 3, 3 ) );
294 REQUIRE( hy[2] == std::complex<float>( 5, 5 ) );
295 REQUIRE( hy[3] == std::complex<float>( 7, 7 ) );
296 REQUIRE( hy[4] == std::complex<float>( 9, 9 ) );
298 stat = cublasDestroy( handle );
300 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
303 WHEN(
"type is double precision complex" )
305 std::vector<std::complex<double>> hx, hy;
306 mx::cuda::cudaPtr<std::complex<double>> dx, dy;
307 std::complex<double> alpha = 2;
310 for(
size_t n = 0; n < hx.size(); ++n )
311 hx[n] = std::complex<double>( n, n );
314 for(
size_t n = 0; n < hy.size(); ++n )
315 hy[n] = std::complex<double>( 1, 1 );
317 dx.upload( hx.data(), hx.size() );
318 REQUIRE( dx.size() == hx.size() );
320 dy.upload( hy.data(), hy.size() );
321 REQUIRE( dy.size() == hy.size() );
323 cublasHandle_t handle;
325 stat = cublasCreate( &handle );
326 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
328 stat = mx::cuda::cublasTaxpy( handle, dx.size(), (cuDoubleComplex *)&alpha, dx(), 1, dy(), 1 );
329 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
331 dy.download( hy.data() );
333 REQUIRE( hy[0] == std::complex<double>( 1, 1 ) );
334 REQUIRE( hy[1] == std::complex<double>( 3, 3 ) );
335 REQUIRE( hy[2] == std::complex<double>( 5, 5 ) );
336 REQUIRE( hy[3] == std::complex<double>( 7, 7 ) );
337 REQUIRE( hy[4] == std::complex<double>( 9, 9 ) );
339 stat = cublasDestroy( handle );
341 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
353TEST_CASE(
"multiplying two vectors element by element",
"[math::cuda::templateCublas]" )
355 if( !mxlibTest::cudaDeviceAvailable() )
357 WARN(
"CUDA runtime is available but no CUDA device is present" );
363 WHEN(
"both types are single precision real" )
365 std::vector<float> hx, hy;
366 mx::cuda::cudaPtr<float> dx, dy;
369 for(
size_t n = 0; n < hx.size(); ++n )
373 for(
size_t n = 0; n < hy.size(); ++n )
376 dx.upload( hx.data(), hx.size() );
377 REQUIRE( dx.size() == hx.size() );
379 dy.resize( hy.size() );
380 dy.upload( hy.data() );
381 REQUIRE( dy.size() == hy.size() );
383 cudaError_t rv = mx::cuda::elementwiseXxY( dx(), dy(), dx.size() );
384 REQUIRE( rv == cudaSuccess );
386 dx.download( hx.data() );
388 REQUIRE( hx[0] == 0 );
389 REQUIRE( hx[1] == 2 );
390 REQUIRE( hx[2] == 8 );
391 REQUIRE( hx[3] == 18 );
392 REQUIRE( hx[4] == 32 );
395 WHEN(
"type1 is complex-float, and type2 is float" )
397 std::vector<std::complex<float>> hx;
398 mx::cuda::cudaPtr<std::complex<float>> dx;
400 std::vector<float> hy;
401 mx::cuda::cudaPtr<float> dy;
404 for(
size_t n = 0; n < hx.size(); ++n )
405 hx[n] = std::complex<float>( n, n );
408 for(
size_t n = 0; n < hy.size(); ++n )
411 dx.upload( hx.data(), hx.size() );
412 REQUIRE( dx.size() == hx.size() );
414 dy.resize( hy.size() );
415 dy.upload( hy.data() );
416 REQUIRE( dy.size() == hy.size() );
418 cudaError_t rv = mx::cuda::elementwiseXxY( dx(), dy(), dx.size() );
419 REQUIRE( rv == cudaSuccess );
421 dx.download( hx.data() );
423 REQUIRE( hx[0] == std::complex<float>( 0, 0 ) );
424 REQUIRE( hx[1] == std::complex<float>( 2, 2 ) );
425 REQUIRE( hx[2] == std::complex<float>( 8, 8 ) );
426 REQUIRE( hx[3] == std::complex<float>( 18, 18 ) );
427 REQUIRE( hx[4] == std::complex<float>( 32, 32 ) );
430 WHEN(
"type1 is complex-float, and type2 is complex-float" )
432 std::vector<std::complex<float>> hx;
433 mx::cuda::cudaPtr<std::complex<float>> dx;
435 std::vector<std::complex<float>> hy;
436 mx::cuda::cudaPtr<std::complex<float>> dy;
439 for(
size_t n = 0; n < hx.size(); ++n )
440 hx[n] = std::complex<float>( n, n );
443 for(
size_t n = 0; n < hy.size(); ++n )
444 hy[n] = std::complex<float>( 0, 2 * n );
446 dx.upload( hx.data(), hx.size() );
447 REQUIRE( dx.size() == hx.size() );
449 dy.resize( hy.size() );
450 dy.upload( hy.data() );
451 REQUIRE( dy.size() == hy.size() );
453 cudaError_t rv = mx::cuda::elementwiseXxY( dx(), dy(), dx.size() );
454 REQUIRE( rv == cudaSuccess );
456 dx.download( hx.data() );
458 REQUIRE( hx[0] == std::complex<float>( 0, 0 ) );
459 REQUIRE( hx[1] == std::complex<float>( -2, 2 ) );
460 REQUIRE( hx[2] == std::complex<float>( -8, 8 ) );
461 REQUIRE( hx[3] == std::complex<float>( -18, 18 ) );
462 REQUIRE( hx[4] == std::complex<float>( -32, 32 ) );
465 WHEN(
"both types are double precision real" )
467 std::vector<double> hx, hy;
468 mx::cuda::cudaPtr<double> dx, dy;
471 for(
size_t n = 0; n < hx.size(); ++n )
475 for(
size_t n = 0; n < hy.size(); ++n )
478 dx.upload( hx.data(), hx.size() );
479 REQUIRE( dx.size() == hx.size() );
481 dy.resize( hy.size() );
482 dy.upload( hy.data() );
483 REQUIRE( dy.size() == hy.size() );
485 cudaError_t rv = mx::cuda::elementwiseXxY( dx(), dy(), dx.size() );
486 REQUIRE( rv == cudaSuccess );
488 dx.download( hx.data() );
490 REQUIRE( hx[0] == 0 );
491 REQUIRE( hx[1] == 2 );
492 REQUIRE( hx[2] == 8 );
493 REQUIRE( hx[3] == 18 );
494 REQUIRE( hx[4] == 32 );
497 WHEN(
"type1 is complex-double, and type2 is double" )
499 std::vector<std::complex<double>> hx;
500 mx::cuda::cudaPtr<std::complex<double>> dx;
502 std::vector<double> hy;
503 mx::cuda::cudaPtr<double> dy;
506 for(
size_t n = 0; n < hx.size(); ++n )
507 hx[n] = std::complex<double>( n, n );
510 for(
size_t n = 0; n < hy.size(); ++n )
513 dx.upload( hx.data(), hx.size() );
514 REQUIRE( dx.size() == hx.size() );
516 dy.resize( hy.size() );
517 dy.upload( hy.data() );
518 REQUIRE( dy.size() == hy.size() );
520 cudaError_t rv = mx::cuda::elementwiseXxY( dx(), dy(), dx.size() );
521 REQUIRE( rv == cudaSuccess );
523 dx.download( hx.data() );
525 REQUIRE( hx[0] == std::complex<double>( 0, 0 ) );
526 REQUIRE( hx[1] == std::complex<double>( 2, 2 ) );
527 REQUIRE( hx[2] == std::complex<double>( 8, 8 ) );
528 REQUIRE( hx[3] == std::complex<double>( 18, 18 ) );
529 REQUIRE( hx[4] == std::complex<double>( 32, 32 ) );
532 WHEN(
"type1 is complex-double, and type2 is complex-double" )
534 std::vector<std::complex<double>> hx;
535 mx::cuda::cudaPtr<std::complex<double>> dx;
537 std::vector<std::complex<double>> hy;
538 mx::cuda::cudaPtr<std::complex<double>> dy;
541 for(
size_t n = 0; n < hx.size(); ++n )
542 hx[n] = std::complex<double>( n, n );
545 for(
size_t n = 0; n < hy.size(); ++n )
546 hy[n] = std::complex<double>( 1, 2 * n );
548 dx.upload( hx.data(), hx.size() );
549 REQUIRE( dx.size() == hx.size() );
551 dy.resize( hy.size() );
552 dy.upload( hy.data() );
553 REQUIRE( dy.size() == hy.size() );
555 cudaError_t rv = mx::cuda::elementwiseXxY( dx(), dy(), dx.size() );
556 REQUIRE( rv == cudaSuccess );
558 dx.download( hx.data() );
560 REQUIRE( hx[0] == std::complex<double>( 0, 0 ) );
561 REQUIRE( hx[1] == std::complex<double>( -1, 3 ) );
562 REQUIRE( hx[2] == std::complex<double>( -6, 10 ) );
563 REQUIRE( hx[3] == std::complex<double>( -15, 21 ) );
564 REQUIRE( hx[4] == std::complex<double>( -28, 36 ) );
576TEST_CASE(
"multiplying a vector by a matrix giving increments",
"[math::cuda::templateCublas]" )
578 if( !mxlibTest::cudaDeviceAvailable() )
580 WARN(
"CUDA runtime is available but no CUDA device is present" );
584 GIVEN(
"a 2x2 matrix, float" )
586 WHEN(
"float precision, beta is 0" )
588 std::vector<float> hA;
589 mx::cuda::cudaPtr<float> dA;
591 std::vector<float> hx;
592 mx::cuda::cudaPtr<float> dx;
594 std::vector<float> hy;
595 mx::cuda::cudaPtr<float> dy;
608 dA.upload( hA.data() );
614 dx.upload( hx.data(), hx.size() );
624 cublasHandle_t handle;
626 stat = cublasCreate( &handle );
627 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
629 stat = mx::cuda::cublasTgemv( handle, CUBLAS_OP_N, 2, 2, &alpha, dA(), 2, dx(), 1, &beta, dy(), 1 );
630 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
632 dy.download( hy.data() );
634 REQUIRE( hy[0] == 7 );
635 REQUIRE( hy[1] == 10 );
637 stat = cublasDestroy( handle );
638 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
641 WHEN(
"float precision, beta is 1, but y is all 0" )
643 std::vector<float> hA;
644 mx::cuda::cudaPtr<float> dA;
646 std::vector<float> hx;
647 mx::cuda::cudaPtr<float> dx;
649 std::vector<float> hy;
650 mx::cuda::cudaPtr<float> dy;
663 dA.upload( hA.data() );
669 dx.upload( hx.data(), hx.size() );
679 cublasHandle_t handle;
681 stat = cublasCreate( &handle );
682 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
684 stat = mx::cuda::cublasTgemv( handle, CUBLAS_OP_N, 2, 2, &alpha, dA(), 2, dx(), 1, &beta, dy(), 1 );
685 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
687 dy.download( hy.data() );
689 REQUIRE( hy[0] == 7 );
690 REQUIRE( hy[1] == 10 );
692 stat = cublasDestroy( handle );
693 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
695 WHEN(
"float precision, beta is 1, y is [1,2]" )
697 std::vector<float> hA;
698 mx::cuda::cudaPtr<float> dA;
700 std::vector<float> hx;
701 mx::cuda::cudaPtr<float> dx;
703 std::vector<float> hy;
704 mx::cuda::cudaPtr<float> dy;
717 dA.upload( hA.data() );
723 dx.upload( hx.data(), hx.size() );
730 dy.upload( hx.data() );
735 cublasHandle_t handle;
737 stat = cublasCreate( &handle );
738 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
740 stat = mx::cuda::cublasTgemv( handle, CUBLAS_OP_N, 2, 2, &alpha, dA(), 2, dx(), 1, &beta, dy(), 1 );
741 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
743 dy.download( hy.data() );
745 REQUIRE( hy[0] == 8 );
746 REQUIRE( hy[1] == 12 );
748 stat = cublasDestroy( handle );
749 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
753 GIVEN(
"a 2x2 matrix, double" )
755 WHEN(
"double precision, beta is 0" )
757 std::vector<double> hA;
758 mx::cuda::cudaPtr<double> dA;
760 std::vector<double> hx;
761 mx::cuda::cudaPtr<double> dx;
763 std::vector<double> hy;
764 mx::cuda::cudaPtr<double> dy;
777 dA.upload( hA.data() );
783 dx.upload( hx.data(), hx.size() );
793 cublasHandle_t handle;
795 stat = cublasCreate( &handle );
796 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
798 stat = mx::cuda::cublasTgemv( handle, CUBLAS_OP_N, 2, 2, &alpha, dA(), 2, dx(), 1, &beta, dy(), 1 );
799 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
801 dy.download( hy.data() );
803 REQUIRE( hy[0] == 7 );
804 REQUIRE( hy[1] == 10 );
806 stat = cublasDestroy( handle );
807 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
810 WHEN(
"double precision, beta is 1, but y is all 0" )
812 std::vector<double> hA;
813 mx::cuda::cudaPtr<double> dA;
815 std::vector<double> hx;
816 mx::cuda::cudaPtr<double> dx;
818 std::vector<double> hy;
819 mx::cuda::cudaPtr<double> dy;
832 dA.upload( hA.data() );
838 dx.upload( hx.data(), hx.size() );
848 cublasHandle_t handle;
850 stat = cublasCreate( &handle );
851 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
853 stat = mx::cuda::cublasTgemv( handle, CUBLAS_OP_N, 2, 2, &alpha, dA(), 2, dx(), 1, &beta, dy(), 1 );
854 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
856 dy.download( hy.data() );
858 REQUIRE( hy[0] == 7 );
859 REQUIRE( hy[1] == 10 );
861 stat = cublasDestroy( handle );
862 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
864 WHEN(
"double precision, beta is 1, y is [1,2]" )
866 std::vector<double> hA;
867 mx::cuda::cudaPtr<double> dA;
869 std::vector<double> hx;
870 mx::cuda::cudaPtr<double> dx;
872 std::vector<double> hy;
873 mx::cuda::cudaPtr<double> dy;
886 dA.upload( hA.data() );
892 dx.upload( hx.data(), hx.size() );
899 dy.upload( hx.data() );
904 cublasHandle_t handle;
906 stat = cublasCreate( &handle );
907 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
909 stat = mx::cuda::cublasTgemv( handle, CUBLAS_OP_N, 2, 2, &alpha, dA(), 2, dx(), 1, &beta, dy(), 1 );
910 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );
912 dy.download( hy.data() );
914 REQUIRE( hy[0] == 8 );
915 REQUIRE( hy[1] == 12 );
917 stat = cublasDestroy( handle );
918 REQUIRE( stat == CUBLAS_STATUS_SUCCESS );