CMS 3D CMS Logo

TestESConcurrentSource.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: FWCore/Integration
4 // Class : TestESConcurrentSource
5 //
6 // Implementation:
7 // ESSource used for tests of Framework support for
8 // ESSources and ESProducers. This is primarily focused
9 // on the infrastructure used by CondDBESSource.
10 //
11 // Original Author: C Jones
12 // Created: 16 Dec 2021
13 
30 
31 #include <atomic>
32 #include <cmath>
33 #include <limits>
34 #include <set>
35 #include <utility>
36 #include <vector>
37 
38 namespace edmtest {
39 
41 
43  public:
45 
46  private:
48  void initializeForNewIOV() override;
49  void const* getAfterPrefetchImpl() const override;
50 
53  };
54 
57  public:
60  ~TestESConcurrentSource() override;
61 
62  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
63 
64  void busyWait(char const* msg) const;
65 
66  void incrementCount() {
67  auto const v = ++count_;
68  auto m = maxCount_.load();
69  while (m < v) {
70  maxCount_.compare_exchange_strong(m, v);
71  }
72  }
73  std::atomic<unsigned int> count_;
74  std::atomic<unsigned int> maxCount_;
75  std::atomic<unsigned int> count_setIntervalFor_;
76  std::atomic<unsigned int> count_initializeForNewIOV_;
77 
78  private:
79  bool isConcurrentFinder() const override { return true; }
81  KeyedResolversVector registerResolvers(EventSetupRecordKey const&, unsigned int iovIndex) override;
82  void initConcurrentIOVs(EventSetupRecordKey const&, unsigned int nConcurrentIOVs) override;
83 
84  std::set<edm::IOVSyncValue> setOfIOV_;
85  const unsigned int iterations_;
86  const double pi_;
88  unsigned int nConcurrentIOVs_ = 0;
90  };
91 
93  : edm::eventsetup::ESSourceProductResolverConcurrentBase(), testESConcurrentSource_(testESConcurrentSource) {}
94 
98  testESConcurrentSource_->busyWait((std::string("getImpl ") + iKey.name().value()).c_str());
99 
100  edm::ValidityInterval iov = iRecord.validityInterval();
101  edm::LogAbsolute("TestESConcurrentSourceTestResolver")
102  << "TestESConcurrentSourceTestResolver::getImpl '" << iKey.name().value()
103  << "' startIOV = " << iov.first().luminosityBlockNumber() << " endIOV = " << iov.last().luminosityBlockNumber()
104  << " IOV index = " << iRecord.iovIndex() << " cache identifier = " << iRecord.cacheIdentifier();
105 
108  iovTestInfo_.iovIndex_ = iRecord.iovIndex();
110 
112  }
113 
115 
117  edm::LogAbsolute("TestESConcurrentSourceTestResolver::initializeForNewIOV")
118  << "TestESConcurrentSourceTestResolver::initializeForNewIOV";
120  }
121 
123  : count_(0),
124  maxCount_(0),
125  count_setIntervalFor_(0),
126  count_initializeForNewIOV_(0),
127  iterations_(pset.getParameter<unsigned int>("iterations")),
128  pi_(std::acos(-1)),
129  expectedNumberOfConcurrentIOVs_(pset.getParameter<unsigned int>("expectedNumberOfConcurrentIOVs")),
130  checkIOVInitialization_(pset.getParameter<bool>("checkIOVInitialization")) {
131  std::vector<unsigned int> temp(pset.getParameter<std::vector<unsigned int>>("firstValidLumis"));
132  for (auto val : temp) {
134  }
135 
136  findingRecord<ESTestRecordI>();
137  usingRecord<ESTestRecordI>();
138  }
139 
141  edm::LogAbsolute("TestESConcurrentSource") << "max concurrency seen " << maxCount_.load();
142  }
143 
146  std::vector<unsigned int> emptyVector;
147  desc.add<unsigned int>("iterations", 10 * 1000 * 1000);
148  desc.add<bool>("checkIOVInitialization", false);
149  desc.add<unsigned int>("expectedNumberOfConcurrentIOVs", 0);
150  desc.add<std::vector<unsigned int>>("firstValidLumis", emptyVector);
151  descriptions.addDefault(desc);
152  }
153 
155  edm::IOVSyncValue const& syncValue,
156  edm::ValidityInterval& iov) {
158  // Note that this check should pass with the specific configuration where I enable
159  // the check, but in general it does not have to be true. The counts are offset
160  // by 1 because the beginRun IOV is invalid (no IOV initialization).
162  throw cms::Exception("TestFailure") << "TestESConcurrentSource::setIntervalFor,"
163  << " unexpected number of IOV initializations";
164  }
165  }
166  incrementCount();
168  busyWait("setIntervalFor");
170 
171  if (setOfIOV_.empty()) {
172  --count_;
173  return;
174  }
175 
176  std::pair<std::set<edm::IOVSyncValue>::iterator, std::set<edm::IOVSyncValue>::iterator> itFound =
177  setOfIOV_.equal_range(syncValue);
178 
179  if (itFound.first == itFound.second) {
180  if (itFound.first == setOfIOV_.begin()) {
181  //request is before first valid interval, so fail
182  --count_;
183  return;
184  }
185  //go back one step
186  --itFound.first;
187  }
188 
190  if (itFound.second != setOfIOV_.end()) {
191  endOfInterval = edm::IOVSyncValue(
192  edm::EventID(1, itFound.second->eventID().luminosityBlock() - 1, edm::EventID::maxEventNumber()));
193  }
194  iov = edm::ValidityInterval(*(itFound.first), endOfInterval);
195  --count_;
196  }
197 
199  EventSetupRecordKey const&, unsigned int iovIndex) {
201  throw cms::Exception("TestFailure") << "TestESConcurrentSource::registerResolvers,"
202  << " unexpected number of concurrent IOVs";
203  }
204  KeyedResolversVector keyedResolversVector;
205 
206  {
207  edm::eventsetup::DataKey dataKey(edm::eventsetup::DataKey::makeTypeTag<IOVTestInfo>(),
209  keyedResolversVector.emplace_back(dataKey, std::make_shared<TestESConcurrentSourceTestResolver>(this));
210  }
211  {
212  edm::eventsetup::DataKey dataKey(edm::eventsetup::DataKey::makeTypeTag<IOVTestInfo>(),
213  edm::eventsetup::IdTags("other"));
214  keyedResolversVector.emplace_back(dataKey, std::make_shared<TestESConcurrentSourceTestResolver>(this));
215  }
216 
217  return keyedResolversVector;
218  }
219 
220  void TestESConcurrentSource::initConcurrentIOVs(EventSetupRecordKey const& key, unsigned int nConcurrentIOVs) {
221  edm::LogAbsolute("TestESConcurrentSource::initConcurrentIOVs")
222  << "Start TestESConcurrentSource::initConcurrentIOVs " << nConcurrentIOVs << " " << key.name();
223  if (EventSetupRecordKey::makeKey<ESTestRecordI>() != key) {
224  throw cms::Exception("TestFailure") << "TestESConcurrentSource::initConcurrentIOVs,"
225  << " unexpected EventSetupRecordKey";
226  }
227  if (expectedNumberOfConcurrentIOVs_ != 0 && nConcurrentIOVs != expectedNumberOfConcurrentIOVs_) {
228  throw cms::Exception("TestFailure") << "TestESConcurrentSource::initConcurrentIOVs,"
229  << " unexpected number of concurrent IOVs";
230  }
231  nConcurrentIOVs_ = nConcurrentIOVs;
232  }
233 
234  void TestESConcurrentSource::busyWait(char const* msg) const {
235  edm::LogAbsolute("TestESConcurrentSource::busyWait") << "Start TestESConcurrentSource::busyWait " << msg;
236  double sum = 0.;
237  const double stepSize = pi_ / iterations_;
238  for (unsigned int i = 0; i < iterations_; ++i) {
239  sum += stepSize * cos(i * stepSize);
240  }
241  edm::LogAbsolute("TestESConcurrentSource::busyWait")
242  << "Stop TestESConcurrentSource::busyWait " << msg << " " << sum;
243  }
244 } // namespace edmtest
245 using namespace edmtest;
const IOVSyncValue & last() const
void busyWait(char const *msg) const
LuminosityBlockNumber_t luminosityBlockNumber() const
Definition: IOVSyncValue.h:41
std::atomic< unsigned int > count_
const IOVSyncValue & first() const
unsigned int iovEndLumi_
Definition: IOVTestInfo.h:24
void prefetch(edm::eventsetup::DataKey const &, edm::EventSetupRecordDetails) override
unsigned int iovIndex_
Definition: IOVTestInfo.h:25
static const IOVSyncValue & endOfTime()
Definition: IOVSyncValue.cc:82
TestESConcurrentSource(edm::ParameterSet const &)
unsigned long long cacheIdentifier() const
std::pair< Time_t, Time_t > ValidityInterval
Definition: Time.h:17
ValidityInterval validityInterval() const
std::atomic< unsigned int > count_initializeForNewIOV_
void addDefault(ParameterSetDescription const &psetDescription)
unsigned int iovStartLumi_
Definition: IOVTestInfo.h:22
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
std::atomic< unsigned int > count_setIntervalFor_
TestESConcurrentSourceTestResolver(TestESConcurrentSource *TestESConcurrentSource)
void setIntervalFor(EventSetupRecordKey const &, edm::IOVSyncValue const &, edm::ValidityInterval &) override
#define DEFINE_FWK_EVENTSETUP_SOURCE(type)
Definition: SourceFactory.h:92
unsigned long long cacheIdentifier_
Definition: IOVTestInfo.h:26
KeyedResolversVector registerResolvers(EventSetupRecordKey const &, unsigned int iovIndex) override
std::set< edm::IOVSyncValue > setOfIOV_
tuple msg
Definition: mps_check.py:286
static EventNumber_t maxEventNumber()
Definition: EventID.h:96
std::vector< std::pair< DataKey, std::shared_ptr< ESProductResolver > >> KeyedResolversVector
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
HLT enums.
static const ValidityInterval & invalidInterval()
Log< level::System, true > LogAbsolute
void initConcurrentIOVs(EventSetupRecordKey const &, unsigned int nConcurrentIOVs) override
std::atomic< unsigned int > maxCount_
const NameTag & name() const
Definition: DataKey.h:53
const char * value() const
Definition: DataKeyTags.h:39