コード例 #1
0
ファイル: lis_esolver.c プロジェクト: florianl/lis
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;
}
コード例 #2
0
ファイル: lis_input.c プロジェクト: huahbo/lis
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;
}
コード例 #3
0
ファイル: lis_solver_orthomin.c プロジェクト: anishida/lis
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;
}
コード例 #4
0
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;
}
コード例 #5
0
ファイル: lis_esolver.c プロジェクト: florianl/lis
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;
}
コード例 #6
0
ファイル: lis_input.c プロジェクト: huahbo/lis
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;
}
コード例 #7
0
ファイル: lis_input.c プロジェクト: huahbo/lis
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;
}
コード例 #8
0
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
}
コード例 #9
0
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
}
コード例 #10
0
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
}
コード例 #11
0
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
}
コード例 #12
0
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;
}
コード例 #13
0
ファイル: lis_esolver.c プロジェクト: florianl/lis
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;
}