UPstreamWindow.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2025 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 Class
27  Foam::UPstream::Window
28 
29 Description
30  An opaque wrapper for MPI_Win with a vendor-independent
31  representation and without any \c <mpi.h> header dependency.
32 
33  The handling for window declaration is very generous - it does not
34  distinguish between readonly and read/write windows. This may become
35  more restrictive in the future.
36 
37 Note
38  The MPI standard states that MPI_Win is always an opaque object.
39  Generally it is either an integer (eg, mpich) or a pointer (eg, openmpi).
40 
41 SourceFiles
42  UPstreamWindow.txx
43 
44 \*---------------------------------------------------------------------------*/
45 
46 #ifndef Foam_UPstreamWindow_H
47 #define Foam_UPstreamWindow_H
48 
49 #include "UPstream.H"
50 
51 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
52 
53 namespace Foam
54 {
55 
56 /*---------------------------------------------------------------------------*\
57  Class UPstream::Window Declaration
58 \*---------------------------------------------------------------------------*/
59 
60 class UPstream::Window
61 {
62 public:
63 
64  // Public Types
65 
66  //- Storage for MPI_Win (as integer or pointer)
67  typedef std::intptr_t value_type;
68 
69 
70 private:
71 
72  // Private Data
73 
74  //- The MPI_Win (as wrapped value)
75  value_type value_;
76 
77 
78 protected:
79 
80  // Protected Method Functions
81 
82  //- Sizing helper for disp_unit
83  template<class Type>
84  static constexpr auto element_width() noexcept
85  {
86  if constexpr (std::is_void_v<Type>) { return 1; }
87  else { return sizeof(Type); }
88  }
89 
90  //- Allocate a local or shared memory window.
91  //- Uses MPI_Win_allocate() or MPI_Win_allocate_shared(), respectively.
92  // A no-op if not running in parallel.
93  // This is a \em collective call.
94  // \returns (address, size) tuple
95  std::pair<void*, int64_t> mpi_win_allocate
96  (
98  std::streamsize num_elements,
101  int disp_unit,
105  const bool shared = false
106  );
107 
108  //- Allocate a local or shared memory window.
109  //- Uses MPI_Win_allocate() or MPI_Win_allocate_shared(), respectively.
110  // A no-op if not running in parallel.
111  // This is a \em collective call.
112  // \returns (address, size) tuple
113  std::pair<void*, int64_t> mpi_win_allocate
114  (
116  std::streamsize num_elements,
119  int disp_unit,
121  int communicator,
123  const bool shared = false
124  );
125 
126  //- Create window onto existing memory with MPI_Win_create().
127  // A no-op if not running in parallel.
128  // This is a \em collective call.
129  bool mpi_win_create
130  (
132  void *baseptr,
134  std::streamsize num_elements,
137  int disp_unit,
140  );
141 
142  //- Create window onto existing memory with MPI_Win_create().
143  // A no-op if not running in parallel.
144  // This is a \em collective call.
145  bool mpi_win_create
146  (
148  void *baseptr,
150  std::streamsize num_elements,
153  int disp_unit,
155  int communicator
156  );
157 
158  //- Retrieve window sizing information as address/count tuple.
159  //- The expected sizeof(Type) is supplied as an assertion parameter.
160  //
161  // \returns (nullptr, 0) if not running in parallel or if either
162  // the address or count are zero
163  static std::pair<void*, int64_t> mpi_win_query
164  (
165  UPstream::Window window,
167  const int expected_disp_unit
168  );
169 
170  //- Retrieve shared window information as address/count tuple.
171  //- The expected sizeof(Type) is supplied as an assertion parameter.
172  //
173  // \returns (nullptr, 0) if not running in parallel or if either
174  // the address or count are zero
175  static std::pair<void*, int64_t> mpi_win_query_shared
176  (
177  UPstream::Window window,
179  int target_rank,
181  const int expected_disp_unit
182  );
183 
184 
185  // Protected Member Functions
186 
187  //- Get buffer contents from given rank.
188  // A no-op if not running in parallel and for empty or null buffer.
189  //
190  // \note The method uses a \c void pointer and the required data type
191  // (as per MPI). This means it should almost never be called directly
192  // but always via a compile-time checked caller.
193  // \return True on success
194  bool get_data
195  (
197  void* origin,
199  std::streamsize count,
200  const UPstream::dataTypes dataTypeId,
201  int target_rank,
202  int target_disp = 0
203  ) const;
204 
205  //- Put buffer contents to given rank.
206  // A no-op if not running in parallel and for empty or null buffer.
207  bool put_data
208  (
210  const void* origin,
212  std::streamsize count,
213  const UPstream::dataTypes dataTypeId,
214  int target_rank,
215  int target_disp = 0
216  ) const;
217 
218  //- Put accumulate buffer contents to given rank.
219  // A no-op if not running in parallel and for empty or null buffer.
220  bool put_data
221  (
223  const UPstream::opCodes opCodeId,
225  const void* origin,
227  std::streamsize count,
228  const UPstream::dataTypes dataTypeId,
229  int target_rank,
230  int target_disp = 0
231  ) const;
232 
233  //- Retrieve the remote content (a single value) and then combine
234  //- in new content.
235  // A no-op if not running in parallel and for empty or null buffer.
236  bool mpi_fetch_and_op
237  (
239  const UPstream::opCodes opCodeId,
241  const void* origin,
243  void* result,
244  const UPstream::dataTypes dataTypeId,
245  int target_rank,
246  int target_disp = 0
247  ) const;
248 
249  //- Entry point to MPI_Win_flush(), MPI_Win_flush_all(),
250  //- MPI_Win_flush_local(), MPI_Win_flush_local_all().
251  // Uses rank == -1 to signal 'all'
252  void mpi_win_flushing(int rank, bool local=false);
253 
254  //- Entry point to MPI_Win_lock(), MPI_Win_lock_all(),
255  //- optionally as exclusive lock.
256  // Uses rank == -1 to signal 'all'
257  void mpi_win_locking(int rank, bool exclusive=false);
258 
259  //- Entry point to MPI_Win_unlock(), MPI_Win_unlock_all().
260  // Uses rank == -1 to signal 'all'
261  void mpi_win_unlocking(int rank);
262 
263 
264 public:
265 
266  // Generated Methods
267 
268  //- Copy construct
269  Window(const Window&) noexcept = default;
270 
271  //- Move construct
272  Window(Window&&) noexcept = default;
273 
274  //- Copy assignment
275  Window& operator=(const Window&) noexcept = default;
276 
277  //- Move assignment
278  Window& operator=(Window&&) noexcept = default;
279 
280 
281  // Member Operators
282 
283  //- Test for equality
284  bool operator==(const Window& rhs) const noexcept
285  {
286  return (value_ == rhs.value_);
287  }
288 
289  //- Test for inequality
290  bool operator!=(const Window& rhs) const noexcept
291  {
292  return (value_ != rhs.value_);
293  }
294 
295 
296  // Constructors
297 
298  //- Default construct as MPI_WIN_NULL
299  Window() noexcept;
300 
301  //- Construct from MPI_Win (as pointer type)
302  explicit Window(const void* p) noexcept
303  :
304  value_(reinterpret_cast<value_type>(p))
305  {}
306 
307  //- Construct from MPI_Win (as integer type)
308  explicit Window(value_type val) noexcept
309  :
310  value_(val)
311  {}
312 
313 
314  // Member Functions
315 
316  // Basic handling
317 
318  //- Return raw value
319  value_type value() const noexcept { return value_; }
320 
321  //- Return as pointer value
322  const void* pointer() const noexcept
323  {
324  return reinterpret_cast<const void*>(value_);
325  }
326 
327  //- True if not equal to MPI_WIN_NULL
328  bool good() const noexcept;
329 
330  //- Reset to default constructed value (MPI_WIN_NULL)
331  void reset() noexcept;
332 
333  //- The number of ranks associated with the window group.
334  // The same as querying the original communicator, assuming the
335  // communicator is available within the current code scope.
336  int size() const;
337 
338 
339  // Window creation with allocation
340 
341  //- Allocate a local memory region and create window onto it.
342  // A no-op if not running in parallel.
343  // This is a \em collective call.
344  template<class Type>
345  inline UList<Type> allocate
346  (
348  std::streamsize count,
351  const bool shared = false
352  );
353 
354  //- Allocate a local memory region and create window onto it.
355  // A no-op if not running in parallel.
356  // This is a \em collective call.
357  template<class Type>
358  inline UList<Type> allocate
359  (
361  std::streamsize count,
362  const int communicator,
364  const bool shared = false
365  );
367  //- Allocate a shared memory region and create window onto it.
368  // A no-op if not running in parallel.
369  // This is a \em collective call.
370  template<class Type>
371  inline UList<Type> allocate_shared
372  (
374  std::streamsize count,
376  );
377 
378  //- Create a window by allocating a new shared memory region.
379  // A no-op if not running in parallel.
380  // This is a \em collective call.
381  template<class Type>
382  inline UList<Type> allocate_shared
383  (
385  std::streamsize count,
386  const int communicator
387  );
388 
389 
390  // Window creation with existing memory
391 
392  //- A window exposing a zero-sized memory region.
393  // A no-op if not running in parallel.
394  // This is a \em collective call.
395  template<class Type = void>
396  bool create(std::nullptr_t, UPstream::Communicator comm)
397  {
398  return mpi_win_create(nullptr, 0, element_width<Type>(), comm);
399  }
400 
401  //- A window exposing a zero-sized memory region.
402  // A no-op if not running in parallel.
403  // This is a \em collective call.
404  template<class Type = void>
405  bool create(std::nullptr_t, const int comm)
406  {
407  return mpi_win_create(nullptr, 0, element_width<Type>(), comm);
408  }
409 
410  //- A window exposing an existing memory region.
411  // A no-op if not running in parallel.
412  // This is a \em collective call.
413  // \note Ignores constness since we can't specify a priori
414  // if this should be a read/write or read only buffer.
415  template<class Type>
416  inline bool create
417  (
418  const Type* buffer,
420  std::streamsize count,
421  UPstream::Communicator communicator
422  );
423 
424  //- A window exposing an existing memory region.
425  // A no-op if not running in parallel.
426  // This is a \em collective call.
427  template<class Type>
428  inline bool create
429  (
430  const Type* buffer,
432  std::streamsize count,
433  const int communicator
434  );
435 
436  //- A window exposing the specified buffer contents.
437  // A no-op if not running in parallel.
438  // This is a \em collective call.
439  template<class Type>
440  bool create(const UList<Type>& buffer, UPstream::Communicator comm)
441  {
442  return create(buffer.cdata(), buffer.size(), comm);
443  }
444 
445  //- A window exposing the specified buffer contents.
446  // A no-op if not running in parallel.
447  // This is a \em collective call.
448  template<class Type>
449  bool create(const UList<Type>& buffer, int communicator)
450  {
451  return create(buffer.cdata(), buffer.size(), communicator);
452  }
453 
454  //- A window exposing the specified buffer contents.
455  // A no-op if not running in parallel.
456  // This is a \em collective call.
457  template<class Type>
458  bool create(SubList<Type> buffer, UPstream::Communicator communicator)
459  {
460  return create(buffer.cdata(), buffer.size(), communicator);
461  }
462 
463  //- A window exposing the specified buffer contents.
464  // A no-op if not running in parallel.
465  // This is a \em collective call.
466  template<class Type>
467  bool create(SubList<Type> buffer, int communicator)
468  {
469  return create(buffer.cdata(), buffer.size(), communicator);
470  }
471 
472 
473  // Synchronization and resource management
474 
475  //- MPI_Win_lock() for given target rank (no assertions),
476  //- optionally as exclusive lock.
477  void lock(int rank, bool exclusive=false)
478  {
479  mpi_win_locking(rank, exclusive);
480  }
481 
482  //- MPI_Win_unlock() for given target rank.
483  void unlock(int rank) { mpi_win_unlocking(rank); }
484 
485  //- MPI_Win_lock_all(), optionally as exclusive lock.
486  void lock_all(bool exclusive=false) { mpi_win_locking(-1, exclusive); }
487 
488  //- MPI_Win_unlock_all()
489  void unlock_all() { mpi_win_unlocking(-1); }
490 
491  //- MPI_Win_flush() for given target rank.
492  // Complete all outstanding RMA operations initiated by the
493  // calling process to the target rank.
494  void flush(int rank) { mpi_win_flushing(rank); }
495 
496  //- MPI_Win_flush_all()
497  // Complete all outstanding RMA operations at both the origin
498  // and the target
499  void flush_all() { mpi_win_flushing(-1); }
500 
501  //- MPI_Win_flush_local()
502  // Locally complete at the origin all outstanding RMA
503  // operations initiated by the calling process to the target
504  // process specified by rank.
505  void flush_local(int rank) { mpi_win_flushing(rank, true); }
506 
507  //- MPI_Win_flush_local_all()
508  // Locally complete at the origin all outstanding RMA
509  // operations to all targets.
510  void flush_local_all() { mpi_win_flushing(-1, true); }
511 
512  //- MPI_Win_sync() - ignored if the window is not active.
513  void sync();
514 
515  //- MPI_Win_free().
516  //- Closes the window view and frees any associated memory,
517  // eg, from allocate() or allocate_shared().
518  // Ignored if the window is not active.
519  // This is a \em collective call.
520  void close();
521 
522 
523  // Queries
524 
525  //- Test if the window is a shared memory window
526  bool is_shared(const bool failNonShared = false) const;
527 
528  //- Return view of the currently exposed window content.
529  //- No restriction on the type of memory associated with the window.
530  // A no-op (empty list) if not running in parallel
531  // or the window is not active.
532  template<class Type>
533  inline UList<Type> view() const;
534 
535  //- Return view of shared memory window content.
536  // A no-op (empty list) if not running in parallel.
537  // Undefined behaviour (likely Fatal) if a shared memory window
538  // has not been allocated.
539  template<class Type>
540  inline UList<Type> view_shared(int target_rank) const;
541 
542 
543  // Window Access
544 
545  //- Get buffer contents from given rank.
546  //- A no-op for an empty or null buffer, or if not running in parallel.
547  template<class Type>
548  inline bool get
549  (
551  Type* buffer,
553  std::streamsize count,
554  int fromProcNo,
555  int target_disp = 0
556  ) const;
557 
558  //- Put buffer contents to given rank.
559  // A no-op for an empty/null buffer, or if not running in parallel.
560  template<class Type>
561  inline bool put
562  (
564  const Type* buffer,
566  std::streamsize count,
567  int toProcNo,
568  int target_disp = 0
569  ) const;
570 
571  //- Put accumulate buffer contents to given rank.
572  // A no-op for an empty/null buffer, or if not running in parallel.
573  // \note Must correspond to basic data types!
574  template<class Type>
575  inline bool put
576  (
577  const UPstream::opCodes opCodeId,
579  const Type* buffer,
581  std::streamsize count,
582  int toProcNo,
583  int target_disp = 0
584  ) const;
585 
586  //- Get a single value from given rank.
587  // \note Use persistent data (not temporary) for value
588  template<class Type>
589  inline bool get_value
590  (
591  Type& value,
592  int fromProcNo,
593  int target_disp = 0
594  ) const
595  {
596  return this->get(&value, 1, fromProcNo, target_disp);
597  }
598 
599  //- Put a single value to given rank.
600  // \note Use persistent data (not temporary) for value
601  template<class Type>
602  inline bool put_value
603  (
604  const Type& value,
605  int toProcNo,
606  int target_disp = 0
607  ) const
608  {
609  return this->put(&value, 1, toProcNo, target_disp);
610  }
611 
612  //- Put and accumulate a single value to given rank
613  // \note Use persistent data (not temporary) for value
614  template<class Type>
615  inline bool put_value
616  (
617  const UPstream::opCodes opCodeId,
618  const Type& value,
619  int toProcNo,
620  int target_disp = 0
621  ) const
622  {
623  return this->put(opCodeId, &value, 1, toProcNo, target_disp);
624  }
625 
626  //- Get into List storage (contiguous data only)
627  //- from window location on given processor.
628  //- A no-op for an empty or null buffer, or if not running in parallel.
629  // \note Only valid for contiguous data types.
630  template<class Type>
631  inline bool get
632  (
633  UList<Type>& buffer,
635  int fromProcNo,
636  int target_disp = 0
637  ) const;
638 
639  //- Put from List storage (contiguous data only)
640  //- to window location on given processor.
641  // \note Only valid for contiguous data types.
642  template<class Type>
643  inline bool put
644  (
645  const UList<Type>& buffer,
646  int toProcNo,
647  int target_disp = 0
648  ) const;
649 
650  //- Put and accumulate from List storage (contiguous data only)
651  //- to window location on given processor.
652  //- A no-op for an empty or null buffer, or if not running in parallel.
653  // \note Only valid for contiguous data types.
654  template<class Type>
655  inline bool put
656  (
657  const UPstream::opCodes opCodeId,
658  const UList<Type>& buffer,
659  int toProcNo,
660  int target_disp = 0
661  ) const;
662 
663  //- Get into SubList storage (contiguous data only)
664  //- from window location on given processor.
665  //- A no-op for an empty or null buffer, or if not running in parallel.
666  // \note Only valid for contiguous data types.
667  template<class Type>
668  inline bool get
669  (
670  SubList<Type> buffer,
671  int fromProcNo,
672  int target_disp = 0
673  ) const;
674 
675  //- Combine the value of origin into the target and return
676  //- the resulting value (MPI_Fetch_and_op).
677  // \note Use persistent data (not temporary) for origin and result,
678  // which must also be disjoint locations.
679  // Only valid for single element (no aggregates).
680  // \return the old target value (before the operation)
681  template<class Type>
682  inline bool fetch_and_op
683  (
684  const UPstream::opCodes opCodeId,
686  const Type& origin,
688  Type& result,
689  int target_rank,
690  int target_disp = 0
691  ) const;
692 
693 
694  //- Put from SubList storage (contiguous data only)
695  //- to window location on given processor.
696  //- A no-op for an empty or null buffer, or if not running in parallel.
697  // \note Only valid for contiguous data types.
698  template<class Type>
699  inline bool put
700  (
701  const SubList<Type> buffer,
702  int toProcNo,
703  int target_disp = 0
704  ) const;
705 
706  //- Put and accumulate from SubList storage (contiguous data only)
707  //- to window location on given processor.
708  //- A no-op for an empty or null buffer, or if not running in parallel.
709  // \note Only valid for contiguous data types.
710  template<class Type>
711  inline bool put
712  (
713  const UPstream::opCodes opCodeId,
714  const SubList<Type> buffer,
715  int toProcNo,
716  int target_disp = 0
717  ) const;
718 };
719 
720 
721 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
722 
723 } // End namespace Foam
724 
725 
726 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
727 
728 #ifdef NoRepository
729  #include "UPstreamWindow.txx"
730 #endif
731 
732 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
733 
734 #endif
735 
736 // ************************************************************************* //
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:119
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...
Definition: UPstream.H:2883
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...
void flush_all()
MPI_Win_flush_all()
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...
std::intptr_t value_type
Storage for MPI_Win (as integer or pointer)
void flush_local(int rank)
MPI_Win_flush_local()
bool good() const noexcept
True if not equal to MPI_WIN_NULL.
static constexpr auto element_width() noexcept
Sizing helper for disp_unit.
UList< Type > allocate(std::streamsize count, UPstream::Communicator communicator, const bool shared=false)
Allocate a local memory region and create window onto it.
void lock_all(bool exclusive=false)
MPI_Win_lock_all(), optionally as exclusive lock.
Definition: FixedList.H:920
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.
bool fetch_and_op(const UPstream::opCodes opCodeId, const Type &origin, Type &result, int target_rank, int target_disp=0) const
Combine the value of origin into the target and return the resulting value (MPI_Fetch_and_op).
opCodes
Mapping of some MPI op codes.
Definition: UPstream.H:149
void unlock(int rank)
MPI_Win_unlock() for given target rank.
void rhs(fvMatrix< typename Expr::value_type > &m, const Expr &expression)
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
bool put_value(const Type &value, int toProcNo, int target_disp=0) const
Put a single value to given rank.
Window() noexcept
Default construct as MPI_WIN_NULL.
void sync()
MPI_Win_sync() - ignored if the window is not active.
void unlock_all()
MPI_Win_unlock_all()
UList< Type > view_shared(int target_rank) const
Return view of shared memory window content.
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.
void lock(int rank, bool exclusive=false)
MPI_Win_lock() for given target rank (no assertions), optionally as exclusive lock.
bool put(const Type *buffer, std::streamsize count, int toProcNo, int target_disp=0) const
Put buffer contents to given rank.
bool create(std::nullptr_t, UPstream::Communicator comm)
A window exposing a zero-sized memory region.
UList< Type > view() const
Return view of the currently exposed window content. No restriction on the type of memory associated ...
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.
bool local
Definition: EEqn.H:20
const void * pointer() const noexcept
Return as pointer value.
bool is_shared(const bool failNonShared=false) const
Test if the window is a shared memory window.
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.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:105
void close()
MPI_Win_free(). Closes the window view and frees any associated memory,.
bool operator!=(const Window &rhs) const noexcept
Test for inequality.
const direction noexcept
Definition: scalarImpl.H:265
value_type value() const noexcept
Return raw value.
dataTypes
Mapping of some fundamental and aggregate types to MPI data types.
Definition: UPstream.H:107
void mpi_win_locking(int rank, bool exclusive=false)
Entry point to MPI_Win_lock(), MPI_Win_lock_all(), optionally as exclusive lock.
Wrapper for internally indexed communicator label. Always invokes UPstream::allocateCommunicatorCompo...
Definition: UPstream.H:2667
decomposeUsingBbs false
Use bounding boxes (default) or unique decomposition of triangles (i.e. do not duplicate triangles) ...
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...
::Foam::direction rank(const expressions::valueTypeCode) noexcept
The vector-space rank associated with given valueTypeCode.
Definition: exprTraits.C:70
bool get_value(Type &value, int fromProcNo, int target_disp=0) const
Get a single value from given rank.
const T * cdata() const noexcept
Return pointer to the underlying array serving as data storage.
Definition: UListI.H:260
void flush_local_all()
MPI_Win_flush_local_all()
volScalarField & p
void reset() noexcept
Reset to default constructed value (MPI_WIN_NULL)
UList< Type > allocate_shared(std::streamsize count, UPstream::Communicator communicator)
Allocate a shared memory region and create window onto it.
void flush(int rank)
MPI_Win_flush() for given target rank.
Inter-processor communications stream.
Definition: UPstream.H:69
Namespace for OpenFOAM.