LCOV - code coverage report
Current view: top level - src/Communicate - Window.hpp (source / functions) Coverage Total Hit
Test: final_report.info Lines: 45.8 % 24 11
Test Date: 2025-07-10 08:04:31 Functions: 40.0 % 5 2

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

Generated by: LCOV version 2.0-1