magma_int_t magma_scustomicsetup( magma_s_matrix A, magma_s_matrix b, magma_s_preconditioner *precond, magma_queue_t queue ) { magma_int_t info = 0; cusparseHandle_t cusparseHandle=NULL; cusparseMatDescr_t descrL=NULL; cusparseMatDescr_t descrU=NULL; magma_s_matrix hA={Magma_CSR}; char preconditionermatrix[255]; snprintf( preconditionermatrix, sizeof(preconditionermatrix), "precondL.mtx" ); CHECK( magma_s_csr_mtx( &hA, preconditionermatrix , queue) ); // for CUSPARSE CHECK( magma_smtransfer( hA, &precond->M, Magma_CPU, Magma_DEV , queue )); // copy the matrix to precond->L and (transposed) to precond->U CHECK( magma_smtransfer(precond->M, &(precond->L), Magma_DEV, Magma_DEV, queue )); CHECK( magma_smtranspose( precond->L, &(precond->U), queue )); // extract the diagonal of L into precond->d CHECK( magma_sjacobisetup_diagscal( precond->L, &precond->d, queue )); CHECK( magma_svinit( &precond->work1, Magma_DEV, hA.num_rows, 1, MAGMA_S_ZERO, queue )); // extract the diagonal of U into precond->d2 CHECK( magma_sjacobisetup_diagscal( precond->U, &precond->d2, queue )); CHECK( magma_svinit( &precond->work2, Magma_DEV, hA.num_rows, 1, MAGMA_S_ZERO, queue )); // CUSPARSE context // CHECK_CUSPARSE( cusparseCreate( &cusparseHandle )); CHECK_CUSPARSE( cusparseCreateMatDescr( &descrL )); CHECK_CUSPARSE( cusparseSetMatType( descrL, CUSPARSE_MATRIX_TYPE_TRIANGULAR )); CHECK_CUSPARSE( cusparseSetMatDiagType( descrL, CUSPARSE_DIAG_TYPE_NON_UNIT )); CHECK_CUSPARSE( cusparseSetMatIndexBase( descrL, CUSPARSE_INDEX_BASE_ZERO )); CHECK_CUSPARSE( cusparseSetMatFillMode( descrL, CUSPARSE_FILL_MODE_LOWER )); CHECK_CUSPARSE( cusparseCreateSolveAnalysisInfo( &precond->cuinfoL )); CHECK_CUSPARSE( cusparseScsrsv_analysis( cusparseHandle, CUSPARSE_OPERATION_NON_TRANSPOSE, precond->M.num_rows, precond->M.nnz, descrL, precond->M.val, precond->M.row, precond->M.col, precond->cuinfoL )); CHECK_CUSPARSE( cusparseCreateMatDescr( &descrU )); CHECK_CUSPARSE( cusparseSetMatType( descrU, CUSPARSE_MATRIX_TYPE_TRIANGULAR )); CHECK_CUSPARSE( cusparseSetMatDiagType( descrU, CUSPARSE_DIAG_TYPE_NON_UNIT )); CHECK_CUSPARSE( cusparseSetMatIndexBase( descrU, CUSPARSE_INDEX_BASE_ZERO )); CHECK_CUSPARSE( cusparseSetMatFillMode( descrU, CUSPARSE_FILL_MODE_LOWER )); CHECK_CUSPARSE( cusparseCreateSolveAnalysisInfo( &precond->cuinfoU )); CHECK_CUSPARSE( cusparseScsrsv_analysis( cusparseHandle, CUSPARSE_OPERATION_TRANSPOSE, precond->M.num_rows, precond->M.nnz, descrU, precond->M.val, precond->M.row, precond->M.col, precond->cuinfoU )); cleanup: cusparseDestroy( cusparseHandle ); cusparseDestroyMatDescr( descrL ); cusparseDestroyMatDescr( descrU ); cusparseHandle=NULL; descrL=NULL; descrU=NULL; magma_smfree( &hA, queue ); return info; }
extern "C" magma_int_t magma_sjacobi( magma_s_matrix A, magma_s_matrix b, magma_s_matrix *x, magma_s_solver_par *solver_par, magma_queue_t queue ) { magma_int_t info = MAGMA_NOTCONVERGED; // some useful variables float c_zero = MAGMA_S_ZERO; real_Double_t tempo1, tempo2, runtime=0; float residual; //float nom0 = 0.0; magma_s_matrix r={Magma_CSR}, d={Magma_CSR}, ACSR={Magma_CSR}; CHECK( magma_smconvert(A, &ACSR, A.storage_type, Magma_CSR, queue ) ); // prepare solver feedback solver_par->solver = Magma_JACOBI; solver_par->info = MAGMA_SUCCESS; // solver setup CHECK( magma_svinit( &r, Magma_DEV, A.num_rows, b.num_cols, c_zero, queue )); CHECK( magma_sresidualvec( ACSR, b, *x, &r, &residual, queue)); solver_par->init_res = residual; if ( solver_par->verbose > 0 ) { solver_par->res_vec[0] = (real_Double_t) residual; } //nom0 = residual; // Jacobi setup CHECK( magma_sjacobisetup_diagscal( ACSR, &d, queue )); magma_s_solver_par jacobiiter_par; if ( solver_par->verbose > 0 ) { jacobiiter_par.maxiter = solver_par->verbose; } else { jacobiiter_par.maxiter = solver_par->maxiter; } solver_par->numiter = 0; solver_par->spmv_count = 0; // Jacobi iterator do { tempo1 = magma_sync_wtime( queue ); solver_par->numiter = solver_par->numiter+jacobiiter_par.maxiter; //CHECK( magma_sjacobiiter_sys( A, b, d, r, x, &jacobiiter_par, queue ) ); CHECK( magma_sjacobispmvupdate(jacobiiter_par.maxiter, ACSR, r, b, d, x, queue )); solver_par->spmv_count = solver_par->spmv_count+jacobiiter_par.maxiter; tempo2 = magma_sync_wtime( queue ); runtime += tempo2 - tempo1; //CHECK( magma_sjacobispmvupdate_bw(jacobiiter_par.maxiter, A, r, b, d, x, queue )); if ( solver_par->verbose > 0 ) { CHECK( magma_sresidualvec( ACSR, 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 = (real_Double_t) runtime; CHECK( magma_sresidualvec( A, b, *x, &r, &residual, queue)); solver_par->final_res = residual; if ( solver_par->init_res > solver_par->final_res ) info = MAGMA_SUCCESS; else info = MAGMA_DIVERGENCE; cleanup: magma_smfree( &r, queue ); magma_smfree( &d, queue ); magma_smfree( &ACSR, queue ); solver_par->info = info; return info; } /* magma_sjacobi */