50 *
this = UPstream::Window(MPI_WIN_NULL);
65 && (MPI_SUCCESS == MPI_Win_get_group(win, &group))
68 if (MPI_SUCCESS != MPI_Group_size(group, &val))
72 MPI_Group_free(&group);
85static std::pair<void*,int64_t>
89 MPI_Comm communicator,
92 std::streamsize num_elements,
121 <<
"Window already exists. Use close() first"
126 int returnCode(MPI_SUCCESS);
127 void *baseptr =
nullptr;
131 returnCode = MPI_Win_allocate_shared
134 std::streamsize(num_elements * disp_unit),
144 returnCode = MPI_Win_allocate
147 std::streamsize(num_elements * disp_unit),
156 if (
FOAM_UNLIKELY((MPI_SUCCESS != returnCode) || (MPI_WIN_NULL == win)))
176 return {baseptr, num_elements};
182std::pair<void*,int64_t>
185 std::streamsize num_elements,
203std::pair<void*,int64_t>
206 std::streamsize num_elements,
239 MPI_Comm communicator,
244 std::streamsize num_elements,
249 using namespace Foam;
273 <<
"Window already exists. Use close() first"
279 if (!baseptr || !num_elements)
285 int returnCode = MPI_Win_create
289 std::streamsize(num_elements * disp_unit),
296 if (
FOAM_UNLIKELY((MPI_SUCCESS != returnCode) || (MPI_WIN_NULL == win)))
306 return (MPI_SUCCESS == returnCode);
313 std::streamsize num_elements,
333 std::streamsize num_elements,
359 *
this = UPstream::Window(MPI_WIN_NULL);
374 if (
local) MPI_Win_flush_local_all(win);
375 else MPI_Win_flush_all(win);
379 if (
local) MPI_Win_flush_local(rank, win);
380 else MPI_Win_flush(rank, win);
407 (exclusive ? MPI_MODE_NOCHECK : 0),
415 (exclusive ? MPI_LOCK_EXCLUSIVE : MPI_LOCK_SHARED),
433 MPI_Win_unlock_all(win);
437 MPI_Win_unlock(rank, win);
448 std::streamsize count,
466 <<
"Called with MPI_WIN_NULL."
471 int returnCode = MPI_Get
474 origin, count, datatype,
476 target_rank, target_disp, count, datatype,
489 return (MPI_SUCCESS == returnCode);
496 std::streamsize count,
514 <<
"Called with MPI_WIN_NULL."
519 int returnCode = MPI_Put
522 origin, count, datatype,
524 target_rank, target_disp, count, datatype,
537 return (MPI_SUCCESS == returnCode);
545 std::streamsize count,
554 return this->put_data
577 <<
"Called with MPI_WIN_NULL."
584 <<
"Invalid opcode:" << int(opCodeId)
585 <<
" type:" << int(dataTypeId) <<
" count:" << label(count) <<
nl
590 int returnCode = MPI_Accumulate
593 origin, count, datatype,
595 target_rank, target_disp, count, datatype,
610 return (MPI_SUCCESS == returnCode);
637 <<
"Called with MPI_WIN_NULL."
644 <<
"Invalid opcode:" << int(opCodeId)
645 <<
" type:" << int(dataTypeId) <<
nl
650 int returnCode = MPI_Fetch_and_op
652 origin, result, datatype,
654 target_rank, target_disp,
669 return (MPI_SUCCESS == returnCode);
676#undef CheckFail_Win_get_attr
677#define CheckFail_Win_get_attr(returnCode, flag, attribute) \
679 if (FOAM_UNLIKELY((MPI_SUCCESS != returnCode) || !flag)) \
681 FatalError("MPI_Win_get_attr()") \
682 << "Failed getting attribute " << attribute << endl \
683 << Foam::abort(FatalError); \
704 int returnCode(MPI_ERR_UNKNOWN);
711 typedef int value_type;
714 returnCode = MPI_Win_get_attr(win, MPI_WIN_CREATE_FLAVOR, &val, &flag);
719 *
static_cast<value_type*
>(val)
723 if (failNonShared && (MPI_WIN_FLAVOR_SHARED != flavour))
726 <<
"Expecting a shared window but had ("
727 << flavour <<
") flavour instead" <<
endl
731 return (MPI_WIN_FLAVOR_SHARED == flavour);
735std::pair<void*,int64_t>
738 UPstream::Window window,
739 const int expected_disp_unit
753 <<
"Called with MPI_WIN_NULL."
760 int returnCode(MPI_ERR_UNKNOWN);
779 std::pair<void*,int64_t> result(
nullptr, 0);
785 typedef MPI_Aint value_type;
788 returnCode = MPI_Win_get_attr(win, MPI_WIN_SIZE, &val, &flag);
791 result.second = *
static_cast<value_type*
>(val);
795 if (result.second == 0)
804 void* value(
nullptr);
806 returnCode = MPI_Win_get_attr(win, MPI_WIN_BASE, &value, &flag);
809 result.first = value;
814 if (result.first ==
nullptr)
820 if (expected_disp_unit)
822 result.second /= expected_disp_unit;
830 typedef int value_type;
833 returnCode = MPI_Win_get_attr(win, MPI_WIN_DISP_UNIT, &val, &flag);
836 disp_unit = *
static_cast<value_type*
>(val);
842 if (expected_disp_unit != disp_unit)
845 <<
"Window [size=" << result.second
846 <<
"] created with Type size=" << disp_unit
847 <<
" but expecting Type size=" << expected_disp_unit <<
endl
856std::pair<void*,int64_t>
859 UPstream::Window window,
861 const int expected_disp_unit
875 <<
"Called with MPI_WIN_NULL."
881 const bool shared = window.
is_shared(
true);
889 MPI_Aint num_bytes = 0;
890 void *baseptr =
nullptr;
893 int returnCode = MPI_Win_shared_query
909 std::pair<void*,int64_t> result(baseptr, num_bytes);
918 if (result.second && expected_disp_unit)
920 result.second /= expected_disp_unit;
925 if (expected_disp_unit != disp_unit)
928 <<
"Window on rank(" << target_rank
929 <<
") [size=" << result.second
930 <<
"] created with Type size=" << disp_unit
931 <<
" but expecting Type size=" << expected_disp_unit <<
endl
940#undef CheckFail_Win_get_attr
An opaque wrapper for MPI_Win with a vendor-independent representation and without any <mpi....
bool mpi_fetch_and_op(const UPstream::opCodes opCodeId, const void *origin, void *result, const UPstream::dataTypes dataTypeId, int target_rank, int target_disp=0) const
Retrieve the remote content (a single value) and then combine in new content.
static std::pair< void *, int64_t > mpi_win_query(UPstream::Window window, const int expected_disp_unit)
Retrieve window sizing information as address/count tuple. The expected sizeof(Type) is supplied as a...
Window() noexcept
Default construct as MPI_WIN_NULL.
void reset() noexcept
Reset to default constructed value (MPI_WIN_NULL).
std::pair< void *, int64_t > mpi_win_allocate(std::streamsize num_elements, int disp_unit, UPstream::Communicator communicator, const bool shared=false)
Allocate a local or shared memory window. Uses MPI_Win_allocate() or MPI_Win_allocate_shared(),...
bool get_data(void *origin, std::streamsize count, const UPstream::dataTypes dataTypeId, int target_rank, int target_disp=0) const
Get buffer contents from given rank.
bool put_data(const void *origin, std::streamsize count, const UPstream::dataTypes dataTypeId, int target_rank, int target_disp=0) const
Put buffer contents to given rank.
void mpi_win_unlocking(int rank)
Entry point to MPI_Win_unlock(), MPI_Win_unlock_all().
bool good() const noexcept
True if not equal to MPI_WIN_NULL.
void close()
MPI_Win_free(). Closes the window view and frees any associated memory,.
void mpi_win_locking(int rank, bool exclusive=false)
Entry point to MPI_Win_lock(), MPI_Win_lock_all(), optionally as exclusive lock.
bool mpi_win_create(void *baseptr, std::streamsize num_elements, int disp_unit, UPstream::Communicator communicator)
Create window onto existing memory with MPI_Win_create().
static std::pair< void *, int64_t > mpi_win_query_shared(UPstream::Window window, int target_rank, const int expected_disp_unit)
Retrieve shared window information as address/count tuple. The expected sizeof(Type) is supplied as a...
void sync()
MPI_Win_sync() - ignored if the window is not active.
bool is_shared(const bool failNonShared=false) const
Test if the window is a shared memory window.
void mpi_win_flushing(int rank, bool local=false)
Entry point to MPI_Win_flush(), MPI_Win_flush_all(), MPI_Win_flush_local(), MPI_Win_flush_local_all()...
int size() const
The number of ranks associated with the window group.
Wrapper for internally indexed communicator label. Always invokes UPstream::allocateCommunicatorCompo...
Inter-processor communications stream.
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
opCodes
Mapping of some MPI op codes.
dataTypes
Mapping of some fundamental and aggregate types to MPI data types.
static bool & parRun() noexcept
Test if this a parallel run.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
static std::pair< void *, int64_t > call_window_allocate(Foam::UPstream::Window *self, MPI_Comm communicator, std::streamsize num_elements, const int disp_unit, const bool shared)
#define CheckFail_Win_get_attr(returnCode, flag, attribute)
static bool call_window_create(Foam::UPstream::Window *self, MPI_Comm communicator, void *baseptr, std::streamsize num_elements, const int disp_unit)
MPI_Datatype getDataType(UPstream::dataTypes id)
Lookup of dataTypes enumeration as an MPI_Datatype.
MPI_Op getOpCode(UPstream::opCodes id)
Lookup of opCodes enumeration as an MPI_Op.
DynamicList< MPI_Comm > MPICommunicators_
constexpr const char *const group
Group name for atomic constants.
Ostream & endl(Ostream &os)
Add newline and flush stream.
errorManip< error > abort(error &err)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
constexpr char nl
The newline '\n' character (0x0a).
#define FOAM_UNLIKELY(cond)
static Type to_mpi(UPstream::Communicator arg) noexcept
Cast UPstream::Communicator to MPI_Comm.