File indexing completed on 2022-10-20 23:30:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include "FWCore/MessageLogger/interface/JobReport.h"
0021 #include "FWCore/Utilities/interface/Map.h"
0022 #include "FWCore/Utilities/interface/EDMException.h"
0023
0024
0025
0026 #include "tinyxml2.h"
0027 #include <fstream>
0028 #include <iomanip>
0029 #include <ostream>
0030 #include <sstream>
0031
0032 namespace edm {
0033
0034
0035
0036
0037
0038
0039 template <typename S, typename T>
0040 S& formatFile(T const& f, S& os) {
0041 tinyxml2::XMLDocument doc;
0042 if (f.fileHasBeenClosed) {
0043 os << "\n<State Value=\"closed\"/>";
0044 } else {
0045 os << "\n<State Value=\"open\"/>";
0046 }
0047 os << "\n<LFN>" << doc.NewText(f.logicalFileName.c_str())->Value() << "</LFN>";
0048 os << "\n<PFN>" << doc.NewText(f.physicalFileName.c_str())->Value() << "</PFN>";
0049 os << "\n<Catalog>" << doc.NewText(f.catalog.c_str())->Value() << "</Catalog>";
0050 os << "\n<ModuleLabel>" << doc.NewText(f.moduleLabel.c_str())->Value() << "</ModuleLabel>";
0051 os << "\n<GUID>" << f.guid << "</GUID>";
0052 os << "\n<Branches>";
0053 for (auto const& branch : f.branchNames) {
0054 os << "\n <Branch>" << doc.NewText(branch.c_str())->Value() << "</Branch>";
0055 doc.DeleteChildren();
0056 }
0057 os << "\n</Branches>";
0058 return os;
0059 }
0060
0061
0062
0063
0064
0065 template <typename S>
0066 S& print(S& os, JobReport::InputFile const& f) {
0067 tinyxml2::XMLDocument doc;
0068 os << "\n<InputFile>";
0069 formatFile(f, os);
0070 os << "\n<InputType>" << f.inputType << "</InputType>";
0071 os << "\n<InputSourceClass>" << doc.NewText(f.inputSourceClassName.c_str())->Value() << "</InputSourceClass>";
0072 os << "\n<EventsRead>" << f.numEventsRead << "</EventsRead>";
0073 return os;
0074 }
0075
0076 template <typename S>
0077 S& print(S& os, JobReport::OutputFile const& f) {
0078 tinyxml2::XMLDocument doc;
0079 formatFile(f, os);
0080 os << "\n<OutputModuleClass>" << doc.NewText(f.outputModuleClassName.c_str())->Value() << "</OutputModuleClass>";
0081 os << "\n<TotalEvents>" << f.numEventsWritten << "</TotalEvents>\n";
0082 os << "\n<DataType>" << doc.NewText(f.dataType.c_str())->Value() << "</DataType>\n";
0083 os << "\n<BranchHash>" << doc.NewText(f.branchHash.c_str())->Value() << "</BranchHash>\n";
0084 return os;
0085 }
0086
0087 template <typename S>
0088 S& print(S& os, JobReport::RunReport const& rep) {
0089 os << "\n<Run ID=\"" << rep.runNumber << "\">\n";
0090
0091 for (auto const& il : rep.lumiSectionsToNEvents) {
0092 if (std::numeric_limits<unsigned long>::max() == il.second) {
0093 os << " <LumiSection ID=\"" << il.first << "\"/>\n";
0094
0095 } else {
0096 os << " <LumiSection ID=\"" << il.first << "\" NEvents=\"" << il.second << "\"/>\n";
0097 }
0098 }
0099 os << "</Run>\n";
0100 return os;
0101 }
0102
0103 std::ostream& operator<<(std::ostream& os, JobReport::InputFile const& f) { return print(os, f); }
0104 std::ostream& operator<<(std::ostream& os, JobReport::OutputFile const& f) { return print(os, f); }
0105 std::ostream& operator<<(std::ostream& os, JobReport::RunReport const& f) { return print(os, f); }
0106
0107 JobReport::InputFile& JobReport::JobReportImpl::getInputFileForToken(InputType inputType, JobReport::Token t) {
0108 InputFile* inputFile = nullptr;
0109 if (inputType == InputType::SecondarySource) {
0110 if (t >= inputFilesSecSource_.size()) {
0111 throw edm::Exception(edm::errors::LogicError) << "Access reported for secondary source input file with token "
0112 << t << " but no matching input file is found\n";
0113 }
0114 inputFile = &inputFilesSecSource_[t];
0115 } else {
0116 if (t >= inputFiles_.size()) {
0117 throw edm::Exception(edm::errors::LogicError)
0118 << "Access reported for input file with token " << t << " but no matching input file is found\n";
0119 }
0120 inputFile = &inputFiles_[t];
0121 }
0122 if (inputFile->fileHasBeenClosed) {
0123 throw edm::Exception(edm::errors::LogicError)
0124 << "Access reported for input file with token " << t << " after this file has been closed.\n"
0125 << "File record follows:\n"
0126 << *inputFile << '\n';
0127 }
0128 return *inputFile;
0129 }
0130
0131 JobReport::OutputFile& JobReport::JobReportImpl::getOutputFileForToken(JobReport::Token t) {
0132 if (t >= outputFiles_.size()) {
0133 throw edm::Exception(edm::errors::LogicError)
0134 << "Access reported for output file with token " << t << " but no matching output file is found\n";
0135 }
0136 if (outputFiles_[t].fileHasBeenClosed) {
0137 throw edm::Exception(edm::errors::LogicError)
0138 << "Access reported for output file with token " << t << " after this file has been closed.\n"
0139 << "File record follows:\n"
0140 << outputFiles_[t] << '\n';
0141 }
0142 return outputFiles_[t];
0143 }
0144
0145
0146
0147
0148
0149
0150
0151 void JobReport::JobReportImpl::insertInputForOutputs(InputType inputType, JobReport::Token t) {
0152 for (auto& outputFile : outputFiles_) {
0153 if (!outputFile.fileHasBeenClosed) {
0154 if (inputType == InputType::SecondarySource) {
0155 outputFile.contributingInputsSecSource.push_back(t);
0156 } else {
0157 outputFile.contributingInputs.push_back(t);
0158 }
0159 }
0160 }
0161 }
0162
0163
0164
0165
0166
0167
0168 void JobReport::JobReportImpl::writeInputFile(JobReport::InputFile const& f) {
0169 if (ost_) {
0170 *ost_ << f;
0171 *ost_ << "\n<Runs>";
0172 for (auto const& runReport : f.runReports) {
0173 *ost_ << runReport.second;
0174 }
0175 *ost_ << "\n</Runs>\n";
0176 *ost_ << "</InputFile>\n";
0177 *ost_ << std::flush;
0178 }
0179 }
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195 void JobReport::JobReportImpl::writeOutputFile(JobReport::OutputFile const& f) {
0196 tinyxml2::XMLDocument doc;
0197 if (ost_) {
0198 *ost_ << "\n<File>";
0199 *ost_ << f;
0200
0201 *ost_ << "\n<Runs>";
0202 for (auto const& runReport : f.runReports) {
0203 *ost_ << runReport.second;
0204 }
0205 *ost_ << "\n</Runs>\n";
0206
0207 *ost_ << "\n<Inputs>";
0208 for (auto token : f.contributingInputs) {
0209 JobReport::InputFile inpFile = inputFiles_.at(token);
0210 *ost_ << "\n<Input>";
0211 *ost_ << "\n <LFN>" << doc.NewText(inpFile.logicalFileName.c_str())->Value() << "</LFN>";
0212 *ost_ << "\n <PFN>" << doc.NewText(inpFile.physicalFileName.c_str())->Value() << "</PFN>";
0213 *ost_ << "\n <FastCopying>" << findOrDefault(f.fastCopyingInputs, inpFile.physicalFileName)
0214 << "</FastCopying>";
0215 *ost_ << "\n</Input>";
0216 doc.DeleteChildren();
0217 }
0218 for (auto token : f.contributingInputsSecSource) {
0219 JobReport::InputFile inpFile = inputFilesSecSource_.at(token);
0220 *ost_ << "\n<Input>";
0221 *ost_ << "\n <LFN>" << doc.NewText(inpFile.logicalFileName.c_str())->Value() << "</LFN>";
0222 *ost_ << "\n <PFN>" << doc.NewText(inpFile.physicalFileName.c_str())->Value() << "</PFN>";
0223 *ost_ << "\n <FastCopying>" << findOrDefault(f.fastCopyingInputs, inpFile.physicalFileName)
0224 << "</FastCopying>";
0225 *ost_ << "\n</Input>";
0226 doc.DeleteChildren();
0227 }
0228 *ost_ << "\n</Inputs>";
0229 *ost_ << "\n</File>\n";
0230 }
0231 }
0232
0233
0234
0235
0236
0237 void JobReport::JobReportImpl::flushFiles(void) {
0238 for (auto const& inputFile : inputFiles_) {
0239 if (!(inputFile.fileHasBeenClosed)) {
0240 writeInputFile(inputFile);
0241 }
0242 }
0243 for (auto const& inputFile : inputFilesSecSource_) {
0244 if (!(inputFile.fileHasBeenClosed)) {
0245 writeInputFile(inputFile);
0246 }
0247 }
0248 for (auto const& outputFile : outputFiles_) {
0249 if (!(outputFile.fileHasBeenClosed)) {
0250 writeOutputFile(outputFile);
0251 }
0252 }
0253 }
0254
0255 void JobReport::JobReportImpl::associateRun(JobReport::Token token, unsigned int runNumber) {
0256 auto& theMap = outputFiles_.at(token).runReports;
0257 std::map<RunNumber, RunReport>::iterator iter(theMap.lower_bound(runNumber));
0258 if (iter == theMap.end() || runNumber < iter->first) {
0259 theMap.emplace_hint(iter, runNumber, JobReport::RunReport{runNumber, {}});
0260 }
0261 }
0262
0263 void JobReport::JobReportImpl::associateInputRun(unsigned int runNumber) {
0264 for (auto& inputFile : inputFiles_) {
0265 if (!inputFile.fileHasBeenClosed) {
0266 std::map<RunNumber, RunReport>& theMap = inputFile.runReports;
0267 std::map<RunNumber, RunReport>::iterator iter(theMap.lower_bound(runNumber));
0268 if (iter == theMap.end() || runNumber < iter->first) {
0269 theMap.emplace_hint(iter, runNumber, JobReport::RunReport{runNumber, {}});
0270 }
0271 }
0272 }
0273 }
0274
0275 void JobReport::JobReportImpl::associateLumiSection(JobReport::Token token,
0276 unsigned int runNumber,
0277 unsigned int lumiSect,
0278 unsigned long nEvents) {
0279 auto& theMap = outputFiles_.at(token).runReports;
0280 std::map<RunNumber, RunReport>::iterator iter(theMap.lower_bound(runNumber));
0281 if (iter == theMap.end() || runNumber < iter->first) {
0282 theMap.emplace_hint(iter, runNumber, JobReport::RunReport{runNumber, {{{lumiSect, nEvents}}}});
0283 } else {
0284 iter->second.lumiSectionsToNEvents[lumiSect] += nEvents;
0285 }
0286 }
0287
0288 void JobReport::JobReportImpl::associateInputLumiSection(unsigned int runNumber, unsigned int lumiSect) {
0289 for (auto& inputFile : inputFiles_) {
0290 if (!inputFile.fileHasBeenClosed) {
0291 std::map<RunNumber, RunReport>& theMap = inputFile.runReports;
0292 std::map<RunNumber, RunReport>::iterator iter(theMap.lower_bound(runNumber));
0293 if (iter == theMap.end() || runNumber < iter->first) {
0294 theMap.emplace_hint(
0295 iter,
0296 runNumber,
0297 JobReport::RunReport{runNumber, {{lumiSect, std::numeric_limits<unsigned long>::max()}}});
0298 } else {
0299 iter->second.lumiSectionsToNEvents[lumiSect] = std::numeric_limits<unsigned long>::max();
0300 }
0301 }
0302 }
0303 }
0304
0305 JobReport::~JobReport() {
0306 impl_->flushFiles();
0307 if (impl_->ost_) {
0308 *(impl_->ost_) << "</FrameworkJobReport>\n" << std::flush;
0309 }
0310 }
0311
0312 void JobReport::temporarilyCloseXML() {
0313 if (impl_->ost_) {
0314
0315 auto pos = impl_->ost_->tellp();
0316 *(impl_->ost_) << "</FrameworkJobReport>\n" << std::flush;
0317
0318 impl_->ost_->seekp(pos);
0319 }
0320 }
0321
0322 JobReport::JobReport() : impl_(new JobReportImpl(nullptr)) {}
0323
0324 JobReport::JobReport(std::ostream* iOstream) : impl_(new JobReportImpl(iOstream)) {
0325 if (impl_->ost_) {
0326 *(impl_->ost_) << "<FrameworkJobReport>\n";
0327 }
0328 temporarilyCloseXML();
0329 }
0330
0331 JobReport::Token JobReport::inputFileOpened(std::string const& physicalFileName,
0332 std::string const& logicalFileName,
0333 std::string const& catalog,
0334 std::string const& inputType,
0335 std::string const& inputSourceClassName,
0336 std::string const& moduleLabel,
0337 std::string const& guid,
0338 std::vector<std::string> const& branchNames) {
0339 InputType theInputType = InputType::Primary;
0340 InputFile* newFile = nullptr;
0341 JobReport::Token newToken = 0;
0342
0343 if (inputType == "mixingFiles") {
0344 theInputType = InputType::SecondarySource;
0345 auto itr = impl_->inputFilesSecSource_.push_back(InputFile());
0346 newFile = &(*itr);
0347 newToken = itr - impl_->inputFilesSecSource_.begin();
0348 } else {
0349 if (inputType == "secondaryFiles") {
0350 theInputType = InputType::SecondaryFile;
0351 }
0352 impl_->inputFiles_.emplace_back();
0353 newFile = &impl_->inputFiles_.back();
0354 newToken = impl_->inputFiles_.size() - 1;
0355 }
0356
0357 if (theInputType == InputType::Primary) {
0358 impl_->lastOpenedPrimaryInputFile_ = impl_->inputFiles_.size() - 1;
0359 }
0360 newFile->logicalFileName = logicalFileName;
0361 newFile->physicalFileName = physicalFileName;
0362 newFile->catalog = catalog;
0363 newFile->inputType = inputType;
0364 newFile->inputSourceClassName = inputSourceClassName;
0365 newFile->moduleLabel = moduleLabel;
0366 newFile->guid = guid;
0367 newFile->numEventsRead = 0;
0368 newFile->branchNames = branchNames;
0369 newFile->fileHasBeenClosed = false;
0370
0371
0372
0373 impl_->insertInputForOutputs(theInputType, newToken);
0374 return newToken;
0375 }
0376
0377 void JobReport::eventReadFromFile(InputType inputType, JobReport::Token fileToken) {
0378 JobReport::InputFile& f = impl_->getInputFileForToken(inputType, fileToken);
0379 ++f.numEventsRead;
0380 }
0381
0382 void JobReport::reportDataType(Token fileToken, std::string const& dataType) {
0383 JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
0384 f.dataType = dataType;
0385 }
0386
0387 void JobReport::inputFileClosed(InputType inputType, JobReport::Token fileToken) {
0388 JobReport::InputFile& f = impl_->getInputFileForToken(inputType, fileToken);
0389 f.fileHasBeenClosed = true;
0390 std::lock_guard<std::mutex> lock(write_mutex);
0391 if (inputType == InputType::Primary) {
0392 impl_->writeInputFile(f);
0393 } else {
0394 impl_->writeInputFile(f);
0395 }
0396 temporarilyCloseXML();
0397 }
0398
0399 JobReport::Token JobReport::outputFileOpened(std::string const& physicalFileName,
0400 std::string const& logicalFileName,
0401 std::string const& catalog,
0402 std::string const& outputModuleClassName,
0403 std::string const& moduleLabel,
0404 std::string const& guid,
0405 std::string const& dataType,
0406 std::string const& branchHash,
0407 std::vector<std::string> const& branchNames) {
0408 auto itr = impl_->outputFiles_.emplace_back();
0409 JobReport::OutputFile& r = *itr;
0410
0411 r.logicalFileName = logicalFileName;
0412 r.physicalFileName = physicalFileName;
0413 r.catalog = catalog;
0414 r.outputModuleClassName = outputModuleClassName;
0415 r.moduleLabel = moduleLabel;
0416 r.guid = guid;
0417 r.dataType = dataType;
0418 r.branchHash = branchHash;
0419 r.numEventsWritten = 0;
0420 r.branchNames = branchNames;
0421 r.fileHasBeenClosed = false;
0422
0423
0424
0425 for (std::vector<Token>::size_type i = 0, iEnd = impl_->inputFiles_.size(); i < iEnd; ++i) {
0426 if (!impl_->inputFiles_[i].fileHasBeenClosed) {
0427 r.contributingInputs.push_back(i);
0428 }
0429 }
0430 for (oneapi::tbb::concurrent_vector<Token>::size_type i = 0, iEnd = impl_->inputFilesSecSource_.size(); i < iEnd;
0431 ++i) {
0432 if (!impl_->inputFilesSecSource_[i].fileHasBeenClosed) {
0433 r.contributingInputsSecSource.push_back(i);
0434 }
0435 }
0436 return itr - impl_->outputFiles_.begin();
0437 }
0438
0439 void JobReport::eventWrittenToFile(JobReport::Token fileToken, RunNumber_t , EventNumber_t) {
0440 JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
0441 ++f.numEventsWritten;
0442 }
0443
0444 void JobReport::outputFileClosed(JobReport::Token fileToken) {
0445 JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
0446 f.fileHasBeenClosed = true;
0447 std::lock_guard<std::mutex> lock(write_mutex);
0448 impl_->writeOutputFile(f);
0449 temporarilyCloseXML();
0450 }
0451
0452 void JobReport::reportSkippedEvent(RunNumber_t run, EventNumber_t event) {
0453 if (impl_->ost_) {
0454 std::ostream& msg = *(impl_->ost_);
0455 {
0456 std::lock_guard<std::mutex> lock(write_mutex);
0457 msg << "<SkippedEvent Run=\"" << run << "\"";
0458 msg << " Event=\"" << event << "\" />\n";
0459 temporarilyCloseXML();
0460 }
0461 }
0462 }
0463
0464 void JobReport::reportFastCopyingStatus(JobReport::Token fileToken,
0465 std::string const& inputFileName,
0466 bool fastCopying) {
0467 JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
0468 f.fastCopyingInputs.insert(std::make_pair(inputFileName, fastCopying));
0469 }
0470
0471 void JobReport::reportLumiSection(JobReport::Token token,
0472 unsigned int run,
0473 unsigned int lumiSectId,
0474 unsigned long nEvents) {
0475 impl_->associateLumiSection(token, run, lumiSectId, nEvents);
0476 }
0477
0478 void JobReport::reportInputLumiSection(unsigned int run, unsigned int lumiSectId) {
0479 impl_->associateInputLumiSection(run, lumiSectId);
0480 }
0481
0482 void JobReport::reportRunNumber(JobReport::Token token, unsigned int run) { impl_->associateRun(token, run); }
0483
0484 void JobReport::reportInputRunNumber(unsigned int run) { impl_->associateInputRun(run); }
0485
0486 void JobReport::reportAnalysisFile(std::string const& fileName, std::map<std::string, std::string> const& fileData) {
0487 tinyxml2::XMLDocument doc;
0488 if (impl_->ost_) {
0489 std::ostream& msg = *(impl_->ost_);
0490 {
0491 std::lock_guard<std::mutex> lock(write_mutex);
0492 msg << "<AnalysisFile>\n"
0493 << " <FileName>" << doc.NewText(fileName.c_str())->Value() << "</FileName>\n";
0494
0495 typedef std::map<std::string, std::string>::const_iterator const_iterator;
0496 for (const_iterator pos = fileData.begin(), posEnd = fileData.end(); pos != posEnd; ++pos) {
0497 msg << " <" << pos->first << " Value=\"" << pos->second << "\" />"
0498 << "\n";
0499 }
0500 msg << "</AnalysisFile>\n";
0501 temporarilyCloseXML();
0502 }
0503 }
0504 }
0505
0506 void JobReport::reportError(std::string const& shortDesc, std::string const& longDesc, int const& exitCode) {
0507 if (impl_->ost_) {
0508 {
0509 std::lock_guard<std::mutex> lock(write_mutex);
0510 std::ostream& msg = *(impl_->ost_);
0511 msg << "<FrameworkError ExitStatus=\"" << exitCode << "\" Type=\"" << shortDesc << "\" >\n";
0512 msg << "<![CDATA[\n" << longDesc << "\n]]>\n";
0513 msg << "</FrameworkError>\n";
0514 temporarilyCloseXML();
0515 }
0516 }
0517 }
0518
0519 void JobReport::reportSkippedFile(std::string const& pfn, std::string const& lfn) {
0520 if (impl_->ost_) {
0521 std::ostream& msg = *(impl_->ost_);
0522 tinyxml2::XMLDocument doc;
0523 tinyxml2::XMLPrinter printer;
0524 tinyxml2::XMLElement* skipped = doc.NewElement("SkippedFile");
0525 skipped->SetAttribute("Pfn", pfn.c_str());
0526 skipped->SetAttribute("Lfn", lfn.c_str());
0527 {
0528 std::lock_guard<std::mutex> lock(write_mutex);
0529 skipped->Accept(&printer);
0530 msg << printer.CStr();
0531 temporarilyCloseXML();
0532 }
0533 }
0534 }
0535
0536 void JobReport::reportFallbackAttempt(std::string const& pfn, std::string const& lfn, std::string const& err) {
0537 if (impl_->ost_) {
0538 std::ostream& msg = *(impl_->ost_);
0539 tinyxml2::XMLDocument doc;
0540 tinyxml2::XMLPrinter printer;
0541 tinyxml2::XMLElement* fallback = doc.NewElement("FallbackAttempt");
0542 fallback->SetAttribute("Pfn", pfn.c_str());
0543 fallback->SetAttribute("Lfn", lfn.c_str());
0544 {
0545 std::lock_guard<std::mutex> lock(write_mutex);
0546 fallback->Accept(&printer);
0547 msg << printer.CStr();
0548 msg << "<![CDATA[\n" << err << "\n]]>\n";
0549 temporarilyCloseXML();
0550 }
0551 }
0552 }
0553
0554 void JobReport::reportMemoryInfo(std::vector<std::string> const& memoryData) {
0555 if (impl_->ost_) {
0556 std::lock_guard<std::mutex> lock(write_mutex);
0557 std::ostream& msg = *(impl_->ost_);
0558 msg << "<MemoryService>\n";
0559
0560 typedef std::vector<std::string>::const_iterator const_iterator;
0561 for (const_iterator pos = memoryData.begin(), posEnd = memoryData.end(); pos != posEnd; ++pos) {
0562 msg << *pos << "\n";
0563 }
0564 msg << "</MemoryService>\n";
0565 temporarilyCloseXML();
0566 }
0567 }
0568
0569 void JobReport::reportMessageInfo(std::map<std::string, double> const& messageData) {
0570 if (impl_->ost_) {
0571 std::lock_guard<std::mutex> lock(write_mutex);
0572 std::ostream& msg = *(impl_->ost_);
0573 msg << "<MessageSummary>\n";
0574 typedef std::map<std::string, double>::const_iterator const_iterator;
0575 for (const_iterator pos = messageData.begin(), posEnd = messageData.end(); pos != posEnd; ++pos) {
0576 msg << " <" << pos->first << " Value=\"" << pos->second << "\" />"
0577 << "\n";
0578 }
0579 msg << "</MessageSummary>\n";
0580 temporarilyCloseXML();
0581 }
0582 }
0583
0584 void JobReport::reportReadBranches() {
0585 bool expected = false;
0586 if (not impl_->printedReadBranches_.compare_exchange_strong(expected, true))
0587 return;
0588 if (impl_->ost_) {
0589 std::lock_guard<std::mutex> lock(write_mutex);
0590 std::ostream& ost = *(impl_->ost_);
0591 ost << "<ReadBranches>\n";
0592 tinyxml2::XMLDocument doc;
0593 tinyxml2::XMLPrinter printer;
0594 for (auto const& iBranch : impl_->readBranches_) {
0595 tinyxml2::XMLElement* branch = doc.NewElement("Branch");
0596 branch->SetAttribute("Name", iBranch.first.c_str());
0597 branch->SetAttribute("ReadCount", int64_t(iBranch.second));
0598 branch->Accept(&printer);
0599 ost << printer.CStr();
0600 printer.ClearBuffer();
0601 }
0602 for (auto const& iBranch : impl_->readBranchesSecFile_) {
0603 tinyxml2::XMLElement* branch = doc.NewElement("Branch");
0604 branch->SetAttribute("Name", iBranch.first.c_str());
0605 branch->SetAttribute("ReadCount", int64_t(iBranch.second));
0606 branch->Accept(&printer);
0607 ost << printer.CStr();
0608 printer.ClearBuffer();
0609 }
0610 ost << "</ReadBranches>\n";
0611 if (!impl_->readBranchesSecSource_.empty()) {
0612 ost << "<SecondarySourceReadBranches>\n";
0613 for (auto const& iBranch : impl_->readBranchesSecSource_) {
0614 tinyxml2::XMLElement* branch = doc.NewElement("Branch");
0615 branch->SetAttribute("Name", iBranch.first.c_str());
0616 branch->SetAttribute("ReadCount", int64_t(iBranch.second.value().load()));
0617 branch->Accept(&printer);
0618 ost << printer.CStr();
0619 printer.ClearBuffer();
0620 }
0621 ost << "</SecondarySourceReadBranches>\n";
0622 }
0623 temporarilyCloseXML();
0624 }
0625 }
0626
0627 void JobReport::reportReadBranch(InputType inputType, std::string const& branchName) {
0628 if (inputType == InputType::Primary) {
0629
0630 std::set<std::string> const& clonedBranches =
0631 impl_->inputFiles_.at(impl_->lastOpenedPrimaryInputFile_).fastClonedBranches;
0632 if (clonedBranches.find(branchName) == clonedBranches.end()) {
0633 ++impl_->readBranches_[branchName];
0634 }
0635 } else if (inputType == InputType::SecondaryFile) {
0636 ++impl_->readBranchesSecFile_[branchName];
0637 } else if (inputType == InputType::SecondarySource) {
0638 ++impl_->readBranchesSecSource_[branchName].value();
0639 }
0640 }
0641
0642 void JobReport::reportFastClonedBranches(std::set<std::string> const& fastClonedBranches, long long nEvents) {
0643 std::set<std::string>& clonedBranches =
0644 impl_->inputFiles_.at(impl_->lastOpenedPrimaryInputFile_).fastClonedBranches;
0645 for (std::set<std::string>::const_iterator it = fastClonedBranches.begin(), itEnd = fastClonedBranches.end();
0646 it != itEnd;
0647 ++it) {
0648 if (clonedBranches.insert(*it).second) {
0649 impl_->readBranches_[*it] += nEvents;
0650 }
0651 }
0652 }
0653
0654 void JobReport::reportRandomStateFile(std::string const& name) {
0655 tinyxml2::XMLDocument doc;
0656 if (impl_->ost_) {
0657 std::ostream& msg = *(impl_->ost_);
0658 {
0659 std::lock_guard<std::mutex> lock(write_mutex);
0660 msg << "<RandomServiceStateFile>\n"
0661 << doc.NewText(name.c_str())->Value() << "\n"
0662 << "</RandomServiceStateFile>\n";
0663 temporarilyCloseXML();
0664 }
0665 }
0666 }
0667
0668 void JobReport::reportPerformanceSummary(std::string const& metricClass,
0669 std::map<std::string, std::string> const& metrics) {
0670 if (impl_->ost_) {
0671 std::ostream& msg = *(impl_->ost_);
0672 msg << "<PerformanceReport>\n"
0673 << " <PerformanceSummary Metric=\"" << metricClass << "\">\n";
0674
0675 typedef std::map<std::string, std::string>::const_iterator const_iterator;
0676 for (const_iterator iter = metrics.begin(), iterEnd = metrics.end(); iter != iterEnd; ++iter) {
0677 msg << " <Metric Name=\"" << iter->first << "\" "
0678 << "Value=\"" << iter->second << "\"/>\n";
0679 }
0680
0681 msg << " </PerformanceSummary>\n"
0682 << "</PerformanceReport>\n";
0683 temporarilyCloseXML();
0684 }
0685 }
0686
0687 void JobReport::reportPerformanceForModule(std::string const& metricClass,
0688 std::string const& moduleName,
0689 std::map<std::string, std::string> const& metrics) {
0690 if (impl_->ost_) {
0691 std::ostream& msg = *(impl_->ost_);
0692 msg << "<PerformanceReport>\n"
0693 << " <PerformanceModule Metric=\"" << metricClass << "\" "
0694 << " Module=\"" << moduleName << "\" >\n";
0695
0696 typedef std::map<std::string, std::string>::const_iterator const_iterator;
0697 for (const_iterator iter = metrics.begin(), iterEnd = metrics.end(); iter != iterEnd; ++iter) {
0698 msg << " <Metric Name=\"" << iter->first << "\" "
0699 << "Value=\"" << iter->second << "\"/>\n";
0700 }
0701
0702 msg << " </PerformanceModule>\n"
0703 << "</PerformanceReport>\n";
0704 temporarilyCloseXML();
0705 }
0706 }
0707
0708 std::string JobReport::dumpFiles(void) {
0709 std::ostringstream msg;
0710
0711 tinyxml2::XMLDocument doc;
0712 for (auto const& f : impl_->outputFiles_) {
0713 msg << "\n<File>";
0714 msg << f;
0715
0716 msg << "\n<LumiSections>";
0717 msg << "\n<Inputs>";
0718 typedef std::vector<JobReport::Token>::iterator iterator;
0719 for (auto const& iInput : f.contributingInputs) {
0720 auto const& inpFile = impl_->inputFiles_[iInput];
0721 msg << "\n<Input>";
0722 msg << "\n <LFN>" << doc.NewText(inpFile.logicalFileName.c_str())->Value() << "</LFN>";
0723 msg << "\n <PFN>" << doc.NewText(inpFile.physicalFileName.c_str())->Value() << "</PFN>";
0724 msg << "\n <FastCopying>" << findOrDefault(f.fastCopyingInputs, inpFile.physicalFileName) << "</FastCopying>";
0725 msg << "\n</Input>";
0726 doc.DeleteChildren();
0727 }
0728 msg << "\n</Inputs>";
0729 msg << "\n</File>";
0730 }
0731 return msg.str();
0732 }
0733
0734 }