19
19
#include < gtest/gtest.h>
20
20
#include < numeric>
21
21
22
+ // Test cases are adapted from slides and exercises of the HLRS course:
23
+ // Introduction to the Message Passing Interface (MPI)
24
+ // Authors: Joel Malard, Alan Simpson, (EPCC)
25
+ // Rolf Rabenseifner, Traugott Streicher, Tobias Haas (HLRS)
26
+ // https://fs.hlrs.de/projects/par/par_prog_ws/pdf/mpi_3.1_rab.pdf
27
+ // https://fs.hlrs.de/projects/par/par_prog_ws/practical/MPI31single.tar.gz
28
+
22
29
TEST (MPI_Window, SharedCommunicator) {
23
30
mpi::communicator world;
24
31
[[maybe_unused]] auto shm = world.split_shared ();
@@ -68,7 +75,7 @@ TEST(MPI_Window, RingOneSidedPut) {
68
75
EXPECT_EQ (sum, (size * (size - 1 )) / 2 );
69
76
}
70
77
71
- TEST (MPI_Window, RingOneSidedAllowShared ) {
78
+ TEST (MPI_Window, RingOneSidedAllocShared ) {
72
79
mpi::communicator world;
73
80
auto shm = world.split_shared ();
74
81
int const rank_shm = shm.rank ();
@@ -91,6 +98,66 @@ TEST(MPI_Window, RingOneSidedAllowShared) {
91
98
EXPECT_EQ (sum, (size_shm * (size_shm - 1 )) / 2 );
92
99
}
93
100
101
+ TEST (MPI_Window, RingOneSidedStoreWinAllocSharedSignal) {
102
+ mpi::communicator world;
103
+ auto shm = world.split_shared ();
104
+
105
+ int const rank_shm = shm.rank ();
106
+ int const size_shm = shm.size ();
107
+ int const right = (rank_shm+1 ) % size_shm;
108
+ int const left = (rank_shm-1 +size_shm) % size_shm;
109
+
110
+ mpi::shared_window<int > win{shm, 1 };
111
+ int *rcv_buf_ptr = win.base (rank_shm);
112
+ win.lock ();
113
+
114
+ int sum = 0 ;
115
+ int snd_buf = rank_shm;
116
+
117
+ MPI_Request rq;
118
+ MPI_Status status;
119
+ int snd_dummy, rcv_dummy;
120
+
121
+ for (int i = 0 ; i < size_shm; ++i) {
122
+ // ... The local Win_syncs are needed to sync the processor and real memory.
123
+ // ... The following pair of syncs is needed that the read-write-rule is fulfilled.
124
+ win.sync ();
125
+
126
+ // ... tag=17: posting to left that rcv_buf is exposed to left, i.e.,
127
+ // the left process is now allowed to store data into the local rcv_buf
128
+ MPI_Irecv (&rcv_dummy, 0 , MPI_INT, right, 17 , shm.get (), &rq);
129
+ MPI_Send (&snd_dummy, 0 , MPI_INT, left, 17 , shm.get ());
130
+ MPI_Wait (&rq, &status);
131
+
132
+ win.sync ();
133
+
134
+ // MPI_Put(&snd_buf, 1, MPI_INT, right, (MPI_Aint) 0, 1, MPI_INT, win);
135
+ // ... is substited by (with offset "right-my_rank" to store into right neigbor's rcv_buf):
136
+ *(rcv_buf_ptr+(right-rank_shm)) = snd_buf;
137
+
138
+
139
+ // ... The following pair of syncs is needed that the write-read-rule is fulfilled.
140
+ win.sync ();
141
+
142
+ // ... The following communication synchronizes the processors in the way
143
+ // that the origin processor has finished the store
144
+ // before the target processor starts to load the data.
145
+ // ... tag=18: posting to right that rcv_buf was stored from left
146
+ MPI_Irecv (&rcv_dummy, 0 , MPI_INT, left, 18 , shm.get (), &rq);
147
+ MPI_Send (&snd_dummy, 0 , MPI_INT, right, 18 , shm.get ());
148
+ MPI_Wait (&rq, &status);
149
+
150
+ win.sync ();
151
+
152
+ snd_buf = *rcv_buf_ptr;
153
+ sum += *rcv_buf_ptr;
154
+ }
155
+
156
+ EXPECT_EQ (sum, (size_shm * (size_shm - 1 )) / 2 );
157
+
158
+ win.unlock ();
159
+ }
160
+
94
161
TEST (MPI_Window, SharedArray) {
95
162
mpi::communicator world;
96
163
auto shm = world.split_shared ();
0 commit comments