Commit 164b39c6 authored by Kenneth Moreland's avatar Kenneth Moreland
Browse files

Work around when MPI_IN_PLACE not available.

The MPI_IN_PLACE feature, which allows you to do collective operations
such as gather with the local data already in the destination array, is
a feature that is not available in MPI 1.  To continue to support MPI
version 1, implement an alternative copying version that is only used
for that version.
parent 4f55c475
......@@ -27,6 +27,9 @@ Revision 2.1:
compositing algorithms to try shuffling the pixels in images to
better load balance the active pixels during compositing.
Patch 1: Fixed compatibility issue with compiling against MPI
version 1.
Revision 2.0: A major restructuring of the IceT code comprising the
following changes:
......
......@@ -11,6 +11,8 @@
#include <IceTDevCommunication.h>
#include <IceTDevDiagnostics.h>
#include <IceTDevPorting.h>
#include <IceTDevState.h>
#include <stdlib.h>
#include <string.h>
......@@ -19,8 +21,14 @@
#define BREAK_ON_MPI_ERROR
#endif
#if MPI_VERSION >= 2
#define ICET_USE_MPI_IN_PLACE
#endif
#define ICET_MPI_REQUEST_MAGIC_NUMBER ((IceTEnum)0xD7168B00)
#define ICET_MPI_TEMP_BUFFER_0 (ICET_COMMUNICATION_LAYER_START | (IceTEnum)0x00)
static IceTCommunicator Duplicate(IceTCommunicator self);
static void Destroy(IceTCommunicator self);
static void Barrier(IceTCommunicator self);
......@@ -324,7 +332,17 @@ static void Gather(IceTCommunicator self,
CONVERT_DATATYPE(datatype, mpitype);
if (sendbuf == ICET_IN_PLACE_COLLECT) {
#ifdef ICET_USE_MPI_IN_PLACE
sendbuf = MPI_IN_PLACE;
#else
int rank;
MPI_Comm_rank(MPI_COMM, &rank);
sendbuf = icetGetStateBuffer(ICET_MPI_TEMP_BUFFER_0,
sendcount*icetTypeWidth(datatype));
memcpy((void *)sendbuf,
((const IceTByte *)recvbuf) + rank*sendcount,
sendcount);
#endif
}
MPI_Gather((void *)sendbuf, sendcount, mpitype,
......@@ -345,7 +363,18 @@ static void Gatherv(IceTCommunicator self,
CONVERT_DATATYPE(datatype, mpitype);
if (sendbuf == ICET_IN_PLACE_COLLECT) {
#ifdef ICET_USE_MPI_IN_PLACE
sendbuf = MPI_IN_PLACE;
#else
int rank;
MPI_Comm_rank(MPI_COMM, &rank);
sendcount = recvcounts[rank];
sendbuf = icetGetStateBuffer(ICET_MPI_TEMP_BUFFER_0,
sendcount*icetTypeWidth(datatype));
memcpy((void *)sendbuf,
((const IceTByte *)recvbuf) + recvoffsets[rank],
sendcount);
#endif
}
MPI_Gatherv((void *)sendbuf, sendcount, mpitype,
......@@ -363,7 +392,17 @@ static void Allgather(IceTCommunicator self,
CONVERT_DATATYPE(datatype, mpitype);
if (sendbuf == ICET_IN_PLACE_COLLECT) {
#ifdef ICET_USE_MPI_IN_PLACE
sendbuf = MPI_IN_PLACE;
#else
int rank;
MPI_Comm_rank(MPI_COMM, &rank);
sendbuf = icetGetStateBuffer(ICET_MPI_TEMP_BUFFER_0,
sendcount*icetTypeWidth(datatype));
memcpy((void *)sendbuf,
((const IceTByte *)recvbuf) + rank*sendcount,
sendcount);
#endif
}
MPI_Allgather((void *)sendbuf, sendcount, mpitype,
......
......@@ -85,7 +85,7 @@ struct IceTCommunicatorStruct {
const void *sendbuf,
int sendcount,
IceTEnum datatype,
void *recvbuf,
void *recvbuf,
const int *recvcounts,
const int *recvoffsets,
int root);
......@@ -415,6 +415,9 @@ ICET_EXPORT void icetDiagnostics(IceTBitField mask);
#define ICET_SI_STRATEGY_BUFFER_14 (ICET_SI_STRATEGY_BUFFER_START | (IceTEnum)0x000E)
#define ICET_SI_STRATEGY_BUFFER_15 (ICET_SI_STRATEGY_BUFFER_START | (IceTEnum)0x000F)
#define ICET_COMMUNICATION_LAYER_START (ICET_STATE_BUFFER_START | (IceTEnum)0x0040)
#define ICET_COMMUNICATION_LAYER_END (ICET_STATE_BUFFER_START | (IceTEnum)0x0050)
#define ICET_STATE_SIZE (IceTEnum)0x00000200
#define ICET_STATE_ENGINE_END (ICET_STATE_ENGINE_START + ICET_STATE_SIZE)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment