20 #include "oneapi/tbb/task_arena.h" 21 #include "oneapi/tbb/task_group.h" 30 #include <sys/resource.h> 33 #include <system_error> 37 #include "boost/ptr_container/ptr_deque.hpp" 82 std::vector<std::string>
makeArgs(uint32_t
nEvents,
unsigned int nThreads, std::uint32_t
seed)
const;
84 void executeScript(std::vector<std::string>
const&
args,
int id,
bool isPost)
const;
92 const std::vector<std::string>
args_;
130 : scriptName_((iConfig.getParameter<
edm::FileInPath>(
"scriptName")).
fullPath()),
131 outputFile_(iConfig.getParameter<
std::
string>(
"outputFile")),
133 npars_(iConfig.getParameter<uint32_t>(
"numberOfParameters")),
134 nEvents_(iConfig.getUntrackedParameter<uint32_t>(
"nEvents")),
135 storeXML_(iConfig.getUntrackedParameter<
bool>(
"storeXML")),
136 generateConcurrently_(iConfig.getUntrackedParameter<
bool>(
"generateConcurrently")),
137 postGenerationCommand_(iConfig.getUntrackedParameter<
std::
vector<
std::
string>>(
"postGenerationCommand")) {
140 <<
"Problem with configuration: " <<
args_.size() <<
" script arguments given, expected " <<
npars_;
142 if (iConfig.
exists(
"nPartonMapping")) {
144 for (
auto&
cfg : processMap) {
145 unsigned processId(
cfg.getParameter<
unsigned>(
"idprup"));
149 if (orderStr ==
"LO")
151 else if (orderStr ==
"NLO")
155 <<
"Invalid order specification for process " << processId <<
": " << orderStr;
157 unsigned np(
cfg.getParameter<
unsigned>(
"np"));
163 xmlPutToken_ = produces<LHEXMLStringProduct, edm::Transition::BeginRun>(
"LHEScriptOutput");
181 <<
"No lhe event found in ExternalLHEProducer::produce(). " 182 <<
"The likely cause is that the lhe file contains fewer events than were requested, which is possible " 183 <<
"in case of phase space integration or uneweighting efficiency problems.";
186 std::unique_ptr<LHEEventProduct> product(
205 order = procDef.first;
207 }
catch (std::out_of_range&) {
209 <<
"Unexpected IDPRUP encountered: " <<
partonLevel_->getHEPEUP()->IDPRUP;
214 product->setNpLO(
np);
215 product->setNpNLO(-1);
218 product->setNpLO(-1);
219 product->setNpNLO(
np);
246 <<
"The ExternalLHEProducer module requires the RandomNumberGeneratorService\n" 247 "which is not present in the configuration file. You must add the service\n" 248 "in the configuration file if you want to run ExternalLHEProducer";
251 std::vector<std::string> infiles;
257 std::exception_ptr except;
258 std::atomic<char> exceptSet{0};
260 tbb::this_task_arena::isolate([
this, &except, &infiles, &exceptSet, nEventsAve, overflow,
seed]() {
261 tbb::task_group
group;
269 using namespace std::filesystem;
272 infiles[
t] =
out.native();
276 if (exceptSet.compare_exchange_strong(expected, 1)) {
277 except = std::current_exception();
285 if (exceptSet != 0) {
286 std::rethrow_exception(except);
289 infiles = std::vector<std::string>(1,
outputFile_);
299 edm::LogWarning(
"ExternalLHEProducer") << postcmd[0] <<
" is not a relative path. Run it as a shell command.";
311 using namespace std::filesystem;
316 std::ifstream instream(
file);
320 instream.seekg(0, instream.end);
321 int insize = instream.tellg();
322 instream.seekg(0, instream.beg);
323 p->fillCompressedContent(instream, 0.25 * insize);
336 unsigned int skip = 0;
337 reader_ = std::make_unique<lhef::LHEReader>(infiles,
skip);
348 if (std::getenv(
"VALIDATION_RUN") !=
nullptr) {
350 <<
"Event loop is over, but there are still lhe events to process, ignoring...";
353 <<
"Error in ExternalLHEProducer::endRunProduce(). " 354 <<
"Event loop is over, but there are still lhe events to process." 355 <<
"This could happen if lhe file contains more events than requested. This is never expected to happen.";
362 using namespace std::filesystem;
365 if (unlink(
out.c_str())) {
366 throw cms::Exception(
"OutputDeleteError") <<
"Unable to delete original script output file " <<
out 367 <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
373 <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
379 unsigned int nThreads,
380 std::uint32_t
seed)
const {
381 std::vector<std::string>
args;
392 for (
unsigned int iArg = 0; iArg <
args.size(); iArg++) {
393 LogDebug(
"LHEInputArgs") <<
"arg [" << iArg <<
"] = " <<
args[iArg];
407 if ((
dir = opendir(
"/proc/self/fd"))) {
409 while ((
dp = readdir(
dir)) !=
nullptr) {
410 if ((strcmp(
dp->d_name,
".") == 0) || (strcmp(
dp->d_name,
"..") == 0)) {
413 if (sscanf(
dp->d_name,
"%d", &
fd) != 1) {
429 for (
fd = 3;
fd < maxfd + 1;
fd++) {
441 int filedes[2], fd_flags;
448 if ((fd_flags = fcntl(filedes[1], F_GETFD,
NULL)) == -1) {
450 <<
"Failed to get pipe file descriptor flags (errno=" << rc <<
", " << strerror(rc) <<
")";
452 if (fcntl(filedes[1], F_SETFD, fd_flags | FD_CLOEXEC) == -1) {
454 <<
"Failed to set pipe file descriptor flags (errno=" << rc <<
", " << strerror(rc) <<
")";
457 unsigned int argc_pre = 0;
462 unsigned int argc = argc_pre +
args.size();
468 for (
unsigned int i = 0;
i <
args.size();
i++) {
478 using namespace std::filesystem;
482 create_directory(newDir, ec);
483 current_path(newDir, ec);
488 while ((
write(filedes[1], &rc,
sizeof(
int)) == -1) && (errno == EINTR)) {
494 for (
unsigned int i = 0;
i <
args.size() + 1;
i++) {
501 <<
"Unable to fork a child (errno=" << errno <<
", " << strerror(errno) <<
")";
506 while (((rc2 =
read(filedes[0], &rc,
sizeof(
int))) == -1) && (errno == EINTR)) {
509 if ((rc2 ==
sizeof(
int)) && rc) {
511 <<
"Failed to execute script (errno=" << rc <<
", " << strerror(rc) <<
")";
518 if (waitpid(pid, &
status, 0) < 0) {
519 if (errno == EINTR) {
523 <<
"Failed to read child status (errno=" << errno <<
", " << strerror(errno) <<
")";
526 if (WIFSIGNALED(
status)) {
527 throw cms::Exception(
"ExternalLHEProducer") <<
"Child exited due to signal " << WTERMSIG(
status) <<
".";
535 throw cms::Exception(
"ExternalLHEProducer") <<
"Child failed with exit code " << rc <<
".";
544 desc.setComment(
"Executes an external script and places its output file into an EDM collection");
549 desc.add<std::vector<std::string>>(
"args");
550 desc.add<uint32_t>(
"numberOfParameters");
551 desc.addUntracked<uint32_t>(
"nEvents");
552 desc.addUntracked<
bool>(
"storeXML",
false);
553 desc.addUntracked<
bool>(
"generateConcurrently",
false)
554 ->setComment(
"If true, run the script concurrently in separate processes.");
555 desc.addUntracked<std::vector<std::string>>(
"postGenerationCommand", std::vector<std::string>())
557 "Command to run after the generation script has completed. The first argument can be a relative path.");
560 nPartonMappingDesc.
add<
unsigned>(
"idprup");
562 nPartonMappingDesc.
add<
unsigned>(
"np");
563 desc.addVPSetOptional(
"nPartonMapping", nPartonMappingDesc);
569 std::unique_ptr<LHERunInfoProduct> retValue;
571 for (
auto const&
file : iFiles) {
572 unsigned int skip = 0;
573 std::vector<std::string> infiles(1,
file);
574 auto reader = std::make_unique<lhef::LHEReader>(infiles,
skip);
575 auto parton =
reader->next();
579 auto runInfo = parton->getRunInfo();
582 std::for_each(
runInfo->getHeaders().begin(),
585 std::for_each(
runInfo->getComments().begin(),
589 retValue = std::make_unique<LHERunInfoProduct>(
std::move(product));
611 newFileOpened =
false;
void beginRunProduce(edm::Run &run, edm::EventSetup const &es) override
void addHeader(const Header &header)
std::string fullPath() const
void addComment(const std::string &line)
#define DEFINE_FWK_MODULE(type)
void produce(edm::Event &, const edm::EventSetup &) override
bool exists(std::string const ¶meterName) const
checks if a parameter exists
void addWeight(const WGT &wgt)
std::string to_string(const V &value)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
edm::EDPutTokenT< LHERunInfoProduct > beginRunPutToken_
edm::EDPutTokenT< LHEEventProduct > eventPutToken_
std::unique_ptr< LHERunInfoProduct > generateRunInfo(std::vector< std::string > const &files) const
void addDefault(ParameterSetDescription const &psetDescription)
virtual std::uint32_t mySeed() const =0
edm::EDPutTokenT< LHEXMLStringProduct > xmlPutToken_
bool generateConcurrently_
std::unique_ptr< lhef::LHEReader > reader_
std::map< unsigned, std::pair< unsigned, unsigned > > nPartonMapping_
def pipe(cmdline, input=None)
ParameterDescriptionBase * add(U const &iLabel, T const &value)
int closeDescriptors(int preserve) const
void executeScript(std::vector< std::string > const &args, int id, bool isPost) const
const std::vector< std::string > args_
std::vector< std::string > makeArgs(uint32_t nEvents, unsigned int nThreads, std::uint32_t seed) const
std::string outputContents_
const std::vector< std::string > postGenerationCommand_
void addComment(const std::string &line)
void beginRun(edm::Run const &, edm::EventSetup const &) override
void preallocThreads(unsigned int) override
bool mergeProduct(const LHERunInfoProduct &other)
VParameterSet const & getParameterSetVector(std::string const &name) const
FileCloseSentry & operator=(const FileCloseSentry &)=delete
Log< level::Warning, false > LogWarning
ExternalLHEProducer(const edm::ParameterSet &iConfig)
std::shared_ptr< lhef::LHEEvent > partonLevel_
void endRun(edm::Run const &, edm::EventSetup const &) override