66
77#include " test_mpi.h"
88#include " mpi_util.h"
9+ #include < climits>
910#include < cstring>
1011#include < vector>
1112#include " components/mc/ucc_mc.h"
@@ -85,24 +86,73 @@ class TestMemMap : public TestCase
8586 void run (bool triggered) override
8687 {
8788 (void )triggered; /* mem_map tests don't support triggered mode */
88- ucc_mem_map_params_t map_params;
89- ucc_mem_map_t segment;
90- int rank;
89+ ucc_mem_map_mem_h export_memh = nullptr ;
90+ ucc_mem_map_params_t map_params = {};
91+ ucc_mem_map_t segment = {};
92+ size_t export_size = 0 ;
93+ uint64_t recv_size = 0 ;
94+ int comm_size, peer, rank;
95+ ucc_status_t status;
9196
9297 MPI_Comm_rank (team.comm , &rank);
98+ MPI_Comm_size (team.comm , &comm_size);
9399
94100 /* Set up memory map parameters */
95101 segment.address = test_buffer;
96102 segment.len = buffer_size;
97103 map_params.segments = &segment;
98104 map_params.n_segments = 1 ;
99105
106+ if (!is_export_test) {
107+ /* Import operates on an exchanged serialized export handle. Send
108+ * each rank's blob to its next peer so import never receives a
109+ * NULL or otherwise uninitialized handle.
110+ */
111+ status = ucc_mem_map (team.ctx , UCC_MEM_MAP_MODE_EXPORT ,
112+ &map_params, &export_size, &export_memh);
113+ if (status != UCC_OK ) {
114+ if (status == UCC_ERR_NOT_SUPPORTED ||
115+ status == UCC_ERR_NOT_IMPLEMENTED ) {
116+ test_skip = TEST_SKIP_NOT_SUPPORTED ;
117+ return ;
118+ }
119+ UCC_CHECK (status);
120+ }
121+ if (!export_memh || export_size == 0 ) {
122+ UCC_CHECK (UCC_ERR_INVALID_PARAM );
123+ }
124+
125+ peer = (rank + 1 ) % comm_size;
126+ uint64_t send_size = export_size;
127+ MPI_Sendrecv (&send_size, 1 , MPI_UINT64_T , peer, 1001 ,
128+ &recv_size, 1 , MPI_UINT64_T ,
129+ (rank + comm_size - 1 ) % comm_size, 1001 ,
130+ team.comm , MPI_STATUS_IGNORE );
131+
132+ if (send_size > INT_MAX || recv_size > INT_MAX ) {
133+ UCC_CHECK (UCC_ERR_INVALID_PARAM );
134+ }
135+ memh = ucc_malloc (recv_size, " import memh blob" );
136+ UCC_MALLOC_CHECK (memh);
137+ MPI_Sendrecv (export_memh, static_cast <int >(send_size), MPI_BYTE ,
138+ peer, 1002 , memh, static_cast <int >(recv_size), MPI_BYTE ,
139+ (rank + comm_size - 1 ) % comm_size, 1002 ,
140+ team.comm , MPI_STATUS_IGNORE );
141+ memh_size = recv_size;
142+ }
143+
100144 /* Test memory map */
101- ucc_status_t status = ucc_mem_map (team.ctx , mode, &map_params,
102- &memh_size, &memh);
145+ status = ucc_mem_map (team.ctx , mode, &map_params, &memh_size, &memh);
103146 if (status != UCC_OK ) {
147+ if (export_memh) {
148+ UCC_CHECK (ucc_mem_unmap (&export_memh));
149+ }
104150 if (status == UCC_ERR_NOT_SUPPORTED ||
105151 status == UCC_ERR_NOT_IMPLEMENTED ) {
152+ if (memh) {
153+ ucc_free (memh);
154+ memh = nullptr ;
155+ }
106156 test_skip = TEST_SKIP_NOT_SUPPORTED ;
107157 return ;
108158 }
@@ -112,19 +162,22 @@ class TestMemMap : public TestCase
112162 if (!memh) {
113163 std::cerr << " Rank " << rank << " : Memory handle is NULL"
114164 << std::endl;
115- return ;
165+ UCC_CHECK ( UCC_ERR_INVALID_PARAM ) ;
116166 }
117- if (memh_size == 0 ) {
167+ if (is_export_test && memh_size == 0 ) {
118168 std::cerr << " Rank " << rank << " : Memory handle size is 0"
119169 << std::endl;
120- return ;
170+ UCC_CHECK ( UCC_ERR_INVALID_PARAM ) ;
121171 }
122172
123173 /* Verify data integrity after mapping */
124174 UCC_CHECK (check ());
125175
126176 /* Test unmap */
127177 UCC_CHECK (ucc_mem_unmap (&memh));
178+ if (export_memh) {
179+ UCC_CHECK (ucc_mem_unmap (&export_memh));
180+ }
128181 if (memh != nullptr ) {
129182 std::cerr << " Rank " << rank
130183 << " : Memory handle not NULL after unmap" << std::endl;
@@ -205,9 +258,6 @@ class TestMemMapStress : public TestCase
205258 ucc_mem_unmap (&memh);
206259 }
207260 }
208- if (test_buffer) {
209- ucc_free (test_buffer);
210- }
211261 }
212262
213263 ucc_status_t set_input (int iter_persistent = 0 ) override
@@ -260,8 +310,8 @@ class TestMemMapStress : public TestCase
260310 ucc_mem_map_mem_h memh;
261311 size_t memh_size;
262312
263- /* Fill buffer with iteration-specific pattern */
264- memset (test_buffer, 0xCC + rank + i , buffer_size);
313+ /* Keep the contents stable while repeatedly mapping the buffer. */
314+ memset (test_buffer, 0xBB + rank, buffer_size);
265315
266316 ucc_status_t status = ucc_mem_map (team.ctx , UCC_MEM_MAP_MODE_EXPORT ,
267317 &map_params, &memh_size, &memh);
@@ -528,26 +578,21 @@ void run_mem_map_tests(UccTestMpi *test,
528578 if (!tc) continue ;
529579
530580 if (TEST_SKIP_NONE == tc->test_skip ) {
581+ UCC_CHECK (tc->set_input ());
531582 tc->run (false );
532583 } else {
533584 results.push_back (
534585 std::make_tuple (tc->args .coll_type , UCC_ERR_LAST ));
535586 continue ;
536587 }
537588
538- ucc_status_t status;
539- do {
540- tc->mpi_progress ();
541- status = tc->test ();
542- } while (status == UCC_INPROGRESS );
543-
544- if (UCC_OK != status) {
545- std::cerr << " error during mem_map test: "
546- << ucc_status_string (status) << std::endl;
547- MPI_Abort (MPI_COMM_WORLD , -1 );
589+ if (TEST_SKIP_NONE != tc->test_skip ) {
590+ results.push_back (
591+ std::make_tuple (tc->args .coll_type , UCC_ERR_LAST ));
592+ continue ;
548593 }
549594
550- status = tc->check ();
595+ ucc_status_t status = tc->check ();
551596 results.push_back (
552597 std::make_tuple (tc->args .coll_type , status));
553598 }
0 commit comments