8 :
Solver(param, profile), mat(mat), matSloppy(matSloppy),
init(false),
9 basis(param.
ca_basis), alpha(nullptr), rp(nullptr), tmpp(nullptr), tmp_sloppy(nullptr) { }
20 for (
int i=0; i<
param.
Nkrylov+1; i++)
if (i>0 || !use_source)
delete p[i];
22 for (
int i=0; i<
param.
Nkrylov; i++)
if (i>0 || !use_source)
delete p[i];
32 if (veci)
delete veci;
65 warningQuda(
"CA-GCR does not support any basis besides QUDA_POWER_BASIS. Switching to QUDA_POWER_BASIS...\n");
75 if (i>0)
q[i-1] =
p[i];
101 using namespace Eigen;
105 const int N = q.size();
106 vector phi(N), psi(N);
112 std::vector<ColorSpinorField*> Q;
113 for (
int i=0; i<N; i++) Q.push_back(q[i]);
119 for (
int i=0; i<N; i++) {
120 phi(i) = A_[i*(N+1)+N];
121 for (
int j=0; j<N; j++) {
122 A(i,j) = A_[i*(N+1)+j];
129 std::vector<ColorSpinorField*> B;
133 for (
int i=0; i<N; i++) phi(i) = phi_[i];
139 for (
int i=0; i<N; i++)
140 for (
int j=0; j<N; j++)
152 LDLT<matrix> cholesky(A);
153 psi = cholesky.solve(phi);
155 for (
int i=0; i<N; i++) psi_[i] = psi(i);
194 double b2 = !fixed_iteration ?
blas::norm2(b) : 1.0;
201 if (!fixed_iteration) {
214 std::vector<ColorSpinorField *> rhs;
254 double heavy_quark_res = 0.0;
258 int resIncreaseTotal = 0;
268 bool l2_converge =
false;
272 PrintStats(
"CA-GCR", total_iter, r2, b2, heavy_quark_res);
276 for (
int k=0; k<nKrylov; k++) {
284 std::vector<ColorSpinorField*>
X;
287 std::vector<ColorSpinorField*> P;
288 for (
int i=0; i<nKrylov; i++) P.push_back(
p[i]);
295 std::vector<ColorSpinorField*>
R;
297 for (
int i=0; i<nKrylov; i++)
alpha[i] = -
alpha[i];
307 PrintStats(
"CA-GCR", total_iter, r2, b2, heavy_quark_res);
322 warningQuda(
"CA-GCR: new reliable residual norm %e is greater than previous reliable residual norm %e (total #inc %i)",
323 sqrt(r2),
sqrt(r2_old), resIncreaseTotal);
324 if (resIncrease > maxResIncrease or resIncreaseTotal > maxResIncreaseTotal) {
325 warningQuda(
"CA-GCR: solver exiting due to too many true residual norm increases");
339 PrintStats(
"CA-GCR (restart)", restart, r2, b2, heavy_quark_res);
345 if (r2 < stop) l2_converge =
true;
void setPrecision(QudaPrecision precision, QudaPrecision ghost_precision=QUDA_INVALID_PRECISION, bool force_native=false)
void create(ColorSpinorField &b)
Initiate the fields needed by the solver.
QudaVerbosity getVerbosity()
#define checkPrecision(...)
double norm2(const ColorSpinorField &a)
__host__ __device__ ValueType sqrt(ValueType x)
Complex cDotProduct(ColorSpinorField &, ColorSpinorField &)
void PrintStats(const char *name, int k, double r2, double b2, double hq2)
Prints out the running statistics of the solver (requires a verbosity of QUDA_VERBOSE) ...
CAGCR(DiracMatrix &mat, DiracMatrix &matSloppy, SolverParam ¶m, TimeProfile &profile)
cudaColorSpinorField * tmp
static ColorSpinorField * Create(const ColorSpinorParam ¶m)
bool convergence(double r2, double hq2, double r2_tol, double hq_tol)
void copy(ColorSpinorField &dst, const ColorSpinorField &src)
double xmyNorm(ColorSpinorField &x, ColorSpinorField &y)
QudaPreserveSource preserve_source
int max_res_increase_total
std::vector< ColorSpinorField * > defl_tmp1
void xpay(ColorSpinorField &x, double a, ColorSpinorField &y)
void solve(Complex *psi_, std::vector< ColorSpinorField *> &q, ColorSpinorField &b)
Solve the equation A p_k psi_k = q_k psi_k = b by minimizing the least square residual using Eigen's ...
std::vector< ColorSpinorField * > defl_tmp2
QudaComputeNullVector compute_null_vector
void deflateSVD(std::vector< ColorSpinorField *> vec_defl, std::vector< ColorSpinorField *> vec, std::vector< ColorSpinorField *> evecs, std::vector< Complex > evals)
Deflate vector with both left and Right singular vectors.
double Last(QudaProfileType idx)
#define qudaDeviceSynchronize()
QudaResidualType residual_type
static double stopping(double tol, double b2, QudaResidualType residual_type)
Set the solver L2 stopping condition.
void axpy(double a, ColorSpinorField &x, ColorSpinorField &y)
bool is_preconditioner
verbosity to use for preconditioner
std::vector< ColorSpinorField * > q
void constructDeflationSpace(const ColorSpinorField &meta, const DiracMatrix &mat, bool svd)
Constructs the deflation space.
double3 HeavyQuarkResidualNorm(ColorSpinorField &x, ColorSpinorField &r)
std::complex< double > Complex
std::vector< Complex > evals
void init()
Create the CUBLAS context.
void caxpy(const Complex &a, ColorSpinorField &x, ColorSpinorField &y)
ColorSpinorField * tmp_sloppy
void zero(ColorSpinorField &a)
std::vector< ColorSpinorField * > evecs
std::vector< ColorSpinorField * > p
void hDotProduct(Complex *result, std::vector< ColorSpinorField *> &a, std::vector< ColorSpinorField *> &b)
Computes the matrix of inner products between the vector set a and the vector set b...
const DiracMatrix & matSloppy
unsigned long long flops() const
QudaUseInitGuess use_init_guess
void operator()(ColorSpinorField &out, ColorSpinorField &in)
QudaPrecision precision_sloppy
void PrintSummary(const char *name, int k, double r2, double b2, double r2_tol, double hq_tol)
Prints out the summary of the solver convergence (requires a verbosity of QUDA_SUMMARIZE). Assumes SolverParam.true_res and SolverParam.true_res_hq has been set.
void mat(void *out, void **link, void *in, int dagger_bit, int mu, QudaPrecision sPrecision, QudaPrecision gPrecision)
const Dirac * Expose() const