@@ -368,73 +368,131 @@ namespace mpi {
368
368
window& operator =(window const &) = delete ;
369
369
window& operator =(window &&) = delete ;
370
370
371
- explicit window (communicator &c, BaseType *base, MPI_Aint size = 0 ) {
371
+ // / Create a window over an existing local memory buffer
372
+ explicit window (communicator &c, BaseType *base, MPI_Aint size = 0 ) noexcept {
372
373
MPI_Win_create (base, size * sizeof (BaseType), alignof (BaseType), MPI_INFO_NULL, c.get (), &win);
373
374
}
374
375
376
+ // / Create a window and allocate memory for a local memory buffer
377
+ explicit window (communicator &c, MPI_Aint size = 0 ) noexcept {
378
+ void *baseptr = nullptr ;
379
+ MPI_Win_allocate (size * sizeof (BaseType), alignof (BaseType), MPI_INFO_NULL, c.get (), &baseptr, &win);
380
+ }
381
+
375
382
~window () {
376
383
if (win != MPI_WIN_NULL) {
377
384
MPI_Win_free (&win);
378
385
}
379
386
}
380
387
381
- operator MPI_Win () const { return win; };
382
- operator MPI_Win*() { return &win; };
388
+ explicit operator MPI_Win () const noexcept { return win; };
389
+ explicit operator MPI_Win*() noexcept { return &win; };
383
390
384
- void fence (int assert = 0 ) const {
391
+ // / Synchronization routine in active target RMA. It opens and closes an access epoch.
392
+ void fence (int assert = 0 ) const noexcept {
385
393
MPI_Win_fence (assert , win);
386
394
}
387
395
396
+ // / Complete all outstanding RMA operations at both the origin and the target
397
+ void flush (int rank = -1 ) const noexcept {
398
+ if (rank < 0 ) {
399
+ MPI_Win_flush_all (win);
400
+ } else {
401
+ MPI_Win_flush (rank, win);
402
+ }
403
+ }
404
+
405
+ // / Synchronize the private and public copies of the window
406
+ void sync () const noexcept {
407
+ MPI_Win_sync (win);
408
+ }
409
+
410
+ // / Starts an RMA access epoch locking access to a particular or all ranks in the window
411
+ void lock (int rank = -1 , int lock_type = MPI_LOCK_SHARED, int assert = 0 ) const noexcept {
412
+ if (rank < 0 ) {
413
+ MPI_Win_lock_all (assert , win);
414
+ } else {
415
+ MPI_Win_lock (lock_type, rank, assert , win);
416
+ }
417
+ }
418
+
419
+ // / Completes an RMA access epoch started by a call to lock()
420
+ void unlock (int rank = -1 ) const noexcept {
421
+ if (rank < 0 ) {
422
+ MPI_Win_unlock_all (win);
423
+ } else {
424
+ MPI_Win_unlock (rank, win);
425
+ }
426
+ }
427
+
428
+ // / Load data from a remote memory window.
388
429
template <typename TargetType = BaseType, typename OriginType>
389
430
std::enable_if_t <has_mpi_type<OriginType> && has_mpi_type<TargetType>, void >
390
- get (OriginType *origin_addr, int origin_count, int target_rank, MPI_Aint target_disp = 0 , int target_count = -1 ) const {
391
- MPI_Datatype origin_datatype = mpi_type<OriginType>::get ();
392
- MPI_Datatype target_datatype = mpi_type<TargetType>::get ();
393
- int target_count_ = target_count < 0 ? origin_count : target_count;
394
- MPI_Get (origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count_, target_datatype, win);
431
+ get (OriginType *origin_addr, int origin_count, int target_rank, MPI_Aint target_disp = 0 , int target_count = -1 ) const noexcept {
432
+ MPI_Datatype origin_datatype = mpi_type<OriginType>::get ();
433
+ MPI_Datatype target_datatype = mpi_type<TargetType>::get ();
434
+ int target_count_ = target_count < 0 ? origin_count : target_count;
435
+ MPI_Get (origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count_, target_datatype, win);
395
436
};
396
437
438
+ // / Store data to a remote memory window.
397
439
template <typename TargetType = BaseType, typename OriginType>
398
440
std::enable_if_t <has_mpi_type<OriginType> && has_mpi_type<TargetType>, void >
399
- put (OriginType *origin_addr, int origin_count, int target_rank, MPI_Aint target_disp = 0 , int target_count = -1 ) const {
400
- MPI_Datatype origin_datatype = mpi_type<OriginType>::get ();
401
- MPI_Datatype target_datatype = mpi_type<TargetType>::get ();
402
- int target_count_ = target_count < 0 ? origin_count : target_count;
403
- MPI_Put (origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count_, target_datatype, win);
441
+ put (OriginType *origin_addr, int origin_count, int target_rank, MPI_Aint target_disp = 0 , int target_count = -1 ) const noexcept {
442
+ MPI_Datatype origin_datatype = mpi_type<OriginType>::get ();
443
+ MPI_Datatype target_datatype = mpi_type<TargetType>::get ();
444
+ int target_count_ = target_count < 0 ? origin_count : target_count;
445
+ MPI_Put (origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count_, target_datatype, win);
404
446
};
405
447
406
- void * get_attr (int win_keyval) const {
448
+ // / Accumulate data into target process through remote memory access.
449
+ template <typename TargetType = BaseType, typename OriginType>
450
+ std::enable_if_t <has_mpi_type<OriginType> && has_mpi_type<TargetType>, void >
451
+ accumulate (OriginType const *origin_addr, int origin_count, int target_rank, MPI_Aint target_disp = 0 , int target_count = -1 , MPI_Op op = MPI_SUM) const noexcept {
452
+ MPI_Datatype origin_datatype = mpi_type<OriginType>::get ();
453
+ MPI_Datatype target_datatype = mpi_type<TargetType>::get ();
454
+ int target_count_ = target_count < 0 ? origin_count : target_count;
455
+ MPI_Accumulate (origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count_, target_datatype, op, win);
456
+ }
457
+
458
+ // / Obtains the value of a window attribute.
459
+ void * get_attr (int win_keyval) const noexcept {
407
460
int flag;
408
461
void *attribute_val;
409
462
MPI_Win_get_attr (win, win_keyval, &attribute_val, &flag);
410
463
assert (flag);
411
464
return attribute_val;
412
465
}
413
- BaseType* base () const { return static_cast <BaseType*>(get_attr (MPI_WIN_BASE)); }
414
- MPI_Aint size () const { return *static_cast <MPI_Aint*>(get_attr (MPI_WIN_SIZE)); }
415
- int disp_unit () const { return *static_cast <int *>(get_attr (MPI_WIN_DISP_UNIT)); }
466
+
467
+ // Expose some commonly used attributes
468
+ BaseType* base () const noexcept { return static_cast <BaseType*>(get_attr (MPI_WIN_BASE)); }
469
+ MPI_Aint size () const noexcept { return *static_cast <MPI_Aint*>(get_attr (MPI_WIN_SIZE)); }
470
+ int disp_unit () const noexcept { return *static_cast <int *>(get_attr (MPI_WIN_DISP_UNIT)); }
416
471
};
417
472
418
473
// / The shared_window class
419
474
template <class BaseType >
420
475
class shared_window : public window <BaseType> {
421
476
public:
422
- shared_window (shared_communicator& c, MPI_Aint size) {
477
+ // / Create a window and allocate memory for a shared memory buffer
478
+ shared_window (shared_communicator& c, MPI_Aint size) noexcept {
423
479
void * baseptr = nullptr ;
424
480
MPI_Win_allocate_shared (size * sizeof (BaseType), alignof (BaseType), MPI_INFO_NULL, c.get (), &baseptr, &(this ->win ));
425
481
}
426
482
427
- std::tuple<MPI_Aint, int , void *> query (int rank = MPI_PROC_NULL) const {
483
+ // / Query a shared memory window
484
+ std::tuple<MPI_Aint, int , void *> query (int rank = MPI_PROC_NULL) const noexcept {
428
485
MPI_Aint size = 0 ;
429
486
int disp_unit = 0 ;
430
487
void *baseptr = nullptr ;
431
488
MPI_Win_shared_query (this ->win , rank, &size, &disp_unit, &baseptr);
432
489
return {size, disp_unit, baseptr};
433
490
}
434
491
435
- MPI_Aint size (int rank = MPI_PROC_NULL) const { return std::get<0 >(query (rank)) / sizeof (BaseType); }
436
- int disp_unit (int rank = MPI_PROC_NULL) const { return std::get<1 >(query (rank)); }
437
- BaseType* base (int rank = MPI_PROC_NULL) const { return static_cast <BaseType*>(std::get<2 >(query (rank))); }
492
+ // Override the commonly used attributes of the window base class
493
+ BaseType* base (int rank = MPI_PROC_NULL) const noexcept { return static_cast <BaseType*>(std::get<2 >(query (rank))); }
494
+ MPI_Aint size (int rank = MPI_PROC_NULL) const noexcept { return std::get<0 >(query (rank)) / sizeof (BaseType); }
495
+ int disp_unit (int rank = MPI_PROC_NULL) const noexcept { return std::get<1 >(query (rank)); }
438
496
};
439
497
440
498
/* -----------------------------------------------------------
0 commit comments