11/* *
2- * Copyright (c) NVIDIA CORPORATION & AFFILIATES, 2001-2015 . ALL RIGHTS RESERVED.
2+ * Copyright (c) NVIDIA CORPORATION & AFFILIATES, 2001-2026 . ALL RIGHTS RESERVED.
33* Copyright (c) UT-Battelle, LLC. 2015. ALL RIGHTS RESERVED.
44*
55* See file LICENSE for terms.
@@ -53,6 +53,21 @@ class test_ucp_rma : public test_ucp_memheap {
5353 }
5454 }
5555
56+ ucs_status_ptr_t do_put (size_t size, void *expected_data, ucp_mem_h memh,
57+ void *target_ptr, ucp_rkey_h rkey, void *arg)
58+ {
59+ ucs_memory_type_t *mem_types = reinterpret_cast <ucs_memory_type_t *>(
60+ arg);
61+ mem_buffer::pattern_fill (expected_data, size, ucs::rand (),
62+ mem_types[0 ]);
63+
64+ ucp_request_param_t param;
65+ request_param_init (¶m, memh);
66+
67+ return ucp_put_nbx (sender ().ep (), expected_data, size,
68+ (uintptr_t )target_ptr, rkey, ¶m);
69+ }
70+
5671 void put_b (size_t size, void *expected_data, ucp_mem_h memh,
5772 void *target_ptr, ucp_rkey_h rkey, void *arg)
5873 {
@@ -76,6 +91,16 @@ class test_ucp_rma : public test_ucp_memheap {
7691 rkey, arg);
7792 }
7893
94+ ucs_status_ptr_t do_get (size_t size, void *expected_data, ucp_mem_h memh,
95+ void *target_ptr, ucp_rkey_h rkey)
96+ {
97+ ucp_request_param_t param;
98+ request_param_init (¶m, memh);
99+
100+ return ucp_get_nbx (sender ().ep (), expected_data, size,
101+ (uintptr_t )target_ptr, rkey, ¶m);
102+ }
103+
79104 void get_b (size_t size, void *expected_data, ucp_mem_h memh,
80105 void *target_ptr, ucp_rkey_h rkey, void *arg)
81106 {
@@ -118,7 +143,6 @@ class test_ucp_rma : public test_ucp_memheap {
118143 ucs::supported_mem_type_pairs ();
119144
120145 for (size_t i = 0 ; i < pairs.size (); ++i) {
121-
122146 /* Memory type put/get is fully supported only with new protocols */
123147 if (!is_proto_enabled () && (!UCP_MEM_IS_HOST (pairs[i][0 ]) ||
124148 !UCP_MEM_IS_HOST (pairs[i][1 ]))) {
@@ -209,19 +233,6 @@ class test_ucp_rma : public test_ucp_memheap {
209233 param->memh = memh;
210234 }
211235
212- ucs_status_ptr_t do_put (size_t size, void *expected_data, ucp_mem_h memh,
213- void *target_ptr, ucp_rkey_h rkey, void *arg)
214- {
215- ucs_memory_type_t *mem_types = reinterpret_cast <ucs_memory_type_t *>(arg);
216- mem_buffer::pattern_fill (expected_data, size, ucs::rand (), mem_types[0 ]);
217-
218- ucp_request_param_t param;
219- request_param_init (¶m, memh);
220-
221- return ucp_put_nbx (sender ().ep (), expected_data, size,
222- (uintptr_t )target_ptr, rkey, ¶m);
223- }
224-
225236 ucs_status_ptr_t do_put_iov (size_t size, void *expected_data,
226237 ucp_request_param_t *param, void *target_ptr,
227238 ucp_rkey_h rkey, ucp_dt_iov_t *iov,
@@ -241,16 +252,6 @@ class test_ucp_rma : public test_ucp_memheap {
241252 rkey, param);
242253 }
243254
244- ucs_status_ptr_t do_get (size_t size, void *expected_data, ucp_mem_h memh,
245- void *target_ptr, ucp_rkey_h rkey)
246- {
247- ucp_request_param_t param;
248- request_param_init (¶m, memh);
249-
250- return ucp_get_nbx (sender ().ep (), expected_data, size,
251- (uintptr_t )target_ptr, rkey, ¶m);
252- }
253-
254255 ucs_status_ptr_t do_get_iov (size_t size, void *expected_data,
255256 ucp_request_param_t *param, void *target_ptr,
256257 ucp_rkey_h rkey, ucp_dt_iov_t *iov,
@@ -345,6 +346,114 @@ UCS_TEST_P(test_ucp_rma, proto_disabled_unsupported, "PROTO_ENABLE=n")
345346UCP_INSTANTIATE_TEST_CASE_GPU_AWARE (test_ucp_rma)
346347
347348
349+ class test_ucp_proto_emulation_enable : public test_ucp_rma {
350+ public:
351+ static constexpr size_t SMALL_SIZE = 8 ;
352+ static constexpr size_t BIG_SIZE = 512 * UCS_KBYTE;
353+
354+ static void get_test_variants (std::vector<ucp_test_variant> &variants)
355+ {
356+ add_variant_with_value (variants, UCP_FEATURE_RMA, 0 , " " );
357+ }
358+
359+ test_ucp_proto_emulation_enable ()
360+ {
361+ modify_config (" PROTO_EMULATION_ENABLE" , " n" );
362+ modify_config (" IB_TX_INLINE_RESP" , " 0" , SETENV_IF_NOT_EXIST);
363+ }
364+
365+ protected:
366+ enum rma_op_t {
367+ RMA_OP_PUT,
368+ RMA_OP_GET
369+ };
370+
371+ void run_expect_canceled (rma_op_t op, size_t size)
372+ {
373+ mapped_buffer rbuf (size * 2 , receiver ());
374+ ucs::handle<ucp_rkey_h> rkey = rbuf.rkey (sender ());
375+ mem_buffer lbuf (size, UCS_MEMORY_TYPE_HOST);
376+ ucs_memory_type_t mem_types[] = {UCS_MEMORY_TYPE_HOST,
377+ UCS_MEMORY_TYPE_HOST};
378+
379+ scoped_log_handler slh (wrap_errors_logger);
380+
381+ ucs_status_ptr_t req;
382+ if (op == RMA_OP_PUT) {
383+ req = do_put (size, lbuf.ptr (), NULL , rbuf.ptr (), rkey.get (),
384+ mem_types);
385+ } else {
386+ req = do_get (size, lbuf.ptr (), NULL , rbuf.ptr (), rkey.get ());
387+ }
388+ ucs_status_t status = request_wait (req);
389+ EXPECT_EQ (UCS_ERR_CANCELED, status)
390+ << (op == RMA_OP_PUT ? " put" : " get" ) << " should be canceled" ;
391+
392+ /* Verify PROTO_EMULATION_ENABLE error message was logged */
393+ bool found_rma_msg = false ;
394+ for (const auto &err : m_errors) {
395+ if (err.find (" set UCX_PROTO_EMULATION_ENABLE=y to proceed" ) !=
396+ std::string::npos) {
397+ found_rma_msg = true ;
398+ break ;
399+ }
400+ }
401+ EXPECT_TRUE (found_rma_msg) << " Expected error message with "
402+ " UCX_PROTO_EMULATION_ENABLE=y advice" ;
403+ }
404+
405+ void test_forced_message_sizes (send_func_t send_func)
406+ {
407+ for (const auto &pair : ucs::supported_mem_type_pairs ()) {
408+ if (check_reg_mem_types (sender (), pair[0 ]) &&
409+ check_reg_mem_types (sender (), pair[1 ])) {
410+ test_message_sizes (send_func, SMALL_SIZE, BIG_SIZE, pair[0 ],
411+ pair[1 ], 0 );
412+ }
413+ }
414+ }
415+ };
416+
417+ UCS_TEST_P (test_ucp_proto_emulation_enable, no_zcopy_proto_fails_put_small,
418+ " PROTOS=put/am/*,get/am/*,reconfig" )
419+ {
420+ run_expect_canceled (RMA_OP_PUT, SMALL_SIZE);
421+ }
422+
423+ UCS_TEST_P (test_ucp_proto_emulation_enable, no_zcopy_proto_fails_put_big,
424+ " PROTOS=put/am/*,get/am/*,reconfig" )
425+ {
426+ run_expect_canceled (RMA_OP_PUT, BIG_SIZE);
427+ }
428+
429+ UCS_TEST_P (test_ucp_proto_emulation_enable, no_zcopy_proto_fails_get_small,
430+ " PROTOS=put/am/*,get/am/*,reconfig" )
431+ {
432+ run_expect_canceled (RMA_OP_GET, SMALL_SIZE);
433+ }
434+
435+ UCS_TEST_P (test_ucp_proto_emulation_enable, no_zcopy_proto_fails_get_big,
436+ " PROTOS=put/am/*,get/am/*,reconfig" )
437+ {
438+ run_expect_canceled (RMA_OP_GET, BIG_SIZE);
439+ }
440+
441+ UCS_TEST_P (test_ucp_proto_emulation_enable, get_zcopy_forced_success,
442+ " PROTOS=get/bcopy,get/zcopy,reconfig" )
443+ {
444+ test_forced_message_sizes (static_cast <send_func_t >(&test_ucp_rma::get_b));
445+ }
446+
447+ UCS_TEST_P (test_ucp_proto_emulation_enable, put_zcopy_forced_success,
448+ " PROTOS=put/offload/*,reconfig" )
449+ {
450+ test_forced_message_sizes (static_cast <send_func_t >(&test_ucp_rma::put_b));
451+ }
452+
453+ UCP_INSTANTIATE_TEST_CASE_TLS_GPU_AWARE (test_ucp_proto_emulation_enable, ib,
454+ " ib" )
455+
456+
348457class test_ucp_rma_reg : public test_ucp_rma {
349458public:
350459 static void get_test_variants (std::vector<ucp_test_variant>& variants) {
0 commit comments