su2hmc
Loading...
Searching...
No Matches
cubosonic.cu
Go to the documentation of this file.
1
7#include <su2hmc.h>
8#include <matrices.h>
9#include <thrust/reduce.h>
10//#include <thrust/execution_policy.h>
11
13namespace Device{
26 __device__ void cuSU2plaq(Complex_f *u11t, Complex_f *u12t, Complex_f *Sigma11, Complex_f *Sigma12, unsigned int *iu,\
27 const unsigned int i, const unsigned short mu, const unsigned short nu){
28 const unsigned int uidm = iu[i+kvol*mu];
29 unsigned int ind=i+kvol*mu;
30 //Need a second index in the nu direction for the first step
31 unsigned int indn=uidm+kvol*nu;
32 *Sigma11=u11t[ind]*u11t[indn]-u12t[ind]*conj(u12t[indn]);
33 *Sigma12=u11t[ind]*u12t[indn]+u12t[ind]*conj(u11t[indn]);
34
35 const int uidn = iu[i+kvol*nu];
36 ind=uidn+kvol*mu;
37 Complex_f a11=*Sigma11*conj(u11t[ind])+*Sigma12*conj(u12t[ind]);
38 Complex_f a12=-*Sigma11*u12t[ind]+*Sigma12*u11t[ind];
39
40 ind=i+kvol*nu;
41 *Sigma11=a11*conj(u11t[ind])+a12*conj(u12t[ind]);
42 *Sigma12=-a11*u12t[ind]+a12*u11t[ind];
43 return;
44 }
45}
46
47namespace Kernels{
48 using namespace Device;
59 __global__ void Average_Plaquette(float *hgs_d, float *hgt_d, Complex_f *u11t, Complex_f *u12t, unsigned int *iu){
60 const unsigned int gsize = gridDim.x*gridDim.y*gridDim.z;
61 const unsigned int bsize = blockDim.x*blockDim.y*blockDim.z;
62 const unsigned int blockId = blockIdx.x+ blockIdx.y * gridDim.x+ gridDim.x * gridDim.y * blockIdx.z;
63 const unsigned int threadId= blockId * bsize+(threadIdx.z * blockDim.y+ threadIdx.y)* blockDim.x+ threadIdx.x;
64 Complex_f Sigma11=0; Complex_f Sigma12=0;
65 //TODO: Check if μ and ν loops inside of site loop is faster. I suspect it is due to memory locality.
66 for(unsigned int i=threadId;i<kvol;i+=bsize*gsize){
67 float hg_c[2];
68 hg_c[0]=0; hg_c[1]=0;
69
70 for(unsigned short mu=1;mu<ndim;mu++)
71 for(unsigned short nu=0;nu<mu;nu++){
72 //This is threadsafe as the μ and ν loops are not distributed across threads
73 cuSU2plaq(u11t,u12t,&Sigma11,&Sigma12,iu,i,mu,nu);
74 switch(mu){
75 //Time component
76 case(ndim-1):
77 hg_c[0] -= creal(Sigma11);
78 break;
79 //Space component
80 default:
81 hg_c[1] -= creal(Sigma11);
82 break;
83 }
84 }
85 hgt_d[i]=hg_c[0]; hgs_d[i]=hg_c[1];
86 }
87 }
88
97 __global__ void Polyakov(Complex_f *Sigma11, Complex_f * Sigma12, Complex_f * u11t,Complex_f *u12t){
98 const unsigned int gsize = gridDim.x*gridDim.y*gridDim.z;
99 const unsigned int bsize = blockDim.x*blockDim.y*blockDim.z;
100 const unsigned int blockId = blockIdx.x+ blockIdx.y * gridDim.x+ gridDim.x * gridDim.y * blockIdx.z;
101 const unsigned int threadId= blockId * bsize+(threadIdx.z * blockDim.y+ threadIdx.y)* blockDim.x+ threadIdx.x;
102 for(unsigned int i=threadId;i<kvol3;i+=gsize*bsize){
103 Complex_f Sig[2]; Sig[0]=Sigma11[i]; Sig[1]=Sigma12[i];
104 Complex_f u[2];
105 for(unsigned int it=1;it<ksizet;it++){
106 const unsigned int indexu=it*kvol3+i;
107 u[0]=u11t[indexu+3*kvol];u[1]=u12t[indexu+3*kvol];
108 Complex_f a11=Sig[0]*u[0]-Sig[1]*conj(u[1]);
109 //Instead of having to store a second buffer just assign it directly
110 Sig[1]=Sig[0]*u[1]+Sig[1]*conj(u[0]);
111 Sig[0]=a11;
112 }
113 Sigma11[i]=Sig[0]; Sigma12[i]=Sig[1];
114 }
115 }
116}
117
118using namespace Kernels;
120__host__ void cuAverage_Plaquette(double *hgs, double *hgt, Complex_f *u11t, Complex_f *u12t, unsigned int *iu,dim3 dimGrid, dim3 dimBlock){
121 // float *hgs_d, *hgt_d;
122 int device=-1;
123 cudaGetDevice(&device);
124 float *hgs_d, *hgt_d;
125 //Thrust want things in a weird format for the reduction, thus we oblige
126 cudaMallocAsync((void **)&hgs_d,kvol*sizeof(float),NULL);
127 thrust::device_ptr<float> hgs_T = thrust::device_pointer_cast(hgs_d);
128 cudaMallocAsync((void **)&hgt_d,kvol*sizeof(float),NULL);
129 thrust::device_ptr<float> hgt_T = thrust::device_pointer_cast(hgt_d);
130
131 Kernels::Average_Plaquette<<<dimGrid,dimBlock,0,NULL>>>(hgs_d, hgt_d, u11t, u12t, iu);
133
134 *hgs= (double)thrust::reduce(hgs_T,hgs_T+kvol,(float)0);
135 *hgt= (double)thrust::reduce(hgt_T,hgt_T+kvol,(float)0);
137
138 cudaFreeAsync(hgs_d,streams[0]); cudaFreeAsync(hgt_d,streams[1]);
139}
140void cuPolyakov(Complex_f *Sigma[2], Complex_f *ut[2], dim3 dimGrid, dim3 dimBlock){
141 int device=-1;
142 cudaGetDevice(&device);
143 cudaMallocManaged((void **)&Sigma[0],kvol3*sizeof(Complex_f),cudaMemAttachGlobal);
144#ifdef _DEBUG
145 cudaMallocManaged((void **)&Sigma[1],kvol3*sizeof(Complex_f),cudaMemAttachGlobal);
146#else
147 cudaMallocAsync((void **)&Sigma[1],kvol3*sizeof(Complex_f),streams[0]);
148#endif
149 //Extract the time component from each site and save in corresponding Sigma
150 cublasCcopy(cublas_handle,kvol3, (cuComplex *)(ut[0])+3*kvolHalo, 1, (cuComplex *)Sigma[0], 1);
151 cublasCcopy(cublas_handle,kvol3, (cuComplex *)(ut[1])+3*kvolHalo, 1, (cuComplex *)Sigma[1], 1);
152
154 Kernels::Polyakov<<<dimGrid,dimBlock>>>(Sigma[0],Sigma[1],ut[0],ut[1]);
155 //cudaMemPrefetchAsync(Sigma[0],kvol3*sizeof(Complex_f),cudaCpuDeviceId,streams[0]);
156#ifdef _DEBUG
157 cudaFree(Sigma[1]);
158#else
159 cudaFreeAsync(Sigma[1],streams[1]);
160#endif
162}
__global__ void Polyakov(Complex_f *Sigma11, Complex_f *Sigma12, Complex_f *u11t, Complex_f *u12t)
Calculate the Polyakov loop (no prizes for guessing that one...).
Definition cubosonic.cu:97
void cuPolyakov(Complex_f *Sigma[2], Complex_f *ut[2], dim3 dimGrid, dim3 dimBlock)
Calculate the Polyakov loop (no prizes for guessing that one...).
Definition cubosonic.cu:140
__host__ void cuAverage_Plaquette(double *hgs, double *hgt, Complex_f *u11t, Complex_f *u12t, unsigned int *iu, dim3 dimGrid, dim3 dimBlock)
Calling wrappers.
Definition cubosonic.cu:120
__global__ void Average_Plaquette(float *hgs_d, float *hgt_d, Complex_f *u11t, Complex_f *u12t, unsigned int *iu)
Calculates the gauge action using new (how new?) lookup table Follows a routine called qedplaq in som...
Definition cubosonic.cu:59
__device__ void cuSU2plaq(Complex_f *u11t, Complex_f *u12t, Complex_f *Sigma11, Complex_f *Sigma12, unsigned int *iu, const unsigned int i, const unsigned short mu, const unsigned short nu)
Calculates the SU2 plaquette.
Definition cubosonic.cu:26
__device__ __forceinline__ T conj(const T &z)
Complex Conjugation.
Definition cusu2hmc.cu:33
Matrix multiplication and related declarations.
CUDA Device code.
Definition cubosonic.cu:13
CUDA Kernels.
Definition cubosonic.cu:47
#define ksizet
Sublattice t extent.
Definition sizes.h:158
#define kvol
Sublattice volume.
Definition sizes.h:163
#define cudaDeviceSynchronise()
Get rid of that bastardised yankee English.
Definition sizes.h:53
cublasHandle_t cublas_handle
Handle for cuBLAS.
Definition main.c:47
#define kvol3
Sublattice spatial volume.
Definition sizes.h:165
#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 kvolHalo
Subvolume + halo size.
Definition sizes.h:234
dim3 dimBlock
Default block size. Usually 128.
Definition cusu2hmc.cu:25
Function declarations for most of the routines.
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.