ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4MPIbatch.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4MPIbatch.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
27 
28 #include "mpi.h"
29 #include <vector>
30 #include "G4UIcommandStatus.hh"
31 #include "G4UImanager.hh"
32 #include "G4MPIbatch.hh"
33 #include "G4MPImanager.hh"
34 
35 // --------------------------------------------------------------------------
36 namespace {
37 
38 void Tokenize(const G4String& str, std::vector<G4String>& tokens)
39 {
40  const char* delimiter = " ";
41 
42  str_size pos0 = str.find_first_not_of(delimiter);
43  str_size pos = str.find_first_of(delimiter, pos0);
44 
45  while (pos != G4String::npos || pos0 != G4String::npos) {
46  if (str[pos0] == '\"') {
47  pos = str.find_first_of("\"", pos0+1);
48  if(pos != G4String::npos) pos++;
49  }
50  if (str[pos0] == '\'') {
51  pos = str.find_first_of("\'", pos0+1);
52  if(pos != G4String::npos) pos++;
53  }
54 
55  tokens.push_back(str.substr(pos0, pos-pos0));
56  pos0 = str.find_first_not_of(delimiter, pos);
57  pos = str.find_first_of(delimiter, pos0);
58  }
59 }
60 
61 } // end of namespace
62 
63 // --------------------------------------------------------------------------
65  : G4VMPIsession(), is_opened_(false), is_batch_mode_(qbatch)
66 {
67  if( is_master_ ) {
68  batch_stream_.open(fname, std::ios::in);
69  if(batch_stream_.fail()) {
70  G4cerr << "cannot open a macro file(" << fname << ")."
71  << G4endl;
72  } else {
73  is_opened_ = true;
74  }
75  }
76 }
77 
78 // --------------------------------------------------------------------------
80 {
81  if( is_opened_ ) batch_stream_.close();
82 }
83 
84 // --------------------------------------------------------------------------
86 {
87  enum { BUFSIZE = 4096 };
88  static char linebuf[BUFSIZE];
89 
90  G4String cmdtotal = "";
91  G4bool qcontinued = false;
92  while( batch_stream_.good() ) {
93  batch_stream_.getline(linebuf, BUFSIZE);
94 
95  G4String cmdline(linebuf);
96 
97  // TAB-> ' ' conversion
98  str_size nb = 0;
99  while ((nb= cmdline.find('\t',nb)) != G4String::npos) {
100  cmdline.replace(nb, 1, " ");
101  }
102 
103  // strip
104  cmdline = cmdline.strip(G4String::both);
105 
106  // skip null line if single line
107  if( !qcontinued && cmdline.size() == 0 ) continue;
108 
109  // '#' is treated as echoing something
110  if( cmdline(0) == '#' ) return cmdline;
111 
112  // tokenize...
113  std::vector<G4String> tokens;
114  Tokenize(cmdline, tokens);
115  qcontinued = false;
116  for( G4int i = 0; i < G4int(tokens.size()); i++ ) {
117  // string after '#" is ignored
118  if( tokens[i](0) == '#' ) break;
119  // '\' or '_' is treated as continued line.
120  if( tokens[i] == '\\' || tokens[i] == '_' ) {
121  qcontinued = true;
122  // check nothing after line continuation character
123  if( i != G4int(tokens.size())-1 ) {
124  G4Exception("G4MPIbatch::ReadCommand", "MPI004", JustWarning,
125  "unexpected character after line continuation character");
126  }
127  break; // stop parsing
128  }
129  cmdtotal += tokens[i];
130  cmdtotal += " ";
131  }
132 
133  if( qcontinued ) continue; // read the next line
134 
135  if( cmdtotal.size() != 0 ) break;
136  if( batch_stream_.eof() ) break;
137  }
138 
139  // strip again
140  cmdtotal = cmdtotal.strip(G4String::both);
141 
142  // bypass some commands
143  cmdtotal = BypassCommand(cmdtotal);
144 
145  // finally,
146  if( batch_stream_.eof() && cmdtotal.size()==0 ) {
147  return "exit";
148  }
149 
150  return cmdtotal;
151 }
152 
153 // --------------------------------------------------------------------------
155 {
156  if( is_master_ && !is_opened_ ) { // macro file is not found
157  g4mpi_-> BcastCommand("exit");
158  return NULL;
159  }
160 
161  G4String newCommand = "", scommand; // newCommand is always "" in slaves
162 
163  while(1) {
164  if( is_master_ ) newCommand = ReadCommand();
165  // broadcast a new G4 command
166  scommand = g4mpi_-> BcastCommand(newCommand);
167  if( scommand == "exit" ) {
168  g4mpi_-> WaitBeamOn();
169  return 0;
170  }
171 
172  // just echo something
173  if( scommand(0) == '#' ) {
174  if( G4UImanager::GetUIpointer()-> GetVerboseLevel() == 2 ) {
175  G4cout << scommand << G4endl;
176  }
177  continue;
178  }
179 
180  G4int rc = ExecCommand(scommand);
181  if ( rc != fCommandSucceeded ) {
182  G4cerr << G4endl << "***** Batch is interupted!! *****" << G4endl;
183  break;
184  }
185  }
186 
187  return NULL;
188 }