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