25 #include "boost/filesystem.hpp"
31 #include <sys/resource.h>
32 #include "tbb/task_arena.h"
34 #include "boost/bind.hpp"
36 #include "boost/ptr_container/ptr_deque.hpp"
91 const std::vector<std::string>
args_;
124 : scriptName_((iConfig.getParameter<
edm::FileInPath>(
"scriptName")).
fullPath()),
125 outputFile_(iConfig.getParameter<
std::
string>(
"outputFile")),
126 args_(iConfig.getParameter<
std::vector<
std::
string>>(
"args")),
127 npars_(iConfig.getParameter<uint32_t>(
"numberOfParameters")),
128 nEvents_(iConfig.getUntrackedParameter<uint32_t>(
"nEvents")),
129 storeXML_(iConfig.getUntrackedParameter<
bool>(
"storeXML")),
130 generateConcurrently_(iConfig.getUntrackedParameter<
bool>(
"generateConcurrently")) {
133 <<
"Problem with configuration: " <<
args_.size() <<
" script arguments given, expected " <<
npars_;
135 if (iConfig.
exists(
"nPartonMapping")) {
137 for (
auto&
cfg : processMap) {
138 unsigned processId(
cfg.getParameter<
unsigned>(
"idprup"));
142 if (orderStr ==
"LO")
144 else if (orderStr ==
"NLO")
148 <<
"Invalid order specification for process " << processId <<
": " << orderStr;
150 unsigned np(
cfg.getParameter<
unsigned>(
"np"));
156 produces<LHEXMLStringProduct, edm::Transition::BeginRun>(
"LHEScriptOutput");
158 produces<LHEEventProduct>();
159 produces<LHERunInfoProduct, edm::Transition::BeginRun>();
160 produces<LHERunInfoProduct, edm::Transition::EndRun>();
175 <<
"No lhe event found in ExternalLHEProducer::produce(). "
176 <<
"The likely cause is that the lhe file contains fewer events than were requested, which is possible "
177 <<
"in case of phase space integration or uneweighting efficiency problems.";
180 std::unique_ptr<LHEEventProduct> product(
199 order = procDef.first;
201 }
catch (std::out_of_range&) {
203 <<
"Unexpected IDPRUP encountered: " <<
partonLevel_->getHEPEUP()->IDPRUP;
208 product->setNpLO(
np);
209 product->setNpNLO(-1);
212 product->setNpLO(-1);
213 product->setNpNLO(
np);
228 std::for_each(
runInfo_->getHeaders().begin(),
231 std::for_each(
runInfo_->getComments().begin(),
261 <<
"The ExternalLHEProducer module requires the RandomNumberGeneratorService\n"
262 "which is not present in the configuration file. You must add the service\n"
263 "in the configuration file if you want to run ExternalLHEProducer";
266 std::vector<std::string> infiles;
272 std::exception_ptr except;
273 std::atomic<char> exceptSet{0};
275 tbb::this_task_arena::isolate([
this, &except, &infiles, &exceptSet, nEventsAve, overflow,
seed]() {
276 tbb::empty_task* waitTask =
new (tbb::task::allocate_root()) tbb::empty_task;
285 [
t,
this, &infiles,
seed,
nEvents, &except, &exceptSet, waitTask]() {
287 using namespace boost::filesystem;
288 using namespace std::string_literals;
290 infiles[
t] =
out.native();
294 if (exceptSet.compare_exchange_strong(expected, 1)) {
295 except = std::current_exception();
299 waitTask->decrement_ref_count();
301 tbb::task::spawn(*
task);
303 waitTask->wait_for_all();
304 tbb::task::destroy(*waitTask);
306 if (exceptSet != 0) {
307 std::rethrow_exception(except);
310 infiles = std::vector<std::string>(1,
outputFile_);
321 using namespace boost::filesystem;
326 std::ifstream instream(
file);
330 instream.seekg(0, instream.end);
331 int insize = instream.tellg();
332 instream.seekg(0, instream.beg);
333 p->fillCompressedContent(instream, 0.25 * insize);
341 unsigned int skip = 0;
342 reader_ = std::make_unique<lhef::LHEReader>(infiles,
skip);
349 std::for_each(
runInfo_->getHeaders().begin(),
352 std::for_each(
runInfo_->getComments().begin(),
369 std::unique_ptr<LHERunInfoProduct> product(
runInfoProducts_.pop_front().release());
376 <<
"Error in ExternalLHEProducer::endRunProduce(). "
377 <<
"Event loop is over, but there are still lhe events to process."
378 <<
"This could happen if lhe file contains more events than requested. This is never expected to happen.";
384 using namespace boost::filesystem;
385 using namespace std::string_literals;
387 if (unlink(
out.c_str())) {
388 throw cms::Exception(
"OutputDeleteError") <<
"Unable to delete original script output file " <<
out
389 <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
395 <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
402 std::uint32_t
seed)
const {
403 std::vector<std::string>
args;
409 args.push_back(std::to_string(
seed));
414 for (
unsigned int iArg = 0; iArg <
args.size(); iArg++) {
415 LogDebug(
"LHEInputArgs") <<
"arg [" << iArg <<
"] = " <<
args[iArg];
429 if ((
dir = opendir(
"/proc/self/fd"))) {
431 while ((
dp = readdir(
dir)) !=
nullptr) {
432 if ((strcmp(
dp->d_name,
".") == 0) || (strcmp(
dp->d_name,
"..") == 0)) {
435 if (sscanf(
dp->d_name,
"%d", &
fd) != 1) {
451 for (
fd = 3;
fd < maxfd + 1;
fd++) {
463 int filedes[2], fd_flags;
470 if ((fd_flags = fcntl(filedes[1], F_GETFD,
NULL)) == -1) {
472 <<
"Failed to get pipe file descriptor flags (errno=" << rc <<
", " << strerror(rc) <<
")";
474 if (fcntl(filedes[1], F_SETFD, fd_flags | FD_CLOEXEC) == -1) {
476 <<
"Failed to set pipe file descriptor flags (errno=" << rc <<
", " << strerror(rc) <<
")";
479 unsigned int argc = 1 +
args.size();
483 for (
unsigned int i = 1;
i <
argc;
i++) {
493 using namespace boost::filesystem;
494 using namespace std::string_literals;
495 boost::system::error_code ec;
496 auto newDir =
path(
"thread"s + std::to_string(
id));
497 create_directory(newDir, ec);
498 current_path(newDir, ec);
503 while ((
write(filedes[1], &rc,
sizeof(
int)) == -1) && (errno == EINTR)) {
509 for (
unsigned int i = 0;
i <
args.size() + 1;
i++) {
516 <<
"Unable to fork a child (errno=" << errno <<
", " << strerror(errno) <<
")";
521 while (((rc2 =
read(filedes[0], &rc,
sizeof(
int))) == -1) && (errno == EINTR)) {
524 if ((rc2 ==
sizeof(
int)) && rc) {
526 <<
"Failed to execute script (errno=" << rc <<
", " << strerror(rc) <<
")";
533 if (waitpid(pid, &
status, 0) < 0) {
534 if (errno == EINTR) {
538 <<
"Failed to read child status (errno=" << errno <<
", " << strerror(errno) <<
")";
541 if (WIFSIGNALED(
status)) {
542 throw cms::Exception(
"ExternalLHEProducer") <<
"Child exited due to signal " << WTERMSIG(
status) <<
".";
550 throw cms::Exception(
"ExternalLHEProducer") <<
"Child failed with exit code " << rc <<
".";
559 desc.
setComment(
"Executes an external script and places its output file into an EDM collection");
564 desc.
add<std::vector<std::string>>(
"args");
565 desc.
add<uint32_t>(
"numberOfParameters");
569 ->setComment(
"If true, run the script concurrently in separate processes.");
572 nPartonMappingDesc.
add<
unsigned>(
"idprup");
574 nPartonMappingDesc.
add<
unsigned>(
"np");
593 newFileOpened =
false;
600 std::shared_ptr<lhef::LHERunInfo> runInfoThis =
partonLevel_->getRunInfo();