KaliVeda  1.13/01
Heavy-Ion Analysis Toolkit
KVBatchSystem.cpp
Go to the documentation of this file.
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 
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
53  if (!KVBase::FindExecutable(fJobSubCmd)) {
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++) {
140  KVNamedParameter* par = fParList.GetParameter(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) {
209  fAnalyser->WriteBatchEnvFile(GetJobName());
210  gSystem->Setenv("KVANALYSER", fAnalyser->ClassName());
211  }
212  gSystem->Exec(GetJobSubCmdLine());
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 ?
354  fCurrJobName = fJobName;
355  }
356  else {
357  //replace any special symbols with their current values
358  fCurrJobName = fAnalyser->ExpandAutoBatchName(fJobName.Data());
359  if (MultiJobsMode() && !fAnalyser->BatchMode()) {
360  KVString tmp;
361  if (fCurrJobRunList.GetNValues() > 1)
362  tmp.Form("_R%d-%d", fCurrJobRunList.First(), fCurrJobRunList.Last());
363  else
364  tmp.Form("_R%d", fCurrJobRunList.First());
365  fCurrJobName += tmp;
366  }
367  }
368  SanitizeJobName();
369  return fCurrJobName.Data();
370 }
371 
372 
373 
374 
377 
379 {
380  // Checks the job and ask for the job name if needed
381  KVString jobName = fJobName;
382  while (!jobName.Length()) {
383  cout << "Please enter the job name : ";
384  cout.flush();
385  jobName.ReadToDelim(cin);
386  if (jobName.Length()) {
387  SetJobName(jobName.Data());
388  }
389  }
390  return kTRUE;
391 }
392 
393 
394 
395 
399 
401 {
402  //Store any useful information on batch system in the TEnv
403  //(this method is used by KVDataAnalyser::WriteBatchEnvFile)
404  env->SetValue("BatchSystem.JobName", GetJobName());
405 }
406 
407 
408 
409 
413 
415 {
416  //Read any useful information on batch system from the TEnv
417  //(this method is used by KVDataAnalyser::ReadBatchEnvFile)
418  fJobName = env->GetValue("BatchSystem.JobName", "");
419 }
420 
421 
422 
423 
427 
428 void KVBatchSystem::Print(Option_t* option) const
429 {
430  //if option="log", print infos for batch log file
431  //if option="all", print detailed info on batch system
432  if (!strcmp(option, "log")) {
433  cout << "Job " << GetJobName()
434  << " executed by batch system " << GetName() << endl;
435  }
436  else if (!strcmp(option, "all")) {
437  cout << ClassName() << " : Name = " << GetName() << endl << " Title = " << GetTitle() << endl;
438  cout << " fJobSubCmd = " << fJobSubCmd.Data() << endl;
439  cout << " fJobScript = " << fJobScript.Data() << endl;
440  cout << " fDefOpt = " << fDefOpt.Data() << endl;
441  fParList.Print(); //list of parameters/switches to be passed on job submission command line
442  }
443  else
444  KVBase::Print(option);
445 }
446 
447 
448 
455 
457 {
458  // Create and fill list with KVBatchJob objects, one for each job currently
459  // handled by the batch system.
460  //
461  // Needs to be implemented for specific systems in child classes.
462  // This method returns 0x0.
463  return 0x0;
464 }
465 
466 
467 
476 
478 {
479  // Fill the list with all relevant parameters for batch system,
480  // set to their default values.
481  //
482  // Parameters defined here are:
483  // JobName [string]
484  // AutoJobName [bool]
485  // AutoJobNameFormat [string]
486 
487  nl.Clear();
488  nl.SetTitle(GetTitle());
489  nl.SetValue("JobName", "");
490  nl.SetValue("AutoJobName", kTRUE);
491  nl.SetValue("AutoJobNameFormat", "$UserClass");
492 }
493 
494 
495 
498 
500 {
501  // Use the parameters in the list to set all relevant parameters for batch system.
502 
503  if (nl.GetBoolValue("AutoJobName"))
504  SetJobName(nl.GetStringValue("AutoJobNameFormat"));
505  else
506  SetJobName(nl.GetStringValue("JobName"));
507  Info("SetBatchSystemParameters", "JobName = %s", GetJobName());
508 }
509 
510 
511 
512 
520 
522 {
523  //Set the job name. In MultiJobsMode this will be used as the base name for all jobs;
524  //each individual job will have the name 'basejobname_Rxxxx", with xxxx=run number for job.
525  //
526  //The job name can be generated automatically by replacing certain special symbols
527  //in the name given here depending on the characteristics of the job. See
528  //KVDataAnalyser::ExpandAutoBatchName for allowed symbols.
529  fJobName = name;
530 }
531 
532 
KVBatchSystem * gBatchSystem
ClassImp(KVPartitionList) void KVPartitionList
Initialisation.
char Char_t
bool Bool_t
const Bool_t kTRUE
const char Option_t
R__EXTERN TEnv * gEnv
char * Form(const char *fmt,...)
R__EXTERN TSystem * gSystem
Base class for KaliVeda framework.
Definition: KVBase.h:141
static Bool_t FindExecutable(TString &exec, const Char_t *path="$(PATH)")
Definition: KVBase.cpp:1001
virtual void Print(Option_t *option="") const
Definition: KVBase.cpp:410
static TPluginHandler * LoadPlugin(const Char_t *base, const Char_t *uri="0")
Definition: KVBase.cpp:793
Base class for interface to a batch job management system.
Definition: KVBatchSystem.h:77
virtual void SubmitTask(KVDataAnalyser *da)
virtual void WriteBatchEnvFile(TEnv *)
virtual const Char_t * GetJobSubCmdLine()
virtual void SetJobName(const Char_t *name)
void cd()
Make this the default batch system.
virtual void SubmitJob()
virtual const Char_t * GetJobName() const
virtual void Run()
virtual KVList * GetListOfJobs()
virtual void Print(Option_t *="") const
virtual void ChangeDefJobOpt(KVDataAnalyser *da)
static KVBatchSystem * GetBatchSystem(const Char_t *plugin)
virtual void ReadBatchEnvFile(TEnv *)
virtual void SetBatchSystemParameters(const KVNameValueList &)
Use the parameters in the list to set all relevant parameters for batch system.
virtual void GetBatchSystemParameterList(KVNameValueList &)
virtual void Clear(Option_t *opt="")
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.
KVDataAnalysisTask * GetAnalysisTask() const
Extended TList class which owns its objects by default.
Definition: KVList.h:27
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
void SetValue(const Char_t *name, value_type value)
virtual void Clear(Option_t *opt="")
Bool_t GetBoolValue(const Char_t *name) const
const Char_t * GetStringValue(const Char_t *name) const
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:72
void Print(const char *="") const
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 const char * GetName() const
virtual void SetTitle(const char *title="")
virtual const char * ClassName() const
Longptr_t ExecPlugin(int nargs, const T &... params)
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
RooCmdArg ClassName(const char *name)
void Info(const char *location, const char *va_(fmt),...)
void Warning(const char *location, const char *va_(fmt),...)