28 #include <system_error>
33 #include <sys/resource.h>
34 #include "tbb/task_arena.h"
36 #include "boost/ptr_container/ptr_deque.hpp"
91 const std::vector<std::string>
args_;
128 : scriptName_((iConfig.getParameter<
edm::FileInPath>(
"scriptName")).
fullPath()),
129 outputFile_(iConfig.getParameter<
std::
string>(
"outputFile")),
131 npars_(iConfig.getParameter<uint32_t>(
"numberOfParameters")),
132 nEvents_(iConfig.getUntrackedParameter<uint32_t>(
"nEvents")),
133 storeXML_(iConfig.getUntrackedParameter<
bool>(
"storeXML")),
134 generateConcurrently_(iConfig.getUntrackedParameter<
bool>(
"generateConcurrently")) {
137 <<
"Problem with configuration: " <<
args_.size() <<
" script arguments given, expected " <<
npars_;
139 if (iConfig.
exists(
"nPartonMapping")) {
141 for (
auto&
cfg : processMap) {
142 unsigned processId(
cfg.getParameter<
unsigned>(
"idprup"));
146 if (orderStr ==
"LO")
148 else if (orderStr ==
"NLO")
152 <<
"Invalid order specification for process " << processId <<
": " << orderStr;
154 unsigned np(
cfg.getParameter<
unsigned>(
"np"));
160 produces<LHEXMLStringProduct, edm::Transition::BeginRun>(
"LHEScriptOutput");
162 produces<LHEEventProduct>();
163 produces<LHERunInfoProduct, edm::Transition::BeginRun>();
164 produces<LHERunInfoProduct, edm::Transition::EndRun>();
179 <<
"No lhe event found in ExternalLHEProducer::produce(). "
180 <<
"The likely cause is that the lhe file contains fewer events than were requested, which is possible "
181 <<
"in case of phase space integration or uneweighting efficiency problems.";
184 std::unique_ptr<LHEEventProduct> product(
203 order = procDef.first;
205 }
catch (std::out_of_range&) {
207 <<
"Unexpected IDPRUP encountered: " <<
partonLevel_->getHEPEUP()->IDPRUP;
212 product->setNpLO(
np);
213 product->setNpNLO(-1);
216 product->setNpLO(-1);
217 product->setNpNLO(
np);
232 std::for_each(
runInfo_->getHeaders().begin(),
235 std::for_each(
runInfo_->getComments().begin(),
265 <<
"The ExternalLHEProducer module requires the RandomNumberGeneratorService\n"
266 "which is not present in the configuration file. You must add the service\n"
267 "in the configuration file if you want to run ExternalLHEProducer";
270 std::vector<std::string> infiles;
276 std::exception_ptr except;
277 std::atomic<char> exceptSet{0};
279 tbb::this_task_arena::isolate([
this, &except, &infiles, &exceptSet, nEventsAve, overflow,
seed]() {
280 tbb::empty_task* waitTask =
new (tbb::task::allocate_root()) tbb::empty_task;
289 [
t,
this, &infiles,
seed,
nEvents, &except, &exceptSet, waitTask]() {
291 using namespace std::filesystem;
292 using namespace std::string_literals;
294 infiles[
t] =
out.native();
298 if (exceptSet.compare_exchange_strong(expected, 1)) {
299 except = std::current_exception();
303 waitTask->decrement_ref_count();
305 tbb::task::spawn(*
task);
307 waitTask->wait_for_all();
308 tbb::task::destroy(*waitTask);
310 if (exceptSet != 0) {
311 std::rethrow_exception(except);
314 infiles = std::vector<std::string>(1,
outputFile_);
325 using namespace std::filesystem;
330 std::ifstream instream(
file);
334 instream.seekg(0, instream.end);
335 int insize = instream.tellg();
336 instream.seekg(0, instream.beg);
337 p->fillCompressedContent(instream, 0.25 * insize);
345 unsigned int skip = 0;
346 reader_ = std::make_unique<lhef::LHEReader>(infiles,
skip);
353 std::for_each(
runInfo_->getHeaders().begin(),
356 std::for_each(
runInfo_->getComments().begin(),
373 std::unique_ptr<LHERunInfoProduct> product(
runInfoProducts_.front().release());
381 if (std::getenv(
"VALIDATION_RUN") !=
nullptr) {
383 <<
"Event loop is over, but there are still lhe events to process, ignoring...";
386 <<
"Error in ExternalLHEProducer::endRunProduce(). "
387 <<
"Event loop is over, but there are still lhe events to process."
388 <<
"This could happen if lhe file contains more events than requested. This is never expected to happen.";
395 using namespace std::filesystem;
396 using namespace std::string_literals;
398 if (unlink(
out.c_str())) {
399 throw cms::Exception(
"OutputDeleteError") <<
"Unable to delete original script output file " <<
out
400 <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
406 <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
413 std::uint32_t
seed)
const {
414 std::vector<std::string>
args;
420 args.push_back(std::to_string(
seed));
425 for (
unsigned int iArg = 0; iArg <
args.size(); iArg++) {
426 LogDebug(
"LHEInputArgs") <<
"arg [" << iArg <<
"] = " <<
args[iArg];
440 if ((
dir = opendir(
"/proc/self/fd"))) {
442 while ((
dp = readdir(
dir)) !=
nullptr) {
443 if ((strcmp(
dp->d_name,
".") == 0) || (strcmp(
dp->d_name,
"..") == 0)) {
446 if (sscanf(
dp->d_name,
"%d", &
fd) != 1) {
462 for (
fd = 3;
fd < maxfd + 1;
fd++) {
474 int filedes[2], fd_flags;
481 if ((fd_flags = fcntl(filedes[1], F_GETFD,
NULL)) == -1) {
483 <<
"Failed to get pipe file descriptor flags (errno=" << rc <<
", " << strerror(rc) <<
")";
485 if (fcntl(filedes[1], F_SETFD, fd_flags | FD_CLOEXEC) == -1) {
487 <<
"Failed to set pipe file descriptor flags (errno=" << rc <<
", " << strerror(rc) <<
")";
490 unsigned int argc = 1 +
args.size();
494 for (
unsigned int i = 1;
i <
argc;
i++) {
504 using namespace std::filesystem;
505 using namespace std::string_literals;
507 auto newDir =
path(
"thread"s + std::to_string(
id));
508 create_directory(newDir, ec);
509 current_path(newDir, ec);
514 while ((
write(filedes[1], &rc,
sizeof(
int)) == -1) && (errno == EINTR)) {
520 for (
unsigned int i = 0;
i <
args.size() + 1;
i++) {
527 <<
"Unable to fork a child (errno=" << errno <<
", " << strerror(errno) <<
")";
532 while (((rc2 =
read(filedes[0], &rc,
sizeof(
int))) == -1) && (errno == EINTR)) {
535 if ((rc2 ==
sizeof(
int)) && rc) {
537 <<
"Failed to execute script (errno=" << rc <<
", " << strerror(rc) <<
")";
544 if (waitpid(pid, &
status, 0) < 0) {
545 if (errno == EINTR) {
549 <<
"Failed to read child status (errno=" << errno <<
", " << strerror(errno) <<
")";
552 if (WIFSIGNALED(
status)) {
553 throw cms::Exception(
"ExternalLHEProducer") <<
"Child exited due to signal " << WTERMSIG(
status) <<
".";
561 throw cms::Exception(
"ExternalLHEProducer") <<
"Child failed with exit code " << rc <<
".";
570 desc.setComment(
"Executes an external script and places its output file into an EDM collection");
575 desc.add<std::vector<std::string>>(
"args");
576 desc.add<uint32_t>(
"numberOfParameters");
577 desc.addUntracked<uint32_t>(
"nEvents");
578 desc.addUntracked<
bool>(
"storeXML",
false);
579 desc.addUntracked<
bool>(
"generateConcurrently",
false)
580 ->setComment(
"If true, run the script concurrently in separate processes.");
583 nPartonMappingDesc.
add<
unsigned>(
"idprup");
585 nPartonMappingDesc.
add<
unsigned>(
"np");
586 desc.addVPSetOptional(
"nPartonMapping", nPartonMappingDesc);
604 newFileOpened =
false;
611 std::shared_ptr<lhef::LHERunInfo> runInfoThis =
partonLevel_->getRunInfo();