Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:28:27

0001 // -*- C++ -*-
0002 //
0003 // Package:     FWCore/Integration
0004 // Class  :     ConcurrentIOVESSource
0005 //
0006 // Implementation:
0007 //     ESSource used for tests of Framework support for
0008 //     concurrent IOVs in the EventSetup system
0009 //
0010 // Original Author:  W. David Dagenhart
0011 //         Created:  21 March 2019
0012 
0013 #include "DataFormats/Provenance/interface/EventID.h"
0014 #include "DataFormats/Provenance/interface/Timestamp.h"
0015 #include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h"
0016 #include "FWCore/Framework/interface/ESProducer.h"
0017 #include "FWCore/Framework/interface/IOVSyncValue.h"
0018 #include "FWCore/Framework/interface/SourceFactory.h"
0019 #include "FWCore/Framework/interface/ValidityInterval.h"
0020 #include "FWCore/Integration/interface/ESTestData.h"
0021 #include "FWCore/Integration/interface/ESTestRecords.h"
0022 #include "FWCore/Integration/test/IOVTestInfo.h"
0023 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0024 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0025 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0026 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0027 #include "FWCore/Utilities/interface/Exception.h"
0028 #include "FWCore/Utilities/interface/WallclockTimer.h"
0029 
0030 #include <memory>
0031 #include <vector>
0032 
0033 namespace edmtest {
0034 
0035   class ConcurrentIOVESSource : public edm::EventSetupRecordIntervalFinder, public edm::ESProducer {
0036   public:
0037     ConcurrentIOVESSource(edm::ParameterSet const&);
0038 
0039     std::unique_ptr<IOVTestInfo> produce(ESTestRecordI const&);
0040     std::unique_ptr<ESTestDataA> produceA(ESTestRecordA const&);
0041 
0042     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0043 
0044   private:
0045     void setIntervalFor(edm::eventsetup::EventSetupRecordKey const&,
0046                         edm::IOVSyncValue const&,
0047                         edm::ValidityInterval&) override;
0048 
0049     bool isConcurrentFinder() const override { return concurrentFinder_; }
0050 
0051     // These are thread safe because after the constructor we do not
0052     // modify their state.
0053     const bool iovIsTime_;
0054     std::set<edm::IOVSyncValue> setOfIOV_;
0055     std::set<edm::IOVSyncValue> setOfInvalidIOV_;
0056     const bool concurrentFinder_;
0057     const bool testForceESSourceMode_;
0058     const bool findForRecordA_;
0059     edm::WallclockTimer wallclockTimer_;
0060 
0061     // Be careful with this. It is modified in setIntervalFor
0062     // and the setIntervalFor function is called serially (nonconcurrent
0063     // with itself). But it is not thread safe to use this data member
0064     // in the produce methods unless concurrentFinder_ is false.
0065     edm::ValidityInterval validityInterval_;
0066   };
0067 
0068   ConcurrentIOVESSource::ConcurrentIOVESSource(edm::ParameterSet const& pset)
0069       : iovIsTime_(!pset.getParameter<bool>("iovIsRunNotTime")),
0070         concurrentFinder_(pset.getParameter<bool>("concurrentFinder")),
0071         testForceESSourceMode_(pset.getParameter<bool>("testForceESSourceMode")),
0072         findForRecordA_(pset.getParameter<bool>("findForRecordA")) {
0073     wallclockTimer_.start();
0074 
0075     std::vector<unsigned int> temp(pset.getParameter<std::vector<unsigned int>>("firstValidLumis"));
0076     for (auto val : temp) {
0077       if (iovIsTime_) {
0078         setOfIOV_.insert(edm::IOVSyncValue(edm::Timestamp(val)));
0079       } else {
0080         setOfIOV_.insert(edm::IOVSyncValue(edm::EventID(1, val, 0)));
0081       }
0082     }
0083 
0084     std::vector<unsigned int> tempInvalid(pset.getParameter<std::vector<unsigned int>>("invalidLumis"));
0085     for (auto val : tempInvalid) {
0086       if (iovIsTime_) {
0087         setOfInvalidIOV_.insert(edm::IOVSyncValue(edm::Timestamp(val)));
0088       } else {
0089         setOfInvalidIOV_.insert(edm::IOVSyncValue(edm::EventID(1, val, 0)));
0090       }
0091     }
0092     this->findingRecord<ESTestRecordI>();
0093     setWhatProduced(this);
0094     if (findForRecordA_) {
0095       this->findingRecord<ESTestRecordA>();
0096       setWhatProduced(this, &ConcurrentIOVESSource::produceA);
0097     }
0098   }
0099 
0100   std::unique_ptr<IOVTestInfo> ConcurrentIOVESSource::produce(ESTestRecordI const& record) {
0101     auto data = std::make_unique<IOVTestInfo>();
0102 
0103     edm::ValidityInterval iov = record.validityInterval();
0104     edm::LogAbsolute("ConcurrentIOVESSource")
0105         << "ConcurrentIOVESSource::produce startIOV = " << iov.first().luminosityBlockNumber()
0106         << " endIOV = " << iov.last().luminosityBlockNumber() << " IOV index = " << record.iovIndex()
0107         << " cache identifier = " << record.cacheIdentifier() << " time = " << wallclockTimer_.realTime();
0108 
0109     if (!concurrentFinder_) {
0110       if (validityInterval_ != iov) {
0111         throw cms::Exception("TestError")
0112             << "ConcurrentIOVESSource::produce, testing as nonconcurrent finder and IOV changed!";
0113       }
0114     }
0115 
0116     data->iovStartLumi_ = iov.first().luminosityBlockNumber();
0117     data->iovEndLumi_ = iov.last().luminosityBlockNumber();
0118     data->iovIndex_ = record.iovIndex();
0119     data->cacheIdentifier_ = record.cacheIdentifier();
0120     return data;
0121   }
0122 
0123   std::unique_ptr<ESTestDataA> ConcurrentIOVESSource::produceA(ESTestRecordA const& record) {
0124     edm::ValidityInterval iov = record.validityInterval();
0125     if (!testForceESSourceMode_ && record.iovIndex() != 0) {
0126       // This criteria should never fail because the EventSetupRecord class
0127       // is hard coded to allow only one IOV at a time.
0128       throw cms::Exception("TestError")
0129           << "ConcurrentIOVESSource::produce, more than one concurrent IOV for type ESTestRecordA!";
0130     }
0131     edm::LogAbsolute("ConcurrentIOVESSource")
0132         << "ConcurrentIOVESSource::produceA startIOV = " << iov.first().luminosityBlockNumber()
0133         << " endIOV = " << iov.last().luminosityBlockNumber() << " IOV index = " << record.iovIndex()
0134         << " cache identifier = " << record.cacheIdentifier() << " time = " << wallclockTimer_.realTime();
0135     return std::make_unique<ESTestDataA>(0);
0136   }
0137 
0138   void ConcurrentIOVESSource::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0139     edm::ParameterSetDescription desc;
0140     std::vector<unsigned int> emptyVector;
0141     desc.add<bool>("iovIsRunNotTime", true);
0142     desc.add<bool>("concurrentFinder", true);
0143     desc.add<bool>("testForceESSourceMode", false);
0144     desc.add<bool>("findForRecordA", false);
0145     desc.add<std::vector<unsigned int>>("firstValidLumis", emptyVector);
0146     desc.add<std::vector<unsigned int>>("invalidLumis", emptyVector);
0147     descriptions.addDefault(desc);
0148   }
0149 
0150   void ConcurrentIOVESSource::setIntervalFor(edm::eventsetup::EventSetupRecordKey const& key,
0151                                              edm::IOVSyncValue const& syncValue,
0152                                              edm::ValidityInterval& interval) {
0153     interval = edm::ValidityInterval::invalidInterval();
0154     validityInterval_ = interval;
0155 
0156     for (auto const& invalidSyncValue : setOfInvalidIOV_) {
0157       if (syncValue == invalidSyncValue) {
0158         return;
0159       }
0160     }
0161 
0162     //if no intervals given, fail immediately
0163     if (setOfIOV_.empty()) {
0164       return;
0165     }
0166 
0167     std::pair<std::set<edm::IOVSyncValue>::iterator, std::set<edm::IOVSyncValue>::iterator> itFound =
0168         setOfIOV_.equal_range(syncValue);
0169 
0170     if (itFound.first == itFound.second) {
0171       if (itFound.first == setOfIOV_.begin()) {
0172         //request is before first valid interval, so fail
0173         return;
0174       }
0175       //go back one step
0176       --itFound.first;
0177     }
0178     edm::IOVSyncValue endOfInterval = edm::IOVSyncValue::endOfTime();
0179 
0180     if (itFound.second != setOfIOV_.end()) {
0181       if (iovIsTime_) {
0182         endOfInterval = edm::IOVSyncValue(edm::Timestamp(itFound.second->time().value() - 1));
0183       } else {
0184         endOfInterval = edm::IOVSyncValue(
0185             edm::EventID(1, itFound.second->eventID().luminosityBlock() - 1, edm::EventID::maxEventNumber()));
0186       }
0187     }
0188     interval = edm::ValidityInterval(*(itFound.first), endOfInterval);
0189     validityInterval_ = interval;
0190   }
0191 }  // namespace edmtest
0192 using namespace edmtest;
0193 DEFINE_FWK_EVENTSETUP_SOURCE(ConcurrentIOVESSource);