void det_heatbath(const int id, hamiltonian_field_t * const hf) { monomial * mnl = &monomial_list[id]; double atime, etime; atime = gettime(); g_mu = mnl->mu; boundary(mnl->kappa); mnl->csg_n = 0; mnl->csg_n2 = 0; mnl->iter0 = 0; mnl->iter1 = 0; if(mnl->even_odd_flag) { random_spinor_field_eo(mnl->w_fields[0], mnl->rngrepro, RN_GAUSS); mnl->energy0 = square_norm(mnl->w_fields[0], VOLUME/2, 1); mnl->Qp(mnl->pf, mnl->w_fields[0]); chrono_add_solution(mnl->pf, mnl->csg_field, mnl->csg_index_array, mnl->csg_N, &mnl->csg_n, VOLUME/2); if(mnl->solver != CG) { chrono_add_solution(mnl->pf, mnl->csg_field2, mnl->csg_index_array2, mnl->csg_N2, &mnl->csg_n2, VOLUME/2); } } else { random_spinor_field_lexic(mnl->w_fields[0], mnl->rngrepro,RN_GAUSS); mnl->energy0 = square_norm(mnl->w_fields[0], VOLUME, 1); Q_plus_psi(mnl->pf, mnl->w_fields[0]); chrono_add_solution(mnl->pf, mnl->csg_field, mnl->csg_index_array, mnl->csg_N, &mnl->csg_n, VOLUME/2); if(mnl->solver != CG) { chrono_add_solution(mnl->pf, mnl->csg_field2, mnl->csg_index_array2, mnl->csg_N2, &mnl->csg_n2, VOLUME/2); } } g_mu = g_mu1; boundary(g_kappa); etime = gettime(); if(g_proc_id == 0) { if(g_debug_level > 1) { printf("# Time for %s monomial heatbath: %e s\n", mnl->name, etime-atime); } if(g_debug_level > 3) { printf("called det_heatbath for id %d energey %f\n", id, mnl->energy0); } } return; }
void cloverdet_heatbath(const int id, hamiltonian_field_t * const hf) { monomial * mnl = &monomial_list[id]; double atime, etime; atime = gettime(); int N = VOLUME/2; g_mu = mnl->mu; g_mu3 = mnl->rho; g_c_sw = mnl->c_sw; boundary(mnl->kappa); mnl->csg_n = 0; mnl->csg_n2 = 0; mnl->iter0 = 0; mnl->iter1 = 0; init_sw_fields(); sw_term( (const su3**) hf->gaugefield, mnl->kappa, mnl->c_sw); if(!mnl->even_odd_flag) { N = VOLUME; random_spinor_field_lexic(mnl->w_fields[0], mnl->rngrepro, RN_GAUSS); } else { sw_invert(EE, mnl->mu); random_spinor_field_eo(mnl->w_fields[0], mnl->rngrepro, RN_GAUSS); } mnl->energy0 = square_norm(mnl->w_fields[0], N, 1); mnl->Qp(mnl->pf, mnl->w_fields[0]); chrono_add_solution(mnl->pf, mnl->csg_field, mnl->csg_index_array, mnl->csg_N, &mnl->csg_n, N); g_mu = g_mu1; g_mu3 = 0.; boundary(g_kappa); etime = gettime(); if(g_proc_id == 0) { if(g_debug_level > 1) { printf("# Time for %s monomial heatbath: %e s\n", mnl->name, etime-atime); } if(g_debug_level > 3) { printf("called cloverdet_heatbath for id %d energy %f\n", id, mnl->energy0); } } return; }
int main(int argc, char *argv[]) { FILE *parameterfile = NULL; int c, j, i, ix = 0, isample = 0, op_id = 0; char * filename = NULL; char datafilename[50]; char parameterfilename[50]; char conf_filename[50]; char * input_filename = NULL; double plaquette_energy; struct stout_parameters params_smear; spinor **s, *s_; #ifdef _KOJAK_INST #pragma pomp inst init #pragma pomp inst begin(main) #endif #if (defined SSE || defined SSE2 || SSE3) signal(SIGILL, &catch_ill_inst); #endif DUM_DERI = 8; DUM_MATRIX = DUM_DERI + 5; #if ((defined BGL && defined XLC) || defined _USE_TSPLITPAR) NO_OF_SPINORFIELDS = DUM_MATRIX + 3; #else NO_OF_SPINORFIELDS = DUM_MATRIX + 3; #endif verbose = 0; g_use_clover_flag = 0; #ifdef MPI # ifdef OMP int mpi_thread_provided; MPI_Init_thread(&argc, &argv, MPI_THREAD_SERIALIZED, &mpi_thread_provided); # else MPI_Init(&argc, &argv); # endif MPI_Comm_rank(MPI_COMM_WORLD, &g_proc_id); #else g_proc_id = 0; #endif while ((c = getopt(argc, argv, "h?vVf:o:")) != -1) { switch (c) { case 'f': input_filename = calloc(200, sizeof(char)); strcpy(input_filename, optarg); break; case 'o': filename = calloc(200, sizeof(char)); strcpy(filename, optarg); break; case 'v': verbose = 1; break; case 'V': fprintf(stdout,"%s %s\n",PACKAGE_STRING,git_hash); exit(0); break; case 'h': case '?': default: usage(); break; } } if (input_filename == NULL) { input_filename = "invert.input"; } if (filename == NULL) { filename = "output"; } /* Read the input file */ if( (j = read_input(input_filename)) != 0) { fprintf(stderr, "Could not find input file: %s\nAborting...\n", input_filename); exit(-1); } #ifdef OMP if(omp_num_threads > 0) { omp_set_num_threads(omp_num_threads); } else { if( g_proc_id == 0 ) printf("# No value provided for OmpNumThreads, running in single-threaded mode!\n"); omp_num_threads = 1; omp_set_num_threads(omp_num_threads); } init_omp_accumulators(omp_num_threads); #endif /* this DBW2 stuff is not needed for the inversion ! */ if (g_dflgcr_flag == 1) { even_odd_flag = 0; } g_rgi_C1 = 0; if (Nsave == 0) { Nsave = 1; } if (g_running_phmc) { NO_OF_SPINORFIELDS = DUM_MATRIX + 8; } tmlqcd_mpi_init(argc, argv); g_dbw2rand = 0; /* starts the single and double precision random number */ /* generator */ start_ranlux(rlxd_level, random_seed); /* we need to make sure that we don't have even_odd_flag = 1 */ /* if any of the operators doesn't use it */ /* in this way even/odd can still be used by other operators */ for(j = 0; j < no_operators; j++) if(!operator_list[j].even_odd_flag) even_odd_flag = 0; #ifndef MPI g_dbw2rand = 0; #endif #ifdef _GAUGE_COPY j = init_gauge_field(VOLUMEPLUSRAND, 1); #else j = init_gauge_field(VOLUMEPLUSRAND, 0); #endif if (j != 0) { fprintf(stderr, "Not enough memory for gauge_fields! Aborting...\n"); exit(-1); } j = init_geometry_indices(VOLUMEPLUSRAND); if (j != 0) { fprintf(stderr, "Not enough memory for geometry indices! Aborting...\n"); exit(-1); } if (no_monomials > 0) { if (even_odd_flag) { j = init_monomials(VOLUMEPLUSRAND / 2, even_odd_flag); } else { j = init_monomials(VOLUMEPLUSRAND, even_odd_flag); } if (j != 0) { fprintf(stderr, "Not enough memory for monomial pseudo fermion fields! Aborting...\n"); exit(-1); } } if (even_odd_flag) { j = init_spinor_field(VOLUMEPLUSRAND / 2, NO_OF_SPINORFIELDS); } else { j = init_spinor_field(VOLUMEPLUSRAND, NO_OF_SPINORFIELDS); } if (j != 0) { fprintf(stderr, "Not enough memory for spinor fields! Aborting...\n"); exit(-1); } if (g_running_phmc) { j = init_chi_spinor_field(VOLUMEPLUSRAND / 2, 20); if (j != 0) { fprintf(stderr, "Not enough memory for PHMC Chi fields! Aborting...\n"); exit(-1); } } g_mu = g_mu1; if (g_cart_id == 0) { /*construct the filenames for the observables and the parameters*/ strcpy(datafilename, filename); strcat(datafilename, ".data"); strcpy(parameterfilename, filename); strcat(parameterfilename, ".para"); parameterfile = fopen(parameterfilename, "w"); write_first_messages(parameterfile, "invert", git_hash); fclose(parameterfile); } /* define the geometry */ geometry(); /* define the boundary conditions for the fermion fields */ boundary(g_kappa); phmc_invmaxev = 1.; init_operators(); /* this could be maybe moved to init_operators */ #ifdef _USE_HALFSPINOR j = init_dirac_halfspinor(); if (j != 0) { fprintf(stderr, "Not enough memory for halffield! Aborting...\n"); exit(-1); } if (g_sloppy_precision_flag == 1) { j = init_dirac_halfspinor32(); if (j != 0) { fprintf(stderr, "Not enough memory for 32-bit halffield! Aborting...\n"); exit(-1); } } # if (defined _PERSISTENT) if (even_odd_flag) init_xchange_halffield(); # endif #endif for (j = 0; j < Nmeas; j++) { sprintf(conf_filename, "%s.%.4d", gauge_input_filename, nstore); if (g_cart_id == 0) { printf("#\n# Trying to read gauge field from file %s in %s precision.\n", conf_filename, (gauge_precision_read_flag == 32 ? "single" : "double")); fflush(stdout); } if( (i = read_gauge_field(conf_filename)) !=0) { fprintf(stderr, "Error %d while reading gauge field from %s\n Aborting...\n", i, conf_filename); exit(-2); } if (g_cart_id == 0) { printf("# Finished reading gauge field.\n"); fflush(stdout); } #ifdef MPI xchange_gauge(g_gauge_field); #endif /*compute the energy of the gauge field*/ plaquette_energy = measure_gauge_action( (const su3**) g_gauge_field); if (g_cart_id == 0) { printf("# The computed plaquette value is %e.\n", plaquette_energy / (6.*VOLUME*g_nproc)); fflush(stdout); } if (use_stout_flag == 1){ params_smear.rho = stout_rho; params_smear.iterations = stout_no_iter; /* if (stout_smear((su3_tuple*)(g_gauge_field[0]), ¶ms_smear, (su3_tuple*)(g_gauge_field[0])) != 0) */ /* exit(1) ; */ g_update_gauge_copy = 1; g_update_gauge_energy = 1; g_update_rectangle_energy = 1; plaquette_energy = measure_gauge_action( (const su3**) g_gauge_field); if (g_cart_id == 0) { printf("# The plaquette value after stouting is %e\n", plaquette_energy / (6.*VOLUME*g_nproc)); fflush(stdout); } } if (reweighting_flag == 1) { reweighting_factor(reweighting_samples, nstore); } /* Compute minimal eigenvalues, if wanted */ if (compute_evs != 0) { eigenvalues(&no_eigenvalues, 5000, eigenvalue_precision, 0, compute_evs, nstore, even_odd_flag); } if (phmc_compute_evs != 0) { #ifdef MPI MPI_Finalize(); #endif return(0); } /* Compute the mode number or topological susceptibility using spectral projectors, if wanted*/ if(compute_modenumber != 0 || compute_topsus !=0){ s_ = calloc(no_sources_z2*VOLUMEPLUSRAND+1, sizeof(spinor)); s = calloc(no_sources_z2, sizeof(spinor*)); if(s_ == NULL) { printf("Not enough memory in %s: %d",__FILE__,__LINE__); exit(42); } if(s == NULL) { printf("Not enough memory in %s: %d",__FILE__,__LINE__); exit(42); } for(i = 0; i < no_sources_z2; i++) { #if (defined SSE3 || defined SSE2 || defined SSE) s[i] = (spinor*)(((unsigned long int)(s_)+ALIGN_BASE)&~ALIGN_BASE)+i*VOLUMEPLUSRAND; #else s[i] = s_+i*VOLUMEPLUSRAND; #endif random_spinor_field_lexic(s[i], reproduce_randomnumber_flag,RN_Z2); /* what is this here needed for?? */ /* spinor *aux_,*aux; */ /* #if ( defined SSE || defined SSE2 || defined SSE3 ) */ /* aux_=calloc(VOLUMEPLUSRAND+1, sizeof(spinor)); */ /* aux = (spinor *)(((unsigned long int)(aux_)+ALIGN_BASE)&~ALIGN_BASE); */ /* #else */ /* aux_=calloc(VOLUMEPLUSRAND, sizeof(spinor)); */ /* aux = aux_; */ /* #endif */ if(g_proc_id == 0) { printf("source %d \n", i); } if(compute_modenumber != 0){ mode_number(s[i], mstarsq); } if(compute_topsus !=0) { top_sus(s[i], mstarsq); } } free(s); free(s_); } /* move to operators as well */ if (g_dflgcr_flag == 1) { /* set up deflation blocks */ init_blocks(nblocks_t, nblocks_x, nblocks_y, nblocks_z); /* the can stay here for now, but later we probably need */ /* something like init_dfl_solver called somewhere else */ /* create set of approximate lowest eigenvectors ("global deflation subspace") */ /* g_mu = 0.; */ /* boundary(0.125); */ generate_dfl_subspace(g_N_s, VOLUME, reproduce_randomnumber_flag); /* boundary(g_kappa); */ /* g_mu = g_mu1; */ /* Compute little Dirac operators */ /* alt_block_compute_little_D(); */ if (g_debug_level > 0) { check_projectors(reproduce_randomnumber_flag); check_local_D(reproduce_randomnumber_flag); } if (g_debug_level > 1) { check_little_D_inversion(reproduce_randomnumber_flag); } } if(SourceInfo.type == 1) { index_start = 0; index_end = 1; } g_precWS=NULL; if(use_preconditioning == 1){ /* todo load fftw wisdom */ #if (defined HAVE_FFTW ) && !( defined MPI) loadFFTWWisdom(g_spinor_field[0],g_spinor_field[1],T,LX); #else use_preconditioning=0; #endif } if (g_cart_id == 0) { fprintf(stdout, "#\n"); /*Indicate starting of the operator part*/ } for(op_id = 0; op_id < no_operators; op_id++) { boundary(operator_list[op_id].kappa); g_kappa = operator_list[op_id].kappa; g_mu = 0.; if(use_preconditioning==1 && PRECWSOPERATORSELECT[operator_list[op_id].solver]!=PRECWS_NO ){ printf("# Using preconditioning with treelevel preconditioning operator: %s \n", precWSOpToString(PRECWSOPERATORSELECT[operator_list[op_id].solver])); /* initial preconditioning workspace */ operator_list[op_id].precWS=(spinorPrecWS*)malloc(sizeof(spinorPrecWS)); spinorPrecWS_Init(operator_list[op_id].precWS, operator_list[op_id].kappa, operator_list[op_id].mu/2./operator_list[op_id].kappa, -(0.5/operator_list[op_id].kappa-4.), PRECWSOPERATORSELECT[operator_list[op_id].solver]); g_precWS = operator_list[op_id].precWS; if(PRECWSOPERATORSELECT[operator_list[op_id].solver] == PRECWS_D_DAGGER_D) { fitPrecParams(op_id); } } for(isample = 0; isample < no_samples; isample++) { for (ix = index_start; ix < index_end; ix++) { if (g_cart_id == 0) { fprintf(stdout, "#\n"); /*Indicate starting of new index*/ } /* we use g_spinor_field[0-7] for sources and props for the moment */ /* 0-3 in case of 1 flavour */ /* 0-7 in case of 2 flavours */ prepare_source(nstore, isample, ix, op_id, read_source_flag, source_location); operator_list[op_id].inverter(op_id, index_start, 1); } } if(use_preconditioning==1 && operator_list[op_id].precWS!=NULL ){ /* free preconditioning workspace */ spinorPrecWS_Free(operator_list[op_id].precWS); free(operator_list[op_id].precWS); } if(operator_list[op_id].type == OVERLAP){ free_Dov_WS(); } } nstore += Nsave; } #ifdef MPI MPI_Finalize(); #endif #ifdef OMP free_omp_accumulators(); #endif free_blocks(); free_dfl_subspace(); free_gauge_field(); free_geometry_indices(); free_spinor_field(); free_moment_field(); free_chi_spinor_field(); return(0); #ifdef _KOJAK_INST #pragma pomp inst end(main) #endif }
int main(int argc,char *argv[]) { #ifdef _USE_HALFSPINOR #undef _USE_HALFSPINOR printf("# WARNING: USE_HALFSPINOR will be ignored (not supported here).\n"); #endif if(even_odd_flag) { even_odd_flag=0; printf("# WARNING: even_odd_flag will be ignored (not supported here).\n"); } int j,j_max,k,k_max = 1; #ifdef HAVE_LIBLEMON paramsXlfInfo *xlfInfo; #endif int status = 0; static double t1,t2,dt,sdt,dts,qdt,sqdt; double antioptaway=0.0; #ifdef MPI static double dt2; DUM_DERI = 6; DUM_SOLVER = DUM_DERI+2; DUM_MATRIX = DUM_SOLVER+6; NO_OF_SPINORFIELDS = DUM_MATRIX+2; # ifdef OMP int mpi_thread_provided; MPI_Init_thread(&argc, &argv, MPI_THREAD_SERIALIZED, &mpi_thread_provided); # else MPI_Init(&argc, &argv); # endif MPI_Comm_rank(MPI_COMM_WORLD, &g_proc_id); #else g_proc_id = 0; #endif g_rgi_C1 = 1.; /* Read the input file */ if((status = read_input("test_Dslash.input")) != 0) { fprintf(stderr, "Could not find input file: test_Dslash.input\nAborting...\n"); exit(-1); } #ifdef OMP init_openmp(); #endif tmlqcd_mpi_init(argc, argv); if(g_proc_id==0) { #ifdef SSE printf("# The code was compiled with SSE instructions\n"); #endif #ifdef SSE2 printf("# The code was compiled with SSE2 instructions\n"); #endif #ifdef SSE3 printf("# The code was compiled with SSE3 instructions\n"); #endif #ifdef P4 printf("# The code was compiled for Pentium4\n"); #endif #ifdef OPTERON printf("# The code was compiled for AMD Opteron\n"); #endif #ifdef _GAUGE_COPY printf("# The code was compiled with -D_GAUGE_COPY\n"); #endif #ifdef BGL printf("# The code was compiled for Blue Gene/L\n"); #endif #ifdef BGP printf("# The code was compiled for Blue Gene/P\n"); #endif #ifdef _USE_HALFSPINOR printf("# The code was compiled with -D_USE_HALFSPINOR\n"); #endif #ifdef _USE_SHMEM printf("# The code was compiled with -D_USE_SHMEM\n"); # ifdef _PERSISTENT printf("# The code was compiled for persistent MPI calls (halfspinor only)\n"); # endif #endif #ifdef MPI # ifdef _NON_BLOCKING printf("# The code was compiled for non-blocking MPI calls (spinor and gauge)\n"); # endif #endif printf("\n"); fflush(stdout); } #ifdef _GAUGE_COPY init_gauge_field(VOLUMEPLUSRAND + g_dbw2rand, 1); #else init_gauge_field(VOLUMEPLUSRAND + g_dbw2rand, 0); #endif init_geometry_indices(VOLUMEPLUSRAND + g_dbw2rand); if(even_odd_flag) { j = init_spinor_field(VOLUMEPLUSRAND/2, 2*k_max+1); } else { j = init_spinor_field(VOLUMEPLUSRAND, 2*k_max); } if ( j!= 0) { fprintf(stderr, "Not enough memory for spinor fields! Aborting...\n"); exit(0); } j = init_moment_field(VOLUME, VOLUMEPLUSRAND + g_dbw2rand); if ( j!= 0) { fprintf(stderr, "Not enough memory for moment fields! Aborting...\n"); exit(0); } if(g_proc_id == 0) { fprintf(stdout,"# The number of processes is %d \n",g_nproc); printf("# The lattice size is %d x %d x %d x %d\n", (int)(T*g_nproc_t), (int)(LX*g_nproc_x), (int)(LY*g_nproc_y), (int)(g_nproc_z*LZ)); printf("# The local lattice size is %d x %d x %d x %d\n", (int)(T), (int)(LX), (int)(LY),(int) LZ); // if(even_odd_flag) { // printf("# benchmarking the even/odd preconditioned Dirac operator\n"); // } // else { // printf("# benchmarking the standard Dirac operator\n"); // } fflush(stdout); } /* define the geometry */ geometry(); /* define the boundary conditions for the fermion fields */ boundary(g_kappa); #ifdef _USE_HALFSPINOR j = init_dirac_halfspinor(); if ( j!= 0) { fprintf(stderr, "Not enough memory for halfspinor fields! Aborting...\n"); exit(0); } if(g_sloppy_precision_flag == 1) { g_sloppy_precision = 1; j = init_dirac_halfspinor32(); if ( j!= 0) { fprintf(stderr, "Not enough memory for 32-Bit halfspinor fields! Aborting...\n"); exit(0); } } # if (defined _PERSISTENT) init_xchange_halffield(); # endif #endif status = check_geometry(); if (status != 0) { fprintf(stderr, "Checking of geometry failed. Unable to proceed.\nAborting....\n"); exit(1); } #if (defined MPI && !(defined _USE_SHMEM)) check_xchange(); #endif start_ranlux(1, 123456); random_gauge_field(reproduce_randomnumber_flag, g_gauge_field); #ifdef MPI /*For parallelization: exchange the gaugefield */ xchange_gauge(g_gauge_field); #endif /* the non even/odd case now */ /*initialize the pseudo-fermion fields*/ j_max=1; sdt=0.; for (k=0;k<k_max;k++) { random_spinor_field_lexic(g_spinor_field[k], reproduce_randomnumber_flag, RN_GAUSS); } #ifdef MPI MPI_Barrier(MPI_COMM_WORLD); #endif t1 = gettime(); /* here the actual Dslash */ D_psi(g_spinor_field[0], g_spinor_field[1]); t2 = gettime(); dt=t2-t1; #ifdef MPI MPI_Allreduce (&dt, &sdt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); #else sdt = dt; #endif if(g_proc_id==0) { printf("# Time for Dslash %e sec.\n", sdt); printf("\n"); fflush(stdout); } #ifdef HAVE_LIBLEMON if(g_proc_id==0) { printf("# Performing parallel IO test ...\n"); } xlfInfo = construct_paramsXlfInfo(0.5, 0); write_gauge_field( "conf.test", 64, xlfInfo); free(xlfInfo); if(g_proc_id==0) { printf("# done ...\n"); } #endif #ifdef OMP free_omp_accumulators(); #endif free_gauge_field(); free_geometry_indices(); free_spinor_field(); free_moment_field(); #ifdef MPI MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); #endif return(0); }
int main(int argc,char *argv[]) { FILE *parameterfile = NULL; char datafilename[206]; char parameterfilename[206]; char conf_filename[50]; char scalar_filename[50]; char * input_filename = NULL; char * filename = NULL; double plaquette_energy; #ifdef _USE_HALFSPINOR #undef _USE_HALFSPINOR printf("# WARNING: USE_HALFSPINOR will be ignored (not supported here).\n"); #endif if(even_odd_flag) { even_odd_flag=0; printf("# WARNING: even_odd_flag will be ignored (not supported here).\n"); } int j,j_max,k,k_max = 2; _Complex double * drvsc; #ifdef HAVE_LIBLEMON paramsXlfInfo *xlfInfo; #endif int status = 0; static double t1,t2,dt,sdt,dts,qdt,sqdt; double antioptaway=0.0; #ifdef MPI static double dt2; DUM_DERI = 6; DUM_SOLVER = DUM_DERI+2; DUM_MATRIX = DUM_SOLVER+6; NO_OF_SPINORFIELDS = DUM_MATRIX+2; #ifdef OMP int mpi_thread_provided; MPI_Init_thread(&argc, &argv, MPI_THREAD_SERIALIZED, &mpi_thread_provided); #else MPI_Init(&argc, &argv); #endif MPI_Comm_rank(MPI_COMM_WORLD, &g_proc_id); #else g_proc_id = 0; #endif g_rgi_C1 = 1.; process_args(argc,argv,&input_filename,&filename); set_default_filenames(&input_filename, &filename); /* Read the input file */ if( (j = read_input(input_filename)) != 0) { fprintf(stderr, "Could not find input file: %s\nAborting...\n", input_filename); exit(-1); } if(g_proc_id==0) { printf("parameter rho_BSM set to %f\n", rho_BSM); printf("parameter eta_BSM set to %f\n", eta_BSM); printf("parameter m0_BSM set to %f\n", m0_BSM); } #ifdef OMP init_openmp(); #endif tmlqcd_mpi_init(argc, argv); if(g_proc_id==0) { #ifdef SSE printf("# The code was compiled with SSE instructions\n"); #endif #ifdef SSE2 printf("# The code was compiled with SSE2 instructions\n"); #endif #ifdef SSE3 printf("# The code was compiled with SSE3 instructions\n"); #endif #ifdef P4 printf("# The code was compiled for Pentium4\n"); #endif #ifdef OPTERON printf("# The code was compiled for AMD Opteron\n"); #endif #ifdef _GAUGE_COPY printf("# The code was compiled with -D_GAUGE_COPY\n"); #endif #ifdef BGL printf("# The code was compiled for Blue Gene/L\n"); #endif #ifdef BGP printf("# The code was compiled for Blue Gene/P\n"); #endif #ifdef _USE_HALFSPINOR printf("# The code was compiled with -D_USE_HALFSPINOR\n"); #endif #ifdef _USE_SHMEM printf("# The code was compiled with -D_USE_SHMEM\n"); #ifdef _PERSISTENT printf("# The code was compiled for persistent MPI calls (halfspinor only)\n"); #endif #endif #ifdef MPI #ifdef _NON_BLOCKING printf("# The code was compiled for non-blocking MPI calls (spinor and gauge)\n"); #endif #endif printf("\n"); fflush(stdout); } #ifdef _GAUGE_COPY init_gauge_field(VOLUMEPLUSRAND + g_dbw2rand, 1); #else init_gauge_field(VOLUMEPLUSRAND + g_dbw2rand, 0); #endif init_geometry_indices(VOLUMEPLUSRAND + g_dbw2rand); j = init_bispinor_field(VOLUMEPLUSRAND, 12); if ( j!= 0) { fprintf(stderr, "Not enough memory for bispinor fields! Aborting...\n"); exit(0); } j = init_spinor_field(VOLUMEPLUSRAND, 12); if ( j!= 0) { fprintf(stderr, "Not enough memory for spinor fields! Aborting...\n"); exit(0); } int numbScalarFields = 4; j = init_scalar_field(VOLUMEPLUSRAND, numbScalarFields); if ( j!= 0) { fprintf(stderr, "Not enough memory for scalar fields! Aborting...\n"); exit(0); } drvsc = malloc(18*VOLUMEPLUSRAND*sizeof(_Complex double)); if(g_proc_id == 0) { fprintf(stdout,"# The number of processes is %d \n",g_nproc); printf("# The lattice size is %d x %d x %d x %d\n", (int)(T*g_nproc_t), (int)(LX*g_nproc_x), (int)(LY*g_nproc_y), (int)(g_nproc_z*LZ)); printf("# The local lattice size is %d x %d x %d x %d\n", (int)(T), (int)(LX), (int)(LY),(int) LZ); fflush(stdout); } /* define the geometry */ geometry(); j = init_bsm_2hop_lookup(VOLUME); if ( j!= 0) { // this should not be reached since the init function calls fatal_error anyway fprintf(stderr, "Not enough memory for BSM2b 2hop lookup table! Aborting...\n"); exit(0); } /* define the boundary conditions for the fermion fields */ /* for the actual inversion, this is done in invert.c as the operators are iterated through */ // // For the BSM operator we don't use kappa normalisation, // as a result, when twisted boundary conditions are applied this needs to be unity. // In addition, unlike in the Wilson case, the hopping term comes with a plus sign. // However, in boundary(), the minus sign for the Wilson case is implicitly included. // We therefore use -1.0 here. boundary(-1.0); status = check_geometry(); if (status != 0) { fprintf(stderr, "Checking of geometry failed. Unable to proceed.\nAborting....\n"); exit(1); } #if (defined MPI && !(defined _USE_SHMEM)) // fails, we're not using spinor fields // check_xchange(); #endif start_ranlux(1, 123456); // read gauge field if( strcmp(gauge_input_filename, "create_random_gaugefield") == 0 ) { random_gauge_field(reproduce_randomnumber_flag, g_gauge_field); } else { sprintf(conf_filename, "%s.%.4d", gauge_input_filename, nstore); if (g_cart_id == 0) { printf("#\n# Trying to read gauge field from file %s in %s precision.\n", conf_filename, (gauge_precision_read_flag == 32 ? "single" : "double")); fflush(stdout); } int i; if( (i = read_gauge_field(conf_filename,g_gauge_field)) !=0) { fprintf(stderr, "Error %d while reading gauge field from %s\n Aborting...\n", i, conf_filename); exit(-2); } if (g_cart_id == 0) { printf("# Finished reading gauge field.\n"); fflush(stdout); } } // read scalar field if( strcmp(scalar_input_filename, "create_random_scalarfield") == 0 ) { for( int s=0; s<numbScalarFields; s++ ) ranlxd(g_scalar_field[s], VOLUME); } else { sprintf(scalar_filename, "%s.%d", scalar_input_filename, nscalar); if (g_cart_id == 0) { printf("#\n# Trying to read scalar field from file %s in %s precision.\n", scalar_filename, (scalar_precision_read_flag == 32 ? "single" : "double")); fflush(stdout); } int i; if( (i = read_scalar_field(scalar_filename,g_scalar_field)) !=0) { fprintf(stderr, "Error %d while reading scalar field from %s\n Aborting...\n", i, scalar_filename); exit(-2); } if (g_cart_id == 0) { printf("# Finished reading scalar field.\n"); fflush(stdout); } } #ifdef MPI xchange_gauge(g_gauge_field); #endif /*compute the energy of the gauge field*/ plaquette_energy = measure_plaquette( (const su3**) g_gauge_field); if (g_cart_id == 0) { printf("# The computed plaquette value is %e.\n", plaquette_energy / (6.*VOLUME*g_nproc)); fflush(stdout); } #ifdef MPI for( int s=0; s<numbScalarFields; s++ ) generic_exchange(g_scalar_field[s], sizeof(scalar)); #endif /*initialize the bispinor fields*/ j_max=1; sdt=0.; // w random_spinor_field_lexic( (spinor*)(g_bispinor_field[4]), reproduce_randomnumber_flag, RN_GAUSS); random_spinor_field_lexic( (spinor*)(g_bispinor_field[4])+VOLUME, reproduce_randomnumber_flag, RN_GAUSS); // for the D^\dagger test: // v random_spinor_field_lexic( (spinor*)(g_bispinor_field[5]), reproduce_randomnumber_flag, RN_GAUSS); random_spinor_field_lexic( (spinor*)(g_bispinor_field[5])+VOLUME, reproduce_randomnumber_flag, RN_GAUSS); #if defined MPI generic_exchange(g_bispinor_field[4], sizeof(bispinor)); #endif // print L2-norm of source: double squarenorm = square_norm((spinor*)g_bispinor_field[4], 2*VOLUME, 1); if(g_proc_id==0) { printf("\n# square norm of the source: ||w||^2 = %e\n\n", squarenorm); fflush(stdout); } double t_MG, t_BK; /* inversion needs to be done first because it uses loads of the g_bispinor_fields internally */ #if TEST_INVERSION if(g_proc_id==1) printf("Testing inversion\n"); // Bartek's operator t1 = gettime(); cg_her_bi(g_bispinor_field[9], g_bispinor_field[4], 25000, 1.0e-14, 0, VOLUME, &Q2_psi_BSM2b); t_BK = gettime() - t1; // Marco's operator t1 = gettime(); cg_her_bi(g_bispinor_field[8], g_bispinor_field[4], 25000, 1.0e-14, 0, VOLUME, &Q2_psi_BSM2m); t_MG = gettime() - t1; if(g_proc_id==0) printf("Operator inversion time: t_MG = %f sec \t t_BK = %f sec\n\n", t_MG, t_BK); #endif /* now apply the operators to the same bispinor field and do various comparisons */ // Marco's operator #ifdef MPI MPI_Barrier(MPI_COMM_WORLD); #endif t_MG = 0.0; t1 = gettime(); D_psi_BSM2m(g_bispinor_field[0], g_bispinor_field[4]); t1 = gettime() - t1; #ifdef MPI MPI_Allreduce (&t1, &t_MG, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); #else t_MG = t1; #endif // Bartek's operator #ifdef MPI MPI_Barrier(MPI_COMM_WORLD); #endif t_BK = 0.0; t1 = gettime(); D_psi_BSM2b(g_bispinor_field[1], g_bispinor_field[4]); t1 = gettime() - t1; #ifdef MPI MPI_Allreduce (&t1, &t_BK, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); #else t_BK = t1; #endif if(g_proc_id==0) printf("Operator application time: t_MG = %f sec \t t_BK = %f sec\n\n", t_MG, t_BK); squarenorm = square_norm((spinor*)g_bispinor_field[0], 2*VOLUME, 1); if(g_proc_id==0) { printf("# || D_MG w ||^2 = %.16e\n", squarenorm); fflush(stdout); } squarenorm = square_norm((spinor*)g_bispinor_field[1], 2*VOLUME, 1); if(g_proc_id==0) { printf("# || D_BK w ||^2 = %.16e\n\n\n", squarenorm); fflush(stdout); } diff( (spinor*)g_bispinor_field[3], (spinor*)g_bispinor_field[0], (spinor*)g_bispinor_field[1], 2*VOLUME); printf("element-wise difference between (D_BK w) and (D_MG w)\n"); printf("( D_MG w - M_BK w )->sp_up.s0.c0= %.16e + I*(%.16e)\n\n", creal(g_bispinor_field[3][0].sp_up.s0.c0), cimag(g_bispinor_field[3][0].sp_up.s0.c0) ); double diffnorm = square_norm( (spinor*) g_bispinor_field[3], 2*VOLUME, 1 ); if(g_proc_id==0){ printf("Square norm of the difference\n"); printf("|| D_MG w - D_BK w ||^2 = %.16e \n\n\n", diffnorm); } // < D w, v > printf("Check consistency of D and D^dagger\n"); _Complex double prod1_MG = scalar_prod( (spinor*)g_bispinor_field[0], (spinor*)g_bispinor_field[5], 2*VOLUME, 1 ); if(g_proc_id==0) printf("< D_MG w, v > = %.16e + I*(%.16e)\n", creal(prod1_MG), cimag(prod1_MG)); _Complex double prod1_BK = scalar_prod( (spinor*)g_bispinor_field[1], (spinor*)g_bispinor_field[5], 2*VOLUME, 1 ); if(g_proc_id==0) printf("< D_BK w, v > = %.16e + I*(%.16e)\n\n", creal(prod1_BK), cimag(prod1_BK)); // < w, D^\dagger v > t_MG = gettime(); D_psi_dagger_BSM2m(g_bispinor_field[6], g_bispinor_field[5]); t_MG = gettime()-t_MG; t_BK = gettime(); D_psi_dagger_BSM2b(g_bispinor_field[7], g_bispinor_field[5]); t_BK = gettime() - t_BK; if(g_proc_id==0) printf("Operator dagger application time: t_MG = %f sec \t t_BK = %f sec\n\n", t_MG, t_BK); _Complex double prod2_MG = scalar_prod((spinor*)g_bispinor_field[4], (spinor*)g_bispinor_field[6], 2*VOLUME, 1); _Complex double prod2_BK = scalar_prod((spinor*)g_bispinor_field[4], (spinor*)g_bispinor_field[7], 2*VOLUME, 1); if( g_proc_id == 0 ){ printf("< w, D_MG^dagger v > = %.16e + I*(%.16e)\n", creal(prod2_MG), cimag(prod2_MG)); printf("< w, D_BK^dagger v > = %.16e + I*(%.16e)\n", creal(prod2_BK), cimag(prod2_BK)); printf("\n| < D_MG w, v > - < w, D_MG^dagger v > | = %.16e\n",cabs(prod2_MG-prod1_MG)); printf("| < D_BK w, v > - < w, D_BK^dagger v > | = %.16e\n\n",cabs(prod2_BK-prod1_BK)); } #if TEST_INVERSION // check result of inversion Q2_psi_BSM2m(g_bispinor_field[10], g_bispinor_field[8]); Q2_psi_BSM2b(g_bispinor_field[11], g_bispinor_field[8]); assign_diff_mul((spinor*)g_bispinor_field[10], (spinor*)g_bispinor_field[4], 1.0, 2*VOLUME); assign_diff_mul((spinor*)g_bispinor_field[11], (spinor*)g_bispinor_field[4], 1.0, 2*VOLUME); double squarenorm_MGMG = square_norm((spinor*)g_bispinor_field[10], 2*VOLUME, 1); double squarenorm_BKMG = square_norm((spinor*)g_bispinor_field[11], 2*VOLUME, 1); if(g_proc_id==0) { printf("# ||Q2_MG*(Q2_MG)^-1*(b)-b||^2 = %.16e\n\n", squarenorm_MGMG); printf("# ||Q2_BK*(Q2_MG)^-1*(b)-b||^2 = %.16e\n\n", squarenorm_BKMG); fflush(stdout); } Q2_psi_BSM2b(g_bispinor_field[10], g_bispinor_field[9]); Q2_psi_BSM2m(g_bispinor_field[11], g_bispinor_field[9]); assign_diff_mul((spinor*)g_bispinor_field[10], (spinor*)g_bispinor_field[4], 1.0, 2*VOLUME); assign_diff_mul((spinor*)g_bispinor_field[11], (spinor*)g_bispinor_field[4], 1.0, 2*VOLUME); double squarenorm_BKBK = square_norm((spinor*)g_bispinor_field[10], 2*VOLUME, 1); double squarenorm_MGBK = square_norm((spinor*)g_bispinor_field[11], 2*VOLUME, 1); if(g_proc_id==0) { printf("# ||Q2_BK*(Q2_BK)^-1*(b)-b||^2 = %.16e\n\n", squarenorm_BKBK); printf("# ||Q2_MG*(Q2_BK)^-1*(b)-b||^2 = %.16e\n\n", squarenorm_MGBK); fflush(stdout); } #endif #ifdef OMP free_omp_accumulators(); #endif free_gauge_field(); free_geometry_indices(); free_bispinor_field(); free_scalar_field(); #ifdef MPI MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); #endif return(0); }
void reweighting_factor(const int N, const int nstore) { int n = VOLUME; monomial * mnl; FILE * ofs; hamiltonian_field_t hf; hf.gaugefield = g_gauge_field; hf.momenta = NULL; hf.derivative = NULL; hf.update_gauge_copy = g_update_gauge_copy; double * data = (double*)calloc(no_monomials*N, sizeof(double)); double * trlog = (double*)calloc(no_monomials, sizeof(double)); // we compute the trlog part first, because they are independent of // stochastic noise. This is only needed for even/odd monomials for(int j = 0; j < no_monomials; j++) { mnl = &monomial_list[j]; if(mnl->even_odd_flag) { init_sw_fields(); double c_sw = mnl->c_sw; if(c_sw < 0.) c_sw = 0.; sw_term( (const su3**) hf.gaugefield, mnl->kappa, c_sw); if(mnl->type != NDDETRATIO) { trlog[j] = -sw_trace(0, mnl->mu); } else { trlog[j] = -sw_trace_nd(0, mnl->mubar, mnl->epsbar); } sw_term( (const su3**) hf.gaugefield, mnl->kappa2, c_sw); if(mnl->type != NDDETRATIO) { trlog[j] -= -sw_trace(0, mnl->mu2); } else { trlog[j] -= -sw_trace_nd(0, mnl->mubar2, mnl->epsbar2); } } else { trlog[j] = 0.; } if(g_proc_id == 0 && g_debug_level > 0) { printf("# monomial[%d] %s, trlog = %e\n", j, mnl->name, trlog[j]); } } for(int i = 0; i < N; i++) { if(g_proc_id == 0 && g_debug_level > 0) { printf("# computing reweighting factors for sample %d\n", i); } for(int j = 0; j < no_monomials; j++) { mnl = &monomial_list[j]; if(mnl->type != GAUGE) { if(mnl->even_odd_flag) { random_spinor_field_eo(mnl->pf, mnl->rngrepro, RN_GAUSS); mnl->energy0 = square_norm(mnl->pf, n/2, 1); } else { random_spinor_field_lexic(mnl->pf, mnl->rngrepro, RN_GAUSS); mnl->energy0 = square_norm(mnl->pf, n, 1); } if(g_proc_id == 0 && g_debug_level > 1) { printf("# monomial[%d] %s, energy0 = %e\n", j, mnl->name, mnl->energy0); } if(mnl->type == NDDETRATIO) { if(mnl->even_odd_flag) { random_spinor_field_eo(mnl->pf2, mnl->rngrepro, RN_GAUSS); mnl->energy0 += square_norm(mnl->pf, n/2, 1); } else { random_spinor_field_lexic(mnl->pf, mnl->rngrepro, RN_GAUSS); mnl->energy0 += square_norm(mnl->pf2, n, 1); } } } } for(int j = 0; j < no_monomials; j++) { mnl = &monomial_list[j]; if(mnl->type != GAUGE) { double y = mnl->accfunction(j, &hf); data[i*no_monomials + j] = y; if(g_proc_id == 0 && g_debug_level > 0) { printf("# monomial[%d] %s, stochastic part: w_%d=%e exp(w_%d)=%e\n", j, mnl->name, j, j, y, exp(y)); } } } } if(g_proc_id == 0) { char filename[50]; sprintf(filename, "reweighting_factor.data.%.5d", nstore); if((ofs = fopen(filename, "w")) == NULL) { fatal_error("Could not open file for data output", "reweighting_factor"); } else { for(int j = 0; j < no_monomials; j++) { mnl = &monomial_list[j]; for(int i = 0; i < N; i++) { fprintf(ofs, "%.2d %.5d %e %e %e %e %.10e\n", j, i, mnl->kappa, mnl->kappa2, mnl->mu, mnl->mu2, data[i*no_monomials + j] + trlog[j]); } } fclose(ofs); } } free(data); free(trlog); }
int main(int argc,char *argv[]) { int j,j_max,k,k_max = 1; #ifdef HAVE_LIBLEMON paramsXlfInfo *xlfInfo; #endif int status = 0; static double t1,t2,dt,sdt,dts,qdt,sqdt; double antioptaway=0.0; #ifdef TM_USE_MPI static double dt2; DUM_DERI = 6; DUM_MATRIX = DUM_DERI+8; NO_OF_SPINORFIELDS = DUM_MATRIX+2; # ifdef TM_USE_OMP int mpi_thread_provided; MPI_Init_thread(&argc, &argv, MPI_THREAD_SERIALIZED, &mpi_thread_provided); # else MPI_Init(&argc, &argv); # endif MPI_Comm_rank(MPI_COMM_WORLD, &g_proc_id); #else g_proc_id = 0; #endif g_rgi_C1 = 1.; /* Read the input file */ if((status = read_input("benchmark.input")) != 0) { fprintf(stderr, "Could not find input file: benchmark.input\nAborting...\n"); exit(-1); } #ifdef TM_USE_OMP init_openmp(); #endif tmlqcd_mpi_init(argc, argv); if(g_proc_id==0) { #ifdef SSE printf("# The code was compiled with SSE instructions\n"); #endif #ifdef SSE2 printf("# The code was compiled with SSE2 instructions\n"); #endif #ifdef SSE3 printf("# The code was compiled with SSE3 instructions\n"); #endif #ifdef P4 printf("# The code was compiled for Pentium4\n"); #endif #ifdef OPTERON printf("# The code was compiled for AMD Opteron\n"); #endif #ifdef _GAUGE_COPY printf("# The code was compiled with -D_GAUGE_COPY\n"); #endif #ifdef BGL printf("# The code was compiled for Blue Gene/L\n"); #endif #ifdef BGP printf("# The code was compiled for Blue Gene/P\n"); #endif #ifdef _USE_HALFSPINOR printf("# The code was compiled with -D_USE_HALFSPINOR\n"); #endif #ifdef _USE_SHMEM printf("# The code was compiled with -D_USE_SHMEM\n"); # ifdef _PERSISTENT printf("# The code was compiled for persistent MPI calls (halfspinor only)\n"); # endif #endif #ifdef TM_USE_MPI # ifdef _NON_BLOCKING printf("# The code was compiled for non-blocking MPI calls (spinor and gauge)\n"); # endif #endif printf("\n"); fflush(stdout); } #ifdef _GAUGE_COPY init_gauge_field(VOLUMEPLUSRAND + g_dbw2rand, 1); #else init_gauge_field(VOLUMEPLUSRAND + g_dbw2rand, 0); #endif init_geometry_indices(VOLUMEPLUSRAND + g_dbw2rand); if(even_odd_flag) { j = init_spinor_field(VOLUMEPLUSRAND/2, 2*k_max+1); } else { j = init_spinor_field(VOLUMEPLUSRAND, 2*k_max); } if ( j!= 0) { fprintf(stderr, "Not enough memory for spinor fields! Aborting...\n"); exit(0); } j = init_moment_field(VOLUME, VOLUMEPLUSRAND + g_dbw2rand); if ( j!= 0) { fprintf(stderr, "Not enough memory for moment fields! Aborting...\n"); exit(0); } if(g_proc_id == 0) { fprintf(stdout,"# The number of processes is %d \n",g_nproc); printf("# The lattice size is %d x %d x %d x %d\n", (int)(T*g_nproc_t), (int)(LX*g_nproc_x), (int)(LY*g_nproc_y), (int)(g_nproc_z*LZ)); printf("# The local lattice size is %d x %d x %d x %d\n", (int)(T), (int)(LX), (int)(LY),(int) LZ); if(even_odd_flag) { printf("# benchmarking the even/odd preconditioned Dirac operator\n"); } else { printf("# benchmarking the standard Dirac operator\n"); } fflush(stdout); } /* define the geometry */ geometry(); /* define the boundary conditions for the fermion fields */ boundary(g_kappa); #ifdef _USE_HALFSPINOR j = init_dirac_halfspinor(); if ( j!= 0) { fprintf(stderr, "Not enough memory for halfspinor fields! Aborting...\n"); exit(0); } if(g_sloppy_precision_flag == 1) { g_sloppy_precision = 1; j = init_dirac_halfspinor32(); if ( j!= 0) { fprintf(stderr, "Not enough memory for 32-Bit halfspinor fields! Aborting...\n"); exit(0); } } # if (defined _PERSISTENT) init_xchange_halffield(); # endif #endif status = check_geometry(); if (status != 0) { fprintf(stderr, "Checking of geometry failed. Unable to proceed.\nAborting....\n"); exit(1); } #if (defined TM_USE_MPI && !(defined _USE_SHMEM)) check_xchange(); #endif start_ranlux(1, 123456); random_gauge_field(reproduce_randomnumber_flag, g_gauge_field); #ifdef TM_USE_MPI /*For parallelization: exchange the gaugefield */ xchange_gauge(g_gauge_field); #endif if(even_odd_flag) { sdt=0.; sqdt=0.0; /*initialize the pseudo-fermion fields*/ for (k = 0; k < k_max; k++) { random_spinor_field_eo(g_spinor_field[k], reproduce_randomnumber_flag, RN_GAUSS); } j_max=512; antioptaway=0.0; /* compute approximately how many applications we need to do to get a reliable measurement */ #ifdef TM_USE_MPI MPI_Barrier(MPI_COMM_WORLD); #endif t1 = gettime(); for (j=0;j<j_max;j++) { for (k=0;k<k_max;k++) { Hopping_Matrix(0, g_spinor_field[k+k_max], g_spinor_field[k]); Hopping_Matrix(1, g_spinor_field[2*k_max], g_spinor_field[k+k_max]); antioptaway+=creal(g_spinor_field[2*k_max][0].s0.c0); } } dt = gettime()-t1; // division by g_nproc because we will average over processes j = (int)(ceil(j_max*31.0/dt/g_nproc)); #ifdef TM_USE_MPI MPI_Allreduce(&j,&j_max, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); #else j_max = j; #endif /* perform the actual benchmark */ #ifdef TM_USE_MPI MPI_Barrier(MPI_COMM_WORLD); #endif t1 = gettime(); antioptaway=0.0; for (j=0;j<j_max;j++) { for (k=0;k<k_max;k++) { Hopping_Matrix(0, g_spinor_field[k+k_max], g_spinor_field[k]); Hopping_Matrix(1, g_spinor_field[2*k_max], g_spinor_field[k+k_max]); antioptaway+=creal(g_spinor_field[2*k_max][0].s0.c0); } } dt = gettime()-t1; #ifdef TM_USE_MPI MPI_Allreduce (&dt, &sdt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); #else sdt = dt; #endif qdt=dt*dt; #ifdef TM_USE_MPI MPI_Allreduce (&qdt, &sqdt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); #else sqdt = qdt; #endif sdt=sdt/((double)g_nproc); sqdt=sqrt(sqdt/g_nproc-sdt*sdt); dts=dt; sdt=1.0e6f*sdt/((double)(k_max*j_max*(VOLUME))); sqdt=1.0e6f*sqdt/((double)(k_max*j_max*(VOLUME))); if(g_proc_id==0) { printf("# The following result is just to make sure that the calculation is not optimized away: %e\n", antioptaway); printf("# Total compute time %e sec, variance of the time %e sec. (%d iterations).\n", sdt, sqdt, j_max); #ifdef TM_USE_MPI printf("# Communication switched on: \n"); #endif printf("\n%12d Mflops(total) %8d Mflops(process)", (int)(g_nproc*1608.0f/sdt),(int)(1608.0f/sdt)); #ifdef TM_USE_OMP printf(" %8d Mflops(thread)",(int)(1608.0f/(omp_num_threads*sdt))); #endif printf(" [ %d bit arithmetic ]\n\n",(int)(sizeof(spinor)/3)); fflush(stdout); } #ifdef TM_USE_MPI /* isolated computation */ t1 = gettime(); antioptaway=0.0; for (j=0;j<j_max;j++) { for (k=0;k<k_max;k++) { Hopping_Matrix_nocom(0, g_spinor_field[k+k_max], g_spinor_field[k]); Hopping_Matrix_nocom(1, g_spinor_field[2*k_max], g_spinor_field[k+k_max]); antioptaway += creal(g_spinor_field[2*k_max][0].s0.c0); } } t2 = gettime(); dt2 = t2-t1; /* compute the bandwidth */ dt=dts-dt2; MPI_Allreduce (&dt, &sdt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); sdt=sdt/((double)g_nproc); MPI_Allreduce (&dt2, &dt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); dt=dt/((double)g_nproc); dt=1.0e6f*dt/((double)(k_max*j_max*(VOLUME))); if(g_proc_id==0) { printf("# The following result is printed just to make sure that the calculation is not optimized away: %e\n",antioptaway); printf("# Communication switched off: \n\n%12d Mflops(total) %8d Mflops(process)", (int)(g_nproc*1608.0f/dt),(int)(1608.0f/dt)); #ifdef TM_USE_OMP printf(" %8d Mflops(thread)",(int)(1608.0f/(omp_num_threads*dt))); #endif printf(" [ %d bit arithmetic ]\n\n",(int)(sizeof(spinor)/3)); fflush(stdout); } sdt=sdt/((double)k_max); sdt=sdt/((double)j_max); sdt=sdt/((double)(2*SLICE)); if(g_proc_id==0) { printf("# The size of the package is %d bytes.\n",(SLICE)*192); #ifdef _USE_HALFSPINOR printf("# The bandwidth is %5.2f + %5.2f MB/sec\n", 192./sdt/1024/1024, 192./sdt/1024./1024); #else printf("# The bandwidth is %5.2f + %5.2f MB/sec\n", 2.*192./sdt/1024/1024, 2.*192./sdt/1024./1024); #endif } #endif fflush(stdout); } else { /* the non even/odd case now */ /*initialize the pseudo-fermion fields*/ j_max=128; sdt=0.; for (k=0;k<k_max;k++) { random_spinor_field_lexic(g_spinor_field[k], reproduce_randomnumber_flag, RN_GAUSS); } /* estimate a reasonable number of applications to get a reliable measurement */ #ifdef TM_USE_MPI MPI_Barrier(MPI_COMM_WORLD); #endif t1 = gettime(); for (j=0;j<j_max;j++) { for (k=0;k<k_max;k++) { D_psi(g_spinor_field[k+k_max], g_spinor_field[k]); antioptaway+=creal(g_spinor_field[k+k_max][0].s0.c0); } } t2 = gettime(); dt=t2-t1; // division by g_nproc because we will average over processes using MPI_SUM j = (int)(ceil(j_max*31.0/dt/g_nproc)); #ifdef TM_USE_MPI MPI_Allreduce(&j,&j_max, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); #else j_max = j; #endif /* perform the actual measurement */ #ifdef TM_USE_MPI MPI_Barrier(MPI_COMM_WORLD); #endif t1 = gettime(); for (j=0;j<j_max;j++) { for (k=0;k<k_max;k++) { D_psi(g_spinor_field[k+k_max], g_spinor_field[k]); antioptaway+=creal(g_spinor_field[k+k_max][0].s0.c0); } } t2 = gettime(); dt=t2-t1; #ifdef TM_USE_MPI MPI_Allreduce (&dt, &sdt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); #else sdt = dt; #endif qdt=dt*dt; #ifdef TM_USE_MPI MPI_Allreduce (&qdt, &sqdt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); #else sqdt = qdt; #endif sdt=sdt/((double)g_nproc); sqdt=sqrt(sqdt/g_nproc-sdt*sdt); dts=dt; sdt=1.0e6f*sdt/((double)(k_max*j_max*(VOLUME))); sqdt=1.0e6f*sqdt/((double)(k_max*j_max*(VOLUME))); if(g_proc_id==0) { printf("# The following result is just to make sure that the calculation is not optimized away: %e\n", antioptaway); printf("# Total compute time %e sec, variance of the time %e sec. (%d iterations).\n\n", sdt, sqdt, j_max); printf(" %12d Mflops(total) %8d Mflops(process)", (int)(1680.0f*g_nproc/sdt),(int)(1680.0f/sdt)); #ifdef TM_USE_OMP printf(" %8d Mflops(thread)",(int)(1680.0f/(omp_num_threads*sdt))); #endif printf(" [ %d bit arithmetic ]\n\n",(int)(sizeof(spinor)/3)); fflush(stdout); } } #ifdef HAVE_LIBLEMON if(g_proc_id==0) { printf("# Performing parallel IO test ...\n"); } xlfInfo = construct_paramsXlfInfo(0.5, 0); write_gauge_field( "conf.test", 64, xlfInfo); free(xlfInfo); if(g_proc_id==0) { printf("# done ...\n"); } #endif #ifdef TM_USE_OMP free_omp_accumulators(); #endif free_gauge_field(); free_geometry_indices(); free_spinor_field(); free_moment_field(); #ifdef TM_USE_MPI MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); #endif return(0); }