extern "C" magma_int_t magma_cbaiter_overlap( magma_c_matrix A, magma_c_matrix b, magma_c_matrix *x, magma_c_solver_par *solver_par, magma_c_preconditioner *precond_par, magma_queue_t queue ) { magma_int_t info = MAGMA_NOTCONVERGED; // prepare solver feedback solver_par->solver = Magma_BAITERO; // some useful variables magmaFloatComplex c_zero = MAGMA_C_ZERO; // initial residual real_Double_t tempo1, tempo2, runtime=0; float residual; magma_int_t localiter = precond_par->maxiter; magma_c_matrix Ah={Magma_CSR}, ACSR={Magma_CSR}, A_d={Magma_CSR}, r={Magma_CSR}, D={Magma_CSR}, R={Magma_CSR}; // setup magma_int_t matrices; matrices = precond_par->levels; struct magma_c_matrix D_d[ 256 ]; struct magma_c_matrix R_d[ 256 ]; magma_int_t overlap; magma_int_t blocksize = 256; if( matrices==2 || matrices==4 || matrices==8 || matrices==16 || matrices==32 || matrices==64 || matrices==128 ){ overlap = blocksize/matrices; }else if( matrices == 1){ overlap = 0; }else{ printf("error: overlap ratio not supported.\n"); goto cleanup; } CHECK( magma_cmtransfer( A, &Ah, A.memory_location, Magma_CPU, queue )); CHECK( magma_cmconvert( Ah, &ACSR, Ah.storage_type, Magma_CSR, queue )); CHECK( magma_cmtransfer( ACSR, &A_d, Magma_CPU, Magma_DEV, queue )); CHECK( magma_cvinit( &r, Magma_DEV, A.num_rows, b.num_cols, c_zero, queue )); CHECK( magma_cresidualvec( A_d, b, *x, &r, &residual, queue)); solver_par->init_res = residual; if ( solver_par->verbose > 0 ) { solver_par->res_vec[0] = (real_Double_t) residual; } // setup for( int i=0; i<matrices; i++ ){ CHECK( magma_ccsrsplit( i*overlap, 256, ACSR, &D, &R, queue )); CHECK( magma_cmtransfer( D, &D_d[i], Magma_CPU, Magma_DEV, queue )); CHECK( magma_cmtransfer( R, &R_d[i], Magma_CPU, Magma_DEV, queue )); magma_cmfree(&D, queue ); magma_cmfree(&R, queue ); } magma_int_t iterinc; if( solver_par->verbose == 0 ){ iterinc = solver_par->maxiter; } else{ iterinc = solver_par->verbose; } solver_par->numiter = 0; solver_par->spmv_count = 0; // block-asynchronous iteration iterator do { tempo1 = magma_sync_wtime( queue ); solver_par->numiter+= iterinc; for( int z=0; z<iterinc; z++){ CHECK( magma_cbajac_csr_overlap( localiter, matrices, overlap, D_d, R_d, b, x, queue )); } tempo2 = magma_sync_wtime( queue ); runtime += tempo2-tempo1; if ( solver_par->verbose > 0 ) { CHECK( magma_cresidualvec( A_d, b, *x, &r, &residual, queue)); solver_par->res_vec[(solver_par->numiter)/solver_par->verbose] = (real_Double_t) residual; solver_par->timing[(solver_par->numiter)/solver_par->verbose] = (real_Double_t) runtime; } } while ( solver_par->numiter+1 <= solver_par->maxiter ); solver_par->runtime = runtime; CHECK( magma_cresidual( A_d, b, *x, &residual, queue)); solver_par->final_res = residual; solver_par->numiter = solver_par->maxiter; if ( solver_par->init_res > solver_par->final_res ){ info = MAGMA_SUCCESS; } else { info = MAGMA_DIVERGENCE; } cleanup: magma_cmfree(&r, queue ); magma_cmfree(&D, queue ); magma_cmfree(&R, queue ); for( int i=0; i<matrices; i++ ){ magma_cmfree(&D_d[i], queue ); magma_cmfree(&R_d[i], queue ); } magma_cmfree(&A_d, queue ); magma_cmfree(&ACSR, queue ); magma_cmfree(&Ah, queue ); solver_par->info = info; return info; } /* magma_cbaiter_overlap */
/* //////////////////////////////////////////////////////////////////////////// -- testing any solver */ int main( int argc, char** argv ) { magma_int_t info = 0; TESTING_INIT(); magma_copts zopts; magma_queue_t queue=NULL; magma_queue_create( &queue ); real_Double_t res; magma_c_matrix A={Magma_CSR}, AT={Magma_CSR}, A2={Magma_CSR}, B={Magma_CSR}, B_d={Magma_CSR}; int i=1; real_Double_t start, end; CHECK( magma_cparse_opts( argc, argv, &zopts, &i, queue )); B.blocksize = zopts.blocksize; B.alignment = zopts.alignment; while( i < argc ) { if ( strcmp("LAPLACE2D", argv[i]) == 0 && i+1 < argc ) { // Laplace test i++; magma_int_t laplace_size = atoi( argv[i] ); CHECK( magma_cm_5stencil( laplace_size, &A, queue )); } else { // file-matrix test CHECK( magma_c_csr_mtx( &A, argv[i], queue )); } printf( "\n# matrix info: %d-by-%d with %d nonzeros\n\n", int(A.num_rows), int(A.num_cols), int(A.nnz) ); // scale matrix CHECK( magma_cmscale( &A, zopts.scaling, queue )); // remove nonzeros in matrix start = magma_sync_wtime( queue ); for (int j=0; j<10; j++) CHECK( magma_cmcsrcompressor( &A, queue )); end = magma_sync_wtime( queue ); printf( " > MAGMA CPU: %.2e seconds.\n", (end-start)/10 ); // transpose CHECK( magma_cmtranspose( A, &AT, queue )); // convert, copy back and forth to check everything works CHECK( magma_cmconvert( AT, &B, Magma_CSR, Magma_CSR, queue )); magma_cmfree(&AT, queue ); CHECK( magma_cmtransfer( B, &B_d, Magma_CPU, Magma_DEV, queue )); magma_cmfree(&B, queue ); start = magma_sync_wtime( queue ); for (int j=0; j<10; j++) CHECK( magma_cmcsrcompressor_gpu( &B_d, queue )); end = magma_sync_wtime( queue ); printf( " > MAGMA GPU: %.2e seconds.\n", (end-start)/10 ); CHECK( magma_cmtransfer( B_d, &B, Magma_DEV, Magma_CPU, queue )); magma_cmfree(&B_d, queue ); CHECK( magma_cmconvert( B, &AT, Magma_CSR, Magma_CSR, queue )); magma_cmfree(&B, queue ); // transpose back CHECK( magma_cmtranspose( AT, &A2, queue )); magma_cmfree(&AT, queue ); CHECK( magma_cmdiff( A, A2, &res, queue )); printf("%% ||A-B||_F = %8.2e\n", res); if ( res < .000001 ) printf("%% tester matrix compressor: ok\n"); else printf("%% tester matrix compressor: failed\n"); magma_cmfree(&A, queue ); magma_cmfree(&A2, queue ); i++; } cleanup: magma_cmfree(&AT, queue ); magma_cmfree(&B, queue ); magma_cmfree(&A, queue ); magma_cmfree(&A2, queue ); magma_queue_destroy( queue ); TESTING_FINALIZE(); return info; }