QUDA  v0.7.0
A library for QCD on GPUs
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
eig_lanczos_quda.cpp
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 
5 #include <quda_internal.h>
6 #include <color_spinor_field.h>
7 #include <blas_quda.h>
8 #include <dslash_quda.h>
9 #include <invert_quda.h>
10 #include <util_quda.h>
11 #include <sys/time.h>
12 #include <lanczos_quda.h>
13 
14 #include <face_quda.h>
15 
16 #include <iostream>
17 
18 namespace quda {
19 
20  Lanczos::Lanczos(RitzMat &ritz_mat, QudaEigParam &eigParam, TimeProfile &profile) :
21  Eig_Solver(eigParam, profile), ritz_mat(ritz_mat)
22  {
23 
24  }
25 
27  {
28 
29  }
30 
31  void Lanczos::operator()(double *alpha, double *beta, cudaColorSpinorField **Eig_Vec, cudaColorSpinorField &r, cudaColorSpinorField &Apsi, int k0, int m)
32  {
34 
35  // Check to see that we'reV not trying to invert on a zero-field source
36  const double b2 = norm2(r);
37  if(b2 == 0){
39  printfQuda("Warning: initial residual is already zero\n");
40  return;
41  }
42 
43  double ff;
44  ff = sqrt(norm2(r));
45  zeroCuda(*(Eig_Vec[k0]));
46  axpyCuda(1.0/ff, r, *(Eig_Vec[k0]));
47 
48  for (int k = k0; k < m; ++k)
49  {
50  if( k == 0 )
51  {
52  // r_k = A*v_k , r_k is used for temporary buffer.
53  ritz_mat(r, *(Eig_Vec[0]));
54  // alpha_k = ( v_k , r_k )
55  alpha[0] = reDotProductCuda(*(Eig_Vec[0]), r);
56  // r_k = (A - alpha_k)v_k - beta_{k-1}*v_{k-1} = r_k - alpha_k*v_k
57  // k = 1 case, beta_0 is defined to 0, so we don`t need beta related term.
58  axpyCuda(-alpha[0],*(Eig_Vec[0]), r);
59  // beta_k = ||r_k||
60  beta[0] = sqrt(norm2(r));
61 
62 
63  zeroCuda(*(Eig_Vec[1]));
64  axpyCuda(1.0/beta[0], r, *(Eig_Vec[1]));
65 
66  }
67  else
68  {
69  // r_k = A*v_k , r_k is used for temporary buffer.
70  ritz_mat(r, *(Eig_Vec[k]));
71  // r_k = (A - alpha_k)v_k - beta_{k-1}*v_{k-1} = r_k - alpha_k*v_k
72  // 1st: r_k = r_k - beta_{k-1}*v_{k-1}
73  // 2nd: alpha = (v_k, A*v_k) = (v_k , r_k)
74  // 3rd: r_k = r_k - alpha_k*v_k
75  axpyCuda(-beta[k-1],*(Eig_Vec[k-1]), r);
76  alpha[k] = reDotProductCuda(*(Eig_Vec[k]), r);
77  axpyCuda(-alpha[k],*(Eig_Vec[k]), r);
78  // beta_k = ||r_k||
79  beta[k] = sqrt(norm2(r));
80 
81  GrandSchm_test(r, Eig_Vec, k+1, 0);
82 
83  if(k+1 < m)
84  {
85  zeroCuda(*(Eig_Vec[k+1]));
86  axpyCuda(1.0/beta[k], r, *(Eig_Vec[k+1]));
87  }
88  }
89  }
91  return;
92  }
93 
95  Eig_Solver(eigParam, profile), ritz_mat(ritz_mat)
96  {
97  }
98 
100  {
101  }
102 
103  void ImpRstLanczos::operator()(double *alpha, double *beta, cudaColorSpinorField **Eig_Vec, cudaColorSpinorField &r, cudaColorSpinorField &Apsi, int k0, int m)
104  {
105  }
106 } // namespace quda
void operator()(double *alpha, double *beta, cudaColorSpinorField **Eig_Vec, cudaColorSpinorField &r, cudaColorSpinorField &Apsi, int k0, int m)
__host__ __device__ ValueType sqrt(ValueType x)
Definition: complex_quda.h:105
ImpRstLanczos(RitzMat &ritz_mat, QudaEigParam &eigParam, TimeProfile &profile)
void GrandSchm_test(cudaColorSpinorField &psi, cudaColorSpinorField **Eig_Vec, int Nvec, double *delta)
Definition: eig_solver.cpp:45
TimeProfile & profile
Definition: lanczos_quda.h:20
void axpyCuda(const double &a, cudaColorSpinorField &x, cudaColorSpinorField &y)
Definition: blas_quda.cu:115
Lanczos(RitzMat &ritz_mat, QudaEigParam &eigParam, TimeProfile &profile)
double reDotProductCuda(cudaColorSpinorField &a, cudaColorSpinorField &b)
Definition: reduce_quda.cu:170
void Stop(QudaProfileType idx)
#define printfQuda(...)
Definition: util_quda.h:67
void zeroCuda(cudaColorSpinorField &a)
Definition: blas_quda.cu:40
void Start(QudaProfileType idx)
void operator()(double *alpha, double *beta, cudaColorSpinorField **Eig_Vec, cudaColorSpinorField &r, cudaColorSpinorField &Apsi, int k0, int m)
double norm2(const ColorSpinorField &)