Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1297 lines
43 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkMPICommunicator.cxx,v $
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkMPICommunicator.h"
#include "vtkMPIController.h"
#include "vtkMPIGroup.h"
#include "vtkMPIGroup.h"
#include "vtkObjectFactory.h"
#include "vtkToolkits.h"
#include "vtkMPI.h"
vtkCxxRevisionMacro(vtkMPICommunicator, "$Revision: 1.36 $");
vtkStandardNewMacro(vtkMPICommunicator);
vtkCxxSetObjectMacro(vtkMPICommunicator,Group,vtkMPIGroup);
vtkMPICommunicator* vtkMPICommunicator::WorldCommunicator = 0;
class vtkMPICommunicatorOpaqueRequest
{
public:
MPI_Request Handle;
};
vtkMPICommunicatorOpaqueComm::vtkMPICommunicatorOpaqueComm()
{
this->Handle = 0;
}
MPI_Comm* vtkMPICommunicatorOpaqueComm::GetHandle()
{
return this->Handle;
}
//----------------------------------------------------------------------------
// overloaded functions for vtkIdType
#ifdef VTK_HAS_ID_TYPE
# ifdef VTK_USE_64BIT_IDS
MPI_Datatype vtkMPICommunicatorGetMPIType()
{
#if VTK_SIZEOF_LONG == 8
return MPI_LONG;
#elif defined(MPI_LONG_LONG)
return MPI_LONG_LONG;
#elif defined(MPI_LONG_LONG_INT)
// lampi only has MPI_LONG_LONG_INT, not MPI_LONG_LONG
return MPI_LONG_LONG_INT;
#else
vtkGenericWarningMacro("This systems MPI doesnt seem to support 64 bit ids and you have 64 bit IDs turned on. Please contact VTK mailing list.");
return MPI_INT;
#endif
}
# endif
#else
MPI_Datatype vtkMPICommunicatorGetMPIType()
{
return MPI_INT;
}
#endif
//----------------------------------------------------------------------------
template <class T>
int vtkMPICommunicatorSendData(T* data, int length, int sizeoftype,
int remoteProcessId, int tag,
MPI_Datatype datatype, MPI_Comm *Handle,
int useCopy)
{
if (useCopy)
{
int retVal;
char* tmpData = vtkMPICommunicator::Allocate(length*sizeoftype);
memcpy(tmpData, data, length*sizeoftype);
retVal = MPI_Send(tmpData, length, datatype, remoteProcessId, tag,
*(Handle));
vtkMPICommunicator::Free(tmpData);
return retVal;
}
else
{
return MPI_Send(data, length, datatype, remoteProcessId, tag, *(Handle));
}
}
//----------------------------------------------------------------------------
template <class T>
int vtkMPICommunicatorReceiveData(T* data, int length, int sizeoftype,
int remoteProcessId, int tag,
MPI_Datatype datatype, MPI_Comm *Handle,
int useCopy)
{
MPI_Status status;
if (remoteProcessId == vtkMultiProcessController::ANY_SOURCE)
{
remoteProcessId = MPI_ANY_SOURCE;
}
if (useCopy)
{
int retVal;
char* tmpData = vtkMPICommunicator::Allocate(length*sizeoftype);
retVal = MPI_Recv(tmpData, length, datatype, remoteProcessId, tag,
*(Handle), &status);
memcpy(data, tmpData, length*sizeoftype);
vtkMPICommunicator::Free(tmpData);
return retVal;
}
else
{
return MPI_Recv(data, length, datatype, remoteProcessId, tag,
*(Handle), &status);
}
}
//----------------------------------------------------------------------------
template <class T>
int vtkMPICommunicatorNoBlockSendData(T* data, int length,
int remoteProcessId, int tag,
MPI_Datatype datatype,
vtkMPICommunicator::Request& req,
MPI_Comm *Handle)
{
return MPI_Isend(data, length, datatype, remoteProcessId, tag,
*(Handle), &req.Req->Handle);
}
//----------------------------------------------------------------------------
template <class T>
int vtkMPICommunicatorNoBlockReceiveData(T* data, int length,
int remoteProcessId, int tag,
MPI_Datatype datatype,
vtkMPICommunicator::Request& req,
MPI_Comm *Handle)
{
if (remoteProcessId == vtkMultiProcessController::ANY_SOURCE)
{
remoteProcessId = MPI_ANY_SOURCE;
}
return MPI_Irecv(data, length, datatype, remoteProcessId, tag,
*(Handle), &req.Req->Handle);
}
//----------------------------------------------------------------------------
template <class T>
int vtkMPICommunicatorBroadcastData(T* data, int length,
int root, MPI_Datatype datatype,
MPI_Comm *Handle)
{
return MPI_Bcast(data, length, datatype, root, *(Handle));
}
//----------------------------------------------------------------------------
template <class T>
int vtkMPICommunicatorGatherData(T* data, T* to,
int sendlength, int root,
MPI_Datatype datatype,
MPI_Comm *Handle)
{
return MPI_Gather(data, sendlength, datatype, to,
sendlength, datatype, root, *(Handle));
}
//----------------------------------------------------------------------------
template <class T>
int vtkMPICommunicatorGatherVData(T* data, T* to,
int sendlength, int* recvlengths,
int* offsets, int root,
MPI_Datatype datatype,
MPI_Comm *Handle)
{
return MPI_Gatherv(data, sendlength, datatype,
to, recvlengths, offsets, datatype,
root, *(Handle));
}
//----------------------------------------------------------------------------
template <class T>
int vtkMPICommunicatorAllGatherData(T* data, T* to,
int sendlength,
MPI_Datatype datatype,
MPI_Comm *Handle)
{
return MPI_Allgather(data, sendlength, datatype, to,
sendlength, datatype, *(Handle));
}
//----------------------------------------------------------------------------
template <class T>
int vtkMPICommunicatorAllGatherVData(T* data, T* to,
int sendlength, int* recvlengths,
int* offsets,
MPI_Datatype datatype,
MPI_Comm *Handle)
{
return MPI_Allgatherv(data, sendlength, datatype,
to, recvlengths, offsets, datatype,
*(Handle));
}
//----------------------------------------------------------------------------
template <class T>
int vtkMPICommunicatorReduceData(T* data, T* to, int root,
int sendlength, MPI_Datatype datatype,
MPI_Op op, MPI_Comm *Handle)
{
return MPI_Reduce(data, to, sendlength, datatype,
op, root, *(Handle));
}
//----------------------------------------------------------------------------
// Return the world communicator (i.e. MPI_COMM_WORLD).
// Create one if necessary (singleton).
vtkMPICommunicator* vtkMPICommunicator::GetWorldCommunicator()
{
int err, size;
if (vtkMPICommunicator::WorldCommunicator == 0)
{
vtkMPICommunicator* comm = vtkMPICommunicator::New();
vtkMPIGroup* group = vtkMPIGroup::New();
comm->MPIComm->Handle = new MPI_Comm;
*(comm->MPIComm->Handle) = MPI_COMM_WORLD;
comm->SetGroup(group);
group->Delete();
group = NULL;
if ( (err = MPI_Comm_size(MPI_COMM_WORLD, &size)) != MPI_SUCCESS )
{
char *msg = vtkMPIController::ErrorString(err);
vtkGenericWarningMacro("MPI error occured: " << msg);
delete[] msg;
delete comm->MPIComm->Handle;
comm->MPIComm = 0;
comm->Delete();
return 0;
}
comm->Group->Initialize(size);
for(int i=0; i<size; i++)
{
comm->Group->AddProcessId(i);
}
comm->Initialized = 1;
comm->KeepHandleOn();
vtkMPICommunicator::WorldCommunicator = comm;
}
return vtkMPICommunicator::WorldCommunicator;
}
//----------------------------------------------------------------------------
void vtkMPICommunicator::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Group: ";
if (this->Group)
{
os << endl;
this->Group->PrintSelf(os, indent.GetNextIndent());
}
else
{
os << "(none)\n";
}
os << indent << "MPI Communicator handler: " ;
if (this->MPIComm->Handle)
{
os << this->MPIComm->Handle << endl;
}
else
{
os << "(none)\n";
}
os << indent << "Initialized: " << (this->Initialized ? "On\n" : "Off\n");
os << indent << "Keep handle: " << (this->KeepHandle ? "On\n" : "Off\n");
if ( this != vtkMPICommunicator::WorldCommunicator )
{
os << indent << "World communicator: ";
if (vtkMPICommunicator::WorldCommunicator)
{
os << endl;
vtkMPICommunicator::WorldCommunicator->PrintSelf(os, indent.GetNextIndent());
}
else
{
os << "(none)";
}
os << endl;
}
return;
}
//----------------------------------------------------------------------------
vtkMPICommunicator::vtkMPICommunicator()
{
this->MPIComm = new vtkMPICommunicatorOpaqueComm;
this->Group = 0;
this->Initialized = 0;
this->KeepHandle = 0;
}
//----------------------------------------------------------------------------
vtkMPICommunicator::~vtkMPICommunicator()
{
// Free the handle if required and asked for.
if (this->MPIComm)
{
if (this->MPIComm->Handle && !this->KeepHandle )
{
if (*(this->MPIComm->Handle) != MPI_COMM_NULL)
{
MPI_Comm_free(this->MPIComm->Handle);
}
}
delete this->MPIComm->Handle;
delete this->MPIComm;
}
this->SetGroup(0);
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Initialize(vtkMPICommunicator* mpiComm,
vtkMPIGroup* group)
{
if (this->Initialized)
{
return 0;
}
// If mpiComm has been initialized, it is guaranteed (unless
// the MPI calls return an error somewhere) to have valid
// Communicator and Group
if (!mpiComm->Initialized)
{
vtkWarningMacro("The communicator passed has not been initialized!");
return 0;
}
this->KeepHandleOff();
int nProcIds = group->GetNumberOfProcessIds();
// The new group has to be a sub-class
if ( ( nProcIds <= 0) ||
( mpiComm->Group == 0 ) ||
( nProcIds > mpiComm->Group->GetNumberOfProcessIds() ) )
{
vtkWarningMacro("The group or the communicator has "
<< "invalid number of ids.");
return 0;
}
// Select the new processes
int* ranks = new int[nProcIds];
for(int i=0; i<nProcIds; i++)
{
ranks[i] = group->GetProcessId(i);
}
MPI_Group superGroup;
MPI_Group subGroup;
// Get the group from the argument
int err;
if ( (err = MPI_Comm_group(*(mpiComm->MPIComm->Handle), &superGroup))
!= MPI_SUCCESS )
{
delete[] ranks;
MPI_Group_free(&superGroup);
char *msg = vtkMPIController::ErrorString(err);
vtkErrorMacro("MPI error occured: " << msg);
delete[] msg;
return 0;
}
// Create a new group by including the process ids in group
if ( (err = MPI_Group_incl(superGroup, nProcIds, ranks, &subGroup))
!= MPI_SUCCESS )
{
delete[] ranks;
MPI_Group_free(&superGroup);
MPI_Group_free(&subGroup);
char *msg = vtkMPIController::ErrorString(err);
vtkErrorMacro("MPI error occured: " << msg);
delete[] msg;
return 0;
}
delete[] ranks;
MPI_Group_free(&superGroup);
this->MPIComm->Handle = new MPI_Comm;
// Create the communicator from the group
if ( (err = MPI_Comm_create(*(mpiComm->MPIComm->Handle), subGroup,
this->MPIComm->Handle) )
!= MPI_SUCCESS )
{
MPI_Group_free(&subGroup);
delete this->MPIComm->Handle;
this->MPIComm->Handle = 0;
char *msg = vtkMPIController::ErrorString(err);
vtkErrorMacro("MPI error occured: " << msg);
delete[] msg;
return 0;
}
MPI_Group_free(&subGroup);
this->Initialized = 1;
// Store the group so that this communicator can be used
// to create new ones
this->SetGroup(group);
this->Modified();
return 1;
}
//----------------------------------------------------------------------------
// Start the copying process
void vtkMPICommunicator::InitializeCopy(vtkMPICommunicator* source)
{
if(!source)
{
return;
}
this->SetGroup(0);
vtkMPIGroup* group = vtkMPIGroup::New();
this->SetGroup(group);
group->Delete();
group = 0;
this->Group->CopyFrom(source->Group);
if (this->MPIComm->Handle && !this->KeepHandle)
{
MPI_Comm_free(this->MPIComm->Handle);
}
delete this->MPIComm->Handle;
this->MPIComm->Handle = 0;
this->Initialized = source->Initialized;
this->Modified();
}
//----------------------------------------------------------------------------
// Copy the MPI handle
void vtkMPICommunicator::CopyFrom(vtkMPICommunicator* source)
{
this->InitializeCopy(source);
if (source->MPIComm->Handle)
{
this->KeepHandleOn();
this->MPIComm->Handle = new MPI_Comm;
*(this->MPIComm->Handle) = *(source->MPIComm->Handle);
}
}
//----------------------------------------------------------------------------
// Duplicate the MPI handle
void vtkMPICommunicator::Duplicate(vtkMPICommunicator* source)
{
this->InitializeCopy(source);
this->KeepHandleOff();
if (source->MPIComm->Handle)
{
this->MPIComm->Handle = new MPI_Comm;
int err;
if ( (err = MPI_Comm_dup(*(source->MPIComm->Handle), this->MPIComm->Handle))
!= MPI_SUCCESS )
{
char *msg = vtkMPIController::ErrorString(err);
vtkErrorMacro("MPI error occured: " << msg);
delete[] msg;
}
}
}
//----------------------------------------------------------------------------
char* vtkMPICommunicator::Allocate(size_t size)
{
#ifdef MPIPROALLOC
char* ptr;
MPI_Alloc_mem(size, NULL, &ptr);
return ptr;
#else
return new char[size];
#endif
}
//----------------------------------------------------------------------------
void vtkMPICommunicator::Free(char* ptr)
{
#ifdef MPIPROALLOC
MPI_Free_mem(ptr);
#else
delete[] ptr;
#endif
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::CheckForMPIError(int err)
{
if ( err == MPI_SUCCESS )
{
return 1;
}
else
{
char *msg = vtkMPIController::ErrorString(err);
vtkGenericWarningMacro("MPI error occured: " << msg);
delete[] msg;
return 0;
}
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Send(int* data, int length, int remoteProcessId,
int tag)
{
return CheckForMPIError(
vtkMPICommunicatorSendData(data, length,
sizeof(int), remoteProcessId, tag,
MPI_INT, this->MPIComm->Handle,
vtkCommunicator::UseCopy));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Send(unsigned long* data, int length,
int remoteProcessId, int tag)
{
return CheckForMPIError(
vtkMPICommunicatorSendData(data, length,
sizeof(unsigned long), remoteProcessId, tag,
MPI_UNSIGNED_LONG, this->MPIComm->Handle,
vtkCommunicator::UseCopy));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Send(char* data, int length,
int remoteProcessId, int tag)
{
return CheckForMPIError(
vtkMPICommunicatorSendData(data, length,
sizeof(char), remoteProcessId, tag,
MPI_CHAR, this->MPIComm->Handle,
vtkCommunicator::UseCopy));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Send(unsigned char* data, int length,
int remoteProcessId, int tag)
{
return CheckForMPIError(
vtkMPICommunicatorSendData(data, length,
sizeof(unsigned char), remoteProcessId, tag,
MPI_UNSIGNED_CHAR, this->MPIComm->Handle,
vtkCommunicator::UseCopy));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Send(float* data, int length,
int remoteProcessId, int tag)
{
return CheckForMPIError(
vtkMPICommunicatorSendData(data, length,
sizeof(float), remoteProcessId, tag,
MPI_FLOAT, this->MPIComm->Handle,
vtkCommunicator::UseCopy));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Send(double* data, int length,
int remoteProcessId, int tag)
{
return CheckForMPIError(
vtkMPICommunicatorSendData(data, length,
sizeof(double), remoteProcessId, tag,
MPI_DOUBLE, this->MPIComm->Handle,
vtkCommunicator::UseCopy));
}
//----------------------------------------------------------------------------
#ifdef VTK_USE_64BIT_IDS
int vtkMPICommunicator::Send(vtkIdType* data, int length,
int remoteProcessId, int tag)
{
return CheckForMPIError(
vtkMPICommunicatorSendData(data, length,
sizeof(vtkIdType), remoteProcessId, tag,
vtkMPICommunicatorGetMPIType(),
this->MPIComm->Handle, vtkCommunicator::UseCopy));
}
#endif
//----------------------------------------------------------------------------
int vtkMPICommunicator::NoBlockSend(int* data, int length,
int remoteProcessId, int tag,
Request& req)
{
return CheckForMPIError(
vtkMPICommunicatorNoBlockSendData(data,
length, remoteProcessId,
tag, MPI_INT, req, this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::NoBlockSend(unsigned long* data, int length,
int remoteProcessId, int tag,
Request& req)
{
return CheckForMPIError(
vtkMPICommunicatorNoBlockSendData(data,
length, remoteProcessId,
tag, MPI_UNSIGNED_LONG, req,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::NoBlockSend(char* data, int length,
int remoteProcessId, int tag, Request& req)
{
return CheckForMPIError(
vtkMPICommunicatorNoBlockSendData(data,
length, remoteProcessId,
tag, MPI_CHAR, req, this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::NoBlockSend(float* data, int length,
int remoteProcessId, int tag, Request& req)
{
return CheckForMPIError(
vtkMPICommunicatorNoBlockSendData(data,
length, remoteProcessId,
tag, MPI_FLOAT, req,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Receive(int* data, int length,
int remoteProcessId, int tag)
{
return CheckForMPIError(
vtkMPICommunicatorReceiveData(data, length,
sizeof(int), remoteProcessId, tag,
MPI_INT, this->MPIComm->Handle,
vtkCommunicator::UseCopy));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Receive(unsigned long* data, int length,
int remoteProcessId, int tag)
{
return CheckForMPIError(
vtkMPICommunicatorReceiveData(data, length,
sizeof(unsigned long),
remoteProcessId, tag,
MPI_UNSIGNED_LONG, this->MPIComm->Handle,
vtkCommunicator::UseCopy));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Receive(char* data, int length,
int remoteProcessId, int tag)
{
return CheckForMPIError(
vtkMPICommunicatorReceiveData(data, length,
sizeof(char), remoteProcessId, tag,
MPI_CHAR, this->MPIComm->Handle,
vtkCommunicator::UseCopy));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Receive(unsigned char* data, int length,
int remoteProcessId, int tag)
{
return CheckForMPIError(
vtkMPICommunicatorReceiveData(data, length,
sizeof(unsigned char), remoteProcessId,
tag, MPI_UNSIGNED_CHAR, this->MPIComm->Handle,
vtkCommunicator::UseCopy));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Receive(float* data, int length,
int remoteProcessId, int tag)
{
return CheckForMPIError(
vtkMPICommunicatorReceiveData(data, length,
sizeof(float), remoteProcessId, tag,
MPI_FLOAT, this->MPIComm->Handle,
vtkCommunicator::UseCopy));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Receive(double* data, int length,
int remoteProcessId, int tag)
{
return CheckForMPIError(
vtkMPICommunicatorReceiveData(data, length,
sizeof(double), remoteProcessId, tag,
MPI_DOUBLE, this->MPIComm->Handle,
vtkCommunicator::UseCopy));
}
//----------------------------------------------------------------------------
#ifdef VTK_USE_64BIT_IDS
int vtkMPICommunicator::Receive(vtkIdType* data, int length,
int remoteProcessId, int tag)
{
return CheckForMPIError(
vtkMPICommunicatorReceiveData(data, length,
sizeof(vtkIdType), remoteProcessId, tag,
vtkMPICommunicatorGetMPIType(),
this->MPIComm->Handle, vtkCommunicator::UseCopy));
}
#endif
//----------------------------------------------------------------------------
int vtkMPICommunicator::NoBlockReceive(int* data, int length,
int remoteProcessId, int tag,
Request& req)
{
return CheckForMPIError(
vtkMPICommunicatorNoBlockReceiveData(data,
length, remoteProcessId,
tag, MPI_INT, req,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::NoBlockReceive(unsigned long* data, int length,
int remoteProcessId, int tag,
Request& req)
{
return CheckForMPIError(
vtkMPICommunicatorNoBlockReceiveData(data,
length, remoteProcessId,
tag, MPI_UNSIGNED_LONG, req,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::NoBlockReceive(char* data, int length,
int remoteProcessId, int tag,
Request& req)
{
return CheckForMPIError(
vtkMPICommunicatorNoBlockReceiveData(data,
length, remoteProcessId,
tag, MPI_CHAR, req,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::NoBlockReceive(float* data, int length,
int remoteProcessId, int tag,
Request& req)
{
return CheckForMPIError(
vtkMPICommunicatorNoBlockReceiveData(data,
length, remoteProcessId,
tag, MPI_FLOAT, req,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
vtkMPICommunicator::Request::Request()
{
this->Req = new vtkMPICommunicatorOpaqueRequest;
}
//----------------------------------------------------------------------------
vtkMPICommunicator::Request::~Request()
{
delete this->Req;
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Request::Test()
{
MPI_Status status;
int retVal;
int err = MPI_Test(&this->Req->Handle, &retVal, &status);
if ( err == MPI_SUCCESS )
{
return retVal;
}
else
{
char *msg = vtkMPIController::ErrorString(err);
vtkGenericWarningMacro("MPI error occured: " << msg);
delete[] msg;
return 0;
}
}
//----------------------------------------------------------------------------
void vtkMPICommunicator::Request::Wait()
{
MPI_Status status;
int err = MPI_Wait(&this->Req->Handle, &status);
if ( err != MPI_SUCCESS )
{
char *msg = vtkMPIController::ErrorString(err);
vtkGenericWarningMacro("MPI error occured: " << msg);
delete[] msg;
}
}
//----------------------------------------------------------------------------
void vtkMPICommunicator::Request::Cancel()
{
int err = MPI_Cancel(&this->Req->Handle);
if ( err != MPI_SUCCESS )
{
char *msg = vtkMPIController::ErrorString(err);
vtkGenericWarningMacro("MPI error occured: " << msg);
delete[] msg;
}
err = MPI_Request_free(&this->Req->Handle);
if ( err != MPI_SUCCESS )
{
char *msg = vtkMPIController::ErrorString(err);
vtkGenericWarningMacro("MPI error occured: " << msg);
delete[] msg;
}
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Broadcast(int* data, int length, int root)
{
return CheckForMPIError(
vtkMPICommunicatorBroadcastData(data, length, root, MPI_INT,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Broadcast(unsigned long* data, int length, int root)
{
return CheckForMPIError(
vtkMPICommunicatorBroadcastData(data, length, root, MPI_UNSIGNED_LONG,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Broadcast(char* data, int length, int root)
{
return CheckForMPIError(
vtkMPICommunicatorBroadcastData(data, length, root, MPI_CHAR,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Broadcast(float* data, int length, int root)
{
return CheckForMPIError(
vtkMPICommunicatorBroadcastData(data, length, root, MPI_FLOAT,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Broadcast(double* data, int length, int root)
{
return CheckForMPIError(
vtkMPICommunicatorBroadcastData(data, length, root, MPI_DOUBLE,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Gather(int* data, int* to, int length, int root)
{
return CheckForMPIError(
vtkMPICommunicatorGatherData(data, to, length, root, MPI_INT,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Gather(unsigned long* data, unsigned long* to,
int length, int root)
{
return CheckForMPIError(
vtkMPICommunicatorGatherData(data, to, length, root, MPI_UNSIGNED_LONG,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Gather(char* data, char* to, int length, int root)
{
return CheckForMPIError(
vtkMPICommunicatorGatherData(data, to, length, root, MPI_CHAR,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Gather(float* data, float* to, int length, int root)
{
return CheckForMPIError(
vtkMPICommunicatorGatherData(data, to, length, root, MPI_FLOAT,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::Gather(double* data, double* to, int length, int root)
{
return CheckForMPIError(
vtkMPICommunicatorGatherData(data, to, length, root, MPI_DOUBLE,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::GatherV(int* data, int* to,
int sendlength, int* recvlengths,
int* offsets, int root)
{
return CheckForMPIError(
vtkMPICommunicatorGatherVData(data, to,
sendlength, recvlengths, offsets,
root, MPI_INT, this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::GatherV(unsigned long* data, unsigned long* to,
int sendlength, int* recvlengths,
int* offsets, int root)
{
return CheckForMPIError(
vtkMPICommunicatorGatherVData(data, to,
sendlength, recvlengths, offsets,
root, MPI_UNSIGNED_LONG,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::GatherV(char* data, char* to,
int sendlength, int* recvlengths,
int* offsets, int root)
{
return CheckForMPIError(
vtkMPICommunicatorGatherVData(data, to,
sendlength, recvlengths, offsets,
root, MPI_CHAR,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::GatherV(float* data, float* to,
int sendlength, int* recvlengths,
int* offsets, int root)
{
return CheckForMPIError(
vtkMPICommunicatorGatherVData(data, to,
sendlength, recvlengths, offsets,
root, MPI_FLOAT,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::GatherV(double* data, double* to,
int sendlength, int* recvlengths,
int* offsets, int root)
{
return CheckForMPIError(
vtkMPICommunicatorGatherVData(data, to,
sendlength, recvlengths, offsets,
root, MPI_DOUBLE,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::AllGather(int* data, int* to, int length)
{
return CheckForMPIError(
vtkMPICommunicatorAllGatherData(data, to, length, MPI_INT,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::AllGather(unsigned long* data, unsigned long* to,
int length)
{
return CheckForMPIError(
vtkMPICommunicatorAllGatherData(data, to, length, MPI_UNSIGNED_LONG,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::AllGather(char* data, char* to, int length)
{
return CheckForMPIError(
vtkMPICommunicatorAllGatherData(data, to, length, MPI_CHAR,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::AllGather(float* data, float* to, int length)
{
return CheckForMPIError(
vtkMPICommunicatorAllGatherData(data, to, length, MPI_FLOAT,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::AllGather(double* data, double* to, int length)
{
return CheckForMPIError(
vtkMPICommunicatorAllGatherData(data, to, length, MPI_DOUBLE,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::AllGatherV(int* data, int* to,
int sendlength, int* recvlengths,
int* offsets)
{
return CheckForMPIError(
vtkMPICommunicatorAllGatherVData(data, to,
sendlength, recvlengths, offsets,
MPI_INT, this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::AllGatherV(unsigned long* data, unsigned long* to,
int sendlength, int* recvlengths,
int* offsets)
{
return CheckForMPIError(
vtkMPICommunicatorAllGatherVData(data, to,
sendlength, recvlengths, offsets,
MPI_UNSIGNED_LONG,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::AllGatherV(char* data, char* to,
int sendlength, int* recvlengths,
int* offsets)
{
return CheckForMPIError(
vtkMPICommunicatorAllGatherVData(data, to,
sendlength, recvlengths, offsets,
MPI_CHAR,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::AllGatherV(float* data, float* to,
int sendlength, int* recvlengths,
int* offsets)
{
return CheckForMPIError(
vtkMPICommunicatorAllGatherVData(data, to,
sendlength, recvlengths, offsets,
MPI_FLOAT,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::AllGatherV(double* data, double* to,
int sendlength, int* recvlengths,
int* offsets)
{
return CheckForMPIError(
vtkMPICommunicatorAllGatherVData(data, to,
sendlength, recvlengths, offsets,
MPI_DOUBLE,
this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::ReduceMax(int* data, int* to,
int sendlength, int root)
{
return CheckForMPIError(
vtkMPICommunicatorReduceData(data, to,
root, sendlength, MPI_INT,
MPI_MAX, this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::ReduceMax(unsigned long* data, unsigned long* to,
int sendlength, int root)
{
return CheckForMPIError(
vtkMPICommunicatorReduceData(data, to,
root, sendlength, MPI_LONG,
MPI_MAX, this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::ReduceMax(float* data, float* to,
int sendlength, int root)
{
return CheckForMPIError(
vtkMPICommunicatorReduceData(data, to,
root, sendlength, MPI_FLOAT,
MPI_MAX, this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::ReduceMax(double* data, double* to,
int sendlength, int root)
{
return CheckForMPIError(
vtkMPICommunicatorReduceData(data, to,
root, sendlength, MPI_DOUBLE,
MPI_MAX, this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::ReduceMin(int* data, int* to,
int sendlength, int root)
{
return CheckForMPIError(
vtkMPICommunicatorReduceData(data, to,
root, sendlength, MPI_INT,
MPI_MIN, this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::ReduceMin(unsigned long* data, unsigned long* to,
int sendlength, int root)
{
return CheckForMPIError(
vtkMPICommunicatorReduceData(data, to,
root, sendlength, MPI_LONG,
MPI_MIN, this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::ReduceMin(float* data, float* to,
int sendlength, int root)
{
return CheckForMPIError(
vtkMPICommunicatorReduceData(data, to,
root, sendlength, MPI_FLOAT,
MPI_MIN, this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::ReduceMin(double* data, double* to,
int sendlength, int root)
{
return CheckForMPIError(
vtkMPICommunicatorReduceData(data, to,
root, sendlength, MPI_DOUBLE,
MPI_MIN, this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::ReduceSum(int* data, int* to,
int sendlength, int root)
{
return CheckForMPIError(
vtkMPICommunicatorReduceData(data, to,
root, sendlength, MPI_INT,
MPI_SUM, this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::ReduceSum(unsigned long* data, unsigned long* to,
int sendlength, int root)
{
return CheckForMPIError(
vtkMPICommunicatorReduceData(data, to,
root, sendlength, MPI_LONG,
MPI_SUM, this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::ReduceSum(float* data, float* to,
int sendlength, int root)
{
return CheckForMPIError(
vtkMPICommunicatorReduceData(data, to,
root, sendlength, MPI_FLOAT,
MPI_SUM, this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::ReduceSum(double* data, double* to,
int sendlength, int root)
{
return CheckForMPIError(
vtkMPICommunicatorReduceData(data, to,
root, sendlength, MPI_DOUBLE,
MPI_SUM, this->MPIComm->Handle));
}
//----------------------------------------------------------------------------
// There is no MPI data type bool in the C binding of MPI
// -> convert to int!
int vtkMPICommunicator::ReduceAnd(bool* data, bool* to,
int size, int root)
{
int i;
int *intsbuffer;
int *intrbuffer;
intsbuffer = new int[size];
intrbuffer = new int[size];
for (i = 0; i < size; ++i)
{
intsbuffer[i] = (data[i] ? 1 : 0);
}
int err = CheckForMPIError(
vtkMPICommunicatorReduceData(intsbuffer, intrbuffer,
root, size, MPI_INT,
MPI_LAND, this->MPIComm->Handle));
for (i = 0; i < size; ++i)
{
to[i] = (intrbuffer[i] == 1);
}
delete [] intsbuffer;
delete [] intrbuffer;
return err;
}
//----------------------------------------------------------------------------
int vtkMPICommunicator::ReduceOr(bool* data, bool* to,
int size, int root)
{
int *intsbuffer;
int *intrbuffer;
int i;
intsbuffer = new int[size];
intrbuffer = new int[size];
for (i = 0; i < size; ++i)
{
intsbuffer[i] = (data[i] ? 1 : 0);
}
int err = CheckForMPIError(
vtkMPICommunicatorReduceData(intsbuffer, intrbuffer,
root, size, MPI_INT,
MPI_LOR, this->MPIComm->Handle));
for (i = 0; i < size; ++i)
{
to[i] = (intrbuffer[i] == 1);
}
delete [] intsbuffer;
delete [] intrbuffer;
return err;
}
//----------------------------------------------------------------------------