CMS 3D CMS Logo

JobReport.cc
Go to the documentation of this file.
1 
2 // -*- C++ -*-
3 //
4 //
5 // 10/23/07 mf In an attempt to get clues about (or ene) the
6 // does-not-output-branches behavior, changed the
7 // generic os<< lines in JobReport::JobReportImpl::writeOutputFile
8 // to direct use of LogInfo.
9 //
10 // 4/8/08 mf Encase the logdesc for in <CDATA> ... </CDATA>
11 //
12 // 6/19/08 mf reportMessageInfo()
13 //
14 // 24 June 2008 ewv Correct format for CDATA and for second instance of reportError
15 
16 //
17 // Original Author: Marc Paterno
18 //
19 
23 
24 // The part of tinyxml used in JobReport was reviewed and
25 // determined to be threadsafe.
26 #include "tinyxml2.h"
27 #include <fstream>
28 #include <iomanip>
29 #include <ostream>
30 #include <sstream>
31 
32 namespace edm {
33  /*
34  * Note that output formatting is spattered across these classes
35  * If something outside these classes requires access to the
36  * same formatting then we need to refactor it into a common library
37  */
38 
39  template <typename S, typename T>
40  S& formatFile(T const& f, S& os) {
41  tinyxml2::XMLDocument doc;
42  if (f.fileHasBeenClosed) {
43  os << "\n<State Value=\"closed\"/>";
44  } else {
45  os << "\n<State Value=\"open\"/>";
46  }
47  os << "\n<LFN>" << doc.NewText(f.logicalFileName.c_str())->Value() << "</LFN>";
48  os << "\n<PFN>" << doc.NewText(f.physicalFileName.c_str())->Value() << "</PFN>";
49  os << "\n<Catalog>" << doc.NewText(f.catalog.c_str())->Value() << "</Catalog>";
50  os << "\n<ModuleLabel>" << doc.NewText(f.moduleLabel.c_str())->Value() << "</ModuleLabel>";
51  os << "\n<GUID>" << f.guid << "</GUID>";
52  os << "\n<Branches>";
53  for (auto const& branch : f.branchNames) {
54  os << "\n <Branch>" << doc.NewText(branch.c_str())->Value() << "</Branch>";
55  doc.DeleteChildren();
56  }
57  os << "\n</Branches>";
58  return os;
59  }
60  /*
61  * Note that output formatting is spattered across these classes
62  * If something outside these classes requires access to the
63  * same formatting then we need to refactor it into a common library
64  */
65  template <typename S>
66  S& print(S& os, JobReport::InputFile const& f) {
67  tinyxml2::XMLDocument doc;
68  os << "\n<InputFile>";
69  formatFile(f, os);
70  os << "\n<InputType>" << f.inputType << "</InputType>";
71  os << "\n<InputSourceClass>" << doc.NewText(f.inputSourceClassName.c_str())->Value() << "</InputSourceClass>";
72  os << "\n<EventsRead>" << f.numEventsRead << "</EventsRead>";
73  return os;
74  }
75 
76  template <typename S>
77  S& print(S& os, JobReport::OutputFile const& f) {
78  tinyxml2::XMLDocument doc;
79  formatFile(f, os);
80  os << "\n<OutputModuleClass>" << doc.NewText(f.outputModuleClassName.c_str())->Value() << "</OutputModuleClass>";
81  os << "\n<TotalEvents>" << f.numEventsWritten << "</TotalEvents>\n";
82  os << "\n<DataType>" << doc.NewText(f.dataType.c_str())->Value() << "</DataType>\n";
83  os << "\n<BranchHash>" << doc.NewText(f.branchHash.c_str())->Value() << "</BranchHash>\n";
84  return os;
85  }
86 
87  template <typename S>
88  S& print(S& os, JobReport::RunReport const& rep) {
89  os << "\n<Run ID=\"" << rep.runNumber << "\">\n";
90 
91  for (auto const& il : rep.lumiSectionsToNEvents) {
92  if (std::numeric_limits<unsigned long>::max() == il.second) {
93  os << " <LumiSection ID=\"" << il.first << "\"/>\n";
94 
95  } else {
96  os << " <LumiSection ID=\"" << il.first << "\" NEvents=\"" << il.second << "\"/>\n";
97  }
98  }
99  os << "</Run>\n";
100  return os;
101  }
102 
103  std::ostream& operator<<(std::ostream& os, JobReport::InputFile const& f) { return print(os, f); }
104  std::ostream& operator<<(std::ostream& os, JobReport::OutputFile const& f) { return print(os, f); }
105  std::ostream& operator<<(std::ostream& os, JobReport::RunReport const& f) { return print(os, f); }
106 
108  InputFile* inputFile = nullptr;
109  if (inputType == InputType::SecondarySource) {
110  if (t >= inputFilesSecSource_.size()) {
111  throw edm::Exception(edm::errors::LogicError) << "Access reported for secondary source input file with token "
112  << t << " but no matching input file is found\n";
113  }
115  } else {
116  if (t >= inputFiles_.size()) {
118  << "Access reported for input file with token " << t << " but no matching input file is found\n";
119  }
120  inputFile = &inputFiles_[t];
121  }
122  if (inputFile->fileHasBeenClosed) {
124  << "Access reported for input file with token " << t << " after this file has been closed.\n"
125  << "File record follows:\n"
126  << *inputFile << '\n';
127  }
128  return *inputFile;
129  }
130 
132  if (t >= outputFiles_.size()) {
134  << "Access reported for output file with token " << t << " but no matching output file is found\n";
135  }
136  if (outputFiles_[t].fileHasBeenClosed) {
138  << "Access reported for output file with token " << t << " after this file has been closed.\n"
139  << "File record follows:\n"
140  << outputFiles_[t] << '\n';
141  }
142  return outputFiles_[t];
143  }
144 
145  /*
146  * Add the input file token provided to every output
147  * file currently available.
148  * Used whenever a new input file is opened, it's token
149  * is added to all open output files as a contributor
150  */
152  for (auto& outputFile : outputFiles_) {
153  if (!outputFile.fileHasBeenClosed) {
154  if (inputType == InputType::SecondarySource) {
155  outputFile.contributingInputsSecSource.push_back(t);
156  } else {
157  outputFile.contributingInputs.push_back(t);
158  }
159  }
160  }
161  }
162 
163  /*
164  * Write anJobReport::InputFile object to the Logger
165  * Generate XML string forJobReport::InputFile instance and dispatch to
166  * job report via MessageLogger
167  */
169  if (ost_) {
170  *ost_ << f;
171  *ost_ << "\n<Runs>";
172  for (auto const& runReport : f.runReports) {
173  *ost_ << runReport.second;
174  }
175  *ost_ << "\n</Runs>\n";
176  *ost_ << "</InputFile>\n";
177  *ost_ << std::flush;
178  }
179  }
180 
181  /*
182  * Write an OutputFile object to the Logger
183  * Generate an XML string for the OutputFile provided and
184  * dispatch it to the logger
185  * Contributing input tokens are resolved to the input LFN and PFN
186  *
187  * TODO: We have not yet addressed the issue where we cleanup not
188  * contributing input files.
189  * Also, it is possible to get fake input to output file mappings
190  * if an input file is open already when a new output file is opened
191  * but the input gets closed without contributing events to the
192  * output file due to filtering etc.
193  *
194  */
196  tinyxml2::XMLDocument doc;
197  if (ost_) {
198  *ost_ << "\n<File>";
199  *ost_ << f;
200 
201  *ost_ << "\n<Runs>";
202  for (auto const& runReport : f.runReports) {
203  *ost_ << runReport.second;
204  }
205  *ost_ << "\n</Runs>\n";
206 
207  *ost_ << "\n<Inputs>";
208  for (auto token : f.contributingInputs) {
209  JobReport::InputFile inpFile = inputFiles_.at(token);
210  *ost_ << "\n<Input>";
211  *ost_ << "\n <LFN>" << doc.NewText(inpFile.logicalFileName.c_str())->Value() << "</LFN>";
212  *ost_ << "\n <PFN>" << doc.NewText(inpFile.physicalFileName.c_str())->Value() << "</PFN>";
213  *ost_ << "\n <FastCopying>" << findOrDefault(f.fastCopyingInputs, inpFile.physicalFileName)
214  << "</FastCopying>";
215  *ost_ << "\n</Input>";
216  doc.DeleteChildren();
217  }
218  for (auto token : f.contributingInputsSecSource) {
219  JobReport::InputFile inpFile = inputFilesSecSource_.at(token);
220  *ost_ << "\n<Input>";
221  *ost_ << "\n <LFN>" << doc.NewText(inpFile.logicalFileName.c_str())->Value() << "</LFN>";
222  *ost_ << "\n <PFN>" << doc.NewText(inpFile.physicalFileName.c_str())->Value() << "</PFN>";
223  *ost_ << "\n <FastCopying>" << findOrDefault(f.fastCopyingInputs, inpFile.physicalFileName)
224  << "</FastCopying>";
225  *ost_ << "\n</Input>";
226  doc.DeleteChildren();
227  }
228  *ost_ << "\n</Inputs>";
229  *ost_ << "\n</File>\n";
230  }
231  }
232 
233  /*
234  * Flush all open files to logger in event of a problem.
235  * Called from JobReport dtor to flush any remaining open files
236  */
238  for (auto const& inputFile : inputFiles_) {
239  if (!(inputFile.fileHasBeenClosed)) {
240  writeInputFile(inputFile);
241  }
242  }
243  for (auto const& inputFile : inputFilesSecSource_) {
244  if (!(inputFile.fileHasBeenClosed)) {
245  writeInputFile(inputFile);
246  }
247  }
248  for (auto const& outputFile : outputFiles_) {
249  if (!(outputFile.fileHasBeenClosed)) {
250  writeOutputFile(outputFile);
251  }
252  }
253  }
254 
256  auto& theMap = outputFiles_.at(token).runReports;
257  std::map<RunNumber, RunReport>::iterator iter(theMap.lower_bound(runNumber));
258  if (iter == theMap.end() || runNumber < iter->first) { // not found
259  theMap.emplace_hint(iter, runNumber, JobReport::RunReport{runNumber, {}}); // insert it
260  }
261  }
262 
264  for (auto& inputFile : inputFiles_) {
265  if (!inputFile.fileHasBeenClosed) {
266  std::map<RunNumber, RunReport>& theMap = inputFile.runReports;
267  std::map<RunNumber, RunReport>::iterator iter(theMap.lower_bound(runNumber));
268  if (iter == theMap.end() || runNumber < iter->first) { // not found
269  theMap.emplace_hint(iter, runNumber, JobReport::RunReport{runNumber, {}}); // insert it
270  }
271  }
272  }
273  }
274 
276  unsigned int runNumber,
277  unsigned int lumiSect,
278  unsigned long nEvents) {
279  auto& theMap = outputFiles_.at(token).runReports;
280  std::map<RunNumber, RunReport>::iterator iter(theMap.lower_bound(runNumber));
281  if (iter == theMap.end() || runNumber < iter->first) { // not found
282  theMap.emplace_hint(iter, runNumber, JobReport::RunReport{runNumber, {{{lumiSect, nEvents}}}}); // insert it
283  } else {
284  iter->second.lumiSectionsToNEvents[lumiSect] += nEvents;
285  }
286  }
287 
288  void JobReport::JobReportImpl::associateInputLumiSection(unsigned int runNumber, unsigned int lumiSect) {
289  for (auto& inputFile : inputFiles_) {
290  if (!inputFile.fileHasBeenClosed) {
291  std::map<RunNumber, RunReport>& theMap = inputFile.runReports;
292  std::map<RunNumber, RunReport>::iterator iter(theMap.lower_bound(runNumber));
293  if (iter == theMap.end() || runNumber < iter->first) { // not found
294  theMap.emplace_hint(
295  iter,
296  runNumber,
298  } else {
299  iter->second.lumiSectionsToNEvents[lumiSect] = std::numeric_limits<unsigned long>::max();
300  }
301  }
302  }
303  }
304 
305  static constexpr std::string_view kJobReportEndElement = "</FrameworkJobReport>\n";
306  static constexpr int kMinSizeOfComment = 8;
307 
309  impl_->flushFiles();
310  if (impl_->ost_) {
311  //are we actually at the end of the file?
312  auto pos = impl_->ost_->tellp();
313  impl_->ost_->seekp(0, std::ios_base::end);
314  auto endpos = impl_->ost_->tellp();
315  impl_->ost_->seekp(pos);
316  if ((endpos - pos) > static_cast<long int>(kJobReportEndElement.size())) {
317  //need to add some padding so use a comment element
318  // comment is used since white spaces are converted to a special node
319  // while comments are usually ignored by xml parsers
320  auto padding = (endpos - pos) - (kJobReportEndElement.size() + kMinSizeOfComment);
321  *(impl_->ost_) << "<!--";
322  for (int i = padding; i > 0; --i) {
323  (*impl_->ost_) << ' ';
324  }
325  *(impl_->ost_) << "-->\n";
326  }
327  *(impl_->ost_) << kJobReportEndElement << std::flush;
328  }
329  }
330 
332  if (impl_->ost_) {
333  //remember where we were
334  auto pos = impl_->ost_->tellp();
335  if (not errorLogged_) {
336  *(impl_->ost_) << "<FrameworkError ExitStatus=\"8901\" Type=\"UnexpectedJobTermination\"/>\n";
337  }
338  *(impl_->ost_) << kJobReportEndElement << std::flush;
339 
340  //overwrite above during next write.
341  impl_->ost_->seekp(pos);
342  }
343  }
344 
346 
347  JobReport::JobReport(std::ostream* iOstream) : impl_(new JobReportImpl(iOstream)) {
348  if (impl_->ost_) {
349  *(impl_->ost_) << "<FrameworkJobReport>\n";
350  }
352  }
353 
355  std::string const& logicalFileName,
356  std::string const& catalog,
357  std::string const& inputType,
358  std::string const& inputSourceClassName,
359  std::string const& moduleLabel,
360  std::string const& guid,
361  std::vector<std::string> const& branchNames) {
362  InputType theInputType = InputType::Primary;
363  InputFile* newFile = nullptr;
364  JobReport::Token newToken = 0;
365 
366  if (inputType == "mixingFiles") {
367  theInputType = InputType::SecondarySource;
368  auto itr = impl_->inputFilesSecSource_.push_back(InputFile());
369  newFile = &(*itr);
370  newToken = itr - impl_->inputFilesSecSource_.begin();
371  } else {
372  if (inputType == "secondaryFiles") {
373  theInputType = InputType::SecondaryFile;
374  }
375  impl_->inputFiles_.emplace_back();
376  newFile = &impl_->inputFiles_.back();
377  newToken = impl_->inputFiles_.size() - 1;
378  }
379 
380  if (theInputType == InputType::Primary) {
381  impl_->lastOpenedPrimaryInputFile_ = impl_->inputFiles_.size() - 1;
382  }
383  newFile->logicalFileName = logicalFileName;
384  newFile->physicalFileName = physicalFileName;
385  newFile->catalog = catalog;
386  newFile->inputType = inputType;
387  newFile->inputSourceClassName = inputSourceClassName;
388  newFile->moduleLabel = moduleLabel;
389  newFile->guid = guid;
390  newFile->numEventsRead = 0;
391  newFile->branchNames = branchNames;
392  newFile->fileHasBeenClosed = false;
393 
394  // Add the new input file token to all output files
395  // currently open.
396  impl_->insertInputForOutputs(theInputType, newToken);
397  return newToken;
398  }
399 
401  JobReport::InputFile& f = impl_->getInputFileForToken(inputType, fileToken);
402  ++f.numEventsRead;
403  }
404 
406  JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
407  f.dataType = dataType;
408  }
409 
411  JobReport::InputFile& f = impl_->getInputFileForToken(inputType, fileToken);
412  f.fileHasBeenClosed = true;
413  std::lock_guard<std::mutex> lock(write_mutex);
414  if (inputType == InputType::Primary) {
415  impl_->writeInputFile(f);
416  } else {
417  impl_->writeInputFile(f);
418  }
420  }
421 
423  std::string const& logicalFileName,
424  std::string const& catalog,
425  std::string const& outputModuleClassName,
426  std::string const& moduleLabel,
427  std::string const& guid,
428  std::string const& dataType,
429  std::string const& branchHash,
430  std::vector<std::string> const& branchNames) {
431  auto itr = impl_->outputFiles_.emplace_back();
432  JobReport::OutputFile& r = *itr;
433 
434  r.logicalFileName = logicalFileName;
435  r.physicalFileName = physicalFileName;
436  r.catalog = catalog;
437  r.outputModuleClassName = outputModuleClassName;
438  r.moduleLabel = moduleLabel;
439  r.guid = guid;
440  r.dataType = dataType;
441  r.branchHash = branchHash;
442  r.numEventsWritten = 0;
443  r.branchNames = branchNames;
444  r.fileHasBeenClosed = false;
445  //
446  // Init list of contributors to list of open input file Tokens
447  //
448  for (std::vector<Token>::size_type i = 0, iEnd = impl_->inputFiles_.size(); i < iEnd; ++i) {
449  if (!impl_->inputFiles_[i].fileHasBeenClosed) {
450  r.contributingInputs.push_back(i);
451  }
452  }
453  for (oneapi::tbb::concurrent_vector<Token>::size_type i = 0, iEnd = impl_->inputFilesSecSource_.size(); i < iEnd;
454  ++i) {
455  if (!impl_->inputFilesSecSource_[i].fileHasBeenClosed) {
456  r.contributingInputsSecSource.push_back(i);
457  }
458  }
459  return itr - impl_->outputFiles_.begin();
460  }
461 
463  JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
464  ++f.numEventsWritten;
465  }
466 
468  JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
469  f.fileHasBeenClosed = true;
470  std::lock_guard<std::mutex> lock(write_mutex);
471  impl_->writeOutputFile(f);
473  }
474 
476  if (impl_->ost_) {
477  std::ostream& msg = *(impl_->ost_);
478  {
479  std::lock_guard<std::mutex> lock(write_mutex);
480  msg << "<SkippedEvent Run=\"" << run << "\"";
481  msg << " Event=\"" << event << "\" />\n";
483  }
484  }
485  }
486 
488  std::string const& inputFileName,
489  bool fastCopying) {
490  JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
491  f.fastCopyingInputs.insert(std::make_pair(inputFileName, fastCopying));
492  }
493 
495  unsigned int run,
496  unsigned int lumiSectId,
497  unsigned long nEvents) {
498  impl_->associateLumiSection(token, run, lumiSectId, nEvents);
499  }
500 
501  void JobReport::reportInputLumiSection(unsigned int run, unsigned int lumiSectId) {
502  impl_->associateInputLumiSection(run, lumiSectId);
503  }
504 
505  void JobReport::reportRunNumber(JobReport::Token token, unsigned int run) { impl_->associateRun(token, run); }
506 
507  void JobReport::reportInputRunNumber(unsigned int run) { impl_->associateInputRun(run); }
508 
509  void JobReport::reportAnalysisFile(std::string const& fileName, std::map<std::string, std::string> const& fileData) {
510  tinyxml2::XMLDocument doc;
511  if (impl_->ost_) {
512  std::ostream& msg = *(impl_->ost_);
513  {
514  std::lock_guard<std::mutex> lock(write_mutex);
515  msg << "<AnalysisFile>\n"
516  << " <FileName>" << doc.NewText(fileName.c_str())->Value() << "</FileName>\n";
517 
518  typedef std::map<std::string, std::string>::const_iterator const_iterator;
519  for (const_iterator pos = fileData.begin(), posEnd = fileData.end(); pos != posEnd; ++pos) {
520  msg << " <" << pos->first << " Value=\"" << pos->second << "\" />"
521  << "\n";
522  }
523  msg << "</AnalysisFile>\n";
525  }
526  }
527  }
528 
529  void JobReport::reportError(std::string const& shortDesc, std::string const& longDesc, int const& exitCode) {
530  if (impl_->ost_) {
531  {
532  std::lock_guard<std::mutex> lock(write_mutex);
533  errorLogged_ = true;
534  std::ostream& msg = *(impl_->ost_);
535  msg << "<FrameworkError ExitStatus=\"" << exitCode << "\" Type=\"" << shortDesc << "\" >\n";
536  msg << "<![CDATA[\n" << longDesc << "\n]]>\n";
537  msg << "</FrameworkError>\n";
539  }
540  }
541  }
542 
544  if (impl_->ost_) {
545  {
546  std::lock_guard<std::mutex> lock(write_mutex);
547  std::ostream& msg = *(impl_->ost_);
548  msg << "<ShutdownSignal/>\n";
550  }
551  }
552  }
553 
554  void JobReport::reportSkippedFile(std::string const& pfn, std::string const& lfn) {
555  if (impl_->ost_) {
556  std::ostream& msg = *(impl_->ost_);
557  tinyxml2::XMLDocument doc;
558  tinyxml2::XMLPrinter printer;
559  tinyxml2::XMLElement* skipped = doc.NewElement("SkippedFile");
560  skipped->SetAttribute("Pfn", pfn.c_str());
561  skipped->SetAttribute("Lfn", lfn.c_str());
562  {
563  std::lock_guard<std::mutex> lock(write_mutex);
564  skipped->Accept(&printer);
565  msg << printer.CStr();
567  }
568  }
569  }
570 
572  if (impl_->ost_) {
573  std::ostream& msg = *(impl_->ost_);
574  tinyxml2::XMLDocument doc;
575  tinyxml2::XMLPrinter printer;
576  tinyxml2::XMLElement* fallback = doc.NewElement("FallbackAttempt");
577  fallback->SetAttribute("Pfn", pfn.c_str());
578  fallback->SetAttribute("Lfn", lfn.c_str());
579  {
580  std::lock_guard<std::mutex> lock(write_mutex);
581  fallback->Accept(&printer);
582  msg << printer.CStr();
583  msg << "<![CDATA[\n" << err << "\n]]>\n";
585  }
586  }
587  }
588 
589  void JobReport::reportMemoryInfo(std::vector<std::string> const& memoryData) {
590  if (impl_->ost_) {
591  std::lock_guard<std::mutex> lock(write_mutex);
592  std::ostream& msg = *(impl_->ost_);
593  msg << "<MemoryService>\n";
594 
595  typedef std::vector<std::string>::const_iterator const_iterator;
596  for (const_iterator pos = memoryData.begin(), posEnd = memoryData.end(); pos != posEnd; ++pos) {
597  msg << *pos << "\n";
598  }
599  msg << "</MemoryService>\n";
601  }
602  }
603 
604  void JobReport::reportMessageInfo(std::map<std::string, double> const& messageData) {
605  if (impl_->ost_) {
606  std::lock_guard<std::mutex> lock(write_mutex);
607  std::ostream& msg = *(impl_->ost_);
608  msg << "<MessageSummary>\n";
609  typedef std::map<std::string, double>::const_iterator const_iterator;
610  for (const_iterator pos = messageData.begin(), posEnd = messageData.end(); pos != posEnd; ++pos) {
611  msg << " <" << pos->first << " Value=\"" << pos->second << "\" />"
612  << "\n";
613  }
614  msg << "</MessageSummary>\n";
616  }
617  }
618 
620  bool expected = false;
621  if (not impl_->printedReadBranches_.compare_exchange_strong(expected, true))
622  return;
623  if (impl_->ost_) {
624  std::lock_guard<std::mutex> lock(write_mutex);
625  std::ostream& ost = *(impl_->ost_);
626  ost << "<ReadBranches>\n";
627  tinyxml2::XMLDocument doc;
628  tinyxml2::XMLPrinter printer;
629  for (auto const& iBranch : impl_->readBranches_) {
630  tinyxml2::XMLElement* branch = doc.NewElement("Branch");
631  branch->SetAttribute("Name", iBranch.first.c_str());
632  branch->SetAttribute("ReadCount", int64_t(iBranch.second));
633  branch->Accept(&printer);
634  ost << printer.CStr();
635  printer.ClearBuffer();
636  }
637  for (auto const& iBranch : impl_->readBranchesSecFile_) {
638  tinyxml2::XMLElement* branch = doc.NewElement("Branch");
639  branch->SetAttribute("Name", iBranch.first.c_str());
640  branch->SetAttribute("ReadCount", int64_t(iBranch.second));
641  branch->Accept(&printer);
642  ost << printer.CStr();
643  printer.ClearBuffer();
644  }
645  ost << "</ReadBranches>\n";
646  if (!impl_->readBranchesSecSource_.empty()) {
647  ost << "<SecondarySourceReadBranches>\n";
648  for (auto const& iBranch : impl_->readBranchesSecSource_) {
649  tinyxml2::XMLElement* branch = doc.NewElement("Branch");
650  branch->SetAttribute("Name", iBranch.first.c_str());
651  branch->SetAttribute("ReadCount", int64_t(iBranch.second.value().load()));
652  branch->Accept(&printer);
653  ost << printer.CStr();
654  printer.ClearBuffer();
655  }
656  ost << "</SecondarySourceReadBranches>\n";
657  }
659  }
660  }
661 
663  if (inputType == InputType::Primary) {
664  // Fast cloned branches have already been reported.
665  std::set<std::string> const& clonedBranches =
666  impl_->inputFiles_.at(impl_->lastOpenedPrimaryInputFile_).fastClonedBranches;
667  if (clonedBranches.find(branchName) == clonedBranches.end()) {
668  ++impl_->readBranches_[branchName];
669  }
670  } else if (inputType == InputType::SecondaryFile) {
671  ++impl_->readBranchesSecFile_[branchName];
672  } else if (inputType == InputType::SecondarySource) {
673  ++impl_->readBranchesSecSource_[branchName].value();
674  }
675  }
676 
677  void JobReport::reportFastClonedBranches(std::set<std::string> const& fastClonedBranches, long long nEvents) {
678  std::set<std::string>& clonedBranches =
679  impl_->inputFiles_.at(impl_->lastOpenedPrimaryInputFile_).fastClonedBranches;
680  for (std::set<std::string>::const_iterator it = fastClonedBranches.begin(), itEnd = fastClonedBranches.end();
681  it != itEnd;
682  ++it) {
683  if (clonedBranches.insert(*it).second) {
684  impl_->readBranches_[*it] += nEvents;
685  }
686  }
687  }
688 
690  tinyxml2::XMLDocument doc;
691  if (impl_->ost_) {
692  std::ostream& msg = *(impl_->ost_);
693  {
694  std::lock_guard<std::mutex> lock(write_mutex);
695  msg << "<RandomServiceStateFile>\n"
696  << doc.NewText(name.c_str())->Value() << "\n"
697  << "</RandomServiceStateFile>\n";
699  }
700  }
701  }
702 
704  std::map<std::string, std::string> const& metrics) {
705  if (impl_->ost_) {
706  std::ostream& msg = *(impl_->ost_);
707  msg << "<PerformanceReport>\n"
708  << " <PerformanceSummary Metric=\"" << metricClass << "\">\n";
709 
710  typedef std::map<std::string, std::string>::const_iterator const_iterator;
711  for (const_iterator iter = metrics.begin(), iterEnd = metrics.end(); iter != iterEnd; ++iter) {
712  msg << " <Metric Name=\"" << iter->first << "\" "
713  << "Value=\"" << iter->second << "\"/>\n";
714  }
715 
716  msg << " </PerformanceSummary>\n"
717  << "</PerformanceReport>\n";
719  }
720  }
721 
723  std::string const& moduleName,
724  std::map<std::string, std::string> const& metrics) {
725  if (impl_->ost_) {
726  std::ostream& msg = *(impl_->ost_);
727  msg << "<PerformanceReport>\n"
728  << " <PerformanceModule Metric=\"" << metricClass << "\" "
729  << " Module=\"" << moduleName << "\" >\n";
730 
731  typedef std::map<std::string, std::string>::const_iterator const_iterator;
732  for (const_iterator iter = metrics.begin(), iterEnd = metrics.end(); iter != iterEnd; ++iter) {
733  msg << " <Metric Name=\"" << iter->first << "\" "
734  << "Value=\"" << iter->second << "\"/>\n";
735  }
736 
737  msg << " </PerformanceModule>\n"
738  << "</PerformanceReport>\n";
740  }
741  }
742 
744  std::ostringstream msg;
745 
746  tinyxml2::XMLDocument doc;
747  for (auto const& f : impl_->outputFiles_) {
748  msg << "\n<File>";
749  msg << f;
750 
751  msg << "\n<LumiSections>";
752  msg << "\n<Inputs>";
753  typedef std::vector<JobReport::Token>::iterator iterator;
754  for (auto const& iInput : f.contributingInputs) {
755  auto const& inpFile = impl_->inputFiles_[iInput];
756  msg << "\n<Input>";
757  msg << "\n <LFN>" << doc.NewText(inpFile.logicalFileName.c_str())->Value() << "</LFN>";
758  msg << "\n <PFN>" << doc.NewText(inpFile.physicalFileName.c_str())->Value() << "</PFN>";
759  msg << "\n <FastCopying>" << findOrDefault(f.fastCopyingInputs, inpFile.physicalFileName) << "</FastCopying>";
760  msg << "\n</Input>";
761  doc.DeleteChildren();
762  }
763  msg << "\n</Inputs>";
764  msg << "\n</File>";
765  }
766  return msg.str();
767  }
768 
769 } // namespace edm
InputType
Definition: InputType.h:5
void reportSkippedFile(std::string const &pfn, std::string const &lfn)
Definition: JobReport.cc:554
std::string inputSourceClassName
Definition: JobReport.h:129
void associateRun(JobReport::Token token, unsigned int runNumber)
Definition: JobReport.cc:255
void reportMemoryInfo(std::vector< std::string > const &memoryData)
Definition: JobReport.cc:589
void reportInputRunNumber(unsigned int run)
Definition: JobReport.cc:507
void eventReadFromFile(InputType inputType, Token fileToken)
Definition: JobReport.cc:400
std::mutex write_mutex
Definition: JobReport.h:437
void reportFallbackAttempt(std::string const &pfn, std::string const &lfn, std::string const &err)
Definition: JobReport.cc:571
std::string logicalFileName
Definition: JobReport.h:125
bool errorLogged_
Definition: JobReport.h:438
static constexpr std::string_view kJobReportEndElement
Definition: JobReport.cc:305
unsigned long long EventNumber_t
void reportFastCopyingStatus(Token t, std::string const &inputFileName, bool fastCopying)
Definition: JobReport.cc:487
void temporarilyCloseXML()
Definition: JobReport.cc:331
void reportRunNumber(JobReport::Token token, unsigned int run)
Definition: JobReport.cc:505
void reportRandomStateFile(std::string const &name)
Definition: JobReport.cc:689
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:66
uint16_t size_type
edm::propagate_const< std::unique_ptr< JobReportImpl > > impl_
Definition: JobReport.h:436
static constexpr int kMinSizeOfComment
Definition: JobReport.cc:306
Token inputFileOpened(std::string const &physicalFileName, std::string const &logicalFileName, std::string const &catalog, std::string const &inputType, std::string const &inputSourceClassName, std::string const &moduleLabel, std::string const &guid, std::vector< std::string > const &branchNames)
Definition: JobReport.cc:354
std::vector< InputFile > inputFiles_
Definition: JobReport.h:252
void reportPerformanceForModule(std::string const &metricClass, std::string const &moduleName, std::map< std::string, std::string > const &metrics)
Definition: JobReport.cc:722
std::string physicalFileName
Definition: JobReport.h:126
void reportSkippedEvent(RunNumber_t run, EventNumber_t event)
Definition: JobReport.cc:475
void insertInputForOutputs(InputType inputType, Token t)
Definition: JobReport.cc:151
std::size_t numEventsRead
Definition: JobReport.h:132
void writeInputFile(InputFile const &f)
Definition: JobReport.cc:168
void reportInputLumiSection(unsigned int run, unsigned int lumiSectId)
Definition: JobReport.cc:501
void reportPerformanceSummary(std::string const &metricClass, std::map< std::string, std::string > const &metrics)
Definition: JobReport.cc:703
reco::JetExtendedAssociation::JetExtendedData Value
double f[11][100]
Token outputFileOpened(std::string const &physicalFileName, std::string const &logicalFileName, std::string const &catalog, std::string const &outputModuleClassName, std::string const &moduleLabel, std::string const &guid, std::string const &dataType, std::string const &branchHash, std::vector< std::string > const &branchNames)
Definition: JobReport.cc:422
rep
Definition: cuy.py:1189
void reportError(std::string const &shortDesc, std::string const &longDesc, int const &exitCode)
Definition: JobReport.cc:529
std::size_t Token
Definition: JobReport.h:106
void associateInputRun(unsigned int runNumber)
Definition: JobReport.cc:263
S & formatFile(T const &f, S &os)
Definition: JobReport.cc:40
void reportReadBranch(InputType inputType, std::string const &branchName)
Inform the job report that a branch has been read.
Definition: JobReport.cc:662
void reportFastClonedBranches(std::set< std::string > const &fastClonedBranches, long long nEvents)
Inform the job report that branches have been fast Cloned.
Definition: JobReport.cc:677
void reportShutdownSignal()
Definition: JobReport.cc:543
Value const & findOrDefault(std::map< Key, Value > const &m, Key const &k, Value const &defaultValue)
Definition: Map.h:24
void eventWrittenToFile(Token fileToken, RunNumber_t run, EventNumber_t event)
Definition: JobReport.cc:462
void reportMessageInfo(std::map< std::string, double > const &messageData)
Definition: JobReport.cc:604
tuple msg
Definition: mps_check.py:286
void associateLumiSection(JobReport::Token token, unsigned int runNumber, unsigned int lumiSection, unsigned long nEvents)
Definition: JobReport.cc:275
std::string dumpFiles(void)
debug/test util
Definition: JobReport.cc:743
std::string moduleName(StableProvenance const &provenance, ProcessHistory const &history)
Definition: Provenance.cc:27
HLT enums.
void reportAnalysisFile(std::string const &fileName, std::map< std::string, std::string > const &fileData)
Definition: JobReport.cc:509
void outputFileClosed(Token fileToken)
Definition: JobReport.cc:467
void writeOutputFile(OutputFile const &f)
Definition: JobReport.cc:195
unsigned int RunNumber_t
InputFile & getInputFileForToken(InputType inputType, Token t)
Definition: JobReport.cc:107
void reportDataType(Token fileToken, std::string const &dataType)
Definition: JobReport.cc:405
StringVector branchNames
Definition: JobReport.h:133
branchNames
Definition: haddnano.py:54
std::ostream & operator<<(std::ostream &ost, const HLTGlobalStatus &hlt)
Formatted printout of trigger table.
long double T
void inputFileClosed(InputType inputType, Token fileToken)
Definition: JobReport.cc:410
void associateInputLumiSection(unsigned int runNumber, unsigned int lumiSection)
Definition: JobReport.cc:288
Definition: event.py:1
void reportReadBranches()
Definition: JobReport.cc:619
OutputFile & getOutputFileForToken(Token t)
Definition: JobReport.cc:131
oneapi::tbb::concurrent_vector< InputFile > inputFilesSecSource_
Definition: JobReport.h:253
void reportLumiSection(JobReport::Token token, unsigned int run, unsigned int lumiSectId, unsigned long nEvents=0)
Definition: JobReport.cc:494