double
bench_action(QOP_gauge_coeffs_t *coeffs, QOP_Force *out)
{
  double sec=0, flop=0, mf=0;
  QLA_Real acts, actt;
  QOP_info_t info = QOP_INFO_ZERO;

  for(int i=0; i<=nit; i++) {
    QOP_symanzik_1loop_gauge_action(&info, gauge, &acts, &actt, coeffs);

    if(i>0) {
      sec += info.final_sec;
      flop += info.final_flop;
      mf += info.final_flop/(1e6*info.final_sec);
    }
  }

#if 1
  printf0("action s: %g  t: %g  tot: %g\n", acts, actt, acts+actt);

  coeffs->plaquette /= 4;
  coeffs->rectangle /= 6;
  coeffs->parallelogram /= 6;
  coeffs->adjoint_plaquette /= 8;
  QLA_Real eps=1;
  QOP_verbose(QOP_VERB_DEBUG);
  QOP_symanzik_1loop_gauge_force(&info, gauge, out, coeffs, eps);
  QOP_verbose(QOP_VERB_OFF);
  coeffs->plaquette *= 4;
  coeffs->rectangle *= 6;
  coeffs->parallelogram *= 6;
  coeffs->adjoint_plaquette *= 8;
#endif

  secs = sec/nit;
  flops = flop/nit;
  return mf/nit;
}
Esempio n. 2
0
static int 
ks_congrad_qop_generic( QOP_FermionLinksAsqtad* qop_links, 
			QOP_invert_arg_t *qop_invert_arg,
			QOP_resid_arg_t  ***qop_resid_arg,
			MASSREAL *masses[], int nmass[], 
			QOP_ColorVector **qop_sol[], 
			QOP_ColorVector* qop_src[], 
			int nsrc, quark_invert_control *qic )
{
  int isrc, imass;
  int iters;
  QOP_info_t info = QOP_INFO_ZERO;
  char myname[] = "ks_congrad_qop_generic";

#ifdef AB_DEBUG_ENTRY_EXIT_ROUTINES
  printf("Enter ks_congrad_qop_generic in d_congrad5_fn_qop_P.c\n");
#endif

#ifndef OLD_QOPQDP_NORM  
  /* Since version 0.9.0 the conventions for QOP_asqtad_invert* do not
     give results consistent with other calls to ks_congrad and
     ks_multicg... when the parity is EVENODD.  You should change the
     call and use mat_invert_uml instead.  */

  if(qop_invert_arg->evenodd == QOP_EVENODD){
    node0_printf("%s: EVENANDODD is currently not supported.\n",myname);
    terminate(1);
  }
#endif

#ifdef CG_DEBUG
  int save_qop_verb;
  save_qop_verb = QOP_verbose(QOP_VERB_HI);
#endif
  
  if(nsrc == 1 && nmass[0] == 1)
    QOP_asqtad_invert( &info, qop_links, qop_invert_arg, qop_resid_arg[0][0],
		       masses[0][0], qop_sol[0][0], qop_src[0] );
  else
    QOP_asqtad_invert_multi( &info, qop_links, qop_invert_arg, qop_resid_arg,
			     masses, nmass, qop_sol, qop_src, nsrc );

#ifdef CG_DEBUG
  QOP_verbose(save_qop_verb);
#endif

  /* For now we return the largest value of the residual and iterations */
  qic[0].final_rsq = 0;
  qic[0].final_relrsq = 0;
  qic[0].converged = 1;
  iters = 0;
  for(isrc = 0; isrc < nsrc; isrc++){
    for(imass = 0; imass < nmass[isrc]; imass++){
      if(this_node == 0){
	if((qic[0].resid > 0 && qop_resid_arg[isrc][imass]->final_rsq <= qic[0].resid * qic[0].resid ) ||
	   (qic[0].relresid > 0 && qop_resid_arg[isrc][imass]->final_rel <= qic[0].relresid * qic[0].relresid )){
#ifdef CG_DEBUG
	  node0_printf(" OK converged (src %d, mass %d) ", isrc, imass);
	  node0_printf("final_rsq = %.2g rel = %.2g restarts = %d iters = %d\n",
		       qop_resid_arg[isrc][imass]->final_rsq,
		       qop_resid_arg[isrc][imass]->final_rel,
		       qop_resid_arg[isrc][imass]->final_restart,
		       qop_resid_arg[isrc][imass]->final_iter);
#endif
	} else {
	  qic[0].converged = 0;
	  node0_printf(" NOT converged (src %d, mass %d) ", isrc, imass);
	  node0_printf("final_rsq = %.2g (cf %.2g) rel = %.2g (cf %.2g) restarts = %d iters = %d\n",
		       qop_resid_arg[isrc][imass]->final_rsq,
		       qic[0].resid * qic[0].resid,
		       qop_resid_arg[isrc][imass]->final_rel,
		       qic[0].relresid * qic[0].relresid,
		       qop_resid_arg[isrc][imass]->final_restart,
		       qop_resid_arg[isrc][imass]->final_iter);
	}
      }
      if(qic[0].final_rsq < qop_resid_arg[isrc][imass]->final_rsq)
	qic[0].final_rsq = qop_resid_arg[isrc][imass]->final_rsq;
      if(qic[0].final_relrsq < qop_resid_arg[isrc][imass]->final_rel)
	qic[0].final_relrsq = qop_resid_arg[isrc][imass]->final_rel;
#ifdef CG_DEBUG
      if(nsrc > 1 || nmass[isrc] > 1)
	node0_printf("CONGRAD5(src %d, mass %d): iters = %d resid = %.2g rel = %.2g\n",
		     isrc, imass,
		     qop_resid_arg[isrc][imass]->final_iter,
		     qop_resid_arg[isrc][imass]->final_rsq,
		     qop_resid_arg[isrc][imass]->final_rel);
#endif
    }
    if(qop_resid_arg[isrc][0]->final_iter > iters)
      iters = qop_resid_arg[isrc][0]->final_iter;
  }

  // This structure isn't very friendly to multimass or multisource use
  // So report restarts for the first mass in the list
  qic[0].final_iters = iters;
  qic[0].final_restart = qop_resid_arg[0][0]->final_restart;

#ifdef CGTIME
  node0_printf("CONGRAD5: time = %e (fn_qop %s) ",
	       info.final_sec,qop_prec[QOP_PrecisionInt-1]);
  for(isrc = 0; isrc < nsrc; isrc++)
    node0_printf("nmass[%d] = %d iters = %d ",
		 isrc,nmass[isrc],qop_resid_arg[isrc][0]->final_iter);
  if(info.final_sec == 0.)
    node0_printf("mflops = 0.0\n");
  else
    node0_printf("mflops = %e\n", info.final_flop/(1.0e6*info.final_sec) );
  fflush(stdout);
#endif

#ifdef AB_DEBUG_ENTRY_EXIT_ROUTINES
  printf("Exit  ks_congrad_qop_generic in d_congrad5_fn_qop_P.c\n");
#endif
  fflush(stdout);
  return iters;
}