10 Complex *sigval,
Complex_f *sigval_f,
unsigned short *sigin,
double *dk[2],
float *dk_f[2],\
12 const char funcname[] =
"Measure";
17 cudaGetDevice(&device);
20 cudaMallocManaged((
void **)&R1,
kferm*
sizeof(
Complex), cudaMemAttachGlobal);
21 cudaMallocManaged((
void **)&R1_f,
kferm*
sizeof(
Complex_f), cudaMemAttachGlobal);
26 cudaMallocManaged((
void **)&x,
kfermHalo*
sizeof(
Complex), cudaMemAttachGlobal);
27 cudaMallocManaged((
void **)&xi,
kferm*
sizeof(
Complex), cudaMemAttachGlobal);
48 cudaMemcpyAsync(x, xi,
kferm*
sizeof(
Complex),cudaMemcpyDefault,0);
51#pragma omp parallel for
58 Dslashd_f(R1_f,xi_f,ut_f,iu,
id,gamval_f,gamin,dk_f,jqq,akappa);
61 ByClover_f(R1_f,xi_f,clover,sigval_f,akappa,sigin,
true);
75 free(xi_f); free(R1_f);
79 if(
Congradp(0, res, Phi,R1,ut,ut_f,clover,iu,
id,gamval,gamval_f,gamin,sigval,sigval_f,sigin,dk,dk_f,jqq,akappa,c_sw,itercg)==
ITERLIM){
84 cudaFree(clover[0]); cudaFree(clover[1]);
89 cudaFreeAsync(clover[0],
streams[1]); cudaFreeAsync(clover[1],
streams[2]);
93 cudaFree(x); cudaFree(xi);
96 free(clover[0]); free(clover[1]);
98 free(x); free(xi); free(R1);
106 cudaFree(clover[0]); cudaFree(clover[1]);
111 cudaFreeAsync(clover[0],
streams[1]); cudaFreeAsync(clover[1],
streams[2]);
120 free(clover[0]); free(clover[1]);
129 for(
unsigned short j=0;j<
ngorkov*
nc;j++){
135 cublasZdotc(
cublas_handle,
kferm,(cuDoubleComplex *)x,1,(cuDoubleComplex *)xi,1,(cuDoubleComplex *)&buff);
139#elif defined USE_BLAS
140 for(
unsigned short j=0;j<
ngorkov*
nc;j++){
148 for(
int i=0;i<
kferm;i++)
158 for(
int idirac = 0; idirac<
ndirac; idirac++){
162 for(
int ic = 0; ic<
nc; ic++){
172 *qbqb+=gamval[4*
ndirac+idirac]*dot;
178 *qq-=gamval[4*
ndirac+idirac]*dot;
183#pragma omp parallel for simd collapse(2) aligned(x,xi:AVX) reduction(+:*qq,*qbqb)
184 for(
int idirac = 0; idirac<
ndirac; idirac++)
185 for(
int i=0; i<
kvol; i++){
198 *qq=(*qq+*qbqb)/(2*
gvol);
215 for(
unsigned short igorkov=0; igorkov<4; igorkov++){
216 const unsigned short igork1=gamin[3*
ndirac+igorkov];
218#pragma omp parallel for simd aligned(dk,x,xi:AVX) reduction(+:xu)
219 for(
unsigned int i = 0; i<
kvol; i++){
220 unsigned int did=
id[3*
kvol+i];
225 conj(ut[0][did+
kvol*3])*(xi[i+
kvol*(igork1)*
nc+1]-xi[i+
kvol*(igorkov)*
nc+1])+\
229 for(
unsigned short igorkov=0; igorkov<4; igorkov++){
230 const unsigned short igork1=gamin[3*
ndirac+igorkov];
231#pragma omp parallel for simd aligned(dk,x,xi:AVX) reduction(+:xd)
232 for(
unsigned int i = 0; i<
kvol; i++){
233 unsigned int uid=iu[3*
kvol+i];
242 for(
unsigned short igorkovPP=4; igorkovPP<8; igorkovPP++){
243 const unsigned short igork1PP=4+gamin[3*
ndirac+igorkovPP-4];
244#pragma omp parallel for simd aligned(dk,x,xi:AVX) reduction(+:xuu)
245 for(
unsigned int i = 0; i<
kvol; i++){
246 unsigned int did=
id[3*
kvol+i];
249 ut[1][did+
kvol*3]*(xi[i+
kvol*(igork1PP*
nc+1)]-xi[i+
kvol*(igorkovPP*
nc+1)]) )+\
251 conj(ut[0][did+
kvol*3])*(xi[i+
kvol*(igork1PP)*
nc+1]-xi[i+
kvol*(igorkovPP)*
nc+1])+\
255 for(
unsigned short igorkovPP=4; igorkovPP<8; igorkovPP++){
256 const unsigned short igork1PP=4+gamin[3*
ndirac+igorkovPP-4];
257#pragma omp parallel for simd aligned(dk,x,xi:AVX) reduction(+:xdd)
258 for(
unsigned int i = 0; i<
kvol; i++){
259 unsigned int uid=iu[3*
kvol+i];
261 conj(ut[0][i+
kvol*3])*(xi[i+
kvol*(igork1PP*
nc)]+xi[i+
kvol*(igorkovPP*
nc)])-\
262 ut[1][i+
kvol*3]*(xi[i+
kvol*(igork1PP*
nc+1)]+xi[i+
kvol*(igorkovPP*
nc+1)]) )+\
265 conj(ut[1][i+
kvol*3])*(xi[i+
kvol*(igorkovPP*
nc)]+xi[i+
kvol*(igork1PP*
nc)]) ) );
268 *endenf=
creal(xu-xd-xuu+xdd);
269 *denf=
creal(xu+xd+xuu+xdd);
277 cudaFree(x); cudaFree(xi);
Routines needed for Clover improved wilson fermions.
#define ITERLIM
Exceeded max number of iterations.
void ByClover_f(Complex_f *phi, Complex_f *r, Complex_f *clover[2], Complex_f *sigval, const float akappa, unsigned short *sigin, bool dag)
Clover analogue of the Dslash operation. This version acts on all flavours similar to Dslash and Dsla...
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.
int Dslashd_f(Complex_f *phi, Complex_f *r, Complex_f *ut[nc], unsigned int *iu, unsigned int *id, Complex_f gamval[20], const unsigned short gamin[16], float *dk[nc], Complex_f jqq, float akappa)
Evaluates in single precision.
int Measure(double *pbp, double *endenf, double *denf, Complex *qq, Complex *qbqb, double res, int *itercg, Complex *ut[2], Complex_f *ut_f[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 c_sw, Complex *Phi)
Calculate fermion expectation values via a noisy estimator.
int ComplexConvert(Complex_f *a, Complex *b, const unsigned int len, const bool dtof, const unsigned short stride)
takes an array of complex float and double precision numbers and converts the precision
__device__ __forceinline__ T conj(const T &z)
Complex Conjugation.
int Congradp(int na, double res, Complex *Phi, Complex *xi, 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 (no up/down flavour partitioning). Solves The matrix multipl...
int ZHalo_swap_dir(Complex *z, 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 Gauss_c(Complex_f *ps, unsigned int n, const Complex_f mu, const float sigma)
Generates a vector of normally distributed random single precision complex numbers using the Box-Mull...
Matrix multiplication and related declarations.
#define UP
Flag for send up.
#define DOWN
Flag for send down.
#define AVX
Alignment of arrays. 64 for AVX-512, 32 for AVX/AVX2. 16 for SSE. Since AVX is standard on modern x86...
#define ngorkov
Gor'kov indices.
#define kvol
Sublattice volume.
#define Complex
Double precision complex number.
#define kferm
sublattice size including Gor'kov indices
#define ndirac
Dirac indices.
#define cudaDeviceSynchronise()
Get rid of that bastardised yankee English.
#define gvol
Lattice volume.
cublasHandle_t cublas_handle
Handle for cuBLAS.
#define Complex_f
Single precision complex number.
#define kvolHalo
Subvolume + halo size.
#define kfermHalo
Gor'kov lattice and halo.
cudaStream_t streams[ndirac *ndim *nadj]
An array of concurrent GPU streams to keep it busy.
#define creal(z)
Extract Real Component using C standard notation.