QUDA
v0.5.0
A library for QCD on GPUs
Main Page
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Pages
quda
lib
dirac_clover.cpp
Go to the documentation of this file.
1
#include <iostream>
2
#include <
dirac_quda.h
>
3
#include <
blas_quda.h
>
4
5
namespace
quda {
6
7
DiracClover::DiracClover
(
const
DiracParam
&
param
)
8
:
DiracWilson
(param), clover(*(param.clover))
9
{
10
initCloverConstants
(
clover
);
11
}
12
13
DiracClover::DiracClover
(
const
DiracClover
&
dirac
)
14
:
DiracWilson
(dirac), clover(dirac.clover)
15
{
16
initCloverConstants
(
clover
);
17
}
18
19
DiracClover::~DiracClover
() { }
20
21
DiracClover
&
DiracClover::operator=
(
const
DiracClover
&
dirac
)
22
{
23
if
(&dirac !=
this
) {
24
DiracWilson::operator=
(dirac);
25
clover
= dirac.
clover
;
26
}
27
return
*
this
;
28
}
29
30
void
DiracClover::checkParitySpinor
(
const
cudaColorSpinorField
&
out
,
const
cudaColorSpinorField
&
in
)
const
31
{
32
Dirac::checkParitySpinor
(out, in);
33
34
if
(out.
Volume
() !=
clover
.
VolumeCB
()) {
35
errorQuda
(
"Parity spinor volume %d doesn't match clover checkboard volume %d"
,
36
out.
Volume
(),
clover
.
VolumeCB
());
37
}
38
}
39
41
void
DiracClover::DslashXpay
(
cudaColorSpinorField
&
out
,
const
cudaColorSpinorField
&
in
,
42
const
QudaParity
parity
,
const
cudaColorSpinorField
&
x
,
43
const
double
&k)
const
44
{
45
initSpinorConstants
(in);
46
checkParitySpinor
(in, out);
47
checkSpinorAlias
(in, out);
48
49
setFace
(
face
);
// FIXME: temporary hack maintain C linkage for dslashCuda
50
51
FullClover
cs(
clover
);
52
asymCloverDslashCuda
(&out,
gauge
, cs, &in, parity,
dagger
, &x, k,
commDim
);
53
54
flops
+= 1872ll*in.
Volume
();
55
}
56
57
// Public method to apply the clover term only
58
void
DiracClover::Clover
(
cudaColorSpinorField
&
out
,
const
cudaColorSpinorField
&
in
,
const
QudaParity
parity
)
const
59
{
60
initSpinorConstants
(in);
61
checkParitySpinor
(in, out);
62
63
// regular clover term
64
FullClover
cs(
clover
);
65
cloverCuda
(&out,
gauge
, cs, &in, parity);
66
67
flops
+= 504ll*in.
Volume
();
68
}
69
70
void
DiracClover::M
(
cudaColorSpinorField
&
out
,
const
cudaColorSpinorField
&
in
)
const
71
{
72
checkFullSpinor
(out, in);
73
DslashXpay
(out.
Odd
(), in.
Even
(),
QUDA_ODD_PARITY
, in.
Odd
(), -
kappa
);
74
DslashXpay
(out.
Even
(), in.
Odd
(),
QUDA_EVEN_PARITY
, in.
Even
(), -
kappa
);
75
}
76
77
void
DiracClover::MdagM
(
cudaColorSpinorField
&
out
,
const
cudaColorSpinorField
&
in
)
const
78
{
79
checkFullSpinor
(out, in);
80
81
bool
reset =
newTmp
(&
tmp1
, in);
82
checkFullSpinor
(*
tmp1
, in);
83
84
M
(*
tmp1
, in);
85
Mdag
(out, *
tmp1
);
86
87
deleteTmp
(&
tmp1
, reset);
88
}
89
90
void
DiracClover::prepare
(
cudaColorSpinorField
* &src,
cudaColorSpinorField
* &sol,
91
cudaColorSpinorField
&
x
,
cudaColorSpinorField
&b,
92
const
QudaSolutionType
solType)
const
93
{
94
if
(solType ==
QUDA_MATPC_SOLUTION
|| solType ==
QUDA_MATPCDAG_MATPC_SOLUTION
) {
95
errorQuda
(
"Preconditioned solution requires a preconditioned solve_type"
);
96
}
97
98
src = &b;
99
sol = &
x
;
100
}
101
102
void
DiracClover::reconstruct
(
cudaColorSpinorField
&
x
,
const
cudaColorSpinorField
&b,
103
const
QudaSolutionType
solType)
const
104
{
105
// do nothing
106
}
107
108
DiracCloverPC::DiracCloverPC
(
const
DiracParam
&
param
) :
109
DiracClover
(param)
110
{
111
// For the preconditioned operator, we need to check that the inverse of the clover term is present
112
if
(!
clover
.cloverInv)
errorQuda
(
"Clover inverse required for DiracCloverPC"
);
113
}
114
115
DiracCloverPC::DiracCloverPC
(
const
DiracCloverPC
&
dirac
) :
DiracClover
(dirac) { }
116
117
DiracCloverPC::~DiracCloverPC
() { }
118
119
DiracCloverPC
&
DiracCloverPC::operator=
(
const
DiracCloverPC
&
dirac
)
120
{
121
if
(&dirac !=
this
) {
122
DiracClover::operator=
(dirac);
123
}
124
return
*
this
;
125
}
126
127
// Public method
128
void
DiracCloverPC::CloverInv
(
cudaColorSpinorField
&
out
,
const
cudaColorSpinorField
&
in
,
129
const
QudaParity
parity
)
const
130
{
131
initSpinorConstants
(in);
132
checkParitySpinor
(in, out);
133
134
// needs to be cloverinv
135
FullClover
cs(
clover
,
true
);
136
cloverCuda
(&out,
gauge
, cs, &in, parity);
137
138
flops
+= 504ll*in.
Volume
();
139
}
140
141
// apply hopping term, then clover: (A_ee^-1 D_eo) or (A_oo^-1 D_oe),
142
// and likewise for dagger: (A_ee^-1 D^dagger_eo) or (A_oo^-1 D^dagger_oe)
143
// NOTE - this isn't Dslash dagger since order should be reversed!
144
void
DiracCloverPC::Dslash
(
cudaColorSpinorField
&
out
,
const
cudaColorSpinorField
&
in
,
145
const
QudaParity
parity
)
const
146
{
147
initSpinorConstants
(in);
148
checkParitySpinor
(in, out);
149
checkSpinorAlias
(in, out);
150
151
setFace
(
face
);
// FIXME: temporary hack maintain C linkage for dslashCuda
152
153
FullClover
cs(
clover
,
true
);
154
cloverDslashCuda
(&out,
gauge
, cs, &in, parity,
dagger
, 0, 0.0,
commDim
);
155
156
flops
+= 1824ll*in.
Volume
();
157
}
158
159
// xpay version of the above
160
void
DiracCloverPC::DslashXpay
(
cudaColorSpinorField
&
out
,
const
cudaColorSpinorField
&
in
,
161
const
QudaParity
parity
,
const
cudaColorSpinorField
&
x
,
162
const
double
&k)
const
163
{
164
initSpinorConstants
(in);
165
checkParitySpinor
(in, out);
166
checkSpinorAlias
(in, out);
167
168
setFace
(
face
);
// FIXME: temporary hack maintain C linkage for dslashCuda
169
170
FullClover
cs(
clover
,
true
);
171
cloverDslashCuda
(&out,
gauge
, cs, &in, parity,
dagger
, &x, k,
commDim
);
172
173
flops
+= 1872ll*in.
Volume
();
174
}
175
176
// Apply the even-odd preconditioned clover-improved Dirac operator
177
void
DiracCloverPC::M
(
cudaColorSpinorField
&
out
,
const
cudaColorSpinorField
&
in
)
const
178
{
179
double
kappa2 = -
kappa
*
kappa
;
180
bool
reset1 =
newTmp
(&
tmp1
, in);
181
182
if
(
matpcType
==
QUDA_MATPC_EVEN_EVEN_ASYMMETRIC
) {
183
// DiracCloverPC::Dslash applies A^{-1}Dslash
184
Dslash
(*
tmp1
, in,
QUDA_ODD_PARITY
);
185
// DiracClover::DslashXpay applies (A - kappa^2 D)
186
DiracClover::DslashXpay
(out, *
tmp1
,
QUDA_EVEN_PARITY
, in, kappa2);
187
}
else
if
(
matpcType
==
QUDA_MATPC_ODD_ODD_ASYMMETRIC
) {
188
// DiracCloverPC::Dslash applies A^{-1}Dslash
189
Dslash
(*
tmp1
, in,
QUDA_EVEN_PARITY
);
190
// DiracClover::DslashXpay applies (A - kappa^2 D)
191
DiracClover::DslashXpay
(out, *
tmp1
,
QUDA_ODD_PARITY
, in, kappa2);
192
}
else
if
(!
dagger
) {
// symmetric preconditioning
193
if
(
matpcType
==
QUDA_MATPC_EVEN_EVEN
) {
194
Dslash
(*
tmp1
, in,
QUDA_ODD_PARITY
);
195
DslashXpay
(out, *
tmp1
,
QUDA_EVEN_PARITY
, in, kappa2);
196
}
else
if
(
matpcType
==
QUDA_MATPC_ODD_ODD
) {
197
Dslash
(*
tmp1
, in,
QUDA_EVEN_PARITY
);
198
DslashXpay
(out, *
tmp1
,
QUDA_ODD_PARITY
, in, kappa2);
199
}
else
{
200
errorQuda
(
"Invalid matpcType"
);
201
}
202
}
else
{
// symmetric preconditioning, dagger
203
if
(
matpcType
==
QUDA_MATPC_EVEN_EVEN
) {
204
CloverInv
(out, in,
QUDA_EVEN_PARITY
);
205
Dslash
(*
tmp1
, out,
QUDA_ODD_PARITY
);
206
DiracWilson::DslashXpay
(out, *
tmp1
,
QUDA_EVEN_PARITY
, in, kappa2);
207
}
else
if
(
matpcType
==
QUDA_MATPC_ODD_ODD
) {
208
CloverInv
(out, in,
QUDA_ODD_PARITY
);
209
Dslash
(*
tmp1
, out,
QUDA_EVEN_PARITY
);
210
DiracWilson::DslashXpay
(out, *
tmp1
,
QUDA_ODD_PARITY
, in, kappa2);
211
}
else
{
212
errorQuda
(
"MatPCType %d not valid for DiracCloverPC"
,
matpcType
);
213
}
214
}
215
216
deleteTmp
(&
tmp1
, reset1);
217
}
218
219
void
DiracCloverPC::MdagM
(
cudaColorSpinorField
&
out
,
const
cudaColorSpinorField
&
in
)
const
220
{
221
// need extra temporary because of symmetric preconditioning dagger
222
// and for multi-gpu the input and output fields cannot alias
223
bool
reset =
newTmp
(&
tmp2
, in);
224
M
(*
tmp2
, in);
225
Mdag
(out, *
tmp2
);
226
deleteTmp
(&
tmp2
, reset);
227
}
228
229
void
DiracCloverPC::prepare
(
cudaColorSpinorField
* &src,
cudaColorSpinorField
* &sol,
230
cudaColorSpinorField
&
x
,
cudaColorSpinorField
&b,
231
const
QudaSolutionType
solType)
const
232
{
233
// we desire solution to preconditioned system
234
if
(solType ==
QUDA_MATPC_SOLUTION
|| solType ==
QUDA_MATPCDAG_MATPC_SOLUTION
) {
235
src = &b;
236
sol = &
x
;
237
return
;
238
}
239
240
bool
reset =
newTmp
(&
tmp1
, b.
Even
());
241
242
// we desire solution to full system
243
if
(
matpcType
==
QUDA_MATPC_EVEN_EVEN
) {
244
// src = A_ee^-1 (b_e + k D_eo A_oo^-1 b_o)
245
src = &(x.
Odd
());
246
CloverInv
(*src, b.
Odd
(),
QUDA_ODD_PARITY
);
247
DiracWilson::DslashXpay
(*
tmp1
, *src,
QUDA_EVEN_PARITY
, b.
Even
(),
kappa
);
248
CloverInv
(*src, *
tmp1
,
QUDA_EVEN_PARITY
);
249
sol = &(x.
Even
());
250
}
else
if
(
matpcType
==
QUDA_MATPC_ODD_ODD
) {
251
// src = A_oo^-1 (b_o + k D_oe A_ee^-1 b_e)
252
src = &(x.
Even
());
253
CloverInv
(*src, b.
Even
(),
QUDA_EVEN_PARITY
);
254
DiracWilson::DslashXpay
(*
tmp1
, *src,
QUDA_ODD_PARITY
, b.
Odd
(),
kappa
);
255
CloverInv
(*src, *
tmp1
,
QUDA_ODD_PARITY
);
256
sol = &(x.
Odd
());
257
}
else
if
(
matpcType
==
QUDA_MATPC_EVEN_EVEN_ASYMMETRIC
) {
258
// src = b_e + k D_eo A_oo^-1 b_o
259
src = &(x.
Odd
());
260
CloverInv
(*
tmp1
, b.
Odd
(),
QUDA_ODD_PARITY
);
// safe even when *tmp1 = b.odd
261
DiracWilson::DslashXpay
(*src, *
tmp1
,
QUDA_EVEN_PARITY
, b.
Even
(),
kappa
);
262
sol = &(x.
Even
());
263
}
else
if
(
matpcType
==
QUDA_MATPC_ODD_ODD_ASYMMETRIC
) {
264
// src = b_o + k D_oe A_ee^-1 b_e
265
src = &(x.
Even
());
266
CloverInv
(*
tmp1
, b.
Even
(),
QUDA_EVEN_PARITY
);
// safe even when *tmp1 = b.even
267
DiracWilson::DslashXpay
(*src, *
tmp1
,
QUDA_ODD_PARITY
, b.
Odd
(),
kappa
);
268
sol = &(x.
Odd
());
269
}
else
{
270
errorQuda
(
"MatPCType %d not valid for DiracCloverPC"
,
matpcType
);
271
}
272
273
// here we use final solution to store parity solution and parity source
274
// b is now up for grabs if we want
275
276
deleteTmp
(&
tmp1
, reset);
277
278
}
279
280
void
DiracCloverPC::reconstruct
(
cudaColorSpinorField
&
x
,
const
cudaColorSpinorField
&b,
281
const
QudaSolutionType
solType)
const
282
{
283
if
(solType ==
QUDA_MATPC_SOLUTION
|| solType ==
QUDA_MATPCDAG_MATPC_SOLUTION
) {
284
return
;
285
}
286
287
checkFullSpinor
(x, b);
288
289
bool
reset =
newTmp
(&
tmp1
, b.
Even
());
290
291
// create full solution
292
293
if
(
matpcType
==
QUDA_MATPC_EVEN_EVEN
||
294
matpcType
==
QUDA_MATPC_EVEN_EVEN_ASYMMETRIC
) {
295
// x_o = A_oo^-1 (b_o + k D_oe x_e)
296
DiracWilson::DslashXpay
(*
tmp1
, x.
Even
(),
QUDA_ODD_PARITY
, b.
Odd
(),
kappa
);
297
CloverInv
(x.
Odd
(), *
tmp1
,
QUDA_ODD_PARITY
);
298
}
else
if
(
matpcType
==
QUDA_MATPC_ODD_ODD
||
299
matpcType
==
QUDA_MATPC_ODD_ODD_ASYMMETRIC
) {
300
// x_e = A_ee^-1 (b_e + k D_eo x_o)
301
DiracWilson::DslashXpay
(*
tmp1
, x.
Odd
(),
QUDA_EVEN_PARITY
, b.
Even
(),
kappa
);
302
CloverInv
(x.
Even
(), *
tmp1
,
QUDA_EVEN_PARITY
);
303
}
else
{
304
errorQuda
(
"MatPCType %d not valid for DiracCloverPC"
,
matpcType
);
305
}
306
307
deleteTmp
(&
tmp1
, reset);
308
309
}
310
311
}
// namespace quda
Generated on Wed Mar 20 2013 12:52:14 for QUDA by
1.8.2