35 UPstream::Window(MPI_WIN_NULL)
49 *
this = UPstream::Window(MPI_WIN_NULL);
64 && (MPI_SUCCESS == MPI_Win_get_group(win, &
group))
67 if (MPI_SUCCESS != MPI_Group_size(
group, &val))
71 MPI_Group_free(&
group);
84 static std::pair<void*,int64_t>
88 MPI_Comm communicator,
91 std::streamsize num_elements,
102 *
self = UPstream::Window(MPI_WIN_NULL);
120 <<
"Window already exists. Use close() first" 125 int returnCode(MPI_SUCCESS);
126 void *baseptr =
nullptr;
130 returnCode = MPI_Win_allocate_shared
133 std::streamsize(num_elements * disp_unit),
143 returnCode = MPI_Win_allocate
146 std::streamsize(num_elements * disp_unit),
155 if (
FOAM_UNLIKELY((MPI_SUCCESS != returnCode) || (MPI_WIN_NULL == win)))
172 *
self = UPstream::Window(win);
175 return {baseptr, num_elements};
181 std::pair<void*,int64_t>
184 std::streamsize num_elements,
202 std::pair<void*,int64_t>
205 std::streamsize num_elements,
238 MPI_Comm communicator,
243 std::streamsize num_elements,
248 using namespace Foam;
253 *
self = UPstream::Window(MPI_WIN_NULL);
272 <<
"Window already exists. Use close() first" 278 if (!baseptr || !num_elements)
284 int returnCode = MPI_Win_create
288 std::streamsize(num_elements * disp_unit),
295 if (
FOAM_UNLIKELY((MPI_SUCCESS != returnCode) || (MPI_WIN_NULL == win)))
303 *
self = UPstream::Window(win);
305 return (MPI_SUCCESS == returnCode);
312 std::streamsize num_elements,
332 std::streamsize num_elements,
358 *
this = UPstream::Window(MPI_WIN_NULL);
373 if (
local) MPI_Win_flush_local_all(win);
374 else MPI_Win_flush_all(win);
378 if (
local) MPI_Win_flush_local(
rank, win);
379 else MPI_Win_flush(
rank, win);
406 (exclusive ? MPI_MODE_NOCHECK : 0),
414 (exclusive ? MPI_LOCK_EXCLUSIVE : MPI_LOCK_SHARED),
432 MPI_Win_unlock_all(win);
436 MPI_Win_unlock(
rank, win);
447 std::streamsize
count,
465 <<
"Called with MPI_WIN_NULL." 470 int returnCode = MPI_Get
473 origin,
count, datatype,
475 target_rank, target_disp,
count, datatype,
488 return (MPI_SUCCESS == returnCode);
495 std::streamsize
count,
513 <<
"Called with MPI_WIN_NULL." 518 int returnCode = MPI_Put
521 origin,
count, datatype,
523 target_rank, target_disp,
count, datatype,
536 return (MPI_SUCCESS == returnCode);
544 std::streamsize
count,
553 return this->put_data
576 <<
"Called with MPI_WIN_NULL." 583 <<
"Invalid opcode:" << int(opCodeId)
584 <<
" type:" << int(dataTypeId) <<
" count:" << label(
count) <<
nl 589 int returnCode = MPI_Accumulate
592 origin,
count, datatype,
594 target_rank, target_disp,
count, datatype,
609 return (MPI_SUCCESS == returnCode);
636 <<
"Called with MPI_WIN_NULL." 643 <<
"Invalid opcode:" << int(opCodeId)
644 <<
" type:" << int(dataTypeId) <<
nl 649 int returnCode = MPI_Fetch_and_op
651 origin, result, datatype,
653 target_rank, target_disp,
668 return (MPI_SUCCESS == returnCode);
675 #undef CheckFail_Win_get_attr 676 #define CheckFail_Win_get_attr(returnCode, flag, attribute) \ 678 if (FOAM_UNLIKELY((MPI_SUCCESS != returnCode) || !flag)) \ 680 FatalError("MPI_Win_get_attr()") \ 681 << "Failed getting attribute " << attribute << endl \ 682 << Foam::abort(FatalError); \ 703 int returnCode(MPI_ERR_UNKNOWN);
710 typedef int value_type;
713 returnCode = MPI_Win_get_attr(win, MPI_WIN_CREATE_FLAVOR, &val, &flag);
718 *static_cast<value_type*>(val)
722 if (failNonShared && (MPI_WIN_FLAVOR_SHARED != flavour))
725 <<
"Expecting a shared window but had (" 726 << flavour <<
") flavour instead" <<
endl 730 return (MPI_WIN_FLAVOR_SHARED == flavour);
734 std::pair<void*,int64_t>
737 UPstream::Window window,
738 const int expected_disp_unit
752 <<
"Called with MPI_WIN_NULL." 759 int returnCode(MPI_ERR_UNKNOWN);
778 std::pair<void*,int64_t> result(
nullptr, 0);
784 typedef MPI_Aint value_type;
787 returnCode = MPI_Win_get_attr(win, MPI_WIN_SIZE, &val, &flag);
790 result.second = *
static_cast<value_type*
>(val);
794 if (result.second == 0)
803 void* value(
nullptr);
805 returnCode = MPI_Win_get_attr(win, MPI_WIN_BASE, &value, &flag);
808 result.first = value;
813 if (result.first ==
nullptr)
819 if (expected_disp_unit)
821 result.second /= expected_disp_unit;
829 typedef int value_type;
832 returnCode = MPI_Win_get_attr(win, MPI_WIN_DISP_UNIT, &val, &flag);
835 disp_unit = *
static_cast<value_type*
>(val);
841 if (expected_disp_unit != disp_unit)
844 <<
"Window [size=" << result.second
845 <<
"] created with Type size=" << disp_unit
846 <<
" but expecting Type size=" << expected_disp_unit <<
endl 855 std::pair<void*,int64_t>
858 UPstream::Window window,
860 const int expected_disp_unit
874 <<
"Called with MPI_WIN_NULL." 880 const bool shared = window.is_shared(
true);
888 MPI_Aint num_bytes = 0;
889 void *baseptr =
nullptr;
892 int returnCode = MPI_Win_shared_query
908 std::pair<void*,int64_t> result(baseptr, num_bytes);
917 if (result.second && expected_disp_unit)
919 result.second /= expected_disp_unit;
924 if (expected_disp_unit != disp_unit)
927 <<
"Window on rank(" << target_rank
928 <<
") [size=" << result.second
929 <<
"] created with Type size=" << disp_unit
930 <<
" but expecting Type size=" << expected_disp_unit <<
endl 939 #undef CheckFail_Win_get_attr
int size() const
The number of ranks associated with the window group.
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().
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()...
An opaque wrapper for MPI_Comm with a vendor-independent representation without any <mpi...
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
void mpi_win_unlocking(int rank)
Entry point to MPI_Win_unlock(), MPI_Win_unlock_all().
An opaque wrapper for MPI_Win with a vendor-independent representation and without any <mpi...
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...
constexpr char nl
The newline '\n' character (0x0a)
bool good() const noexcept
True if not equal to MPI_WIN_NULL.
DynamicList< MPI_Comm > MPICommunicators_
Ostream & endl(Ostream &os)
Add newline and flush stream.
static bool & parRun() noexcept
Test if this a parallel run.
static Type to_mpi(UPstream::Communicator arg) noexcept
Cast UPstream::Communicator to MPI_Comm.
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.
opCodes
Mapping of some MPI op codes.
constexpr const char *const group
Group name for atomic constants.
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Window() noexcept
Default construct as MPI_WIN_NULL.
void sync()
MPI_Win_sync() - ignored if the window is not active.
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.
#define CheckFail_Win_get_attr(returnCode, flag, attribute)
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(), respectively.
#define FOAM_UNLIKELY(cond)
MPI_Op getOpCode(UPstream::opCodes id)
Lookup of opCodes enumeration as an MPI_Op.
bool is_shared(const bool failNonShared=false) const
Test if the window is a shared memory window.
errorManip< error > abort(error &err)
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 close()
MPI_Win_free(). Closes the window view and frees any associated memory,.
static bool call_window_create(Foam::UPstream::Window *self, MPI_Comm communicator, void *baseptr, std::streamsize num_elements, const int disp_unit)
dataTypes
Mapping of some fundamental and aggregate types to MPI data types.
void mpi_win_locking(int rank, bool exclusive=false)
Entry point to MPI_Win_lock(), MPI_Win_lock_all(), optionally as exclusive lock.
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...
MPI_Datatype getDataType(UPstream::dataTypes id)
Lookup of dataTypes enumeration as an MPI_Datatype.
::Foam::direction rank(const expressions::valueTypeCode) noexcept
The vector-space rank associated with given valueTypeCode.
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)
void reset() noexcept
Reset to default constructed value (MPI_WIN_NULL)