36 UPstream::Window(MPI_WIN_NULL)
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);
85 static std::pair<void*,int64_t>
89 MPI_Comm communicator,
92 std::streamsize num_elements,
103 *
self = UPstream::Window(MPI_WIN_NULL);
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)))
173 *
self = UPstream::Window(win);
176 return {baseptr, num_elements};
182 std::pair<void*,int64_t>
185 std::streamsize num_elements,
203 std::pair<void*,int64_t>
206 std::streamsize num_elements,
239 MPI_Comm communicator,
244 std::streamsize num_elements,
249 using namespace Foam;
254 *
self = UPstream::Window(MPI_WIN_NULL);
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)))
304 *
self = UPstream::Window(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);
735 std::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 856 std::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
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)