MUST COMPILE WITH QIO FOR THE SCRATCH FILE #endif /* Comment these out if you want to suppress detailed timing */ /*#define IOTIME*/ /*#define PRTIME*/ int main(int argc, char *argv[]) { int meascount; int prompt; Real avm_iters,avs_iters; double starttime,endtime; #ifdef IOTIME double dtime; int iotime = 1; #else int iotime = 0; #endif int MinCG,MaxCG; Real RsdCG, RRsdCG; int spin,color,j,k; int flag; int status; w_prop_file *fp_in_w[MAX_KAP]; /* For reading binary propagator files */ w_prop_file *fp_out_w[MAX_KAP]; /* For writing binary propagator files */ w_prop_file *fp_scr[MAX_KAP]; quark_source wqs_scr; /* scratch file */ char scratch_file[MAX_KAP][MAXFILENAME]; wilson_vector *psi = NULL; wilson_prop_field *quark_propagator = NULL; wilson_prop_field *quark_prop2 = NULL; int cg_cl = CL_CG; int source_type; initialize_machine(&argc,&argv); /* Remap standard I/O */ if(remap_stdio_from_args(argc, argv) == 1)terminate(1); g_sync(); /* set up */ prompt = setup_cl(); /* loop over input sets */ psi = create_wv_field(); quark_propagator = create_wp_field(3); quark_prop2 = create_wp_field(3); while( readin(prompt) == 0) { starttime=dclock(); MaxCG=niter; avm_iters=0.0; meascount=0; spectrum_cl_hl_init(); if( fixflag == COULOMB_GAUGE_FIX) { if(this_node == 0) printf("Fixing to Coulomb gauge\n"); #ifdef IOTIME dtime = -dclock(); #endif gaugefix(TUP,(Real)1.5,500,GAUGE_FIX_TOL); #ifdef IOTIME dtime += dclock(); if(this_node==0)printf("Time to gauge fix = %e\n",dtime); #endif invalidate_this_clov(gen_clov); } else if(this_node == 0)printf("COULOMB GAUGE FIXING SKIPPED.\n"); /* save lattice if requested */ if( saveflag != FORGET ){ savelat_p = save_lattice( saveflag, savefile, stringLFN ); } if(this_node==0)printf("END OF HEADER\n"); /* if(this_node==0) printf("num_kap = %d\n", num_kap); */ /* Loop over kappas to compute and store quark propagator */ for(k=0;k<num_kap;k++){ kappa=kap[k]; RsdCG=resid[k]; RRsdCG=relresid[k]; if(this_node==0)printf("Kappa= %g r0= %g residue= %g rel= %g\n", (double)kappa,(double)wqs.r0,(double)RsdCG, (double)RRsdCG); /* open files for wilson propagators */ #ifdef IOTIME dtime = -dclock(); #endif wqstmp = wqs; /* For clover_info.c */ fp_in_w[k] = r_open_wprop(startflag_w[k], startfile_w[k]); fp_out_w[k] = w_open_wprop(saveflag_w[k], savefile_w[k], wqs.type); #ifdef IOTIME dtime += dclock(); if(startflag_w[k] != FRESH) node0_printf("Time to open prop = %e\n",dtime); #endif /* Open scratch file and write header */ sprintf(scratch_file[k],"%s_%02d",scratchstem_w,k); source_type = UNKNOWN; fp_scr[k] = w_open_wprop(scratchflag, scratch_file[k], source_type); init_qs(&wqs_scr); /* Loop over source spins */ for(spin=0;spin<4;spin++){ /* Loop over source colors */ for(color=0;color<3;color++){ meascount ++; /*if(this_node==0)printf("color=%d spin=%d\n",color,spin);*/ if(startflag_w[k] == CONTINUE) { if(k == 0) { node0_printf("Can not continue propagator here! Zeroing it instead\n"); startflag_w[k] = FRESH; } else { copy_wv_from_wp(psi, quark_propagator, color, spin); } } /* Saves one multiplication by zero in cgilu */ if(startflag_w[k] == FRESH)flag = 0; else flag = 1; /* load psi if requested */ status = reload_wprop_sc_to_field( startflag_w[k], fp_in_w[k], &wqs, spin, color, psi, iotime); if(status != 0) { node0_printf("control_cl_hl: Recovering from error by resetting initial guess to zero\n"); reload_wprop_sc_to_field( FRESH, fp_in_w[k], &wqs, spin, color, psi,0); flag = 0; } /* Complete the source structure */ wqs.color = color; wqs.spin = spin; /* If we are starting afresh, we set a minimum number of iterations */ if(startflag_w[k] == FRESH || status != 0)MinCG = nt/2; else MinCG = 0; /* Load inversion control structure */ qic.prec = PRECISION; qic.min = 0; qic.max = MaxCG; qic.nrestart = nrestart; qic.parity = EVENANDODD; qic.start_flag = flag; qic.nsrc = 1; qic.resid = RsdCG; qic.relresid = RRsdCG; /* Load Dirac matrix parameters */ dcp.Kappa = kappa; dcp.Clov_c = clov_c; dcp.U0 = u0; switch (cg_cl) { case BICG: avs_iters = (Real)wilson_invert_field_wqs(&wqs, w_source_field, psi, bicgilu_cl_field, &qic,(void *)&dcp); break; case HOP: avs_iters = (Real)wilson_invert_field_wqs(&wqs, w_source_field, psi, hopilu_cl_field, &qic,(void *)&dcp); break; case MR: avs_iters = (Real)wilson_invert_field_wqs(&wqs, w_source_field, psi, mrilu_cl_field, &qic,(void *)&dcp); break; case CG: avs_iters = (Real)wilson_invert_field_wqs(&wqs, w_source_field, psi, cgilu_cl_field, &qic,(void *)&dcp); break; default: node0_printf("main(%d): Inverter choice %d not supported\n", cg_cl, this_node); } avm_iters += avs_iters; copy_wp_from_wv(quark_propagator, psi, color, spin); /* Write psi to scratch disk */ #ifdef IOTIME dtime = -dclock(); #endif save_wprop_sc_from_field(scratchflag, fp_scr[k], &wqs_scr, spin, color, psi, "Scratch record", iotime); #ifdef IOTIME dtime += dclock(); if(this_node==0) printf("Time to dump prop spin %d color %d %e\n", spin,color,dtime); #endif /* save psi if requested */ save_wprop_sc_from_field( saveflag_w[k],fp_out_w[k], &wqs, spin,color,psi,"", iotime); } /* source colors */ } /* source spins */ /* Close and release scratch file */ w_close_wprop(scratchflag, fp_scr[k]); /*if(this_node==0)printf("Dumped prop to file %s\n", scratch_file[k]); */ /* close files for wilson propagators */ #ifdef IOTIME dtime = -dclock(); #endif r_close_wprop(startflag_w[k],fp_in_w[k]); w_close_wprop(saveflag_w[k],fp_out_w[k]); #ifdef IOTIME dtime += dclock(); if(saveflag_w[k] != FORGET) node0_printf("Time to close prop = %e\n",dtime); #endif } /* kappas */ /* Loop over heavy kappas for the point sink spectrum */ for(k=0;k<num_kap;k++){ /* Read the propagator from the scratch file */ #ifdef IOTIME dtime = -dclock(); #endif kappa=kap[k]; init_qs(&wqs_scr); reload_wprop_to_wp_field(scratchflag, scratch_file[k], &wqs_scr, quark_propagator, iotime); #ifdef IOTIME dtime += dclock(); if(this_node==0) { printf("Time to read 12 spin,color combinations %e\n",dtime); fflush(stdout); } #endif /*if(this_node==0) printf("Closed scratch file %s\n",scratch_file[k]); fflush(stdout); */ /* Diagonal spectroscopy */ spectrum_cl_hl_diag_baryon(quark_propagator, k); spectrum_cl_hl_diag_meson(quark_propagator, k); spectrum_cl_hl_diag_rot_meson(quark_propagator, k); if(strstr(spectrum_request,",sink_smear,") != NULL){ spectrum_cl_hl_diag_smeared_meson(quark_propagator, k); } /* Heavy-light spectroscopy */ /* Loop over light kappas for the point sink spectrum */ for(j=k+1;j<num_kap;j++){ #ifdef IOTIME dtime = -dclock(); #endif /* Read the propagator from the scratch file */ kappa=kap[j]; init_qs(&wqs_scr); reload_wprop_to_wp_field(scratchflag, scratch_file[j], &wqs_scr, quark_prop2, iotime); #ifdef IOTIME dtime += dclock(); if(this_node==0) { printf("Time to read 12 spin,color combinations %e\n",dtime); fflush(stdout); } #endif #ifdef PRTIME dtime = -dclock(); #endif spectrum_cl_hl_offdiag_baryon( quark_propagator, quark_prop2, j, k); spectrum_cl_hl_offdiag_meson( quark_propagator, quark_prop2, j, k); spectrum_cl_hl_offdiag_rot_meson( quark_propagator, quark_prop2, j, k); #ifdef PRTIME dtime = -dclock(); #endif } /* light kappas */ /* Smear the heavy propagator in place */ sink_smear_prop( quark_propagator ); /* Write the smeared propagator to the scratch file (overwriting)*/ kappa=kap[k]; #ifdef IOTIME dtime = -dclock(); #endif save_wprop_from_wp_field(scratchflag, scratch_file[k], &wqs_scr, quark_propagator, "Scratch propagator", iotime); #ifdef IOTIME dtime += dclock(); if(this_node==0) { printf("Time to dump convolution %d %e\n",k,dtime); fflush(stdout); } #endif } /* heavy kappas */ /* Loop over heavy kappas for the shell sink spectrum */ if(strstr(spectrum_request,",sink_smear,") != NULL) for(k=0;k<num_kap;k++){ #ifdef IOTIME dtime = -dclock(); #endif /* Read the propagator from the scratch file */ kappa=kap[k]; init_qs(&wqs_scr); reload_wprop_to_wp_field(scratchflag, scratch_file[k], &wqs_scr, quark_propagator, iotime); #ifdef IOTIME dtime += dclock(); if(this_node==0) { printf("Time to read convolution %d %e\n",k,dtime); fflush(stdout); } #endif /* Diagonal spectroscopy */ spectrum_cl_hl_diag_smeared_meson(quark_propagator, k); /* Heavy-light spectroscopy */ /* Loop over light kappas for the shell sink spectrum */ for(j=k+1;j<num_kap;j++){ #ifdef PRTIME dtime = -dclock(); #endif /* Read the propagator from the scratch file */ kappa=kap[j]; init_qs(&wqs_scr); reload_wprop_to_wp_field(scratchflag, scratch_file[j], &wqs_scr, quark_prop2, iotime); /* Compute the spectrum */ spectrum_cl_hl_offdiag_smeared_meson( quark_propagator, quark_prop2, j, k); #ifdef PRTIME dtime += dclock(); if(this_node==0) { printf("Time to read and do off diagonal mesons %d %d %e\n", j,k,dtime); fflush(stdout); } #endif } /* light kappas */ } /* heavy kappas */ spectrum_cl_hl_print(wqs.t0); spectrum_cl_hl_cleanup(); if(this_node==0)printf("RUNNING COMPLETED\n"); if(meascount>0){ if(this_node==0)printf("total cg iters for measurement= %e\n", (double)avm_iters); if(this_node==0)printf("cg iters for measurement= %e\n", (double)avm_iters/(double)meascount); } endtime=dclock(); if(this_node==0){ printf("Time = %e seconds\n",(double)(endtime-starttime)); printf("total_iters = %d\n",total_iters); } fflush(stdout); } destroy_wv_field(psi); destroy_wp_field(quark_propagator); return 0; }
int solve_ksprop(int num_prop, int startflag[], char startfile[][MAXFILENAME], int saveflag[], char savefile[][MAXFILENAME], ks_prop_field *ksprop[], quark_source *my_ksqs, quark_invert_control my_qic[], ks_param my_ksp[], Real charge, Real bdry_phase[], int r0[4], int check) { int color; int i,j; int status = 0; char *fileinfo; int tot_iters = 0; ks_prop_file *fp_in[MAX_PROP], *fp_out[MAX_PROP]; su3_vector **dst, *src; imp_ferm_links_t **fn = NULL; Real mybdry_phase[4]; imp_ferm_links_t **fn_multi = NULL; int n_naiks = fermion_links_get_n_naiks(fn_links); char myname[] = "solve_ksprop"; /* Local copy of bdry_phase */ for(i = 0; i < 4; i++) mybdry_phase[i] = bdry_phase[i]; /* Offset for setting the staggered phases in FN links. They can be different for each propagator NO, they must be the same! */ // r0[0] = my_ksqs->x0; // r0[1] = my_ksqs->y0; // r0[2] = my_ksqs->z0; // r0[3] = my_ksqs->t0; ksqstmp = *my_ksqs; /* For ksprop_info. Source is common to the set */ ksptmp = my_ksp[0]; /* For action parameters */ /* Open files for KS propagators, if requested */ for(j = 0; j < num_prop; j++){ fp_in[j] = r_open_ksprop(startflag[j], startfile[j]); fp_out[j] = w_open_ksprop(saveflag[j], savefile[j], VECTOR_FIELD_FILE); } /* Provision for writing the source to a file */ if(my_ksqs->saveflag != FORGET){ fileinfo = create_ks_XML(); w_source_open_ks(my_ksqs, fileinfo); free(fileinfo); } /* Construct fermion links if we will need them */ if(check != CHECK_NO || startflag[0] == FRESH ){ #ifdef U1_FIELD /* Apply U(1) phases if we are using it */ u1phase_on(charge, u1_A); invalidate_fermion_links(fn_links); #endif restore_fermion_links_from_site(fn_links, my_qic[0].prec); fn = get_fm_links(fn_links); /* Apply twisted boundary conditions and move KS phases and time boundary to new origin r0, if requested */ /* This operation applies the phase to the boundary FN links */ for(j = 0; j < n_naiks; j++){ set_boundary_twist_fn(fn[j], mybdry_phase, r0); boundary_twist_fn(fn[j], ON); } /* Apply twist to the APE links */ /* They do not carry the KS phases, but they do carry an antiperiodic bc */ /* This operation applies the phase to the volume */ // mybdry_phase[3] = 0; // momentum_twist_links(mybdry_phase, 1, ape_links); // mybdry_phase[3] = bdry_phase[3]; boundary_twist_field( mybdry_phase, r0, 1, ape_links); /* Copy pointers for fermion links, based on Naik epsilon indices */ fn_multi = (imp_ferm_links_t **) malloc(sizeof(imp_ferm_links_t *)*num_prop); for(j = 0; j < num_prop; j++) fn_multi[j] = fn[my_ksp[j].naik_term_epsilon_index]; } /* Check (or produce) the solution if requested */ for(color = 0; color < my_ksqs->ncolor; color++){ node0_printf("%s: color = %d\n",myname, color); /* Load the propagators */ for(j = 0; j < num_prop; j++){ status = reload_ksprop_c_to_field(startflag[j], fp_in[j], my_ksqs, color, ksprop[j]->v[color], 1); if(status != 0){ node0_printf("Failed to reload propagator\n"); terminate(1); } } /* Solve for the propagator if the starting guess is zero or we didn't say not to solve. */ if(check != CHECK_NO || startflag[0] == FRESH){ /* Create the source common to this inversion */ src = create_v_field(); if(v_source_field(src, my_ksqs)){ printf("%s(%d): error getting source\n",myname,this_node); terminate(1); }; /* Cache the source for writing to the propagator file */ if(my_ksqs->saveflag != FORGET){ alloc_cached_v_source(my_ksqs); copy_v_field(my_ksqs->v_src, src); } /* Write the source, if requested */ if(my_ksqs->saveflag != FORGET){ if(w_source_ks( src, my_ksqs ) != 0){ node0_printf("Error writing source\n"); } } /* Make a list of num_prop solution pointers for the current color */ dst = (su3_vector **)malloc(num_prop*sizeof(su3_vector *)); for(j = 0; j < num_prop; j++){ dst[j] = ksprop[j]->v[color]; } if(check != CHECK_SOURCE_ONLY){ /* Apply the momentum twist to the source. This U(1) gauge transformation converts the boundary twist on the gauge field above into the desired volume twist. We do it this way to make our coding compatible with QOP, which does only a surface twist. */ /* The time phase is special. It is applied only on the boundary, so we don't gauge-transform it to the volume here. It is used only for switching between periodic and antiperiodic bc's */ mybdry_phase[3] = 0; rephase_v_field(src, mybdry_phase, r0, 1); mybdry_phase[3] = bdry_phase[3]; if(startflag[0] != FRESH){ /* Apply the momentum twist to the initial guess */ mybdry_phase[3] = 0; for(j = 0; j < num_prop; j++){ rephase_v_field(dst[j], mybdry_phase, r0, 1); } mybdry_phase[3] = bdry_phase[3]; } if(num_prop == 1){ /* Single mass inversion */ if(startflag[0] == FRESH) my_qic[0].start_flag = START_ZERO_GUESS; else my_qic[0].start_flag = START_NONZERO_GUESS; /* When we start from a preloaded solution we use the less optimized mat_invert_cg_field algorithm, instead of mat_invert_uml_field here to avoid "reconstructing", and so overwriting the odd-site solution. This would be a degradation if the propagator was precomputed in double precision, and we were doing single precision here. When we are computing the propagator from a fresh start, we use the optimized mat_invert_uml_field algorithm. */ if(startflag[0] == FRESH){ tot_iters += mat_invert_uml_field(src, dst[0], my_qic+0, my_ksp[0].mass, fn_multi[0]); } else { tot_iters += mat_invert_cg_field(src, dst[0], my_qic+0, my_ksp[0].mass, fn_multi[0]); } } else { /* Multimass inversion */ tot_iters = mat_invert_multi(src, dst, my_ksp, num_prop, my_qic, fn_multi); } /* Transform solution, completing the U(1) gauge transformation */ mybdry_phase[3] = 0; for(j = 0; j < num_prop; j++){ rephase_v_field(dst[j], mybdry_phase, r0, -1); } mybdry_phase[3] = bdry_phase[3]; } else { /* if(check != CHECK_SOURCE_ONLY) */ /* Copy source to solution(s) so we can use it there */ for(j = 0; j < num_prop; j++) copy_v_field(dst[j], src); } /* save solutions if requested */ for(i = 0; i < num_prop; i++){ status = save_ksprop_c_from_field( saveflag[i], fp_out[i], my_ksqs, color, dst[i], "", 1); if(status != 0){ node0_printf("Failed to write propagator\n"); terminate(1); } } #ifdef DEBUG_NAIVE rephase( OFF ); for(i = 0; i < num_prop; i++) { spin_wilson_vector *swv = create_swv_field(); wilson_vector *wv = create_wv_field(); wilson_vector *wvsrc = create_wv_field(); su3_vector *v = create_v_field(); int ks_source_r[4] = {0,0,0,0}; /* Hypercube corners */ int spin; convert_ksprop_to_wprop_swv(swv, dst[i], ks_source_r, r0); for(spin = 0; spin < 4; spin++){ copy_wv_from_swv(wv, swv, spin); clear_wv_field(wvsrc); copy_wv_from_v(wvsrc, src, spin); check_naive(wv, wvsrc, my_ksp[i].mass, 1e-5); } destroy_v_field(v); destroy_wv_field(wv); destroy_wv_field(wvsrc); destroy_swv_field(swv); } rephase( ON ); #endif /* Clean up */ free(dst); destroy_v_field(src); } /* if(check != CHECK_NO || startflag[0] == FRESH)} */ } /* color */ if(check != CHECK_NO || startflag[0] == FRESH ){ /* Unapply twist to the APE links */ // mybdry_phase[3] = 0; // momentum_twist_links(mybdry_phase, -1, ape_links); // mybdry_phase[3] = bdry_phase[3]; boundary_twist_field( mybdry_phase, r0, -1, ape_links); /* Unapply twisted boundary conditions on the fermion links and restore conventional KS phases and antiperiodic BC, if changed. */ for(j = 0; j < n_naiks; j++) boundary_twist_fn(fn[j], OFF); } for(i = 0; i < num_prop; i++){ r_close_ksprop(startflag[i], fp_in[i]); w_close_ksprop(saveflag[i], fp_out[i]); if(saveflag[i] != FORGET) node0_printf("Saved propagator to %s\n",savefile[i]); } if(my_ksqs->saveflag != FORGET){ w_source_close(my_ksqs); } #ifdef U1_FIELD /* Unapply the U(1) field phases */ u1phase_off(); invalidate_fermion_links(fn_links); #endif if(fn_multi != NULL)free(fn_multi); return tot_iters; }
int main(int argc, char *argv[]) { int meascount; int prompt; Real avm_iters,avs_iters; double starttime,endtime; #ifdef IOTIME double dtime; int iotime = 1; #else int iotime = 0; #endif int MaxCG; Real RsdCG, RRsdCG; int spin,color,k; int flag; int status; int cl_cg = CL_CG; w_prop_file *fp_in_w[MAX_KAP]; /* For propagator files */ w_prop_file *fp_out_w[MAX_KAP]; /* For propagator files */ wilson_vector *psi = NULL; wilson_prop_field quark_propagator = NULL; initialize_machine(&argc,&argv); #ifdef HAVE_QDP QDP_initialize(&argc, &argv); #endif /* Remap standard I/O */ if(remap_stdio_from_args(argc, argv) == 1)terminate(1); g_sync(); /* set up */ prompt = setup_cl(); /* loop over input sets */ psi = create_wv_field(); quark_propagator = create_wp_field(); while( readin(prompt) == 0) { starttime=dclock(); MaxCG=niter; wqstmp = wqs; /* For clover_info.c */ avm_iters=0.0; meascount=0; if( fixflag == COULOMB_GAUGE_FIX) { if(this_node == 0) printf("Fixing to Coulomb gauge\n"); #ifdef IOTIME dtime = -dclock(); #endif gaugefix(TUP,(Real)1.5,500,GAUGE_FIX_TOL); #ifdef IOTIME dtime += dclock(); if(this_node==0)printf("Time to gauge fix = %e\n",dtime); #endif invalidate_this_clov(gen_clov); } else if(this_node == 0)printf("COULOMB GAUGE FIXING SKIPPED.\n"); /* save lattice if requested */ if( saveflag != FORGET ){ savelat_p = save_lattice( saveflag, savefile, stringLFN ); } if(this_node==0)printf("END OF HEADER\n"); /* if(this_node==0) printf("num_kap = %d\n", num_kap); */ /* Loop over kappas */ for(k=0;k<num_kap;k++){ kappa=kap[k]; RsdCG=resid[k]; RRsdCG=relresid[k]; if(this_node==0)printf("Kappa= %g r0= %g residue= %g rel= %g\n", (double)kappa,(double)wqs.r0,(double)RsdCG, (double)RRsdCG); /* open files for wilson propagators */ #ifdef IOTIME dtime = -dclock(); #endif fp_in_w[k] = r_open_wprop(startflag_w[k], startfile_w[k]); #ifdef IOTIME dtime += dclock(); if(startflag_w[k] != FRESH) node0_printf("Time to open prop = %e\n",dtime); #endif fp_out_w[k] = w_open_wprop(saveflag_w[k], savefile_w[k], wqs.type); /* Loop over source spins */ for(spin=0;spin<4;spin++){ /* Loop over source colors */ for(color=0;color<3;color++){ meascount ++; /*if(this_node==0)printf("color=%d spin=%d\n",color,spin); */ if(startflag_w[k] == CONTINUE) { node0_printf("Can not continue propagator here! Zeroing it instead\n"); startflag_w[k] = FRESH; } /* Saves one multiplication by zero in cgilu */ if(startflag_w[k] == FRESH)flag = 0; else flag = 1; /* load psi if requested */ status = reload_wprop_sc_to_field( startflag_w[k], fp_in_w[k], &wqs, spin, color, psi, iotime); if(status != 0) { node0_printf("control_cl: Recovering from error by resetting initial guess to zero\n"); reload_wprop_sc_to_field( FRESH, fp_in_w[k], &wqs, spin, color, psi, 0); flag = 0; } /* Complete the source structure */ wqs.color = color; wqs.spin = spin; /* Load inversion control structure */ qic.prec = PRECISION; qic.max = MaxCG; qic.nrestart = nrestart; qic.resid = RsdCG; qic.relresid = RRsdCG; qic.start_flag = flag; /* Load Dirac matrix parameters */ dcp.Kappa = kappa; dcp.Clov_c = clov_c; dcp.U0 = u0; /* compute the propagator. Result in psi. */ switch (cl_cg) { case BICG: avs_iters = (Real)wilson_invert_field_wqs(&wqs, w_source_field, psi, bicgilu_cl_field, &qic,(void *)&dcp); break; case HOP: avs_iters = (Real)wilson_invert_field_wqs(&wqs, w_source_field, psi, hopilu_cl_field, &qic,(void *)&dcp); break; case MR: avs_iters = (Real)wilson_invert_field_wqs(&wqs, w_source_field, psi, mrilu_cl_field, &qic,(void *)&dcp); break; case CG: avs_iters = (Real)wilson_invert_field_wqs(&wqs, w_source_field, psi, cgilu_cl_field, &qic,(void *)&dcp); break; default: node0_printf("main(%d): Inverter choice %d not supported\n", this_node,cl_cg); } avm_iters += avs_iters; copy_wp_from_wv(quark_propagator, psi, color, spin); /* save psi if requested */ save_wprop_sc_from_field( saveflag_w[k],fp_out_w[k], &wqs, spin,color,psi,"Fill in record info here",iotime); } /* source spins */ } /* source colors */ /* close files for wilson propagators */ r_close_wprop(startflag_w[k],fp_in_w[k]); #ifdef IOTIME dtime = -dclock(); #endif w_close_wprop(saveflag_w[k],fp_out_w[k]); #ifdef IOTIME dtime += dclock(); if(saveflag_w[k] != FORGET) node0_printf("Time to close prop = %e\n",dtime); #endif /* spectrum, if requested */ if(strstr(spectrum_request,",spectrum,") != NULL) spectrum_cl(quark_propagator, wqs.t0, k); } /* kappas */ if(this_node==0)printf("RUNNING COMPLETED\n"); if(meascount>0){ if(this_node==0)printf("total cg iters for measurement= %e\n", (double)avm_iters); if(this_node==0)printf("cg iters for measurement= %e\n", (double)avm_iters/(double)meascount); } endtime=dclock(); if(this_node==0){ printf("Time = %e seconds\n",(double)(endtime-starttime)); printf("total_iters = %d\n",total_iters); } fflush(stdout); } destroy_wv_field(psi); destroy_wp_field(quark_propagator); return 0; }