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 
24 #include "IOVTestInfo.h"
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 
56  public:
59  ~TestESConcurrentSource() override;
60 
61  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
62 
63  void busyWait(char const* msg) const;
64 
65  void incrementCount() {
66  auto const v = ++count_;
67  auto m = maxCount_.load();
68  while (m < v) {
69  maxCount_.compare_exchange_strong(m, v);
70  }
71  }
72  std::atomic<unsigned int> count_;
73  std::atomic<unsigned int> maxCount_;
74  std::atomic<unsigned int> count_setIntervalFor_;
75  std::atomic<unsigned int> count_initializeForNewIOV_;
76 
77  private:
78  bool isConcurrentFinder() const override { return true; }
80  KeyedProxiesVector registerProxies(EventSetupRecordKey const&, unsigned int iovIndex) override;
81  void initConcurrentIOVs(EventSetupRecordKey const&, unsigned int nConcurrentIOVs) override;
82 
83  std::set<edm::IOVSyncValue> setOfIOV_;
84  const unsigned int iterations_;
85  const double pi_;
87  unsigned int nConcurrentIOVs_ = 0;
89  };
90 
92  : edm::eventsetup::ESSourceDataProxyConcurrentBase(), testESConcurrentSource_(testESConcurrentSource) {}
93 
97  testESConcurrentSource_->busyWait((std::string("getImpl ") + iKey.name().value()).c_str());
98 
100  edm::LogAbsolute("TestESConcurrentSourceTestProxy")
101  << "TestESConcurrentSourceTestProxy::getImpl '" << iKey.name().value()
102  << "' startIOV = " << iov.first().luminosityBlockNumber() << " endIOV = " << iov.last().luminosityBlockNumber()
103  << " IOV index = " << iRecord.iovIndex() << " cache identifier = " << iRecord.cacheIdentifier();
104 
107  iovTestInfo_.iovIndex_ = iRecord.iovIndex();
109 
111  }
112 
114 
116  edm::LogAbsolute("TestESConcurrentSourceTestProxy::initializeForNewIOV")
117  << "TestESConcurrentSourceTestProxy::initializeForNewIOV";
119  }
120 
122  : count_(0),
123  maxCount_(0),
124  count_setIntervalFor_(0),
125  count_initializeForNewIOV_(0),
126  iterations_(pset.getParameter<unsigned int>("iterations")),
127  pi_(std::acos(-1)),
128  expectedNumberOfConcurrentIOVs_(pset.getParameter<unsigned int>("expectedNumberOfConcurrentIOVs")),
129  checkIOVInitialization_(pset.getParameter<bool>("checkIOVInitialization")) {
130  std::vector<unsigned int> temp(pset.getParameter<std::vector<unsigned int>>("firstValidLumis"));
131  for (auto val : temp) {
133  }
134 
135  findingRecord<ESTestRecordI>();
136  usingRecord<ESTestRecordI>();
137  }
138 
140  edm::LogAbsolute("TestESConcurrentSource") << "max concurrency seen " << maxCount_.load();
141  }
142 
145  std::vector<unsigned int> emptyVector;
146  desc.add<unsigned int>("iterations", 10 * 1000 * 1000);
147  desc.add<bool>("checkIOVInitialization", false);
148  desc.add<unsigned int>("expectedNumberOfConcurrentIOVs", 0);
149  desc.add<std::vector<unsigned int>>("firstValidLumis", emptyVector);
150  descriptions.addDefault(desc);
151  }
152 
154  edm::IOVSyncValue const& syncValue,
155  edm::ValidityInterval& iov) {
157  // Note that this check should pass with the specific configuration where I enable
158  // the check, but in general it does not have to be true. The counts are offset
159  // by 1 because the beginRun IOV is invalid (no IOV initialization).
161  throw cms::Exception("TestFailure") << "TestESConcurrentSource::setIntervalFor,"
162  << " unexpected number of IOV initializations";
163  }
164  }
165  incrementCount();
167  busyWait("setIntervalFor");
169 
170  if (setOfIOV_.empty()) {
171  --count_;
172  return;
173  }
174 
175  std::pair<std::set<edm::IOVSyncValue>::iterator, std::set<edm::IOVSyncValue>::iterator> itFound =
176  setOfIOV_.equal_range(syncValue);
177 
178  if (itFound.first == itFound.second) {
179  if (itFound.first == setOfIOV_.begin()) {
180  //request is before first valid interval, so fail
181  --count_;
182  return;
183  }
184  //go back one step
185  --itFound.first;
186  }
187 
189  if (itFound.second != setOfIOV_.end()) {
190  endOfInterval = edm::IOVSyncValue(
191  edm::EventID(1, itFound.second->eventID().luminosityBlock() - 1, edm::EventID::maxEventNumber()));
192  }
193  iov = edm::ValidityInterval(*(itFound.first), endOfInterval);
194  --count_;
195  }
196 
198  EventSetupRecordKey const&, unsigned int iovIndex) {
200  throw cms::Exception("TestFailure") << "TestESConcurrentSource::registerProxies,"
201  << " unexpected number of concurrent IOVs";
202  }
203  KeyedProxiesVector keyedProxiesVector;
204 
205  {
206  edm::eventsetup::DataKey dataKey(edm::eventsetup::DataKey::makeTypeTag<IOVTestInfo>(),
208  keyedProxiesVector.emplace_back(dataKey, std::make_shared<TestESConcurrentSourceTestProxy>(this));
209  }
210  {
211  edm::eventsetup::DataKey dataKey(edm::eventsetup::DataKey::makeTypeTag<IOVTestInfo>(),
212  edm::eventsetup::IdTags("other"));
213  keyedProxiesVector.emplace_back(dataKey, std::make_shared<TestESConcurrentSourceTestProxy>(this));
214  }
215 
216  return keyedProxiesVector;
217  }
218 
219  void TestESConcurrentSource::initConcurrentIOVs(EventSetupRecordKey const& key, unsigned int nConcurrentIOVs) {
220  edm::LogAbsolute("TestESConcurrentSource::initConcurrentIOVs")
221  << "Start TestESConcurrentSource::initConcurrentIOVs " << nConcurrentIOVs << " " << key.name();
222  if (EventSetupRecordKey::makeKey<ESTestRecordI>() != key) {
223  throw cms::Exception("TestFailure") << "TestESConcurrentSource::initConcurrentIOVs,"
224  << " unexpected EventSetupRecordKey";
225  }
226  if (expectedNumberOfConcurrentIOVs_ != 0 && nConcurrentIOVs != expectedNumberOfConcurrentIOVs_) {
227  throw cms::Exception("TestFailure") << "TestESConcurrentSource::initConcurrentIOVs,"
228  << " unexpected number of concurrent IOVs";
229  }
230  nConcurrentIOVs_ = nConcurrentIOVs;
231  }
232 
233  void TestESConcurrentSource::busyWait(char const* msg) const {
234  edm::LogAbsolute("TestESConcurrentSource::busyWait") << "Start TestESConcurrentSource::busyWait " << msg;
235  double sum = 0.;
236  const double stepSize = pi_ / iterations_;
237  for (unsigned int i = 0; i < iterations_; ++i) {
238  sum += stepSize * cos(i * stepSize);
239  }
240  edm::LogAbsolute("TestESConcurrentSource::busyWait")
241  << "Stop TestESConcurrentSource::busyWait " << msg << " " << sum;
242  }
243 } // namespace edmtest
244 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
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
TestESConcurrentSourceTestProxy(TestESConcurrentSource *TestESConcurrentSource)
void prefetch(edm::eventsetup::DataKey const &, edm::EventSetupRecordDetails) override
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_
KeyedProxiesVector registerProxies(EventSetupRecordKey const &, unsigned int iovIndex) override
void setIntervalFor(EventSetupRecordKey const &, edm::IOVSyncValue const &, edm::ValidityInterval &) override
std::vector< std::pair< DataKey, std::shared_ptr< DataProxy > >> KeyedProxiesVector
#define DEFINE_FWK_EVENTSETUP_SOURCE(type)
Definition: SourceFactory.h:92
unsigned long long cacheIdentifier_
Definition: IOVTestInfo.h:26
std::set< edm::IOVSyncValue > setOfIOV_
tuple msg
Definition: mps_check.py:286
static EventNumber_t maxEventNumber()
Definition: EventID.h:96
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
void const * getAfterPrefetchImpl() const override
const char * value() const
Definition: DataKeyTags.h:39