LCOV - code coverage report
Current view: top level - src/Communicate - Window.hpp (source / functions) Coverage Total Hit
Test: final_report.info Lines: 92.3 % 26 24
Test Date: 2025-09-02 05:42:33 Functions: 100.0 % 5 5

            Line data    Source code
       1              : //
       2              : // Class Window
       3              : //   Defines an interface to perform one-sided communication.
       4              : //   The term RMA stands for remote memory accesss.
       5              : //
       6              : #include "Utility/IpplException.h"
       7              : 
       8              : namespace ippl {
       9              :     namespace mpi {
      10              :         namespace rma {
      11              : 
      12              :             template <TargetComm Target>
      13          120 :             Window<Target>::~Window() {
      14          120 :                 if (win_m != MPI_WIN_NULL) {
      15          120 :                     MPI_Win_free(&win_m);
      16          120 :                     win_m = MPI_WIN_NULL;
      17              :                 }
      18          120 :             }
      19              : 
      20              :             template <TargetComm Target>
      21              :             template <std::contiguous_iterator Iter>
      22          120 :             bool Window<Target>::create(const Communicator& comm, Iter first, Iter last) {
      23              :                 static_assert(isActiveTarget<Target>::value,
      24              :                               "No active target communication window");
      25              : 
      26          120 :                 if (allocated_m) {
      27            0 :                     return false;
      28              :                 }
      29          120 :                 allocated_m = true;
      30              : 
      31          120 :                 count_m       = std::distance(first, last);
      32          120 :                 int dispUnit  = sizeof(typename Iter::value_type);
      33          120 :                 MPI_Aint size = (MPI_Aint)count_m * dispUnit;
      34          120 :                 MPI_Win_create(&(*first), size, dispUnit, MPI_INFO_NULL, comm, &win_m);
      35              : 
      36          120 :                 return allocated_m;
      37              :             }
      38              : 
      39              :             template <TargetComm Target>
      40              :             template <std::contiguous_iterator Iter>
      41              :             bool Window<Target>::attach(const Communicator& comm, Iter first, Iter last) {
      42              :                 if (attached_m) {
      43              :                     return false;
      44              :                 }
      45              :                 attached_m = true;
      46              : 
      47              :                 if (!allocated_m) {
      48              :                     MPI_Win_create_dynamic(MPI_INFO_NULL, comm, &win_m);
      49              :                     allocated_m = true;
      50              :                 }
      51              : 
      52              :                 count_m       = std::distance(first, last);
      53              :                 MPI_Aint size = (MPI_Aint)count_m * sizeof(typename Iter::value_type);
      54              :                 MPI_Win_attach(win_m, &(*first), size);
      55              : 
      56              :                 return attached_m;
      57              :             }
      58              : 
      59              :             template <TargetComm Target>
      60              :             template <std::contiguous_iterator Iter>
      61              :             bool Window<Target>::detach(Iter first) {
      62              :                 if (!attached_m) {
      63              :                     return false;
      64              :                 }
      65              :                 attached_m = false;
      66              :                 MPI_Win_detach(win_m, &(*first));
      67              :                 return true;
      68              :             }
      69              : 
      70              :             template <TargetComm Target>
      71          336 :             void Window<Target>::fence(int asrt) {
      72              :                 static_assert(isActiveTarget<Target>::value,
      73              :                               "No active target communication window");
      74          336 :                 MPI_Win_fence(asrt, win_m);
      75          336 :             }
      76              : 
      77              :             template <TargetComm Target>
      78              :             template <std::contiguous_iterator Iter>
      79              :             void Window<Target>::put(Iter first, Iter last, int dest, unsigned int pos,
      80              :                                      Request* request) {
      81              :                 MPI_Datatype datatype = get_mpi_datatype<typename Iter::value_type>(*first);
      82              :                 auto count            = std::distance(first, last);
      83              :                 if (count > count_m) {
      84              :                     throw IpplException("Window::put", "Count exceeds RMA window size.");
      85              :                 }
      86              :                 if (request == nullptr) {
      87              :                     MPI_Put(&(*first), count, datatype, dest, (MPI_Aint)pos, count, datatype,
      88              :                             win_m);
      89              :                 } else {
      90              :                     MPI_Rput(&(*first), count, datatype, dest, (MPI_Aint)pos, count, datatype,
      91              :                              win_m, *request);
      92              :                 }
      93              :             }
      94              : 
      95              :             template <TargetComm Target>
      96              :             template <typename T>
      97          132 :             void Window<Target>::put(const T& value, int dest, unsigned int pos, Request* request) {
      98          132 :                 this->put(&value, dest, pos, request);
      99          132 :             }
     100              : 
     101              :             template <TargetComm Target>
     102              :             template <typename T>
     103          132 :             void Window<Target>::put(const T* value, int dest, unsigned int pos, Request* request) {
     104          132 :                 MPI_Datatype datatype = get_mpi_datatype<T>(*value);
     105          132 :                 if (request == nullptr) {
     106          132 :                     MPI_Put(value, 1, datatype, dest, (MPI_Aint)pos, 1, datatype, win_m);
     107              :                 } else {
     108            0 :                     MPI_Rput(value, 1, datatype, dest, (MPI_Aint)pos, 1, datatype, win_m, *request);
     109              :                 }
     110          132 :             }
     111              : 
     112              :             template <TargetComm Target>
     113              :             template <std::contiguous_iterator Iter>
     114              :             void Window<Target>::get(Iter first, Iter last, int source, unsigned int pos,
     115              :                                      Request* request) {
     116              :                 MPI_Datatype datatype = get_mpi_datatype<typename Iter::value_type>(*first);
     117              :                 auto count            = std::distance(first, last);
     118              :                 if (count > count_m) {
     119              :                     throw IpplException("Window::put", "Count exceeds RMA window size.");
     120              :                 }
     121              :                 if (request == nullptr) {
     122              :                     MPI_Get(&(*first), count, datatype, source, (MPI_Aint)pos, count, datatype,
     123              :                             win_m);
     124              :                 } else {
     125              :                     MPI_Rget(&(*first), count, datatype, source, (MPI_Aint)pos, count, datatype,
     126              :                              win_m, *request);
     127              :                 }
     128              :             }
     129              : 
     130              :             template <TargetComm Target>
     131              :             template <typename T>
     132              :             void Window<Target>::get(T& value, int source, unsigned int pos, Request* request) {
     133              :                 this->get(&value, source, pos, request);
     134              :             }
     135              : 
     136              :             template <TargetComm Target>
     137              :             template <typename T>
     138              :             void Window<Target>::get(T* value, int source, unsigned int pos, Request* request) {
     139              :                 MPI_Datatype datatype = get_mpi_datatype<T>(*value);
     140              :                 if (request == nullptr) {
     141              :                     MPI_Get(value, 1, datatype, source, (MPI_Aint)pos, 1, datatype, win_m);
     142              :                 } else {
     143              :                     MPI_Rget(value, 1, datatype, source, (MPI_Aint)pos, 1, datatype, win_m,
     144              :                              *request);
     145              :                 }
     146              :             }
     147              : 
     148              :             /*
     149              :              * Passive target communication:
     150              :              */
     151              :             template <TargetComm Target>
     152              :             void Window<Target>::flush(int rank) {
     153              :                 static_assert(!isActiveTarget<Target>::value,
     154              :                               "No passive target communication window");
     155              :                 MPI_Win_flush(rank, win_m);
     156              :             }
     157              : 
     158              :             template <TargetComm Target>
     159              :             void Window<Target>::flushall() {
     160              :                 static_assert(!isActiveTarget<Target>::value,
     161              :                               "No passive target communication window");
     162              :                 MPI_Win_flush_all(win_m);
     163              :             }
     164              : 
     165              :             template <TargetComm Target>
     166              :             void Window<Target>::lock(int locktype, int rank, int asrt) {
     167              :                 static_assert(!isActiveTarget<Target>::value,
     168              :                               "No passive target communication window");
     169              :                 MPI_Win_lock(locktype, rank, asrt, win_m);
     170              :             }
     171              : 
     172              :             template <TargetComm Target>
     173              :             void Window<Target>::lockall(int asrt) {
     174              :                 static_assert(!isActiveTarget<Target>::value,
     175              :                               "No passive target communication window");
     176              :                 MPI_Win_lock_all(asrt, win_m);
     177              :             }
     178              : 
     179              :             template <TargetComm Target>
     180              :             void Window<Target>::unlock(int rank) {
     181              :                 static_assert(!isActiveTarget<Target>::value,
     182              :                               "No passive target communication window");
     183              :                 MPI_Win_unlock(rank, win_m);
     184              :             }
     185              : 
     186              :             template <TargetComm Target>
     187              :             void Window<Target>::unlockall() {
     188              :                 static_assert(!isActiveTarget<Target>::value,
     189              :                               "No passive target communication window");
     190              :                 MPI_Win_unlock_all(win_m);
     191              :             }
     192              : 
     193              :         }  // namespace rma
     194              :     }      // namespace mpi
     195              : }  // namespace ippl
        

Generated by: LCOV version 2.0-1