QUDA  v0.7.0
A library for QCD on GPUs
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
inv_mre.cpp
Go to the documentation of this file.
1 #include <invert_quda.h>
2 #include <blas_quda.h>
3 
4 namespace quda {
5 
7  : mat(mat), profile(profile){
8 
9  }
10 
12 
13  }
14 
17 
18  /*
19  We want to find the best initial guess of the solution of
20  A x = b, and we have N previous solutions x_i.
21  The method goes something like this:
22 
23  1. Orthonormalise the p_i and q_i
24  2. Form the matrix G_ij = x_i^dagger A x_j
25  3. Form the vector B_i = x_i^dagger b
26  4. solve A_ij a_j = B_i
27  5. x = a_i p_i
28  */
29 
30  // if no guess is required, then set initial guess = 0
31  if (N == 0) {
32  zeroCuda(x);
33  return;
34  }
35 
36  double b2 = norm2(b);
37 
38  // Array to hold the matrix elements
39  Complex **G = new Complex*[N];
40  for (int i=0; i<N; i++) G[i] = new Complex[N];
41 
42  // Solution and source vectors
43  Complex *alpha = new Complex[N];
44  Complex *beta = new Complex[N];
45 
46  // Orthonormalise the vector basis
47  for (int i=0; i<N; i++) {
48  double p2 = norm2(*p[i]);
49  axCuda(1 / sqrt(p2), *p[i]);
50  for (int j=i+1; j<N; j++) {
51  Complex xp = cDotProductCuda(*p[i], *p[j]);
52  caxpyCuda(-xp, *p[i], *p[j]);
53  }
54  }
55 
56  // Perform sparse matrix multiplication and construct rhs
57  for (int i=0; i<N; i++) {
58  beta[i] = cDotProductCuda(*p[i], b);
59  mat(*q[i], *p[i]);
60  G[i][i] = reDotProductCuda(*q[i], *p[i]);
61  }
62 
63  // Construct the matrix
64  for (int j=0; j<N; j++) {
65  for (int k=j+1; k<N; k++) {
66  G[j][k] = cDotProductCuda(*p[j], *q[k]);
67  G[k][j] = conj(G[j][k]);
68  }
69  }
70 
71  // Gauss-Jordan elimination with partial pivoting
72  for (int i=0; i<N; i++) {
73 
74  // Perform partial pivoting
75  int k = i;
76  for (int j=i+1; j<N; j++) if (abs(G[j][j]) > abs(G[k][k])) k = j;
77  if (k != i) {
78  std::swap<Complex>(beta[k], beta[i]);
79  for (int j=0; j<N; j++) std::swap<Complex>(G[k][j], G[i][j]);
80  }
81 
82  // Convert matrix to upper triangular form
83  for (int j=i+1; j<N; j++) {
84  Complex xp = G[j][i]/G[i][i];
85  beta[j] -= xp * beta[i];
86  for (int k=0; k<N; k++) G[j][k] -= xp * G[i][k];
87  }
88  }
89 
90  // Use Gaussian Elimination to solve equations and calculate initial guess
91  zeroCuda(x);
92  for (int i=N-1; i>=0; i--) {
93  alpha[i] = 0.0;
94  for (int j=i+1; j<N; j++) alpha[i] += G[i][j] * alpha[j];
95  alpha[i] = (beta[i]-alpha[i])/G[i][i];
96  caxpyCuda(alpha[i], *p[i], x);
97  caxpyCuda(-alpha[i], *q[i], b);
98  //printfQuda("%d %e %e\n", i, real(alpha[i]), imag(alpha[i]));
99  }
100 
101  double rsd = sqrt(norm2(b) / b2 );
102  printfQuda("MinResExt: N = %d, |res| / |src| = %e\n", N, rsd);
103 
104  for (int j=0; j<N; j++) delete [] G[j];
105 
106  delete [] G;
107  delete [] alpha;
108  delete [] beta;
109  }
110 
111 } // namespace quda
void caxpyCuda(const Complex &a, cudaColorSpinorField &x, cudaColorSpinorField &y)
Definition: blas_quda.cu:207
void operator()(cudaColorSpinorField &x, cudaColorSpinorField &b, cudaColorSpinorField **p, cudaColorSpinorField **q, int N)
Definition: inv_mre.cpp:15
__host__ __device__ ValueType sqrt(ValueType x)
Definition: complex_quda.h:105
std::complex< double > Complex
Definition: eig_variables.h:13
void mat(void *out, void **fatlink, void **longlink, void *in, double kappa, int dagger_bit, QudaPrecision sPrecision, QudaPrecision gPrecision)
Complex cDotProductCuda(cudaColorSpinorField &, cudaColorSpinorField &)
Definition: reduce_quda.cu:468
MinResExt(DiracMatrix &mat, TimeProfile &profile)
Definition: inv_mre.cpp:6
int x[4]
double reDotProductCuda(cudaColorSpinorField &a, cudaColorSpinorField &b)
Definition: reduce_quda.cu:170
virtual ~MinResExt()
Definition: inv_mre.cpp:11
#define printfQuda(...)
Definition: util_quda.h:67
void zeroCuda(cudaColorSpinorField &a)
Definition: blas_quda.cu:40
__host__ __device__ ValueType abs(ValueType x)
Definition: complex_quda.h:110
__host__ __device__ ValueType conj(ValueType x)
Definition: complex_quda.h:115
void axCuda(const double &a, cudaColorSpinorField &x)
Definition: blas_quda.cu:171
double norm2(const ColorSpinorField &)
const DiracMatrix & mat
Definition: invert_quda.h:511