Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-05-05 02:47:10

0001 #include "CondCore/CondDB/interface/ConnectionPool.h"
0002 #include "CondCore/CondDB/interface/IOVProxy.h"
0003 #include "CondCore/CondDB/interface/GTProxy.h"
0004 
0005 #include "CondCore/Utilities/interface/Utilities.h"
0006 #include "CondCore/Utilities/interface/CondDBImport.h"
0007 #include <iostream>
0008 #include <fstream>
0009 
0010 #include <chrono>
0011 #include <memory>
0012 
0013 #include <boost/thread/mutex.hpp>
0014 #include "oneapi/tbb/parallel_for_each.h"
0015 #include "oneapi/tbb/global_control.h"
0016 
0017 namespace cond {
0018 
0019   using namespace persistency;
0020 
0021   class ConnectionPoolWrapper {
0022   public:
0023     ConnectionPoolWrapper(int authenticationSystem, const std::string& authenticationPath, bool debug);
0024     Session createSession(const std::string& connectionString);
0025     boost::mutex lock;
0026     ConnectionPool connPool;
0027   };
0028 
0029   class UntypedPayloadProxy {
0030   public:
0031     UntypedPayloadProxy();
0032 
0033     UntypedPayloadProxy(const UntypedPayloadProxy& rhs);
0034 
0035     UntypedPayloadProxy& operator=(const UntypedPayloadProxy& rhs);
0036 
0037     void init(Session session);
0038 
0039     void load(const std::string& tag);
0040 
0041     void reload();
0042 
0043     void reset();
0044 
0045     void disconnect();
0046 
0047     TimeType timeType() const;
0048     std::string tag() const;
0049     std::string payloadType() const;
0050 
0051     bool get(cond::Time_t targetTime, bool debug);
0052 
0053     size_t numberOfQueries() const;
0054 
0055     const std::vector<std::string>& history() const;
0056 
0057     const Binary& getBuffer() const;
0058     size_t getBufferSize() const;
0059 
0060     const Binary& getStreamerInfo() const;
0061 
0062     void setRecordInfo(const std::string& recName, const std::string& recLabel) {
0063       m_recName = recName;
0064       m_recLabel = recLabel;
0065     }
0066 
0067     const std::string recName() const { return m_recName; }
0068     const std::string recLabel() const { return m_recLabel; }
0069 
0070   private:
0071     struct pimpl {
0072       cond::Iov_t current;
0073       std::vector<std::string> history;
0074     };
0075 
0076     Session m_session;
0077     IOVProxy m_iov;
0078     std::shared_ptr<pimpl> m_data;
0079 
0080     Binary m_buffer;
0081     Binary m_streamerInfo;
0082 
0083     std::string m_recName;
0084     std::string m_recLabel;
0085 
0086   };  //  end class UntypedPayloadProxy
0087 
0088   class TestGTPerf : public cond::Utilities {
0089   public:
0090     TestGTPerf();
0091     int execute() override;
0092   };  // end class TestGTLoad
0093 
0094 }  // end namespace cond
0095 
0096 cond::ConnectionPoolWrapper::ConnectionPoolWrapper(int authenticationSystem,
0097                                                    const std::string& authenticationPath,
0098                                                    bool debug) {
0099   connPool.setAuthenticationSystem(authenticationSystem);
0100   if (!authenticationPath.empty())
0101     connPool.setAuthenticationPath(authenticationPath);
0102   if (debug)
0103     connPool.setMessageVerbosity(coral::Debug);
0104   connPool.configure();
0105 }
0106 
0107 cond::Session cond::ConnectionPoolWrapper::createSession(const std::string& connectionString) {
0108   Session s;
0109   {
0110     boost::mutex::scoped_lock slock(lock);
0111     s = connPool.createSession(connectionString);
0112   }
0113   return s;
0114 }
0115 
0116 cond::UntypedPayloadProxy::UntypedPayloadProxy() : m_session(), m_iov(), m_data(), m_buffer() {
0117   m_data.reset(new pimpl);
0118   m_data->current.clear();
0119 }
0120 
0121 cond::UntypedPayloadProxy::UntypedPayloadProxy(const UntypedPayloadProxy& rhs)
0122     : m_session(rhs.m_session), m_iov(rhs.m_iov), m_data(rhs.m_data), m_buffer(rhs.m_buffer) {}
0123 
0124 cond::UntypedPayloadProxy& cond::UntypedPayloadProxy::operator=(const cond::UntypedPayloadProxy& rhs) {
0125   m_session = rhs.m_session;
0126   m_iov = rhs.m_iov;
0127   m_data = rhs.m_data;
0128   m_buffer = rhs.m_buffer;
0129   return *this;
0130 }
0131 
0132 void cond::UntypedPayloadProxy::init(Session session) {
0133   m_session = session;
0134   reset();
0135 }
0136 
0137 void cond::UntypedPayloadProxy::load(const std::string& tag) {
0138   m_data->current.clear();
0139   m_session.transaction().start();
0140   m_iov = m_session.readIov(tag);
0141   m_session.transaction().commit();
0142 }
0143 
0144 void cond::UntypedPayloadProxy::reload() {
0145   std::string tag = m_iov.tagInfo().name;
0146   load(tag);
0147 }
0148 
0149 void cond::UntypedPayloadProxy::reset() {
0150   m_iov.reset();
0151   m_data->current.clear();
0152 }
0153 
0154 void cond::UntypedPayloadProxy::disconnect() { m_session.close(); }
0155 
0156 std::string cond::UntypedPayloadProxy::tag() const { return m_iov.tagInfo().name; }
0157 
0158 cond::TimeType cond::UntypedPayloadProxy::timeType() const { return m_iov.tagInfo().timeType; }
0159 
0160 std::string cond::UntypedPayloadProxy::payloadType() const { return m_iov.tagInfo().payloadType; }
0161 
0162 bool cond::UntypedPayloadProxy::get(cond::Time_t targetTime, bool debug) {
0163   bool loaded = false;
0164 
0165   //  check if the current iov loaded is the good one...
0166   if (targetTime < m_data->current.since || targetTime >= m_data->current.till) {
0167     // a new payload is required!
0168     if (debug)
0169       std::cout << " Searching tag " << m_iov.tagInfo().name << " for a valid payload for time=" << targetTime
0170                 << std::endl;
0171     m_session.transaction().start();
0172     auto iovs = m_iov.selectAll();
0173     auto iIov = iovs.find(targetTime);
0174     if (iIov == iovs.end())
0175       cond::throwException(std::string("Tag ") + m_iov.tagInfo().name +
0176                                ": No iov available for the target time:" + std::to_string(targetTime),
0177                            "UntypedPayloadProxy::get");
0178     m_data->current = *iIov;
0179 
0180     std::string payloadType("");
0181     loaded = m_session.fetchPayloadData(m_data->current.payloadId, payloadType, m_buffer, m_streamerInfo);
0182     m_session.transaction().commit();
0183 
0184     if (!loaded) {
0185       std::cout << "ERROR: payload with id " << m_data->current.payloadId << " could not be loaded." << std::endl;
0186     } else {
0187       if (debug)
0188         std::cout << "Loaded payload of type \"" << payloadType << "\" (" << m_buffer.size() << " bytes)" << std::endl;
0189     }
0190   }
0191   return loaded;
0192 }
0193 
0194 size_t cond::UntypedPayloadProxy::numberOfQueries() const { return m_iov.numberOfQueries(); }
0195 
0196 const std::vector<std::string>& cond::UntypedPayloadProxy::history() const { return m_data->history; }
0197 
0198 size_t cond::UntypedPayloadProxy::getBufferSize() const { return m_buffer.size(); }
0199 
0200 const cond::Binary& cond::UntypedPayloadProxy::getBuffer() const { return m_buffer; }
0201 
0202 const cond::Binary& cond::UntypedPayloadProxy::getStreamerInfo() const { return m_streamerInfo; }
0203 
0204 // ================================================================================
0205 
0206 class Timer {
0207 public:
0208   Timer(const std::string& nameIn) : name(nameIn) { reset(); }
0209   void reset() {
0210     start = std::chrono::steady_clock::now();
0211     intervals.clear();
0212     intervalNames.clear();
0213     interval("start");
0214   }
0215 
0216   void interval(const std::string& intName) {
0217     intervals.push_back(std::chrono::steady_clock::now());
0218     intervalNames.push_back(intName);
0219   }
0220 
0221   void fetchInt(size_t sizeIn) {
0222     fetchTime.push_back(std::chrono::steady_clock::now());
0223     fetchNum.push_back(sizeIn);
0224   }
0225   void deserInt(size_t sizeIn) {
0226     deserTime.push_back(std::chrono::steady_clock::now());
0227     deserNum.push_back(sizeIn);
0228   }
0229 
0230   void show(std::ostream& os = std::cout) {
0231     showIntervals(os);
0232     showFetchInfo(os);
0233     showDeserInfo(os);
0234   }
0235   void showIntervals(std::ostream& os = std::cout);
0236   void showFetchInfo(std::ostream& os = std::cout);
0237   void showDeserInfo(std::ostream& os = std::cout);
0238 
0239 private:
0240   std::string name;
0241 
0242   std::chrono::time_point<std::chrono::steady_clock> start;
0243 
0244   std::vector<std::chrono::time_point<std::chrono::steady_clock> > intervals;
0245   std::vector<std::string> intervalNames;
0246 
0247   std::vector<std::chrono::time_point<std::chrono::steady_clock> > fetchTime;
0248   std::vector<int> fetchNum;
0249 
0250   std::vector<std::chrono::time_point<std::chrono::steady_clock> > deserTime;
0251   std::vector<int> deserNum;
0252 };
0253 
0254 void Timer::showIntervals(std::ostream& os) {
0255   os << std::endl;
0256   os << "Serialization type: " << name << std::endl;
0257   for (size_t i = 1; i < intervals.size(); i++) {
0258     os << intervalNames[i] << " : "
0259        << std::chrono::duration<double, std::milli>(intervals[i] - intervals[i - 1]).count() << " msec. " << std::endl;
0260   }
0261   os << "\noverall time elapsed"
0262      << " : " << std::chrono::duration<double, std::milli>(intervals[intervals.size() - 1] - intervals[0]).count()
0263      << " msec. " << std::endl;
0264   os << std::endl;
0265 }
0266 
0267 void Timer::showFetchInfo(std::ostream& os) {
0268   os << std::endl;
0269   os << "Serialization type: " << name << std::endl;
0270   if (fetchTime.empty()) {
0271     os << "No fetch info available." << std::endl;
0272     return;
0273   }
0274   int totSize = 0;
0275   for (size_t i = 1; i < fetchTime.size(); i++) {
0276     totSize += fetchNum[i];
0277     auto delta = std::chrono::duration<double, std::milli>(fetchTime[i] - fetchTime[i - 1]).count();
0278     os << fetchNum[i] << " : " << delta << " ms (" << float(fetchNum[i]) / (1024. * float(delta)) << " MB/s)"
0279        << std::endl;
0280   }
0281   auto deltaAll = std::chrono::duration<double, std::milli>(fetchTime[fetchTime.size() - 1] - fetchTime[0]).count();
0282   os << "\noverall time for " << totSize << " bytes : " << deltaAll << " ms ("
0283      << float(totSize) / (1024. * float(deltaAll)) << " MB/s)" << std::endl;
0284   os << std::endl;
0285 }
0286 
0287 void Timer::showDeserInfo(std::ostream& os) {
0288   os << std::endl;
0289   os << "Serialization type: " << name << std::endl;
0290   if (deserTime.empty()) {
0291     os << "No deserialization info available." << std::endl;
0292     return;
0293   }
0294   int totSize = 0;
0295   for (size_t i = 1; i < deserTime.size(); i++) {
0296     totSize += deserNum[i];
0297     auto delta = std::chrono::duration<double, std::milli>(deserTime[i] - deserTime[i - 1]).count();
0298     os << deserNum[i] << " : " << delta << " ms (" << float(deserNum[i]) / (1024. * float(delta)) << " MB/s)"
0299        << std::endl;
0300   }
0301   auto deltaAll = std::chrono::duration<double, std::milli>(deserTime[deserTime.size() - 1] - deserTime[0]).count();
0302   os << "\noverall time for " << totSize << " bytes : " << deltaAll << " ms ("
0303      << float(totSize) / (1024. * float(deltaAll)) << " MB/s)" << std::endl;
0304   os << std::endl;
0305 }
0306 
0307 // ================================================================================
0308 
0309 cond::TestGTPerf::TestGTPerf() : Utilities("conddb_test_gt_load") {
0310   addConnectOption("connect", "c", "database connection string(required)");
0311   addAuthenticationOptions();
0312   addOption<size_t>("iterations", "n", "number of iterations (default=10)");
0313   addOption<Time_t>("start_run", "R", "start for Run iterations (default=150005)");
0314   addOption<Time_t>("step_run", "r", "step for Run iterations (default=1000)");
0315   addOption<Time_t>("start_ts", "T", "start for TS iterations (default=5800013687234232320)");
0316   addOption<Time_t>("step_ts", "t", "step for TS iterations (default=10000000000000)");
0317   addOption<Time_t>("start_lumi", "L", "start for Lumi iterations (default=908900979179966)");
0318   addOption<Time_t>("step_lumi", "l", "step for Lumi iterations (default=10000000000)");
0319   addOption<std::string>("globaltag", "g", "global tag (required)");
0320   addOption<bool>("verbose", "v", "verbose print out (optional)");
0321   addOption<int>("n_fetch", "f", "number of threads to load payloads (default=1)");
0322   addOption<int>("n_deser", "d", "number of threads do deserialize payloads (default=1)");
0323 }
0324 
0325 // thread helpers
0326 
0327 // global counter for dummy thread measurements:
0328 volatile int fooGlobal = 0;
0329 
0330 class FetchWorker {
0331 private:
0332   cond::ConnectionPoolWrapper& connectionPool;
0333   std::string connectionString;
0334   cond::UntypedPayloadProxy* p;
0335   std::map<std::string, size_t>* requests;
0336   cond::Time_t runSel;
0337   cond::Time_t lumiSel;
0338   cond::Time_t tsSel;
0339 
0340   boost::mutex my_lock;
0341 
0342 public:
0343   FetchWorker(cond::ConnectionPoolWrapper& connPool,
0344               const std::string& connString,
0345               cond::UntypedPayloadProxy* pIn,
0346               std::map<std::string, size_t>* reqIn,
0347               const cond::Time_t& run,
0348               const cond::Time_t& lumi,
0349               const cond::Time_t& ts)
0350       : connectionPool(connPool),
0351         connectionString(connString),
0352         p(pIn),
0353         requests(reqIn),
0354         runSel(run),
0355         lumiSel(lumi),
0356         tsSel(ts) {}
0357 
0358   void run() { runReal(); }
0359 
0360   void runFake() { fooGlobal++; }
0361   void runReal() {
0362     bool debug = false;
0363     bool loaded = false;
0364     cond::time::TimeType ttype = p->timeType();
0365     auto r = requests->find(p->tag());
0366     cond::Session s;
0367     try {
0368       s = connectionPool.createSession(connectionString);
0369       p->init(s);
0370       p->reload();
0371       if (ttype == cond::runnumber) {
0372         p->get(runSel, debug);
0373         boost::mutex::scoped_lock slock(my_lock);
0374         r->second++;
0375       } else if (ttype == cond::lumiid) {
0376         p->get(lumiSel, debug);
0377         boost::mutex::scoped_lock slock(my_lock);
0378         r->second++;
0379       } else if (ttype == cond::timestamp) {
0380         p->get(tsSel, debug);
0381         boost::mutex my_lock;
0382         r->second++;
0383       } else {
0384         std::cout << "WARNING: iov request on tag " << p->tag()
0385                   << " (timeType=" << cond::time::timeTypeName(p->timeType()) << ") has been skipped." << std::endl;
0386       }
0387       s.close();
0388       //-ap:  not thread-safe!  timex.fetchInt(p->getBufferSize()); // keep track of time vs. size
0389     } catch (const cond::Exception& e) {
0390       std::cout << "ERROR:" << e.what() << std::endl;
0391     }
0392   }
0393 };
0394 
0395 class DeserialWorker {
0396 private:
0397   cond::UntypedPayloadProxy* p;
0398   std::shared_ptr<void> payload;
0399   boost::mutex my_lock;
0400 
0401 public:
0402   DeserialWorker(cond::UntypedPayloadProxy* pIn, std::shared_ptr<void>& plIn) : p(pIn), payload(plIn) {}
0403 
0404   void run() { runReal(); }
0405 
0406   void runFake() { fooGlobal++; }
0407   void runReal() {
0408     std::shared_ptr<void> payloadPtr;
0409     std::string payloadTypeName = p->payloadType();
0410     const cond::Binary& buffer = p->getBuffer();
0411     const cond::Binary& streamerInfo = p->getStreamerInfo();
0412 
0413     auto result = std::make_unique<std::pair<std::string, std::shared_ptr<void> > >(
0414         cond::persistency::fetchOne(payloadTypeName, buffer, streamerInfo, payloadPtr));
0415     payload = result->second;
0416 
0417     return;
0418   }
0419 };
0420 
0421 template <typename T>
0422 struct invoker {
0423   void operator()(T& it) const { it->run(); }
0424 };
0425 
0426 int cond::TestGTPerf::execute() {
0427   std::string gtag = getOptionValue<std::string>("globaltag");
0428   bool debug = hasDebug();
0429   std::string connect = getOptionValue<std::string>("connect");
0430   bool verbose = hasOptionValue("verbose");
0431 
0432   int nThrF = getOptionValue<int>("n_fetch");
0433   int nThrD = getOptionValue<int>("n_deser");
0434   std::cout << "\n++> going to use " << nThrF << " threads for loading, " << nThrD << " threads for deserialization. \n"
0435             << std::endl;
0436 
0437   std::string serType = "unknown";
0438   if (connect.find("CMS_CONDITIONS") != -1) {
0439     serType = "ROOT-5";
0440   } else if (connect.find("CMS_TEST_CONDITIONS") != -1) {
0441     serType = "boost";
0442   }
0443 
0444   Time_t startRun = 150005;
0445   if (hasOptionValue("start_run"))
0446     startRun = getOptionValue<Time_t>("start_run");
0447   Time_t startTs = 5800013687234232320;
0448   if (hasOptionValue("start_ts"))
0449     startTs = getOptionValue<Time_t>("start_ts");
0450   Time_t startLumi = 908900979179966;
0451   if (hasOptionValue("start_lumi"))
0452     startLumi = getOptionValue<Time_t>("start_lumi");
0453 
0454   std::string authPath("");
0455   if (hasOptionValue("authPath"))
0456     authPath = getOptionValue<std::string>("authPath");
0457 
0458   initializePluginManager();
0459 
0460   Timer timex(serType);
0461 
0462   ConnectionPoolWrapper connPool(1, authPath, hasDebug());
0463   Session session = connPool.createSession(connect);
0464   session.transaction().start();
0465 
0466   std::cout << "Loading Global Tag " << gtag << std::endl;
0467   GTProxy gt = session.readGlobalTag(gtag);
0468 
0469   session.transaction().commit();
0470 
0471   std::cout << "Loading " << gt.size() << " tags..." << std::endl;
0472   std::vector<UntypedPayloadProxy*> proxies;
0473   std::map<std::string, size_t> requests;
0474   for (const auto& t : gt) {
0475     UntypedPayloadProxy* p = new UntypedPayloadProxy;
0476     p->init(session);
0477     try {
0478       p->load(t.tagName());
0479       if (nThrF == 1) {  // detailed info only needed in single-threaded mode to get the types/names
0480         p->setRecordInfo(t.recordName(), t.recordLabel());
0481       }
0482       proxies.push_back(p);
0483       requests.insert(std::make_pair(t.tagName(), 0));
0484     } catch (const cond::Exception& e) {
0485       std::cout << "ERROR: " << e.what() << std::endl;
0486     }
0487   }
0488   std::cout << proxies.size() << " tags successfully loaded." << std::endl;
0489   timex.interval("loading iovs");
0490 
0491   Time_t run = startRun;
0492   Time_t lumi = startLumi;
0493   Time_t ts = startTs;
0494 
0495   if (nThrF > 1)
0496     session.transaction().commit();
0497 
0498   tbb::global_control init(tbb::global_control::max_allowed_parallelism, nThrF);
0499   std::vector<std::shared_ptr<FetchWorker> > tasks;
0500 
0501   std::string payloadTypeName;
0502   for (auto p : proxies) {
0503     payloadTypeName = p->payloadType();
0504     // ignore problematic ones for now
0505     if ((payloadTypeName == "SiPixelGainCalibrationOffline")  // 2 * 133 MB !!!
0506     ) {
0507       std::cout << "WARNING: Ignoring problematic payload of type " << payloadTypeName << std::endl;
0508       continue;
0509     }
0510 
0511     if (nThrF > 1) {
0512       auto fw =
0513           std::make_shared<FetchWorker>(connPool, connect, p, (std::map<std::string, size_t>*)&requests, run, lumi, ts);
0514       tasks.push_back(fw);
0515     } else {
0516       bool loaded = false;
0517       time::TimeType ttype = p->timeType();
0518       auto r = requests.find(p->tag());
0519       try {
0520         if (ttype == runnumber) {
0521           p->get(run, hasDebug());
0522           r->second++;
0523         } else if (ttype == lumiid) {
0524           p->get(lumi, hasDebug());
0525           r->second++;
0526         } else if (ttype == timestamp) {
0527           p->get(ts, hasDebug());
0528           r->second++;
0529         } else {
0530           std::cout << "WARNING: iov request on tag " << p->tag() << " (timeType=" << time::timeTypeName(p->timeType())
0531                     << ") has been skipped." << std::endl;
0532         }
0533         timex.fetchInt(p->getBufferSize());  // keep track of time vs. size
0534       } catch (const cond::Exception& e) {
0535         std::cout << "ERROR:" << e.what() << std::endl;
0536       }
0537     }  // end else (single thread)
0538   }
0539 
0540   tbb::parallel_for_each(tasks.begin(), tasks.end(), invoker<std::shared_ptr<FetchWorker> >());
0541 
0542   std::cout << "global counter : " << fooGlobal << std::endl;
0543 
0544   if (nThrF == 1)
0545     session.transaction().commit();
0546   // session.transaction().commit();
0547 
0548   timex.interval("loading payloads");
0549 
0550   size_t totBufSize = 0;
0551   for (auto p : proxies) {
0552     totBufSize += p->getBufferSize();
0553   }
0554   std::cout << "++> total buffer size used : " << totBufSize << std::endl;
0555 
0556   std::vector<std::shared_ptr<void> > payloads;
0557   payloads.resize(400);  //-todo: check we don't have more payloads than that !!
0558 
0559   std::shared_ptr<void> payloadPtr;
0560 
0561   tbb::global_control initD(tbb::global_control::max_allowed_parallelism, nThrD);
0562   std::vector<std::shared_ptr<DeserialWorker> > tasksD;
0563 
0564   timex.interval("setup deserialization");
0565 
0566   int nEmpty = 0;
0567   int nBig = 0;
0568   int index = 0;
0569   for (auto p : proxies) {
0570     ///     if ( p->getBufferSize() == 0 ) { // nothing to do for these ...
0571     ///       std::cout << "empty buffer found for " << p->payloadType() << std::endl;
0572     ///       nEmpty++;
0573     ///       continue;
0574     ///     }
0575 
0576     payloadTypeName = p->payloadType();
0577 
0578     // ignore problematic ones for now
0579     if ((payloadTypeName == "SiPixelGainCalibrationForHLT") or
0580         (payloadTypeName == "SiPixelGainCalibrationOffline")  // 2 * 133 MB !!!
0581         or (payloadTypeName == "DTKeyedConfig") or (payloadTypeName == "std::vector<unsigned long long>") or
0582         (payloadTypeName == "  AlignmentSurfaceDeformations")
0583         // only in root for now:
0584         or (payloadTypeName == "PhysicsTools::Calibration::MVAComputerContainer") or
0585         (payloadTypeName == "PhysicsTools::Calibration::MVAComputerContainer") or
0586         (payloadTypeName == "PhysicsTools::Calibration::MVAComputerContainer") or
0587         (payloadTypeName == "PhysicsTools::Calibration::MVAComputerContainer")) {
0588       std::cout << "INFO: Ignoring payload of type " << payloadTypeName << std::endl;
0589       continue;
0590     }
0591 
0592     if (nThrD > 1) {
0593       auto dw = std::make_shared<DeserialWorker>(p, payloads[index]);
0594       tasksD.push_back(dw);
0595     } else {  // single tread only
0596       try {
0597         std::pair<std::string, std::shared_ptr<void> > result =
0598             fetchOne(payloadTypeName, p->getBuffer(), p->getStreamerInfo(), payloadPtr);
0599         payloads.push_back(result.second);
0600       } catch (const cond::Exception& e) {
0601         std::cout << "\nERROR (cond): " << e.what() << std::endl;
0602         std::cout << "for payload type name: " << payloadTypeName << std::endl;
0603       } catch (const std::exception& e) {
0604         std::cout << "\nERROR (boost/std): " << e.what() << std::endl;
0605         std::cout << "for payload type name: " << payloadTypeName << std::endl;
0606       }
0607       timex.deserInt(p->getBufferSize());  // keep track of time vs. size
0608     }                                      // single-thread
0609     index++;                               // increment index into payloads
0610   }
0611   std::cout << std::endl;
0612 
0613   tbb::parallel_for_each(tasksD.begin(), tasksD.end(), invoker<std::shared_ptr<DeserialWorker> >());
0614 
0615   timex.interval("deserializing payloads");
0616 
0617   std::cout << "global counter : " << fooGlobal << std::endl;
0618   std::cout << "found   " << nEmpty << " empty payloads while deserialising " << std::endl;
0619 
0620   std::cout << std::endl;
0621   std::cout << "*** End of job." << std::endl;
0622   std::cout << "*** GT: " << gtag << " Tags:" << gt.size() << " Loaded:" << proxies.size() << std::endl;
0623   std::cout << std::endl;
0624   for (auto p : proxies) {
0625     auto r = requests.find(p->tag());
0626     if (verbose) {
0627       std::cout << "*** Tag: " << p->tag() << " Requests processed:" << r->second << " Queries:" << p->numberOfQueries()
0628                 << std::endl;
0629       const std::vector<std::string>& hist = p->history();
0630       for (const auto& e : p->history())
0631         std::cout << "    " << e << std::endl;
0632     }
0633   }
0634 
0635   // only for igprof checking of live mem:
0636   // ::exit(0);
0637 
0638   timex.interval("postprocessing ... ");
0639   timex.showIntervals();
0640 
0641   if (nThrF == 1) {
0642     std::ofstream ofs("fetchInfo.txt");
0643     timex.showFetchInfo(ofs);
0644     std::ofstream ofs2("sizeInfo.txt");
0645     for (auto p : proxies) {
0646       ofs2 << p->payloadType() << "[" << p->recName() << ":" << p->recLabel() << "]"
0647            << " : " << p->getBufferSize() << std::endl;
0648     }
0649   }
0650   if (nThrD == 1) {
0651     std::ofstream ofs1("deserializeInfo.txt");
0652     timex.showDeserInfo(ofs1);
0653   }
0654 
0655   return 0;
0656 }
0657 
0658 // ================================================================================
0659 
0660 int main(int argc, char** argv) {
0661   // usage: conddb_test_gt_perf -g START70_V1 -n 1 -c oracle://cms_orcoff_prep/CMS_CONDITIONS --n_fetch 1 --n_deser 1 2>&1 | tee run.log
0662   // usage: conddb_test_gt_perf -g START70_V1 -n 1 -c oracle://cms_orcoff_prep/CMS_TEST_CONDITIONS --n_fetch 2 --n_deser 8 2>&1 | tee run_2f_8d.log
0663 
0664   cond::TestGTPerf test;
0665   return test.run(argc, argv);
0666 }