/* //////////////////////////////////////////////////////////////////////////// -- Testing cheevd */ int main( int argc, char** argv) { TESTING_CUDA_INIT(); cuFloatComplex *h_A, *h_R, *h_work; float *rwork, *w1, *w2; magma_int_t *iwork; float gpu_time, cpu_time; magma_timestr_t start, end; /* Matrix size */ magma_int_t N=0, n2; magma_int_t size[8] = {1024,2048,3072,4032,5184,6016,7040,8064}; magma_int_t i, info; magma_int_t ione = 1, izero = 0; magma_int_t ISEED[4] = {0,0,0,1}; const char *uplo = MagmaLowerStr; const char *jobz = MagmaVectorsStr; magma_int_t checkres; float result[3], eps = lapackf77_slamch( "E" ); if (argc != 1){ for(i = 1; i<argc; i++){ if (strcmp("-N", argv[i])==0) { N = atoi(argv[++i]); } else if ( strcmp("-JV", argv[i]) == 0 ) { jobz = MagmaVectorsStr; } else if ( strcmp("-JN", argv[i]) == 0 ) { jobz = MagmaNoVectorsStr; } } if (N>0) printf(" testing_cheevd -N %d [-JV] [-JN]\n\n", (int) N); else { printf("\nUsage: \n"); printf(" testing_cheevd -N %d [-JV] [-JN]\n\n", (int) N); exit(1); } } else { printf("\nUsage: \n"); printf(" testing_cheevd -N %d [-JV] [-JN]\n\n", 1024); N = size[7]; } checkres = getenv("MAGMA_TESTINGS_CHECK") != NULL; if ( checkres && jobz[0] == MagmaNoVectors ) { printf( "Cannot check results when vectors are not computed (jobz='N')\n" ); checkres = false; } /* Query for workspace sizes */ cuFloatComplex aux_work[1]; float aux_rwork[1]; magma_int_t aux_iwork[1]; magma_cheevd( jobz[0], uplo[0], N, h_R, N, w1, aux_work, -1, aux_rwork, -1, aux_iwork, -1, &info ); magma_int_t lwork, lrwork, liwork; lwork = (magma_int_t) MAGMA_C_REAL( aux_work[0] ); lrwork = (magma_int_t) aux_rwork[0]; liwork = aux_iwork[0]; /* Allocate host memory for the matrix */ TESTING_MALLOC( h_A, cuFloatComplex, N*N ); TESTING_MALLOC( w1, float , N ); TESTING_MALLOC( w2, float , N ); TESTING_HOSTALLOC( h_R, cuFloatComplex, N*N ); TESTING_HOSTALLOC( h_work, cuFloatComplex, lwork ); TESTING_MALLOC( rwork, float, lrwork ); TESTING_MALLOC( iwork, magma_int_t, liwork ); printf(" N CPU Time(s) GPU Time(s) \n"); printf("===================================\n"); for(i=0; i<8; i++){ if (argc==1){ N = size[i]; } n2 = N*N; /* Initialize the matrix */ lapackf77_clarnv( &ione, ISEED, &n2, h_A ); for( int i=0; i<N; i++) { MAGMA_C_SET2REAL( h_A[i*N+i], MAGMA_C_REAL(h_A[i*N+i]) ); } lapackf77_clacpy( MagmaUpperLowerStr, &N, &N, h_A, &N, h_R, &N ); /* warm up run */ magma_cheevd(jobz[0], uplo[0], N, h_R, N, w1, h_work, lwork, rwork, lrwork, iwork, liwork, &info); lapackf77_clacpy( MagmaUpperLowerStr, &N, &N, h_A, &N, h_R, &N ); /* query for optimal workspace sizes */ magma_cheevd(jobz[0], uplo[0], N, h_R, N, w1, h_work, -1, rwork, -1, iwork, -1, &info); int lwork_save = lwork; int lrwork_save = lrwork; int liwork_save = liwork; lwork = min( lwork, (magma_int_t) MAGMA_C_REAL( h_work[0] )); lrwork = min( lrwork, (magma_int_t) rwork[0] ); liwork = min( liwork, iwork[0] ); //printf( "lwork %d, query %d, used %d; liwork %d, query %d, used %d\n", // lwork_save, (magma_int_t) h_work[0], lwork, // liwork_save, iwork[0], liwork ); /* ==================================================================== Performs operation using MAGMA =================================================================== */ start = get_current_time(); magma_cheevd(jobz[0], uplo[0], N, h_R, N, w1, h_work, lwork, rwork, lrwork, iwork, liwork, &info); end = get_current_time(); gpu_time = GetTimerValue(start,end)/1000.; lwork = lwork_save; lrwork = lrwork_save; liwork = liwork_save; if ( checkres ) { /* ===================================================================== Check the results following the LAPACK's [zcds]drvst routine. A is factored as A = U S U' and the following 3 tests computed: (1) | A - U S U' | / ( |A| N ) (2) | I - U'U | / ( N ) (3) | S(with U) - S(w/o U) | / | S | =================================================================== */ float temp1, temp2; cuFloatComplex *tau; lapackf77_chet21(&ione, uplo, &N, &izero, h_A, &N, w1, w1, h_R, &N, h_R, &N, tau, h_work, rwork, &result[0]); lapackf77_clacpy( MagmaUpperLowerStr, &N, &N, h_A, &N, h_R, &N ); magma_cheevd('N', uplo[0], N, h_R, N, w2, h_work, lwork, rwork, lrwork, iwork, liwork, &info); temp1 = temp2 = 0; for(int j=0; j<N; j++){ temp1 = max(temp1, absv(w1[j])); temp1 = max(temp1, absv(w2[j])); temp2 = max(temp2, absv(w1[j]-w2[j])); } result[2] = temp2 / temp1; } /* ===================================================================== Performs operation using LAPACK =================================================================== */ start = get_current_time(); lapackf77_cheevd(jobz, uplo, &N, h_A, &N, w2, h_work, &lwork, rwork, &lrwork, iwork, &liwork, &info); end = get_current_time(); if (info < 0) printf("Argument %d of cheevd had an illegal value.\n", (int) -info); cpu_time = GetTimerValue(start,end)/1000.; /* ===================================================================== Print execution time =================================================================== */ printf("%5d %6.2f %6.2f\n", (int) N, cpu_time, gpu_time); if ( checkres ){ printf("Testing the factorization A = U S U' for correctness:\n"); printf("(1) | A - U S U' | / (|A| N) = %e\n", result[0]*eps); printf("(2) | I - U'U | / N = %e\n", result[1]*eps); printf("(3) | S(w/ U)-S(w/o U)|/ |S| = %e\n\n", result[2]); } if (argc != 1) break; } /* Memory clean up */ TESTING_FREE( h_A); TESTING_FREE( w1); TESTING_FREE( w2); TESTING_FREE( rwork); TESTING_FREE( iwork); TESTING_HOSTFREE(h_work); TESTING_HOSTFREE( h_R); /* Shutdown */ TESTING_CUDA_FINALIZE(); }
/* //////////////////////////////////////////////////////////////////////////// -- Testing cheevd */ int main( int argc, char** argv) { TESTING_INIT(); real_Double_t gpu_time, cpu_time; magmaFloatComplex *h_A, *h_R, *h_work, aux_work[1]; float *rwork, *w1, *w2, result[3], eps, aux_rwork[1]; magma_int_t *iwork, aux_iwork[1]; magma_int_t N, n2, info, lwork, lrwork, liwork, lda; magma_int_t izero = 0; magma_int_t ione = 1; magma_int_t ISEED[4] = {0,0,0,1}; eps = lapackf77_slamch( "E" ); magma_int_t status = 0; magma_opts opts; parse_opts( argc, argv, &opts ); float tol = opts.tolerance * lapackf77_slamch("E"); float tolulp = opts.tolerance * lapackf77_slamch("P"); if ( opts.check && opts.jobz == MagmaNoVec ) { fprintf( stderr, "checking results requires vectors; setting jobz=V (option -JV)\n" ); opts.jobz = MagmaVec; } printf("using: jobz = %s, uplo = %s\n", lapack_vec_const(opts.jobz), lapack_uplo_const(opts.uplo)); printf(" N CPU Time (sec) GPU Time (sec)\n"); printf("=======================================\n"); for( int itest = 0; itest < opts.ntest; ++itest ) { for( int iter = 0; iter < opts.niter; ++iter ) { N = opts.nsize[itest]; n2 = N*N; lda = N; // query for workspace sizes magma_cheevd( opts.jobz, opts.uplo, N, NULL, lda, NULL, aux_work, -1, aux_rwork, -1, aux_iwork, -1, &info ); lwork = (magma_int_t) MAGMA_C_REAL( aux_work[0] ); lrwork = (magma_int_t) aux_rwork[0]; liwork = aux_iwork[0]; /* Allocate host memory for the matrix */ TESTING_MALLOC_CPU( h_A, magmaFloatComplex, N*lda ); TESTING_MALLOC_CPU( w1, float, N ); TESTING_MALLOC_CPU( w2, float, N ); TESTING_MALLOC_CPU( rwork, float, lrwork ); TESTING_MALLOC_CPU( iwork, magma_int_t, liwork ); TESTING_MALLOC_PIN( h_R, magmaFloatComplex, N*lda ); TESTING_MALLOC_PIN( h_work, magmaFloatComplex, lwork ); /* Initialize the matrix */ lapackf77_clarnv( &ione, ISEED, &n2, h_A ); magma_cmake_hermitian( N, h_A, N ); lapackf77_clacpy( MagmaUpperLowerStr, &N, &N, h_A, &lda, h_R, &lda ); /* warm up run */ if ( opts.warmup ) { magma_cheevd( opts.jobz, opts.uplo, N, h_R, lda, w1, h_work, lwork, rwork, lrwork, iwork, liwork, &info ); if (info != 0) printf("magma_cheevd returned error %d: %s.\n", (int) info, magma_strerror( info )); lapackf77_clacpy( MagmaUpperLowerStr, &N, &N, h_A, &lda, h_R, &lda ); } /* ==================================================================== Performs operation using MAGMA =================================================================== */ gpu_time = magma_wtime(); magma_cheevd( opts.jobz, opts.uplo, N, h_R, lda, w1, h_work, lwork, rwork, lrwork, iwork, liwork, &info ); gpu_time = magma_wtime() - gpu_time; if (info != 0) printf("magma_cheevd returned error %d: %s.\n", (int) info, magma_strerror( info )); if ( opts.check ) { /* ===================================================================== Check the results following the LAPACK's [zcds]drvst routine. A is factored as A = U S U' and the following 3 tests computed: (1) | A - U S U' | / ( |A| N ) (2) | I - U'U | / ( N ) (3) | S(with U) - S(w/o U) | / | S | =================================================================== */ float temp1, temp2; // tau=NULL is unused since itype=1 lapackf77_chet21( &ione, lapack_uplo_const(opts.uplo), &N, &izero, h_A, &lda, w1, w1, h_R, &lda, h_R, &lda, NULL, h_work, rwork, &result[0] ); lapackf77_clacpy( MagmaUpperLowerStr, &N, &N, h_A, &lda, h_R, &lda ); magma_cheevd( MagmaNoVec, opts.uplo, N, h_R, lda, w2, h_work, lwork, rwork, lrwork, iwork, liwork, &info ); if (info != 0) printf("magma_cheevd returned error %d: %s.\n", (int) info, magma_strerror( info )); temp1 = temp2 = 0; for( int j=0; j<N; j++ ) { temp1 = max(temp1, fabs(w1[j])); temp1 = max(temp1, fabs(w2[j])); temp2 = max(temp2, fabs(w1[j]-w2[j])); } result[2] = temp2 / (((float)N)*temp1); } /* ===================================================================== Performs operation using LAPACK =================================================================== */ if ( opts.lapack ) { cpu_time = magma_wtime(); lapackf77_cheevd( lapack_vec_const(opts.jobz), lapack_uplo_const(opts.uplo), &N, h_A, &lda, w2, h_work, &lwork, rwork, &lrwork, iwork, &liwork, &info ); cpu_time = magma_wtime() - cpu_time; if (info != 0) printf("lapackf77_cheevd returned error %d: %s.\n", (int) info, magma_strerror( info )); printf("%5d %7.2f %7.2f\n", (int) N, cpu_time, gpu_time); } else { printf("%5d --- %7.2f\n", (int) N, gpu_time); } /* ===================================================================== Print execution time =================================================================== */ if ( opts.check ) { printf("Testing the factorization A = U S U' for correctness:\n"); printf("(1) | A - U S U' | / (|A| N) = %8.2e %s\n", result[0]*eps, (result[0]*eps < tol ? "ok" : "failed") ); printf("(2) | I - U'U | / N = %8.2e %s\n", result[1]*eps, (result[1]*eps < tol ? "ok" : "failed") ); printf("(3) | S(w/ U) - S(w/o U) | / |S| = %8.2e %s\n\n", result[2] , (result[2] < tolulp ? "ok" : "failed") ); status += ! (result[0]*eps < tol && result[1]*eps < tol && result[2] < tolulp); } TESTING_FREE_CPU( h_A ); TESTING_FREE_CPU( w1 ); TESTING_FREE_CPU( w2 ); TESTING_FREE_CPU( rwork ); TESTING_FREE_CPU( iwork ); TESTING_FREE_PIN( h_R ); TESTING_FREE_PIN( h_work ); fflush( stdout ); } if ( opts.niter > 1 ) { printf( "\n" ); } } TESTING_FINALIZE(); return status; }
extern "C" int calc_numerical_range(magmaFloatComplex *M, magma_int_t M_lead_dim, float _from, float _step, magma_int_t _steps, magmaFloatComplex *pts) { magma_int_t idx = 0, rslt = 0; magmaFloatComplex p, scalar; std::complex<float> vtmp; float j; magmaFloatComplex *dA = nullptr; magmaFloatComplex *dAth = NULL, *dAthT = NULL, *dX = NULL, *dY = NULL; float *dE = NULL; //float *hE = NULL; //magma_int_t *ipiv = NULL; magma_int_t lda = M_lead_dim; //magma_int_t ldx = lda; magma_int_t info = 0; magma_int_t nb = 0; //magma_vec_t jobvl; //magma_vec_t jobvr; magmaFloatComplex *work = nullptr; magma_int_t lwork = 0; float *rwork = nullptr; magma_int_t lrwork = 0; magma_int_t *iwork = nullptr; magma_int_t liwork = 0; nb = magma_get_cgehrd_nb( M_lead_dim ); lwork = 2 * max(M_lead_dim + M_lead_dim*nb, 2 * M_lead_dim + M_lead_dim*M_lead_dim); // MagmaVec lrwork = 1 + 5 * M_lead_dim + 2 * M_lead_dim*M_lead_dim; // MagmaVec liwork = (3 + 5 * M_lead_dim); // MagmaVec magma_imalloc_cpu(&iwork, liwork); magma_smalloc_cpu(&rwork, lrwork); magma_cmalloc_pinned(&work, lwork); magma_cmalloc_pinned(&dA, lda*M_lead_dim); magma_cmalloc_pinned(&dAth, lda*M_lead_dim); magma_cmalloc_pinned(&dAthT, lda*M_lead_dim); magma_smalloc_pinned(&dE, M_lead_dim); //magma_smalloc_cpu(&hE, M_lead_dim); magma_cmalloc_pinned(&dX, M_lead_dim); magma_cmalloc_pinned(&dY, M_lead_dim); magma_csetmatrix(M_lead_dim, M_lead_dim, M, lda, dA, M_lead_dim, queue); // th=[0:resolution:2*pi] j = _from; for (idx = 0; idx < _steps; idx++) { //scalar = exp( 1im * -j); vtmp.real( 0.0f ); vtmp.imag( -j ); //vtmp = _FCbuild(0.0f, -j); //printf("vtmp = %f + i%f\n", vtmp._Val[0], vtmp._Val[1]); vtmp = exp(vtmp); scalar.x = vtmp.real(); scalar.y = vtmp.imag(); //printf("scalar = %f + i%f\n", scalar.x, scalar.y); magma_ccopy(lda * M_lead_dim, dA, 1, dAth, 1, queue); // Ath = exp(1im * -j) * As magma_cscal(lda * M_lead_dim, scalar, dAth, 1, queue); //magma_cprint_gpu(N, N, dA, lda); //magma_cprint_gpu(N, N, dAth, lda); // AthT = (Ath + Ath') magmablas_ctranspose_conj(M_lead_dim, M_lead_dim, dAth, M_lead_dim, dAthT, M_lead_dim, queue); magmablas_cgeadd(M_lead_dim, M_lead_dim, MAGMA_C_MAKE(1.0f, 0.0f), dAth, M_lead_dim, dAthT, M_lead_dim, queue); // AthT = AthT / 2 magma_cscal(lda*M_lead_dim, MAGMA_C_MAKE(0.5f, 0.0f), dAthT, 1, queue); magma_sync_wtime(queue); //magma_cprint_gpu(M_lead_dim, M_lead_dim, dAthT, lda); // e, r = eig(AthT) rslt = magma_cheevd(MagmaVec, MagmaLower, M_lead_dim, dAthT, lda, dE, work, lwork, rwork, lrwork, iwork, liwork, &info); magma_sync_wtime(queue); //printf("magma_cheevd info=%d\n", info); //magma_cprint_gpu(M_lead_dim, M_lead_dim, dAthT, lda); //magma_sprint_gpu(M_lead_dim, 1, dE, M_lead_dim); //magma_sgetvector(M_lead_dim, dE, 1, hE, 1, queue); //printf("%f %f\n", hE[0], hE[1]); // p = r[:,s]' * A * r[:,s] // r = r[:,s] magma_ccopy( M_lead_dim, dAthT + (M_lead_dim*(M_lead_dim-1)), 1, // dAthT + (N), where (N) is a column offset dX, 1, queue); magma_sync_wtime(queue); //magma_cprint_gpu(M_lead_dim, 1, dX, M_lead_dim); // pp = A * r[:,s] magma_cgemv(MagmaNoTrans, M_lead_dim, M_lead_dim, MAGMA_C_MAKE(1.0f, 0.0f), dA, lda, dX, 1, MAGMA_C_MAKE(0.0f, 0.0f), dY, 1, queue); magma_sync_wtime(queue); //magma_cprint_gpu(M_lead_dim, 1, dY, M_lead_dim); // p = r' * pp p = magma_cdotc(M_lead_dim, dX, 1, dY, 1, queue); magma_sync_wtime(queue); pts[idx] = p; //printf("p = %f %fi\n", p.x, p.y); j += _step; } // end of for (idx = 0; idx < _steps; idx++) magma_free_pinned(dY); magma_free_pinned(dX); //magma_free_cpu(hE); magma_free_pinned(dE); magma_free_pinned(dAthT); magma_free_pinned(dAth); magma_free_pinned(dA); magma_free_pinned(work); magma_free_cpu(rwork); magma_free_cpu(iwork); //magma_free_cpu(w); //magma_free_cpu(A); return rslt; }
extern "C" int calc_bounding_box(magmaFloatComplex *M, magma_int_t M_lead_dim, float *wReEig, float *wImEig) { magma_int_t rslt = 0; //magmaFloatComplex *AT = nullptr; magmaFloatComplex *dA = nullptr, *dAT = nullptr, *dreA = nullptr, *dimA = nullptr; float *dreEig = nullptr; float *dimEig = nullptr; //magma_int_t *ipiv = NULL; magma_int_t lda = M_lead_dim; //magma_int_t ldx = lda; magma_int_t info = 0; magma_int_t nb = 0; //magma_vec_t jobvl; //magma_vec_t jobvr; magmaFloatComplex *work = nullptr; magma_int_t lwork = 0; float *rwork = nullptr; magma_int_t lrwork = 0; magma_int_t *iwork = nullptr; magma_int_t liwork = 0; nb = magma_get_cgehrd_nb( M_lead_dim ); lwork = 2 * (M_lead_dim + M_lead_dim*nb); // MagmaNoVec //lwork = 2 * max(M_lead_dim + M_lead_dim*nb, 2*M_lead_dim + M_lead_dim*M_lead_dim); // MagmaVec lrwork = M_lead_dim; // MagmaNoVec //lrwork = 1 + 5 * M_lead_dim + 2*M_lead_dim*M_lead_dim; // MagmaVec liwork = 1; // MagmaNoVec //liwork = 3 + 5*M_lead_dim; // MagmaVec magma_imalloc_cpu(&iwork, liwork); magma_smalloc_cpu(&rwork, lrwork); //magma_cmalloc_cpu(&A, lda*M_lead_dim); //magma_cmalloc_cpu(&AT, lda*M_lead_dim); //magma_smalloc_cpu(&reEig, M_lead_dim); //magma_smalloc_cpu(&imEig, M_lead_dim); magma_cmalloc_pinned(&dA, lda*M_lead_dim); magma_cmalloc_pinned(&dAT, lda*M_lead_dim); magma_cmalloc_pinned(&dreA, lda*M_lead_dim); magma_cmalloc_pinned(&dimA, lda*M_lead_dim); //magma_cmalloc_pinned(&VL, lda*M_lead_dim); //magma_cmalloc_pinned(&VR, lda*M_lead_dim); magma_cmalloc_pinned(&work, lwork); magma_smalloc_pinned(&dreEig, M_lead_dim); magma_smalloc_pinned(&dimEig, M_lead_dim); //matrix_fillzero(AT, M_lead_dim); //vector_fillzero(reEig, M_lead_dim); //vector_fillzero(imEig, M_lead_dim); //prepare_matrix_2(M); magma_csetmatrix(M_lead_dim, M_lead_dim, M, lda, dA, M_lead_dim, queue); //magma_csetmatrix(M_lead_dim, M_lead_dim, AT, lda, dAT, M_lead_dim, queue); //magma_ssetvector(M_lead_dim, wReEig, 1, dreEig, 1, queue); //magma_ssetvector(M_lead_dim, wImEig, 1, dimEig, 1, queue); //magma_cprint_gpu(M_lead_dim, M_lead_dim, dA, lda); // reA = ( (A + A')/2.0 ) // A' magmablas_ctranspose(M_lead_dim, M_lead_dim, dA, M_lead_dim, dAT, M_lead_dim, queue); //magma_cprint_gpu(M_lead_dim, M_lead_dim, dAT, lda); // AT = A + A' magmablas_cgeadd(M_lead_dim, M_lead_dim, MAGMA_C_MAKE(1.0f, 0.0f), dA, M_lead_dim, dAT, M_lead_dim, queue); //magma_cprint_gpu(M_lead_dim, M_lead_dim, dAT, lda); // AT=AT*0.5 magma_cscal(lda*M_lead_dim, MAGMA_C_MAKE(0.5f, 0.0f), dAT, 1, queue); //magma_cprint_gpu(M_lead_dim, M_lead_dim, dAT, lda); // reA = AT magma_ccopy(lda*M_lead_dim, dAT, 1, dreA, 1, queue); //magma_cprint_gpu(M_lead_dim, M_lead_dim, dreA, lda); magma_sync_wtime(queue); // imA = ( -1im*(A - A')/2.0 ) // A' magmablas_ctranspose(M_lead_dim, M_lead_dim, dA, M_lead_dim, dAT, M_lead_dim, queue); //magma_cprint_gpu(M_lead_dim, M_lead_dim, dAT, lda); // AT = A + A' magmablas_cgeadd(M_lead_dim, M_lead_dim, MAGMA_C_MAKE(-1.0f, 0.0f), dAT, M_lead_dim, dA, M_lead_dim, queue); // A=A*-1j*0.5 magma_cscal(lda*M_lead_dim, MAGMA_C_MAKE(0.0f, -0.5f), dA, 1, queue); // imA = A magma_ccopy(lda*M_lead_dim, dA, 1, dimA, 1, queue); magma_sync_wtime(queue); //magma_cprint_gpu(M_lead_dim, M_lead_dim, dreA, lda); //magma_cprint_gpu(M_lead_dim, M_lead_dim, dimA, lda); // reEig::Vector=eigvals(reA) rslt = magma_cheevd(MagmaNoVec, MagmaLower, M_lead_dim, dreA, lda, dreEig, work, lwork, rwork, lrwork, iwork, liwork, &info); // imEig::Vector=eigvals(imA) rslt = magma_cheevd(MagmaNoVec, MagmaLower, M_lead_dim, dimA, lda, dimEig, work, lwork, rwork, lrwork, iwork, liwork, &info); //magma_sprint_gpu(M_lead_dim, 1, dreEig, M_lead_dim); //magma_sprint_gpu(M_lead_dim, 1, dimEig, M_lead_dim); magma_sgetvector(M_lead_dim, dreEig, 1, wReEig, 1, queue); //magma_sync_wtime(queue); magma_sgetvector(M_lead_dim, dimEig, 1, wImEig, 1, queue); //magma_sync_wtime(queue); /* maxReIdx = magma_isamax(M_lead_dim, dreEig, 1, queue) - 1; minReIdx = magma_isamin(M_lead_dim, dreEig, 1, queue) - 1; maxImIdx = magma_isamax(M_lead_dim, dimEig, 1, queue) - 1; minImIdx = magma_isamin(M_lead_dim, dimEig, 1, queue) - 1; printf("max re idx = %d\nmin re idx = %d\n", maxReIdx, minReIdx); printf("%f %f\n", wReEig[maxReIdx], wReEig[minReIdx]); printf("max im idx = %d\nmin im idx = %d\n", maxImIdx, minImIdx); printf("%f %f\n", wImEig[maxImIdx], wImEig[minImIdx]); */ //printf("test wReEig: %f %f\n", wReEig[0], wReEig[1]); //printf("test wImEig: %f %f\n", wImEig[0], wImEig[1]); magma_free_cpu(iwork); magma_free_cpu(rwork); //magma_free_cpu(AT); magma_free_pinned(dA); magma_free_pinned(dAT); magma_free_pinned(dreA); magma_free_pinned(dimA); magma_free_pinned(work); magma_free_pinned(dreEig); magma_free_pinned(dimEig); return rslt; }
/* //////////////////////////////////////////////////////////////////////////// -- Testing cheevd */ int main( int argc, char** argv) { TESTING_INIT(); /* Constants */ const float d_zero = 0; const magma_int_t izero = 0; const magma_int_t ione = 1; /* Local variables */ real_Double_t gpu_time, cpu_time; magmaFloatComplex *h_A, *h_R, *h_Z, *h_work, aux_work[1]; #ifdef COMPLEX float *rwork, aux_rwork[1]; magma_int_t lrwork; #endif float *w1, *w2, result[4]={0, 0, 0, 0}, eps, abstol; magma_int_t *iwork, *isuppz, *ifail, aux_iwork[1]; magma_int_t N, n2, info, lwork, liwork, lda; magma_int_t ISEED[4] = {0,0,0,1}; eps = lapackf77_slamch( "E" ); magma_int_t status = 0; magma_opts opts; opts.parse_opts( argc, argv ); // checking NoVec requires LAPACK opts.lapack |= (opts.check && opts.jobz == MagmaNoVec); magma_range_t range = MagmaRangeAll; if (opts.fraction != 1) range = MagmaRangeI; #ifdef REAL if (opts.version == 3 || opts.version == 4) { printf("%% magma_cheevr and magma_cheevx are not available for real precisions (single, float).\n"); return status; } #endif float tol = opts.tolerance * lapackf77_slamch("E"); float tolulp = opts.tolerance * lapackf77_slamch("P"); // pass ngpu = -1 to test multi-GPU code using 1 gpu magma_int_t abs_ngpu = abs( opts.ngpu ); printf("%% jobz = %s, range = %s, uplo = %s, fraction = %6.4f, ngpu = %d\n", lapack_vec_const(opts.jobz), lapack_range_const(range), lapack_uplo_const(opts.uplo), opts.fraction, int(abs_ngpu) ); printf("%% N CPU Time (sec) GPU Time (sec) |S-S_magma| |A-USU^H| |I-U^H U|\n"); printf("%%============================================================================\n"); for( int itest = 0; itest < opts.ntest; ++itest ) { for( int iter = 0; iter < opts.niter; ++iter ) { N = opts.nsize[itest]; n2 = N*N; lda = N; abstol = 0; // auto, in cheevr // TODO: test vl-vu range magma_int_t m1 = 0; float vl = 0; float vu = 0; magma_int_t il = 0; magma_int_t iu = 0; if (opts.fraction == 0) { il = max( 1, magma_int_t(0.1*N) ); iu = max( 1, magma_int_t(0.3*N) ); } else { il = 1; iu = max( 1, magma_int_t(opts.fraction*N) ); } // query for workspace sizes if ( opts.version == 1 || opts.version == 2 ) { magma_cheevd( opts.jobz, opts.uplo, N, NULL, lda, NULL, // A, w aux_work, -1, #ifdef COMPLEX aux_rwork, -1, #endif aux_iwork, -1, &info ); } else if ( opts.version == 3 ) { #ifdef COMPLEX magma_cheevr( opts.jobz, range, opts.uplo, N, NULL, lda, // A vl, vu, il, iu, abstol, &m1, NULL, // w NULL, lda, NULL, // Z, isuppz aux_work, -1, #ifdef COMPLEX aux_rwork, -1, #endif aux_iwork, -1, &info ); #endif } else if ( opts.version == 4 ) { #ifdef COMPLEX magma_cheevx( opts.jobz, range, opts.uplo, N, NULL, lda, // A vl, vu, il, iu, abstol, &m1, NULL, // w NULL, lda, // Z aux_work, -1, #ifdef COMPLEX aux_rwork, #endif aux_iwork, NULL, // ifail &info ); // cheevx doesn't query rwork, iwork; set them for consistency aux_rwork[0] = float(7*N); aux_iwork[0] = float(5*N); #endif } lwork = (magma_int_t) MAGMA_C_REAL( aux_work[0] ); #ifdef COMPLEX lrwork = (magma_int_t) aux_rwork[0]; #endif liwork = aux_iwork[0]; /* Allocate host memory for the matrix */ TESTING_MALLOC_CPU( h_A, magmaFloatComplex, N*lda ); TESTING_MALLOC_CPU( w1, float, N ); TESTING_MALLOC_CPU( w2, float, N ); #ifdef COMPLEX TESTING_MALLOC_CPU( rwork, float, lrwork ); #endif TESTING_MALLOC_CPU( iwork, magma_int_t, liwork ); TESTING_MALLOC_PIN( h_R, magmaFloatComplex, N*lda ); TESTING_MALLOC_PIN( h_work, magmaFloatComplex, lwork ); if (opts.version == 3) { TESTING_MALLOC_CPU( h_Z, magmaFloatComplex, N*lda ); TESTING_MALLOC_CPU( isuppz, magma_int_t, 2*max(1,N) ); } if (opts.version == 4) { TESTING_MALLOC_CPU( h_Z, magmaFloatComplex, N*lda ); TESTING_MALLOC_CPU( ifail, magma_int_t, N ); } /* Clear eigenvalues, for |S-S_magma| check when fraction < 1. */ lapackf77_slaset( "Full", &N, &ione, &d_zero, &d_zero, w1, &N ); lapackf77_slaset( "Full", &N, &ione, &d_zero, &d_zero, w2, &N ); /* Initialize the matrix */ lapackf77_clarnv( &ione, ISEED, &n2, h_A ); magma_cmake_hermitian( N, h_A, lda ); lapackf77_clacpy( MagmaFullStr, &N, &N, h_A, &lda, h_R, &lda ); /* ==================================================================== Performs operation using MAGMA =================================================================== */ gpu_time = magma_wtime(); if (opts.version == 1) { if (opts.ngpu == 1) { magma_cheevd( opts.jobz, opts.uplo, N, h_R, lda, w1, h_work, lwork, #ifdef COMPLEX rwork, lrwork, #endif iwork, liwork, &info ); } else { //printf( "magma_cheevd_m, ngpu %d (%d)\n", opts.ngpu, abs_ngpu ); magma_cheevd_m( abs_ngpu, opts.jobz, opts.uplo, N, h_R, lda, w1, h_work, lwork, #ifdef COMPLEX rwork, lrwork, #endif iwork, liwork, &info ); } } else if ( opts.version == 2 ) { // version 2: cheevdx computes selected eigenvalues/vectors if (opts.ngpu == 1) { magma_cheevdx( opts.jobz, range, opts.uplo, N, h_R, lda, vl, vu, il, iu, &m1, w1, h_work, lwork, #ifdef COMPLEX rwork, lrwork, #endif iwork, liwork, &info ); } else { //printf( "magma_cheevdx_m, ngpu %d (%d)\n", opts.ngpu, abs_ngpu ); magma_cheevdx_m( abs_ngpu, opts.jobz, range, opts.uplo, N, h_R, lda, vl, vu, il, iu, &m1, w1, h_work, lwork, #ifdef COMPLEX rwork, lrwork, #endif iwork, liwork, &info ); } //printf( "il %d, iu %d, m1 %d\n", il, iu, m1 ); } else if ( opts.version == 3 ) { // version 3: MRRR, computes selected eigenvalues/vectors // only complex version available #ifdef COMPLEX magma_cheevr( opts.jobz, range, opts.uplo, N, h_R, lda, vl, vu, il, iu, abstol, &m1, w1, h_Z, lda, isuppz, h_work, lwork, #ifdef COMPLEX rwork, lrwork, #endif iwork, liwork, &info ); lapackf77_clacpy( "Full", &N, &N, h_Z, &lda, h_R, &lda ); #endif } else if ( opts.version == 4 ) { // version 3: cheevx (QR iteration), computes selected eigenvalues/vectors // only complex version available #ifdef COMPLEX magma_cheevx( opts.jobz, range, opts.uplo, N, h_R, lda, vl, vu, il, iu, abstol, &m1, w1, h_Z, lda, h_work, lwork, #ifdef COMPLEX rwork, /*lrwork,*/ #endif iwork, /*liwork,*/ ifail, &info ); lapackf77_clacpy( "Full", &N, &N, h_Z, &lda, h_R, &lda ); #endif } gpu_time = magma_wtime() - gpu_time; if (info != 0) { printf("magma_cheevd returned error %d: %s.\n", (int) info, magma_strerror( info )); } bool okay = true; if ( opts.check && opts.jobz != MagmaNoVec ) { /* ===================================================================== Check the results following the LAPACK's [zcds]drvst routine. A is factored as A = U S U^H and the following 3 tests computed: (1) | A - U S U^H | / ( |A| N ) (2) | I - U^H U | / ( N ) (3) | S(with U) - S(w/o U) | / | S | // currently disabled, but compares to LAPACK =================================================================== */ magmaFloatComplex *work; TESTING_MALLOC_CPU( work, magmaFloatComplex, 2*N*N ); // e=NULL is unused since kband=0; tau=NULL is unused since itype=1 lapackf77_chet21( &ione, lapack_uplo_const(opts.uplo), &N, &izero, h_A, &lda, w1, NULL, h_R, &lda, h_R, &lda, NULL, work, #ifdef COMPLEX rwork, #endif &result[0] ); result[0] *= eps; result[1] *= eps; TESTING_FREE_CPU( work ); work=NULL; // Disable third eigenvalue check that calls routine again -- // it obscures whether error occurs in first call above or in this call. // But see comparison to LAPACK below. // //lapackf77_clacpy( MagmaFullStr, &N, &N, h_A, &lda, h_R, &lda ); //magma_cheevd( MagmaNoVec, opts.uplo, // N, h_R, lda, w2, // h_work, lwork, // #ifdef COMPLEX // rwork, lrwork, // #endif // iwork, liwork, // &info ); //if (info != 0) { // printf("magma_cheevd returned error %d: %s.\n", // (int) info, magma_strerror( info )); //} // //float maxw=0, diff=0; //for( int j=0; j < N; j++ ) { // maxw = max(maxw, fabs(w1[j])); // maxw = max(maxw, fabs(w2[j])); // diff = max(diff, fabs(w1[j]-w2[j])); //} //result[2] = diff / (N*maxw); } /* ===================================================================== Performs operation using LAPACK =================================================================== */ if ( opts.lapack ) { cpu_time = magma_wtime(); if ( opts.version == 1 || opts.version == 2 ) { lapackf77_cheevd( lapack_vec_const(opts.jobz), lapack_uplo_const(opts.uplo), &N, h_A, &lda, w2, h_work, &lwork, #ifdef COMPLEX rwork, &lrwork, #endif iwork, &liwork, &info ); } else if ( opts.version == 3 ) { lapackf77_cheevr( lapack_vec_const(opts.jobz), lapack_range_const(range), lapack_uplo_const(opts.uplo), &N, h_A, &lda, &vl, &vu, &il, &iu, &abstol, &m1, w2, h_Z, &lda, isuppz, h_work, &lwork, #ifdef COMPLEX rwork, &lrwork, #endif iwork, &liwork, &info ); lapackf77_clacpy( "Full", &N, &N, h_Z, &lda, h_A, &lda ); } else if ( opts.version == 4 ) { lapackf77_cheevx( lapack_vec_const(opts.jobz), lapack_range_const(range), lapack_uplo_const(opts.uplo), &N, h_A, &lda, &vl, &vu, &il, &iu, &abstol, &m1, w2, h_Z, &lda, h_work, &lwork, #ifdef COMPLEX rwork, #endif iwork, ifail, &info ); lapackf77_clacpy( "Full", &N, &N, h_Z, &lda, h_A, &lda ); } cpu_time = magma_wtime() - cpu_time; if (info != 0) { printf("lapackf77_cheevd returned error %d: %s.\n", (int) info, magma_strerror( info )); } // compare eigenvalues float maxw=0, diff=0; for( int j=0; j < N; j++ ) { maxw = max(maxw, fabs(w1[j])); maxw = max(maxw, fabs(w2[j])); diff = max(diff, fabs(w1[j] - w2[j])); } result[3] = diff / (N*maxw); okay = okay && (result[3] < tolulp); printf("%5d %9.4f %9.4f %8.2e ", (int) N, cpu_time, gpu_time, result[3] ); } else { printf("%5d --- %9.4f --- ", (int) N, gpu_time); } // print error checks if ( opts.check && opts.jobz != MagmaNoVec ) { okay = okay && (result[0] < tol) && (result[1] < tol); printf(" %8.2e %8.2e", result[0], result[1] ); } else { printf(" --- --- "); } printf(" %s\n", (okay ? "ok" : "failed")); status += ! okay; TESTING_FREE_CPU( h_A ); TESTING_FREE_CPU( w1 ); TESTING_FREE_CPU( w2 ); #ifdef COMPLEX TESTING_FREE_CPU( rwork ); #endif TESTING_FREE_CPU( iwork ); TESTING_FREE_PIN( h_R ); TESTING_FREE_PIN( h_work ); if ( opts.version == 3 ) { TESTING_FREE_CPU( h_Z ); TESTING_FREE_CPU( isuppz ); } if ( opts.version == 4 ) { TESTING_FREE_CPU( h_Z ); TESTING_FREE_CPU( ifail ); } fflush( stdout ); } if ( opts.niter > 1 ) { printf( "\n" ); } } opts.cleanup(); TESTING_FINALIZE(); return status; }