su2hmc
Loading...
Searching...
No Matches
su2hmc.c
Go to the documentation of this file.
1
6#include <assert.h>
7#include <clover.h>
8#include <matrices.h>
9
10int Init(const int istart, const int ibound, const int iread, const float beta, const float fmu, const float akappa,\
11 const Complex_f ajq, const float c_sw, Complex *u[2], Complex *ut[2], Complex_f *ut_f[2], Complex gamval[20],\
12 Complex_f gamval_f[20], unsigned short gamin[16], double *dk[2], float *dk_f[2],\
13 unsigned int *iu, unsigned int *id){
14 const char funcname[] = "Init";
15
16#ifdef _OPENMP
17 omp_set_num_threads(nthreads);
18#ifdef __USE_MKL__
19 mkl_set_num_threads(nthreads);
20#endif
21#endif
22 //First things first, calculate a few constants for coordinates
23 Addrc(iu, id);
24 //And confirm they're legit
27#ifdef _DEBUG
28 printf("Checked addresses\n");
29#endif
30 double chem1=exp(-fmu); double chem2 = 1/chem1;
31 //CUDA this. Only limit will be the bus speed
32#pragma omp parallel for simd //aligned(dk[0],dk[1]:AVX)
33 for(unsigned int i = 0; i<kvol; i++){
34 dk[0][i]=akappa*chem1; dk[1][i]=akappa*chem2;
35 }
36 //Anti periodic Boundary Conditions. Flip the terms at the edge of the time
37 //direction
38 if(ibound == -1 && pcoord[3+ndim*rank]==npt-1){
39#ifdef _DEBUG
40 printf("Implementing antiperiodic boundary conditions on rank %i\n", rank);
41#endif
42#pragma omp parallel for simd //aligned(dk[0],dk[1]:AVX)
43 for(unsigned int k= kvol-1; k>=kvol-kvol3; k--){
44 //int k = kvol - kvol3 + i;
45 dk[1][k]*=-1;
46 dk[0][k]*=-1;
47 }
48 }
49 //These are constant so swap the halos when initialising and be done with it
50 //May need to add a synchronisation statement here first
51#if(npt>1)
52 DHalo_swap_dir(dk[1], 1, 3, UP);
53 DHalo_swap_dir(dk[0], 1, 3, UP);
54#endif
55 //Float versions
56#ifdef USE_GPU
57 cuReal_convert(dk_f[1],dk[1],kvol+halo,true,dimBlock,dimGrid);
58 cuReal_convert(dk_f[0],dk[0],kvol+halo,true,dimBlock,dimGrid);
59#else
60#pragma omp parallel for simd //aligned(dk[0],dk[1],dk_f[0],dk_f[1]:AVX)
61 for(unsigned int i=0;i<kvol+halo;i++){
62 dk_f[1][i]=(float)dk[1][i];
63 dk_f[0][i]=(float)dk[0][i];
64 }
65#endif
66 //What row of each dirac/sigma matrix contains the entry acting on element i of the spinor
67 unsigned short __attribute__((aligned(AVX))) gamin_t[4][4] = {{3,2,1,0},{3,2,1,0},{2,3,0,1},{2,3,0,1}};
68 //Gamma Matrices in Chiral Representation
69 //See Appendix 8.1.2 of Montvay and Munster
70 //_t is for temp. We copy these into the real gamvals later
71#ifdef USE_GPU
72 cudaMemcpy(gamin,gamin_t,4*4*sizeof(short),cudaMemcpyHostToDevice);
73#else
74 memcpy(gamin,gamin_t,4*4*sizeof(short));
75#endif
76 //Each row of the dirac matrix contains only one non-zero entry, so that's all we encode here
77 Complex __attribute__((aligned(AVX))) gamval_t[5][4] = {{-I,-I,I,I},{-1,1,1,-1},{-I,I,I,-I},{1,1,1,1},{1,1,-1,-1}};
78 //Each gamma matrix is rescaled by akappa by flattening the gamval array
79#if defined USE_BLAS
80 //Don't cuBLAS this. It is small and won't saturate the GPU. Let the CPU handle
81 //it and just copy it later
82 cblas_zdscal(5*4, akappa, gamval_t, 1);
83#else
84#pragma omp parallel for simd collapse(2) aligned(gamval,gamval_f:AVX)
85 for(unsigned short i=0;i<5;i++)
86 for(unsigned short j=0;j<4;j++)
87 gamval_t[i][j]*=akappa;
88#endif
89
90
91#ifdef USE_GPU
92 cudaMemcpy(gamval,gamval_t,5*4*sizeof(Complex),cudaMemcpyHostToDevice);
93 cuComplex_convert(gamval_f,gamval,20,true,dimBlockOne,dimGridOne);
94#else
95 memcpy(gamval,gamval_t,5*4*sizeof(Complex));
96 for(unsigned short i=0;i<5*4;i++)
97 gamval_f[i]=(Complex_f)gamval[i];
98#endif
99
100 if(iread){
101 if(!rank) printf("Calling Par_sread() for configuration: %i\n", iread);
102 Par_sread(iread, beta, fmu, akappa, ajq,c_sw,u[0],u[1],ut[0],ut[1]);
103 Par_ranset(&seed,iread);
104 }
105 else{
106 Par_ranset(&seed,iread);
107 if(istart==0){
108 //Initialise a cold start to zero
109 //memset is safe to use here because zero is zero
110#pragma omp parallel for simd //aligned(ut[0]:AVX)
111 //Leave it to the GPU?
112 for(unsigned int i=0; i<kvol;i++)
113 for(unsigned short mu=0;mu<ndim;mu++){
114 ut[0][i+kvolHalo*mu]=1+0*I; ut[1][i+kvolHalo*mu]=0+0*I;
115 }
116 }
117 else if(istart>0){
118 //Ideally, we can use gsl_ranlux as the PRNG
119#ifdef __RANLUX__
120 for(unsigned int i=0; i<kvol;i++)
121 for(unsigned short mu=0;mu<ndim;mu++){
122 ut[0][i+kvolHalo*mu]=2*(gsl_rng_uniform(ranlux_instd)-0.5+I*(gsl_rng_uniform(ranlux_instd)-0.5));
123 ut[1][i+kvolHalo*mu]=2*(gsl_rng_uniform(ranlux_instd)-0.5+I*(gsl_rng_uniform(ranlux_instd)-0.5));
124 }
125 //Last resort, Numerical Recipes' Ran2
126#else
127 for(unsigned int i=0; i<kvol;i++)
128 for(unsigned short mu=0;mu<ndim;mu++){
129 ut[0][i+kvolHalo*mu]=2*(ran2(&seed)-0.5+I*(ran2(&seed)-0.5));
130 ut[1][i+kvolHalo*mu]=2*(ran2(&seed)-0.5+I*(ran2(&seed)-0.5));
131 }
132#endif
133 }
134 else
135 fprintf(stderr,"Warning %i in %s: Gauge fields are not initialised.\n", NOINIT, funcname);
136
137#ifdef USE_GPU
138 int device=-1;
139 cudaGetDevice(&device);
140 //cudaMemPrefetchAsync(ut[0], ndim*kvol*sizeof(Complex),device,streams[0]);
141 //cudaMemPrefetchAsync(ut[1], ndim*kvol*sizeof(Complex),device,streams[1]);
142#endif
143 //Send trials to accelerator for reunitarisation
144 Reunitarise(ut);
145 //Get trials back
146#ifdef USE_GPU
147#if (nproc>1) //Strided for multi-GPU
148 for(unsigned short mu=0;mu<ndim;mu++){
149 cudaMemcpy(u[0]+kvol*mu, ut[0]+kvolHalo*mu, kvol*sizeof(Complex),cudaMemcpyDefault);
150 cudaMemcpy(u[1]+kvol*mu, ut[1]+kvolHalo*mu, kvol*sizeof(Complex),cudaMemcpyDefault);
151 }
152#else
153 cudaMemcpy(u[0], ut[0], ndim*kvol*sizeof(Complex),cudaMemcpyDefault);
154 cudaMemcpy(u[1], ut[1], ndim*kvol*sizeof(Complex),cudaMemcpyDefault);
155#endif
156#else
157 for(unsigned short mu=0;mu<ndim;mu++){
158 memcpy(u[0]+kvol*mu, ut[0]+kvolHalo*mu, kvol*sizeof(Complex));
159 memcpy(u[1]+kvol*mu, ut[1]+kvolHalo*mu, kvol*sizeof(Complex));
160 }
161#endif
162 }
163#ifdef _DEBUG
164 printf("Initialisation Complete\n");
165#endif
166 return 0;
167}
168int Hamilton(double *h,double *s,double res2,double *pp,Complex *X0,Complex *X1,Complex *Phi, Complex *ud[2],Complex_f *ut[2],
169 unsigned int *iu,unsigned int *id, Complex gamval[20], Complex_f gamval_f[20],const unsigned short gamin[16], Complex *sigval, Complex_f *sigval_f,
170 unsigned short *sigin, double *dk[2],float *dk_f[2],Complex_f jqq,float akappa,float beta,float c_sw, double *ancgh,
171 int traj){
172 const char funcname[] = "Hamilton";
173 //Iterate over momentum terms.
174#ifdef USE_GPU
175 double hp;
176 int device=-1;
177 cudaGetDevice(&device);
178 //cudaMemPrefetchAsync(pp,kmom*sizeof(double),device,NULL);
179 cublasDnrm2(cublas_handle, kmom, pp, 1,&hp);
180 hp*=hp;
181#elif defined USE_BLAS
182 double hp = cblas_dnrm2(kmom, pp, 1);
183 hp*=hp;
184#else
185 double hp=0;
186 for(unsigned int i = 0; i<kmom; i++)
187 hp+=pp[i]*pp[i];
188#endif
189 hp*=0.5;
190 double avplaqs, avplaqt;
191 double hg = 0;
192 //avplaq? isn't seen again here.
193 Average_Plaquette(&hg,&avplaqs,&avplaqt,ut,iu,beta);
194
195 alignas(8) double hf = 0; int itercg = 0;
196#ifdef USE_GPU
197 Complex *smallPhi;
198#ifdef _DEBUG
199 cudaMallocManaged((void **)&smallPhi,kferm2*sizeof(Complex),cudaMemAttachGlobal);
200#else
201 cudaMallocAsync((void **)&smallPhi,kferm2*sizeof(Complex),NULL);
202#endif
203#else
204 Complex *smallPhi = aligned_alloc(AVX,kferm2*sizeof(Complex));
205#endif
206 Complex_f *clover[nc];
207 if(c_sw)
208 Clover(clover,ut,iu,id);
209 //Iterating over flavours
210 for(unsigned short na=0;na<nf;na++){
211#ifdef USE_GPU
212#if (nproc>1) //strided for multi-GPU
213 for(unsigned short j=0;j<nc*ndirac;j++)
214 cudaMemcpyAsync(X1+j*kvolHalo,X0+na*kferm2+j*kvol,kvol*sizeof(Complex),cudaMemcpyDeviceToDevice,streams[j]);
215#else
216 cudaMemcpyAsync(X1,X0+na*kferm2,kferm2*sizeof(Complex),cudaMemcpyDeviceToDevice,streams[0]);
217#endif
218#else
219 for(unsigned short j=0;j<nc*ndirac;j++)
220 memcpy(X1+j*kvolHalo,X0+na*kferm2+j*kvol,kvol*sizeof(Complex));
221#endif
222 Fill_Small_Phi(na, smallPhi, Phi);
223 if(Congradq(na,res2,X1,smallPhi,ud,ut,clover,iu,id,gamval,gamval_f,gamin,sigval,sigval_f,sigin,dk,dk_f,\
224 jqq,akappa,c_sw,&itercg))
225 fprintf(stderr,"Trajectory %d\n", traj);
226
227 *ancgh+=itercg;
228#ifdef USE_GPU
229#if (nproc>1) //strided for multi-GPU
230 for(unsigned short j=0;j<nc*ndirac;j++)
231 cudaMemcpyAsync(X0+na*kferm2+j*kvol,X1+j*kvolHalo,kvol*sizeof(Complex),cudaMemcpyDeviceToDevice,streams[j]);
232#else
233 cudaMemcpyAsync(X0+na*kferm2,X1,kferm2*sizeof(Complex),cudaMemcpyDeviceToDevice,streams[0]);
234#endif
235#else
236 for(unsigned short j=0;j<nc*ndirac;j++)
237 memcpy(X0+na*kferm2+j*kvol,X1+j*kvolHalo,kvol*sizeof(Complex));
238#endif
239 Fill_Small_Phi(na, smallPhi,Phi);
240#ifdef USE_GPU
241 alignas(16) Complex dot=0;
242#if (nproc>1)
243 for(unsigned short j=0;j<nc*ndirac;j++){
244 alignas(16) Complex buff;
245 cublasZdotc(cublas_handle,kvol,(cuDoubleComplex *)smallPhi+j*kvol,1,(cuDoubleComplex *) X1+j*kvolHalo,1,(cuDoubleComplex *) &buff);
246 dot+=buff;
247 }
248#else
249 cublasZdotc(cublas_handle,kferm2,(cuDoubleComplex *)smallPhi,1,(cuDoubleComplex *) X1,1,(cuDoubleComplex *) &dot);
250#endif
251 hf+=creal(dot);
252#elif defined USE_BLAS
253 Complex dot=0;
254 for(unsigned short j=0;j<nc*ndirac;j++){
255 alignas(16) Complex buff=0;
256 cblas_zdotc_sub(kvol, smallPhi+j*kvol, 1, X1+j*kvolHalo, 1, &buff);
257 dot+=buff;
258 }
259 hf+=creal(dot);
260#else
261 //It is a dot product of the flattened arrays, could use
262 //a module to convert index to coordinate array...
263#pragma omp parallel for simd collapse(2) aligned(smallPhi,X1:AVX)
264 for(unsigned short j=0;j<nc*ndirac;j++)
265 for(unsigned int i=0;i<kvol;i++)
266 hf+=creal(conj(smallPhi[i+j*kvol])*X1[i+j*kvolHalo]);
267#endif
268 }
269 if(c_sw)
270 Clover_free(clover);
271#ifdef USE_GPU
272#ifdef _DEBUG
273 cudaFree(smallPhi);
274#else
275 cudaFreeAsync(smallPhi,NULL);
276#endif
277#else
278 free(smallPhi);
279#endif
280 //hg was summed over inside of Average_Plaquette.
281#if(nproc>1)
282 Par_dsum(&hp); Par_dsum(&hf);
283#endif
284 *s=hg+hf; *h=(*s)+hp;
285#ifdef _DEBUG
286 if(!rank)
287 printf("hg=%.5e; hf=%.5e; hp=%.5e; h=%.5e\n", hg, hf, hp, *h);
288#endif
289 return 0;
290}
291inline int C_gather(Complex_f *x, Complex_f *y, int n, unsigned int *table, unsigned int mu)
292{
293 const char funcname[] = "C_gather";
294 //FORTRAN had a second parameter m giving the size of y (kvol+halo) normally
295 //Pointers mean that's not an issue for us so I'm leaving it out
296#pragma omp parallel for simd aligned (x,y,table:AVX)
297 for(unsigned int i=0; i<n; i++)
298 x[i]=y[table[i+kvol*mu]+kvolHalo*mu];
299 return 0;
300}
301inline int Z_gather(Complex *x, Complex *y, int n, unsigned int *table, unsigned int mu)
302{
303 const char funcname[] = "Z_gather";
304 //FORTRAN had a second parameter m giving the size of y (kvol+halo) normally
305 //Pointers mean that's not an issue for us so I'm leaving it out
306#pragma omp parallel for simd aligned (x,y,table:AVX)
307 for(unsigned int i=0; i<n; i++)
308 x[i]=y[table[i+kvol*mu]+kvolHalo*mu];
309 return 0;
310}
311inline int Fill_Small_Phi(int na, Complex *smallPhi, Complex *Phi)
312{
313 const char funcname[] = "Fill_Small_Phi";
314 //BIG and small phi index
315#ifdef USE_GPU
316 cuFill_Small_Phi(na,smallPhi,Phi,dimBlock,dimGrid);
317#else
318#pragma omp parallel for simd aligned(smallPhi,Phi:AVX) collapse(3)
319 for(unsigned int i = 0; i<kvol;i++)
320 for(unsigned short idirac = 0; idirac<ndirac; idirac++)
321 for(unsigned short ic= 0; ic<nc; ic++)
322 // PHI_index=i*16+j*2+k;
323 smallPhi[i+kvol*(ic+nc*idirac)]=Phi[i+kvol*(ic+nc*(idirac+ngorkov*na))];
324#endif
325 return 0;
326}
327inline int UpDownPart(const unsigned int na, Complex *X0, Complex *R1){
328#ifdef USE_GPU
329 cuUpDownPart(na,X0,R1,dimBlock,dimGrid);
331#else
332#pragma omp parallel for simd collapse(2) aligned(X0,R1:AVX)
333 for(unsigned int i=0; i<kvol; i++)
334 for(unsigned short idirac=0;idirac<ndirac;idirac++){
335 //R1 has ngorkov spinors, but we only want the first four.
336 X0[i+kvol*(0+nc*(idirac+ndirac*na))]=R1[i+kvol*(0+nc*idirac)];
337 X0[i+kvol*(1+nc*(idirac+ndirac*na))]=R1[i+kvol*(1+nc*idirac)];
338 }
339#endif
340 return 0;
341}
342inline int Reunitarise(Complex *ut[2]){
343 const char funcname[] = "Reunitarise";
344#ifdef USE_GPU
346#else
347#pragma omp parallel for simd
348 for(unsigned short mu=0;mu<ndim;mu++)
349 for(unsigned int i=0; i<kvol; i++){
350 //Declaring anorm inside the loop will hopefully let the compiler know it
351 //is safe to vectorise aggressively
352 double anorm=sqrt(conj(ut[0][i+kvolHalo*mu])*ut[0][i+kvolHalo*mu]+conj(ut[1][i+kvolHalo*mu])*ut[1][i+kvolHalo*mu]);
353 ut[0][i+kvolHalo*mu]/=anorm; ut[1][i+kvolHalo*mu]/=anorm;
354 }
355#endif
356 return 0;
357}
Routines needed for Clover improved wilson fermions.
#define NOINIT
Not initialising the lattice.
Definition errorcodes.h:144
int Average_Plaquette(double *hg, double *avplaqs, double *avplaqt, Complex_f *ut[2], unsigned int *iu, float beta)
Calculates the gauge action using new (how new?) lookup table Follows a routine called qedplaq in som...
Definition bosonic.c:14
void Clover_free(Complex_f *clover[nc])
Free's memory used for clover terms and leaves.
Definition clover.c:750
void Clover(Complex_f *clover[2], Complex_f *ut[2], unsigned int *iu, unsigned int *id)
Calculates the clovers in all directions at all sites.
Definition clover.c:203
int Z_gather(Complex *x, Complex *y, int n, unsigned int *table, unsigned int mu)
Extracts all the double precision gauge links in the direction only.
Definition su2hmc.c:301
void cuReunitarise(Complex *ut[2], dim3 dimGrid, dim3 dimBlock)
Reunitarises u11t and u12t as in conj(u11t[i])*u11t[i]+conj(u12t[i])*u12t[i]=1.
Definition cusu2hmc.cu:294
void cuUpDownPart(const unsigned int na, Complex *X0, Complex *R1, dim3 dimBlock, dim3 dimGrid)
Up/Down partitioning of the pseudofermion field.
Definition cusu2hmc.cu:291
int Init(const int istart, const int ibound, const int iread, const float beta, const float fmu, const float akappa, const Complex_f ajq, const float c_sw, Complex *u[2], Complex *ut[2], Complex_f *ut_f[2], Complex gamval[20], Complex_f gamval_f[20], unsigned short gamin[16], double *dk[2], float *dk_f[2], unsigned int *iu, unsigned int *id)
Initialises the system.
Definition su2hmc.c:10
__device__ __forceinline__ T conj(const T &z)
Complex Conjugation.
Definition cusu2hmc.cu:33
int UpDownPart(const unsigned int na, Complex *X0, Complex *R1)
Up/Down partitioning of the pseudofermion field.
Definition su2hmc.c:327
void cuReal_convert(float *a, double *b, const unsigned int len, const bool dtof, dim3 dimBlock, dim3 dimGrid)
takes an array of real-valued float and double precision numbers and converts the precision
Definition cusu2hmc.cu:280
int Reunitarise(Complex *ut[2])
Reunitarises u11t and u12t as in conj(u11t[i])*u11t[i]+conj(u12t[i])*u12t[i]=1.
Definition su2hmc.c:342
void cuComplex_convert(Complex_f *a, Complex *b, const unsigned int len, const bool dtof, dim3 dimBlock, dim3 dimGrid)
takes an array of complex float and double precision numbers and converts the precision
Definition cusu2hmc.cu:284
int Fill_Small_Phi(int na, Complex *smallPhi, Complex *Phi)
Copies necessary (2*4*kvol) elements of Phi into a vector variable.
Definition su2hmc.c:311
void cuFill_Small_Phi(const unsigned int na, Complex *smallPhi, Complex *Phi, dim3 dimBlock, dim3 dimGrid)
Copies necessary (2*4*kvol) elements of Phi into a vector variable.
Definition cusu2hmc.cu:288
int C_gather(Complex_f *x, Complex_f *y, int n, unsigned int *table, unsigned int mu)
Extracts all the single precision gauge links in the direction only.
Definition su2hmc.c:291
int Check_addr(unsigned int *table, int lns, int lnt, int imin, int imax)
Checks that the addresses are within bounds before an update.
Definition coord.c:305
int Addrc(unsigned int *iu, unsigned int *id)
Loads the addresses required during the update.
Definition coord.c:13
int Congradq(int na, double res, Complex *X1, Complex *r, Complex *ud[2], Complex_f *ut[2], Complex_f *clover_f[nc], unsigned int *iu, unsigned int *id, Complex gamval[20], Complex_f gamval_f[20], const unsigned short gamin[16], Complex *sigval, Complex_f *sigval_f, unsigned short *sigin, double *dk[2], float *dk_f[2], Complex_f jqq, float akappa, float c_sw, int *itercg)
Matrix Inversion via Conjugate Gradient (up/down flavour partitioning). Solves Implements up/down pa...
Definition congrad.c:278
int Par_sread(const int iread, const float beta, const float fmu, const float akappa, const Complex_f ajq, const float c_sw, Complex *u11, Complex *u12, Complex *u11t, Complex *u12t)
Reads and assigns the gauges from file.
Definition par_mpi.c:114
int DHalo_swap_dir(double *d, int ncpt, int idir, int layer)
Swaps the halos along the axis given by idir in the direction given by layer.
int Par_dsum(double *dval)
Performs a reduction on a double dval to get a sum which is then distributed to all ranks.
int Hamilton(double *h, double *s, double res2, double *pp, Complex *X0, Complex *X1, Complex *Phi, Complex *ud[2], Complex_f *ut[2], unsigned int *iu, unsigned int *id, Complex gamval[20], Complex_f gamval_f[20], const unsigned short gamin[16], Complex *sigval, Complex_f *sigval_f, unsigned short *sigin, double *dk[2], float *dk_f[2], Complex_f jqq, float akappa, float beta, float c_sw, double *ancgh, int traj)
Calculate the Hamiltonian.
Definition su2hmc.c:168
int Par_ranset(unsigned long *seed, int iread)
Uses the rank to get a new seed. Copying from the FORTRAN description here c create new seeds in rang...
Definition random.c:64
Matrix multiplication and related declarations.
#define UP
Flag for send up.
Definition par_mpi.h:39
int rank
The MPI rank.
Definition par_mpi.c:20
int * pcoord
The processor grid.
Definition par_mpi.c:17
unsigned long seed
RANLUX seed.
Definition random.c:18
gsl_rng * ranlux_instd
RANLUX instance.
Definition random.c:16
#define AVX
Alignment of arrays. 64 for AVX-512, 32 for AVX/AVX2. 16 for SSE. Since AVX is standard on modern x86...
Definition sizes.h:279
#define nc
Colours.
Definition sizes.h:182
#define kmom
sublattice momentum sites
Definition sizes.h:193
#define ngorkov
Gor'kov indices.
Definition sizes.h:190
#define ksizet
Sublattice t extent.
Definition sizes.h:158
#define kvol
Sublattice volume.
Definition sizes.h:163
#define Complex
Double precision complex number.
Definition sizes.h:64
#define nthreads
Number of threads for OpenMP, which can be overwritten at runtime.
Definition sizes.h:144
#define ksize
Sublattice spatial extent for a cubic lattice.
Definition sizes.h:155
#define nf
Fermion flavours (double it).
Definition sizes.h:160
#define ndirac
Dirac indices.
Definition sizes.h:186
#define cudaDeviceSynchronise()
Get rid of that bastardised yankee English.
Definition sizes.h:53
dim3 dimBlockOne
block size of one
Definition cusu2hmc.cu:22
dim3 dimGridOne
Grid size of one.
Definition cusu2hmc.cu:23
cublasHandle_t cublas_handle
Handle for cuBLAS.
Definition main.c:47
#define kvol3
Sublattice spatial volume.
Definition sizes.h:165
#define halo
Total Halo size.
Definition sizes.h:231
#define Complex_f
Single precision complex number.
Definition sizes.h:62
dim3 dimGrid
Default grid size. First component is normally nt. Second and third depend whatever is needed to get ...
Definition cusu2hmc.cu:27
#define ndim
Dimensions.
Definition sizes.h:188
#define kferm2
sublattice size including Dirac indices
Definition sizes.h:197
#define npt
Processor grid t extent.
Definition sizes.h:130
#define kvolHalo
Subvolume + halo size.
Definition sizes.h:234
dim3 dimBlock
Default block size. Usually 128.
Definition cusu2hmc.cu:25
cudaStream_t streams[ndirac *ndim *nadj]
An array of concurrent GPU streams to keep it busy.
Definition cusu2hmc.cu:29
#define creal(z)
Extract Real Component using C standard notation.
#define I
Define I in double precision using C standard notation.