su2hmc
Loading...
Searching...
No Matches
integrate.h File Reference

Integrators for the HMC. More...

#include <stdbool.h>
#include <random.h>
#include <sizes.h>
Include dependency graph for integrate.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

int Gauge_Update (const double d, double *pp, Complex *u11t, Complex *u12t, Complex_f *u11t_f, Complex_f *u12t_f)
 Gauge update for the integration step of the HMC.
 
int Momentum_Update (const double d, const double *dSdpi, double *pp)
 Wrapper for the momentum update during the integration step of the HMC.
 
int Leapfrog (Complex *u11t, Complex *u12t, Complex_f *u11t_f, Complex_f *u12t_f, Complex *X0, Complex *X1, Complex *Phi, double *dk4m, double *dk4p, float *dk4m_f, float *dk4p_f, double *dSdpi, double *pp, int *iu, int *id, Complex *gamval, Complex_f *gamval_f, int *gamin, Complex jqq, float beta, float akappa, int stepl, float dt, double *ancg, int *itot, float proby)
 Leapfrog integrator. Each trajectory step takes the form of p->p+dt/2,u->u+dt,p->p+dt/2 In practice this is implemented for the entire trajectory as p->p+dt/2,u->u+dt,p->p+dt,u->u+dt,p->p+dt,...p->p+dt/2,u->u+dt,p->p+dt/2.
 
int OMF2 (Complex *u11t, Complex *u12t, Complex_f *u11t_f, Complex_f *u12t_f, Complex *X0, Complex *X1, Complex *Phi, double *dk4m, double *dk4p, float *dk4m_f, float *dk4p_f, double *dSdpi, double *pp, int *iu, int *id, Complex *gamval, Complex_f *gamval_f, int *gamin, Complex jqq, float beta, float akappa, int stepl, float dt, double *ancg, int *itot, float proby)
 OMF integrator. Each trajectory step takes the form of p->p+dt/2,u->u+dt,p->p+dt/2 In practice this is implemented for the entire trajectory as p->p+dt/2,u->u+dt,p->p+dt,u->u+dt,p->p+dt,...p->p+dt/2,u->u+dt,p->p+dt/2.
 
int OMF4 (Complex *u11t, Complex *u12t, Complex_f *u11t_f, Complex_f *u12t_f, Complex *X0, Complex *X1, Complex *Phi, double *dk4m, double *dk4p, float *dk4m_f, float *dk4p_f, double *dSdpi, double *pp, int *iu, int *id, Complex *gamval, Complex_f *gamval_f, int *gamin, Complex jqq, float beta, float akappa, int stepl, float dt, double *ancg, int *itot, float proby)
 

Detailed Description

Integrators for the HMC.

Definition in file integrate.h.

Function Documentation

◆ Gauge_Update()

int Gauge_Update ( const double d,
double * pp,
Complex * u11t,
Complex * u12t,
Complex_f * u11t_f,
Complex_f * u12t_f )

Gauge update for the integration step of the HMC.

Parameters
dtGauge step size
ppMomentum field
u11t,u12tDouble precision gauge fields
u11t_f,u12t_fSingle precision gauge fields
Returns
Zero on success, integer error code otherwise.

Definition at line 3 of file integrate.c.

3 {
4 /*
5 * @brief Generates new trial fields
6 *
7 * @see cuGauge_Update (CUDA Wrapper)
8 *
9 * @param d: Half lattice spacing
10 * @param pp: Momentum field
11 * @param u11t: First colour field
12 * @param u12t: Second colour field
13 *
14 * @returns Zero on success, integer error code otherwise
15 */
16 char *funcname = "Gauge_Update";
17#ifdef __NVCC__
18 cuGauge_Update(d,pp,u11t,u12t,dimGrid,dimBlock);
19#else
20#pragma omp parallel for simd collapse(2) aligned(pp,u11t,u12t:AVX)
21 for(int i=0;i<kvol;i++)
22 for(int mu = 0; mu<ndim; mu++){
23 /*
24 * Sticking to what was in the FORTRAN for variable names.
25 * CCC for cosine SSS for sine AAA for...
26 * Re-exponentiating the force field. Can be done analytically in SU(2)
27 * using sine and cosine which is nice
28 */
29
30 double AAA = d*sqrt(pp[i*nadj*ndim+mu]*pp[i*nadj*ndim+mu]\
31 +pp[(i*nadj+1)*ndim+mu]*pp[(i*nadj+1)*ndim+mu]\
32 +pp[(i*nadj+2)*ndim+mu]*pp[(i*nadj+2)*ndim+mu]);
33 double CCC = cos(AAA);
34 double SSS = d*sin(AAA)/AAA;
35 Complex a11 = CCC+I*SSS*pp[(i*nadj+2)*ndim+mu];
36 Complex a12 = pp[(i*nadj+1)*ndim+mu]*SSS + I*SSS*pp[i*nadj*ndim+mu];
37 //b11 and b12 are u11t and u12t terms, so we'll use u12t directly
38 //but use b11 for u11t to prevent RAW dependency
39 complex b11 = u11t[i*ndim+mu];
40 u11t[i*ndim+mu] = a11*b11-a12*conj(u12t[i*ndim+mu]);
41 u12t[i*ndim+mu] = a11*u12t[i*ndim+mu]+a12*conj(b11);
42 }
43#endif
44 Reunitarise(u11t,u12t);
45 //Get trial fields from accelerator for halo exchange
46 Trial_Exchange(u11t,u12t,u11t_f,u12t_f);
47 return 0;
48}
int Trial_Exchange(Complex *u11t, Complex *u12t, Complex_f *u11t_f, Complex_f *u12t_f)
Exchanges the trial fields.
Definition par_mpi.c:1178
#define nadj
adjacent spatial indices
Definition sizes.h:175
#define kvol
Sublattice volume.
Definition sizes.h:154
#define Complex
Double precision complex number.
Definition sizes.h:58
#define ndim
Dimensions.
Definition sizes.h:179
int Reunitarise(Complex *u11t, Complex *u12t)
Reunitarises u11t and u12t as in conj(u11t[i])*u11t[i]+conj(u12t[i])*u12t[i]=1.
Definition matrices.c:904

References Complex, Gauge_Update(), kvol, nadj, ndim, Reunitarise(), and Trial_Exchange().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Leapfrog()

int Leapfrog ( Complex * u11t,
Complex * u12t,
Complex_f * u11t_f,
Complex_f * u12t_f,
Complex * X0,
Complex * X1,
Complex * Phi,
double * dk4m,
double * dk4p,
float * dk4m_f,
float * dk4p_f,
double * dSdpi,
double * pp,
int * iu,
int * id,
Complex * gamval,
Complex_f * gamval_f,
int * gamin,
Complex jqq,
float beta,
float akappa,
int stepl,
float dt,
double * ancg,
int * itot,
float proby )

Leapfrog integrator. Each trajectory step takes the form of p->p+dt/2,u->u+dt,p->p+dt/2 In practice this is implemented for the entire trajectory as p->p+dt/2,u->u+dt,p->p+dt,u->u+dt,p->p+dt,...p->p+dt/2,u->u+dt,p->p+dt/2.

Parameters
u11t,u12tDouble precision colour fields
u11t_f,u12t_fSingle precision colour fields
X0Up/down partitioned pseudofermion field
X1Holder for the partitioned fermion field, then the conjugate gradient output
PhiPseudofermion field
dk4m\(\left(1+\gamma_0\right)e^{-\mu}\)
dk4p\(\left(1-\gamma_0\right)e^\mu\)
dk4m_f\(\left(1+\gamma_0\right)e^{-\mu}\) float
dk4p_f\(\left(1-\gamma_0\right)e^\mu\) float
dSdpiThe force
ppMomentum field
iu,idLattice indices
gaminGamma indices
gamvalDouble precision gamma matrices rescaled by kappa
gamval_fSingle precision gamma matrices rescaled by kappa
jqqDiquark source
akappaHopping parameter
betaInverse gauge coupling
steplSteps per trajectory
dtStep size
ancgCounter for average conjugate gradient iterations
itotTotal average conjugate gradient iterations
probyTermination probability for random trajectory length
Returns
Zero on success, integer error code otherwise

Definition at line 60 of file integrate.c.

64{
65 //This was originally in the half-step of the FORTRAN code, but it makes more sense to declare
66 //it outside the loop. Since it's always being subtracted we'll define it as negative
67 const double d =-dt*0.5;
68 //Half step forward for p
69 //=======================
70#ifdef _DEBUG
71 printf("Evaluating force on rank %i\n", rank);
72#endif
73 Force(dSdpi, 1, rescgg,X0,X1,Phi,u11t,u12t,u11t_f,u12t_f,iu,id,gamval,gamval_f,gamin,dk4m,dk4p,\
74 dk4m_f,dk4p_f,jqq,akappa,beta,ancg);
75 Momentum_Update(d,dSdpi,pp);
76 //Main loop for classical time evolution
77 //======================================
78 bool end_traj=false; int step =1;
79 // for(int step = 1; step<=stepmax; step++){
80 do{
81#ifdef _DEBUG
82 if(!rank)
83 printf("Step: %d\n", step);
84#endif
85 //The FORTRAN redefines d=dt here, which makes sense if you have a limited line length.
86 //I'll stick to using dt though.
87 //step (i) st(t+dt)=st(t)+p(t+dt/2)*dt;
88 //Note that we are moving from kernel to kernel within the default streams so don't need a Device_Sync here
89 Gauge_Update(dt,pp,u11t,u12t,u11t_f,u12t_f);
90
91 //p(t+3et/2)=p(t+dt/2)-dSds(t+dt)*dt
92 // Force(dSdpi, 0, rescgg);
93 Force(dSdpi, 0, rescgg,X0,X1,Phi,u11t,u12t,u11t_f,u12t_f,iu,id,gamval,gamval_f,gamin,dk4m,dk4p,\
94 dk4m_f,dk4p_f,jqq,akappa,beta,ancg);
95
96 // if(step>=stepl*4.0/5.0 && (step>=stepl*(6.0/5.0) || Par_granf()<proby)){
97 if(step==stepl){
98 //Final trajectory has a half momentum step
99 Momentum_Update(d,dSdpi,pp);
100 *itot+=step;
101 *ancg/=step;
102 end_traj=true;
103 break;
104 }
105 else{
106 //Otherwise, there's a half step at the end and start of each trajectory, so we combine them into one full step.
107 Momentum_Update(-dt,dSdpi,pp);
108 step++;
109 }
110 }while(!end_traj);
111 return 0;
112}
int Gauge_Update(const double d, double *pp, Complex *u11t, Complex *u12t, Complex_f *u11t_f, Complex_f *u12t_f)
Gauge update for the integration step of the HMC.
Definition integrate.c:3
int Momentum_Update(const double d, const double *dSdpi, double *pp)
Wrapper for the momentum update during the integration step of the HMC.
Definition integrate.c:49
int rank
The MPI rank.
Definition par_mpi.c:22
#define rescgg
Conjugate gradient residue for update.
Definition sizes.h:240
int Force(double *dSdpi, int iflag, double res1, Complex *X0, Complex *X1, Complex *Phi, Complex *u11t, Complex *u12t, Complex_f *u11t_f, Complex_f *u12t_f, unsigned int *iu, unsigned int *id, Complex *gamval, Complex_f *gamval_f, int *gamin, double *dk4m, double *dk4p, float *dk4m_f, float *dk4p_f, Complex_f jqq, float akappa, float beta, double *ancg)
Calculates the force at each intermediate time.
Definition force.c:131

References Force(), Gauge_Update(), Leapfrog(), Momentum_Update(), rank, and rescgg.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Momentum_Update()

int Momentum_Update ( const double d,
const double * dSdpi,
double * pp )
inline

Wrapper for the momentum update during the integration step of the HMC.

Parameters
dtGauge step size
ppMomentum field
dSdpiForce field
Returns
Zero on success, integer error code otherwise.

Definition at line 49 of file integrate.c.

50{
51#ifdef __NVCC__
52 cublasDaxpy(cublas_handle,kmom, &d, dSdpi, 1, pp, 1);
53#elif defined USE_BLAS
54 cblas_daxpy(kmom, d, dSdpi, 1, pp, 1);
55#else
56 for(int i=0;i<kmom;i++)
57 pp[i]+=d*dSdpi[i];
58#endif
59}
#define kmom
sublattice momentum sites
Definition sizes.h:184

References kmom, and Momentum_Update().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OMF2()

int OMF2 ( Complex * u11t,
Complex * u12t,
Complex_f * u11t_f,
Complex_f * u12t_f,
Complex * X0,
Complex * X1,
Complex * Phi,
double * dk4m,
double * dk4p,
float * dk4m_f,
float * dk4p_f,
double * dSdpi,
double * pp,
int * iu,
int * id,
Complex * gamval,
Complex_f * gamval_f,
int * gamin,
Complex jqq,
float beta,
float akappa,
int stepl,
float dt,
double * ancg,
int * itot,
float proby )

OMF integrator. Each trajectory step takes the form of p->p+dt/2,u->u+dt,p->p+dt/2 In practice this is implemented for the entire trajectory as p->p+dt/2,u->u+dt,p->p+dt,u->u+dt,p->p+dt,...p->p+dt/2,u->u+dt,p->p+dt/2.

Parameters
u11t,u12tDouble precision colour fields
u11t_f,u12t_fSingle precision colour fields
X0Up/down partitioned pseudofermion field
X1Holder for the partitioned fermion field, then the conjugate gradient output
PhiPseudofermion field
dk4m\(\left(1+\gamma_0\right)e^{-\mu}\)
dk4p\(\left(1-\gamma_0\right)e^\mu\)
dk4m_f\(\left(1+\gamma_0\right)e^{-\mu}\) float
dk4p_f\(\left(1-\gamma_0\right)e^\mu\) float
dSdpiThe force
ppMomentum field
iu,idLattice indices
gaminGamma indices
gamvalDouble precision gamma matrices rescaled by kappa
gamval_fSingle precision gamma matrices rescaled by kappa
jqqDiquark source
akappaHopping parameter
betaInverse gauge coupling
steplSteps per trajectory
dtStep size
ancgCounter for average conjugate gradient iterations
itotTotal average conjugate gradient iterations
probyTermination probability for random trajectory length
Returns
Zero on success, integer error code otherwise

Definition at line 113 of file integrate.c.

117{
118 const double lambda=0.5-(pow(2.0*sqrt(326.0)+36.0,1.0/3.0)/12.0)+1.0/(6*pow(2.0*sqrt(326.0) + 36.0,1.0/3.0));
119 //const double lambda=1.0/6.0;
120 // const double lambda=0.5;
121
122 //Gauge update by half dt
123 const double dU = dt*0.5;
124
125 //Momentum updates by lambda, 2lambda and (1-2lambda) in the middle
126 const double dp= -lambda*dt;
127 const double dp2= 2.0*dp;
128 const double dpm= -(1.0-2.0*lambda)*dt;
129 //Initial step forward for p
130 //=======================
131#ifdef _DEBUG
132 printf("Evaluating force on rank %i\n", rank);
133#endif
134 Force(dSdpi, 1, rescgg,X0,X1,Phi,u11t,u12t,u11t_f,u12t_f,iu,id,gamval,gamval_f,gamin,dk4m,dk4p,\
135 dk4m_f,dk4p_f,jqq,akappa,beta,ancg);
136 //Initial momentum update
137 Momentum_Update(dp,dSdpi,pp);
138
139 //Main loop for classical time evolution
140 //======================================
141 bool end_traj=false; int step =1;
142 // for(int step = 1; step<=stepmax; step++){
143 do{
144#ifdef _DEBUG
145 if(!rank)
146 printf("Step: %d\n", step);
147#endif
148 //First gauge update
149 Gauge_Update(dU,pp,u11t,u12t,u11t_f,u12t_f);
150
151 //Calculate force for middle momentum update
152 Force(dSdpi, 0, rescgg,X0,X1,Phi,u11t,u12t,u11t_f,u12t_f,iu,id,gamval,gamval_f,gamin,dk4m,dk4p,\
153 dk4m_f,dk4p_f,jqq,akappa,beta,ancg);
154 //Now do the middle momentum update
155 Momentum_Update(dpm,dSdpi,pp);
156
157 //Second gauge update
158 Gauge_Update(dU,pp,u11t,u12t,u11t_f,u12t_f);
159
160 //Calculate force for second momentum update
161 Force(dSdpi, 0, rescgg,X0,X1,Phi,u11t,u12t,u11t_f,u12t_f,iu,id,gamval,gamval_f,gamin,dk4m,dk4p,\
162 dk4m_f,dk4p_f,jqq,akappa,beta,ancg);
163
164 //if(step>=stepl*4.0/5.0 && (step>=stepl*(6.0/5.0) || Par_granf()<proby)){
165 if(step==stepl){
166 //Final momentum step
167 Momentum_Update(dp,dSdpi,pp);
168 *itot+=step;
169 //Two force terms, so an extra factor of two in the average?
170 //Or leave it as it was, to get the average CG iterations per trajectory rather than force
171 *ancg/=step;
172 end_traj=true;
173 break;
174 }
175 else{
176 //Since we apply the momentum at the start and end of a step we instead apply a double step here
177 Momentum_Update(dp2,dSdpi,pp);
178 step++;
179 }
180 }while(!end_traj);
181 return 0;
182}

References Force(), Gauge_Update(), Momentum_Update(), OMF2(), rank, and rescgg.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OMF4()

int OMF4 ( Complex * u11t,
Complex * u12t,
Complex_f * u11t_f,
Complex_f * u12t_f,
Complex * X0,
Complex * X1,
Complex * Phi,
double * dk4m,
double * dk4p,
float * dk4m_f,
float * dk4p_f,
double * dSdpi,
double * pp,
int * iu,
int * id,
Complex * gamval,
Complex_f * gamval_f,
int * gamin,
Complex jqq,
float beta,
float akappa,
int stepl,
float dt,
double * ancg,
int * itot,
float proby )

Momentum updates

Outer updates depend on r1. We have two of these, doubled for between full steps

Middle updates depend on r3

Inner updates depend on r1 and r3

Gauge updates. These depend on r2 and r4

Outer gauge update depends on r2

Middle gauge update depends on r4

Inner gauge update depends on r2 and r4

Definition at line 183 of file integrate.c.

187{
188 //These values were lifted from openqcd-fastsum, and should probably be tuned for QC2D. They also probably never
189 //will be...
190 const double r1 = 0.08398315262876693;
191 const double r2 = 0.2539785108410595;
192 const double r3 = 0.6822365335719091;
193 const double r4 = -0.03230286765269967;
196 const double dpO= -r1*dt;
197 const double dpO2= 2*dpO;
199 const double dpM= -r3*dt;
201 const double dpI= -(0.5-r1-r3)*dt;
202
205 const double duO = dt*r2;
207 const double duM = dt*r4;
209 const double duI = dt*(1-2*(r2+r4));
210
211 //Initial step forward for p
212 //=======================
213#ifdef _DEBUG
214 printf("Evaluating force on rank %i\n", rank);
215#endif
216 Force(dSdpi, 1, rescgg,X0,X1,Phi,u11t,u12t,u11t_f,u12t_f,iu,id,gamval,gamval_f,gamin,dk4m,dk4p,\
217 dk4m_f,dk4p_f,jqq,akappa,beta,ancg);
218 Momentum_Update(dpO,dSdpi,pp);
219
220 //Main loop for classical time evolution
221 //======================================
222 bool end_traj=false; int step =1;
223 // for(int step = 1; step<=stepmax; step++){
224 do{
225#ifdef _DEBUG
226 if(!rank)
227 printf("Step: %d\n", step);
228#endif
229 //First outer gauge update
230 Gauge_Update(duO,pp,u11t,u12t,u11t_f,u12t_f);
231
232 //Calculate force for first middle momentum update
233 Force(dSdpi, 0, rescgg,X0,X1,Phi,u11t,u12t,u11t_f,u12t_f,iu,id,gamval,gamval_f,gamin,dk4m,dk4p,\
234 dk4m_f,dk4p_f,jqq,akappa,beta,ancg);
235 //Now do the first middle momentum update
236 Momentum_Update(dpM,dSdpi,pp);
237
238 //First middle gauge update
239 Gauge_Update(duM,pp,u11t,u12t,u11t_f,u12t_f);
240
241 //Calculate force for first inner momentum update
242 Force(dSdpi, 0, rescgg,X0,X1,Phi,u11t,u12t,u11t_f,u12t_f,iu,id,gamval,gamval_f,gamin,dk4m,dk4p,\
243 dk4m_f,dk4p_f,jqq,akappa,beta,ancg);
244 //Now do the first inner momentum update
245 Momentum_Update(dpI,dSdpi,pp);
246
247 //Inner gauge update
248 Gauge_Update(duI,pp,u11t,u12t,u11t_f,u12t_f);
249
250 //Calculate force for second inner momentum update
251 Force(dSdpi, 0, rescgg,X0,X1,Phi,u11t,u12t,u11t_f,u12t_f,iu,id,gamval,gamval_f,gamin,dk4m,dk4p,\
252 dk4m_f,dk4p_f,jqq,akappa,beta,ancg);
253 //Now do the second inner momentum update
254 Momentum_Update(dpI,dSdpi,pp);
255
256 //Second middle gauge update
257 Gauge_Update(duM,pp,u11t,u12t,u11t_f,u12t_f);
258
259 //Calculate force for second middle momentum update
260 Force(dSdpi, 0, rescgg,X0,X1,Phi,u11t,u12t,u11t_f,u12t_f,iu,id,gamval,gamval_f,gamin,dk4m,dk4p,\
261 dk4m_f,dk4p_f,jqq,akappa,beta,ancg);
262 //Now do the second middle momentum update
263 Momentum_Update(dpM,dSdpi,pp);
264
265 //Second outer gauge update
266 Gauge_Update(duO,pp,u11t,u12t,u11t_f,u12t_f);
267
268 //Calculate force for outer momentum update
269 Force(dSdpi, 0, rescgg,X0,X1,Phi,u11t,u12t,u11t_f,u12t_f,iu,id,gamval,gamval_f,gamin,dk4m,dk4p,\
270 dk4m_f,dk4p_f,jqq,akappa,beta,ancg);
271
272 //Outer momentum update depends on if we've finished the trajectory
273 //if(step>=stepl*4.0/5.0 && (step>=stepl*(6.0/5.0) || Par_granf()<proby)){
274 if(step==stepl){
275 //Final momentum step
276 Momentum_Update(dpO,dSdpi,pp);
277 *itot+=step;
278
279 //Four force terms, so an extra factor of four in the average?
280 //Or leave it as it was, to get the average CG iterations per trajectory rather than force
281 *ancg/=step;
282 end_traj=true;
283 break;
284 }
285 else{
286 //Since we apply the momentum at the start and end of a step we instead apply a double step here
287 Momentum_Update(dpO2,dSdpi,pp);
288 step++;
289 }
290 }while(!end_traj);
291 return 0;
292}

References Force(), Gauge_Update(), Momentum_Update(), OMF4(), rank, and rescgg.

Here is the call graph for this function:
Here is the caller graph for this function: