Import Geant4 9.6.0 source tree
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
/// @file G4MPIbatch.cc
|
||||
/// @brief MPI batch session
|
||||
|
||||
#include "G4MPIbatch.hh"
|
||||
#include "G4MPImanager.hh"
|
||||
#include "G4UImanager.hh"
|
||||
#include "G4UIcommandStatus.hh"
|
||||
#include <vector>
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
static void Tokenize(const G4String& str, std::vector<G4String>& tokens)
|
||||
{
|
||||
const char* delimiter = " ";
|
||||
|
||||
str_size pos0 = str.find_first_not_of(delimiter);
|
||||
str_size pos = str.find_first_of(delimiter, pos0);
|
||||
|
||||
while (pos != G4String::npos || pos0 != G4String::npos) {
|
||||
if (str[pos0] == '\"') {
|
||||
pos = str.find_first_of("\"", pos0+1);
|
||||
if(pos != G4String::npos) pos++;
|
||||
}
|
||||
if (str[pos0] == '\'') {
|
||||
pos = str.find_first_of("\'", pos0+1);
|
||||
if(pos != G4String::npos) pos++;
|
||||
}
|
||||
|
||||
tokens.push_back(str.substr(pos0, pos-pos0));
|
||||
pos0 = str.find_first_not_of(delimiter, pos);
|
||||
pos = str.find_first_of(delimiter, pos0);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4MPIbatch::G4MPIbatch(const G4String& fname, G4bool qbatch)
|
||||
: G4VMPIsession(), isOpened(false), isBatchMode(qbatch)
|
||||
{
|
||||
if(isMaster) {
|
||||
batchStream.open(fname, std::ios::in);
|
||||
if(batchStream.fail()) {
|
||||
G4cerr << "cannot open a macro file(" << fname << ")."
|
||||
<< G4endl;
|
||||
} else {
|
||||
isOpened = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4MPIbatch::~G4MPIbatch()
|
||||
{
|
||||
if(isOpened) batchStream.close();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4String G4MPIbatch::ReadCommand()
|
||||
{
|
||||
enum { BUFSIZE = 4096 };
|
||||
static char linebuf[BUFSIZE];
|
||||
|
||||
G4String cmdtotal = "";
|
||||
G4bool qcontinued = false;
|
||||
while(batchStream.good()) {
|
||||
batchStream.getline(linebuf, BUFSIZE);
|
||||
|
||||
G4String cmdline(linebuf);
|
||||
|
||||
// TAB-> ' ' conversion
|
||||
str_size nb = 0;
|
||||
while ((nb= cmdline.find('\t',nb)) != G4String::npos) {
|
||||
cmdline.replace(nb, 1, " ");
|
||||
}
|
||||
|
||||
// strip
|
||||
cmdline = cmdline.strip(G4String::both);
|
||||
|
||||
// skip null line if single line
|
||||
if(!qcontinued && cmdline.size() == 0) continue;
|
||||
|
||||
// '#' is treated as echoing something
|
||||
if(cmdline(0) == '#') return cmdline;
|
||||
|
||||
// tokenize...
|
||||
std::vector<G4String> tokens;
|
||||
Tokenize(cmdline, tokens);
|
||||
qcontinued = false;
|
||||
for (G4int i = 0; i < G4int(tokens.size()); i++) {
|
||||
// string after '#" is ignored
|
||||
if(tokens[i](0) == '#' ) break;
|
||||
// '\' or '_' is treated as continued line.
|
||||
if(tokens[i] == '\\' || tokens[i] == '_' ) {
|
||||
qcontinued = true;
|
||||
// check nothing after line continuation character
|
||||
if( i != G4int(tokens.size())-1) {
|
||||
G4Exception("G4MPIbatch::ReadCommand", "MPI002", JustWarning,
|
||||
"unexpected character after line continuation character");
|
||||
}
|
||||
break; // stop parsing
|
||||
}
|
||||
cmdtotal += tokens[i];
|
||||
cmdtotal += " ";
|
||||
}
|
||||
|
||||
if(qcontinued) continue; // read the next line
|
||||
|
||||
if(cmdtotal.size() != 0) break;
|
||||
if(batchStream.eof()) break;
|
||||
}
|
||||
|
||||
// strip again
|
||||
cmdtotal = cmdtotal.strip(G4String::both);
|
||||
|
||||
// bypass some commands
|
||||
cmdtotal = BypassCommand(cmdtotal);
|
||||
|
||||
// finally,
|
||||
if(batchStream.eof() && cmdtotal.size()==0) {
|
||||
return "exit";
|
||||
}
|
||||
|
||||
return cmdtotal;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4UIsession* G4MPIbatch::SessionStart()
|
||||
{
|
||||
if( isMaster && !isOpened ){ // macro file is not found
|
||||
g4MPI-> BcastCommand("exit");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
G4String newCommand = "", scommand; // newCommand is always "" in slaves
|
||||
|
||||
while(1) {
|
||||
if (isMaster) newCommand = ReadCommand();
|
||||
// broadcast a new G4 command
|
||||
scommand = g4MPI-> BcastCommand(newCommand);
|
||||
if(scommand == "exit") {
|
||||
g4MPI-> WaitBeamOn();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// just echo something
|
||||
if( scommand(0) == '#') {
|
||||
if(G4UImanager::GetUIpointer()-> GetVerboseLevel() == 2) {
|
||||
G4cout << scommand << G4endl;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
G4int rc = ExecCommand(scommand);
|
||||
if (rc != fCommandSucceeded) {
|
||||
G4cerr << G4endl << "***** Batch is interupted!! *****" << G4endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,550 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
/// @file G4MPImanager.cc
|
||||
/// @brief MPI manager class
|
||||
|
||||
#include "G4MPImanager.hh"
|
||||
#include "G4MPImessenger.hh"
|
||||
#include "G4MPIsession.hh"
|
||||
#include "G4MPIbatch.hh"
|
||||
#include "G4MPIstatus.hh"
|
||||
#include "G4MPIrandomSeedGenerator.hh"
|
||||
#include "G4UImanager.hh"
|
||||
#include "G4RunManager.hh"
|
||||
#include "G4StateManager.hh"
|
||||
#include "G4Run.hh"
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <assert.h>
|
||||
|
||||
G4MPImanager* G4MPImanager::theManager = 0;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// wrappers for thread functions
|
||||
static void thread_ExecuteThreadCommand(const G4String* command)
|
||||
{
|
||||
G4MPImanager::GetManager()-> ExecuteThreadCommand(*command);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4MPImanager::G4MPImanager()
|
||||
: verbose(0), qfcout(false), qinitmacro(false), qbatchmode(false),
|
||||
threadID(0), masterWeight(1.)
|
||||
{
|
||||
//MPI::Init();
|
||||
MPI::Init_thread(MPI::THREAD_SERIALIZED);
|
||||
Initialize();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4MPImanager::G4MPImanager(int argc, char** argv)
|
||||
: verbose(0), qfcout(false), qinitmacro(false), qbatchmode(false),
|
||||
threadID(0), masterWeight(1.)
|
||||
{
|
||||
//MPI::Init(argc, argv);
|
||||
MPI::Init_thread(argc, argv, MPI::THREAD_SERIALIZED);
|
||||
Initialize();
|
||||
ParseArguments(argc, argv);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4MPImanager::~G4MPImanager()
|
||||
{
|
||||
if(isSlave && qfcout) fscout.close();
|
||||
|
||||
delete status;
|
||||
delete messenger;
|
||||
delete session;
|
||||
|
||||
COMM_G4COMMAND.Free();
|
||||
|
||||
MPI::Finalize();
|
||||
|
||||
theManager = 0;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4MPImanager* G4MPImanager::GetManager()
|
||||
{
|
||||
assert( theManager != 0 );
|
||||
return theManager;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPImanager::Initialize()
|
||||
{
|
||||
assert( theManager == 0 );
|
||||
|
||||
theManager= this;
|
||||
|
||||
// get rank information
|
||||
size = MPI::COMM_WORLD.Get_size();
|
||||
rank = MPI::COMM_WORLD.Get_rank();
|
||||
isMaster = (rank == RANK_MASTER);
|
||||
isSlave = (rank != RANK_MASTER);
|
||||
|
||||
// initialize MPI communicator
|
||||
COMM_G4COMMAND = MPI::COMM_WORLD.Dup();
|
||||
|
||||
// new G4MPI stuffs
|
||||
messenger = new G4MPImessenger(this);
|
||||
session = new G4MPIsession;
|
||||
status = new G4MPIstatus;
|
||||
|
||||
// default seed generator is random generator.
|
||||
seedGenerator = new G4MPIrandomSeedGenerator;
|
||||
DistributeSeeds();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPImanager::ParseArguments(int argc, char** argv)
|
||||
{
|
||||
G4int qhelp = 0;
|
||||
G4String ofprefix = "mpi";
|
||||
|
||||
G4int c;
|
||||
while (1) {
|
||||
G4int option_index= 0;
|
||||
static struct option long_options[] = {
|
||||
{"help", 0, 0, 0},
|
||||
{"verbose", 0, 0, 0},
|
||||
{"init", 1, 0, 0},
|
||||
{"ofile", 2, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
opterr = 0; // suppress message
|
||||
c= getopt_long(argc, argv, "hvi:o", long_options, &option_index);
|
||||
opterr = 1;
|
||||
|
||||
if(c == -1) break;
|
||||
|
||||
switch (c) {
|
||||
case 0:
|
||||
switch(option_index) {
|
||||
case 0 : // --help
|
||||
qhelp = 1;
|
||||
break;
|
||||
case 1 : // --verbose
|
||||
verbose = 1;
|
||||
break;
|
||||
case 2 : // --init
|
||||
qinitmacro = true;
|
||||
initFileName = optarg;
|
||||
break;
|
||||
case 3 : // --ofile
|
||||
qfcout = true;
|
||||
if(optarg) ofprefix = optarg;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'h' :
|
||||
qhelp = 1;
|
||||
break;
|
||||
case 'v' :
|
||||
verbose = 1;
|
||||
break;
|
||||
case 'i' :
|
||||
qinitmacro = true;
|
||||
initFileName = optarg;
|
||||
break;
|
||||
case 'o' :
|
||||
qfcout = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// show help
|
||||
if(qhelp) {
|
||||
if(isMaster) ShowHelp();
|
||||
MPI::Finalize();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// file output
|
||||
if(isSlave && qfcout) {
|
||||
G4String prefix = ofprefix + ".%03d" + ".cout";
|
||||
char str[1024];
|
||||
sprintf(str, prefix.c_str(), rank);
|
||||
G4String fname(str);
|
||||
fscout.open(fname.c_str(), std::ios::out);
|
||||
}
|
||||
|
||||
// non-option ARGV-elements ...
|
||||
if (optind < argc ) {
|
||||
qbatchmode = true;
|
||||
macroFileName = argv[optind];
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPImanager::Wait(G4int ausec) const
|
||||
{
|
||||
struct timespec treq, trem;
|
||||
treq.tv_sec = 0;
|
||||
treq.tv_nsec = ausec*1000;
|
||||
|
||||
nanosleep(&treq, &trem);
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
void G4MPImanager::UpdateStatus()
|
||||
{
|
||||
G4RunManager* runManager = G4RunManager::GetRunManager();
|
||||
const G4Run* run = runManager-> GetCurrentRun();
|
||||
|
||||
G4int runid, eventid, neventTBP;
|
||||
|
||||
G4StateManager* stateManager = G4StateManager::GetStateManager();
|
||||
G4ApplicationState g4state = stateManager-> GetCurrentState();
|
||||
|
||||
if (run) {
|
||||
runid = run-> GetRunID();
|
||||
neventTBP = run -> GetNumberOfEventToBeProcessed();
|
||||
eventid = run-> GetNumberOfEvent();
|
||||
if(g4state == G4State_GeomClosed || g4state == G4State_EventProc) {
|
||||
status-> StopTimer();
|
||||
}
|
||||
} else {
|
||||
runid = 0;
|
||||
eventid = 0;
|
||||
neventTBP = 0;
|
||||
}
|
||||
|
||||
status-> SetStatus(rank, runid, neventTBP, eventid, g4state);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPImanager::ShowStatus()
|
||||
{
|
||||
G4int buff[G4MPIstatus::NSIZE];
|
||||
|
||||
UpdateStatus();
|
||||
G4bool gstatus = CheckThreadStatus();
|
||||
|
||||
if(isMaster) {
|
||||
status-> Print(); // for maser itself
|
||||
|
||||
G4int nev = status-> GetEventID();
|
||||
G4int nevtp = status-> GetNEventToBeProcessed();
|
||||
G4double cputime = status-> GetCPUTime();
|
||||
|
||||
// receive from each slave
|
||||
for (G4int islave = 1; islave < size; islave++) {
|
||||
COMM_G4COMMAND.Recv(buff, G4MPIstatus::NSIZE, MPI::INT,
|
||||
islave, TAG_G4STATUS);
|
||||
status-> UnPack(buff);
|
||||
status-> Print();
|
||||
|
||||
// aggregation
|
||||
nev += status-> GetEventID();
|
||||
nevtp += status-> GetNEventToBeProcessed();
|
||||
cputime += status-> GetCPUTime();
|
||||
}
|
||||
|
||||
G4String strStatus;
|
||||
if(gstatus) {
|
||||
strStatus = "Run";
|
||||
} else {
|
||||
strStatus = "Idle";
|
||||
}
|
||||
|
||||
G4cout << "-------------------------------------------------------"
|
||||
<< G4endl
|
||||
<< "* #ranks= " << size
|
||||
<< " event= " << nev << "/" << nevtp
|
||||
<< " state= " << strStatus
|
||||
<< " time= " << cputime << "s"
|
||||
<< G4endl;
|
||||
} else {
|
||||
status-> Pack(buff);
|
||||
COMM_G4COMMAND.Send(buff, G4MPIstatus::NSIZE, MPI::INT,
|
||||
RANK_MASTER, TAG_G4STATUS);
|
||||
}
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
void G4MPImanager::DistributeSeeds()
|
||||
{
|
||||
std::vector<G4long> seedList = seedGenerator-> GetSeedList();
|
||||
CLHEP::HepRandom::setTheSeed(seedList[rank]);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPImanager::ShowSeeds()
|
||||
{
|
||||
G4long buff;
|
||||
|
||||
if(isMaster) {
|
||||
// print master
|
||||
G4cout << "* rank= " << rank
|
||||
<< " seed= " << CLHEP::HepRandom::getTheSeed()
|
||||
<< G4endl;
|
||||
// receive from each slave
|
||||
for (G4int islave = 1; islave < size; islave++) {
|
||||
COMM_G4COMMAND.Recv(&buff, 1, MPI::LONG, islave, TAG_G4SEED);
|
||||
G4cout << "* rank= " << islave
|
||||
<< " seed= " << buff
|
||||
<< G4endl;
|
||||
}
|
||||
} else { // slaves
|
||||
buff = CLHEP::HepRandom::getTheSeed();
|
||||
COMM_G4COMMAND.Send(&buff, 1, MPI::LONG, RANK_MASTER, TAG_G4SEED);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPImanager::SetSeed(G4int inode, G4long seed)
|
||||
{
|
||||
if(rank == inode) {
|
||||
CLHEP::HepRandom::setTheSeed(seed);
|
||||
}
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
G4bool G4MPImanager::CheckThreadStatus()
|
||||
{
|
||||
unsigned buff;
|
||||
G4bool qstatus= false;
|
||||
|
||||
if(isMaster) {
|
||||
qstatus = threadID;
|
||||
// get slave status
|
||||
for (G4int islave = 1; islave < size; islave++) {
|
||||
MPI::Request request = COMM_G4COMMAND.Irecv(&buff, 1, MPI::UNSIGNED,
|
||||
islave, TAG_G4STATUS);
|
||||
MPI::Status status;
|
||||
while(! request.Test(status)) {
|
||||
Wait(1000);
|
||||
}
|
||||
qstatus |= buff;
|
||||
}
|
||||
} else {
|
||||
buff = unsigned(threadID);
|
||||
COMM_G4COMMAND.Send(&buff, 1, MPI::UNSIGNED, RANK_MASTER, TAG_G4STATUS);
|
||||
}
|
||||
|
||||
// broadcast
|
||||
buff = qstatus; // for master
|
||||
COMM_G4COMMAND.Bcast(&buff, 1, MPI::UNSIGNED, RANK_MASTER);
|
||||
qstatus = buff; // for slave
|
||||
|
||||
return qstatus;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPImanager::ExecuteThreadCommand(const G4String& command)
|
||||
{
|
||||
// this method is a thread function.
|
||||
G4UImanager* UI = G4UImanager::GetUIpointer();
|
||||
G4int rc = UI-> ApplyCommand(command);
|
||||
|
||||
G4int commandStatus = rc - (rc%100);
|
||||
|
||||
switch(commandStatus) {
|
||||
case fCommandSucceeded:
|
||||
break;
|
||||
case fIllegalApplicationState:
|
||||
G4cerr << "illegal application state -- command refused" << G4endl;
|
||||
break;
|
||||
default:
|
||||
G4cerr << "command refused (" << commandStatus << ")" << G4endl;
|
||||
break;
|
||||
}
|
||||
|
||||
// thread is joined
|
||||
if(threadID) {
|
||||
pthread_join(threadID, 0);
|
||||
threadID = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPImanager::ExecuteBeamOnThread(const G4String& command)
|
||||
{
|
||||
G4bool threadStatus = CheckThreadStatus();
|
||||
|
||||
if (threadStatus) {
|
||||
if(isMaster) {
|
||||
G4cout << "G4MPIsession:: beamOn is still running." << G4endl;
|
||||
}
|
||||
} else { // ok
|
||||
static G4String cmdstr;
|
||||
cmdstr = command;
|
||||
G4int rc = pthread_create(&threadID, 0,
|
||||
(Func_t)thread_ExecuteThreadCommand,
|
||||
(void*)&cmdstr);
|
||||
if (rc != 0)
|
||||
G4Exception("G4MPImanager::ExecuteBeamOnThread()",
|
||||
"MPI001",
|
||||
FatalException,
|
||||
"Failed to create a beamOn thread.");
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPImanager::JoinBeamOnThread()
|
||||
{
|
||||
if(threadID) {
|
||||
pthread_join(threadID, 0);
|
||||
threadID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
G4String G4MPImanager::BcastCommand(const G4String& command)
|
||||
{
|
||||
enum { BUFF_SIZE = 512 };
|
||||
static char sbuff[BUFF_SIZE];
|
||||
command.copy(sbuff,BUFF_SIZE);
|
||||
G4int len = command.size();
|
||||
sbuff[len] ='\0'; // no boundary check
|
||||
|
||||
// "command" is not yet fixed in slaves at this time.
|
||||
|
||||
// waiting message exhausts CPU in LAM!
|
||||
//COMM_G4COMMAND.Bcast(sbuff, ssize, MPI::CHAR, RANK_MASTER);
|
||||
|
||||
// another implementation
|
||||
if( isMaster ) {
|
||||
for (G4int islave = 1; islave < size; islave++) {
|
||||
COMM_G4COMMAND.Send(sbuff, BUFF_SIZE, MPI::CHAR, islave, TAG_G4COMMAND);
|
||||
}
|
||||
} else {
|
||||
// try non-blocking receive
|
||||
MPI::Request request= COMM_G4COMMAND.Irecv(sbuff, BUFF_SIZE, MPI::CHAR,
|
||||
RANK_MASTER, TAG_G4COMMAND);
|
||||
// polling...
|
||||
MPI::Status status;
|
||||
while(! request.Test(status)) {
|
||||
Wait(1000);
|
||||
}
|
||||
}
|
||||
|
||||
return G4String(sbuff);
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
void G4MPImanager::ExecuteMacroFile(const G4String& fname, G4bool qbatch)
|
||||
{
|
||||
G4bool currentmode = qbatchmode;
|
||||
qbatchmode = true;
|
||||
G4MPIbatch* batchSession = new G4MPIbatch(fname, qbatch);
|
||||
batchSession-> SessionStart();
|
||||
delete batchSession;
|
||||
qbatchmode = currentmode;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPImanager::BeamOn(G4int nevent, G4bool qdivide)
|
||||
{
|
||||
G4RunManager* runManager = G4RunManager::GetRunManager();
|
||||
|
||||
if(qdivide) { // events are divided
|
||||
G4double ntot = masterWeight+size-1.;
|
||||
G4int nproc = G4int(nevent/ntot);
|
||||
G4int nproc0 = nevent-nproc*(size-1);
|
||||
|
||||
if(verbose>0 && isMaster) {
|
||||
G4cout << "#events in master=" << nproc0 << " / "
|
||||
<< "#events in slave=" << nproc << G4endl;
|
||||
}
|
||||
|
||||
status-> StartTimer(); // start timer
|
||||
if(isMaster) runManager-> BeamOn(nproc0);
|
||||
else runManager-> BeamOn(nproc);
|
||||
status-> StopTimer(); // stop timer
|
||||
|
||||
} else { // same events are generated in each node (for test use)
|
||||
if(verbose>0 && isMaster) {
|
||||
G4cout << "#events in master=" << nevent << " / "
|
||||
<< "#events in slave=" << nevent << G4endl;
|
||||
}
|
||||
status-> StartTimer(); // start timer
|
||||
runManager-> BeamOn(nevent);
|
||||
status-> StopTimer(); // stop timer
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPImanager::WaitBeamOn()
|
||||
{
|
||||
G4int buff = 0;
|
||||
if (qbatchmode) { // valid only in batch mode
|
||||
if(isMaster) {
|
||||
// receive from each slave
|
||||
for (G4int islave = 1; islave < size; islave++) {
|
||||
MPI::Request request = COMM_G4COMMAND.Irecv(&buff, 1, MPI::INT,
|
||||
islave, TAG_G4STATUS);
|
||||
MPI::Status status;
|
||||
while(! request.Test(status)) {
|
||||
Wait(1000);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
buff = 1;
|
||||
COMM_G4COMMAND.Send(&buff, 1, MPI::INT, RANK_MASTER, TAG_G4STATUS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPImanager::Print(const G4String& message)
|
||||
{
|
||||
if(isMaster){
|
||||
std::cout << message << std::flush;
|
||||
} else {
|
||||
if(qfcout) { // output to a file
|
||||
fscout << message << std::flush;
|
||||
} else { // output to stdout
|
||||
std::cout << rank << ":" << message << std::flush;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPImanager::ShowHelp() const
|
||||
{
|
||||
if(isSlave) return;
|
||||
|
||||
G4cout << "Geant4 MPI interface" << G4endl;
|
||||
G4cout << "usage:" << G4endl;
|
||||
G4cout << "<app> [options] [macro file]"
|
||||
<< G4endl << G4endl;
|
||||
G4cout << " -h, --help show this message."
|
||||
<< G4endl;
|
||||
G4cout << " -v, --verbose show verbose message"
|
||||
<< G4endl;
|
||||
G4cout << " -i, --init=FNAME set an init macro file"
|
||||
<< G4endl;
|
||||
G4cout << " -o, --ofile[=FNAME] set slave output to a flie"
|
||||
<< G4endl;
|
||||
G4cout << G4endl;
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
/// @file G4MPImessenger.cc
|
||||
/// @brief Define MPI commands
|
||||
|
||||
#include "G4MPImessenger.hh"
|
||||
#include "G4MPImanager.hh"
|
||||
#include "G4VMPIseedGenerator.hh"
|
||||
#include "G4UImanager.hh"
|
||||
#include "G4UIdirectory.hh"
|
||||
#include "G4UIcmdWithoutParameter.hh"
|
||||
#include "G4UIcmdWithAnInteger.hh"
|
||||
#include "G4UIcmdWithAString.hh"
|
||||
#include "G4UIcmdWithADouble.hh"
|
||||
#include "G4UIcommand.hh"
|
||||
#include "G4UIparameter.hh"
|
||||
#include <sstream>
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4MPImessenger::G4MPImessenger( G4MPImanager* manager)
|
||||
: G4UImessenger(), g4MPI(manager)
|
||||
{
|
||||
// /mpi
|
||||
dir = new G4UIdirectory("/mpi/");
|
||||
dir-> SetGuidance("MPI control commands");
|
||||
|
||||
// /mpi/verbose
|
||||
verbose = new G4UIcmdWithAnInteger("/mpi/verbose", this);
|
||||
verbose-> SetGuidance("Set verbose level.");
|
||||
verbose-> SetParameterName("verbose", false, false);
|
||||
verbose->SetRange("verbose>=0 && verbose<=1");
|
||||
|
||||
// /mpi/status
|
||||
status = new G4UIcmdWithoutParameter("/mpi/status", this);
|
||||
status-> SetGuidance( "Show mpi status.");
|
||||
|
||||
// /mpi/execute
|
||||
execute = new G4UIcmdWithAString("/mpi/execute", this);
|
||||
execute-> SetGuidance("Execute a macro file. (=/control/execute)");
|
||||
execute-> SetParameterName("fileName", false, false);
|
||||
|
||||
// /mpi/beamOn
|
||||
beamOn = new G4UIcommand("/mpi/beamOn", this);
|
||||
beamOn-> SetGuidance("Start a parallel run w/ thread.");
|
||||
|
||||
G4UIparameter* p1= new G4UIparameter("numberOfEvent", 'i', true);
|
||||
p1-> SetDefaultValue(1);
|
||||
p1-> SetParameterRange("numberOfEvent>=0");
|
||||
beamOn-> SetParameter(p1);
|
||||
|
||||
G4UIparameter* p2= new G4UIparameter("divide", 'b', true);
|
||||
p2-> SetDefaultValue(true);
|
||||
beamOn-> SetParameter(p2);
|
||||
|
||||
// /mpi/.beamOn
|
||||
dotbeamOn = new G4UIcommand("/mpi/.beamOn", this);
|
||||
dotbeamOn-> SetGuidance("Start a parallel run w/o thread.");
|
||||
|
||||
p1= new G4UIparameter("numberOfEvent", 'i', true);
|
||||
p1-> SetDefaultValue(1);
|
||||
p1-> SetParameterRange("numberOfEvent>=0");
|
||||
dotbeamOn-> SetParameter(p1);
|
||||
|
||||
p2= new G4UIparameter("divide", 'b', true);
|
||||
p2-> SetDefaultValue(true);
|
||||
dotbeamOn-> SetParameter(p2);
|
||||
|
||||
// /mpi/weightForMaster
|
||||
masterWeight = new G4UIcmdWithADouble("/mpi/masterWeight", this);
|
||||
masterWeight-> SetGuidance("Set weight for master node.");
|
||||
masterWeight-> SetParameterName("weight", false, false);
|
||||
masterWeight-> SetRange("weight>=0. && weight<=1.");
|
||||
|
||||
// /mpi/showSeeds
|
||||
showSeeds = new G4UIcmdWithoutParameter("/mpi/showSeeds", this);
|
||||
showSeeds-> SetGuidance("Show seeds of MPI nodes.");
|
||||
|
||||
// /mpi/setMasterSeed
|
||||
setMasterSeed = new G4UIcmdWithAnInteger("/mpi/setMasterSeed", this);
|
||||
setMasterSeed-> SetGuidance("Set a master seed for the seed generator.");
|
||||
setMasterSeed-> SetParameterName("seed", false, false);
|
||||
|
||||
// /mpi/setSeed
|
||||
setSeed = new G4UIcommand("/mpi/setSeed", this);
|
||||
setSeed-> SetGuidance("Set a seed for a specified node.");
|
||||
|
||||
p1 = new G4UIparameter("node", 'i', false);
|
||||
p1-> SetParameterRange("node>=0");
|
||||
setSeed-> SetParameter(p1);
|
||||
|
||||
p2 = new G4UIparameter("seed", 'i', false);
|
||||
setSeed-> SetParameter(p2);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4MPImessenger::~G4MPImessenger()
|
||||
{
|
||||
delete verbose;
|
||||
delete status;
|
||||
delete execute;
|
||||
delete beamOn;
|
||||
delete dotbeamOn;
|
||||
delete masterWeight;
|
||||
delete showSeeds;
|
||||
delete setMasterSeed;
|
||||
delete setSeed;
|
||||
|
||||
delete dir;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPImessenger::SetNewValue( G4UIcommand* command, G4String newValue)
|
||||
{
|
||||
if (command == verbose) { // /mpi/verbose
|
||||
G4int lv= verbose-> GetNewIntValue(newValue);
|
||||
g4MPI-> SetVerbose(lv);
|
||||
|
||||
} else if (command == status){ // /mpi/status
|
||||
g4MPI-> ShowStatus();
|
||||
|
||||
} else if (command == execute){ // /mpi/execute
|
||||
G4UImanager* UI = G4UImanager::GetUIpointer();
|
||||
g4MPI-> ExecuteMacroFile(UI-> FindMacroPath(newValue));
|
||||
|
||||
} else if (command == beamOn){ // /mpi/beamOn
|
||||
std::istringstream is(newValue);
|
||||
G4int nevent;
|
||||
G4bool qdivide;
|
||||
is >> nevent >> qdivide;
|
||||
g4MPI-> BeamOn(nevent, qdivide);
|
||||
|
||||
} else if (command == dotbeamOn){ // /mpi/.beamOn
|
||||
std::istringstream is(newValue);
|
||||
G4int nevent;
|
||||
G4bool qdivide;
|
||||
is >> nevent >> qdivide;
|
||||
g4MPI-> BeamOn(nevent, qdivide);
|
||||
|
||||
} else if (command == masterWeight){ // /mpi/masterWeight
|
||||
G4double weight= masterWeight-> GetNewDoubleValue(newValue);
|
||||
g4MPI-> SetMasterWeight(weight);
|
||||
|
||||
} else if (command == showSeeds){ // /mpi/showSeeds
|
||||
g4MPI-> ShowSeeds();
|
||||
|
||||
} else if (command == setMasterSeed){ // /mpi/setMasterSeed
|
||||
std::istringstream is(newValue);
|
||||
G4long seed;
|
||||
is >> seed;
|
||||
g4MPI-> GetSeedGenerator()-> SetMasterSeed(seed);
|
||||
g4MPI-> DistributeSeeds();
|
||||
|
||||
} else if (command == setSeed){ // /mpi/setSeed
|
||||
std::istringstream is(newValue);
|
||||
G4int inode;
|
||||
G4long seed;
|
||||
is >> inode >> seed;
|
||||
g4MPI-> SetSeed(inode, seed);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4String G4MPImessenger::GetCurrentValue(G4UIcommand* command)
|
||||
{
|
||||
G4String cv;
|
||||
|
||||
if (command == verbose) {
|
||||
cv= verbose-> ConvertToString(g4MPI->GetVerbose());
|
||||
} else if (command == masterWeight) {
|
||||
cv= masterWeight-> ConvertToString(g4MPI->GetMasterWeight());
|
||||
}
|
||||
|
||||
return cv;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
/// @file G4MPIrandomSeedGenerator.cc
|
||||
/// @brief An implementation of random number seed distribution
|
||||
|
||||
#include "G4MPIrandomSeedGenerator.hh"
|
||||
#include "G4MPImanager.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4MPIrandomSeedGenerator::G4MPIrandomSeedGenerator()
|
||||
: G4VMPIseedGenerator()
|
||||
{
|
||||
GenerateSeeds();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4MPIrandomSeedGenerator::~G4MPIrandomSeedGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4bool G4MPIrandomSeedGenerator::CheckDoubleCount()
|
||||
{
|
||||
G4MPImanager* g4MPI = G4MPImanager::GetManager();
|
||||
G4int nsize = g4MPI-> GetSize();
|
||||
|
||||
for (G4int i = 0; i < nsize; i++) {
|
||||
for (G4int j = 0; j < nsize; j++) {
|
||||
if((i != j) && (seedList[i] == seedList[j])) {
|
||||
G4double x = G4UniformRand();
|
||||
seedList[j] = G4long(x*LONG_MAX);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPIrandomSeedGenerator::GenerateSeeds()
|
||||
{
|
||||
G4MPImanager* g4MPI = G4MPImanager::GetManager();
|
||||
G4int nsize= g4MPI-> GetSize();
|
||||
seedList.clear();
|
||||
|
||||
for (G4int i = 0; i < nsize; i++) {
|
||||
G4double x = G4UniformRand();
|
||||
G4int seed = G4long(x*LONG_MAX);
|
||||
seedList.push_back(seed);
|
||||
}
|
||||
|
||||
while(! CheckDoubleCount()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
/// @file G4MPIsession.cc
|
||||
/// @brief A terminal session for MPI application
|
||||
|
||||
#include "G4MPIsession.hh"
|
||||
#include "G4MPImanager.hh"
|
||||
#include "G4RunManager.hh"
|
||||
#include "G4UImanager.hh"
|
||||
#include "G4UIcommand.hh"
|
||||
#include "G4UIcsh.hh"
|
||||
#include "G4UItcsh.hh"
|
||||
#include "G4UImpish.hh"
|
||||
|
||||
#ifndef WIN32
|
||||
static const G4bool tcsh_build = true;
|
||||
#else
|
||||
static const G4bool tcsh_build = false;
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4MPIsession::G4MPIsession(G4VUIshell* ashell)
|
||||
: G4VMPIsession()
|
||||
{
|
||||
G4UImanager* UI = G4UImanager::GetUIpointer();
|
||||
UI-> SetSession(this);
|
||||
UI-> SetCoutDestination(this);
|
||||
|
||||
// shell
|
||||
if(isMaster) {
|
||||
if(ashell) {
|
||||
shell = ashell;
|
||||
} else {
|
||||
if ( g4MPI->GetSize() == 1 && tcsh_build ) shell = new G4UItcsh;
|
||||
else shell = new G4UIcsh;
|
||||
}
|
||||
} else {
|
||||
shell = new G4UImpish;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4MPIsession::~G4MPIsession()
|
||||
{
|
||||
delete shell;
|
||||
|
||||
G4UImanager* UI = G4UImanager::GetUIpointer();
|
||||
UI-> SetSession(0);
|
||||
UI-> SetCoutDestination(0);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPIsession::SetPrompt(const G4String& prompt)
|
||||
{
|
||||
shell-> SetPrompt(prompt);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPIsession::SetShell(G4VUIshell* ashell)
|
||||
{
|
||||
delete shell;
|
||||
shell = ashell;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4String G4MPIsession::GetCommand(const char* msg)
|
||||
{
|
||||
G4UImanager* UI = G4UImanager::GetUIpointer();
|
||||
|
||||
G4String newCommand;
|
||||
const G4String nullString="";
|
||||
|
||||
// get command from shell...
|
||||
newCommand = shell-> GetCommandLineString(msg);
|
||||
|
||||
G4String nC= newCommand.strip(G4String::leading);
|
||||
if( nC.length() == 0 ) {
|
||||
newCommand = nullString;
|
||||
|
||||
} else if( nC(0) == '#' ) {
|
||||
G4cout << nC << G4endl;
|
||||
newCommand = nullString;
|
||||
|
||||
} else if(nC=="ls" || nC(0,3)=="ls " ) { // list commands
|
||||
ListDirectory(nC);
|
||||
newCommand = nullString;
|
||||
|
||||
} else if(nC=="lc" || nC(0,3)=="lc " ) { // ... by shell
|
||||
shell-> ListCommand(nC.remove(0,2));
|
||||
newCommand = nullString;
|
||||
|
||||
} else if(nC == "pwd") { // show current directory
|
||||
G4cout << "Current Command Directory : "
|
||||
<< GetCurrentWorkingDirectory() << G4endl;
|
||||
newCommand = nullString;
|
||||
|
||||
} else if(nC == "cwd") { // ... by shell
|
||||
shell-> ShowCurrentDirectory();
|
||||
newCommand = nullString;
|
||||
|
||||
} else if(nC == "cd" || nC(0,3) == "cd ") { // "cd"
|
||||
ChangeDirectoryCommand(nC);
|
||||
shell-> SetCurrentDirectory(GetCurrentWorkingDirectory());
|
||||
newCommand = nullString;
|
||||
|
||||
} else if(nC == "help" || nC(0,5) == "help ") { // "help"
|
||||
TerminalHelp(nC);
|
||||
newCommand = nullString;
|
||||
|
||||
} else if(nC(0) == '?') { // "show current value of a parameter"
|
||||
ShowCurrent(nC);
|
||||
newCommand = nullString;
|
||||
|
||||
} else if(nC == "hist" || nC == "history") { // "hist/history"
|
||||
G4int nh= UI-> GetNumberOfHistory();
|
||||
for (G4int i = 0; i<nh; i++) {
|
||||
G4cout << i << ": " << UI->GetPreviousCommand(i) << G4endl;
|
||||
}
|
||||
newCommand = nullString;
|
||||
|
||||
} else if(nC(0) == '!') { // "!"
|
||||
G4String ss= nC(1, nC.length()-1);
|
||||
G4int vl;
|
||||
const char* tt = ss;
|
||||
std::istringstream is(tt);
|
||||
is >> vl;
|
||||
G4int nh= UI-> GetNumberOfHistory();
|
||||
if(vl>=0 && vl<nh) {
|
||||
newCommand = UI-> GetPreviousCommand(vl);
|
||||
G4cout << newCommand << G4endl;
|
||||
} else {
|
||||
G4cerr << "history " << vl << " is not found." << G4endl;
|
||||
newCommand = nullString;
|
||||
}
|
||||
|
||||
} else if( nC.empty() ){ // NULL command
|
||||
newCommand = nullString;
|
||||
|
||||
} else if( nC == "exit" ){ // "exit"
|
||||
return "exit";
|
||||
|
||||
} else { // ...
|
||||
|
||||
}
|
||||
|
||||
newCommand = TruncateCommand(newCommand);
|
||||
return ModifyToFullPathCommand(newCommand);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4UIsession* G4MPIsession::SessionStart()
|
||||
{
|
||||
// execute init macro
|
||||
if( g4MPI-> IsInitMacro() ) {
|
||||
g4MPI-> ExecuteMacroFile(g4MPI->GetInitFileName());
|
||||
}
|
||||
|
||||
// batch mode
|
||||
if( g4MPI-> IsBatchMode() ) {
|
||||
g4MPI-> ExecuteMacroFile(g4MPI->GetMacroFileName(), true);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// interactive session
|
||||
G4String newCommand = "", scommand; // newCommand is always "" in slaves
|
||||
|
||||
while(1) {
|
||||
if(isMaster) newCommand = GetCommand();
|
||||
// broadcast a new G4 command
|
||||
scommand = g4MPI-> BcastCommand(newCommand);
|
||||
if(scommand == "exit") {
|
||||
G4bool qexit = TryForcedTerminate();
|
||||
if(qexit) break;
|
||||
else scommand = "";
|
||||
}
|
||||
ExecCommand(scommand);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4bool G4MPIsession::TryForcedTerminate()
|
||||
{
|
||||
if(! g4MPI-> CheckThreadStatus()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
G4String xmessage;
|
||||
|
||||
// beamOn is still running
|
||||
if(isMaster) {
|
||||
char c[1024];
|
||||
while(1) {
|
||||
G4cout << "Run is still running. Do you abort a run? [y/N]:"
|
||||
<< std::flush;
|
||||
G4cin.getline(c,1024);
|
||||
G4String yesno= c;
|
||||
if(yesno == "y" || yesno == "Y" ||
|
||||
yesno == "n" || yesno == "N" || yesno == "") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(c[0] == 'y' || c[0] == 'Y') {
|
||||
G4cout << "Aborting a run..." << G4endl;
|
||||
xmessage = g4MPI-> BcastCommand("kill me");
|
||||
} else {
|
||||
xmessage = g4MPI-> BcastCommand("alive");
|
||||
}
|
||||
} else {
|
||||
xmessage = g4MPI-> BcastCommand("");
|
||||
}
|
||||
|
||||
if(xmessage == "kill me") {
|
||||
G4RunManager* runManager= G4RunManager::GetRunManager();
|
||||
runManager-> AbortRun(true); // soft abort
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
/// @file G4MPIstatus.cc
|
||||
/// @brief status of MPI application
|
||||
|
||||
#include "G4MPIstatus.hh"
|
||||
#include "G4ApplicationState.hh"
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4MPIstatus::G4MPIstatus()
|
||||
: rank(0), runID(0), nEventToBeProcessed(0), eventID(0),
|
||||
cputime(0.), g4state(G4State_Quit)
|
||||
{
|
||||
timer = new G4Timer;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4MPIstatus::~G4MPIstatus()
|
||||
{
|
||||
delete timer;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPIstatus::SetStatus(G4int arank, G4int runid, G4int noe, G4int evtid,
|
||||
G4ApplicationState state)
|
||||
{
|
||||
rank = arank;
|
||||
runID = runid;
|
||||
nEventToBeProcessed = noe;
|
||||
eventID = evtid;
|
||||
g4state = state;
|
||||
if (timer-> IsValid()) cputime = timer-> GetUserElapsed();
|
||||
else cputime = 0.;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPIstatus::Pack(G4int* data) const
|
||||
{
|
||||
data[0] = rank;
|
||||
data[1] = runID;
|
||||
data[2] = nEventToBeProcessed;
|
||||
data[3] = eventID;
|
||||
data[4] = g4state;
|
||||
|
||||
G4double* ddata = (G4double*)(data+5);
|
||||
ddata[0] = cputime;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPIstatus::UnPack(G4int* data)
|
||||
{
|
||||
rank = data[0];
|
||||
runID = data[1];
|
||||
nEventToBeProcessed = data[2];
|
||||
eventID = data[3];
|
||||
g4state = (G4ApplicationState)data[4];
|
||||
|
||||
G4double* ddata = (G4double*)(data+5);
|
||||
cputime = ddata[0];
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPIstatus::Print() const
|
||||
{
|
||||
// * rank= 001 run= 10002 event= 00001 / 100000 state= Idle"
|
||||
G4cout << "* rank= " << rank
|
||||
<< " run= " << runID
|
||||
<< " event= " << eventID << " / " << nEventToBeProcessed
|
||||
<< " state= " << GetStateString(g4state)
|
||||
<< " time= " << cputime << "s"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4String G4MPIstatus::GetStateString(G4ApplicationState astate) const
|
||||
{
|
||||
G4String sname;
|
||||
|
||||
switch(astate) {
|
||||
case G4State_PreInit:
|
||||
sname = "PreInit";
|
||||
break;
|
||||
case G4State_Init:
|
||||
sname = "Init";
|
||||
break;
|
||||
case G4State_Idle:
|
||||
sname = "Idle";
|
||||
break;
|
||||
case G4State_GeomClosed:
|
||||
sname = "GeomClosed";
|
||||
break;
|
||||
case G4State_EventProc:
|
||||
sname = "EventProc";
|
||||
break;
|
||||
case G4State_Quit:
|
||||
sname = "Quit";
|
||||
break;
|
||||
case G4State_Abort:
|
||||
sname = "Abort";
|
||||
break;
|
||||
default:
|
||||
sname = "Unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
return sname;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
/// @file G4UImpish.cc
|
||||
/// @brief A basic shell for MPI session
|
||||
|
||||
#include "G4UImpish.hh"
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4UImpish::G4UImpish()
|
||||
: G4VUIshell("")
|
||||
{
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4UImpish::~G4UImpish()
|
||||
{
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4String G4UImpish::GetCommandLineString(const char*)
|
||||
{
|
||||
G4String newCommand;
|
||||
|
||||
// recieve command string from master
|
||||
G4cout << "hoge hoge" << G4endl;
|
||||
|
||||
return newCommand;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
/// @file G4VMPIseedGenerator.cc
|
||||
/// @brief A base class for random number seed distribution
|
||||
|
||||
#include "G4VMPIseedGenerator.hh"
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4VMPIseedGenerator::G4VMPIseedGenerator()
|
||||
: masterSeed(123456789)
|
||||
{
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4VMPIseedGenerator::~G4VMPIseedGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4VMPIseedGenerator::SetMasterSeed(G4long aseed)
|
||||
{
|
||||
masterSeed = aseed;
|
||||
GenerateSeeds();
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
/// @file G4VMPIsession.cc
|
||||
/// @brief A base class for MPI sessions
|
||||
|
||||
#include "G4VMPIsession.hh"
|
||||
#include "G4MPImanager.hh"
|
||||
#include "G4UImanager.hh"
|
||||
#include "G4UIcommand.hh"
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4VMPIsession::G4VMPIsession()
|
||||
: G4VBasicShell()
|
||||
{
|
||||
// MPI
|
||||
g4MPI = G4MPImanager::GetManager();
|
||||
|
||||
isMaster = g4MPI-> IsMaster();
|
||||
isSlave = g4MPI-> IsSlave();
|
||||
rank = g4MPI-> GetRank();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4VMPIsession::~G4VMPIsession()
|
||||
{
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4bool G4VMPIsession::GetHelpChoice(G4int& aval)
|
||||
{
|
||||
G4cin >> aval;
|
||||
if(!G4cin.good()){
|
||||
G4cin.clear();
|
||||
G4cin.ignore(30,'\n');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4VMPIsession::ExitHelp() const
|
||||
{
|
||||
char temp[100];
|
||||
G4cin.getline(temp, 100);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
void G4VMPIsession::PauseSessionStart(const G4String&)
|
||||
{
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4int G4VMPIsession::ExecCommand(G4String acommand)
|
||||
{
|
||||
if( acommand.length() < 2 ) return fCommandSucceeded;
|
||||
|
||||
G4UImanager* UI = G4UImanager::GetUIpointer();
|
||||
G4int returnVal = 0;
|
||||
|
||||
G4String command = BypassCommand(acommand);
|
||||
|
||||
// "/mpi/beamOn is threaded out.
|
||||
if(command(0,11) == "/mpi/beamOn") {
|
||||
g4MPI-> ExecuteBeamOnThread(command);
|
||||
returnVal = fCommandSucceeded;
|
||||
} else if(command(0,12) == "/mpi/.beamOn") { // care for beamOn
|
||||
G4bool threadStatus = g4MPI-> CheckThreadStatus();
|
||||
if (threadStatus) { // still /run/beamOn is active
|
||||
if(isMaster) {
|
||||
G4cout << "G4MPIsession:: beamOn is still running." << G4endl;
|
||||
}
|
||||
returnVal = fCommandSucceeded;
|
||||
} else {
|
||||
returnVal = UI-> ApplyCommand(command);
|
||||
}
|
||||
} else { // normal command
|
||||
returnVal = UI-> ApplyCommand(command);
|
||||
}
|
||||
|
||||
G4int paramIndex = returnVal % 100;
|
||||
// 0 - 98 : paramIndex-th parameter is invalid
|
||||
// 99 : convination of parameters is invalid
|
||||
G4int commandStatus = returnVal - paramIndex;
|
||||
|
||||
G4UIcommand* cmd = 0;
|
||||
if(commandStatus != fCommandSucceeded) {
|
||||
cmd = FindCommand(command);
|
||||
}
|
||||
|
||||
switch(commandStatus) {
|
||||
case fCommandSucceeded:
|
||||
break;
|
||||
case fCommandNotFound:
|
||||
G4cerr << "command <" << UI-> SolveAlias(command)
|
||||
<< "> not found" << G4endl;
|
||||
break;
|
||||
case fIllegalApplicationState:
|
||||
G4cerr << "illegal application state -- command refused" << G4endl;
|
||||
break;
|
||||
case fParameterOutOfRange:
|
||||
// ...
|
||||
break;
|
||||
case fParameterOutOfCandidates:
|
||||
G4cerr << "Parameter is out of candidate list (index "
|
||||
<< paramIndex << ")" << G4endl;
|
||||
G4cerr << "Candidates : "
|
||||
<< cmd->GetParameter(paramIndex)-> GetParameterCandidates()
|
||||
<< G4endl;
|
||||
break;
|
||||
case fParameterUnreadable:
|
||||
G4cerr << "Parameter is wrong type and/or is not omittable (index "
|
||||
<< paramIndex << ")" << G4endl;
|
||||
break;
|
||||
case fAliasNotFound:
|
||||
// ...
|
||||
break;
|
||||
default:
|
||||
G4cerr << "command refused (" << commandStatus << ")" << G4endl;
|
||||
}
|
||||
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4String G4VMPIsession::TruncateCommand(const G4String& command) const
|
||||
{
|
||||
// replace "//" with "/" in G4command
|
||||
G4String acommand = command;
|
||||
G4String strarg;
|
||||
|
||||
str_size iarg = acommand.find(' ');
|
||||
if(iarg != G4String::npos) {
|
||||
strarg = acommand(iarg, acommand.size()-iarg);
|
||||
acommand = acommand(0,iarg);
|
||||
}
|
||||
|
||||
str_size idx;
|
||||
while( (idx = acommand.find("//")) != G4String::npos) {
|
||||
G4String command1 = acommand(0,idx+1);
|
||||
G4String command2 = acommand(idx+2, acommand.size()-idx-2);
|
||||
acommand = command1 + command2;
|
||||
}
|
||||
|
||||
acommand += strarg;
|
||||
|
||||
return acommand;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4String G4VMPIsession::BypassCommand(const G4String& command) const
|
||||
{
|
||||
// bypass some commands
|
||||
// * /mpi/beamOn
|
||||
// -> /mpi/.beamOn (batch session)
|
||||
//
|
||||
// * /run/beamOn
|
||||
// -> /mpi/.beamOn (batch session)
|
||||
// -> /mpi/beamOn (interactive session)
|
||||
//
|
||||
// * /control/execute -> /mpi/execute
|
||||
|
||||
G4String acommand = command;
|
||||
|
||||
// /mpi/beamOn
|
||||
if(acommand(0,11) == "/mpi/beamOn") {
|
||||
if(g4MPI-> IsBatchMode()) {
|
||||
acommand = "/mpi/.beamOn";
|
||||
if(command.length() > 11) {
|
||||
acommand += command.substr(11);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// /run/beamOn
|
||||
if(acommand(0,11) == "/run/beamOn") {
|
||||
G4String strarg = "";
|
||||
G4bool qget = false;
|
||||
G4bool qdone = false;
|
||||
|
||||
for (str_size idx = 10; idx < command.size(); idx++) {
|
||||
if(command[idx] == ' ' || command[idx] == '\011') {
|
||||
qget = true;
|
||||
if(qdone) break;
|
||||
continue;
|
||||
}
|
||||
if(qget) {
|
||||
strarg += command[idx];
|
||||
qdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(g4MPI-> IsBatchMode()) { // batch session
|
||||
acommand = "/mpi/.beamOn ";
|
||||
if(command.length() > 11) acommand += strarg;
|
||||
} else { // interactive session
|
||||
if(g4MPI-> GetVerbose()>0 && isMaster) {
|
||||
G4cout << "/run/beamOn is overridden by /mpi/.beamOn" << G4endl;
|
||||
}
|
||||
acommand = "/mpi/beamOn ";
|
||||
if(command.length() > 11) acommand += strarg;
|
||||
}
|
||||
}
|
||||
|
||||
// /control/execute
|
||||
if(acommand(0,16) == "/control/execute") {
|
||||
if(g4MPI-> GetVerbose()>0 && isMaster) {
|
||||
G4cout << "/control/execute is overridden by /mpi/execute"
|
||||
<< G4endl;
|
||||
}
|
||||
acommand.replace(0, 16, "/mpi/execute ");
|
||||
}
|
||||
|
||||
return acommand;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4int G4VMPIsession::ReceiveG4cout(const G4String& coutString)
|
||||
{
|
||||
g4MPI-> Print(coutString);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
G4int G4VMPIsession::ReceiveG4cerr(const G4String& cerrString)
|
||||
{
|
||||
g4MPI-> Print(cerrString);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user