LIS_INT lis_matrix_set_csr(LIS_INT nnz, LIS_INT *ptr, LIS_INT *index, LIS_SCALAR *value, LIS_MATRIX A) { LIS_INT err; LIS_DEBUG_FUNC_IN; #if 0 err = lis_matrix_check(A,LIS_MATRIX_CHECK_SET); if( err ) return err; #else if(lis_matrix_is_assembled(A)) return LIS_SUCCESS; else { err = lis_matrix_check(A,LIS_MATRIX_CHECK_SET); if( err ) return err; } #endif A->ptr = ptr; A->index = index; A->value = value; A->is_copy = LIS_FALSE; A->status = -LIS_MATRIX_CSR; A->nnz = nnz; LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; }
LIS_INT lis_matrix_setDLU_csr(LIS_INT nnzl, LIS_INT nnzu, LIS_SCALAR *diag, LIS_INT *lptr, LIS_INT *lindex, LIS_SCALAR *lvalue, LIS_INT *uptr, LIS_INT *uindex, LIS_SCALAR *uvalue, LIS_MATRIX A) { LIS_INT err; LIS_MATRIX_DIAG D; LIS_DEBUG_FUNC_IN; #if 0 err = lis_matrix_check(A,LIS_MATRIX_CHECK_SET); if( err ) return err; #else if(lis_matrix_is_assembled(A)) return LIS_SUCCESS; else { err = lis_matrix_check(A,LIS_MATRIX_CHECK_SET); if( err ) return err; } #endif A->L = (LIS_MATRIX_CORE)lis_calloc(sizeof(struct LIS_MATRIX_CORE_STRUCT), "lis_matrix_setDLU_csr::A->L"); if( A->L==NULL ) { LIS_SETERR_MEM(sizeof(struct LIS_MATRIX_CORE_STRUCT)); return LIS_OUT_OF_MEMORY; } A->U = (LIS_MATRIX_CORE)lis_calloc(sizeof(struct LIS_MATRIX_CORE_STRUCT), "lis_matrix_setDLU_csr::A->U"); if( A->U==NULL ) { LIS_SETERR_MEM(sizeof(struct LIS_MATRIX_CORE_STRUCT)); lis_matrix_DLU_destroy(A); return LIS_OUT_OF_MEMORY; } err = lis_matrix_diag_create(A->n,0,A->comm,&D); if( err ) { lis_matrix_DLU_destroy(A); return err; } lis_free(D->value); D->value = diag; A->D = D; A->L->nnz = nnzl; A->L->ptr = lptr; A->L->index = lindex; A->L->value = lvalue; A->U->nnz = nnzu; A->U->ptr = uptr; A->U->index = uindex; A->U->value = uvalue; A->is_copy = LIS_FALSE; A->status = -LIS_MATRIX_CSR; A->is_splited = LIS_TRUE; LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; }
LIS_INT lis_output(LIS_MATRIX A, LIS_VECTOR b, LIS_VECTOR x, LIS_INT format, char *path) { LIS_INT err; LIS_MATRIX B; LIS_DEBUG_FUNC_IN; #ifdef USE_MPI MPI_Barrier(A->comm); #endif err = lis_matrix_check(A,LIS_MATRIX_CHECK_ALL); if( err ) return err; if( format==LIS_FMT_MM || format==LIS_FMT_MMB ) { switch( A->matrix_type ) { case LIS_MATRIX_CSR: err = lis_output_mm_csr(A,b,x,format,path); break; default: err = lis_matrix_duplicate(A,&B); if( err ) return err; lis_matrix_set_type(B,LIS_MATRIX_CSR); err = lis_matrix_convert(A,B); if( err ) return err; err = lis_output_mm_csr(B,b,x,format,path); lis_matrix_destroy(B); break; } } LIS_DEBUG_FUNC_OUT; return err; }
LIS_INT lis_input(LIS_MATRIX A, LIS_VECTOR b, LIS_VECTOR x, char *filename) { LIS_INT err; LIS_INT fileformat; char buf[256],banner[128]; FILE *file; LIS_DEBUG_FUNC_IN; err = lis_matrix_check(A,LIS_MATRIX_CHECK_NULL); if( err ) return err; if( b!=NULL && x!=NULL ) { err = lis_vector_check(b,LIS_VECTOR_CHECK_NULL); if( err ) return err; err = lis_vector_check(x,LIS_VECTOR_CHECK_NULL); if( err ) return err; } if( filename==NULL ) { LIS_SETERR(LIS_ERR_ILL_ARG,"filname is NULL\n"); return LIS_ERR_ILL_ARG; } file = fopen(filename, "r"); if( file==NULL ) { LIS_SETERR1(LIS_ERR_FILE_IO,"cannot open file %s\n",filename); return LIS_ERR_FILE_IO; } /* file format check */ if( fgets(buf, 256, file) == NULL ) { fclose(file); return LIS_ERR_FILE_IO; } sscanf(buf, "%s", banner); if( strncmp(banner, MM_BANNER, strlen(MM_BANNER)) == 0) { fileformat = LIS_FMT_MM; } /* else if( strncmp(banner, LISBanner, strlen(LISBanner)) == 0) { fileformat = LIS_FMT_LIS; } else if( strncmp(banner, ITBLBanner, strlen(ITBLBanner)) == 0) { fileformat = LIS_FMT_ITBL; } */ else { fileformat = LIS_FMT_HB; } rewind(file); /* if( fileformat==LIS_FMT_FREE ) { fclose(file); err = lis_input_option(&option, filename); if( err ) return err; file = fopen(option.filename, "r"); if( file==NULL ) { LIS_SETERR1(LIS_ERR_FILE_IO,"cannot open file %s\n",filename); return LIS_ERR_FILE_IO; } } */ switch( fileformat ) { case LIS_FMT_MM: err = lis_input_mm(A,b,x,file); break; case LIS_FMT_HB: err = lis_input_hb(A,b,x,file); break; /* case LIS_FMT_ITBL: err = lis_input_mmm(A,b,x,file,comm,matrix_type,bnr,bnc,row,col); break; case LIS_FMT_LIS: err = lis_input_lis(A,b,x,filename,file,comm,matrix_type,bnr,bnc,row,col); break; case LIS_FMT_FREE: err = lis_input_free(A,b,x,option,file,comm,matrix_type,bnr,bnc,row,col); break; */ default: fclose(file); return err; } fclose(file); #ifdef USE_MPI MPI_Barrier(A->comm); #endif LIS_DEBUG_FUNC_OUT; return err; }
LIS_INT lis_matrix_copyDLU_csr(LIS_MATRIX Ain, LIS_MATRIX_DIAG *D, LIS_MATRIX *L, LIS_MATRIX *U) { LIS_INT err; LIS_INT i,n,np,lnnz,unnz; LIS_INT *lptr,*lindex; LIS_INT *uptr,*uindex; LIS_SCALAR *lvalue,*uvalue,*diag; LIS_DEBUG_FUNC_IN; *D = NULL; *L = NULL; *U = NULL; err = lis_matrix_check(Ain,LIS_MATRIX_CHECK_ALL); if( err ) return err; n = Ain->n; np = Ain->np; err = lis_matrix_duplicate(Ain,L); if( err ) { return err; } err = lis_matrix_duplicate(Ain,U); if( err ) { lis_matrix_destroy(*L); return err; } err = lis_matrix_diag_duplicateM(Ain,D); if( err ) { lis_matrix_destroy(*L); lis_matrix_destroy(*U); return err; } lis_free((*D)->value); if( Ain->is_splited ) { } lnnz = Ain->L->nnz; unnz = Ain->U->nnz; lptr = NULL; lindex = NULL; uptr = NULL; uindex = NULL; diag = NULL; err = lis_matrix_malloc_csr(n,lnnz,&lptr,&lindex,&lvalue); if( err ) { return err; } err = lis_matrix_malloc_csr(n,unnz,&uptr,&uindex,&uvalue); if( err ) { lis_free2(7,diag,uptr,lptr,uindex,lindex,uvalue,lvalue); return err; } diag = (LIS_SCALAR *)lis_malloc(np*sizeof(LIS_SCALAR),"lis_matrix_copyDLU_csr::diag"); if( diag==NULL ) { lis_free2(7,diag,uptr,lptr,uindex,lindex,uvalue,lvalue); return err; } #ifdef _OPENMP #pragma omp parallel for private(i) #endif for(i=0;i<n;i++) { diag[i] = Ain->D->value[i]; } lis_matrix_elements_copy_csr(n,Ain->L->ptr,Ain->L->index,Ain->L->value,lptr,lindex,lvalue); lis_matrix_elements_copy_csr(n,Ain->U->ptr,Ain->U->index,Ain->U->value,uptr,uindex,uvalue); (*D)->value = diag; err = lis_matrix_set_csr(lnnz,lptr,lindex,lvalue,*L); if( err ) { lis_free2(7,diag,uptr,lptr,uindex,lindex,uvalue,lvalue); return err; } err = lis_matrix_set_csr(unnz,uptr,uindex,uvalue,*U); if( err ) { lis_free2(7,diag,uptr,lptr,uindex,lindex,uvalue,lvalue); return err; } err = lis_matrix_assemble(*L); if( err ) { return err; } err = lis_matrix_assemble(*U); if( err ) { return err; } LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; }
LIS_INT lis_esolve(LIS_MATRIX A, LIS_VECTOR x, LIS_SCALAR *evalue0, LIS_ESOLVER esolver) { LIS_INT nesolver,niesolver,emaxiter; LIS_SCALAR *evalue; LIS_VECTOR *evector; LIS_SCALAR *resid; LIS_SCALAR *rhistory; LIS_INT *iter,*iter2; LIS_INT err; LIS_INT output; LIS_INT ss, mode; double time; double gshift; LIS_INT estorage,eblock; LIS_MATRIX B; LIS_INT eprecision; LIS_VECTOR xx; LIS_DEBUG_FUNC_IN; /* begin parameter check */ err = lis_matrix_check(A,LIS_MATRIX_CHECK_ALL); if( err ) return err; if( x==NULL ) { LIS_SETERR(LIS_ERR_ILL_ARG,"vector x is undefined\n"); return LIS_ERR_ILL_ARG; } if( A->n!=x->n ) { return LIS_ERR_ILL_ARG; } if( A->gn<=0 ) { LIS_SETERR1(LIS_ERR_ILL_ARG,"Size n(=%d) of matrix A is less than 0\n",A->gn); return LIS_ERR_ILL_ARG; } nesolver = esolver->options[LIS_EOPTIONS_ESOLVER]; niesolver = esolver->options[LIS_EOPTIONS_INNER_ESOLVER]; ss = esolver->options[LIS_EOPTIONS_SUBSPACE]; mode = esolver->options[LIS_EOPTIONS_MODE]; emaxiter = esolver->options[LIS_EOPTIONS_MAXITER]; gshift = esolver->params[LIS_EPARAMS_SHIFT - LIS_EOPTIONS_LEN]; output = esolver->options[LIS_EOPTIONS_OUTPUT]; estorage = esolver->options[LIS_EOPTIONS_STORAGE]; eblock = esolver->options[LIS_EOPTIONS_STORAGE_BLOCK]; eprecision = esolver->options[LIS_EOPTIONS_PRECISION]; esolver->eprecision = eprecision; if( nesolver < 1 || nesolver > LIS_ESOLVER_LEN ) { LIS_SETERR2(LIS_ERR_ILL_ARG,"Parameter LIS_EOPTIONS_ESOLVER is %d (Set between 1 to %d)\n",nesolver, LIS_ESOLVER_LEN); return LIS_ERR_ILL_ARG; } if( niesolver < 1 || niesolver > 7 ) { LIS_SETERR1(LIS_ERR_ILL_ARG,"Parameter LIS_EOPTIONS_INNER_ESOLVER is %d (Set between 1 to 7)\n", niesolver); return LIS_ERR_ILL_ARG; } if ( esolver->options[LIS_EOPTIONS_ESOLVER] == LIS_ESOLVER_SI && niesolver > 4 ) { LIS_SETERR1(LIS_ERR_ILL_ARG,"Parameter LIS_EOPTIONS_INNER_ESOLVER is %d (Set between 1 to 4 for Subspace)\n", niesolver); return LIS_ERR_ILL_ARG; } if ( esolver->options[LIS_EOPTIONS_ESOLVER] == LIS_ESOLVER_LI && niesolver == LIS_ESOLVER_PI ) { LIS_SETERR1(LIS_ERR_ILL_ARG,"Parameter LIS_EOPTIONS_INNER_ESOLVER is %d (Set between 2 to 7 for Lanczos)\n", niesolver); return LIS_ERR_ILL_ARG; } if ( esolver->options[LIS_EOPTIONS_ESOLVER] == LIS_ESOLVER_AI && (( niesolver == LIS_ESOLVER_PI ) || ( niesolver == LIS_ESOLVER_CG) || ( niesolver == LIS_ESOLVER_JD)) ) { LIS_SETERR1(LIS_ERR_ILL_ARG,"Parameter LIS_EOPTIONS_INNER_ESOLVER is %d (Set between 2 to 4 or 6 for Arnoldi)\n", niesolver); return LIS_ERR_ILL_ARG; } if ( esolver->options[LIS_EOPTIONS_ESOLVER] == LIS_ESOLVER_SI && ss > A->gn ) { LIS_SETERR2(LIS_ERR_ILL_ARG,"Parameter LIS_EOPTIONS_SUBSPACE is %d (Set less than or equal to matrix size %d for Subspace)\n", ss, A->gn); return LIS_ERR_ILL_ARG; } if (( esolver->options[LIS_EOPTIONS_ESOLVER] == LIS_ESOLVER_LI || esolver->options[LIS_EOPTIONS_ESOLVER] == LIS_ESOLVER_AI ) && ss > A->gn ) { LIS_SETERR2(LIS_ERR_ILL_ARG,"Parameter LIS_EOPTIONS_SUBSPACE is %d (Set less than or equal to matrix size %d for Lanczos and Arnoldi)\n", ss, A->gn); return LIS_ERR_ILL_ARG; } if ( esolver->options[LIS_EOPTIONS_ESOLVER] == LIS_ESOLVER_SI && mode >= ss ) { LIS_SETERR2(LIS_ERR_ILL_ARG,"Parameter LIS_EOPTIONS_MODE is %d (Set less than subspace size %d for Subspace)\n", mode, ss); return LIS_ERR_ILL_ARG; } if ( esolver->options[LIS_EOPTIONS_ESOLVER] == ( LIS_ESOLVER_LI || LIS_ESOLVER_AI ) && mode >= ss ) { LIS_SETERR2(LIS_ERR_ILL_ARG,"Parameter LIS_EOPTIONS_MODE is %d (Set less than subspace size %d for Lanczos or Arnoldi)\n", mode, ss); return LIS_ERR_ILL_ARG; } #ifdef USE_QUAD_PRECISION if( eprecision==LIS_PRECISION_QUAD && lis_esolver_execute_quad[nesolver]==NULL ) { LIS_SETERR1(LIS_ERR_NOT_IMPLEMENTED,"Quad precision eigensolver %s is not implemented\n",lis_esolvername[nesolver]); return LIS_ERR_NOT_IMPLEMENTED; } else if( eprecision==LIS_PRECISION_SWITCH && lis_esolver_execute_switch[nesolver]==NULL ) { LIS_SETERR1(LIS_ERR_NOT_IMPLEMENTED,"Switch esolver %s is not implemented\n",lis_esolvername[nesolver]); return LIS_ERR_NOT_IMPLEMENTED; } if( esolver->options[LIS_EOPTIONS_SWITCH_MAXITER]==-1 ) { esolver->options[LIS_EOPTIONS_SWITCH_MAXITER] = emaxiter; } #endif /* create eigenvalue array */ if( esolver->evalue ) lis_free(esolver->evalue); evalue = (LIS_SCALAR *)lis_malloc((ss+2)*sizeof(LIS_SCALAR),"lis_esolve::evalue"); if( evalue==NULL ) { LIS_SETERR_MEM((ss+2)*sizeof(LIS_SCALAR)); esolver->retcode = err; return err; } evalue[0] = 1.0; evalue[ss-1] = 1.0; /* create residual norm array */ if( esolver->resid ) lis_free(esolver->resid); resid = (LIS_SCALAR *)lis_malloc((ss+2)*sizeof(LIS_SCALAR),"lis_esolve::resid"); if( resid==NULL ) { LIS_SETERR_MEM((ss+2)*sizeof(LIS_SCALAR)); esolver->retcode = err; return err; } /* create number of iterations array */ if( esolver->iter ) lis_free(esolver->iter); iter = (LIS_INT *)lis_malloc((ss+2)*sizeof(LIS_SCALAR),"lis_esolve::iter"); if( iter==NULL ) { LIS_SETERR_MEM((ss+2)*sizeof(LIS_SCALAR)); esolver->retcode = err; return err; } /* create quad precision number of iterations array */ if( esolver->iter2 ) lis_free(esolver->iter2); iter2 = (LIS_INT *)lis_malloc((ss+2)*sizeof(LIS_SCALAR),"lis_esolve::iter2"); if( iter2==NULL ) { LIS_SETERR_MEM((ss+2)*sizeof(LIS_SCALAR)); esolver->retcode = err; return err; } /* create initial vector */ #ifndef USE_QUAD_PRECISION err = lis_vector_duplicate(A,&xx); #else if( eprecision==LIS_PRECISION_DOUBLE ) { err = lis_vector_duplicate(A,&xx); } else { err = lis_vector_duplicateex(LIS_PRECISION_QUAD,A,&xx); } #endif if( err ) { esolver->retcode = err; return err; } if( esolver->options[LIS_EOPTIONS_INITGUESS_ONES] ) { if( output ) lis_printf(A->comm,"initial vector x : 1\n"); #ifndef USE_QUAD_PRECISION lis_vector_set_all(1.0,xx); #else if( eprecision==LIS_PRECISION_DOUBLE ) { lis_vector_set_all(1.0,xx); } else { lis_vector_set_allex_nm(1.0,xx); } #endif } else { if( output ) lis_printf(A->comm,"initial vector x : user defined\n"); #ifndef USE_QUAD_PRECISION lis_vector_copy(x,xx); #else if( eprecision==LIS_PRECISION_DOUBLE ) { lis_vector_copy(x,xx); } else { lis_vector_copyex_nm(x,xx); } #endif } /* global shift */ if ( output ) if( A->my_rank==0 ) printf("shift : %e\n", gshift); /* create eigenvector array */ if( esolver->evector ) lis_free(esolver->evector); evector = (LIS_VECTOR *)lis_malloc((ss+2)*sizeof(LIS_VECTOR),"lis_esolve::evector"); if( evector==NULL ) { LIS_SETERR_MEM((ss+2)*sizeof(LIS_VECTOR)); esolver->retcode = err; return err; } /* create residual history array */ if( esolver->rhistory ) lis_free(esolver->rhistory); rhistory = (LIS_SCALAR *)lis_malloc((emaxiter+2)*sizeof(LIS_SCALAR),"lis_esolve::rhistory"); if( rhistory==NULL ) { LIS_SETERR_MEM((emaxiter+2)*sizeof(LIS_SCALAR)); lis_vector_destroy(xx); esolver->retcode = err; return err; } /* convert matrix */ if( estorage>0 && A->matrix_type!=estorage ) { err = lis_matrix_duplicate(A,&B); if( err ) return err; lis_matrix_set_blocksize(B,eblock,eblock,NULL,NULL); lis_matrix_set_type(B,estorage); err = lis_matrix_convert(A,B); if( err ) return err; lis_matrix_storage_destroy(A); lis_matrix_DLU_destroy(A); lis_matrix_diag_destroy(A->WD); if( A->l2g_map ) lis_free( A->l2g_map ); if( A->commtable ) lis_commtable_destroy( A->commtable ); if( A->ranges ) lis_free( A->ranges ); err = lis_matrix_copy_struct(B,A); if( err ) return err; lis_free(B); } esolver->A = A; esolver->evalue = evalue; esolver->x = x; esolver->evector = evector; rhistory[0] = 1.0; esolver->rhistory = rhistory; esolver->resid = resid; esolver->iter = iter; esolver->iter2 = iter2; if( A->my_rank==0 ) { #ifdef _LONG__DOUBLE if ( output ) printf("precision : long double\n"); #else if ( output ) printf("precision : %s\n", lis_eprecisionname[eprecision]); #endif #ifdef _LONG__LONG if ( output ) printf("eigensolver : %s\n", lis_esolvername[nesolver]); #else if ( output ) printf("eigensolver : %s\n", lis_esolvername[nesolver]); #endif } if( A->my_rank==0 ) { #ifdef _LONG__DOUBLE if ( output ) printf("convergence condition : ||lx-Ax||_2 <= %6.1Le * ||lx||_2\n", esolver->params[LIS_EPARAMS_RESID - LIS_EOPTIONS_LEN]); #else if ( output ) printf("convergence condition : ||lx-Ax||_2 <= %6.1e * ||lx||_2\n", esolver->params[LIS_EPARAMS_RESID - LIS_EOPTIONS_LEN]); #endif } if( A->my_rank==0 ) { if( A->matrix_type==LIS_MATRIX_BSR || A->matrix_type==LIS_MATRIX_BSC ) { #ifdef _LONG__LONG if ( output ) printf("matrix storage format : %s(%lld x %lld)\n", lis_estoragename[A->matrix_type-1],eblock,eblock); #else if ( output ) printf("matrix storage format : %s(%d x %d)\n", lis_estoragename[A->matrix_type-1],eblock,eblock); #endif } else { if ( output ) printf("matrix storage format : %s\n", lis_estoragename[A->matrix_type-1]); } } time = lis_wtime(); esolver->ptime = 0; esolver->itime = 0; esolver->p_c_time = 0; esolver->p_i_time = 0; if (gshift != 0.0) lis_matrix_shift_diagonal(A, gshift); /* create work vector */ err = lis_esolver_malloc_work[nesolver](esolver); if( err ) { lis_vector_destroy(xx); esolver->retcode = err; return err; } esolver->x = xx; esolver->xx = x; /* execute esolver */ #ifndef USE_QUAD_PRECISION err = lis_esolver_execute[nesolver](esolver); #else if( eprecision==LIS_PRECISION_DOUBLE ) { err = lis_esolver_execute[nesolver](esolver); } else if( eprecision==LIS_PRECISION_QUAD ) { err = lis_esolver_execute_quad[nesolver](esolver); } else if( eprecision==LIS_PRECISION_SWITCH ) { err = lis_esolver_execute_switch[nesolver](esolver); } #endif esolver->retcode = err; *evalue0 = esolver->evalue[0]; lis_vector_copy(esolver->x, x); esolver->time = lis_wtime() - time; lis_matrix_shift_diagonal(A, -gshift); if( A->my_rank==0 ) { if( err ) { #ifdef _LONG__LONG if ( output ) printf("eigensolver status : %s(code=%lld)\n\n",lis_ereturncode[err],err); #else if ( output ) printf("eigensolver status : %s(code=%d)\n\n",lis_ereturncode[err],err); #endif } else { if ( output ) printf("eigensolver status : normal end\n\n"); } } if( eprecision==LIS_PRECISION_DOUBLE ) { esolver->iter2[mode] = esolver->iter[mode]; } else if( eprecision==LIS_PRECISION_QUAD ) { esolver->iter2[mode] = 0; } lis_vector_destroy(xx); LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; }