int main(int argc, char *argv[]) { int prompt; int i, j, iq0, iq1; #ifdef CLOV_LEAN int oldiq0, oldiq1, oldip0; #endif double starttime, endtime; #ifdef PRTIME double dtime; #endif wilson_prop_field *prop[MAX_PROP]; wilson_prop_field *quark[MAX_QK]; initialize_machine(&argc,&argv); /* Remap standard I/O */ if(remap_stdio_from_args(argc, argv) == 1)terminate(1); g_sync(); starttime=dclock(); /* set up */ STARTTIME; prompt = setup(); ENDTIME("setup"); /* loop over input sets */ while( readin(prompt) == 0){ if(prompt == 2)continue; total_iters=0; #ifdef HISQ_SVD_COUNTER hisq_svd_counter = 0; #endif /**************************************************************/ /* Set up gauge field */ if( param.fixflag == COULOMB_GAUGE_FIX) { if(this_node == 0) printf("Fixing to Coulomb gauge\n"); STARTTIME; gaugefix(TUP,(Real)1.5,500,GAUGE_FIX_TOL); ENDTIME("gauge fix"); /* (Re)construct APE smeared links after gauge fixing. No KS phases here! */ destroy_ape_links_3D(ape_links); ape_links = ape_smear_3D( param.staple_weight, param.ape_iter ); invalidate_this_clov(gen_clov); } else if(this_node == 0)printf("COULOMB GAUGE FIXING SKIPPED.\n"); /* save lattice if requested */ if( param.saveflag != FORGET ){ savelat_p = save_lattice( param.saveflag, param.savefile, param.stringLFN ); } else { savelat_p = NULL; } if(this_node==0)printf("END OF HEADER\n"); /**************************************************************/ /* Loop over the propagators */ STARTTIME; for(i=0; i<param.num_prop; i++){ node0_printf("******* Creating propagator %d ********\n",i);fflush(stdout); /**************************************************************/ /* Read and/or generate quark propagator */ if(param.prop_type[i] == CLOVER_TYPE) { int ncolor = convert_ksource_to_color(param.src_qs[i].nsource); prop[i] = create_wp_field(ncolor); node0_printf("Generate Dirac propagator\n"); node0_printf("Kappa= %g source %s residue= %g rel= %g\n", (double)param.dcp[i].Kappa, param.src_qs[i].descrp, (double)param.qic[i].resid, (double)param.qic[i].relresid); /* For clover_info */ wqstmp = param.src_qs[i]; dcptmp = param.dcp[i]; total_iters += get_wprop_to_wp_field(param.prop_type[i], param.startflag_w[i], param.startfile_w[i], param.saveflag_w[i], param.savefile_w[i], prop[i], ¶m.src_qs[i], ¶m.qic[i], (void *)¶m.dcp[i], param.bdry_phase[i], param.coord_origin, param.check[i]); #ifdef CLOV_LEAN /* Free clover prop memory if we have saved the prop to disk */ if(param.saveflag_w[i] != FORGET){ free_wp_field(prop[i]); clear_qs(¶m.src_qs[i]); node0_printf("destroy prop[%d]\n",i); } #endif } /* ------------------------------------------- */ else if(param.prop_type[i] == IFLA_TYPE) { int ncolor = convert_ksource_to_color(param.src_qs[i].nsource); prop[i] = create_wp_field(ncolor); node0_printf("Generate Dirac IFLA propagator\n"); if(this_node==0)printf("Kappa= %g source %s residue= %g rel= %g\n", (double)param.nap[i].kapifla, param.src_qs[i].descrp, (double)param.qic[i].resid, (double)param.qic[i].relresid); /* For clover_info */ wqstmp = param.src_qs[i]; naptmp = param.nap[i]; total_iters += get_wprop_to_wp_field(param.prop_type[i], param.startflag_w[i], param.startfile_w[i], param.saveflag_w[i], param.savefile_w[i], prop[i], ¶m.src_qs[i], ¶m.qic[i], (void *)¶m.nap[i], param.bdry_phase[i], param.coord_origin, param.check[i]); #ifdef CLOV_LEAN /* Free clover prop memory if we have saved the prop to disk */ if(param.saveflag_w[i] != FORGET){ free_wp_field(prop[i]); clear_qs(¶m.src_qs[i]); node0_printf("destroy prop[%d]\n",i); } #endif } else if(param.prop_type[i] == KS_TYPE || param.prop_type[i] == KS0_TYPE ) /* KS_TYPE */ { prop[i] = create_wp_field(param.src_qs[i].ncolor); if(this_node==0)printf("Mass= %g source %s residue= %g rel= %g\n", (double)param.ksp[i].mass, param.src_qs[i].descrp, (double)param.qic[i].resid, (double)param.qic[i].relresid); total_iters += get_ksprop_to_wp_field(param.startflag_ks[i], param.startfile_ks[i], param.saveflag_ks[i], param.savefile_ks[i], prop[i], ¶m.src_qs[i], ¶m.qic[i], ¶m.ksp[i], param.bdry_phase[i], param.coord_origin, param.check[i], param.prop_type[i] == KS0_TYPE); #ifdef CLOV_LEAN /* (We don't free naive prop memory, since we don't save it as a clover prop in get_ksprop_to_wp_field) */ #endif } else /* KS4_TYPE */ { prop[i] = create_wp_field(param.src_qs[i].ncolor); if(this_node==0)printf("Mass= %g source %s residue= %g rel= %g\n", (double)param.ksp[i].mass, param.src_qs[i].descrp, (double)param.qic[i].resid, (double)param.qic[i].relresid); total_iters += get_ksprop4_to_wp_field(param.startflag_w[i], param.startfile_w[i], param.saveflag_w[i], param.savefile_w[i], prop[i], ¶m.src_qs[i], ¶m.qic[i], ¶m.ksp[i], param.bdry_phase[i], param.coord_origin, param.check[i]); } } /* propagators */ ENDTIME("compute propagators"); /*****************************************************************/ /* Complete the quark propagators by applying the sink operators to either the raw propagator or by building on an existing quark propagator */ STARTTIME; #ifdef CLOV_LEAN oldip0 = -1; oldiq0 = -1; oldiq1 = -1; #endif for(j=0; j<param.num_qk; j++){ node0_printf("******* Creating quark %d ********\n",j); fflush(stdout); i = param.prop_for_qk[j]; if(param.parent_type[j] == PROP_TYPE){ #ifdef CLOV_LEAN /* Restore clover prop[i] from file. */ /* But first destroy the old one, unless we still need it */ if(oldip0 >= 0 && oldip0 != i) if(param.prop_type[oldip0] == CLOVER_TYPE && param.saveflag_w[oldip0] != FORGET){ free_wp_field(prop[oldip0]); node0_printf("destroy prop[%d]\n",oldip0); } /* In this case we won't need any old quarks */ if(oldiq0 >= 0) if(param.saveflag_q[oldiq0] != FORGET){ free_wp_field(quark[oldiq0]); node0_printf("destroy quark[%d]\n",oldiq0); } if(oldiq1 >= 0) if(param.saveflag_q[oldiq1] != FORGET){ free_wp_field(quark[oldiq1]); node0_printf("destroy quark[%d]\n",oldiq1); } if(prop[i]->swv[0] == NULL) reread_wprop_to_wp_field(param.saveflag_w[i], param.savefile_w[i], prop[i]); #endif /* Before applying operator, apply momentum twist to ape_links. Use the momentum twist of the parent propagator */ momentum_twist_ape_links(i, +1); /* Apply sink operator quark[j] <- Op[j] prop[i] */ quark[j] = create_wp_field_copy(prop[i]); wp_sink_op(¶m.snk_qs_op[j], quark[j]); /* Remove twist */ momentum_twist_ape_links(i, -1); #ifdef CLOV_LEAN oldip0 = i; oldiq0 = -1; #endif } else if(param.parent_type[j] == QUARK_TYPE) { /* QUARK_TYPE */ #ifdef CLOV_LEAN /* Restore quark[i] from file */ /* But first destroy the old ones, unless we still need one of them */ /* In this case we won't need the old prop */ if(oldip0 >= 0) if(param.prop_type[oldip0] == CLOVER_TYPE && param.saveflag_w[oldip0] != FORGET){ free_wp_field(prop[oldip0]); node0_printf("destroy prop[%d]\n",oldip0); } if(oldiq0 >= 0 && oldiq0 != i) if(param.saveflag_q[oldiq0] != FORGET){ free_wp_field(quark[oldiq0]); node0_printf("destroy quark[%d]\n",oldiq0); } if(oldiq1 >= 0 && oldiq1 != i) if(param.saveflag_q[oldiq1] != FORGET){ free_wp_field(quark[oldiq1]); node0_printf("destroy quark[%d]\n",oldiq1); } if(quark[i]->swv[0] == NULL) reread_wprop_to_wp_field(param.saveflag_q[i], param.savefile_q[i], quark[i]); #endif /* Apply sink operator quark[j] <- Op[j] quark[i] */ momentum_twist_ape_links(i, +1); quark[j] = create_wp_field_copy(quark[i]); wp_sink_op(¶m.snk_qs_op[j], quark[j]); momentum_twist_ape_links(i, -1); #ifdef CLOV_LEAN oldip0 = -1; oldiq0 = i; #endif } else { /* COMBO_TYPE */ int k; int nc = quark[param.combo_qk_index[j][0]]->nc; /* Create a zero field */ quark[j] = create_wp_field(nc); /* Compute the requested linear combination */ for(k = 0; k < param.num_combo[j]; k++){ wilson_prop_field *q = quark[param.combo_qk_index[j][k]]; if(nc != q->nc){ printf("Error: Attempting to combine an inconsistent number of colors: %d != %d\n",nc, q->nc); terminate(1); } scalar_mult_add_wprop_field(quark[j], q, param.combo_coeff[j][k], quark[j]); } } /* Save the resulting quark[j] if requested */ dump_wprop_from_wp_field( param.saveflag_q[j], param.savetype_q[j], param.savefile_q[j], quark[j]); /* Can we delete any props and quarks now? */ /* If nothing later depends on a prop or quark, free it up. */ for(i = 0; i < param.num_prop; i++) if( prop[i]->swv[0] != NULL && param.prop_dep_qkno[i] < j ){ free_wp_field(prop[i]); node0_printf("free prop[%d]\n",i); } for(i = 0; i < j; i++) if( quark[i]->swv[0] != NULL && param.quark_dep_qkno[i] < j ){ free_wp_field(quark[i]); node0_printf("free quark[%d]\n",i); } #ifdef CLOV_LEAN oldiq1 = j; #endif } #ifdef CLOV_LEAN /* Free remaining memory */ if(oldip0 >= 0) if(param.prop_type[oldip0] == CLOVER_TYPE && param.saveflag_w[oldip0] != FORGET){ free_wp_field(prop[oldip0]); node0_printf("destroy prop[%d]\n",oldip0); } if(oldiq0 >= 0) if(param.saveflag_q[oldiq0] != FORGET){ free_wp_field(quark[oldiq0]); node0_printf("destroy quark[%d]\n",oldiq0); } if(oldiq1 >= 0) if(param.saveflag_q[oldiq1] != FORGET){ free_wp_field(quark[oldiq1]); node0_printf("destroy quark[%d]\n",oldiq1); } #endif /* Now destroy all remaining propagator fields */ for(i = 0; i < param.num_prop; i++){ if(prop[i] != NULL)node0_printf("destroy prop[%d]\n",i); destroy_wp_field(prop[i]); prop[i] = NULL; } ENDTIME("generate quarks"); /****************************************************************/ /* Compute the meson propagators */ STARTTIME; for(i = 0; i < param.num_pair; i++){ /* Index for the quarks making up this meson */ iq0 = param.qkpair[i][0]; iq1 = param.qkpair[i][1]; node0_printf("Mesons for quarks %d and %d\n",iq0,iq1); #ifdef CLOV_LEAN /* Restore quarks from file and free old memory */ /* We try to reuse props that are already in memory, so we don't destroy them immediately, but wait to see if we need them again for the next pair. */ if(i > 0 && oldiq0 != iq0 && oldiq0 != iq1) if(param.saveflag_q[oldiq0] != FORGET){ free_wp_field(quark[oldiq0]); node0_printf("destroy quark[%d]\n",oldiq0); } if(i > 0 && oldiq1 != iq0 && oldiq1 != iq1) if(param.saveflag_q[oldiq1] != FORGET){ free_wp_field(quark[oldiq1]); node0_printf("destroy quark[%d]\n",oldiq1); } if(quark[iq0]->swv[0] == NULL) reread_wprop_to_wp_field(param.saveflag_q[iq0], param.savefile_q[iq0], quark[iq0]); if(quark[iq1]->swv[0] == NULL){ reread_wprop_to_wp_field(param.saveflag_q[iq1], param.savefile_q[iq1], quark[iq1]); } #endif /* Tie together to generate hadron spectrum */ spectrum_cl(quark[iq0], quark[iq1], i); /* Remember, in case we need to free memory */ #ifdef CLOV_LEAN oldiq0 = iq0; oldiq1 = iq1; #endif } #ifdef CLOV_LEAN /* Free any remaining quark prop memory */ if(quark[oldiq0]->swv[0] != NULL) if(param.saveflag_q[oldiq0] != FORGET){ free_wp_field(quark[oldiq0]); node0_printf("destroy quark[%d]\n",oldiq0); } if(quark[oldiq1]->swv[0] != NULL) if(param.saveflag_q[oldiq1] != FORGET){ free_wp_field(quark[oldiq1]); node0_printf("destroy quark[%d]\n",oldiq1); } #endif ENDTIME("tie hadron correlators"); node0_printf("RUNNING COMPLETED\n"); endtime=dclock(); node0_printf("Time = %e seconds\n",(double)(endtime-starttime)); node0_printf("total_iters = %d\n",total_iters); #ifdef HISQ_SVD_COUNTER printf("hisq_svd_counter = %d\n",hisq_svd_counter); #endif fflush(stdout); for(i = 0; i < param.num_qk; i++){ if(quark[i] != NULL)node0_printf("destroy quark[%d]\n",i); destroy_wp_field(quark[i]); quark[i] = NULL; } destroy_ape_links_3D(ape_links); /* Destroy fermion links (possibly created in make_prop()) */ #if FERM_ACTION == HISQ destroy_fermion_links_hisq(fn_links); #else destroy_fermion_links(fn_links); #endif fn_links = NULL; } /* readin(prompt) */ #ifdef HAVE_QUDA qudaFinalize(); #endif normal_exit(0); return 0; }
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; }