KaliVeda
Toolkit for HIC analysis
KVBatchSystem.cpp
1 /*
2 $Id: KVBatchSystem.cpp,v 1.12 2008/04/14 08:49:11 franklan Exp $
3 $Revision: 1.12 $
4 $Date: 2008/04/14 08:49:11 $
5 */
6 
7 //Created by KVClassFactory on Thu Apr 13 13:07:59 2006
8 //Author: John Frankland
9 
10 #include "KVBatchSystem.h"
11 #include "KVBase.h"
12 #include "TEnv.h"
13 #include "TPluginManager.h"
14 #include "TSystem.h"
15 #include "KVDataAnalyser.h"
16 #include "KVDataAnalysisTask.h"
17 
18 using namespace std;
19 
21 
22 KVBatchSystem* gBatchSystem = 0;
23 
24 
35 
37  : KVBase(name), fAnalyser(nullptr)
38 {
39  // Constructor with name of batch system. Name will be used to retrieve
40  // resources from configuration file, e.g. batch system title, job submission
41  // command, name of batch script, default job options, runs per job in multijob mode:
42  //
43  // [batch system name].BatchSystem.Title:
44  // [batch system name].BatchSystem.JobSubCmd:
45  // [batch system name].BatchSystem.JobScript:
46  // [batch system name].BatchSystem.DefaultJobOptions:
47 
48  //set title of batch system
49  SetTitle(gEnv->GetValue(Form("%s.BatchSystem.Title", name), ""));
50  //command for job submission
51  fJobSubCmd = gEnv->GetValue(Form("%s.BatchSystem.JobSubCmd", name), "");
52  //check command is valid
54  Warning("KVBatchSystem", "Batch system %s has unknown job submission command: %s",
55  name, fJobSubCmd.Data());
56  }
57  //script for batch job
58  SetJobScript(gEnv->GetValue(Form("%s.BatchSystem.JobScript", name), ""));
59  //set default job options
60  SetDefaultJobOptions(gEnv->GetValue(Form("%s.BatchSystem.DefaultJobOptions", name), ""));
61 }
62 
63 
64 
67 
68 KVBatchSystem::~KVBatchSystem()
69 {
70  //Destructor
71  if (gBatchSystem == this)
72  gBatchSystem = 0;
73 }
74 
75 
76 
105 
107 {
108  //Builds and returns static string containing full command line necessary to submit a batch
109  //job. This is constructed as follows:
110  //
111  // [JobSubCmd] [default options] [par1 val1] [par2 val2] ... [JobScript]
112  //
113  //The 'default options' can be set with SetDefaultJobOptions().
114  //
115  //The 'par1,val1' pairs are the named parameters held in the fParList KVParameterList.
116  //For each parameter in the list, the name of the parameter is used for 'par1' and the value
117  //of the parameter is used for 'val1' etc. etc.
118  //e.g. if the job submission command requires an option to be passed with the following
119  //syntax
120  // [JobSubCmd] -Noption
121  //one of the parameters in the list should be called "-N" and its value should be 'option'
122  //
123  //In order to add a simple flag such as
124  // [JobSubCmd] -V
125  //add a parameter called "-V" with value "".
126  //
127  //The special variable #JobName# can be used anywhere and will be replaced by the
128  //jobname returned by GetJobName() at the moment of job submission.
129  //
130  //The special variable #tmpDIR# can be used anywhere and will be replaced by the
131  //full path to the system temporary directory at the moment of job submission.
132  //
133  //The special variable #launchDIR# can be used anywhere and will be replaced by the
134  //full path to the working directory at the moment of job submission.
135 
136  static TString command_line;
137  command_line.Form("%s %s ", fJobSubCmd.Data(), fDefOpt.Data());
138  if (fParList.GetNpar()) {
139  for (int i = 0; i < fParList.GetNpar(); i++) {
141  command_line += par->GetName();
142  if (par->GetTString() != "") {
143  command_line += par->GetString();
144  }
145  command_line += " ";
146  }
147  }
148  command_line += fJobScript;
149  //replace #JobName# with name of current job
150  command_line.ReplaceAll("#JobName#", GetJobName());
151  //replace #tmpDIR# with temporary directory path
152  command_line.ReplaceAll("#tmpDIR#", gSystem->TempDirectory());
153  //replace #launchDIR# with working directory (job submission directory) path
154  command_line.ReplaceAll("#launchDIR#", gSystem->WorkingDirectory());
155  return command_line.Data();
156 }
157 
158 
159 
160 
164 
166 {
167  //Clear previously set parameters in order to create a new job submission command
168  //(default options are not affected: use SetDefaultJobOptions to change them)
169 
170  fJobName = "";
171  fParList.Clear();
172  fAnalyser = nullptr;
173 }
174 
175 
176 
177 
180 
182 {
183  //Make this the default batch system
184  gBatchSystem = this;
185 }
186 
187 
188 
189 
196 
198 {
199  //Submits a job to batch system, i.e. executes the string formed by GetJobSubCmdLine,
200  //if all necessary parameters have been given (any missing ones will be asked for).
201  //Parameters specific to a given batch system can be added my modifying the
202  //CheckJobParameters() method for the associated child class.
203 
204  //set environment variables required by KaliVedaAnalysis batch executable
205  gSystem->Setenv("KVBATCHNAME", GetJobName());
206  gSystem->Setenv("KVLAUNCHDIR", gSystem->WorkingDirectory());
207  cout << GetJobSubCmdLine() << endl;
208  if (fAnalyser) {
210  gSystem->Setenv("KVANALYSER", fAnalyser->ClassName());
211  }
213 }
214 
215 
216 
217 
222 
224 {
225  //Processes the job requests for the batch system.
226  //In normal mode, this submits one job for the data analyser fAnalyser
227  //In multijobs mode, this submits one job for each run in the runlist associated to fAnalyser
228 
229  if (!CheckJobParameters()) return;
230 
231  SubmitJob();
232 }
233 
234 
235 
236 
242 
244 {
245  // Create batch system object defined as a plugin in .kvrootrc
246  // If no plugin is found, we create a new KVBatchSystem base object which
247  // will be initialised from resources defined in .kvrootrc using its name.
248 
249  //check and load plugin library
250  TPluginHandler* ph = KVBase::LoadPlugin("KVBatchSystem", plugin);
251  if (!ph)
252  return new KVBatchSystem(plugin);
253 
254  //execute constructor/macro for multidetector
255  return ((KVBatchSystem*) ph->ExecPlugin(1, plugin));
256 }
257 
258 
259 
260 
266 
268 {
269  // Submit data analysis task described by KVDataAnalyser object to the batch system.
270  //
271  // Note that the default options for this batch system may be changed just before
272  // job submission depending on the current environment, see ChangeDefJobOpt().
273 
274  Info("SubmitTask", "Task submission for analyser class : %s", da->ClassName());
275  SetAnalyser(da);
276  //change job submission options depending on task, environment, etc.
277  ChangeDefJobOpt(da);
278  Run();
279 }
280 
281 
282 
283 
296 
298 {
299  // PRIVATE method called by SubmitTask() at moment of job submission.
300  // Depending on the current environment, the default job submission options
301  // may be changed by this method.
302  // For example, default options may be changed depending on the analysis
303  // task to be performed. We look for an environment variable of the form:
304  //
305  // [batch system name].BatchSystem.DefaultJobOptions.[analysis task name]
306  //
307  // and if found we use the options defined by it. If not, we use the default
308  // job options defined by
309  // [batch system name].BatchSystem.DefaultJobOptions
310 
311  TString tmp = gEnv->GetValue(Form("%s.BatchSystem.DefaultJobOptions.%s",
312  GetName(), da->GetAnalysisTask()->GetName()), "");
313  if (tmp.Length()) {
314  Info("ChangeDefJobOpt", "Changing default batch options for task %s.", da->GetAnalysisTask()->GetName());
315  Info("ChangeDefJobOpt", "Batch job options for this job are : %s", tmp.Data());
316  SetDefaultJobOptions(tmp.Data());
317  }
318  else {
319  tmp = gEnv->GetValue(Form("%s.BatchSystem.DefaultJobOptions", GetName()), "");
320  SetDefaultJobOptions(tmp.Data());
321  }
322 }
323 
324 
325 
326 
338 
340 {
341  //Returns name of batch job, either during submission of batch jobs or when an analysis
342  //task is running in batch mode (access through gBatchSystem global pointer).
343  //
344  //In multi-job mode, the job name is generated from the base name set by SetJobName()
345  //plus the extension "_Rxxxx-yyyy" with "xxxx" and "yyyy" the number of the first and last run
346  //which will be analysed by the current job.
347  //
348  // Depending on the batch system, some sanitization of the jobname may be required
349  // e.g. to remove "illegal" characters from the jobname. This is done by SanitizeJobName()
350  // before the jobname is returned.
351 
352  if (!fAnalyser) {
353  //stand-alone batch submission ?
355  }
356  else {
357  //replace any special symbols with their current values
359  if (MultiJobsMode() && !fAnalyser->BatchMode()) {
360  KVString tmp;
361  if (fCurrJobRunList.GetNValues() > 1)
362  tmp.Form("_R%s-%s", fCurrJobRunList.First().as_string().Data(),
363  fCurrJobRunList.Last().as_string().Data());
364  else
365  tmp.Form("_R%s", fCurrJobRunList.First().as_string().Data());
366  fCurrJobName += tmp;
367  }
368  }
369  SanitizeJobName();
370  return fCurrJobName.Data();
371 }
372 
373 
374 
375 
378 
380 {
381  // Checks the job and ask for the job name if needed
382  KVString jobName = fJobName;
383  while (!jobName.Length()) {
384  cout << "Please enter the job name : ";
385  cout.flush();
386  jobName.ReadToDelim(cin);
387  if (jobName.Length()) {
388  SetJobName(jobName.Data());
389  }
390  }
391  return kTRUE;
392 }
393 
394 
395 
396 
400 
402 {
403  //Store any useful information on batch system in the TEnv
404  //(this method is used by KVDataAnalyser::WriteBatchEnvFile)
405  env->SetValue("BatchSystem.JobName", GetJobName());
406 }
407 
408 
409 
410 
414 
416 {
417  //Read any useful information on batch system from the TEnv
418  //(this method is used by KVDataAnalyser::ReadBatchEnvFile)
419  fJobName = env->GetValue("BatchSystem.JobName", "");
420 }
421 
422 
423 
424 
428 
429 void KVBatchSystem::Print(Option_t* option) const
430 {
431  //if option="log", print infos for batch log file
432  //if option="all", print detailed info on batch system
433  if (!strcmp(option, "log")) {
434  cout << "Job " << GetJobName()
435  << " executed by batch system " << GetName() << endl;
436  }
437  else if (!strcmp(option, "all")) {
438  cout << ClassName() << " : Name = " << GetName() << endl << " Title = " << GetTitle() << endl;
439  cout << " fJobSubCmd = " << fJobSubCmd.Data() << endl;
440  cout << " fJobScript = " << fJobScript.Data() << endl;
441  cout << " fDefOpt = " << fDefOpt.Data() << endl;
442  fParList.Print(); //list of parameters/switches to be passed on job submission command line
443  }
444  else
446 }
447 
448 
449 
456 
458 {
459  // Create and fill list with KVBatchJob objects, one for each job currently
460  // handled by the batch system.
461  //
462  // Needs to be implemented for specific systems in child classes.
463  // This method returns 0x0.
464  return 0x0;
465 }
466 
467 
468 
477 
479 {
480  // Fill the list with all relevant parameters for batch system,
481  // set to their default values.
482  //
483  // Parameters defined here are:
484  // JobName [string]
485  // AutoJobName [bool]
486  // AutoJobNameFormat [string]
487 
488  nl.Clear();
489  nl.SetTitle(GetTitle());
490  nl.SetValue("JobName", "");
491  nl.SetValue("AutoJobName", kTRUE);
492  nl.SetValue("AutoJobNameFormat", "$UserClass");
493 }
494 
495 
496 
499 
501 {
502  // Use the parameters in the list to set all relevant parameters for batch system.
503 
504  if (nl.GetBoolValue("AutoJobName"))
505  SetJobName(nl.GetStringValue("AutoJobNameFormat"));
506  else
507  SetJobName(nl.GetStringValue("JobName"));
508  Info("SetBatchSystemParameters", "JobName = %s", GetJobName());
509 }
510 
511 
512 
513 
521 
523 {
524  //Set the job name. In MultiJobsMode this will be used as the base name for all jobs;
525  //each individual job will have the name 'basejobname_Rxxxx", with xxxx=run number for job.
526  //
527  //The job name can be generated automatically by replacing certain special symbols
528  //in the name given here depending on the characteristics of the job. See
529  //KVDataAnalyser::ExpandAutoBatchName for allowed symbols.
530  fJobName = name;
531 }
532 
533 
bool Bool_t
char Char_t
constexpr Bool_t kTRUE
const char Option_t
R__EXTERN TEnv * gEnv
Option_t Option_t option
char name[80]
char * Form(const char *fmt,...)
R__EXTERN TSystem * gSystem
Base class for KaliVeda framework.
Definition: KVBase.h:139
static Bool_t FindExecutable(TString &exec, const Char_t *path="$(PATH)")
Definition: KVBase.cpp:971
void Print(Option_t *option="") const override
Definition: KVBase.cpp:389
static TPluginHandler * LoadPlugin(const Char_t *base, const Char_t *uri="0")
Definition: KVBase.cpp:772
Base class for interface to a batch job management system.
Definition: KVBatchSystem.h:78
virtual void SubmitTask(KVDataAnalyser *da)
KVString fJobSubCmd
shell command for submitting job
Definition: KVBatchSystem.h:85
virtual void WriteBatchEnvFile(TEnv *)
KVString fJobName
base job name
Definition: KVBatchSystem.h:84
void Clear(Option_t *opt="") override
virtual const Char_t * GetJobSubCmdLine()
virtual void SetJobName(const Char_t *name)
virtual void SetDefaultJobOptions(const Char_t *opt)
virtual Bool_t MultiJobsMode() const
void cd()
Make this the default batch system.
virtual void SubmitJob()
KVString fJobScript
full path of shell script to be executed by batch system
Definition: KVBatchSystem.h:86
KVBatchSystem(const Char_t *name)
virtual const Char_t * GetJobName() const
virtual void Run()
virtual void SanitizeJobName() const
KVNameValueList fParList
list of parameters/switches to be passed on job submission command line
Definition: KVBatchSystem.h:83
virtual KVList * GetListOfJobs()
virtual void ChangeDefJobOpt(KVDataAnalyser *da)
virtual void SetAnalyser(KVDataAnalyser *da)
static KVBatchSystem * GetBatchSystem(const Char_t *plugin)
virtual void ReadBatchEnvFile(TEnv *)
KVString fDefOpt
default options for job submission command
Definition: KVBatchSystem.h:87
virtual void SetBatchSystemParameters(const KVNameValueList &)
Use the parameters in the list to set all relevant parameters for batch system.
run_index_list fCurrJobRunList
runlist for (multi job mode) job being submitted
Definition: KVBatchSystem.h:89
KVDataAnalyser * fAnalyser
the analyser object which requests job submission, it has all details on the job
Definition: KVBatchSystem.h:82
virtual void SetJobScript(const Char_t *path)
KVString fCurrJobName
name of current job being submitted
Definition: KVBatchSystem.h:88
void Print(Option_t *="") const override
virtual void GetBatchSystemParameterList(KVNameValueList &)
virtual Bool_t CheckJobParameters()
Checks the job and ask for the job name if needed.
Manager class which sets up and runs data analysis tasks.
virtual TString ExpandAutoBatchName(const Char_t *format) const
virtual void WriteBatchEnvFile(const TString &, Bool_t sav=kTRUE)
KVDataAnalysisTask * GetAnalysisTask() const
Bool_t BatchMode() const
Extended TList class which owns its objects by default.
Definition: KVList.h:28
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
KVNamedParameter * GetParameter(Int_t idx) const
return the parameter object with index idx
void SetValue(const Char_t *name, value_type value)
Int_t GetNpar() const
return the number of stored parameters
void Clear(Option_t *opt="") override
Bool_t GetBoolValue(const Char_t *name) const
const Char_t * GetStringValue(const Char_t *name) const
void Print(Option_t *opt="") const override
A generic named parameter storing values of different types.
const Char_t * GetString() const
TString GetTString() const
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:73
virtual const char * GetValue(const char *name, const char *dflt) const
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=nullptr)
virtual void SetTitle(const char *title="")
const char * GetName() const override
const char * GetTitle() const override
virtual const char * ClassName() const
virtual void Warning(const char *method, const char *msgfmt,...) const
virtual void Info(const char *method, const char *msgfmt,...) const
Longptr_t ExecPlugin(int nargs)
Ssiz_t Length() const
std::istream & ReadToDelim(std::istream &str, char delim='\n')
const char * Data() const
void Form(const char *fmt,...)
TString & ReplaceAll(const char *s1, const char *s2)
virtual Int_t Exec(const char *shellcmd)
virtual const char * WorkingDirectory()
virtual void Setenv(const char *name, const char *value)
virtual const char * TempDirectory() const
ClassImp(TPyArg)