-
Notifications
You must be signed in to change notification settings - Fork 104
/
Copy pathdeflation.h
212 lines (158 loc) · 5.76 KB
/
deflation.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#pragma once
#include <invert_quda.h>
#include <vector>
#include <complex_quda.h>
namespace quda {
/**
This struct contains all the metadata required to define the
deflated solvers.
*/
struct DeflationParam {
/** This points to the parameter struct that is passed into QUDA.
We use this to set (per-level) parameters */
QudaEigParam &eig_global;
/** Buffer for Ritz vectors
For staggered: we need to reduce dimensionality of each component?
*/
ColorSpinorField *RV;
/** Inverse Ritz values*/
double *invRitzVals;
/** The Dirac operator to use for spinor deflation operation */
DiracMatrix &matDeflation;
/** Host projection matrix (e.g. eigCG VH A V) */
Complex *matProj;
/** projection matrix leading dimension */
int ld;
/** projection matrix full (maximum) dimension (nev*deflation_grid) */
int tot_dim;
/** current dimension (must match rhs_idx: if(rhs_idx < deflation_grid) curr_nevs <= nev * rhs_idx) */
int cur_dim;
/** use inverse Ritz values for deflation (for the best performance) */
bool use_inv_ritz;
/** Where to compute Ritz vectors */
QudaFieldLocation location;
/** Filename for where to load/store the deflation space */
char filename[100];
DeflationParam(QudaEigParam ¶m, ColorSpinorField *RV, DiracMatrix &matDeflation, int cur_dim = 0) : eig_global(param), RV(RV), matDeflation(matDeflation),
cur_dim(cur_dim), use_inv_ritz(false), location(param.location) {
if(param.nk == 0 || param.np == 0 || (param.np % param.nk != 0)) errorQuda("\nIncorrect deflation space parameters...\n");
//redesign: param.nk => param.nev, param.np => param.deflation_grid*param.nev;
tot_dim = param.np;
ld = ((tot_dim+15) / 16) * tot_dim;
//allocate deflation resources:
matProj = new Complex[ld*tot_dim];
invRitzVals = new double[tot_dim];
//Check that RV is a composite field:
if(RV->IsComposite() == false) errorQuda("\nRitz vectors must be contained in a composite field.\n");
cudaHostRegister(matProj,ld*tot_dim*sizeof(Complex),cudaHostRegisterDefault);
}
~DeflationParam(){
cudaHostUnregister(matProj);
if(matProj) delete[] matProj;
if(invRitzVals) delete[] invRitzVals;
}
};
/**
Deflation methods :
*/
class Deflation {
private:
/** Local copy of the deflation metadata */
DeflationParam ¶m;
/** TimeProfile for this level */
TimeProfile profile;
/** High precision aux field */
ColorSpinorField *r;
/** High precision aux field */
ColorSpinorField *Av;
/** Ritz precision residual vector */
ColorSpinorField *r_sloppy;
/** Deflation matrix operation result */
ColorSpinorField *Av_sloppy;
public:
/**
Constructor for Deflation class
@param param DeflationParam struct that defines all meta data
@param profile Timeprofile instance used to profile
*/
Deflation(DeflationParam ¶m, TimeProfile &profile);
/**
Destructor for Deflation class. Frees any existing Deflation
instance
*/
virtual ~Deflation();
/**
This method verifies the correctness of the MG method. It checks:
1. eigen-vector accuracy
2. ...
*/
void verify();
/**
In the incremental eigcg: expands deflation space.
@param V container of new eigenvectors
@param nev number of vectors to load
*/
void increment(ColorSpinorField &V, int nev);
/**
In the incremental eigcg: reduce deflation space
based on the following criteria:
@param tol : keep all eigenvectors with residual norm less then tol
@param max_nev : keep the lowest max_nev eigenvectors (conservative)
*/
void reduce(double tol, int max_nev);
/**
This applies deflation operation on a given spinor vector(s)
@param out The projected vector
@param in The input vector (or equivalently the right hand side vector)
*/
void operator()(ColorSpinorField &out, ColorSpinorField &in);
/**
@brief Load the eigen space vectors from file
@param RV Loaded eigen-space vectors (pre-allocated)
*/
void loadVectors(ColorSpinorField *RV);
/**
@brief Save the eigen space vectors in file
@param RV Save eigen-space vectors from here
*/
void saveVectors(ColorSpinorField *RV);
/**
@brief Test whether the deflation space is complete
and therefore cannot be further extended
*/
bool is_complete() {return (param.cur_dim == param.tot_dim);}
/**
@brief return deflation space size
*/
int size() {return param.cur_dim;}
/**
@brief Return the total flops done on this and all coarser levels.
*/
double flops() const;
};
/**
Following the multigrid design, this is an object that captures an entire deflation operations.
A bit of a hack at the moment, this is used to allow us
to store and reuse the deflation stuff between solves. This is use by
the newDeflationQuda and destroyDeflationQuda interface functions.
*/
struct deflated_solver {
Dirac *d;
DiracMatrix *m;
ColorSpinorField *RV;//Ritz vectors
DeflationParam *deflParam;
Deflation *defl;
TimeProfile &profile;
deflated_solver(QudaEigParam &eig_param, TimeProfile &profile);
virtual ~deflated_solver()
{
profile.TPSTART(QUDA_PROFILE_FREE);
if (defl) delete defl;
if (deflParam) delete deflParam;
if (RV) delete RV;
if (m) delete m;
if (d) delete d;
profile.TPSTOP(QUDA_PROFILE_FREE);
}
};
} // namespace quda