Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • irmb/VirtualFluids
1 result
Show changes
vf_add_library(NAME mpi PUBLIC_LINK logger PRIVATE_LINK MPI::MPI_CXX basics)
vf_add_library(PUBLIC_LINK logger MPI::MPI_CXX basics)
if(MSVC)
target_link_libraries(parallel PRIVATE ws2_32)
endif()
......@@ -34,7 +34,7 @@
#include "Communicator.h"
#include <basics/utilities/UbException.h>
namespace vf::mpi
namespace vf::parallel
{
std::mutex Communicator::instantiation_mutex = std::mutex();
std::shared_ptr<Communicator> Communicator::instance = std::shared_ptr<Communicator>();
......
......@@ -34,43 +34,43 @@
#ifndef MPI_COMMUNICATOR_H
#define MPI_COMMUNICATOR_H
#include <string>
#include <vector>
#include <memory>
#include <sstream>
#include <mutex>
#include <sstream>
#include <string>
#include <vector>
#include <basics/DataTypes.h>
namespace vf::mpi
namespace vf::parallel
{
//! \brief An abstract class for communication between processes in parallel computation
class Communicator
{
public:
Communicator(const Communicator&) = delete;
Communicator & operator=(const Communicator& rhs) = delete;
Communicator(const Communicator &) = delete;
Communicator &operator=(const Communicator &rhs) = delete;
static std::shared_ptr<Communicator> getInstance();
virtual ~Communicator() = default;
virtual int getBundleID() = 0;
virtual int getNumberOfBundles() = 0;
virtual int getProcessID() = 0;
virtual int getProcessID(int bundle, int rank) = 0;
virtual int getNumberOfProcesses() = 0;
virtual bool isRoot() = 0;
virtual void *getNativeCommunicator() = 0;
virtual int getBundleID() const = 0;
virtual int getNumberOfBundles() const = 0;
virtual int getProcessID() const = 0;
virtual int getProcessID(int bundle, int rank) const = 0;
virtual bool isRoot() const = 0;
virtual void *getNativeCommunicator() = 0;
virtual void sendSerializedObject(std::stringstream &ss, int target) = 0;
virtual void receiveSerializedObject(std::stringstream &ss, int source) = 0;
virtual int getRoot() = 0;
virtual int getBundleRoot() = 0;
virtual int getProcessRoot() = 0;
virtual int getNumberOfProcessesInBundle(int bundle) = 0;
virtual void barrier() = 0;
virtual void abort(int errorcode) = 0;
virtual int getRoot() const = 0;
virtual int getBundleRoot() const = 0;
virtual int getProcessRoot() const = 0;
virtual int getNumberOfProcessesInBundle(int bundle) const = 0;
virtual void barrier() = 0;
virtual void abort(int errorcode) = 0;
virtual std::vector<std::string> gather(const std::string &str) = 0;
virtual std::vector<int> gather(std::vector<int> &values) = 0;
......@@ -92,6 +92,20 @@ public:
virtual void broadcast(std::vector<double> &values) = 0;
virtual void broadcast(std::vector<long int> &values) = 0;
virtual void receiveSend(uint *buffer_receive, int size_buffer_recv, int neighbor_rank_recv, uint *buffer_send,
int size_buffer_send, int neighbor_rank_send) const = 0;
virtual int getNumberOfProcesses() const = 0;
virtual void send(real *sbuf, int count_s, int nb_rank) const = 0;
virtual double reduceSum(double quantityPerProcess) const = 0;
virtual int mapCudaDevicesOnHosts(const std::vector<unsigned int> &devices, int numberOfDevices) const = 0;
virtual void receiveSend(real *buffer_send, int size_buffer_send, real *buffer_receive, int size_buffer_recv,
int neighbor_rank) const = 0;
virtual void receiveNonBlocking(real *rbuf, int count_r, int sourceRank) = 0;
virtual void sendNonBlocking(real *sbuf, int count_s, int destinationRank) = 0;
virtual void send(real *sbuf, int count_s, int destinationRank) = 0;
virtual void waitAll() = 0;
virtual void resetRequests() = 0;
protected:
Communicator() = default;
......
#if defined VF_MPI
#if defined (_WIN32) || defined (_WIN64)
#include <Winsock2.h>
#elif defined (__unix__)
#include <unistd.h>
#endif
#include "MPICommunicator.h"
#include <mpi.h>
#include <sstream>
#include <logger/Logger.h>
using namespace std;
namespace vf::mpi
namespace vf::parallel
{
std::shared_ptr<Communicator> MPICommunicator::getInstance()
{
std::lock_guard<std::mutex> myLock(instantiation_mutex);
if (!instance){
if (!instance) {
instance = std::shared_ptr<MPICommunicator>(new MPICommunicator);
}
return instance;
......@@ -22,13 +31,11 @@ MPICommunicator::MPICommunicator()
// proof if MPI is initialized
int mpiInitialized = 0; // false
MPI_Initialized(&mpiInitialized);
if (!mpiInitialized) {
if (mpiInitialized == 0) {
MPI_Init(NULL, NULL);
// MPI_Init_thread(NULL, NULL, MPI_THREAD_FUNNELED, NULL);
}
MPI_Comm_rank(MPI_COMM_WORLD, &PID);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
// numprocs = 1000;
comm = MPI_COMM_WORLD;
root = 0;
}
......@@ -38,9 +45,8 @@ MPICommunicator::~MPICommunicator()
// proof if MPI is finalized
int _mpiFinalized = 0; // false
MPI_Finalized(&_mpiFinalized);
if (!_mpiFinalized) {
if (_mpiFinalized == 0) {
MPI_Finalize();
// UBLOG(logINFO, "MPI_Finalize()");
}
}
//////////////////////////////////////////////////////////////////////////
......@@ -88,27 +94,27 @@ std::vector<unsigned long long> MPICommunicator::gather(std::vector<unsigned lon
return gather<unsigned long long>(values);
}
//////////////////////////////////////////////////////////////////////////
int MPICommunicator::getProcessID() { return PID; }
int MPICommunicator::getProcessID() const { return PID; }
//////////////////////////////////////////////////////////////////////////
int MPICommunicator::getProcessID(int /*bundle*/, int /*rank*/) { return PID; }
int MPICommunicator::getProcessID(int /*bundle*/, int /*rank*/) const { return PID; }
//////////////////////////////////////////////////////////////////////////
int MPICommunicator::getNumberOfProcesses() { return numprocs; }
int MPICommunicator::getNumberOfProcesses() const { return numprocs; }
//////////////////////////////////////////////////////////////////////////
void *MPICommunicator::getNativeCommunicator() { return &comm; }
//////////////////////////////////////////////////////////////////////////
int MPICommunicator::getBundleID() { return 0; }
int MPICommunicator::getBundleID() const { return 0; }
//////////////////////////////////////////////////////////////////////////
int MPICommunicator::getNumberOfBundles() { return 1; }
int MPICommunicator::getNumberOfBundles() const { return 1; }
//////////////////////////////////////////////////////////////////////////
int MPICommunicator::getRoot() { return root; }
int MPICommunicator::getRoot() const { return root; }
//////////////////////////////////////////////////////////////////////////
int MPICommunicator::getBundleRoot() { return 0; }
int MPICommunicator::getBundleRoot() const { return 0; }
//////////////////////////////////////////////////////////////////////////
int MPICommunicator::getProcessRoot() { return 0; }
int MPICommunicator::getProcessRoot() const { return 0; }
//////////////////////////////////////////////////////////////////////////
int MPICommunicator::getNumberOfProcessesInBundle(int /*bundle*/) { return numprocs; }
int MPICommunicator::getNumberOfProcessesInBundle(int /*bundle*/) const { return numprocs; }
//////////////////////////////////////////////////////////////////////////
bool MPICommunicator::isRoot() { return PID == root; }
bool MPICommunicator::isRoot() const { return PID == root; }
//////////////////////////////////////////////////////////////////////////
void MPICommunicator::sendSerializedObject(std::stringstream &ss, int target)
{
......@@ -169,6 +175,120 @@ void MPICommunicator::broadcast(double &value) { broadcast<double>(value); }
//////////////////////////////////////////////////////////////////////////
void MPICommunicator::broadcast(long int &value) { broadcast<long int>(value); }
void MPICommunicator::receiveSend(uint *buffer_receive, int size_buffer_recv,
int neighbor_rank_recv, uint *buffer_send, int size_buffer_send,
int neighbor_rank_send) const
{
MPI_Request recv_request;
MPI_Irecv(buffer_receive, size_buffer_recv, MPI_UNSIGNED, neighbor_rank_recv, 0, comm,
&recv_request);
// printf("receive_send PID: %i, nbRev: nb_rank_recv: %i", this->getPID(), nb_rank_r);
// fflush(stdout);
MPI_Send(buffer_send, size_buffer_send, MPI_UNSIGNED, neighbor_rank_send, 0, comm);
// printf("receive_send PID: %i, sendUintGPU: nb_rank_send: %i", this->getPID(), nb_rank_s);
// fflush(stdout);
MPI_Wait(&recv_request, MPI_STATUSES_IGNORE); // TODO: Do we have a benefit here or could we simply do a blocking receiv.
}
void MPICommunicator::receiveSend(real *buffer_send, int size_buffer_send, real *buffer_receive, int size_buffer_recv,
int neighbor_rank) const
{
MPI_Send(buffer_send, size_buffer_send, VF_MPI_REAL, neighbor_rank, 0, comm);
MPI_Recv(buffer_receive, size_buffer_recv, VF_MPI_REAL, neighbor_rank, 0, comm, MPI_STATUS_IGNORE);
}
void MPICommunicator::send(real *sbuf, int count_s, int nb_rank) const
{
MPI_Send(sbuf, count_s, VF_MPI_REAL, nb_rank, 0, comm);
}
double MPICommunicator::reduceSum(double quantityPerProcess) const
{
double *buffer_send = &quantityPerProcess;
double *buffer_recv = (double *)malloc(sizeof(double));
MPI_Reduce(buffer_send, buffer_recv, 1, MPI_DOUBLE, MPI_SUM, 0, comm);
return *buffer_recv;
}
int MPICommunicator::mapCudaDevicesOnHosts(const std::vector<unsigned int> &devices, int numberOfDevices) const
{
int device = -1;
char *host = (char *)malloc(sizeof(char) * getNumberOfProcesses() * 255);
unsigned int *map = (unsigned int *)malloc(sizeof(unsigned int) * getNumberOfProcesses());
char hostname[255];
gethostname(hostname, 254);
hostname[254] = 0;
MPI_Gather(hostname, 255, MPI_BYTE, host, 255, MPI_BYTE, 0, MPI_COMM_WORLD);
int i, j;
if (isRoot()) {
for (i = 0; i < getNumberOfProcesses(); i++) {
int counter = 0;
for (j = 0; j < i; j++) {
if (strcmp(&host[i * 255], &host[j * 255]) == 0)
counter++;
}
if (counter >= numberOfDevices) {
VF_LOG_CRITICAL("More processes than GPUs!");
exit(1);
}
map[i] = devices[counter];
}
}
MPI_Scatter(map, 1, MPI_UNSIGNED, &device, 1, MPI_UNSIGNED, 0, MPI_COMM_WORLD);
VF_LOG_INFO("Rank: {} runs on host: {} with GPU: {}", getProcessID(), hostname, device);
free(map);
free(host);
return device;
}
void MPICommunicator::receiveNonBlocking(real *rbuf, int count_r, int sourceRank)
{
// printf("\n Start Recv Rank: %d, neighbor Rank: %d, request = %d \n", PID, nb_rank, (int)requestGPU.size());
// fflush(stdout);
MPI_Request request;
MPI_Irecv(rbuf, count_r, VF_MPI_REAL, sourceRank, 0, comm, &request);
requests.push_back(request);
// printf("\n End Recv - Rank: %d , neighbor Rank: %d \n", PID, nb_rank);
// fflush(stdout);
}
void MPICommunicator::sendNonBlocking(real *sbuf, int count_s, int destinationRank)
{
// printf("\n Start Send Rank: %d, neighbor Rank: %d, request = %d \n", PID, nb_rank, (int)requestGPU.size());
// fflush(stdout);
MPI_Request request;
MPI_Isend(sbuf, count_s, VF_MPI_REAL, destinationRank, 0, comm, &request);
requests.push_back(request);
// printf("\n End Send - Rank: %d , neighbor Rank: %d \n", PID, nb_rank);
// fflush(stdout);
}
void MPICommunicator::send(real *sbuf, int count_s, int destinationRank)
{
MPI_Send(sbuf, count_s, VF_MPI_REAL, destinationRank, 0, comm);
}
void MPICommunicator::waitAll()
{
MPI_Waitall((int)requests.size(), requests.data(), MPI_STATUSES_IGNORE);
}
void MPICommunicator::resetRequests()
{
requests.clear();
}
}
#endif
\ No newline at end of file
#endif
......@@ -4,14 +4,22 @@
#define MPI_MPICOMMUNICATOR_H
#include "Communicator.h"
#include <PointerDefinitions.h>
#include <basics/PointerDefinitions.h>
#include <basics/utilities/UbException.h>
#include <basics/utilities/UbLogger.h>
#include <mpi.h>
#include <string>
#include <vector>
namespace vf::mpi
//////////////////////////////////
#ifdef VF_DOUBLE_ACCURACY
#define VF_MPI_REAL MPI_DOUBLE
#else
#define VF_MPI_REAL MPI_FLOAT
#endif
//////////////////////////////////
namespace vf::parallel
{
//! \brief A class uses MPI library to communication.
......@@ -25,17 +33,17 @@ public:
~MPICommunicator() override;
static std::shared_ptr<Communicator> getInstance();
int getBundleID() override;
int getNumberOfBundles() override;
int getProcessID() override;
int getProcessID(int bundle, int rank) override;
int getNumberOfProcesses() override;
int getBundleID() const override;
int getNumberOfBundles() const override;
int getProcessID() const override;
int getProcessID(int bundle, int rank) const override;
int getNumberOfProcesses() const override;
void *getNativeCommunicator() override;
int getRoot() override;
int getBundleRoot() override;
int getProcessRoot() override;
int getNumberOfProcessesInBundle(int bundle) override;
bool isRoot() override;
int getRoot() const override;
int getBundleRoot() const override;
int getProcessRoot() const override;
int getNumberOfProcessesInBundle(int bundle) const override;
bool isRoot() const override;
void abort(int errorcode) override;
void sendSerializedObject(std::stringstream &ss, int target) override;
......@@ -75,12 +83,30 @@ public:
template <class T>
void broadcast(T &value);
void receiveSend(uint *buffer_receive, int size_buffer_recv, int neighbor_rank_recv, uint *buffer_send,
int size_buffer_send, int neighbor_rank_send) const override;
void send(real *sbuf, int count_s, int nb_rank) const override;
double reduceSum(double quantityPerProcess) const override;
int mapCudaDevicesOnHosts(const std::vector<unsigned int> &devices, int numberOfDevices) const override;
void receiveSend(real *buffer_send, int size_buffer_send, real *buffer_receive, int size_buffer_recv,
int neighbor_rank) const override;
void receiveNonBlocking(real *rbuf, int count_r, int sourceRank) override;
void sendNonBlocking(real *sbuf, int count_s, int destinationRank) override;
void send(real *sbuf, int count_s, int destinationRank) override;
void waitAll() override;
void resetRequests() override;
private:
MPICommunicator();
int numprocs, PID;
MPI_Comm comm;
int root;
std::vector<MPI_Request> requests;
};
//////////////////////////////////////////////////////////////////////////
......@@ -96,6 +122,8 @@ std::vector<T> MPICommunicator::gather(std::vector<T> &values)
mpiDataType = MPI_INT;
else if ((std::string) typeid(T).name() == (std::string) typeid(unsigned long long).name())
mpiDataType = MPI_UNSIGNED_LONG_LONG;
else if ((std::string) typeid(T).name() == (std::string) typeid(char).name())
mpiDataType = MPI_CHAR;
else
throw UbException(UB_EXARGS, "no MpiDataType for T" + (std::string) typeid(T).name());
......@@ -209,6 +237,7 @@ void MPICommunicator::broadcast(T &value)
}
//////////////////////////////////////////////////////////////////////////
#endif
}
......
......@@ -33,65 +33,185 @@
#include "NullCommunicator.h"
namespace vf::mpi
#include <memory>
namespace vf::parallel
{
std::shared_ptr<Communicator> NullCommunicator::getInstance()
{
std::lock_guard<std::mutex> myLock(instantiation_mutex);
if (!instance){
instance = std::shared_ptr<NullCommunicator>(new NullCommunicator);
}
return instance;
std::shared_ptr<Communicator> NullCommunicator::getInstance()
{
std::lock_guard<std::mutex> myLock(instantiation_mutex);
if (!instance) {
instance = std::make_shared<NullCommunicator>();
}
//////////////////////////////////////////////////////////////////////////
int NullCommunicator::getBundleID() { return 0; }
//////////////////////////////////////////////////////////////////////////
int NullCommunicator::getNumberOfBundles() { return 0; }
//////////////////////////////////////////////////////////////////////////
int NullCommunicator::getProcessID() { return 0; }
//////////////////////////////////////////////////////////////////////////
int NullCommunicator::getNumberOfProcesses() { return 0; }
//////////////////////////////////////////////////////////////////////////
void *NullCommunicator::getNativeCommunicator() { return NULL; }
//////////////////////////////////////////////////////////////////////////
int NullCommunicator::getRoot() { return 0; }
//////////////////////////////////////////////////////////////////////////
int NullCommunicator::getBundleRoot() { return 0; }
//////////////////////////////////////////////////////////////////////////
int NullCommunicator::getProcessRoot() { return 0; }
//////////////////////////////////////////////////////////////////////////
std::vector<std::string> NullCommunicator::gather(const std::string & /*str*/) { return std::vector<std::string>(); }
//////////////////////////////////////////////////////////////////////////
void NullCommunicator::sendSerializedObject(std::stringstream &ss, int target) {}
//////////////////////////////////////////////////////////////////////////
void NullCommunicator::receiveSerializedObject(std::stringstream &ss, int source) {}
int NullCommunicator::getProcessID(int bundle, int rank) { return 0; }
bool NullCommunicator::isRoot() {return true; }
int NullCommunicator::getNumberOfProcessesInBundle(int bundle) {return 0;}
void NullCommunicator::barrier() {}
void NullCommunicator::abort(int errorcode) {}
std::vector<int> NullCommunicator::gather(std::vector<int> &values){ return std::vector<int>(); }
std::vector<float> NullCommunicator::gather(std::vector<float> &values){ return std::vector<float>(); }
std::vector<double> NullCommunicator::gather(std::vector<double> &values){ return std::vector<double>(); }
std::vector<unsigned long long> NullCommunicator::gather(std::vector<unsigned long long> &values){ return std::vector<unsigned long long>(); }
void NullCommunicator::allGather(std::vector<int> &svalues, std::vector<int> &rvalues){ }
void NullCommunicator::allGather(std::vector<float> &svalues, std::vector<float> &rvalues){ }
void NullCommunicator::allGather(std::vector<double> &svalues, std::vector<double> &rvalues){ }
void NullCommunicator::allGather(std::vector<unsigned long long> &svalues, std::vector<unsigned long long> &rvalues){ }
void NullCommunicator::broadcast(int &value){ }
void NullCommunicator::broadcast(float &value){ }
void NullCommunicator::broadcast(double &value){ }
void NullCommunicator::broadcast(long int &value){ }
void NullCommunicator::broadcast(std::vector<int> &values){ }
void NullCommunicator::broadcast(std::vector<float> &values){ }
void NullCommunicator::broadcast(std::vector<double> &values){ }
void NullCommunicator::broadcast(std::vector<long int> &values){ }
return instance;
}
//////////////////////////////////////////////////////////////////////////
int NullCommunicator::getBundleID() const
{
return 0;
}
//////////////////////////////////////////////////////////////////////////
int NullCommunicator::getNumberOfBundles() const
{
return 0;
}
//////////////////////////////////////////////////////////////////////////
int NullCommunicator::getProcessID() const
{
return 0;
}
//////////////////////////////////////////////////////////////////////////
int NullCommunicator::getNumberOfProcesses() const
{
return 1;
}
//////////////////////////////////////////////////////////////////////////
void *NullCommunicator::getNativeCommunicator()
{
return NULL;
}
//////////////////////////////////////////////////////////////////////////
int NullCommunicator::getRoot() const
{
return 0;
}
//////////////////////////////////////////////////////////////////////////
int NullCommunicator::getBundleRoot() const
{
return 0;
}
//////////////////////////////////////////////////////////////////////////
int NullCommunicator::getProcessRoot() const
{
return 0;
}
//////////////////////////////////////////////////////////////////////////
std::vector<std::string> NullCommunicator::gather(const std::string & /*str*/)
{
return {};
}
//////////////////////////////////////////////////////////////////////////
void NullCommunicator::sendSerializedObject(std::stringstream &stream, int target)
{
}
//////////////////////////////////////////////////////////////////////////
void NullCommunicator::receiveSerializedObject(std::stringstream &stream, int source)
{
}
int NullCommunicator::getProcessID(int bundle, int rank) const
{
return 0;
}
bool NullCommunicator::isRoot() const
{
return true;
}
int NullCommunicator::getNumberOfProcessesInBundle(int bundle) const
{
return 0;
}
void NullCommunicator::barrier()
{
}
void NullCommunicator::abort(int errorcode)
{
}
std::vector<int> NullCommunicator::gather(std::vector<int> &values)
{
return {};
}
std::vector<float> NullCommunicator::gather(std::vector<float> &values)
{
return {};
}
std::vector<double> NullCommunicator::gather(std::vector<double> &values)
{
return {};
}
std::vector<unsigned long long> NullCommunicator::gather(std::vector<unsigned long long> &values)
{
return {};
}
void NullCommunicator::allGather(std::vector<int> &svalues, std::vector<int> &rvalues)
{
}
void NullCommunicator::allGather(std::vector<float> &svalues, std::vector<float> &rvalues)
{
}
void NullCommunicator::allGather(std::vector<double> &svalues, std::vector<double> &rvalues)
{
}
void NullCommunicator::allGather(std::vector<unsigned long long> &svalues, std::vector<unsigned long long> &rvalues)
{
}
void NullCommunicator::broadcast(int &value)
{
}
void NullCommunicator::broadcast(float &value)
{
}
void NullCommunicator::broadcast(double &value)
{
}
void NullCommunicator::broadcast(long int &value)
{
}
void NullCommunicator::broadcast(std::vector<int> &values)
{
}
void NullCommunicator::broadcast(std::vector<float> &values)
{
}
void NullCommunicator::broadcast(std::vector<double> &values)
{
}
void NullCommunicator::broadcast(std::vector<long int> &values)
{
}
void NullCommunicator::receiveSend(uint *buffer_receive, int size_buffer_recv, int neighbor_rank_recv, uint *buffer_send,
int size_buffer_send, int neighbor_rank_send) const
{
}
void NullCommunicator::send(real *sbuf, int count_s, int nb_rank) const {};
double NullCommunicator::reduceSum(double /*quantityPerProcess*/) const
{
return 0.0;
};
int NullCommunicator::mapCudaDevicesOnHosts(const std::vector<unsigned int> &devices, int numberOfDevices) const
{
return 0;
}
void NullCommunicator::receiveSend(real *buffer_send, int size_buffer_send, real *buffer_receive, int size_buffer_recv,
int neighbor_rank) const
{
}
void NullCommunicator::receiveNonBlocking(real *rbuf, int count_r, int sourceRank)
{
}
void NullCommunicator::sendNonBlocking(real *sbuf, int count_s, int destinationRank)
{
}
void NullCommunicator::send(real *sbuf, int count_s, int destinationRank)
{
}
void NullCommunicator::waitAll()
{
}
void NullCommunicator::resetRequests()
{
}
} // namespace vf::parallel
......@@ -36,7 +36,7 @@
#include "Communicator.h"
namespace vf::mpi
namespace vf::parallel
{
//! \brief A class implements Communicator for shared memory.
......@@ -46,45 +46,62 @@ class NullCommunicator : public Communicator
public:
static std::shared_ptr<Communicator> getInstance();
int getBundleID();
int getNumberOfBundles();
int getProcessID();
int getProcessID(int bundle, int rank);
int getNumberOfProcesses();
bool isRoot();
void *getNativeCommunicator();
void sendSerializedObject(std::stringstream &ss, int target);
void receiveSerializedObject(std::stringstream &ss, int source);
int getRoot();
int getBundleRoot();
int getProcessRoot();
int getNumberOfProcessesInBundle(int bundle);
void barrier();
void abort(int errorcode);
std::vector<std::string> gather(const std::string &str);
std::vector<int> gather(std::vector<int> &values);
std::vector<float> gather(std::vector<float> &values);
std::vector<double> gather(std::vector<double> &values);
std::vector<unsigned long long> gather(std::vector<unsigned long long> &values);
void allGather(std::vector<int> &svalues, std::vector<int> &rvalues);
void allGather(std::vector<float> &svalues, std::vector<float> &rvalues);
void allGather(std::vector<double> &svalues, std::vector<double> &rvalues);
void allGather(std::vector<unsigned long long> &svalues, std::vector<unsigned long long> &rvalues);
void broadcast(int &value);
void broadcast(float &value);
void broadcast(double &value);
void broadcast(long int &value);
void broadcast(std::vector<int> &values);
void broadcast(std::vector<float> &values);
void broadcast(std::vector<double> &values);
void broadcast(std::vector<long int> &values);
int getBundleID() const override;
int getNumberOfBundles() const override;
int getProcessID() const override;
int getProcessID(int bundle, int rank) const override;
int getNumberOfProcesses() const override;
bool isRoot() const override;
void *getNativeCommunicator() override;
void sendSerializedObject(std::stringstream &stream, int target) override;
void receiveSerializedObject(std::stringstream &stream, int source) override;
int getRoot() const override;
int getBundleRoot() const override;
int getProcessRoot() const override;
int getNumberOfProcessesInBundle(int bundle) const override;
void barrier() override;
void abort(int errorcode) override;
std::vector<std::string> gather(const std::string &str) override;
std::vector<int> gather(std::vector<int> &values) override;
std::vector<float> gather(std::vector<float> &values) override;
std::vector<double> gather(std::vector<double> &values) override;
std::vector<unsigned long long> gather(std::vector<unsigned long long> &values) override;
void allGather(std::vector<int> &svalues, std::vector<int> &rvalues) override;
void allGather(std::vector<float> &svalues, std::vector<float> &rvalues) override;
void allGather(std::vector<double> &svalues, std::vector<double> &rvalues) override;
void allGather(std::vector<unsigned long long> &svalues, std::vector<unsigned long long> &rvalues) override;
void broadcast(int &value) override;
void broadcast(float &value) override;
void broadcast(double &value) override;
void broadcast(long int &value) override;
void broadcast(std::vector<int> &values) override;
void broadcast(std::vector<float> &values) override;
void broadcast(std::vector<double> &values) override;
void broadcast(std::vector<long int> &values) override;
void receiveSend(uint *buffer_receive, int size_buffer_recv, int neighbor_rank_recv, uint *buffer_send,
int size_buffer_send, int neighbor_rank_send) const override;
void send(real *sbuf, int count_s, int nb_rank) const override;
double reduceSum(double quantityPerProcess) const override;
int mapCudaDevicesOnHosts(const std::vector<unsigned int> &devices, int numberOfDevices) const override;
void receiveSend(real *buffer_send, int size_buffer_send, real *buffer_receive, int size_buffer_recv,
int neighbor_rank) const override;
void receiveNonBlocking(real *rbuf, int count_r, int sourceRank) override;
void sendNonBlocking(real *sbuf, int count_s, int destinationRank) override;
void send(real *sbuf, int count_s, int destinationRank) override;
void waitAll() override;
void resetRequests() override;
};
}
} // namespace vf::parallel
#endif