Import Geant4 11.4.0.beta source tree
This commit is contained in:
@@ -52,12 +52,12 @@ void G4MPIhistoMerger::Merge()
|
||||
G4cout << "Starting merging of histograms" << G4endl;
|
||||
}
|
||||
|
||||
const MPI::Intracomm* parentComm = G4MPImanager::GetManager()->GetComm();
|
||||
MPI::Intracomm comm = parentComm->Dup();
|
||||
const MPI_Comm* parentComm = G4MPImanager::GetManager()->GetComm();
|
||||
MPI_Comm comm;
|
||||
MPI_Comm_dup(*parentComm, &comm);
|
||||
|
||||
G4bool verbose = (verboseLevel > 1);
|
||||
G4int tag = G4MPImanager::kTAG_HISTO;
|
||||
// const MPI::Intracomm* comm = &COMM_G4COMMAND_;
|
||||
toolx::mpi::hmpi* hmpi = new toolx::mpi::hmpi(G4cout, destination, tag, comm, verbose);
|
||||
if (!manager->Merge(hmpi)) {
|
||||
G4cout << " Merge FAILED" << G4endl;
|
||||
@@ -68,5 +68,5 @@ void G4MPIhistoMerger::Merge()
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << "End merging of histograms" << G4endl;
|
||||
}
|
||||
comm.Free();
|
||||
MPI_Comm_free(&comm);
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <vector>
|
||||
|
||||
G4MPImanager* G4MPImanager::g4mpi_ = NULL;
|
||||
|
||||
@@ -83,8 +84,13 @@ G4MPImanager::G4MPImanager(int nof_extra_workers)
|
||||
master_weight_(1.),
|
||||
nof_extra_workers_(nof_extra_workers)
|
||||
{
|
||||
// MPI::Init();
|
||||
MPI::Init_thread(MPI::THREAD_SERIALIZED);
|
||||
int provided;
|
||||
MPI_Init_thread(nullptr, nullptr, MPI_THREAD_SERIALIZED, &provided);
|
||||
if (provided < MPI_THREAD_SERIALIZED) {
|
||||
G4Exception("G4MPImanager::G4MPImanager()", "G4MPImanager001", FatalException,
|
||||
"MPI Initialization failed to setup with MPI_THREAD_SERIALIZED or better");
|
||||
}
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
@@ -102,8 +108,12 @@ G4MPImanager::G4MPImanager(int argc, char** argv, int nof_extra_workers)
|
||||
master_weight_(1.),
|
||||
nof_extra_workers_(nof_extra_workers)
|
||||
{
|
||||
// MPI::Init(argc, argv);
|
||||
MPI::Init_thread(argc, argv, MPI::THREAD_SERIALIZED);
|
||||
int provided;
|
||||
MPI_Init_thread(&argc, &argv, MPI_THREAD_SERIALIZED, &provided);
|
||||
if (provided < MPI_THREAD_SERIALIZED) {
|
||||
G4Exception("G4MPImanager::G4MPImanager()", "G4MPImanager001", FatalException,
|
||||
"MPI Initialization failed to setup with MPI_THREAD_SERIALIZED or better");
|
||||
}
|
||||
Initialize();
|
||||
ParseArguments(argc, argv);
|
||||
}
|
||||
@@ -133,10 +143,10 @@ G4MPImanager::~G4MPImanager()
|
||||
}
|
||||
}
|
||||
else {
|
||||
COMM_G4COMMAND_.Free();
|
||||
MPI_Comm_free(&COMM_G4COMMAND_);
|
||||
}
|
||||
|
||||
MPI::Finalize();
|
||||
MPI_Finalize();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -173,14 +183,14 @@ void G4MPImanager::Initialize()
|
||||
g4mpi_ = this;
|
||||
|
||||
// get rank information
|
||||
world_size_ = MPI::COMM_WORLD.Get_size();
|
||||
MPI_Comm_size(MPI_COMM_WORLD, &world_size_);
|
||||
if (world_size_ - nof_extra_workers_ <= 0) {
|
||||
G4Exception("G4MPImanager::SetExtraWorker()", "MPI001", JustWarning,
|
||||
"Cannot reserve extra ranks: the MPI size is not sufficient.");
|
||||
nof_extra_workers_ = 0;
|
||||
}
|
||||
size_ = world_size_ - nof_extra_workers_;
|
||||
rank_ = MPI::COMM_WORLD.Get_rank();
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &rank_);
|
||||
is_master_ = (rank_ == kRANK_MASTER);
|
||||
is_slave_ = (rank_ != kRANK_MASTER);
|
||||
is_extra_worker_ = false;
|
||||
@@ -220,13 +230,12 @@ void G4MPImanager::Initialize()
|
||||
MPI_Comm_create_group(MPI_COMM_WORLD, collecting_group_, 0, &collecting_comm_);
|
||||
MPI_Comm_create_group(MPI_COMM_WORLD, all_group_, 0, &all_comm_);
|
||||
|
||||
// COMM_G4COMMAND_ = processing_comm_ copy
|
||||
COMM_G4COMMAND_ = MPI::Intracomm(processing_comm_);
|
||||
MPI_Comm_dup(processing_comm_, &COMM_G4COMMAND_);
|
||||
}
|
||||
else {
|
||||
// G4cout << "No extra workers requested" << G4endl;
|
||||
// initialize MPI communicator
|
||||
COMM_G4COMMAND_ = MPI::COMM_WORLD.Dup();
|
||||
MPI_Comm_dup(MPI_COMM_WORLD, &COMM_G4COMMAND_);
|
||||
}
|
||||
|
||||
is_extra_worker_ = (collecting_comm_ != MPI_COMM_NULL);
|
||||
@@ -257,50 +266,51 @@ void G4MPImanager::Initialize()
|
||||
// --------------------------------------------------------------------------
|
||||
void G4MPImanager::ParseArguments(int argc, char** argv)
|
||||
{
|
||||
_options.clear();
|
||||
G4int qhelp = 0;
|
||||
G4String ofprefix = "mpi";
|
||||
|
||||
G4int c;
|
||||
while (1) {
|
||||
G4int option_index = 0;
|
||||
static struct option long_options[] = {{"help", no_argument, NULL, 'h'},
|
||||
{"verbose", no_argument, NULL, 'v'},
|
||||
{"init", required_argument, NULL, 'i'},
|
||||
{"ofile", optional_argument, NULL, 'o'},
|
||||
{NULL, 0, NULL, 0}};
|
||||
G4int option_index = -1;
|
||||
|
||||
opterr = 0; // suppress message
|
||||
c = getopt_long(argc, argv, "hvi:o", long_options, &option_index);
|
||||
opterr = 1;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
G4String arg = argv[i];
|
||||
G4String sub;
|
||||
G4String endsub = sub;
|
||||
if (arg.length() > 5) {
|
||||
sub = arg.substr(0, 5);
|
||||
endsub = arg.substr(arg.length() - 4);
|
||||
}
|
||||
|
||||
if (c == -1) break;
|
||||
|
||||
switch (c) {
|
||||
case 'h':
|
||||
qhelp = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose_ = 1;
|
||||
break;
|
||||
case 'i':
|
||||
qinitmacro_ = true;
|
||||
init_file_name_ = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
qfcout_ = true;
|
||||
if (optarg) ofprefix = optarg;
|
||||
break;
|
||||
default:
|
||||
G4cerr << "*** invalid options specified." << G4endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
break;
|
||||
if (arg == "help") {
|
||||
qhelp = 1;
|
||||
}
|
||||
else if (arg == "verbose") {
|
||||
verbose_ = 1;
|
||||
}
|
||||
else if (arg == "init") {
|
||||
qinitmacro_ = true;
|
||||
init_file_name_ = optarg;
|
||||
}
|
||||
else if (arg == "ofile") {
|
||||
qfcout_ = true;
|
||||
if (optarg) ofprefix = optarg;
|
||||
}
|
||||
else if (sub == "macro" or endsub == ".mac") {
|
||||
option_index = i;
|
||||
qbatchmode_ = true;
|
||||
}
|
||||
// default:
|
||||
// G4cerr << "*** invalid options specified." << G4endl;
|
||||
// std::exit(EXIT_FAILURE);
|
||||
else {
|
||||
_options.push_back(arg);
|
||||
}
|
||||
}
|
||||
|
||||
// show help
|
||||
if (qhelp) {
|
||||
if (is_master_) ShowHelp();
|
||||
MPI::Finalize();
|
||||
MPI_Finalize();
|
||||
std::exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -308,15 +318,14 @@ void G4MPImanager::ParseArguments(int argc, char** argv)
|
||||
if (is_slave_ && qfcout_) {
|
||||
G4String prefix = ofprefix + ".%03d" + ".cout";
|
||||
char str[1024];
|
||||
sprintf(str, prefix.c_str(), rank_);
|
||||
snprintf(str, 1024, prefix.c_str(), rank_);
|
||||
G4String fname(str);
|
||||
fscout_.open(fname.c_str(), std::ios::out);
|
||||
}
|
||||
|
||||
// non-option ARGV-elements ...
|
||||
if (optind < argc) {
|
||||
qbatchmode_ = true;
|
||||
macro_file_name_ = argv[optind];
|
||||
if (qbatchmode_) {
|
||||
macro_file_name_ = argv[option_index];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,7 +374,8 @@ void G4MPImanager::ShowStatus()
|
||||
|
||||
// receive from each slave
|
||||
for (G4int islave = 1; islave < size_; islave++) {
|
||||
COMM_G4COMMAND_.Recv(buff, G4MPIstatus::kNSIZE, MPI::INT, islave, kTAG_G4STATUS);
|
||||
MPI_Recv(buff, G4MPIstatus::kNSIZE, MPI_INT, islave, kTAG_G4STATUS, COMM_G4COMMAND_,
|
||||
MPI_STATUS_IGNORE);
|
||||
status_->UnPack(buff);
|
||||
status_->Print();
|
||||
|
||||
@@ -389,7 +399,7 @@ void G4MPImanager::ShowStatus()
|
||||
}
|
||||
else {
|
||||
status_->Pack(buff);
|
||||
COMM_G4COMMAND_.Send(buff, G4MPIstatus::kNSIZE, MPI::INT, kRANK_MASTER, kTAG_G4STATUS);
|
||||
MPI_Send(buff, G4MPIstatus::kNSIZE, MPI_INT, kRANK_MASTER, kTAG_G4STATUS, COMM_G4COMMAND_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,13 +423,13 @@ void G4MPImanager::ShowSeeds()
|
||||
G4cout << "* rank= " << rank_ << " seed= " << G4Random::getTheSeed() << G4endl;
|
||||
// receive from each slave
|
||||
for (G4int islave = 1; islave < size_; islave++) {
|
||||
COMM_G4COMMAND_.Recv(&buff, 1, MPI::LONG, islave, kTAG_G4SEED);
|
||||
MPI_Recv(&buff, 1, MPI_LONG, islave, kTAG_G4SEED, COMM_G4COMMAND_, MPI_STATUS_IGNORE);
|
||||
G4cout << "* rank= " << islave << " seed= " << buff << G4endl;
|
||||
}
|
||||
}
|
||||
else { // slaves
|
||||
buff = G4Random::getTheSeed();
|
||||
COMM_G4COMMAND_.Send(&buff, 1, MPI::LONG, kRANK_MASTER, kTAG_G4SEED);
|
||||
MPI_Send(&buff, 1, MPI_LONG, kRANK_MASTER, kTAG_G4SEED, COMM_G4COMMAND_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,21 +451,25 @@ G4bool G4MPImanager::CheckThreadStatus()
|
||||
qstatus = (thread_id_ != 0);
|
||||
// get slave status
|
||||
for (G4int islave = 1; islave < size_; islave++) {
|
||||
MPI::Request request = COMM_G4COMMAND_.Irecv(&buff, 1, MPI::UNSIGNED, islave, kTAG_G4STATUS);
|
||||
while (!request.Test()) {
|
||||
MPI_Request request;
|
||||
MPI_Irecv(&buff, 1, MPI_UNSIGNED, islave, kTAG_G4STATUS, COMM_G4COMMAND_, &request);
|
||||
int flag = 0;
|
||||
while (!flag) {
|
||||
MPI_Test(&request, &flag, MPI_STATUS_IGNORE);
|
||||
::Wait(1000);
|
||||
}
|
||||
|
||||
qstatus |= buff;
|
||||
}
|
||||
}
|
||||
else {
|
||||
buff = (thread_id_ != 0);
|
||||
COMM_G4COMMAND_.Send(&buff, 1, MPI::UNSIGNED, kRANK_MASTER, kTAG_G4STATUS);
|
||||
MPI_Send(&buff, 1, MPI_UNSIGNED, kRANK_MASTER, kTAG_G4STATUS, COMM_G4COMMAND_);
|
||||
}
|
||||
|
||||
// broadcast
|
||||
buff = qstatus; // for master
|
||||
COMM_G4COMMAND_.Bcast(&buff, 1, MPI::UNSIGNED, kRANK_MASTER);
|
||||
MPI_Bcast(&buff, 1, MPI_UNSIGNED, kRANK_MASTER, COMM_G4COMMAND_);
|
||||
qstatus = buff; // for slave
|
||||
|
||||
if (qstatus != 0)
|
||||
@@ -540,20 +554,21 @@ G4String G4MPImanager::BcastCommand(const G4String& command)
|
||||
// "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 (is_master_) {
|
||||
for (G4int islave = 1; islave < size_; islave++) {
|
||||
COMM_G4COMMAND_.Send(sbuff, kBUFF_SIZE, MPI::CHAR, islave, kTAG_G4COMMAND);
|
||||
MPI_Send(sbuff, kBUFF_SIZE, MPI_CHAR, islave, kTAG_G4COMMAND, COMM_G4COMMAND_);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// try non-blocking receive
|
||||
MPI::Request request =
|
||||
COMM_G4COMMAND_.Irecv(sbuff, kBUFF_SIZE, MPI::CHAR, kRANK_MASTER, kTAG_G4COMMAND);
|
||||
// polling...
|
||||
while (!request.Test()) {
|
||||
MPI_Request request;
|
||||
MPI_Irecv(sbuff, kBUFF_SIZE, MPI_CHAR, kRANK_MASTER, kTAG_G4COMMAND, COMM_G4COMMAND_, &request);
|
||||
|
||||
int flag = 0;
|
||||
while (!flag) {
|
||||
MPI_Test(&request, &flag, MPI_STATUS_IGNORE);
|
||||
::Wait(1000);
|
||||
}
|
||||
}
|
||||
@@ -654,8 +669,11 @@ void G4MPImanager::WaitBeamOn()
|
||||
// receive from each slave
|
||||
for (G4int islave = 1; islave < size_; islave++) {
|
||||
// G4cout << "calling Irecv for islave " << islave << G4endl;
|
||||
MPI::Request request = COMM_G4COMMAND_.Irecv(&buff, 1, MPI::INT, islave, kTAG_G4STATUS);
|
||||
while (!request.Test()) {
|
||||
MPI_Request request;
|
||||
MPI_Irecv(&buff, 1, MPI_INT, islave, kTAG_G4STATUS, COMM_G4COMMAND_, &request);
|
||||
int flag = 0;
|
||||
while (flag) {
|
||||
MPI_Test(&request, &flag, MPI_STATUS_IGNORE);
|
||||
::Wait(1000);
|
||||
}
|
||||
}
|
||||
@@ -663,7 +681,7 @@ void G4MPImanager::WaitBeamOn()
|
||||
else {
|
||||
buff = 1;
|
||||
// G4cout << "calling send for i " << kRANK_MASTER << G4endl;
|
||||
COMM_G4COMMAND_.Send(&buff, 1, MPI::INT, kRANK_MASTER, kTAG_G4STATUS);
|
||||
MPI_Send(&buff, 1, MPI_INT, kRANK_MASTER, kTAG_G4STATUS, COMM_G4COMMAND_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,20 +49,20 @@ namespace
|
||||
struct MPIStatDouble : public G4StatDouble
|
||||
{
|
||||
G4int verbose;
|
||||
inline void Pack(void* buffer, int bufferSize, int* position, MPI::Intracomm& comm) const
|
||||
inline void Pack(void* buffer, int bufferSize, int* position, MPI_Comm& comm) const
|
||||
{
|
||||
DMSG(4, "Packing G4StatDouble(n,scale,sum_w,sum_w2,sum_wx,sum_wx2): "
|
||||
<< m_n << " " << m_scale << " " << m_sum_w << " " << m_sum_w2 << " " << m_sum_wx
|
||||
<< " " << m_sum_wx2);
|
||||
MPI_Pack(&m_n, 1, MPI::INT, buffer, bufferSize, position, comm);
|
||||
MPI_Pack(&m_n, 1, MPI_INT, buffer, bufferSize, position, comm);
|
||||
const G4double data[]{m_scale, m_sum_w, m_sum_w2, m_sum_wx, m_sum_wx2};
|
||||
MPI_Pack(&data, 5, MPI::DOUBLE, buffer, bufferSize, position, comm);
|
||||
MPI_Pack(&data, 5, MPI_DOUBLE, buffer, bufferSize, position, comm);
|
||||
}
|
||||
inline void UnPack(void* buffer, int bufferSize, int* position, MPI::Intracomm& comm)
|
||||
inline void UnPack(void* buffer, int bufferSize, int* position, MPI_Comm& comm)
|
||||
{
|
||||
MPI_Unpack(buffer, bufferSize, position, &m_n, 1, MPI::INT, comm);
|
||||
MPI_Unpack(buffer, bufferSize, position, &m_n, 1, MPI_INT, comm);
|
||||
G4double data[5];
|
||||
MPI_Unpack(buffer, bufferSize, position, data, 5, MPI::DOUBLE, comm);
|
||||
MPI_Unpack(buffer, bufferSize, position, data, 5, MPI_DOUBLE, comm);
|
||||
m_scale = data[0];
|
||||
m_sum_w = data[1];
|
||||
m_sum_w2 = data[2];
|
||||
@@ -148,8 +148,8 @@ void G4MPIscorerMerger::Merge()
|
||||
DMSG(1, "Comm world size is 1, nothing to do");
|
||||
return;
|
||||
}
|
||||
const MPI::Intracomm* parentComm = G4MPImanager::GetManager()->GetComm();
|
||||
comm = parentComm->Dup();
|
||||
const MPI_Comm* parentComm = G4MPImanager::GetManager()->GetComm();
|
||||
MPI_Comm_dup(*parentComm, &comm);
|
||||
DestroyBuffer();
|
||||
|
||||
// ANDREA:->
|
||||
@@ -168,14 +168,16 @@ void G4MPIscorerMerger::Merge()
|
||||
// ANDREA:<-
|
||||
|
||||
bytesSent = 0;
|
||||
const G4double sttime = MPI::Wtime();
|
||||
const G4double sttime = MPI_Wtime();
|
||||
|
||||
// Use G4MPIutils to optimize communications between ranks
|
||||
typedef std::function<void(unsigned int)> handler_t;
|
||||
using std::placeholders::_1;
|
||||
handler_t sender = std::bind(&G4MPIscorerMerger::Send, this, _1);
|
||||
handler_t receiver = std::bind(&G4MPIscorerMerger::Receive, this, _1);
|
||||
std::function<void(void)> barrier = std::bind(&MPI::Intracomm::Barrier, &comm);
|
||||
std::function<void(void)> barrier = [this]() {
|
||||
MPI_Barrier(comm);
|
||||
};
|
||||
G4mpi::Merge(sender, receiver, barrier, commSize, myrank);
|
||||
|
||||
// OLD Style p2p communications
|
||||
@@ -194,9 +196,9 @@ void G4MPIscorerMerger::Merge()
|
||||
}
|
||||
}
|
||||
*/
|
||||
const G4double elapsed = MPI::Wtime() - sttime;
|
||||
const G4double elapsed = MPI_Wtime() - sttime;
|
||||
long total = 0;
|
||||
comm.Reduce(&bytesSent, &total, 1, MPI::LONG, MPI::SUM, destinationRank);
|
||||
MPI_Reduce(&bytesSent, &total, 1, MPI_LONG, MPI_SUM, destinationRank, comm);
|
||||
if (verbose > 0 && myrank == destinationRank) {
|
||||
// Collect from ranks how much data was sent around
|
||||
G4cout << "G4MPIscorerMerger::Merge() -data transfer performances: "
|
||||
@@ -218,7 +220,7 @@ void G4MPIscorerMerger::Merge()
|
||||
// }
|
||||
// }
|
||||
// ANDREA:<-
|
||||
comm.Free();
|
||||
MPI_Comm_free(&comm);
|
||||
DMSG(0, "G4MPIscorerMerger::Merge done.");
|
||||
}
|
||||
|
||||
@@ -227,9 +229,11 @@ void G4MPIscorerMerger::Receive(const unsigned int source)
|
||||
DMSG(1, "Receiving scorers");
|
||||
// DestroyBuffer();
|
||||
DMSG(2, "Receiving from: " << source);
|
||||
MPI::Status status;
|
||||
comm.Probe(source, G4MPImanager::kTAG_CMDSCR, status);
|
||||
const G4int newbuffsize = status.Get_count(MPI::PACKED);
|
||||
MPI_Status status;
|
||||
MPI_Probe(source, G4MPImanager::kTAG_CMDSCR, comm, &status);
|
||||
int nbs;
|
||||
MPI_Get_count(&status, MPI_PACKED, &nbs);
|
||||
const G4int newbuffsize = nbs; // Need this interposed since G4int may not be int
|
||||
DMSG(2, "Preparing to receive buffer of size: " << newbuffsize);
|
||||
char* buffer = outputBuffer;
|
||||
if (newbuffsize > outputBufferSize) {
|
||||
@@ -244,7 +248,7 @@ void G4MPIscorerMerger::Receive(const unsigned int source)
|
||||
ownsBuffer = true;
|
||||
}
|
||||
SetupOutputBuffer(buffer, newbuffsize, 0);
|
||||
comm.Recv(buffer, newbuffsize, MPI::PACKED, source, G4MPImanager::kTAG_CMDSCR, status);
|
||||
MPI_Recv(buffer, newbuffsize, MPI_PACKED, source, G4MPImanager::kTAG_CMDSCR, comm, &status);
|
||||
DMSG(3, "Buffer Size: " << outputBufferSize << " bytes at: " << (void*)outputBuffer);
|
||||
UnPackAndMerge(scoringManager);
|
||||
DMSG(1, "Receiving of comamnd line scorers done");
|
||||
@@ -271,7 +275,8 @@ void G4MPIscorerMerger::Send(const unsigned int destination)
|
||||
assert(outputBufferSize == outputBufferPosition);
|
||||
|
||||
// Version 1: p2p communication
|
||||
comm.Send(outputBuffer, outputBufferSize, MPI::PACKED, destination, G4MPImanager::kTAG_CMDSCR);
|
||||
MPI_Send(outputBuffer, outputBufferSize, MPI_PACKED, destination, G4MPImanager::kTAG_CMDSCR,
|
||||
comm);
|
||||
bytesSent += newbuffsize;
|
||||
// Receiver should use probe to get size of the package being sent
|
||||
DMSG(1, "Sending done");
|
||||
@@ -287,10 +292,10 @@ void G4MPIscorerMerger::Pack(const G4ScoringManager* sm)
|
||||
}
|
||||
DMSG(2, "Starting packing of meshes, # meshes: " << sm->GetNumberOfMesh());
|
||||
/*const*/ size_t numMeshes = sm->GetNumberOfMesh(); // TODO: OLD MPI interface
|
||||
MPI_Pack(&numMeshes, 1, MPI::UNSIGNED, outputBuffer, outputBufferSize, &outputBufferPosition,
|
||||
MPI_Pack(&numMeshes, 1, MPI_UNSIGNED, outputBuffer, outputBufferSize, &outputBufferPosition,
|
||||
comm);
|
||||
for (size_t i = 0; i < numMeshes; ++i) {
|
||||
MPI_Pack(&i, 1, MPI::UNSIGNED, outputBuffer, outputBufferSize, &outputBufferPosition, comm);
|
||||
MPI_Pack(&i, 1, MPI_UNSIGNED, outputBuffer, outputBufferSize, &outputBufferPosition, comm);
|
||||
Pack(sm->GetMesh(i));
|
||||
}
|
||||
}
|
||||
@@ -304,7 +309,7 @@ void G4MPIscorerMerger::UnPackAndMerge(const G4ScoringManager* sm)
|
||||
return;
|
||||
}
|
||||
size_t numMeshes = 0;
|
||||
MPI_Unpack(outputBuffer, outputBufferSize, &outputBufferPosition, &numMeshes, 1, MPI::UNSIGNED,
|
||||
MPI_Unpack(outputBuffer, outputBufferSize, &outputBufferPosition, &numMeshes, 1, MPI_UNSIGNED,
|
||||
comm);
|
||||
if (numMeshes != sm->GetNumberOfMesh()) {
|
||||
G4ExceptionDescription msg;
|
||||
@@ -318,7 +323,7 @@ void G4MPIscorerMerger::UnPackAndMerge(const G4ScoringManager* sm)
|
||||
|
||||
size_t meshid = 0;
|
||||
for (size_t i = 0; i < numMeshes; ++i) {
|
||||
MPI_Unpack(outputBuffer, outputBufferSize, &outputBufferPosition, &meshid, 1, MPI::UNSIGNED,
|
||||
MPI_Unpack(outputBuffer, outputBufferSize, &outputBufferPosition, &meshid, 1, MPI_UNSIGNED,
|
||||
comm);
|
||||
if (meshid != i) {
|
||||
G4ExceptionDescription msg;
|
||||
@@ -342,18 +347,18 @@ void G4MPIscorerMerger::Pack(const G4VScoringMesh* mesh)
|
||||
|
||||
auto map = mesh->GetScoreMap();
|
||||
/*const*/ size_t nummaps = map.size(); // TODO: old MPI interface
|
||||
MPI_Pack(&nummaps, 1, MPI::UNSIGNED, outputBuffer, outputBufferSize, &outputBufferPosition, comm);
|
||||
MPI_Pack(&nummaps, 1, MPI_UNSIGNED, outputBuffer, outputBufferSize, &outputBufferPosition, comm);
|
||||
for (const auto& ele : map) {
|
||||
const G4String& name = ele.first;
|
||||
/*const*/ size_t ss = name.size();
|
||||
MPI_Pack(&ss, 1, MPI::UNSIGNED, outputBuffer, outputBufferSize, &outputBufferPosition, comm);
|
||||
MPI_Pack(&ss, 1, MPI_UNSIGNED, outputBuffer, outputBufferSize, &outputBufferPosition, comm);
|
||||
#ifdef G4MPI_USE_MPI_PACK_NOT_CONST
|
||||
char* nn = new char[name.length()];
|
||||
std::copy(name.begin(), name.end(), nn);
|
||||
#else
|
||||
const char* nn = name.c_str();
|
||||
#endif
|
||||
MPI_Pack(nn, ss, MPI::CHAR, outputBuffer, outputBufferSize, &outputBufferPosition, comm);
|
||||
MPI_Pack(nn, ss, MPI_CHAR, outputBuffer, outputBufferSize, &outputBufferPosition, comm);
|
||||
Pack(ele.second);
|
||||
#ifdef G4MPI_USE_MPI_PACK_NOT_CONST
|
||||
delete[] nn;
|
||||
@@ -369,17 +374,17 @@ void G4MPIscorerMerger::UnPackAndMerge(G4VScoringMesh* inmesh)
|
||||
DMSG(3, "Preparing to unpack a mesh and merge into: " << inmesh);
|
||||
const G4String& detName = inmesh->GetWorldName();
|
||||
size_t nummaps = 0;
|
||||
MPI_Unpack(outputBuffer, outputBufferSize, &outputBufferPosition, &nummaps, 1, MPI::UNSIGNED,
|
||||
MPI_Unpack(outputBuffer, outputBufferSize, &outputBufferPosition, &nummaps, 1, MPI_UNSIGNED,
|
||||
comm);
|
||||
for (size_t i = 0; i < nummaps; ++i) {
|
||||
size_t nameSize = 0;
|
||||
MPI_Unpack(outputBuffer, outputBufferSize, &outputBufferPosition, &nameSize, 1, MPI::UNSIGNED,
|
||||
MPI_Unpack(outputBuffer, outputBufferSize, &outputBufferPosition, &nameSize, 1, MPI_UNSIGNED,
|
||||
comm);
|
||||
// Create a null-terminated c-string: needed later when converting this to a G4String
|
||||
//(Not sure: but issue reported by valgrind with the use of MPI_Unpack)
|
||||
char* name = new char[nameSize + 1];
|
||||
std::fill(name, name + nameSize + 1, 0);
|
||||
MPI_Unpack(outputBuffer, outputBufferSize, &outputBufferPosition, name, nameSize, MPI::CHAR,
|
||||
MPI_Unpack(outputBuffer, outputBufferSize, &outputBufferPosition, name, nameSize, MPI_CHAR,
|
||||
comm);
|
||||
const G4String colname(name, nameSize);
|
||||
delete[] name;
|
||||
@@ -393,31 +398,6 @@ void G4MPIscorerMerger::UnPackAndMerge(G4VScoringMesh* inmesh)
|
||||
}
|
||||
}
|
||||
|
||||
// void G4MPIscorerMerger::Pack(const HitMap* sm) {
|
||||
// assert(sm!=nullptr);
|
||||
// assert(outputBuffer!=nullptr);
|
||||
// assert(outputBufferPosition<=outputBufferSize);
|
||||
// DMSG(3,"Packing hitmap: "<<sm<<" with: "<<sm->GetSize()<<" elements.");
|
||||
// /*const*/ size_t numEl = sm->GetSize();//TODO: old MPI implementation
|
||||
// MPI_Pack(&numEl,1,MPI::UNSIGNED,
|
||||
// outputBuffer,outputBufferSize,
|
||||
// &outputBufferPosition,comm);
|
||||
// const auto& theMap = *sm->GetMap();
|
||||
// std::vector<G4int> ids;
|
||||
// std::vector<G4double> vals;
|
||||
// std::transform(theMap.begin(),theMap.end(),std::back_inserter(ids),
|
||||
// [](decltype(*theMap.begin())& e){ return e.first;});
|
||||
// std::transform(theMap.begin(),theMap.end(),std::back_inserter(vals),
|
||||
// [](decltype(*theMap.begin())& e){ return *e.second;});
|
||||
// assert(ids.size()==vals.size()&&ids.size()==numEl);
|
||||
// MPI_Pack(ids.data(),ids.size(),MPI::INT,
|
||||
// outputBuffer,outputBufferSize,
|
||||
// &outputBufferPosition,comm);
|
||||
// MPI_Pack(vals.data(),vals.size(),MPI::DOUBLE,
|
||||
// outputBuffer,outputBufferSize,
|
||||
// &outputBufferPosition,comm);
|
||||
// }
|
||||
|
||||
void G4MPIscorerMerger::Pack(const HitStatDoubleMap* sm)
|
||||
{
|
||||
assert(sm != nullptr);
|
||||
@@ -425,13 +405,13 @@ void G4MPIscorerMerger::Pack(const HitStatDoubleMap* sm)
|
||||
assert(outputBufferPosition <= outputBufferSize);
|
||||
DMSG(3, "Packing hitmap: " << sm << " with: " << sm->GetSize() << " elements.");
|
||||
/*const*/ size_t numEl = sm->GetSize(); // TODO: old MPI implementation
|
||||
MPI_Pack(&numEl, 1, MPI::UNSIGNED, outputBuffer, outputBufferSize, &outputBufferPosition, comm);
|
||||
MPI_Pack(&numEl, 1, MPI_UNSIGNED, outputBuffer, outputBufferSize, &outputBufferPosition, comm);
|
||||
const auto& theMap = *sm->GetMap();
|
||||
std::vector<G4int> ids;
|
||||
std::transform(theMap.begin(), theMap.end(), std::back_inserter(ids),
|
||||
[](decltype(*theMap.begin())& e) { return e.first; });
|
||||
assert(/*ids.size()==vals.size()&&*/ ids.size() == numEl);
|
||||
MPI_Pack(ids.data(), ids.size(), MPI::INT, outputBuffer, outputBufferSize, &outputBufferPosition,
|
||||
MPI_Pack(ids.data(), ids.size(), MPI_INT, outputBuffer, outputBufferSize, &outputBufferPosition,
|
||||
comm);
|
||||
for (const auto& e : theMap) {
|
||||
const MPIStatDouble sd(*e.second, verbose);
|
||||
@@ -439,27 +419,6 @@ void G4MPIscorerMerger::Pack(const HitStatDoubleMap* sm)
|
||||
}
|
||||
}
|
||||
|
||||
// HitMap* G4MPIscorerMerger::UnPackHitMap(const G4String& detName,
|
||||
// const G4String& colName) {
|
||||
// assert(outputBuffer!=nullptr);
|
||||
// assert(outputBufferPosition<=outputBufferSize);
|
||||
// DMSG(3,"Preparing to unpack a hit map for: "<<detName<<","<<colName);
|
||||
// size_t numEl =0 ;
|
||||
// MPI_Unpack(outputBuffer,outputBufferSize,&outputBufferPosition,
|
||||
// &numEl,1,MPI::UNSIGNED,comm);
|
||||
// G4int* ids = new G4int[numEl];
|
||||
// MPI_Unpack(outputBuffer,outputBufferSize,&outputBufferPosition,
|
||||
// ids,numEl,MPI::INT,comm);
|
||||
// G4double* vals = new G4double[numEl];
|
||||
// MPI_Unpack(outputBuffer,outputBufferSize,&outputBufferPosition,
|
||||
// vals,numEl,MPI::DOUBLE,comm);
|
||||
// HitMap* result = new HitMap(detName,colName);
|
||||
// for ( unsigned int i = 0; i<numEl;++i) result->set(ids[i],vals[i]);
|
||||
// delete[] ids;
|
||||
// delete[] vals;
|
||||
// return result;
|
||||
// }
|
||||
|
||||
HitStatDoubleMap* G4MPIscorerMerger::UnPackHitStatDoubleMap(const G4String& detName,
|
||||
const G4String& colName)
|
||||
{
|
||||
@@ -467,10 +426,10 @@ HitStatDoubleMap* G4MPIscorerMerger::UnPackHitStatDoubleMap(const G4String& detN
|
||||
assert(outputBufferPosition <= outputBufferSize);
|
||||
DMSG(3, "Preparing to unpack a hit map for: " << detName << "," << colName);
|
||||
size_t numEl = 0;
|
||||
MPI_Unpack(outputBuffer, outputBufferSize, &outputBufferPosition, &numEl, 1, MPI::UNSIGNED, comm);
|
||||
MPI_Unpack(outputBuffer, outputBufferSize, &outputBufferPosition, &numEl, 1, MPI_UNSIGNED, comm);
|
||||
DMSG(3, "Will receive " << numEl << " values");
|
||||
G4int* ids = new G4int[numEl];
|
||||
MPI_Unpack(outputBuffer, outputBufferSize, &outputBufferPosition, ids, numEl, MPI::INT, comm);
|
||||
MPI_Unpack(outputBuffer, outputBufferSize, &outputBufferPosition, ids, numEl, MPI_INT, comm);
|
||||
HitStatDoubleMap* result = new HitStatDoubleMap(detName, colName);
|
||||
for (unsigned int i = 0; i < numEl; ++i) {
|
||||
MPIStatDouble sd(verbose);
|
||||
|
||||
@@ -60,12 +60,15 @@ void G4VUserMPIrunMerger::Send(const unsigned int destination)
|
||||
<< " events to: " << destination);
|
||||
input_userdata.clear();
|
||||
Pack(); // User code
|
||||
InputUserData(&nevts, MPI::INT, 1);
|
||||
InputUserData(&nevts, MPI_INT, 1);
|
||||
|
||||
DestroyBuffer();
|
||||
G4int newbuffsize = 0;
|
||||
for (const const_registered_data& el : input_userdata) {
|
||||
newbuffsize += (el.dt.Get_size() * el.count);
|
||||
// Assumes type size small enough to be held in int. Use MPI_Type_size_x if not true
|
||||
int sz;
|
||||
MPI_Type_size(el.dt, &sz);
|
||||
newbuffsize += (sz * el.count);
|
||||
}
|
||||
char* buffer = new char[newbuffsize];
|
||||
// Avoid complains from valgrind (i'm not really sure why this is needed, but, beside the
|
||||
@@ -85,25 +88,29 @@ void G4VUserMPIrunMerger::Send(const unsigned int destination)
|
||||
outputBuffer, outputBufferSize, &outputBufferPosition, COMM_G4COMMAND_);
|
||||
}
|
||||
assert(outputBufferSize == outputBufferPosition);
|
||||
COMM_G4COMMAND_.Send(outputBuffer, outputBufferSize, MPI::PACKED, destination,
|
||||
G4MPImanager::kTAG_RUN);
|
||||
MPI_Send(outputBuffer, outputBufferSize, MPI_PACKED, destination, G4MPImanager::kTAG_RUN,
|
||||
COMM_G4COMMAND_);
|
||||
bytesSent += outputBufferSize;
|
||||
DMSG(2, "G4VUserMPIrunMerger::Send() : Done ");
|
||||
}
|
||||
|
||||
void G4VUserMPIrunMerger::Receive(const unsigned int source)
|
||||
{
|
||||
const MPI::Intracomm* parentComm = G4MPImanager::GetManager()->GetComm();
|
||||
DMSG(1, "G4VUserMPIrunMerger::Receive(...) , this rank : " << parentComm->Get_rank()
|
||||
const MPI_Comm* parentComm = G4MPImanager::GetManager()->GetComm();
|
||||
int rank;
|
||||
MPI_Comm_rank(*parentComm, &rank);
|
||||
DMSG(1, "G4VUserMPIrunMerger::Receive(...) , this rank : " << rank
|
||||
<< " and receiving from : " << source);
|
||||
// DestroyBuffer();
|
||||
// Receive from all but one
|
||||
// for (G4int rank = 0; rank < commSize-1; ++rank)
|
||||
//{
|
||||
MPI::Status status;
|
||||
COMM_G4COMMAND_.Probe(source, G4MPImanager::kTAG_RUN, status);
|
||||
MPI_Status status;
|
||||
MPI_Probe(source, G4MPImanager::kTAG_RUN, COMM_G4COMMAND_, &status);
|
||||
// const G4int source = status.Get_source();
|
||||
const G4int newbuffsize = status.Get_count(MPI::PACKED);
|
||||
int nbs;
|
||||
MPI_Get_count(&status, MPI_PACKED, &nbs);
|
||||
const G4int newbuffsize = nbs;
|
||||
DMSG(2, "Preparing to receive buffer of size: " << newbuffsize);
|
||||
char* buffer = outputBuffer;
|
||||
if (newbuffsize > outputBufferSize) {
|
||||
@@ -117,7 +124,8 @@ void G4VUserMPIrunMerger::Receive(const unsigned int source)
|
||||
ownsBuffer = true;
|
||||
}
|
||||
SetupOutputBuffer(buffer, newbuffsize, 0);
|
||||
COMM_G4COMMAND_.Recv(buffer, newbuffsize, MPI::PACKED, source, G4MPImanager::kTAG_RUN, status);
|
||||
MPI_Recv(buffer, newbuffsize, MPI_PACKED, source, G4MPImanager::kTAG_RUN, COMM_G4COMMAND_,
|
||||
&status);
|
||||
DMSG(3, "Buffer Size: " << outputBufferSize << " bytes at: " << (void*)outputBuffer);
|
||||
output_userdata.clear();
|
||||
// User code, if implemented will return the concrete G4Run class
|
||||
@@ -125,7 +133,7 @@ void G4VUserMPIrunMerger::Receive(const unsigned int source)
|
||||
if (aNewRun == nullptr) aNewRun = new G4Run;
|
||||
// Add number of events counter
|
||||
G4int nevets = 0;
|
||||
OutputUserData(&nevets, MPI::INT, 1);
|
||||
OutputUserData(&nevets, MPI_INT, 1);
|
||||
// now userdata contains all data references, do the real unpacking
|
||||
for (const registered_data& el : output_userdata) {
|
||||
MPI_Unpack(outputBuffer, outputBufferSize, &outputBufferPosition, el.p_data, el.count, el.dt,
|
||||
@@ -147,8 +155,9 @@ void G4VUserMPIrunMerger::Merge()
|
||||
// G4cout << "G4VUserMPIrunMerger::Merge called" << G4endl;
|
||||
|
||||
DMSG(0, "G4VUserMPIrunMerger::Merge called");
|
||||
const MPI::Intracomm* parentComm = G4MPImanager::GetManager()->GetComm();
|
||||
const unsigned int myrank = parentComm->Get_rank();
|
||||
const MPI_Comm* parentComm = G4MPImanager::GetManager()->GetComm();
|
||||
G4int myrank;
|
||||
MPI_Comm_rank(*parentComm, &myrank);
|
||||
commSize = G4MPImanager::GetManager()->GetActiveSize();
|
||||
// do not include extra worker in this communication
|
||||
|
||||
@@ -156,17 +165,19 @@ void G4VUserMPIrunMerger::Merge()
|
||||
DMSG(1, "Comm world size is 1, nothing to do");
|
||||
return;
|
||||
}
|
||||
COMM_G4COMMAND_ = parentComm->Dup();
|
||||
MPI_Comm_dup(*parentComm, &COMM_G4COMMAND_);
|
||||
bytesSent = 0;
|
||||
const G4double sttime = MPI::Wtime();
|
||||
const G4double sttime = MPI_Wtime();
|
||||
|
||||
// Use G4MPIutils to optimize communications between ranks
|
||||
typedef std::function<void(unsigned int)> handler_t;
|
||||
using std::placeholders::_1;
|
||||
handler_t sender = std::bind(&G4VUserMPIrunMerger::Send, this, _1);
|
||||
handler_t receiver = std::bind(&G4VUserMPIrunMerger::Receive, this, _1);
|
||||
std::function<void(void)> barrier = std::bind(&MPI::Intracomm::Barrier, &COMM_G4COMMAND_);
|
||||
// G4cout << "go to G4mpi::Merge" << G4endl;
|
||||
std::function<void(void)> barrier = [this]() {
|
||||
MPI_Barrier(COMM_G4COMMAND_);
|
||||
};
|
||||
// G4cout << "go to G4mpi::Merge" << G4endl;i
|
||||
G4mpi::Merge(sender, receiver, barrier, commSize, myrank);
|
||||
|
||||
// OLD Style p2p communications
|
||||
@@ -183,9 +194,9 @@ void G4VUserMPIrunMerger::Merge()
|
||||
}
|
||||
}
|
||||
*/
|
||||
const G4double elapsed = MPI::Wtime() - sttime;
|
||||
const G4double elapsed = MPI_Wtime() - sttime;
|
||||
long total = 0;
|
||||
COMM_G4COMMAND_.Reduce(&bytesSent, &total, 1, MPI::LONG, MPI::SUM, destinationRank);
|
||||
MPI_Reduce(&bytesSent, &total, 1, MPI_LONG, MPI_SUM, destinationRank, COMM_G4COMMAND_);
|
||||
if (verbose > 0 && myrank == destinationRank) {
|
||||
// Collect from ranks how much data was sent around
|
||||
G4cout << "G4VUserMPIrunMerger::Merge() - data transfer performances: "
|
||||
@@ -194,6 +205,6 @@ void G4VUserMPIrunMerger::Merge()
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
COMM_G4COMMAND_.Free();
|
||||
MPI_Comm_free(&COMM_G4COMMAND_);
|
||||
DMSG(0, "G4VUserMPIrunMerger::Merge done");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user