For the early phases of this translation, I'm going to try and copy the original format as much as possible and keep things in one file. Hopefully this will change as we move through the methods so we can get a more logical structure.
Another vestige of the Fortran code that will be implemented here is the frequent flattening of arrays. But while FORTRAN Allows you to write array(i,j) as array(i+M*j) where M is the number of rows, C resorts to pointers
One change I will try and make is the introduction of error-codes (nothing to do with the Irish postal service) These can be found in the file errorcode.h and can help with debugging
Lastly, the comment style for the start of a function is based off of doxygen. It should consist of a description of the function, a list of parameters with a brief explanation and lastly what is returned by the function (on success or failure).
The input file format is like the table below, with values sepearated by whitespace
The default values here are straight from the FORTRAN. Note that the bottom line labelling each input is ignored
Changing the value of istart in the input parameter file gives us the following start options. These are quoted from the FORTRAN comments
istart < 0: Start from tape in FORTRAN?!? How old was this code? (depreciated, replaced with iread)
istart = 0: Ordered/Cold Start For some reason this leaves the trial fields as zero in the FORTRAN code?
71 {
72
73 const char funcname[] = "main";
74
76
77#if(nproc>1)
78 MPI_Comm_rank(comm, &
rank);
79 MPI_Comm_size(comm, &
size);
80#endif
81
105 float beta = 1.7f;
106 float akappa = 0.1780f;
107#ifdef USE_GPU
108 __managed__
109#endif
111 float fmu = 0.0f; int iread = 0; int istart = 1;
112 int iprint = 1;
113 int icheck = 5;
114 int ibound = -1;
115
116 float dt=0.004; float c_sw = 0.0; float delb=0;
117 float ajq = 0.0; int stepl = 250; int ntraj = 10;
118
120 FILE *midout;
121 const char *filename = (argc!=2) ?"midout":argv[1];
122 char *fileop = "r";
123 if( !(midout = fopen(filename, fileop) ) ){
124 fprintf(stderr, "Error %i in %s: Failed to open file %s for %s.\nExiting\n\n",\
126#if(nproc>1)
128#else
130#endif
131 }
132
133 fscanf(midout, "%f %f %f %f %f %f %f %d %d %d %d %d", &dt, &beta, &akappa,\
134 &ajq, &c_sw, &fmu, &delb, &stepl, &ntraj, &istart, &icheck, &iread);
135 fclose(midout);
136 assert(stepl>0); assert(ntraj>0); assert(istart>=0); assert(icheck>0); assert(iread>=0);
137 }
138
139#if(nproc>1)
140 if(c_sw!=0){
141 fprintf(stderr,"Error %i in %s: Multiple MPI Ranks are not currently supported for the clover action.\n"\
142 "This is due to the corner halo terms needed to compute the clover force not being implemented.\n"\
143 "Please recompile for a single MPI rank or run with c_sw=0.\n"\
144 "\nExiting...\n\n",
NOIMPL,funcname);
147 }
152#endif
153
154
155 jqq=ajq;
156
157#ifdef USE_GPU
158
160
162
163 int device=-1;
164 cudaGetDevice(&device);
165
166
167
168
169
170 cudaDeviceGetDefaultMemPool(&
mempool, device);
172 cudaMemPoolSetAttribute(
mempool, cudaMemPoolAttrReleaseThreshold, &threshold);
173#endif
174#ifdef _DEBUG
175 printf(
"jqq=%f+(%f)I\n",
creal(jqq),
cimag(jqq));
176#endif
177#ifdef _DEBUG
179#else
181#endif
182
183
184
185
186
187
188
189
190
191
192
193
194
197 double *dk[2], *pp;
198 float *dk_f[2];
199
200 unsigned int *iu, *id;
201
203#ifdef USE_GPU
204
205 cudaMallocManaged((
void**)&iu,
ndim*
kvol*
sizeof(
int),cudaMemAttachGlobal);
206 cudaMallocManaged((
void**)&
id,
ndim*
kvol*
sizeof(
int),cudaMemAttachGlobal);
207
208 cudaMallocManaged((
void **)&dk[0],(
kvolHalo)*
sizeof(
double),cudaMemAttachGlobal);
209 cudaMallocManaged((
void **)&dk[1],(
kvolHalo)*
sizeof(
double),cudaMemAttachGlobal);
210#ifdef _DEBUG
211 cudaMallocManaged((
void **)&dk_f[0],(
kvolHalo)*
sizeof(
float),cudaMemAttachGlobal);
212 cudaMallocManaged((
void **)&dk_f[1],(
kvolHalo)*
sizeof(
float),cudaMemAttachGlobal);
213#else
214 cudaMalloc((
void **)&dk_f[0],(
kvolHalo)*
sizeof(
float));
215 cudaMalloc((
void **)&dk_f[1],(
kvolHalo)*
sizeof(
float));
216#endif
217
219 cudaMallocManaged((
void **)&gamval_f,5*4*
sizeof(
Complex_f),cudaMemAttachGlobal);
220 cudaMallocManaged((
void **)&gamval,5*4*
sizeof(
Complex),cudaMemAttachGlobal);
221 cudaMallocManaged((void **)&gamin,4*4*sizeof(short),cudaMemAttachGlobal);
222
223 cudaMallocManaged((
void **)&u[0],
ndim*
kvol*
sizeof(
Complex),cudaMemAttachGlobal);
224 cudaMallocManaged((
void **)&u[1],
ndim*
kvol*
sizeof(
Complex),cudaMemAttachGlobal);
225
228#ifdef _DEBUG
231#else
234
235
236#endif
237#else
238 id = (
unsigned int*)aligned_alloc(
AVX,
ndim*
kvol*
sizeof(
int));
239 iu = (
unsigned int*)aligned_alloc(
AVX,
ndim*
kvol*
sizeof(
int));
240
242
243 dk[0] = (
double *)aligned_alloc(
AVX,(
kvolHalo)*
sizeof(
double));
244 dk[1] = (
double *)aligned_alloc(
AVX,(
kvolHalo)*
sizeof(
double));
245 dk_f[0] = (
float *)aligned_alloc(
AVX,(
kvolHalo)*
sizeof(
float));
246 dk_f[1] = (
float *)aligned_alloc(
AVX,(
kvolHalo)*
sizeof(
float));
247
254#endif
268 Init(istart,ibound,iread,beta,fmu,akappa,ajq,c_sw,u,ut,ut_f,gamval,gamval_f,gamin,dk,dk_f,iu,
id);
269 if(c_sw)
271
273#ifdef USE_GPU
274
275 Init_CUDA(ut[0],ut[1],gamval,gamval_f,gamin,dk[0],dk[1],iu,
id);
276#endif
277
279
280#ifdef USE_GPU
281#if(nproc>1)
282 for(
unsigned short mu=0;mu<
ndim;mu++){
285 }
286#else
289#endif
290#else
291 for(
unsigned short mu=0;mu<
ndim;mu++){
294 }
295#endif
296#ifdef USE_GPU
298#endif
299#ifdef DIAGNOSTIC
300 double ancg_diag=0;
301 Diagnostics(istart, u, ut, ut_f, iu,
id,
hu,
hd, dk,\
302 dk_f, gamin, gamval, gamval_f, sigval, sigval_f, sigin, jqq, akappa, beta, c_sw,ancg_diag);
303#endif
304
305
306
309#ifdef _DEBUG
310 if(!
rank) printf(
"Initial Polyakov loop evaluated as %e\n", poly);
311#endif
312 double hg, avplaqs, avplaqt;
313
315
316 double traj=stepl*dt;
317
318 double proby = 2.5/stepl;
320 int buffer; char buff2[7];
321
322 buffer = (int)round(100*beta);
323 sprintf(buff2,"b%03d",buffer);
324 strcat(suffix,buff2);
325
326 buffer = (int)round(10000*akappa);
327 sprintf(buff2,"k%04d",buffer);
328 strcat(suffix,buff2);
329
330 buffer = (int)round(1000*fmu);
331 sprintf(buff2,"mu%04d",buffer);
332 strcat(suffix,buff2);
333
334 buffer = (int)round(1000*ajq);
335 sprintf(buff2,"j%03d",buffer);
336 strcat(suffix,buff2);
337
338 if(c_sw){
339 buffer = (int)round(100*c_sw);
340 sprintf(buff2,"c%03d",buffer);
341 strcat(suffix,buff2);
342 }
343
344 sprintf(buff2,
"s%02d",
nx);
345 strcat(suffix,buff2);
346
347 sprintf(buff2,
"t%02d",
nt);
348 strcat(suffix,buff2);
349 char outname[
FILELEN] =
"Output.";
char *outop=
"a";
350 strcat(outname,suffix);
351 FILE *output;
353 if(!(output=fopen(outname, outop) )){
354 fprintf(stderr,
"Error %i in %s: Failed to open file %s for %s.\nExiting\n\n",
OPENERROR,funcname,outname,outop);
355#if(nproc>1)
357#else
359#endif
360 }
361 printf("hg = %e, <Ps> = %e, <Pt> = %e, <Poly> = %e\n", hg, avplaqs, avplaqt, poly);
362 fprintf(output, "ksize = %i ksizet = %i Nf = %i Halo =%i\nTime step dt = %e Trajectory length = %e\n"\
363 "No. of Trajectories = %i β = %e\nκ = %e μ = %e\nDiquark source = %e Clover coefficient = %e\n"\
364 "Stopping Residuals: Guidance: %e Acceptance: %e, Estimator: %e\nSeed = %ld\n",
365 ksize,
ksizet,
nf,
halo, dt, traj, ntraj, beta, akappa, fmu, ajq, c_sw,
rescgg,
rescga,
respbp,
seed);
366#ifdef _DEBUG
367
368 printf("ksize = %i ksizet = %i Nf = %i Halo = %i\nTime step dt = %e Trajectory length = %e\n"\
369 "No. of Trajectories = %i β = %e\nκ = %e μ = %e\nDiquark source = %e Clover coefficient = %e\n"\
370 "Stopping Residuals: Guidance: %e Acceptance: %e, Estimator: %e\nSeed = %ld\n",
371 ksize,
ksizet,
nf,
halo, dt, traj, ntraj, beta, akappa, fmu, ajq, c_sw,
rescgg,
rescga,
respbp,
seed);
372#endif
373 }
374
375
376 double actiona = 0.0; double vel2a = 0.0; double pbpa = 0.0; double endenfa = 0.0; double denfa = 0.0;
377
378 double e_dH=0; double e_dH_e=0;
379
380 double yav = 0.0; double yyav = 0.0;
381
382 int naccp = 0; int ipbp = 0; int itot = 0;
383
384
385
386 double pbp;
388 double *dSdpi;
389
391
392
393#ifdef USE_GPU
394#ifdef _DEBUG
395 cudaMallocManaged((
void **)&X0,
nf*
kferm2*
sizeof(
Complex),cudaMemAttachGlobal);
396 cudaMallocManaged((
void **)&Phi,
nf*
kferm*
sizeof(
Complex),cudaMemAttachGlobal);
397 cudaMallocManaged((
void **)&dSdpi,
kmom*
sizeof(
double),cudaMemAttachGlobal);
399#else
403 cudaMalloc((
void **)&dSdpi,
kmom*
sizeof(
double));
404#endif
405
406 cudaMallocManaged((
void **)&pp,
kmom*
sizeof(
double),cudaMemAttachGlobal);
408#else
412 dSdpi = aligned_alloc(
AVX,
kmom*
sizeof(
double));
413
414 pp = aligned_alloc(
AVX,
kmom*
sizeof(
double));
415#endif
421#if (defined SA3AT)
422 double start_time=0;
424#if(nproc>1)
425 start_time = MPI_Wtime();
426#else
427 start_time = omp_get_wtime();
428#endif
429 }
430#endif
431 double action;
432
433 double ancg,ancgh,totancg,totancgh;
434 ancg=ancgh=totancg=totancgh=0;
435 for(int itraj = iread+1; itraj <= ntraj+iread; itraj++){
436
437 ancg = 0; ancgh = 0;
438#ifdef _DEBUG
440 printf("Starting itraj %i\n", itraj);
441#endif
443 if(c_sw)
444 Clover(clover,ut_f,iu,
id);
445 for(
int na=0; na<
nf; na++){
446
447
448
449
450
451#ifdef USE_GPU
454#ifdef _DEBUG
455 cudaMallocManaged((
void **)&R1,
kferm*
sizeof(
Complex),cudaMemAttachGlobal);
456 cudaMallocManaged((
void **)&R1_f,
kferm*
sizeof(
Complex_f),cudaMemAttachGlobal);
458#else
462#endif
463#else
468#endif
469
470
471
472#if (defined USE_GPU && defined _DEBUG)
473
474#endif
475
478
479 Dslashd_f(R1_f,R,ut_f,iu,
id,gamval_f,gamin,dk_f,jqq,akappa);
480 if(c_sw)
481 ByClover_f(R1_f,R,clover,sigval_f,akappa,sigin,
true);
482#ifdef USE_GPU
483
484 cudaFree(R);
485
487#ifdef _DEBUG
488 cudaFree(R1_f);
489#else
490
492 cudaFreeAsync(R1_f,
streams[0]);
493#endif
495#else
496 free(R);
497#pragma omp simd aligned(R1_f,R1:AVX)
498 for(
int i=0;i<
kferm;i++)
500 free(R1_f);
502
503#endif
505#ifdef USE_GPU
506#ifdef _DEBUG
507 cudaFree(R1);
508#else
509
512#endif
513#else
514 free(R1);
515#endif
516 }
517 if(c_sw)
519
520
521
522
523#ifdef USE_GPU
524#if(nproc>1)
525 for(
unsigned short mu=0;mu<
ndim;mu++){
528 }
529#else
532#endif
534#else
535 for(
unsigned short mu=0;mu<
ndim;mu++){
538 }
539#endif
542
543
544
545
546
547 double H0, S0;
548 Hamilton(&H0,&S0,
rescga,pp,X0,X1,Phi,ut,ut_f,iu,
id,gamval,gamval_f,gamin,sigval,sigval_f,sigin,dk,dk_f,\
549 jqq,akappa,beta,c_sw,&ancgh,itraj);
550#ifdef _DEBUG
551 if(!
rank) printf(
"H0: %e S0: %e\n", H0, S0);
552#endif
553 if(itraj==1)
555
556
558#if (defined INT_LPFR && defined INT_OMF2) ||(defined INT_LPFR && defined INT_OMF4)||(defined INT_OMF2 && defined INT_OMF4)
559#error "Only one integrator may be defined"
560#elif defined INT_LPFR
561 Leapfrog(ut,ut_f,X0,X1,Phi,dk,dk_f,dSdpi,pp,iu,
id,gamval,gamval_f,gamin,sigval,sigval_f,sigin,\
562 jqq,beta,akappa,c_sw,stepl,dt,&ancg,&itot,proby);
563#elif defined INT_OMF2
564 OMF2(ut,ut_f,X0,X1,Phi,dk,dk_f,dSdpi,pp,iu,
id,gamval,gamval_f,gamin,sigval,sigval_f,sigin,\
565 jqq,beta,akappa,c_sw,stepl,dt,&ancg,&itot,proby);
566#elif defined INT_OMF4
567#warning "OMF4 can be less efficient than OMF2 in certain cases. Use with caution. See http://dx.doi.org/10.1103/PhysRevE.73.036706"
568 OMF4(ut,ut_f,X0,X1,Phi,dk,dk_f,dSdpi,pp,iu,
id,gamval,gamval_f,gamin,sigval,sigval_f,sigin,\
569 jqq,beta,akappa,c_sw,stepl,dt,&ancg,&itot,proby);
570#else
571#error "No integrator defined. Please define {INT_LPFR.INT_OMF2,INT_OMF4}"
572#endif
573
574 totancg+=ancg;
575
576
578 double H1, S1;
579 Hamilton(&H1,&S1,
rescga,pp,X0,X1,Phi,ut,ut_f,iu,
id,gamval,gamval_f,gamin,sigval,sigval_f,sigin,dk,dk_f,\
580 jqq,akappa,beta,c_sw,&ancgh,itraj);
581 ancgh/=2.0;
582 totancgh+=ancgh;
583#ifdef _DEBUG
584 printf("H0-H1=%f-%f",H0,H1);
585#endif
586 double dH = H0 - H1;
587#ifdef _DEBUG
588 printf("=%f\n",dH);
589#endif
590 double dS = S0 - S1;
592 fprintf(output, "dH = %e dS = %e\n", dH, dS);
593#ifdef _DEBUG
594 printf("dH = %e dS = %e\n", dH, dS);
595#endif
596 }
597 e_dH+=dH; e_dH_e+=dH*dH;
598 double y = exp(dH);
599 yav+=y;
600 yyav+=y*y;
601
602
603 bool acc;
605
607 printf("New configuration accepted on trajectory %i.\n", itraj);
608
609
610
611#ifdef USE_GPU
612#if(nproc>1)
613 for(
unsigned short mu=0;mu<
ndim;mu++){
616 }
617#else
620#endif
621#else
622 for(
unsigned short mu=0;mu<
ndim;mu++){
625 }
626#endif
627 naccp++;
628
630 acc=true;
631 }
632 else{
634 printf("New configuration rejected on trajectory %i.\n", itraj);
635 acc=false;
636 }
637 actiona+=action;
638 double vel2=0.0;
639#ifdef USE_GPU
641 vel2*=vel2;
643#elif defined USE_BLAS
644 vel2 = cblas_dnrm2(
kmom, pp, 1);
645 vel2*=vel2;
646#else
647#pragma unroll
648 for(
int i=0; i<
kmom; i++)
649 vel2+=pp[i]*pp[i];
650#endif
651#if(nproc>1)
653#endif
655
656 if(itraj%iprint==0){
657
658 if(!acc){
659#ifdef USE_GPU
660#if(nproc>1)
661 for(
unsigned short mu=0;mu<
ndim;mu++){
664 }
665#else
668#endif
670#else
671 for(
unsigned short mu=0;mu<
ndim;mu++){
674 }
675#endif
677 }
678#ifdef _DEBUG
680 printf("Starting measurements\n");
681#endif
682 int itercg=0;
683 double endenf, denf;
685
686
687
688 int measure_check=0;
689 measure_check =
Measure(&pbp,&endenf,&denf,&qq,&qbqb,
respbp,&itercg,ut,ut_f,iu,
id,\
690 gamval,gamval_f,gamin,sigval,sigval_f,sigin,dk,dk_f,jqq,akappa,c_sw,Phi);
691#ifdef _DEBUG
693 printf("Finished measurements\n");
694#endif
695 pbpa+=pbp; endenfa+=endenf; denfa+=denf; ipbp++;
698
699
700
701#if (nproc>=4)
703#else
705#pragma omp parallel for
706 for(int i=0; i<4; i++)
707 switch(i)
708#endif
709 {
710 case(0):
711
712
713
714
715 fprintf(output, "Measure (CG) %i Update (CG) %.3f Hamiltonian (CG) %.3f\n", itercg, ancg, ancgh);
716 fflush(output);
717 break;
718 case(1):
719 {
720 FILE *fortout;
721 char fortname[
FILELEN] =
"fermi.";
722 strcat(fortname,suffix);
723 const char *fortop= (itraj==1) ? "w" : "a";
724 if(!(fortout=fopen(fortname, fortop) )){
725 fprintf(stderr, "Error %i in %s: Failed to open file %s for %s.\nExiting\n\n",\
727#if(nproc>1)
729#else
731#endif
732 }
733 if(itraj==1)
734 fprintf(fortout, "pbp\tendenf\tdenf\n");
735 if(measure_check)
736 fprintf(fortout, "%e\t%e\t%e\n", NAN, NAN, NAN);
737 else
738 fprintf(fortout, "%e\t%e\t%e\n", pbp, endenf, denf);
739 fclose(fortout);
740 break;
741 }
742 case(2):
743
744
745
746 {
747 FILE *fortout;
748 char fortname[
FILELEN] =
"bose.";
749 strcat(fortname,suffix);
750 const char *fortop= (itraj==1) ? "w" : "a";
751 if(!(fortout=fopen(fortname, fortop) )){
752 fprintf(stderr, "Error %i in %s: Failed to open file %s for %s.\nExiting\n\n",\
754 }
755 if(itraj==1)
756 fprintf(fortout, "avplaqs\tavplaqt\tpoly\n");
757 fprintf(fortout, "%e\t%e\t%e\n", avplaqs, avplaqt, poly);
758 fclose(fortout);
759 break;
760 }
761 case(3):
762 {
763 FILE *fortout;
764 char fortname[
FILELEN] =
"diq.";
765 strcat(fortname,suffix);
766 const char *fortop= (itraj==1) ? "w" : "a";
767 if(!(fortout=fopen(fortname, fortop) )){
768 fprintf(stderr, "Error %i in %s: Failed to open file %s for %s.\nExiting\n\n",\
770#if(nproc>1)
772#else
774#endif
775 }
776 if(itraj==1)
777 fprintf(fortout, "Re(qq)\n");
778 if(measure_check)
779 fprintf(fortout, "%e\n", NAN);
780 else
781 fprintf(fortout,
"%e\n",
creal(qq));
782 fclose(fortout);
783 break;
784 }
785 default: break;
786 }
787 }
788 if(itraj%icheck==0){
789 Par_swrite(itraj,icheck,beta,fmu,akappa,ajq,c_sw,u[0],u[1]);
790 }
792 fflush(output);
793 }
794#if (defined SA3AT)
795 double elapsed = 0;
797#if(nproc>1)
798 elapsed = MPI_Wtime()-start_time;
799#else
800 elapsed = omp_get_wtime()-start_time;
801#endif
802 }
803#endif
804
805
806#ifdef USE_GPU
807
808 cudaFree(dk[0]); cudaFree(dk[1]); cudaFree(dSdpi); cudaFree(pp);
809 cudaFree(Phi); cudaFree(ut[0]); cudaFree(ut[1]);
810 cudaFree(X0); cudaFree(X1); cudaFree(u[0]); cudaFree(u[1]);
811 cudaFree(id); cudaFree(iu);
812 cudaFree(dk_f[0]); cudaFree(dk_f[1]); cudaFree(ut_f[0]); cudaFree(ut_f[1]);
813 cudaFree(gamin); cudaFree(gamval); cudaFree(gamval_f);
814 if(c_sw){
815 cudaFree(sigval); cudaFree(sigval_f); cudaFree(sigin);
816 }
818#else
819 free(dk[0]); free(dk[1]);free(dSdpi); free(pp);
820 free(Phi); free(ut[0]); free(ut[1]);
821 free(X0); free(X1); free(u[0]); free(u[1]);
822 free(id); free(iu);
823 free(dk_f[0]); free(dk_f[1]); free(ut_f[0]); free(ut_f[1]);
824 if(c_sw){
825 free(sigval); free(sigval_f); free(sigin);
826 }
827#endif
829#ifdef __RANLUX__
831#endif
832#if (defined SA3AT)
834 FILE *sa3at = fopen("Bench_times.csv", "a");
835#ifdef USE_GPU
836 char version[256];
837 int cuversion; cudaRuntimeGetVersion(&cuversion);
838 sprintf(version,"CUDA %d\tBlock: (%d,%d,%d)\tGrid: (%d,%d,%d)\n%s\n",cuversion,\
840#else
841 char *version=__VERSION__;
842#endif
843 fprintf(sa3at, "%s\nβ%0.3f κ:%0.4f μ:%0.4f j:%0.3f s:%i t:%i kvol:%ld\n"
844 "npx:%i npt:%i nthread:%i ncore:%i time:%f traj_time:%f\n\n",\
845 version,beta,akappa,fmu,ajq,
nx,
nt,
kvol,
npx,
npt,
nthreads,
npx*
npy*
npz*
npt*
nthreads,elapsed,elapsed/ntraj);
846 fclose(sa3at);
847 }
848#endif
849
850 actiona/=ntraj; vel2a/=ntraj; pbpa/=ipbp; endenfa/=ipbp; denfa/=ipbp;
851 totancg/=ntraj; totancgh/=ntraj;
852 e_dH/=ntraj; e_dH_e=sqrt((e_dH_e/ntraj-e_dH*e_dH)/(ntraj-1));
853 yav/=ntraj; yyav=sqrt((yyav/ntraj - yav*yav)/(ntraj-1));
854 float traj_cost=totancg/dt;
855 double atraj=dt*itot/ntraj;
856
858 fprintf(output, "Averages for the last %i trajectories\n"\
859 "Number of acceptances: %i\tAverage Trajectory Length = %e\n"\
860 "<dH>=%e+/-%e\t<exp(dH)>=%e+/-%e\tTrajectory cost=N_cg/dt =%e\n"\
861 "Average number of congrad iter guidance: %.3f acceptance %.3f\n"\
862 "psibarpsi = %e\n"\
863 "Mean Square Velocity = %e\tAction Per Site = %e\n"\
864 "Energy Density = %e\tNumber Density %e\n\n\n",\
865 ntraj, naccp, atraj, e_dH,e_dH_e, yav, yyav, traj_cost, totancg, totancgh, pbpa, vel2a, actiona, endenfa, denfa);
866 fclose(output);
867 }
868#if(nproc>1)
869
870 MPI_Barrier(comm);
872#endif
873 fflush(stdout);
874 return 0;
875}
unsigned int * hd
Down halo indices.
unsigned int * hu
Up halo indices.
#define OPENERROR
Error opening file.
#define NOIMPL
Not implemented.
double Polyakov(Complex_f *ut[2])
Calculate the Polyakov loop (no prizes for guessing that one...).
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...
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_free(Complex_f *clover[nc])
Free's memory used for clover terms and leaves.
int Init_clover(Complex **sigval, Complex_f **sigval_f, unsigned short **sigin, float c_sw)
Initialise values needed for the clover terms.
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.
void blockInit(int x, int y, int z, int t, dim3 *dimBlock, dim3 *dimGrid)
Initialises the CUDA grid and block size for a given lattice.
void Init_CUDA(Complex *u11t, Complex *u12t, Complex gamval[20], Complex_f gamval_f[20], unsigned short gamin[16], double *dk4m, double *dk4p, unsigned int *iu, unsigned int *id)
Initialise CUDA cuInit was taken already by CUDA (unsurprisingly).
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.
int UpDownPart(const unsigned int na, Complex *X0, Complex *R1)
Up/Down partitioning of the pseudofermion field.
int Reunitarise(Complex *ut[2])
Reunitarises u11t and u12t as in conj(u11t[i])*u11t[i]+conj(u12t[i])*u12t[i]=1.
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
int OMF2(Complex *ut[2], Complex_f *ut_f[2], Complex *X0, Complex *X1, Complex *Phi, double *dk[2], float *dk_f[2], double *dSdpi, double *pp, 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, const Complex jqq, const float beta, const float akappa, const float c_sw, const int stepl, const float dt, double *ancg, int *itot, const float proby)
OMF second order five step integrator.
int Leapfrog(Complex *ut[2], Complex_f *ut_f[2], Complex *X0, Complex *X1, Complex *Phi, double *dk[2], float *dk_f[2], double *dSdpi, double *pp, 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, const Complex jqq, const float beta, const float akappa, const float c_sw, const int stepl, const float dt, double *ancg, int *itot, const float proby)
Leapfrog integrator. Each trajectory step takes the form of p->p+dt/2,u->u+dt,p->p+dt/2 In practice t...
int OMF4(Complex *ut[2], Complex_f *ut_f[2], Complex *X0, Complex *X1, Complex *Phi, double *dk[2], float *dk_f[2], double *dSdpi, double *pp, 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, const Complex jqq, const float beta, const float akappa, const float c_sw, const int stepl, const float dt, double *ancg, int *itot, const float proby)
OMF fourth order eleven step integrator.
int Par_fcopy(float *fval)
Broadcasts a float to the other processes.
int Par_begin(int argc, char *argv[])
Initialises the MPI configuration.
int Par_swrite(const int itraj, const int icheck, const float beta, const float fmu, const float akappa, const Complex_f ajq, const float c_sw, Complex *u11, Complex *u12)
Copies u11 and u12 into arrays without halos which then get written to output.
int Par_icopy(int *ival)
Broadcasts an integer to the other processes.
int Trial_Exchange(Complex *ut[2], Complex_f *ut_f[2])
Exchanges the trial fields.
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.
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...
int Gauss_d(double *ps, unsigned int n, const double mu, const double sigma)
Generates a vector of normally distributed random double precision numbers using the Box-Muller Metho...
double Par_granf()
Generates a random double which is then sent to the other ranks.
int size
The number of MPI ranks in total.
#define MPI_Finalise()
Avoid any accidents with US/UK spelling.
int * pcoord
The processor grid.
unsigned long seed
RANLUX seed.
gsl_rng * ranlux_instd
RANLUX instance.
#define AVX
Alignment of arrays. 64 for AVX-512, 32 for AVX/AVX2. 16 for SSE. Since AVX is standard on modern x86...
#define rescgg
Conjugate gradient residue for update.
#define nt
Lattice temporal extent. This also corresponds to the inverse temperature.
#define kmom
sublattice momentum sites
#define nx
Lattice x extent.
cudaMemPool_t mempool
Memory pool for Async allocations.
#define ngorkov
Gor'kov indices.
#define ksizet
Sublattice t extent.
#define kferm2Halo
Dirac lattice and halo.
#define npx
Processor grid x extent. This must be a divisor of nx.
#define nadj
adjacent spatial indices
#define kvol
Sublattice volume.
#define Complex
Double precision complex number.
#define kferm
sublattice size including Gor'kov indices
#define rescga
Conjugate gradient residue for acceptance.
#define npz
Processor grid z extent.
#define nthreads
Number of threads for OpenMP, which can be overwritten at runtime.
#define ksize
Sublattice spatial extent for a cubic lattice.
#define nf
Fermion flavours (double it).
#define cudaDeviceSynchronise()
Get rid of that bastardised yankee English.
#define respbp
Conjugate gradient residue for .
#define gvol
Lattice volume.
#define FILELEN
Default file name length.
cublasHandle_t cublas_handle
Handle for cuBLAS.
#define halo
Total Halo size.
#define Complex_f
Single precision complex number.
dim3 dimGrid
Default grid size. First component is normally nt. Second and third depend whatever is needed to get ...
#define npy
Processor grid y extent.
#define kferm2
sublattice size including Dirac indices
#define npt
Processor grid t extent.
#define kvolHalo
Subvolume + halo size.
#define kfermHalo
Gor'kov lattice and halo.
#define nz
Lattice z extent. We normally use cubic lattices so this is the same as nx.
#define ny
Lattice y extent. We normally use cubic lattices so this is the same as nx.
dim3 dimBlock
Default block size. Usually 128.
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.
#define cimag(z)
Extract Imaginary Component using C standard notation.