00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <vector>
00011 #include <map>
00012 #include <qdp-lapack.h>
00013 #include <qdp_config.h>
00014 #include "handle.h"
00015 #include "meas/inline/hadron/inline_disco_eigcg_w.h"
00016 #include "meas/inline/abs_inline_measurement_factory.h"
00017 #include "meas/smear/quark_smearing_factory.h"
00018 #include "meas/smear/quark_smearing_aggregate.h"
00019 #include "meas/smear/displacement.h"
00020 #include "meas/sources/source_smearing_aggregate.h"
00021 #include "meas/sources/source_smearing_factory.h"
00022 #include "meas/sources/dilutezN_source_const.h"
00023 #include "meas/sources/zN_src.h"
00024 #include "meas/sinks/sink_smearing_aggregate.h"
00025 #include "meas/sinks/sink_smearing_factory.h"
00026 #include "meas/hadron/barspinmat_w.h"
00027 #include "meas/hadron/baryon_operator_aggregate_w.h"
00028 #include "meas/hadron/baryon_operator_factory_w.h"
00029 #include "meas/hadron/barQll_w.h"
00030 #include "meas/hadron/dilution_scheme_aggregate.h"
00031 #include "meas/hadron/dilution_scheme_factory.h"
00032 #include "meas/glue/mesplq.h"
00033 #include "util/ft/sftmom.h"
00034 #include "util/info/proginfo.h"
00035 #include "meas/inline/make_xml_file.h"
00036 #include "util/info/unique_id.h"
00037 #include "util/ferm/transf.h"
00038 #include "meas/inline/io/named_objmap.h"
00039
00040 #include "actions/ferm/fermacts/fermact_factory_w.h"
00041 #include "actions/ferm/fermacts/fermacts_aggregate_w.h"
00042
00043 #include "eoprec_logdet_wilstype_fermact_w.h"
00044 #include "actions/ferm/linop/lgherm_w.h"
00045
00046 #include "actions/ferm/fermacts/clover_fermact_params_w.h"
00047 #include "actions/ferm/fermacts/wilson_fermact_params_w.h"
00048 #include "actions/ferm/linop/linop_w.h"
00049
00050
00051 #include "util/ferm/key_val_db.h"
00052
00053
00054
00055 namespace Chroma{
00056 namespace InlineDiscoEigCGEnv{
00057 namespace{
00058 AbsInlineMeasurement* createMeasurement(XMLReader& xml_in,
00059 const std::string& path)
00060 {
00061 return new InlineMeas(Params(xml_in, path));
00062 }
00063
00064
00065 bool registered = false;
00066 }
00067
00068 const std::string name = "DISCO_EIGCG";
00069
00070
00071 bool registerAll()
00072 {
00073 bool success = true;
00074 if (! registered)
00075 {
00076
00077 success &= TheInlineMeasurementFactory::Instance().registerObject(name, createMeasurement);
00078 registered = true;
00079 }
00080 return success;
00081 }
00082
00083
00084 void read(XMLReader& xml, const string& path, Params::Param_t& param){
00085 XMLReader paramtop(xml, path);
00086
00087 int version;
00088 read(paramtop, "version", version);
00089
00090 switch (version)
00091 {
00092 case 1:
00093
00094 read(paramtop,"max_path_length",param.max_path_length);
00095 read(paramtop,"p2_max",param.p2_max);
00096 read(paramtop,"mass_label",param.mass_label);
00097 param.chi = readXMLArrayGroup(paramtop, "Quarks", "DilutionType");
00098 param.action = readXMLGroup(paramtop, "FermionAction","FermAct");
00099
00100 break;
00101
00102 default :
00103
00104
00105 QDPIO::cerr << "Input parameter version " << version << " unsupported." << endl;
00106 QDP_abort(1);
00107 }
00108 }
00109
00110
00111 void write(XMLWriter& xml, const string& path, const Params::Param_t& param){
00112 push(xml, path);
00113
00114 int version = 1;
00115
00116 write(xml, "version", version);
00117
00118 write(xml,"max_path_length",param.max_path_length);
00119 write(xml,"p2_max",param.p2_max);
00120 write(xml,"mass_label",param.mass_label);
00121 push(xml,"FermionAction");
00122 xml<<param.action.xml ;
00123 pop(xml);
00124 push(xml,"Quarks");
00125 for( int t(0);t<param.chi.size();t++){
00126 push(xml,"elem");
00127 xml<<param.chi[t].xml;
00128 pop(xml);
00129 }
00130 pop(xml);
00131
00132 pop(xml);
00133 }
00134
00135
00136 void read(XMLReader& xml, const string& path, Params::NamedObject_t& input)
00137 {
00138 XMLReader inputtop(xml, path);
00139
00140 read(inputtop, "gauge_id" , input.gauge_id ) ;
00141
00142 if ( inputtop.count("evecs_file")!=0 )
00143 read(inputtop, "evecs_file" , input.evecs_file ) ;
00144 else
00145 input.evecs_file="";
00146
00147 read(inputtop, "op_db_file" , input.op_db_file ) ;
00148 }
00149
00150
00151 void write(XMLWriter& xml, const string& path, const Params::NamedObject_t& input){
00152 push(xml, path);
00153
00154 write(xml, "gauge_id" , input.gauge_id );
00155 write(xml, "evecs_file" , input.evecs_file );
00156 write(xml, "op_db_file" , input.op_db_file );
00157 pop(xml);
00158 }
00159
00160
00161
00162 Params::Params(){
00163 frequency = 0;
00164 }
00165
00166 Params::Params(XMLReader& xml_in, const std::string& path)
00167 {
00168 try
00169 {
00170 XMLReader paramtop(xml_in, path);
00171
00172 if (paramtop.count("Frequency") == 1)
00173 read(paramtop, "Frequency", frequency);
00174 else
00175 frequency = 1;
00176
00177
00178 read(paramtop, "Param", param);
00179
00180
00181 read(paramtop, "NamedObject", named_obj);
00182
00183
00184 if (paramtop.count("xml_file") != 0)
00185 {
00186 read(paramtop, "xml_file", xml_file);
00187 }
00188 }
00189 catch(const std::string& e)
00190 {
00191 QDPIO::cerr << __func__ << ": Caught Exception reading XML: " << e << endl;
00192 QDP_abort(1);
00193 }
00194 }
00195
00196
00197 void Params::write(XMLWriter& xml_out, const std::string& path)
00198 {
00199 push(xml_out, path);
00200
00201
00202 InlineDiscoEigCGEnv::write(xml_out, "Param", param);
00203
00204
00205 InlineDiscoEigCGEnv::write(xml_out, "NamedObject", named_obj);
00206
00207 pop(xml_out);
00208 }
00209
00210
00211
00212 struct KeyOperator_t
00213 {
00214 multi1d<short int> mom ;
00215 unsigned short int t_slice ;
00216 multi1d<short int> disp ;
00217
00218 KeyOperator_t(){
00219 mom.resize(Nd-1);
00220 }
00221 };
00222
00223 bool operator<(const KeyOperator_t& a, const KeyOperator_t& b){
00224 return ((a.t_slice<b.t_slice)||(a.mom<b.mom)||(a.disp<b.disp));
00225 }
00226
00227 std::ostream& operator<<(std::ostream& os, const KeyOperator_t& d)
00228 {
00229 os << "KeyOperator_t:"
00230 << " t_slice = " << d.t_slice
00231 << ", disp = ";
00232 for (int i=0; i<d.disp.size();i++)
00233 os << d.disp[i] << " " ;
00234
00235 os << ", mom = ";
00236 for (int i=0; i<d.mom.size();i++)
00237 os << d.mom[i] << " " ;
00238
00239 os << std::endl;
00240
00241 return os;
00242 }
00243
00244 class ValOperator_t{
00245 public:
00246 multi1d<ComplexD> op ;
00247 ValOperator_t(){op.resize(Ns*Ns);}
00248 ~ValOperator_t(){}
00249 } ;
00250
00251
00252
00253 std::ostream& operator<<(std::ostream& os, const ValOperator_t& d)
00254 {
00255 os << "ValOperator_t:\n";
00256 for (int i=0; i<d.op.size();i++)
00257 os <<" gamma["<<i<<"] = "<< d.op[i] << endl ;
00258
00259 return os;
00260 }
00261
00262 struct KeyVal_t{
00263 SerialDBKey <KeyOperator_t> k ;
00264 SerialDBData<ValOperator_t> v ;
00265 };
00266
00267
00268 void read(BinaryReader& bin, KeyOperator_t& d){
00269 read(bin,d.t_slice);
00270 unsigned short int n ;
00271 read(bin,n);
00272 d.disp.resize(n);
00273 read(bin,d.disp);
00274 d.mom.resize(Nd-1) ;
00275 read(bin,d.mom);
00276 }
00277
00278 void write(BinaryWriter& bin, KeyOperator_t& d){
00279 write(bin,d.t_slice);
00280 unsigned short int n ;
00281 n = d.disp.size();
00282 write(bin,n);
00283 write(bin,d.disp);
00284 write(bin,d.mom);
00285 }
00286
00287
00288 void read(BinaryReader& bin, ValOperator_t& d){
00289 d.op.resize(Ns*Ns);
00290 read(bin,d.op);
00291 }
00292
00293 void write(BinaryWriter& bin, ValOperator_t& d){
00294 write(bin,d.op);
00295 }
00296
00297 namespace{
00298 StandardOutputStream& operator<<(StandardOutputStream& os, const multi1d<short int>& d){
00299 if (d.size() > 0){
00300 os << d[0];
00301 for(int i=1; i < d.size(); i++)
00302 os << " " << d[i];
00303 }
00304 return os;
00305 }
00306 }
00307
00308
00309
00310
00311
00312
00313
00314 typedef LatticeFermion T;
00315 typedef multi1d<LatticeColorMatrix> P;
00316 typedef multi1d<LatticeColorMatrix> Q;
00317
00318 Handle<EvenOddPrecLinearOperator<T,P,Q> >
00319 createOddOdd_Op( const Params::Param_t& param, const P& u){
00320
00321
00322
00323 std::istringstream xml_s(param.action.xml);
00324 XMLReader fermacttop(xml_s);
00325 QDPIO::cout << "FermAct = " << param.action.id << endl;
00326
00327
00328
00329 Handle< FermState< T,P,Q> > state ;
00330 try{
00331 QDPIO::cout << "Try the various Wilson fermion factories" << endl;
00332
00333 Handle< FermionAction< T,P,Q > >
00334 Sf(TheFermionActionFactory::Instance().createObject(param.action.id,
00335 fermacttop,
00336 param.action.path));
00337 state = Sf->createState(u);
00338 QDPIO::cout << "Suitable factory found: compute the trace quark prop"<<endl;
00339 }
00340 catch (const std::string& e){
00341 QDPIO::cout << name
00342 << ": caught exception instantiating the action: " << e << endl;
00343 }
00344
00345
00346
00347
00348
00349
00350
00351 Handle<EvenOddPrecLinearOperator<T,P,Q> > Doo ;
00352 if(param.action.id == "WILSON"){
00353 WilsonFermActParams wp(fermacttop,param.action.path);
00354 return new EvenOddPrecWilsonLinOp(state,wp.Mass,wp.anisoParam ) ;
00355 }
00356 else if(param.action.id == "CLOVER"){
00357 CloverFermActParams cp(fermacttop,param.action.path);
00358 return new EvenOddPrecCloverLinOp(state,cp) ;
00359 }
00360 else{
00361 QDPIO::cout<<name<<" : Tough luck dude! No code for you..."<<endl ;
00362 QDP_abort(1);
00363 }
00364 return NULL ;
00365 }
00366
00367 struct CholeskyFactors{
00368 multi1d<Real> evals ;
00369 multi1d<Complex> H ;
00370 multi1d<Complex> HU ;
00371 int ldh ;
00372 int Nvec ;
00373 } ;
00374
00375 void do_disco(map< KeyOperator_t, ValOperator_t >& db,
00376 const LatticeFermion& qbar,
00377 const LatticeFermion& q,
00378 const SftMom& p,
00379 const int& t,
00380 const multi1d<short int>& path,
00381 const int& max_path_length ){
00382 QDPIO::cout<<" Computing Operator with path length "<<path.size()
00383 <<" on timeslice "<<t<<". Path: "<<path <<endl;
00384 ValOperator_t val ;
00385 KeyOperator_t key ;
00386 pair<KeyOperator_t, ValOperator_t> kv ;
00387 kv.first.t_slice = t ;
00388 if(path.size()==0){
00389 kv.first.disp.resize(1);
00390 kv.first.disp[0] = 0 ;
00391 }
00392 else
00393 kv.first.disp = path ;
00394
00395 multi1d< multi1d<ComplexD> > foo(p.numMom()) ;
00396 for (int m(0); m < p.numMom(); m++)
00397 foo[m].resize(Ns*Ns);
00398 for(int g(0);g<Ns*Ns;g++){
00399 LatticeComplex cc = localInnerProduct(qbar,Gamma(g)*q);
00400 for (int m(0); m < p.numMom(); m++){
00401 foo[m][g] = sum(p[m]*cc,p.getSet()[t]);
00402 }
00403 }
00404 for (int m(0); m < p.numMom(); m++){
00405 for(int i(0);i<(Nd-1);i++)
00406 kv.first.mom[i] = p.numToMom(m)[i] ;
00407
00408 kv.second.op = foo[m];
00409 pair<map< KeyOperator_t, ValOperator_t >::iterator, bool> itbo;
00410
00411 itbo = db.insert(kv);
00412 if( itbo.second ){
00413 QDPIO::cout<<"Inserting new entry in map\n";
00414 }
00415 else{
00416 for(int i(0);i<kv.second.op.size();i++)
00417 itbo.first->second.op[i] += kv.second.op[i] ;
00418 }
00419 }
00420
00421 if(path.size()<max_path_length){
00422 QDPIO::cout<<" attempt to add new path. "
00423 <<" current path length is : "<<path.size();
00424 multi1d<short int> new_path(path.size()+1);
00425 QDPIO::cout<<" new path length is : "<<new_path.size()<<endl;
00426 for(int i(0);i<path.size();i++)
00427 new_path[i] = path[i] ;
00428 for(int sign(-1);sign<2;sign+=2)
00429 for(int mu(0);mu<Nd;mu++){
00430 new_path[path.size()]= sign*(mu+1) ;
00431
00432 bool back_track=false ;
00433 if(path.size()>0)
00434 if(path[path.size()-1] == -new_path[path.size()])
00435 back_track=true;
00436 if(!back_track){
00437 QDPIO::cout<<" Added path: "<<new_path<<endl;
00438 LatticeFermion q_mu ;
00439 if(sign>0)
00440 q_mu = shift(q, FORWARD, mu);
00441 else
00442 q_mu = shift(q, BACKWARD, mu);
00443
00444 do_disco(db, qbar, q_mu, p, t, new_path, max_path_length);
00445 }
00446 }
00447 }
00448
00449 }
00450
00451 void do_disco(map< KeyOperator_t, ValOperator_t >& db,
00452 CholeskyFactors Clsk ,
00453 multi1d<LatticeFermion>& vec,
00454 const Params::Param_t& param,
00455 const Handle<EvenOddPrecLinearOperator<T,P,Q> >& Doo,
00456 const P& u,
00457 const int& t,
00458 const Subset& trb,
00459 const SftMom& p,
00460 const multi1d<short int>& path){
00461
00462 QDPIO::cout<<" Computing Operator with path length "<<path.size()
00463 <<" on timeslice "<<t<<". Path: "<<path <<endl;
00464 int max_path_length = param.max_path_length;
00465
00466 ValOperator_t val ;
00467 KeyOperator_t key ;
00468 pair<KeyOperator_t, ValOperator_t> kv ;
00469
00470 kv.first.t_slice = t ;
00471 if(path.size()==0){
00472 kv.first.disp.resize(1);
00473 kv.first.disp[0] = 0 ;
00474 }
00475 else
00476 kv.first.disp = path ;
00477
00478 int ldb = vec.size();
00479 int info;
00480 char U = 'U';
00481 int Nrhs = ldb;
00482 multi2d<Complex> B(Nrhs,ldb);
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 multi1d< multi1d<ComplexD> > foo(p.numMom()) ;
00512 for (int m(0); m < p.numMom(); m++){
00513 foo[m].resize(Ns*Ns);
00514 foo[m] = zero;
00515 }
00516
00517 multi1d< LatticeFermion > Svec(ldb);
00518 multi1d< LatticeFermion > DDvec(ldb);
00519 multi1d< LatticeFermion > DDSvec(ldb);
00520 Svec = zero;
00521 DDvec = zero;
00522 for(int i(0); i<ldb;i++){
00523 LatticeFermion qtmp = zero ;
00524
00525 Doo->evenOddLinOp(qtmp, vec[i],PLUS);
00526 Doo->evenEvenInvLinOp(DDvec[i], qtmp,PLUS);
00527 qtmp = zero;
00528
00529 Doo->oddOddLinOp(qtmp,vec[i],PLUS);
00530 LatticeFermion qtmp2 = zero;
00531 Doo->evenOddLinOp(qtmp2,qtmp,MINUS);
00532 Doo->evenEvenInvLinOp(DDSvec[i],qtmp2,MINUS);
00533
00534 Doo->oddOddLinOp(Svec[i],vec[i],PLUS);
00535 }
00536
00537 for(int g(0);g<Ns*Ns;g++){
00538 for (int m(0); m < p.numMom(); m++){
00539 for (int i(0); i<ldb;i++){
00540 for (int j(0); j<ldb;j++){
00541 LatticeComplex cc1 = localInnerProduct(Svec[j],Gamma(g)*vec[i]);
00542 LatticeComplex cc2 = localInnerProduct(DDSvec[j],Gamma(g)*DDvec[i]);
00543 B[i][j] = sum(p[m]*(cc1+cc2),trb) ;
00544
00545 }
00546 }
00547
00548 #if BASE_PRECISION == 32
00549 int r = QDPLapack::cpotrs(U, Clsk.Nvec, Nrhs, Clsk.HU, Clsk.ldh, B, ldb, info);
00550 #else
00551 int r = QDPLapack::zpotrs(U, Clsk.Nvec, Nrhs, Clsk.HU, Clsk.ldh, B, ldb, info);
00552 #endif
00553
00554
00555
00556 QDPIO::cout<<"do_disco cpotrs r = "<<r<<endl;
00557 QDPIO::cout<<"do_disco cpotrs info = "<<info<<endl;
00558
00559 for (int i(0); i<ldb;i++){
00560 foo[m][g] += ComplexD(B[i][i]);
00561 }
00562 }
00563 }
00564 for (int m(0); m < p.numMom(); m++){
00565 for(int i(0);i<(Nd-1);i++)
00566 kv.first.mom[i] = p.numToMom(m)[i] ;
00567
00568 kv.second.op = foo[m];
00569
00570 pair<map< KeyOperator_t, ValOperator_t >::iterator, bool> itbo;
00571
00572 itbo = db.insert(kv);
00573 if( !(itbo.second) ){
00574 for(int i(0);i<kv.second.op.size();i++)
00575 itbo.first->second.op[i] += kv.second.op[i] ;
00576 }
00577 else
00578 QDPIO::cout<<"Inserting new entry in map\n";
00579 }
00580
00581 if(path.size()<max_path_length){
00582 QDPIO::cout<<" attempt to add new path. "
00583 <<" current path length is : "<<path.size();
00584 multi1d<short int> new_path(path.size()+1);
00585 QDPIO::cout<<" new path length is : "<<new_path.size()<<endl;
00586 for(int i(0);i<path.size();i++)
00587 new_path[i] = path[i] ;
00588 for(int sign(-1);sign<2;sign+=2)
00589 for(int mu(0);mu<Nd;mu++){
00590 new_path[path.size()]= sign*(mu+1) ;
00591
00592 bool back_track=false ;
00593 if(path.size()>0)
00594 if(path[path.size()-1] == -new_path[path.size()])
00595 back_track=true;
00596 if(!back_track){
00597 QDPIO::cout<<" Added path: "<<new_path<<endl;
00598 multi1d<LatticeFermion> vec_mu(vec.size()) ;
00599 for(int j(0);j<vec.size();j++){
00600 if(sign>0)
00601 vec_mu[j] = shift(vec[j], FORWARD, mu);
00602 else
00603 vec_mu[j] = shift(vec[j], BACKWARD, mu);
00604 }
00605 do_disco(db, Clsk , vec_mu, param, Doo, u, t, trb, p, new_path);
00606 }
00607 }
00608 }
00609 }
00610
00611
00612 void ReadOPTEigCGVecs(multi1d<LatticeFermion>& vec,
00613 CholeskyFactors& Clsk,
00614 const string& evecs_file)
00615 {
00616 QDPIO::cout<<name<<" : Reading vecs from "
00617 << evecs_file <<endl ;
00618 StopWatch swatch;
00619 swatch.reset();
00620 swatch.start();
00621
00622 int Nvecs,ldh ;
00623
00624 XMLReader file_xml;
00625
00626 QDPFileReader to(file_xml,evecs_file,QDPIO_SERIAL);
00627 read(file_xml, "/OptEigInfo/ncurEvals", Nvecs);
00628 read(file_xml, "/OptEigInfo/ldh", ldh);
00629
00630 Clsk.Nvec = Nvecs;
00631 Clsk.ldh = ldh;
00632 vec.resize(Nvecs);
00633 Clsk.evals.resize(ldh);
00634 Clsk.H.resize(ldh*ldh);
00635 Clsk.HU.resize(ldh*ldh);
00636
00637 for(int v(0);v<Nvecs;v++){
00638 XMLReader record_xml;
00639 read(to, record_xml, vec[v]);
00640 }
00641
00642 XMLReader record_xml;
00643 read(to, record_xml, Clsk.evals);
00644 read(to, record_xml, Clsk.H);
00645 read(to, record_xml, Clsk.HU);
00646 swatch.stop();
00647 QDPIO::cout<<name<<" : Time to read vecs= "
00648 << swatch.getTimeInSeconds() <<" secs "<<endl ;
00649 }
00650
00651
00652
00653 void PRchi(multi1d<multi1d< multi1d<LatticeFermion> > >& quarkstilde,
00654 const multi1d< Handle< DilutionScheme<LatticeFermion> > >& quarks,
00655 Handle<EvenOddPrecLinearOperator<T,P,Q> >& Doo,
00656 CholeskyFactors Clsk , multi1d<LatticeFermion>& vec,
00657 const Params::Param_t& param, const P& u){
00658 char U = 'U';
00659 int info;
00660
00661 int ldb = vec.size();
00662
00663 Set timerb;
00664 timerb.make(TimeSliceRBFunc(3));
00665
00666
00667 for(int n(0);n<quarks.size();n++){
00668 for (int it(0) ; it < quarks[n]->getNumTimeSlices() ; ++it){
00669 int t = quarks[n]->getT0(it) ;
00670 int Nrhs = quarks[n]->getDilSize(it) ;
00671 multi2d<Complex> B(Nrhs, ldb);
00672 for(int i(0); i<ldb;i++){
00673 for(int j = 0 ; j < Nrhs ; j++){
00674
00675
00676
00677
00678
00679
00680
00681
00682 LatticeFermion qsrc = quarks[n]->dilutedSource(it,j);
00683 LatticeFermion SdagSchi = zero ;
00684 Doo->oddOddLinOp(SdagSchi,qsrc,MINUS);
00685
00686
00687
00688 B[j][i] = sum(localInnerProduct(vec[i],SdagSchi),rb[1]);
00689
00690 }
00691 }
00692
00693 #if BASE_PRECISION == 32
00694 int r = QDPLapack::cpotrs(U, Clsk.Nvec, Nrhs, Clsk.HU, Clsk.ldh, B, ldb, info);
00695 #else
00696 int r = QDPLapack::zpotrs(U, Clsk.Nvec, Nrhs, Clsk.HU, Clsk.ldh, B, ldb, info);
00697 #endif
00698 QDPIO::cout<<"PRchi cpotrs r = "<<r<<endl;
00699 QDPIO::cout<<"PRchi cpotrs info = "<<info<<endl;
00700
00701 for(int j = 0 ; j < Nrhs ; j++){
00702 LatticeFermion vB = zero;
00703 LatticeFermion q = quarks[n]->dilutedSolution(it,j);
00704 for(int i(0); i<ldb;i++)
00705 vB += B[j][i]*vec[i];
00706 quarkstilde[n][it][j] = q - vB;
00707 cout<<"Norm of PRchi: "<<norm2(quarkstilde[n][it][j])<<endl;
00708 }
00709 }
00710 }
00711 }
00712
00713
00714
00715
00716 void PRchi(multi1d<multi1d< multi1d<LatticeFermion> > >& quarkstilde,
00717 multi1d< Handle< DilutionScheme<LatticeFermion> > >& quarks){
00718
00719 for(int n(0);n<quarks.size();n++){
00720 for (int it(0) ; it < quarks[n]->getNumTimeSlices() ; it++){
00721 for (int j(0) ; j < quarks[n]->getDilSize(it) ; j++){
00722 quarkstilde[n][it][j] = quarks[n]->dilutedSolution(it,j);
00723 }
00724 }
00725 }
00726 }
00727
00728
00729
00730
00731
00732
00733 void InlineMeas::operator()(unsigned long update_no,
00734 XMLWriter& xml_out)
00735 {
00736
00737 if (params.xml_file != ""){
00738 string xml_file = makeXMLFileName(params.xml_file, update_no);
00739
00740 push(xml_out, "discoEigCG");
00741 write(xml_out, "update_no", update_no);
00742 write(xml_out, "xml_file", xml_file);
00743 pop(xml_out);
00744
00745 XMLFileWriter xml(xml_file);
00746 func(update_no, xml);
00747 }
00748 else{
00749 func(update_no, xml_out);
00750 }
00751 }
00752
00753
00754
00755
00756
00757
00758 void InlineMeas::func(unsigned long update_no,
00759 XMLWriter& xml_out)
00760 {
00761 START_CODE();
00762
00763 StopWatch snoop;
00764 snoop.reset();
00765 snoop.start();
00766
00767
00768
00769 XMLBufferWriter gauge_xml;
00770 try
00771 {
00772 TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
00773 TheNamedObjMap::Instance().get(params.named_obj.gauge_id).getRecordXML(gauge_xml);
00774 }
00775 catch( std::bad_cast )
00776 {
00777 QDPIO::cerr << InlineDiscoEigCGEnv::name << ": caught dynamic cast error"
00778 << endl;
00779 QDP_abort(1);
00780 }
00781 catch (const string& e)
00782 {
00783 QDPIO::cerr << name << ": map call failed: " << e
00784 << endl;
00785 QDP_abort(1);
00786 }
00787 const multi1d<LatticeColorMatrix>& u =
00788 TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
00789
00790 push(xml_out, "discoEigCG");
00791 write(xml_out, "update_no", update_no);
00792
00793 QDPIO::cout << name << ": Disconnected diagrams with eigCG vectors" << endl;
00794
00795 proginfo(xml_out);
00796
00797
00798 params.write(xml_out, "Input");
00799
00800
00801 write(xml_out, "Config_info", gauge_xml);
00802
00803 push(xml_out, "Output_version");
00804 write(xml_out, "out_version", 1);
00805 pop(xml_out);
00806
00807
00808
00809 MesPlq(xml_out, "Observables", u);
00810
00811
00812 Seed ran_seed;
00813 QDP::RNG::savern(ran_seed);
00814
00815
00816
00817
00818 StopWatch swatch;
00819 swatch.reset();
00820 swatch.start();
00821
00822 int N_quarks = params.param.chi.size() ;
00823
00824 multi1d< Handle< DilutionScheme<LatticeFermion> > > quarks(N_quarks);
00825
00826 try{
00827
00828 for(int n(0); n < params.param.chi.size(); n++){
00829 const GroupXML_t& dil_xml = params.param.chi[n];
00830 std::istringstream xml_d(dil_xml.xml);
00831 XMLReader diltop(xml_d);
00832 QDPIO::cout << "Dilution type = " << dil_xml.id << endl;
00833 quarks[n] =
00834 TheFermDilutionSchemeFactory::Instance().createObject(dil_xml.id,
00835 diltop,
00836 dil_xml.path);
00837 }
00838 }
00839 catch(const std::string& e){
00840 QDPIO::cerr << name << ": Caught Exception constructing dilution scheme: " << e << endl;
00841 QDP_abort(1);
00842 }
00843
00844
00845
00846
00847
00848
00849
00850 for (int n = 1 ; n < N_quarks ; n++){
00851 if (quarks[0]->getCfgInfo() != quarks[n]->getCfgInfo()){
00852 QDPIO::cerr << name << " : Quarks do not contain the same cfg info";
00853 QDPIO::cerr << ", quark "<< n << endl;
00854 QDP_abort(1);
00855 }
00856 }
00857
00858
00859
00860 {
00861 std::string cfgInfo;
00862
00863
00864 XMLBufferWriter top;
00865 write(top, "Config_info", gauge_xml);
00866 XMLReader from(top);
00867 XMLReader from2(from, "/Config_info");
00868 std::ostringstream os;
00869 from2.print(os);
00870
00871 cfgInfo = os.str();
00872
00873 if (cfgInfo != quarks[0]->getCfgInfo()){
00874 QDPIO::cerr << name << " : Quarks do not contain the same";
00875 QDPIO::cerr << " cfg info as the gauge field." ;
00876 QDPIO::cerr << "gauge: XX"<<cfgInfo<<"XX quarks: XX" ;
00877 QDPIO::cerr << quarks[0]->getCfgInfo()<<"XX"<< endl;
00878 QDP_abort(1);
00879 }
00880 }
00881
00882 int decay_dir = quarks[0]->getDecayDir();
00883
00884
00885
00886 SftMom phases(params.param.p2_max, false, decay_dir);
00887
00888
00889 Set timerb;
00890 timerb.make(TimeSliceRBFunc(decay_dir));
00891
00892
00893
00894 for(int n = 1 ; n < quarks.size(); n++){
00895 if(toBool(quarks[n]->getSeed()==quarks[0]->getSeed())){
00896 QDPIO::cerr << name << ": error, quark seeds are the same" << endl;
00897 QDP_abort(1);
00898 }
00899
00900 if(toBool(quarks[n]->getDecayDir()!=quarks[0]->getDecayDir())){
00901 QDPIO::cerr<<name<< ": error, quark decay dirs do not match" <<endl;
00902 QDP_abort(1);
00903 }
00904 }
00905
00906
00907 Handle<EvenOddPrecLinearOperator<T,P,Q> > Doo=createOddOdd_Op(params.param,u);
00908
00909
00910 multi1d<LatticeFermion> vec;
00911 CholeskyFactors Clsk;
00912 if (params.named_obj.evecs_file!="")
00913 ReadOPTEigCGVecs(vec,Clsk,params.named_obj.evecs_file);
00914
00915 map< KeyOperator_t, ValOperator_t > data ;
00916
00917 multi1d<multi1d< multi1d<LatticeFermion> > > quarkstilde(quarks.size());
00918 for(int n(0);n<quarks.size();n++){
00919 quarkstilde[n].resize(quarks[n]->getNumTimeSlices());
00920 for (int it(0) ; it < quarks[n]->getNumTimeSlices() ; it++){
00921 quarkstilde[n][it].resize(quarks[n]->getDilSize(it));
00922 }
00923 }
00924
00925
00926
00927
00928
00929 if (params.named_obj.evecs_file!="")
00930 PRchi(quarkstilde, quarks, Doo, Clsk, vec, params.param, u);
00931 else
00932 PRchi(quarkstilde, quarks);
00933
00934 for(int n(0);n<quarks.size();n++){
00935 for (int it(0) ; it < quarks[n]->getNumTimeSlices() ; it++){
00936 int t = quarks[n]->getT0(it) ;
00937 QDPIO::cout<<" Doing quark: "<< n <<endl ;
00938 QDPIO::cout<<" quark: "<< n <<" has "<<quarks[n]->getDilSize(it);
00939 QDPIO::cout<<" dilutions on time slice "<< t <<endl ;
00940 for(int i = 0 ; i < quarks[n]->getDilSize(it) ; i++){
00941 QDPIO::cout<<" Doing dilution : "<<i<<endl ;
00942 multi1d<short int> d ;
00943
00944 LatticeFermion qbar = quarks[n]->dilutedSource(it,i);
00945 LatticeFermion q = quarkstilde[n][it][i];
00946 QDPIO::cout<<" Starting recursion "<<endl ;
00947
00948 do_disco(data, qbar, q, phases, t, d, params.param.max_path_length);
00949
00950 QDPIO::cout<<" done with recursion! "
00951 <<" The length of the path is: "<<d.size()<<endl ;
00952 }
00953 QDPIO::cout<<" Done with dilutions for quark: "<<n <<endl ;
00954 }
00955 }
00956
00957
00958
00959 SerialDBKey <KeyOperator_t> key ;
00960 SerialDBData<ValOperator_t> val ;
00961 map< KeyOperator_t, ValOperator_t >::iterator it;
00962
00963 for(it=data.begin();it!=data.end();it++){
00964 key.key() = it->first ;
00965 val.data().op.resize(it->second.op.size()) ;
00966 for(int i(0);i<it->second.op.size();i++){
00967 val.data().op[i] = it->second.op[i]/toDouble(quarks.size());
00968 }
00969 }
00970
00971
00972
00973
00974
00975 if (params.named_obj.evecs_file!=""){
00976 for (int it(0) ; it < quarks[0]->getNumTimeSlices() ; it++){
00977 multi1d<short int> d ;
00978 int t = quarks[0]->getT0(it) ;
00979 QDPIO::cout<<" Starting recursion again"<<endl ;
00980
00981 do_disco(data, Clsk, vec, params.param, Doo, u, t, timerb[2*t+1], phases,d);
00982
00983 QDPIO::cout<<" done with recursion! "
00984 <<" The length of the path is: "<<d.size()<<endl ;
00985 }
00986 }
00987
00988
00989
00990 BinaryStoreDB<SerialDBKey<KeyOperator_t>,SerialDBData<ValOperator_t> > qdp_db;
00991
00992
00993 {
00994 XMLBufferWriter file_xml;
00995
00996 push(file_xml, "DBMetaData");
00997 write(file_xml, "id", string("discoEigElemOp"));
00998 write(file_xml, "lattSize", QDP::Layout::lattSize());
00999 write(file_xml, "decay_dir", decay_dir);
01000 write(file_xml, "Params", params.param);
01001 write(file_xml, "Config_info", gauge_xml);
01002 pop(file_xml);
01003
01004 std::string file_str(file_xml.str());
01005 qdp_db.setMaxUserInfoLen(file_str.size());
01006
01007 qdp_db.open(params.named_obj.op_db_file, O_RDWR | O_CREAT, 0664);
01008
01009 qdp_db.insertUserdata(file_str);
01010 }
01011
01012
01013 for(it=data.begin();it!=data.end();it++){
01014 key.key() = it->first ;
01015 val.data().op.resize(it->second.op.size()) ;
01016
01017
01018 for(int i(0);i<it->second.op.size();i++)
01019 val.data().op[i] = it->second.op[i];
01020 qdp_db.insert(key,val) ;
01021 }
01022
01023
01024 pop(xml_out);
01025
01026 snoop.stop();
01027 QDPIO::cout << name << ": total time = "
01028 << snoop.getTimeInSeconds()
01029 << " secs" << endl;
01030
01031 QDPIO::cout << name << ": ran successfully" << endl;
01032
01033 END_CODE();
01034 }
01035 }
01036 }