CMS 3D CMS Logo

externalGenerator.cc
Go to the documentation of this file.
1 #include "boost/program_options.hpp"
2 
3 #include <atomic>
4 #include <csignal>
5 #include <iostream>
6 #include <string>
7 #include <thread>
8 
10 
18 
20 
27 
28 static char const* const kMemoryNameOpt = "memory-name";
29 static char const* const kMemoryNameCommandOpt = "memory-name,m";
30 static char const* const kUniqueIDOpt = "unique-id";
31 static char const* const kUniqueIDCommandOpt = "unique-id,i";
32 static char const* const kHelpOpt = "help";
33 static char const* const kHelpCommandOpt = "help,h";
34 static char const* const kVerboseOpt = "verbose";
35 static char const* const kVerboseCommandOpt = "verbose,v";
36 
37 //NOTE: Can use TestProcessor as the harness for the worker
38 
39 using namespace edm::shared_memory;
40 class Harness {
41 public:
42  Harness(std::string const& iConfig, edm::ServiceToken iToken)
43  : tester_(edm::test::TestProcessor::Config{iConfig}, iToken) {}
44 
46  auto lumi = tester_.testBeginLuminosityBlock(iLumi);
47  ExternalGeneratorLumiInfo returnValue;
48  returnValue.header_ = *lumi.get<GenLumiInfoHeader>();
49  return returnValue;
50  }
51 
53  ExternalGeneratorEventInfo returnValue;
54  auto event = tester_.test();
55  returnValue.hepmc_ = *event.get<edm::HepMCProduct>("unsmeared");
56  returnValue.eventInfo_ = *event.get<GenEventInfoProduct>();
57  returnValue.keepEvent_ = event.modulePassed();
58  return returnValue;
59  }
60 
62  auto lumi = tester_.testEndLuminosityBlock();
63  return *lumi.get<GenLumiInfoProduct>();
64  }
65 
67  auto run = tester_.testEndRun();
68  return *run.get<GenRunInfoProduct>();
69  }
70 
71 private:
73 };
74 
75 template <typename T>
77 
78 int main(int argc, char* argv[]) {
79  std::string descString(argv[0]);
80  descString += " [--";
81  descString += kMemoryNameOpt;
82  descString += "] memory_name";
83  boost::program_options::options_description desc(descString);
84 
85  desc.add_options()(kHelpCommandOpt, "produce help message")(
86  kMemoryNameCommandOpt, boost::program_options::value<std::string>(), "memory name")(
87  kUniqueIDCommandOpt, boost::program_options::value<std::string>(), "unique id")(kVerboseCommandOpt,
88  "verbose output");
89 
90  boost::program_options::positional_options_description p;
91  p.add(kMemoryNameOpt, 1);
92  p.add(kUniqueIDOpt, 2);
93 
94  boost::program_options::options_description all_options("All Options");
95  all_options.add(desc);
96 
97  boost::program_options::variables_map vm;
98  try {
99  store(boost::program_options::command_line_parser(argc, argv).options(all_options).positional(p).run(), vm);
100  notify(vm);
101  } catch (boost::program_options::error const& iException) {
102  std::cout << argv[0] << ": Error while trying to process command line arguments:\n"
103  << iException.what() << "\nFor usage and an options list, please do 'cmsRun --help'.";
104  return 1;
105  }
106 
107  if (vm.count(kHelpOpt)) {
108  std::cout << desc << std::endl;
109  return 0;
110  }
111 
112  bool verbose = false;
113  if (vm.count(kVerboseOpt)) {
114  verbose = true;
115  }
116 
117  if (!vm.count(kMemoryNameOpt)) {
118  std::cout << " no argument given" << std::endl;
119  return 1;
120  }
121 
122  if (!vm.count(kUniqueIDOpt)) {
123  std::cout << " no second argument given" << std::endl;
124  return 1;
125  }
126 
127  WorkerMonitorThread monitorThread;
128 
129  monitorThread.startThread();
130 
131  CMS_SA_ALLOW try {
132  std::string const memoryName(vm[kMemoryNameOpt].as<std::string>());
133  std::string const uniqueID(vm[kUniqueIDOpt].as<std::string>());
134  {
135  //This class is holding the lock
136  WorkerChannel communicationChannel(memoryName, uniqueID);
137 
138  WriteBuffer sm_buffer{memoryName, communicationChannel.fromWorkerBufferInfo()};
139  ReadBuffer sm_readbuffer{std::string("Rand") + memoryName, communicationChannel.toWorkerBufferInfo()};
140  int counter = 0;
141 
142  //The lock must be released if there is a catastrophic signal
143  auto lockPtr = communicationChannel.accessLock();
144  monitorThread.setAction([lockPtr]() {
145  if (lockPtr) {
146  std::cerr << "SIGNAL CAUGHT: unlock\n";
147  lockPtr->unlock();
148  }
149  });
150 
151  Serializer<ExternalGeneratorEventInfo> serializer(sm_buffer);
152  Serializer<ExternalGeneratorLumiInfo> bl_serializer(sm_buffer);
153  Serializer<GenLumiInfoProduct> el_serializer(sm_buffer);
154  Serializer<GenRunInfoProduct> er_serializer(sm_buffer);
155 
156  ROOTDeserializer<edm::RandomNumberGeneratorState, ReadBuffer> random_deserializer(sm_readbuffer);
157 
158  std::cerr << uniqueID << " process: initializing " << std::endl;
159  int nlines;
160  std::cin >> nlines;
161 
163  for (int i = 0; i < nlines; ++i) {
164  std::string c;
165  std::getline(std::cin, c);
166  if (verbose) {
167  std::cerr << c << "\n";
168  }
169  configuration += c + "\n";
170  }
171 
173  auto serviceToken =
174  edm::ServiceRegistry::createContaining(std::unique_ptr<edm::RandomNumberGenerator>(randomService));
175  Harness harness(configuration, serviceToken);
176 
177  //Either ROOT or the Framework are overriding the signal handlers
178  monitorThread.setupSignalHandling();
179 
180  if (verbose) {
181  std::cerr << uniqueID << " process: done initializing" << std::endl;
182  }
183  communicationChannel.workerSetupDone();
184 
185  if (verbose)
186  std::cerr << uniqueID << " process: waiting " << counter << std::endl;
187  communicationChannel.handleTransitions([&](edm::Transition iTransition, unsigned long long iTransitionID) {
188  ++counter;
189  switch (iTransition) {
191  if (verbose)
192  std::cerr << uniqueID << " process: start beginRun " << std::endl;
193  if (verbose)
194  std::cerr << uniqueID << " process: end beginRun " << std::endl;
195 
196  break;
197  }
199  if (verbose)
200  std::cerr << uniqueID << " process: start beginLumi " << std::endl;
201  auto randState = random_deserializer.deserialize();
202  if (verbose)
203  std::cerr << uniqueID << " random " << randState.state_.size() << " " << randState.seed_ << std::endl;
204  randomService->setState(randState.state_, randState.seed_);
205  auto value = harness.getBeginLumiValue(iTransitionID);
206  value.randomState_.state_ = randomService->getState();
207  value.randomState_.seed_ = randomService->mySeed();
208 
209  bl_serializer.serialize(value);
210  if (verbose)
211  std::cerr << uniqueID << " process: end beginLumi " << std::endl;
212  if (verbose)
213  std::cerr << uniqueID << " rand " << value.randomState_.state_.size() << " " << value.randomState_.seed_
214  << std::endl;
215  break;
216  }
217  case edm::Transition::Event: {
218  if (verbose)
219  std::cerr << uniqueID << " process: event " << counter << std::endl;
220  auto randState = random_deserializer.deserialize();
221  randomService->setState(randState.state_, randState.seed_);
222  auto value = harness.getEventValue();
223  value.randomState_.state_ = randomService->getState();
224  value.randomState_.seed_ = randomService->mySeed();
225 
226  if (verbose)
227  std::cerr << uniqueID << " process: event " << counter << std::endl;
228 
229  serializer.serialize(value);
230  if (verbose)
231  std::cerr << uniqueID << " process: "
232  << " " << counter << std::endl;
233  //usleep(10000000);
234  break;
235  }
237  if (verbose)
238  std::cerr << uniqueID << " process: start endLumi " << std::endl;
239  auto value = harness.getEndLumiValue();
240 
241  el_serializer.serialize(value);
242  if (verbose)
243  std::cerr << uniqueID << " process: end endLumi " << std::endl;
244 
245  break;
246  }
248  if (verbose)
249  std::cerr << uniqueID << " process: start endRun " << std::endl;
250  auto value = harness.getEndRunValue();
251 
252  er_serializer.serialize(value);
253  if (verbose)
254  std::cerr << uniqueID << " process: end endRun " << std::endl;
255 
256  break;
257  }
258  default: {
259  assert(false);
260  }
261  }
262  if (verbose)
263  std::cerr << uniqueID << " process: notifying and waiting " << counter << std::endl;
264  });
265  }
266  } catch (std::exception const& iExcept) {
267  std::cerr << "caught exception \n" << iExcept.what() << "\n";
268  return 1;
269  } catch (...) {
270  std::cerr << "caught unknown exception";
271  return 1;
272  }
273  return 0;
274 }
GenEventInfoProduct
Definition: GenEventInfoProduct.h:17
counter
Definition: counter.py:1
cmsBatch.argv
argv
Definition: cmsBatch.py:279
Harness::getEndRunValue
edmtest::ThingCollection getEndRunValue()
Definition: interprocess.cc:52
mps_fire.i
i
Definition: mps_fire.py:355
kUniqueIDOpt
static char const *const kUniqueIDOpt
Definition: externalGenerator.cc:30
dir2webdir.argc
argc
Definition: dir2webdir.py:39
ReadBuffer.h
edm
HLT enums.
Definition: AlignableModifier.h:19
edm::Transition::Event
kUniqueIDCommandOpt
static char const *const kUniqueIDCommandOpt
Definition: externalGenerator.cc:31
AlCaHLTBitMon_ParallelJobs.p
p
Definition: AlCaHLTBitMon_ParallelJobs.py:153
TestProcessor
gather_cfg.cout
cout
Definition: gather_cfg.py:144
cms::cuda::assert
assert(be >=bs)
edm::shared_memory::WorkerMonitorThread
Definition: WorkerMonitorThread.h:32
edm::ExternalRandomNumberGeneratorService::mySeed
std::uint32_t mySeed() const final
Definition: ExternalRandomNumberGeneratorService.cc:69
kMemoryNameCommandOpt
static char const *const kMemoryNameCommandOpt
Definition: externalGenerator.cc:29
Harness::getBeginLumiValue
ExternalGeneratorLumiInfo getBeginLumiValue(unsigned int iLumi)
Definition: externalGenerator.cc:45
edm::shared_memory::ROOTSerializer
Definition: ROOTSerializer.h:31
Harness
Definition: interprocess.cc:28
relativeConstraints.error
error
Definition: relativeConstraints.py:53
GenRunInfoProduct.h
CMS_SA_ALLOW
#define CMS_SA_ALLOW
Definition: thread_safety_macros.h:5
ExternalGeneratorEventInfo.h
kMemoryNameOpt
static char const *const kMemoryNameOpt
Definition: externalGenerator.cc:28
edm::shared_memory::WorkerChannel::fromWorkerBufferInfo
BufferInfo * fromWorkerBufferInfo()
This can be used with WriteBuffer to keep Controller and Worker in sync.
Definition: WorkerChannel.h:53
TestProcessor.h
edm::shared_memory::ROOTDeserializer
Definition: ROOTDeserializer.h:31
edm::shared_memory::WriteBuffer
Definition: WriteBuffer.h:37
edm::shared_memory::WorkerChannel::accessLock
boost::interprocess::scoped_lock< boost::interprocess::named_mutex > * accessLock()
the lock is made accessible so that the WorkerMonitorThread can be used to unlock it in the event of ...
Definition: WorkerChannel.h:48
edm::shared_memory::WorkerMonitorThread::setupSignalHandling
void setupSignalHandling()
Sets the unix signal handler which communicates with the thread.
Definition: WorkerMonitorThread.cc:102
ExternalGeneratorEventInfo::hepmc_
edm::HepMCProduct hepmc_
Definition: ExternalGeneratorEventInfo.h:15
edm::ServiceToken
Definition: ServiceToken.h:40
test
Definition: SmallWORMDict.h:13
edm::ExternalRandomNumberGeneratorService::setState
void setState(std::vector< unsigned long > const &, long seed)
Definition: ExternalRandomNumberGeneratorService.cc:24
ExternalGeneratorLumiInfo::header_
GenLumiInfoHeader header_
Definition: ExternalGeneratorLumiInfo.h:14
kHelpCommandOpt
static char const *const kHelpCommandOpt
Definition: externalGenerator.cc:33
edm::shared_memory::WorkerMonitorThread::startThread
void startThread()
Definition: WorkerMonitorThread.cc:78
Harness::Harness
Harness(std::string const &iConfig, edm::ServiceToken iToken)
Definition: externalGenerator.cc:42
main
int main(int argc, char *argv[])
Definition: externalGenerator.cc:78
edm::shared_memory::WorkerMonitorThread::setAction
void setAction(std::function< void()> iFunc)
Definition: WorkerMonitorThread.h:48
verbose
static constexpr int verbose
Definition: HLTExoticaSubAnalysis.cc:25
kVerboseCommandOpt
static char const *const kVerboseCommandOpt
Definition: externalGenerator.cc:35
edm::Transition::BeginLuminosityBlock
GenRunInfoProduct
Definition: GenRunInfoProduct.h:8
Harness::getBeginLumiValue
edmtest::ThingCollection getBeginLumiValue(unsigned int iLumi)
Definition: interprocess.cc:37
edm::shared_memory::ROOTSerializer::serialize
void serialize(T &iValue)
Definition: ROOTSerializer.h:44
kVerboseOpt
static char const *const kVerboseOpt
Definition: externalGenerator.cc:34
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
cppFunctionSkipper.exception
exception
Definition: cppFunctionSkipper.py:10
es_hardcode_cfi.iLumi
iLumi
Definition: es_hardcode_cfi.py:206
edm::Transition
Transition
Definition: Transition.h:12
GenEventInfoProduct.h
Harness::getEndRunValue
GenRunInfoProduct getEndRunValue()
Definition: externalGenerator.cc:66
ctppsRawToDigi_cff.configuration
configuration
Definition: ctppsRawToDigi_cff.py:11
beam_dqm_sourceclient-live_cfg.cerr
cerr
Definition: beam_dqm_sourceclient-live_cfg.py:17
ExternalGeneratorEventInfo::eventInfo_
GenEventInfoProduct eventInfo_
Definition: ExternalGeneratorEventInfo.h:16
Harness::getEventValue
edmtest::ThingCollection getEventValue()
Definition: interprocess.cc:42
WorkerChannel.h
Harness::getEventValue
ExternalGeneratorEventInfo getEventValue()
Definition: externalGenerator.cc:52
ExternalRandomNumberGeneratorService.h
value
Definition: value.py:1
GenLumiInfoProduct
Definition: GenLumiInfoProduct.h:11
GenLumiInfoHeader.h
counter
static std::atomic< unsigned int > counter
Definition: SharedResourceNames.cc:15
edm::test::TestProcessor
Definition: TestProcessor.h:154
edm::shared_memory
Definition: buffer_names.h:27
ExternalGeneratorLumiInfo
Definition: ExternalGeneratorLumiInfo.h:13
HltBtagPostValidation_cff.c
c
Definition: HltBtagPostValidation_cff.py:31
edm::shared_memory::ROOTDeserializer::deserialize
T deserialize()
Definition: ROOTDeserializer.h:44
edm::shared_memory::WorkerChannel::handleTransitions
void handleTransitions(F &&iF)
Definition: WorkerChannel.h:65
Harness::getEndLumiValue
edmtest::ThingCollection getEndLumiValue()
Definition: interprocess.cc:47
edm::shared_memory::WorkerChannel
Definition: WorkerChannel.h:35
ExternalGeneratorEventInfo::keepEvent_
bool keepEvent_
Definition: ExternalGeneratorEventInfo.h:18
edm::ExternalRandomNumberGeneratorService::getState
std::vector< unsigned long > getState() const
Definition: ExternalRandomNumberGeneratorService.cc:32
edm::Transition::EndLuminosityBlock
writedatasetfile.run
run
Definition: writedatasetfile.py:27
edm::ServiceRegistry::createContaining
static ServiceToken createContaining(std::unique_ptr< T > iService)
create a service token that holds the service defined by iService
Definition: ServiceRegistry.h:97
edm::Transition::BeginRun
ROOTDeserializer.h
AlcaSiPixelAliHarvester0T_cff.options
options
Definition: AlcaSiPixelAliHarvester0T_cff.py:42
ExternalGeneratorLumiInfo.h
WriteBuffer.h
Harness::getEndLumiValue
GenLumiInfoProduct getEndLumiValue()
Definition: externalGenerator.cc:61
WorkerMonitorThread.h
edm::shared_memory::ReadBuffer
Definition: ReadBuffer.h:34
edm::HepMCProduct
Definition: HepMCProduct.h:18
kHelpOpt
static char const *const kHelpOpt
Definition: externalGenerator.cc:32
HepMCProduct.h
Config
Definition: Config.py:1
edm::ExternalRandomNumberGeneratorService
Definition: ExternalRandomNumberGeneratorService.h:20
edm::Transition::EndRun
edm::shared_memory::WorkerChannel::workerSetupDone
void workerSetupDone()
Matches the ControllerChannel::setupWorker call.
Definition: WorkerChannel.h:56
GenLumiInfoProduct.h
lumi
Definition: LumiSectionData.h:20
edm::shared_memory::WorkerChannel::toWorkerBufferInfo
BufferInfo * toWorkerBufferInfo()
This can be used with ReadBuffer to keep Controller and Worker in sync.
Definition: WorkerChannel.h:51
GenLumiInfoHeader
Definition: GenLumiInfoHeader.h:12
ROOTSerializer.h
ExternalGeneratorEventInfo
Definition: ExternalGeneratorEventInfo.h:14