LIS_INT lis_esolver_get_iters(LIS_ESOLVER esolver, LIS_VECTOR v) { LIS_INT i,ii,ss,n,gn,is,ie; LIS_DEBUG_FUNC_IN; if ( esolver->options[LIS_EOPTIONS_ESOLVER] != LIS_ESOLVER_SI && esolver->options[LIS_EOPTIONS_ESOLVER] != LIS_ESOLVER_LI && esolver->options[LIS_EOPTIONS_ESOLVER] != LIS_ESOLVER_AI ) { LIS_SETERR1(LIS_ERR_ILL_ARG,"Parameter LIS_EOPTIONS_ESOLVER is %d (Set Subspace, Lanczos, or Arnoldi)\n", esolver->options[LIS_EOPTIONS_ESOLVER]); return LIS_ERR_ILL_ARG; } ss = esolver->options[LIS_EOPTIONS_SUBSPACE]; lis_vector_set_size(v,0,ss); lis_vector_get_size(v,&n,&gn); lis_vector_get_range(v,&is,&ie); for(i=0;i<n;i++) { ii=i; if( v->origin ) ii++; lis_vector_set_value(LIS_INS_VALUE,ii+is,esolver->iter[i+is],v); } v->intvalue = 1; LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; }
LIS_INT lis_input_vector(LIS_VECTOR v, char *filename) { LIS_INT fileformat; char buf[256],banner[128]; LIS_INT err; FILE *file; LIS_Comm comm; comm = v->comm; 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; } 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 { fileformat = LIS_FMT_PLAIN; } rewind(file); switch( fileformat ) { case LIS_FMT_MM: err = lis_input_vector_mm(v,file); break; case LIS_FMT_LIS: err = lis_input_vector_lis(v,filename,file); break; case LIS_FMT_PLAIN: err = lis_input_vector_plain(v,file); break; } fclose(file); #ifdef USE_MPI MPI_Barrier(comm); #endif return err; }
LIS_INT lis_orthomin_check_params(LIS_SOLVER solver) { LIS_INT restart; LIS_DEBUG_FUNC_IN; restart = solver->options[LIS_OPTIONS_RESTART]; if( restart<0 ) { LIS_SETERR1(LIS_ERR_ILL_ARG,"Parameter LIS_OPTIONS_RESTART(=%D) is less than 0\n",restart); return LIS_ERR_ILL_ARG; } LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; }
LIS_INT lis_esi_check_params(LIS_ESOLVER esolver) { LIS_INT ss; LIS_DEBUG_FUNC_IN; ss = esolver->options[LIS_EOPTIONS_SUBSPACE]; if( ss<0 ) { LIS_SETERR1(LIS_ERR_ILL_ARG,"Parameter LIS_OPTIONS_SUBSPACE(=%d) is less than 0\n",ss); return LIS_ERR_ILL_ARG; } LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; }
LIS_INT lis_esolver_get_evectors(LIS_ESOLVER esolver, LIS_MATRIX M) { LIS_INT i,ii,j,jj,n,gn,is,ie,js; LIS_INT ss,lis_esolver_evector_size; LIS_DEBUG_FUNC_IN; if ( esolver->options[LIS_EOPTIONS_ESOLVER] != LIS_ESOLVER_SI && esolver->options[LIS_EOPTIONS_ESOLVER] != LIS_ESOLVER_LI && esolver->options[LIS_EOPTIONS_ESOLVER] != LIS_ESOLVER_AI ) { LIS_SETERR1(LIS_ERR_ILL_ARG,"Parameter LIS_EOPTIONS_ESOLVER is %d (Set Subspace, Lanczos, or Arnoldi)\n", esolver->options[LIS_EOPTIONS_ESOLVER]); return LIS_ERR_ILL_ARG; } ss = esolver->options[LIS_EOPTIONS_SUBSPACE]; lis_esolver_evector_size = esolver->evector[0]->gn; lis_matrix_set_size(M,0,lis_esolver_evector_size); lis_matrix_get_size(M,&n,&gn); lis_matrix_get_range(M,&is,&ie); js=0; if( esolver->evector[0]->origin ) { is++; js++; } for(j=0;j<ss;j++) { for(i=0;i<n;i++) { ii=i+is; jj=j+js; lis_matrix_set_value(LIS_INS_VALUE,ii,jj,esolver->evector[j]->value[i],M); } } lis_matrix_set_type(M,LIS_MATRIX_CSR); lis_matrix_assemble(M); LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; }
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_input_vector_lis(LIS_VECTOR v, char *filename, FILE *file) { LIS_INT err; char buf[BUFSIZE],banner[128],mode[128],mattype[128]; LIS_INT in_mode; if( fgets(buf, BUFSIZE, file) == NULL ) { LIS_SETERR_FIO; return LIS_ERR_FILE_IO; } buf[10] = '\0'; sscanf(buf, "%s %s %s", banner, mode, mattype); if( strncmp(banner, LISBanner, strlen(LISBanner)) != 0) { LIS_SETERR(LIS_ERR_FILE_IO,"not lis file format\n"); return LIS_ERR_FILE_IO; } in_mode = LIS_FMT_LIS_ASCII; if( mode[0]=='B' || mode[0]=='L' ) { fclose(file); file = fopen(filename, "rb"); if( file==NULL ) { LIS_SETERR1(LIS_ERR_FILE_IO,"cannot open file %s\n", filename); return LIS_ERR_FILE_IO; } err = fread(buf, sizeof(char), 10, file); if( err ) { return err; } in_mode = 1; in_mode = *(char *)&in_mode; if( (in_mode==LIS_BINARY_BIG && mode[0]=='L') || (in_mode==LIS_BINARY_LITTLE && mode[0]=='B') ) { in_mode = LIS_TRUE; } else { in_mode = LIS_FALSE; } } if( strncmp(mattype, "vec", 3) == 0 ) { if( in_mode==LIS_FMT_LIS_ASCII ) { lis_input_vector_lis_ascii(v,file); } else { LIS_SETERR_IMP; return LIS_ERR_NOT_IMPLEMENTED; } } else { LIS_SETERR(LIS_ERR_FILE_IO,"not lis file format\n"); return LIS_ERR_FILE_IO; } return LIS_SUCCESS; }
LIS_INT lis_esolver_output_rhistory(LIS_ESOLVER esolver, char *filename) { LIS_INT i,maxiter; #ifdef USE_MPI LIS_INT my_rank,err; #endif FILE *file; LIS_DEBUG_FUNC_IN; maxiter = esolver->iter+1; if( esolver->retcode!=LIS_SUCCESS ) { maxiter--; } #ifdef USE_MPI if( esolver->residual==NULL ) { LIS_SETERR(LIS_FAILS,"eigensolver's residual history is empty\n"); return LIS_FAILS; } if( esolver->A==NULL ) { LIS_SETERR(LIS_FAILS,"matrix A is NULL\n"); return LIS_FAILS; } MPI_Barrier(esolver->A->comm); my_rank = esolver->A->my_rank; err = 0; if( my_rank==0 ) { file = fopen(filename, "w"); if( file==NULL ) { LIS_SETERR1(LIS_ERR_FILE_IO,"cannot open file %s\n", filename); err = 1; } else { for(i=0;i<maxiter;i++) { #ifdef _LONG__DOUBLE fprintf(file, "%Le\n", esolver->residual[i]); #else fprintf(file, "%e\n", esolver->residual[i]); #endif } fclose(file); } } MPI_Barrier(esolver->A->comm); LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; #else if( esolver->residual==NULL ) { LIS_SETERR(LIS_FAILS,"eigensolver's residual history is empty\n"); return LIS_FAILS; } file = fopen(filename, "w"); if( file==NULL ) { LIS_SETERR1(LIS_ERR_FILE_IO,"cannot open file %s\n", filename); return LIS_ERR_FILE_IO; } for(i=0;i<maxiter;i++) { #ifdef _LONG__DOUBLE fprintf(file, "%Le\n", esolver->residual[i]); #else fprintf(file, "%e\n", esolver->residual[i]); #endif } fclose(file); LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; #endif }
LIS_INT lis_output_vector_lis_ascii(LIS_VECTOR v, char *path) { LIS_INT i,n; #ifdef USE_MPI LIS_INT pe,nprocs,my_rank; LIS_INT err,ret; #endif FILE *file; LIS_DEBUG_FUNC_IN; #ifdef USE_MPI nprocs = v->nprocs; my_rank = v->my_rank; n = v->n; err = 0; if( my_rank==0 ) { file = fopen(path, "w"); if( file==NULL ) { LIS_SETERR1(LIS_ERR_FILE_IO,"cannot open file %s\n", path); err = 1; } fprintf(file, "#LIS A vec\n"); #ifdef _LONGLONG fprintf(file, "%lld\n", nprocs); #else fprintf(file, "%d\n", nprocs); #endif fclose(file); } MPI_Allreduce(&err,&ret,1,LIS_MPI_INT,MPI_SUM,v->comm); if( ret ) { return LIS_FAILS; } err = 0; for(pe=0;pe<nprocs;pe++) { if( my_rank==pe ) { file = fopen(path, "a"); if( file==NULL ) { LIS_SETERR1(LIS_ERR_FILE_IO,"cannot open file %s\n", path); err = 1; } else { #ifdef _LONGLONG fprintf(file, "# %lld %lld\n", pe, v->n); #else fprintf(file, "# %d %d\n", pe, v->n); #endif for(i=0;i<n;i++) { #ifdef _LONG__DOUBLE fprintf(file, "%28.20Le ",v->value[i]); #else fprintf(file, "%28.20e ",v->value[i]); #endif if( (i+1)%3==0 ) fprintf(file, "\n"); } if( n%3!=0 ) fprintf(file, "\n"); fclose(file); } } MPI_Allreduce(&err,&ret,1,LIS_MPI_INT,MPI_SUM,v->comm); if( ret ) { return LIS_FAILS; } } LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; #else n = v->n; file = fopen(path, "w"); if( file==NULL ) { LIS_SETERR1(LIS_ERR_FILE_IO,"cannot open file %s\n", path); return LIS_ERR_FILE_IO; } fprintf(file, "#LIS A vec\n"); fprintf(file, "1\n"); #ifdef _LONGLONG fprintf(file, "# 0 %lld\n", v->n); #else fprintf(file, "# 0 %d\n", v->n); #endif for(i=0;i<n;i++) { #ifdef _LONG__DOUBLE fprintf(file, "%28.20Le ",v->value[i]); #else fprintf(file, "%28.20e ",v->value[i]); #endif if( (i+1)%3==0 ) fprintf(file, "\n"); } if( n%3!=0 ) fprintf(file, "\n"); fclose(file); LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; #endif }
LIS_INT lis_output_vector_mm(LIS_VECTOR v, char *path) { LIS_INT i,n,is; #ifdef USE_MPI LIS_INT pe,nprocs,my_rank; LIS_INT err,ret; #endif FILE *file; LIS_DEBUG_FUNC_IN; #ifdef USE_MPI nprocs = v->nprocs; my_rank = v->my_rank; n = v->n; is = v->is; err = 0; if( my_rank==0 ) { file = fopen(path, "w"); if( file==NULL ) { LIS_SETERR1(LIS_ERR_FILE_IO,"cannot open file %s\n", path); err = 1; } fprintf(file, "%%%%MatrixMarket vector coordinate real general\n"); #ifdef _LONGLONG fprintf(file, "%lld\n", v->gn); #else fprintf(file, "%d\n", v->gn); #endif fclose(file); } MPI_Allreduce(&err,&ret,1,LIS_MPI_INT,MPI_SUM,v->comm); if( ret ) { return LIS_FAILS; } err = 0; for(pe=0;pe<nprocs;pe++) { if( my_rank==pe ) { file = fopen(path, "a"); if( file==NULL ) { LIS_SETERR1(LIS_ERR_FILE_IO,"cannot open file %s\n", path); err = 1; } else { for(i=0;i<n;i++) { #ifdef _LONGLONG #ifdef _LONG__DOUBLE fprintf(file, "%lld %28.20Le\n", i+is+1, v->value[i]); #else fprintf(file, "%lld %28.20e\n", i+is+1, v->value[i]); #endif #else #ifdef _LONG__DOUBLE fprintf(file, "%d %28.20Le\n", i+is+1, v->value[i]); #else fprintf(file, "%d %28.20e\n", i+is+1, v->value[i]); #endif #endif } fclose(file); } } MPI_Allreduce(&err,&ret,1,LIS_MPI_INT,MPI_SUM,v->comm); if( ret ) { return LIS_FAILS; } } LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; #else n = v->n; is = v->is; file = fopen(path, "w"); if( file==NULL ) { LIS_SETERR1(LIS_ERR_FILE_IO,"cannot open file %s\n", path); return LIS_ERR_FILE_IO; } fprintf(file, "%%%%MatrixMarket vector coordinate real general\n"); #ifdef _LONGLONG fprintf(file, "%lld\n", v->gn); #else fprintf(file, "%d\n", v->gn); #endif for(i=0;i<n;i++) { #ifdef _LONGLONG #ifdef _LONG__DOUBLE fprintf(file, "%lld %28.20Le\n", i+is+1, v->value[i]); #else fprintf(file, "%lld %28.20e\n", i+is+1, v->value[i]); #endif #else #ifdef _LONG__DOUBLE fprintf(file, "%d %28.20Le\n", i+is+1, v->value[i]); #else fprintf(file, "%d %28.20e\n", i+is+1, v->value[i]); #endif #endif /* fprintf(file, "%d %28.20e\n", i+1, v->value[i]); */ } fclose(file); LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; #endif }
LIS_INT lis_output_vector_plain(LIS_VECTOR v, char *path) { LIS_INT n,i; #ifdef USE_MPI LIS_INT pe,nprocs,my_rank; LIS_INT err,ret; #endif FILE *file; LIS_DEBUG_FUNC_IN; #ifdef USE_MPI nprocs = v->nprocs; my_rank = v->my_rank; n = v->n; err = 0; for(pe=0;pe<nprocs;pe++) { if( my_rank==pe ) { if( my_rank==0 ) { file = fopen(path, "w"); } else { file = fopen(path, "a"); } if( file==NULL ) { LIS_SETERR1(LIS_ERR_FILE_IO,"cannot open file %s\n", path); err = 1; } for(i=0;i<n;i++) { #ifdef _LONG__DOUBLE fprintf(file, "%28.20Le\n", v->value[i]); #else fprintf(file, "%28.20e\n", v->value[i]); #endif } fclose(file); } MPI_Allreduce(&err,&ret,1,LIS_MPI_INT,MPI_SUM,v->comm); if( ret ) { return LIS_FAILS; } } LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; #else n = v->n; file = fopen(path, "w"); if( file==NULL ) { LIS_SETERR1(LIS_ERR_FILE_IO,"cannot open file %s\n", path); return LIS_ERR_FILE_IO; } for(i=0;i<n;i++) { #ifdef _LONG__DOUBLE fprintf(file, "%28.20Le\n", v->value[i]); #else fprintf(file, "%28.20e\n", v->value[i]); #endif } fclose(file); LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; #endif }
LIS_INT lis_solve_kernel(LIS_MATRIX A, LIS_VECTOR b, LIS_VECTOR x, LIS_SOLVER solver, LIS_PRECON precon) { LIS_INT nsolver, precon_type, maxiter; LIS_INT err; LIS_SCALAR *residual; LIS_VECTOR xx; LIS_INT output; LIS_INT scale; LIS_INT conv_cond; LIS_INT precision,is_use_at,storage,block; LIS_INT i,n,np; double p_c_times, p_i_times,itimes; LIS_SCALAR nrm2,tol,tol_w; LIS_VECTOR t; LIS_VECTOR bb; LIS_MATRIX AA,B; LIS_MATRIX At; char buf[64]; LIS_DEBUG_FUNC_IN; nsolver = solver->options[LIS_OPTIONS_SOLVER]; precon_type = solver->options[LIS_OPTIONS_PRECON]; maxiter = solver->options[LIS_OPTIONS_MAXITER]; output = solver->options[LIS_OPTIONS_OUTPUT]; scale = solver->options[LIS_OPTIONS_SCALE]; precision = solver->options[LIS_OPTIONS_PRECISION]; is_use_at = solver->options[LIS_OPTIONS_USE_AT]; storage = solver->options[LIS_OPTIONS_STORAGE]; block = solver->options[LIS_OPTIONS_STORAGE_BLOCK]; conv_cond = solver->options[LIS_OPTIONS_CONV_COND]; tol = solver->params[LIS_PARAMS_RESID-LIS_OPTIONS_LEN]; tol_w = solver->params[LIS_PARAMS_RESID_WEIGHT-LIS_OPTIONS_LEN]; solver->precision = precision; if( nsolver < 1 || nsolver > LIS_SOLVERS_LEN ) { LIS_SETERR2(LIS_ERR_ILL_ARG,"Parameter LIS_OPTIONS_SOLVER is %d (Set between 1 to %d)\n",nsolver, LIS_SOLVERS_LEN); return LIS_ERR_ILL_ARG; } if( precon_type < 0 || precon_type > precon_register_type ) { LIS_SETERR2(LIS_ERR_ILL_ARG,"Parameter LIS_OPTIONS_PRECON is %d (Set between 0 to %d)\n",precon_type, precon_register_type-1); return LIS_ERR_ILL_ARG; } if( maxiter<0 ) { LIS_SETERR1(LIS_ERR_ILL_ARG,"Parameter LIS_OPTIONS_MAXITER(=%d) is less than 0\n",maxiter); return LIS_ERR_ILL_ARG; } #ifdef USE_MPI if( precon_type == LIS_PRECON_TYPE_SAAMG && solver->A->nprocs < 2) { LIS_SETERR1(LIS_ERR_ILL_ARG,"Parameter A->nprocs (=%d) is less than 2 (Set more than 1 when using parallel version of SAAMG)\n",solver->A->nprocs); return LIS_ERR_ILL_ARG; } #endif #ifdef USE_QUAD_PRECISION if( precision==LIS_PRECISION_QUAD && lis_solver_execute_quad[nsolver]==NULL ) { LIS_SETERR1(LIS_ERR_NOT_IMPLEMENTED,"Quad precision solver %s is not implemented\n",lis_solvername[nsolver]); return LIS_ERR_NOT_IMPLEMENTED; } else if( precision==LIS_PRECISION_SWITCH && lis_solver_execute_switch[nsolver]==NULL ) { LIS_SETERR1(LIS_ERR_NOT_IMPLEMENTED,"Switch solver %s is not implemented\n",lis_solvername[nsolver]); return LIS_ERR_NOT_IMPLEMENTED; } if( solver->options[LIS_OPTIONS_SWITCH_MAXITER]==-1 ) { solver->options[LIS_OPTIONS_SWITCH_MAXITER] = maxiter; } #endif err = lis_solver_check_params[nsolver](solver); if( err ) { solver->retcode = err; return err; } /* end parameter check */ solver->A = A; solver->b = b; /* create initial vector */ #ifndef USE_QUAD_PRECISION err = lis_vector_duplicate(A,&xx); #else if( precision==LIS_PRECISION_DOUBLE ) { err = lis_vector_duplicate(A,&xx); } else { err = lis_vector_duplicateex(LIS_PRECISION_QUAD,A,&xx); } #endif if( err ) { solver->retcode = err; return err; } if( solver->options[LIS_OPTIONS_INITGUESS_ZEROS] ) { if( output ) lis_printf(A->comm,"initial vector x = 0\n"); #ifndef USE_QUAD_PRECISION lis_vector_set_all(0.0,xx); #else if( precision==LIS_PRECISION_DOUBLE ) { lis_vector_set_all(0.0,xx); } else { lis_vector_set_allex_nm(0.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( precision==LIS_PRECISION_DOUBLE ) { lis_vector_copy(x,xx); } else { lis_vector_copyex_nm(x,xx); } #endif } /* create residual history vector */ if( solver->residual ) lis_free(solver->residual); residual = (LIS_SCALAR *)lis_malloc((maxiter+2)*sizeof(LIS_SCALAR),"lis_solve::residual"); if( residual==NULL ) { LIS_SETERR_MEM((maxiter+2)*sizeof(LIS_SCALAR)); lis_vector_destroy(xx); solver->retcode = err; return err; } residual[0] = 1.0; n = A->n; np = A->np; t = NULL; At = NULL; p_c_times = lis_wtime(); if( precon_type==LIS_PRECON_TYPE_IS ) { if( solver->d==NULL ) { err = lis_vector_duplicate(A,&solver->d); if( err ) { return err; } } if( !A->is_scaled ) { lis_matrix_scaling(A,b,solver->d,LIS_SCALE_JACOBI); } else if( !b->is_scaled ) { #ifdef _OPENMP #pragma omp parallel for #endif for(i=0;i<n;i++) { b->value[i] = b->value[i]*solver->d->value[i]; } } if( nsolver >= LIS_SOLVER_JACOBI && nsolver <= LIS_SOLVER_SOR ) { solver->options[LIS_OPTIONS_ISLEVEL] = 0; } } else if( nsolver >= LIS_SOLVER_JACOBI && nsolver <= LIS_SOLVER_SOR && precon_type!=LIS_PRECON_TYPE_NONE ) { if( solver->d==NULL ) { err = lis_vector_duplicate(A,&solver->d); if( err ) { return err; } } if( !A->is_scaled ) { lis_matrix_scaling(A,b,solver->d,LIS_SCALE_JACOBI); } } else if( scale ) { if( storage==LIS_MATRIX_BSR && scale==LIS_SCALE_JACOBI ) { if( A->matrix_type!=LIS_MATRIX_BSR ) { err = lis_matrix_duplicate(A,&B); if( err ) return err; lis_matrix_set_blocksize(B,block,block,NULL,NULL); lis_matrix_set_type(B,storage); 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); } err = lis_matrix_split(A); if( err ) return err; err = lis_matrix_diag_duplicate(A->D,&solver->WD); if( err ) return err; lis_matrix_diag_copy(A->D,solver->WD); lis_matrix_diag_inverse(solver->WD); lis_matrix_bscaling_bsr(A,solver->WD); lis_vector_duplicate(A,&t); lis_matrix_diag_matvec(solver->WD,b,t); lis_vector_copy(t,b); lis_vector_destroy(t); t = NULL; } else { if( solver->d==NULL ) { err = lis_vector_duplicate(A,&solver->d); if( err ) { return err; } } if( scale==LIS_SCALE_JACOBI && nsolver==LIS_SOLVER_CG ) { scale = LIS_SCALE_SYMM_DIAG; } if( !A->is_scaled ) { lis_matrix_scaling(A,b,solver->d,scale); } else if( !b->is_scaled ) { #ifdef _OPENMP #pragma omp parallel for #endif for(i=0;i<n;i++) { b->value[i] = b->value[i]*solver->d->value[i]; } } } } /* precon_type = precon->precon_type;*/ if( precon_type==LIS_PRECON_TYPE_IS ) { if( nsolver < LIS_SOLVER_JACOBI || nsolver > LIS_SOLVER_SOR ) { AA = solver->A; bb = solver->b; } else { AA = precon->A; bb = precon->Pb; } } else { AA = A; bb = b; } p_c_times = lis_wtime() - p_c_times; itimes = lis_wtime(); /* Matrix Convert */ solver->A = AA; solver->b = bb; err = lis_matrix_convert_self(solver); if( err ) { lis_vector_destroy(xx); lis_solver_work_destroy(solver); lis_free(residual); solver->retcode = err; return err; } block = solver->A->bnr; if( A->my_rank==0 ) { if( output ) printf("precision : %s\n", lis_precisionname[precision]); if( output ) printf("solver : %s %d\n", lis_solvername[nsolver],nsolver); switch( precon_type ) { case LIS_PRECON_TYPE_ILU: i = solver->options[LIS_OPTIONS_FILL]; if( A->matrix_type==LIS_MATRIX_BSR || A->matrix_type==LIS_MATRIX_VBR ) { if( output ) sprintf(buf,"Block %s(%d)",lis_preconname[precon_type],i); } else { if( output ) sprintf(buf,"%s(%d)",lis_preconname[precon_type],i); } break; default: if( output ) sprintf(buf,"%s",lis_preconname[precon_type]); break; } if( solver->options[LIS_OPTIONS_ADDS] && precon_type ) { if( output ) printf("precon : %s + additive schwarz\n", buf); } else { if( output ) printf("precon : %s\n", buf); } } switch(conv_cond) { case LIS_CONV_COND_NRM2_R: case LIS_CONV_COND_NRM2_B: if( A->my_rank==0 ) { if( output ) ("CONV_COND : ||r||_2 <= %6.1e*||r_0||_2\n", tol); } break; case LIS_CONV_COND_NRM1_B: lis_vector_nrm1(b,&nrm2); nrm2 = nrm2*tol_w + tol; if( A->my_rank==0 ) { if( output ) printf("conv_cond : ||r||_1 <= %6.1e*||b||_1 + %6.1e = %6.1e\n", tol_w,tol,nrm2); } break; } if( A->my_rank==0 ) { if( AA->matrix_type==LIS_MATRIX_BSR || AA->matrix_type==LIS_MATRIX_BSC ) { if( output ) printf("storage : %s(%d x %d)\n", lis_storagename[AA->matrix_type-1],block,block); } else { if( output ) printf("storage : %s\n", lis_storagename[AA->matrix_type-1]); } } /* create work vector */ err = lis_solver_malloc_work[nsolver](solver); if( err ) { lis_vector_destroy(xx); lis_precon_destroy(precon); solver->retcode = err; return err; } if( nsolver==LIS_SOLVER_BICG && is_use_at ) { if( output ) lis_printf(A->comm,"Use At\n"); lis_matrix_duplicate(AA,&At); lis_matrix_set_type(At,LIS_USE_AT_TYPE[AA->matrix_type]); lis_matrix_convert(AA,At); solver->At = At; } solver->x = xx; solver->xx = x; solver->precon = precon; solver->residual = residual; /* execute solver */ #ifndef USE_QUAD_PRECISION err = lis_solver_execute[nsolver](solver); #else if( precision==LIS_PRECISION_DOUBLE ) { err = lis_solver_execute[nsolver](solver); } else if( precision==LIS_PRECISION_QUAD ) { err = lis_solver_execute_quad[nsolver](solver); } else if( precision==LIS_PRECISION_SWITCH ) { err = lis_solver_execute_switch[nsolver](solver); } #endif solver->retcode = err; if( scale==LIS_SCALE_SYMM_DIAG && precon_type!=LIS_PRECON_TYPE_IS) { #ifdef _OPENMP #pragma omp parallel for #endif for(i=0;i<n;i++) { x->value[i] = xx->value[i]*solver->d->value[i]; } } else { #ifndef USE_QUAD_PRECISION lis_vector_copy(xx,x); #else if( precision==LIS_PRECISION_DOUBLE ) { lis_vector_copy(xx,x); } else { lis_vector_copyex_mn(xx,x); } #endif } itimes = lis_wtime() - itimes - solver->ptimes; p_i_times = solver->ptimes; solver->ptimes = p_c_times + p_i_times; solver->p_c_times = p_c_times; solver->p_i_times = p_i_times; solver->times = solver->ptimes + itimes; solver->itimes = itimes; lis_solver_work_destroy(solver); lis_vector_duplicate(A,&t); xx->precision = LIS_PRECISION_DEFAULT; lis_matvec(A,xx,t); lis_vector_xpay(b,-1.0,t); if( scale==LIS_SCALE_SYMM_DIAG && precon_type!=LIS_PRECON_TYPE_IS) { #ifdef _OPENMP #pragma omp parallel for #endif for(i=0;i<n;i++) { t->value[i] = t->value[i]/solver->d->value[i]; } } lis_vector_nrm2(t,&nrm2); /* solver->resid = nrm2; */ if( A->my_rank==0 ) { if( err ) { if( output ) printf("lis_solve : %s(code=%d)\n\n",lis_returncode[err],err); } else { if( output ) printf("lis_solve : normal end\n\n"); } } if( precision==LIS_PRECISION_DOUBLE ) { solver->iter2 = solver->iter; } else if( precision==LIS_PRECISION_QUAD ) { solver->iter2 = 0; } lis_vector_destroy(t); /* lis_vector_destroy(d);*/ lis_vector_destroy(xx); 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; }