27 #include <system_error>
32 #include <sys/resource.h>
33 #include "tbb/task_arena.h"
34 #include "tbb/task_group.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 xmlPutToken_ = produces<LHEXMLStringProduct, edm::Transition::BeginRun>(
"LHEScriptOutput");
178 <<
"No lhe event found in ExternalLHEProducer::produce(). "
179 <<
"The likely cause is that the lhe file contains fewer events than were requested, which is possible "
180 <<
"in case of phase space integration or uneweighting efficiency problems.";
183 std::unique_ptr<LHEEventProduct> product(
202 order = procDef.first;
204 }
catch (std::out_of_range&) {
206 <<
"Unexpected IDPRUP encountered: " <<
partonLevel_->getHEPEUP()->IDPRUP;
211 product->setNpLO(
np);
212 product->setNpNLO(-1);
215 product->setNpLO(-1);
216 product->setNpNLO(
np);
243 <<
"The ExternalLHEProducer module requires the RandomNumberGeneratorService\n"
244 "which is not present in the configuration file. You must add the service\n"
245 "in the configuration file if you want to run ExternalLHEProducer";
248 std::vector<std::string> infiles;
254 std::exception_ptr except;
255 std::atomic<char> exceptSet{0};
257 tbb::this_task_arena::isolate([
this, &except, &infiles, &exceptSet, nEventsAve, overflow,
seed]() {
258 tbb::task_group
group;
266 using namespace std::filesystem;
267 using namespace std::string_literals;
269 infiles[
t] =
out.native();
273 if (exceptSet.compare_exchange_strong(expected, 1)) {
274 except = std::current_exception();
282 if (exceptSet != 0) {
283 std::rethrow_exception(except);
286 infiles = std::vector<std::string>(1,
outputFile_);
297 using namespace std::filesystem;
302 std::ifstream instream(
file);
306 instream.seekg(0, instream.end);
307 int insize = instream.tellg();
308 instream.seekg(0, instream.beg);
309 p->fillCompressedContent(instream, 0.25 * insize);
322 unsigned int skip = 0;
323 reader_ = std::make_unique<lhef::LHEReader>(infiles,
skip);
334 <<
"Error in ExternalLHEProducer::endRunProduce(). "
335 <<
"Event loop is over, but there are still lhe events to process."
336 <<
"This could happen if lhe file contains more events than requested. This is never expected to happen.";
342 using namespace std::filesystem;
343 using namespace std::string_literals;
345 if (unlink(
out.c_str())) {
346 throw cms::Exception(
"OutputDeleteError") <<
"Unable to delete original script output file " <<
out
347 <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
353 <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
360 std::uint32_t
seed)
const {
361 std::vector<std::string>
args;
367 args.push_back(std::to_string(
seed));
372 for (
unsigned int iArg = 0; iArg <
args.size(); iArg++) {
373 LogDebug(
"LHEInputArgs") <<
"arg [" << iArg <<
"] = " <<
args[iArg];
387 if ((
dir = opendir(
"/proc/self/fd"))) {
389 while ((
dp = readdir(
dir)) !=
nullptr) {
390 if ((strcmp(
dp->d_name,
".") == 0) || (strcmp(
dp->d_name,
"..") == 0)) {
393 if (sscanf(
dp->d_name,
"%d", &
fd) != 1) {
409 for (
fd = 3;
fd < maxfd + 1;
fd++) {
421 int filedes[2], fd_flags;
428 if ((fd_flags = fcntl(filedes[1], F_GETFD,
NULL)) == -1) {
430 <<
"Failed to get pipe file descriptor flags (errno=" << rc <<
", " << strerror(rc) <<
")";
432 if (fcntl(filedes[1], F_SETFD, fd_flags | FD_CLOEXEC) == -1) {
434 <<
"Failed to set pipe file descriptor flags (errno=" << rc <<
", " << strerror(rc) <<
")";
437 unsigned int argc = 1 +
args.size();
441 for (
unsigned int i = 1;
i <
argc;
i++) {
451 using namespace std::filesystem;
452 using namespace std::string_literals;
454 auto newDir =
path(
"thread"s + std::to_string(
id));
455 create_directory(newDir, ec);
456 current_path(newDir, ec);
461 while ((
write(filedes[1], &rc,
sizeof(
int)) == -1) && (errno == EINTR)) {
467 for (
unsigned int i = 0;
i <
args.size() + 1;
i++) {
474 <<
"Unable to fork a child (errno=" << errno <<
", " << strerror(errno) <<
")";
479 while (((rc2 =
read(filedes[0], &rc,
sizeof(
int))) == -1) && (errno == EINTR)) {
482 if ((rc2 ==
sizeof(
int)) && rc) {
484 <<
"Failed to execute script (errno=" << rc <<
", " << strerror(rc) <<
")";
491 if (waitpid(pid, &
status, 0) < 0) {
492 if (errno == EINTR) {
496 <<
"Failed to read child status (errno=" << errno <<
", " << strerror(errno) <<
")";
499 if (WIFSIGNALED(
status)) {
500 throw cms::Exception(
"ExternalLHEProducer") <<
"Child exited due to signal " << WTERMSIG(
status) <<
".";
508 throw cms::Exception(
"ExternalLHEProducer") <<
"Child failed with exit code " << rc <<
".";
517 desc.setComment(
"Executes an external script and places its output file into an EDM collection");
522 desc.add<std::vector<std::string>>(
"args");
523 desc.add<uint32_t>(
"numberOfParameters");
524 desc.addUntracked<uint32_t>(
"nEvents");
525 desc.addUntracked<
bool>(
"storeXML",
false);
526 desc.addUntracked<
bool>(
"generateConcurrently",
false)
527 ->setComment(
"If true, run the script concurrently in separate processes.");
530 nPartonMappingDesc.
add<
unsigned>(
"idprup");
532 nPartonMappingDesc.
add<
unsigned>(
"np");
533 desc.addVPSetOptional(
"nPartonMapping", nPartonMappingDesc);
539 std::unique_ptr<LHERunInfoProduct> retValue;
541 for (
auto const&
file : iFiles) {
542 unsigned int skip = 0;
543 std::vector<std::string> infiles(1,
file);
544 auto reader = std::make_unique<lhef::LHEReader>(infiles,
skip);
545 auto parton =
reader->next();
549 auto runInfo = parton->getRunInfo();
552 std::for_each(
runInfo->getHeaders().begin(),
555 std::for_each(
runInfo->getComments().begin(),
559 retValue = std::make_unique<LHERunInfoProduct>(
std::move(product));
561 retValue->mergeProduct(product);
581 newFileOpened =
false;