ATLAS Offline Software
Loading...
Searching...
No Matches
LocalDriver.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7
8//
9// includes
10//
11
13
14#include <sstream>
15#include <TSystem.h>
17#include <EventLoop/Job.h>
22#include <mutex>
23#include <thread>
24
25//
26// method implementations
27//
28
30
31namespace EL
32{
33 void LocalDriver ::
34 testInvariant () const
35 {
36 RCU_INVARIANT (this != 0);
37 }
38
39
40
41 LocalDriver ::
42 LocalDriver ()
43 {
44 RCU_NEW_INVARIANT (this);
45 }
46
47
48
49 ::StatusCode LocalDriver ::
50 doManagerStep (Detail::ManagerData& data) const
51 {
52 RCU_READ_INVARIANT (this);
53 using namespace msgEventLoop;
55 switch (data.step)
56 {
58 {
59 data.batchSkipReleaseSetup = true;
60 }
61 break;
62
65 {
66 // safely ignoring: resubmit
67
68 const std::string dockerImage {
69 data.options.castString(Job::optDockerImage)};
70 const std::string dockerOptions {
71 data.options.castString(Job::optDockerOptions)};
72 int numParallelProcs
73 = data.options.castDouble (Job::optNumParallelProcs, 1);
74 if (numParallelProcs < 0)
75 {
76 ANA_MSG_ERROR ("invalid number of parallel processes: " << numParallelProcs);
77 return StatusCode::FAILURE;
78 }
79
80 std::ostringstream basedirName;
81 basedirName << data.submitDir << "/tmp";
82 if (!data.resubmit)
83 {
84 if (gSystem->MakeDirectory (basedirName.str().c_str()) != 0)
85 {
86 ANA_MSG_ERROR ("failed to create directory " << basedirName.str());
87 return StatusCode::FAILURE;
88 }
89 }
90 auto submitSingle = [&] (std::size_t index) noexcept -> StatusCode
91 {
92 try
93 {
94 std::ostringstream dirName;
95 dirName << basedirName.str() << "/" << index;
96 if (gSystem->MakeDirectory (dirName.str().c_str()) != 0)
97 {
98 ANA_MSG_ERROR ("failed to create directory " + dirName.str());
99 return StatusCode::FAILURE;
100 }
101
102 std::ostringstream cmd;
103 cmd << "cd " << dirName.str() << " && ";
104 if (!dockerImage.empty())
105 cmd << "docker run --rm -v " << RCU::Shell::quote (data.submitDir) << ":" << RCU::Shell::quote (data.submitDir) << " " << dockerOptions << " " << dockerImage << " ";
106 cmd << RCU::Shell::quote (data.submitDir) << "/submit/run " << index;
107 RCU::Shell::exec (cmd.str());
108 } catch (std::exception& e)
109 {
110 ANA_MSG_ERROR ("exception in job " << index << ": " << e.what());
111 return StatusCode::FAILURE;
112 }
113 return StatusCode::SUCCESS;
114 };
115 if (numParallelProcs == 1)
116 {
117 for (std::size_t index : data.batchJobIndices)
118 {
119 if (submitSingle (index).isFailure())
120 return StatusCode::FAILURE;
121 }
122 } else
123 {
124 if (numParallelProcs == 0)
125 numParallelProcs = std::thread::hardware_concurrency();
126 if (numParallelProcs > int (data.batchJobIndices.size()))
127 numParallelProcs = data.batchJobIndices.size();
128 std::vector<std::thread> threads;
129 std::mutex mutex;
130 auto indexIter = data.batchJobIndices.begin();
131 bool abort = false;
132 while (threads.size() < unsigned (numParallelProcs))
133 {
134 threads.emplace_back ([&] () noexcept
135 {
136 std::unique_lock<std::mutex> lock (mutex);
137 while (indexIter != data.batchJobIndices.end() && !abort)
138 {
139 auto myindex = *indexIter;
140 ++ indexIter;
141 lock.unlock();
142 if (submitSingle (myindex).isFailure())
143 {
144 abort = true;
145 return;
146 }
147 lock.lock ();
148 }
149 });
150 }
151 for (auto& thread : threads)
152 thread.join();
153 if (abort)
154 return StatusCode::FAILURE;
155 }
156 data.submitted = true;
157 }
158 break;
159
160 default:
161 break;
162 }
163 return ::StatusCode::SUCCESS;
164 }
165}
#define RCU_INVARIANT(x)
Definition Assert.h:189
#define RCU_NEW_INVARIANT(x)
Definition Assert.h:221
#define RCU_READ_INVARIANT(x)
Definition Assert.h:217
#define ANA_MSG_ERROR(xmsg)
Macro printing error messages.
#define ANA_CHECK(EXP)
check whether the given expression was successful
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
ClassImp(EL::LocalDriver) namespace EL
virtual::StatusCode doManagerStep(Detail::ManagerData &data) const override
static const std::string optDockerOptions
any extra options we may want to pass to docker
Definition Job.h:523
static const std::string optNumParallelProcs
the option to specify the number of parallel jobs in LocalDriver (0 = number of hardware cores) (defa...
Definition Job.h:431
static const std::string optDockerImage
this is the name of the docker image, when using docker with a supported batch driver
Definition Job.h:520
a Driver for running batch jobs locally for testing purposes
Definition LocalDriver.h:26
STL class.
@ doResubmit
call the actual doResubmit method
@ submitJob
do the actual job submission
Definition ManagerStep.h:92
@ batchScriptVar
create the variables needed for the batch-run script
Definition ManagerStep.h:83
This module defines the arguments passed from the BATCH driver to the BATCH worker.
::StatusCode StatusCode
StatusCode definition for legacy code.
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
std::string quote(const std::string &name)
effects: quote the given name to protect it from the shell returns: the quoted name guarantee: strong...
Definition ShellExec.cxx:65
Definition index.py:1