00001
00002
00003
00004
00005
00006 #include <vector>
00007 #include <map>
00008
00009 #include "handle.h"
00010 #include "meas/inline/hadron/inline_disco_w.h"
00011 #include "meas/inline/abs_inline_measurement_factory.h"
00012 #include "meas/smear/quark_smearing_factory.h"
00013 #include "meas/smear/quark_smearing_aggregate.h"
00014 #include "meas/smear/displacement.h"
00015 #include "meas/sources/source_smearing_aggregate.h"
00016 #include "meas/sources/source_smearing_factory.h"
00017 #include "meas/sources/dilutezN_source_const.h"
00018 #include "meas/sources/zN_src.h"
00019 #include "meas/sinks/sink_smearing_aggregate.h"
00020 #include "meas/sinks/sink_smearing_factory.h"
00021 #include "meas/hadron/barspinmat_w.h"
00022 #include "meas/hadron/baryon_operator_aggregate_w.h"
00023 #include "meas/hadron/baryon_operator_factory_w.h"
00024 #include "meas/hadron/dilution_scheme_aggregate.h"
00025 #include "meas/hadron/dilution_scheme_factory.h"
00026 #include "meas/glue/mesplq.h"
00027 #include "util/ft/sftmom.h"
00028 #include "util/info/proginfo.h"
00029 #include "meas/inline/make_xml_file.h"
00030 #include "util/info/unique_id.h"
00031 #include "util/ferm/transf.h"
00032 #include "meas/inline/io/named_objmap.h"
00033
00034 #include "util/ferm/key_val_db.h"
00035
00036 namespace Chroma{
00037 namespace InlineDiscoEnv{
00038 namespace{
00039 AbsInlineMeasurement* createMeasurement(XMLReader& xml_in,
00040 const std::string& path)
00041 {
00042 return new InlineMeas(Params(xml_in, path));
00043 }
00044
00045
00046 bool registered = false;
00047 }
00048
00049 const std::string name = "DISCO";
00050
00051
00052 bool registerAll()
00053 {
00054 bool success = true;
00055 if (! registered)
00056 {
00057
00058 success &= TheInlineMeasurementFactory::Instance().registerObject(name, createMeasurement);
00059 registered = true;
00060 }
00061 return success;
00062 }
00063
00064
00065 void read(XMLReader& xml, const string& path, Params::Param_t& param){
00066 XMLReader paramtop(xml, path);
00067
00068 int version;
00069 read(paramtop, "version", version);
00070
00071 switch (version)
00072 {
00073 case 1:
00074
00075 read(paramtop,"max_path_length",param.max_path_length);
00076 read(paramtop,"p2_max",param.p2_max);
00077 read(paramtop,"mass_label",param.mass_label);
00078 param.chi = readXMLArrayGroup(paramtop, "Quarks", "DilutionType");
00079
00080 break;
00081
00082 default :
00083
00084
00085 QDPIO::cerr << "Input parameter version " << version << " unsupported." << endl;
00086 QDP_abort(1);
00087 }
00088
00089
00090 }
00091
00092
00093
00094 void write(XMLWriter& xml, const string& path, const Params::Param_t& param){
00095 push(xml, path);
00096
00097 int version = 1;
00098
00099 write(xml, "version", version);
00100
00101 write(xml,"max_path_length",param.max_path_length);
00102 write(xml,"p2_max",param.p2_max);
00103 write(xml,"mass_label",param.mass_label);
00104
00105 push(xml,"Quarks");
00106 for( int t(0);t<param.chi.size();t++){
00107 push(xml,"elem");
00108 xml<<param.chi[t].xml;
00109 pop(xml);
00110 }
00111 pop(xml);
00112
00113 pop(xml);
00114 }
00115
00116
00117
00118 void read(XMLReader& xml, const string& path, Params::NamedObject_t& input)
00119 {
00120 XMLReader inputtop(xml, path);
00121
00122 read(inputtop, "gauge_id", input.gauge_id);
00123 read(inputtop, "op_db_file", input.op_db_file);
00124 }
00125
00126
00127 void write(XMLWriter& xml, const string& path, const Params::NamedObject_t& input){
00128 push(xml, path);
00129
00130 write(xml, "gauge_id", input.gauge_id);
00131 write(xml, "op_db_file", input.op_db_file);
00132 pop(xml);
00133 }
00134
00135
00136
00137 Params::Params(){
00138 frequency = 0;
00139 }
00140
00141 Params::Params(XMLReader& xml_in, const std::string& path)
00142 {
00143 try
00144 {
00145 XMLReader paramtop(xml_in, path);
00146
00147 if (paramtop.count("Frequency") == 1)
00148 read(paramtop, "Frequency", frequency);
00149 else
00150 frequency = 1;
00151
00152
00153 read(paramtop, "Param", param);
00154
00155
00156 read(paramtop, "NamedObject", named_obj);
00157
00158
00159 if (paramtop.count("xml_file") != 0)
00160 {
00161 read(paramtop, "xml_file", xml_file);
00162 }
00163 }
00164 catch(const std::string& e)
00165 {
00166 QDPIO::cerr << __func__ << ": Caught Exception reading XML: " << e << endl;
00167 QDP_abort(1);
00168 }
00169 }
00170
00171
00172 void Params::write(XMLWriter& xml_out, const std::string& path)
00173 {
00174 push(xml_out, path);
00175
00176
00177 InlineDiscoEnv::write(xml_out, "Param", param);
00178
00179
00180 InlineDiscoEnv::write(xml_out, "NamedObject", named_obj);
00181
00182 pop(xml_out);
00183 }
00184
00185
00186
00187 struct KeyOperator_t
00188 {
00189 unsigned short int t_slice ;
00190 multi1d<short int> disp ;
00191 multi1d<short int> mom ;
00192
00193 KeyOperator_t(){
00194 mom.resize(Nd-1);
00195 }
00196 };
00197
00198 bool operator<(const KeyOperator_t& a, const KeyOperator_t& b){
00199 return ((a.t_slice<b.t_slice)||(a.mom<b.mom)||(a.disp<b.disp));
00200 }
00201
00202 std::ostream& operator<<(std::ostream& os, const KeyOperator_t& d)
00203 {
00204 os << "KeyOperator_t:"
00205 << " t_slice = " << d.t_slice
00206 << ", disp = ";
00207 for (int i=0; i<d.disp.size();i++){
00208 os << d.disp[i] << " " ;
00209 }
00210 os << ", mom = ";
00211 for (int i=0; i<d.mom.size();i++){
00212 os << d.mom[i] << " " ;
00213 }
00214 os << std::endl;
00215
00216 return os;
00217 }
00218 class ValOperator_t{
00219 public:
00220 multi1d<ComplexD> op ;
00221 ValOperator_t(){op.resize(Ns*Ns);}
00222 ~ValOperator_t(){}
00223 } ;
00224
00225
00226
00227 std::ostream& operator<<(std::ostream& os, const ValOperator_t& d)
00228 {
00229 os << "ValOperator_t:\n";
00230 for (int i=0; i<d.op.size();i++){
00231 os <<" gamma["<<i<<"] = "<< d.op[i] << endl ;
00232 }
00233
00234 return os;
00235 }
00236
00237 struct KeyVal_t{
00238 SerialDBKey <KeyOperator_t> k ;
00239 SerialDBData<ValOperator_t> v ;
00240 };
00241
00242
00243 void read(BinaryReader& bin, KeyOperator_t& d){
00244 read(bin,d.t_slice);
00245 unsigned short int n ;
00246 read(bin,n);
00247 d.disp.resize(n);
00248 read(bin,d.disp);
00249 d.mom.resize(Nd-1) ;
00250 read(bin,d.mom);
00251 }
00252
00253 void write(BinaryWriter& bin, KeyOperator_t& d){
00254 write(bin,d.t_slice);
00255 unsigned short int n ;
00256 n = d.disp.size();
00257 write(bin,n);
00258 write(bin,d.disp);
00259 write(bin,d.mom);
00260 }
00261
00262
00263 void read(BinaryReader& bin, ValOperator_t& d){
00264 d.op.resize(Ns*Ns);
00265 read(bin,d.op);
00266 }
00267
00268 void write(BinaryWriter& bin, ValOperator_t& d){
00269 write(bin,d.op);
00270 }
00271
00272 namespace{
00273 StandardOutputStream& operator<<(StandardOutputStream& os, const multi1d<short int>& d){
00274 if (d.size() > 0){
00275 os << d[0];
00276 for(int i=1; i < d.size(); ++i)
00277 os << " " << d[i];
00278 }
00279 return os;
00280 }
00281 }
00282
00283 void do_disco(map< KeyOperator_t, ValOperator_t >& db,
00284 const LatticeFermion& qbar,
00285 const LatticeFermion& q,
00286 const SftMom& p,
00287 const int& t,
00288 const multi1d<short int>& path,
00289 const int& max_path_length ){
00290 QDPIO::cout<<" Computing Operator with path length "<<path.size()
00291 <<" on timeslice "<<t<<". Path: "<<path <<endl;
00292
00293 ValOperator_t val ;
00294 KeyOperator_t key ;
00295 pair<KeyOperator_t, ValOperator_t> kv ;
00296 kv.first.t_slice = t ;
00297 if(path.size()==0){
00298 kv.first.disp.resize(1);
00299 kv.first.disp[0] = 0 ;
00300 }
00301 else
00302 kv.first.disp = path ;
00303
00304 multi1d< multi1d<ComplexD> > foo(p.numMom()) ;
00305 for (int m(0); m < p.numMom(); m++)
00306 foo[m].resize(Ns*Ns);
00307 for(int g(0);g<Ns*Ns;g++){
00308 LatticeComplex cc = localInnerProduct(qbar,Gamma(g)*q);
00309 for (int m(0); m < p.numMom(); m++){
00310 foo[m][g] = sum(p[m]*cc,p.getSet()[t]) ;
00311 }
00312 }
00313 for (int m(0); m < p.numMom(); m++){
00314 for(int i(0);i<(Nd-1);i++)
00315 kv.first.mom[i] = p.numToMom(m)[i] ;
00316
00317 kv.second.op = foo[m];
00318 pair<map< KeyOperator_t, ValOperator_t >::iterator, bool> itbo;
00319
00320 itbo = db.insert(kv);
00321 if( itbo.second ){
00322 QDPIO::cout<<"Inserting new entry in map\n";
00323 }
00324 else{
00325 cout<<"Key = "<<kv.first<<endl;
00326 QDPIO::cout<<"Adding result to value already there"<<endl;
00327 for(int i(0);i<kv.second.op.size();i++){
00328 itbo.first->second.op[i] += kv.second.op[i] ;
00329 }
00330 }
00331 }
00332
00333 if(path.size()<max_path_length){
00334 QDPIO::cout<<" attempt to add new path. "
00335 <<" current path length is : "<<path.size();
00336 multi1d<short int> new_path(path.size()+1);
00337 QDPIO::cout<<" new path length is : "<<new_path.size()<<endl;
00338 for(int i(0);i<path.size();i++)
00339 new_path[i] = path[i] ;
00340 for(int sign(-1);sign<2;sign+=2)
00341 for(int mu(0);mu<Nd;mu++){
00342 new_path[path.size()]= sign*(mu+1) ;
00343
00344 bool back_track=false ;
00345 if(path.size()>0)
00346 if(path[path.size()-1] == -new_path[path.size()])
00347 back_track=true;
00348 if(!back_track){
00349 QDPIO::cout<<" Added path: "<<new_path<<endl;
00350 LatticeFermion q_mu ;
00351 if(sign>0)
00352 q_mu = shift(q, FORWARD, mu);
00353 else
00354 q_mu = shift(q, BACKWARD, mu);
00355
00356 do_disco(db, qbar, q_mu, p, t, new_path, max_path_length);
00357 }
00358 }
00359 }
00360
00361 }
00362
00363
00364
00365
00366
00367
00368
00369 void InlineMeas::operator()(unsigned long update_no,
00370 XMLWriter& xml_out)
00371 {
00372
00373 if (params.xml_file != ""){
00374 string xml_file = makeXMLFileName(params.xml_file, update_no);
00375
00376 push(xml_out, "propagator_3pt");
00377 write(xml_out, "update_no", update_no);
00378 write(xml_out, "xml_file", xml_file);
00379 pop(xml_out);
00380
00381 XMLFileWriter xml(xml_file);
00382 func(update_no, xml);
00383 }
00384 else{
00385 func(update_no, xml_out);
00386 }
00387 }
00388
00389
00390
00391
00392
00393
00394 void InlineMeas::func(unsigned long update_no,
00395 XMLWriter& xml_out)
00396 {
00397 START_CODE();
00398
00399 StopWatch snoop;
00400 snoop.reset();
00401 snoop.start();
00402
00403
00404 XMLBufferWriter gauge_xml;
00405 try
00406 {
00407 TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
00408 TheNamedObjMap::Instance().get(params.named_obj.gauge_id).getRecordXML(gauge_xml);
00409 }
00410 catch( std::bad_cast )
00411 {
00412 QDPIO::cerr << InlineDiscoEnv::name << ": caught dynamic cast error"
00413 << endl;
00414 QDP_abort(1);
00415 }
00416 catch (const string& e)
00417 {
00418 QDPIO::cerr << name << ": map call failed: " << e
00419 << endl;
00420 QDP_abort(1);
00421 }
00422 const multi1d<LatticeColorMatrix>& u =
00423 TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
00424
00425 push(xml_out, "disco");
00426 write(xml_out, "update_no", update_no);
00427
00428 QDPIO::cout << name << ": Disconnected diagrams" << endl;
00429
00430 proginfo(xml_out);
00431
00432
00433 params.write(xml_out, "Input");
00434
00435
00436 write(xml_out, "Config_info", gauge_xml);
00437
00438 push(xml_out, "Output_version");
00439 write(xml_out, "out_version", 1);
00440 pop(xml_out);
00441
00442
00443
00444 MesPlq(xml_out, "Observables", u);
00445
00446
00447 Seed ran_seed;
00448 QDP::RNG::savern(ran_seed);
00449
00450
00451
00452
00453 StopWatch swatch;
00454 swatch.reset();
00455 swatch.start();
00456
00457 int N_quarks = params.param.chi.size() ;
00458
00459 multi1d< Handle< DilutionScheme<LatticeFermion> > > quarks(N_quarks);
00460
00461 try{
00462
00463 for(int n(0); n < params.param.chi.size(); ++n){
00464 const GroupXML_t& dil_xml = params.param.chi[n];
00465 std::istringstream xml_d(dil_xml.xml);
00466 XMLReader diltop(xml_d);
00467 QDPIO::cout << "Dilution type = " << dil_xml.id << endl;
00468 quarks[n] =
00469 TheFermDilutionSchemeFactory::Instance().createObject(dil_xml.id,
00470 diltop,
00471 dil_xml.path);
00472 }
00473 }
00474 catch(const std::string& e){
00475 QDPIO::cerr << name << ": Caught Exception constructing dilution scheme: " << e << endl;
00476 QDP_abort(1);
00477 }
00478
00479
00480
00481
00482
00483
00484
00485 for (int n = 1 ; n < N_quarks ; ++n){
00486 if (quarks[0]->getCfgInfo() != quarks[n]->getCfgInfo()){
00487 QDPIO::cerr << name << " : Quarks do not contain the same cfg info";
00488 QDPIO::cerr << ", quark "<< n << endl;
00489 QDP_abort(1);
00490 }
00491 }
00492
00493
00494
00495
00496 {
00497 std::string cfgInfo;
00498
00499
00500 XMLBufferWriter top;
00501 write(top, "Config_info", gauge_xml);
00502 XMLReader from(top);
00503 XMLReader from2(from, "/Config_info");
00504 std::ostringstream os;
00505 from2.print(os);
00506
00507 cfgInfo = os.str();
00508
00509 if (cfgInfo != quarks[0]->getCfgInfo()){
00510 QDPIO::cerr << name << " : Quarks do not contain the same";
00511 QDPIO::cerr << " cfg info as the gauge field." ;
00512 QDPIO::cerr << "gauge: XX"<<cfgInfo<<"XX quarks: XX" ;
00513 QDPIO::cerr << quarks[0]->getCfgInfo()<<"XX"<< endl;
00514 QDP_abort(1);
00515 }
00516 }
00517
00518
00519 int decay_dir = quarks[0]->getDecayDir();
00520
00521
00522
00523
00524 SftMom phases(params.param.p2_max, false, decay_dir);
00525
00526
00527
00528 for(int n = 1 ; n < quarks.size(); ++n){
00529 if(toBool(quarks[n]->getSeed()==quarks[0]->getSeed())){
00530 QDPIO::cerr << name << ": error, quark seeds are the same" << endl;
00531 QDP_abort(1);
00532 }
00533
00534 if(toBool(quarks[n]->getDecayDir()!=quarks[0]->getDecayDir())){
00535 QDPIO::cerr<<name<< ": error, quark decay dirs do not match" <<endl;
00536 QDP_abort(1);
00537 }
00538 }
00539
00540 map< KeyOperator_t, ValOperator_t > data ;
00541
00542 for(int n(0);n<quarks.size();n++){
00543 for (int it(0) ; it < quarks[n]->getNumTimeSlices() ; ++it){
00544 int t = quarks[n]->getT0(it) ;
00545 QDPIO::cout<<" Doing quark: "<<n <<endl ;
00546 QDPIO::cout<<" quark: "<<n <<" has "<<quarks[n]->getDilSize(it);
00547 QDPIO::cout<<" dilutions on time slice "<<t<<endl ;
00548 for(int i = 0 ; i < quarks[n]->getDilSize(it) ; ++i){
00549 QDPIO::cout<<" Doing dilution : "<<i<<endl ;
00550 multi1d<short int> d ;
00551 LatticeFermion qbar = quarks[n]->dilutedSource(it,i);
00552 LatticeFermion q = quarks[n]->dilutedSolution(it,i);
00553 QDPIO::cout<<" Starting recursion "<<endl ;
00554 do_disco(data, qbar, q, phases, t, d, params.param.max_path_length);
00555 QDPIO::cout<<" done with recursion! "
00556 <<" The length of the path is: "<<d.size()<<endl ;
00557 }
00558 QDPIO::cout<<" Done with dilutions for quark: "<<n <<endl ;
00559 }
00560 }
00561
00562
00563 BinaryStoreDB<SerialDBKey<KeyOperator_t>,SerialDBData<ValOperator_t> > qdp_db;
00564
00565
00566 {
00567 XMLBufferWriter file_xml;
00568
00569 push(file_xml, "DBMetaData");
00570 write(file_xml, "id", string("eigElemOp"));
00571 write(file_xml, "lattSize", QDP::Layout::lattSize());
00572 write(file_xml, "decay_dir", decay_dir);
00573 write(file_xml, "Params", params.param);
00574 write(file_xml, "Config_info", gauge_xml);
00575 pop(file_xml);
00576
00577 std::string file_str(file_xml.str());
00578 qdp_db.setMaxUserInfoLen(file_str.size());
00579
00580 qdp_db.open(params.named_obj.op_db_file, O_RDWR | O_CREAT, 0664);
00581
00582 qdp_db.insertUserdata(file_str);
00583 }
00584
00585
00586 SerialDBKey <KeyOperator_t> key ;
00587 SerialDBData<ValOperator_t> val ;
00588 map< KeyOperator_t, ValOperator_t >::iterator it;
00589 for(it=data.begin();it!=data.end();it++){
00590 key.key() = it->first ;
00591 val.data().op.resize(it->second.op.size()) ;
00592
00593 for(int i(0);i<it->second.op.size();i++)
00594 val.data().op[i] = it->second.op[i]/toDouble(quarks.size());
00595 qdp_db.insert(key,val) ;
00596 }
00597
00598
00599 pop(xml_out);
00600
00601 snoop.stop();
00602 QDPIO::cout << name << ": total time = "
00603 << snoop.getTimeInSeconds()
00604 << " secs" << endl;
00605
00606 QDPIO::cout << name << ": ran successfully" << endl;
00607
00608 END_CODE();
00609 }
00610 }
00611 }