ATLAS Offline Software
Loading...
Searching...
No Matches
EL::PrunDriver Class Referencefinal

a Driver to submit jobs via prun More...

#include <PrunDriver.h>

Inheritance diagram for EL::PrunDriver:
Collaboration diagram for EL::PrunDriver:

Public Member Functions

 PrunDriver ()
void testInvariant () const
SH::MetaObjectoptions ()
 the list of options to jobs with this driver
const SH::MetaObjectoptions () const
std::string submit (const Job &job, const std::string &location) const
 submit the given job with the given output location and wait for it to finish
std::string submitOnly (const Job &job, const std::string &location) const
 submit the given job with the given output location and return immediately

Static Public Member Functions

static void status (const std::string &location)
static void setState (const std::string &location, const std::string &task, const std::string &state)
static void resubmit (const std::string &location, const std::string &option)
 resubmit all failed sub-jobs for the job in the given location
static bool retrieve (const std::string &location)
 retrieve all the output for the job in the given location
static bool wait (const std::string &location, unsigned time=60)
 retrieve all the output for the job in the given location and wait until it is finished completely.
static void updateLocation (const std::string &location)
 update the internal location of files, after moving the submission directory
static void mergedOutputSave (Detail::ManagerData &data)
 create and save a sample handler assuming we created all the merged files at the requested locations
static void diskOutputSave (Detail::ManagerData &data)
 make the output sample handler for the given job or stream from the information stored in the histogram files.

Protected Member Functions

virtual::StatusCode doManagerStep (Detail::ManagerData &data) const override

Static Protected Attributes

static bool abortRetrieve
 this flag is set to true when the wait() function is running and a SIGINT is caught, meaning that control should be returned to the user as soon as possible.

Private Member Functions

::StatusCode doRetrieve (Detail::ManagerData &data) const
 ClassDef (EL::PrunDriver, 1)

Private Attributes

SH::MetaObject m_options
 members directly corresponding to accessors

Detailed Description

a Driver to submit jobs via prun

Definition at line 23 of file PrunDriver.h.

Constructor & Destructor Documentation

◆ PrunDriver()

EL::PrunDriver::PrunDriver ( )

Definition at line 503 of file PrunDriver.cxx.

504{
505 RCU_NEW_INVARIANT(this);
506}
#define RCU_NEW_INVARIANT(x)
Definition Assert.h:221

Member Function Documentation

◆ ClassDef()

EL::PrunDriver::ClassDef ( EL::PrunDriver ,
1  )
private

◆ diskOutputSave()

void EL::Driver::diskOutputSave ( Detail::ManagerData & data)
staticinherited

make the output sample handler for the given job or stream from the information stored in the histogram files.

This is optional, but it is convenient for drivers that use (conventional) writers

Guarantee
basic
Failures
out of memory II
i/o errors

◆ doManagerStep()

StatusCode EL::PrunDriver::doManagerStep ( Detail::ManagerData & data) const
overrideprotected

Definition at line 508 of file PrunDriver.cxx.

510{
511 using namespace msgEventLoop;
513 switch (data.step)
514 {
516 {
517 const std::string jobELGDir = data.submitDir + "/elg";
518 const std::string runShFile = jobELGDir + "/runjob.sh";
519 //const std::string runShOrig = "$ROOTCOREBIN/data/EventLoopGrid/runjob.sh";
520 const std::string mergeShFile = jobELGDir + "/elg_merge";
521 //const std::string mergeShOrig =
522 // "$ROOTCOREBIN/user_scripts/EventLoopGrid/elg_merge";
523 const std::string runShOrig = PathResolverFindCalibFile("EventLoopGrid/runjob.sh");
524 const std::string mergeShOrig = PathResolverFindCalibFile("EventLoopGrid/elg_merge");
525
526 const std::string jobDefFile = jobELGDir + "/jobdef.root";
527 gSystem->Exec(Form("mkdir -p %s", jobELGDir.c_str()));
528 gSystem->Exec(Form("cp %s %s", runShOrig.c_str(), runShFile.c_str()));
529 gSystem->Exec(Form("chmod +x %s", runShFile.c_str()));
530 gSystem->Exec(Form("cp %s %s", mergeShOrig.c_str(), mergeShFile.c_str()));
531 gSystem->Exec(Form("chmod +x %s", mergeShFile.c_str()));
532
533 // create symbolic links for additionnal files/directories if any to ship to the grid
534 std::string listToShipToGrid = data.options.castString(EL::Job::optGridPrunShipAdditionalFilesOrDirs, "");
535 // parse the list of comma separated files and/or directories to ship to the grid
536 if (listToShipToGrid.size()){
538 "Creating symbolic links for additional files or directories to be sent to grid.\n"
539 "For root or heavy files you should also add their name (not the full path) to EL::Job::optUserFiles.\n"
540 "Otherwise prun ignores those files."
541 );
542
543 std::vector<std::string> vect_filesOrDirToShip;
544 for (auto&& part : std::views::split(listToShipToGrid, ',')) vect_filesOrDirToShip.emplace_back(part.begin(), part.end());
545 // Create symbolic links of files or directories to the submission directory
546 for (const std::string & fileOrDirToShip: vect_filesOrDirToShip){
547 ANA_MSG_INFO (("Creating symbolic link for: " +fileOrDirToShip).c_str());
548 RCU::Shell::exec("ln -sf " + fileOrDirToShip + " " + jobELGDir);
549 }
550 ANA_MSG_INFO ("Finished creation of symbolic links");
551 }
552
553 const SH::SampleHandler& sh = data.job->sampleHandler();
554
555 for (SH::SampleHandler::iterator s = sh.begin(); s != sh.end(); ++s) {
556 SH::MetaObject& meta = *(*s)->meta();
557 meta.fetchDefaults(data.options);
559 meta.setString("nc_outputs", outputFileNames(*data.job));
560 std::string outputSampleName = meta.castString("nc_outputSampleName");
561 if (outputSampleName.empty()) {
562 outputSampleName = "user.%nickname%.%in:name%";
563 }
564 meta.setString("nc_outDS", formatOutputName(meta, outputSampleName));
565 meta.setString("nc_inDS", meta.castString("nc_grid", (*s)->name()));
566 meta.setString("nc_writeInputToTxt", "IN:input.txt");
567 meta.setString("nc_match", meta.castString("nc_grid_filter"));
568 const std::string execstr = "runjob.sh " + (*s)->name();
569 meta.setString("nc_exec", execstr);
570 meta.setString("nc_framework", "EventLoopGrid");
571 }
572
573 saveJobDef(jobDefFile, *data.job, sh);
574
575 for (EL::Job::outputIter out = data.job->outputBegin();
576 out != data.job->outputEnd(); ++out) {
577 SH::SampleHandler shOut = outputSH(sh, out->label());
578 shOut.save(data.submitDir + "/output-" + out->label());
579 }
580 SH::SampleHandler shHist = outputSH(sh, "hist-output");
581 shHist.save(data.submitDir + "/output-hist");
582
583 TmpCd keepDir(jobELGDir);
584
585 processAllInState(sh, JobState::INIT, 0);
586
587 sh.save(data.submitDir + "/input");
588 data.submitted = true;
589 }
590 break;
591
593 {
594 ANA_CHECK (doRetrieve (data));
595 }
596 break;
597
598 default:
599 (void) true; // safe to do nothing
600 }
601 return ::StatusCode::SUCCESS;
602}
#define ANA_MSG_INFO(xmsg)
Macro printing info messages.
#define ANA_CHECK(EXP)
check whether the given expression was successful
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
static SH::MetaObject defaultOpts()
static void processAllInState(const SH::SampleHandler &sh, JobState::Enum state, const size_t nThreads)
std::string outputFileNames(const EL::Job &job)
static std::string formatOutputName(const SH::MetaObject &sampleMeta, const std::string &pattern)
static void saveJobDef(const std::string &fileName, const EL::Job &job, const SH::SampleHandler sh)
static SH::SampleHandler outputSH(const SH::SampleHandler &in, const std::string &outputLabel)
virtual::StatusCode doManagerStep(Detail::ManagerData &data) const
const OutputStream * outputIter
Definition Job.h:139
static const std::string optGridPrunShipAdditionalFilesOrDirs
Enables to ship additional files to the tarbal sent to the grid Should be a list of comma separated p...
Definition Job.h:473
::StatusCode doRetrieve(Detail::ManagerData &data) const
void fetchDefaults(const MetaObject &source)
fetch the meta-data from the given sample not present in this sample.
void setString(const std::string &name, const std::string &value)
set the meta-data string with the given name
std::string castString(const std::string &name, const std::string &def_val="", CastMode mode=CAST_ERROR_THROW) const
the meta-data string with the given name
void save(const std::string &directory) const
save the list of samples to the given directory
boost::transform_iterator< SamplePtrToRawSample, std::vector< std::shared_ptr< Sample > >::const_iterator > iterator
the iterator to use
@ doRetrieve
call the actual doRetrieve method
@ submitJob
do the actual job submission
Definition ManagerStep.h:92
void exec(const std::string &cmd)
effects: execute the given command guarantee: strong failures: out of memory II failures: system fail...
Definition ShellExec.cxx:27

◆ doRetrieve()

StatusCode EL::PrunDriver::doRetrieve ( Detail::ManagerData & data) const
private

Definition at line 604 of file PrunDriver.cxx.

605{
606 RCU_READ_INVARIANT(this);
607 RCU_REQUIRE(not data.submitDir.empty());
608
609 TmpCd tmpDir(data.submitDir);
610
611 SH::SampleHandler sh;
612 sh.load("input");
613 RCU_ASSERT(sh.size());
614
615 const size_t nRunThreads = options()->castDouble("nc_run_threads", 0);
616 const size_t nDlThreads = options()->castDouble("nc_download_threads", 0);
617 processAllInState(sh, JobState::INIT, 0);
618 processAllInState(sh, JobState::RUN, nRunThreads);
619 processAllInState(sh, JobState::DOWNLOAD, nDlThreads);
620 processAllInState(sh, JobState::MERGE, 0);
621
622 sh.save("input");
623
624 std::cout << std::endl;
625
626 bool allDone = true;
627 for (SH::SampleHandler::iterator s = sh.begin(); s != sh.end(); ++s) {
628 JobState::Enum state = sampleState(*s);
629 std::string details = (*s)->meta()->castString("nc_ELG_state_details", "", SH::MetaObject::CAST_NOCAST_DEFAULT);
630 if (not details.empty()) { details = '(' + details + ')'; }
631
632 std::cout << (*s)->name() << "\t";
633 switch (state) {
634 case JobState::INIT:
635 case JobState::RUN:
636 case JobState::DOWNLOAD:
637 case JobState::MERGE:
638 std::cout << JobState::name[state] << "\t";
639 break;
640 case JobState::FINISHED:
641 std::cout << "\033[1;32m" << JobState::name[state] << "\033[0m\t";
642 break;
643 case JobState::FAILED:
644 std::cout << "\033[1;31m" << JobState::name[state] << "\033[0m\t";
645 break;
646 }
647 std::cout << details << std::endl;
648
649 allDone &= (state == JobState::FINISHED || state == JobState::FAILED);
650 }
651
652 std::cout << std::endl;
653
654 data.retrieved = true;
655 data.completed = allDone;
656 return ::StatusCode::SUCCESS;
657}
#define RCU_ASSERT(x)
Definition Assert.h:210
#define RCU_REQUIRE(x)
Definition Assert.h:196
#define RCU_READ_INVARIANT(x)
Definition Assert.h:217
static JobState::Enum sampleState(SH::Sample *sample)
SH::MetaObject * options()
the list of options to jobs with this driver
double castDouble(const std::string &name, double def_val=0, CastMode mode=CAST_ERROR_THROW) const
the meta-data double with the given name
@ CAST_NOCAST_DEFAULT
cast and return the default value if the input has the wrong type
Definition MetaObject.h:70

◆ mergedOutputSave()

void EL::Driver::mergedOutputSave ( Detail::ManagerData & data)
staticinherited

create and save a sample handler assuming we created all the merged files at the requested locations

This is optional, but it is convenient for drivers that want to keep their outputs locally.

Guarantee
basic
Failures
out of memory II
i/o errors

◆ options() [1/2]

SH::MetaObject * EL::Driver::options ( )
inherited

the list of options to jobs with this driver

Guarantee
no-fail
Postcondition
result != 0

◆ options() [2/2]

const SH::MetaObject * EL::Driver::options ( ) const
inherited

◆ resubmit()

void EL::Driver::resubmit ( const std::string & location,
const std::string & option )
staticinherited

resubmit all failed sub-jobs for the job in the given location

\parm option driver-specific option string selecting which jobs to resubmit (and how)

Guarantee
basic, may partially resubmit
Failures
out of memory III
job resubmission errors
job can't be read
job was made with different driver

◆ retrieve()

bool EL::Driver::retrieve ( const std::string & location)
staticinherited

retrieve all the output for the job in the given location

While job failures will cause this method to fail you can typically retry it multiple times if you can use partial results.

Returns
whether the job completed successfully
Guarantee
basic, may partially retrieve
Failures
out of memory III
job failures
job can't be read
job was made with different driver

◆ setState()

void EL::PrunDriver::setState ( const std::string & location,
const std::string & task,
const std::string & state )
static

Definition at line 677 of file PrunDriver.cxx.

680{
681 RCU_REQUIRE(not location.empty());
682 RCU_REQUIRE(not task.empty());
683 RCU_REQUIRE(not state.empty());
684 TmpCd tmpDir(location);
685 SH::SampleHandler sh;
686 sh.load("input");
687 RCU_ASSERT(sh.size());
688 if (not sh.get(task)) {
689 std::cout << "Unknown task: " << task << std::endl;
690 std::cout << "Choose one of: " << std::endl;
691 sh.print();
692 return;
693 }
694 JobState::parse(state);
695 sh.get(task)->meta()->setString("nc_ELG_state", state);
696 sh.save("input");
697}

◆ status()

void EL::PrunDriver::status ( const std::string & location)
static

Definition at line 659 of file PrunDriver.cxx.

660{
661 RCU_REQUIRE(not location.empty());
662 TmpCd tmpDir(location);
663 SH::SampleHandler sh;
664 sh.load("input");
665 RCU_ASSERT(sh.size());
666 processAllInState(sh, JobState::RUN, 0);
667 sh.save("input");
668 for (SH::SampleHandler::iterator s = sh.begin(); s != sh.end(); ++s) {
669 JobState::Enum state = sampleState(*s);
670 std::string details = (*s)->meta()->castString("nc_ELG_state_details", "", SH::MetaObject::CAST_NOCAST_DEFAULT);
671 if (not details.empty()) { details = '(' + details + ')'; }
672 std::cout << (*s)->name() << "\t" << JobState::name[state]
673 << "\t" << details << std::endl;
674 }
675}

◆ submit()

std::string EL::Driver::submit ( const Job & job,
const std::string & location ) const
inherited

submit the given job with the given output location and wait for it to finish

This is mostly for small jobs and backward compatibility. For longer jobs use submitOnly instead.

Returns
The actual location of the submit directory, if the job was configured to generate a unique directory.
Guarantee
basic, may partially submit
Failures
out of memory II
Failures
can't create directory at location
submission errors

◆ submitOnly()

std::string EL::Driver::submitOnly ( const Job & job,
const std::string & location ) const
inherited

submit the given job with the given output location and return immediately

This method allows you to submit jobs to your local batch system, log out and at a later point log back in again.

Returns
The actual location of the submit directory, if the job was configured to generate a unique directory.
Guarantee
basic, may partially submit
Failures
out of memory II
can't create directory at location
submission errors \warn not all drivers support this. some will do all their work in the submit function. \warn you normally need to call wait() or retrieve() before you can use the output.

◆ testInvariant()

void EL::PrunDriver::testInvariant ( ) const

Definition at line 498 of file PrunDriver.cxx.

499{
500 RCU_INVARIANT(this != 0);
501}
#define RCU_INVARIANT(x)
Definition Assert.h:189

◆ updateLocation()

void EL::Driver::updateLocation ( const std::string & location)
staticinherited

update the internal location of files, after moving the submission directory

Guarantee
basic, may update partially
Failures
out of memory II \warn only move the submission directory after all your jobs are finished, or the results will be unpredictable

◆ wait()

bool EL::Driver::wait ( const std::string & location,
unsigned time = 60 )
staticinherited

retrieve all the output for the job in the given location and wait until it is finished completely.

poll the output every time seconds.

While job failures will cause this method to fail you can typically retry it multiple times if you can use partial results.

Typically sleeping for 60 seconds is an appropriate interval, but if it doesn't work for you, you can change it here.

Guarantee
basic, may partially retrieve
Failures
out of memory III
job failures
job can't be read
job was made with different driver

Member Data Documentation

◆ abortRetrieve

bool EL::Driver::abortRetrieve
staticprotectedinherited

this flag is set to true when the wait() function is running and a SIGINT is caught, meaning that control should be returned to the user as soon as possible.

drivers can use it to abort long running operations in doRetrieve before completion

Definition at line 212 of file Driver.h.

◆ m_options

SH::MetaObject EL::Driver::m_options
privateinherited

members directly corresponding to accessors

Definition at line 233 of file Driver.h.


The documentation for this class was generated from the following files: