1 /**
2 * Copyright (C) Mellanox Technologies Ltd. 2001-2015.  ALL RIGHTS RESERVED.
3 * Copyright (C) UT-Battelle, LLC. 2016.  ALL RIGHTS RESERVED.
4 *
5 * See file LICENSE for terms.
6 */
7 
8 #include "test_ucp_atomic.h"
9 extern "C" {
10 #include <ucp/core/ucp_context.h>
11 }
12 
13 std::vector<ucp_test_param>
enum_test_params(const ucp_params_t & ctx_params,const std::string & name,const std::string & test_case_name,const std::string & tls)14 test_ucp_atomic::enum_test_params(const ucp_params_t& ctx_params,
15                                   const std::string& name,
16                                   const std::string& test_case_name,
17                                   const std::string& tls)
18 {
19     std::vector<ucp_test_param> result;
20     generate_test_params_variant(ctx_params, name,
21                                  test_case_name, tls, UCP_ATOMIC_MODE_CPU, result);
22     generate_test_params_variant(ctx_params, name,
23                                  test_case_name, tls, UCP_ATOMIC_MODE_DEVICE, result);
24     generate_test_params_variant(ctx_params, name,
25                                  test_case_name, tls, UCP_ATOMIC_MODE_GUESS, result);
26     return result;
27 }
28 
init()29 void test_ucp_atomic::init() {
30     const char *atomic_mode =
31                     (GetParam().variant == UCP_ATOMIC_MODE_CPU)    ? "cpu" :
32                     (GetParam().variant == UCP_ATOMIC_MODE_DEVICE) ? "device" :
33                     (GetParam().variant == UCP_ATOMIC_MODE_GUESS)  ? "guess" :
34                     "";
35     modify_config("ATOMIC_MODE", atomic_mode);
36     test_ucp_memheap::init();
37 }
38 
39 template <typename T>
blocking_add(entity * e,size_t max_size,void * memheap_addr,ucp_rkey_h rkey,std::string & expected_data)40 void test_ucp_atomic::blocking_add(entity *e,  size_t max_size, void *memheap_addr,
41                                    ucp_rkey_h rkey, std::string& expected_data)
42 {
43     ucs_status_t status;
44     T add, prev;
45 
46     prev = *(T*)memheap_addr;
47     add  = (T)ucs::rand() * (T)ucs::rand();
48 
49     if (sizeof(T) == sizeof(uint32_t)) {
50         status = ucp_atomic_add32(e->ep(), add, (uintptr_t)memheap_addr, rkey);
51     } else if (sizeof(T) == sizeof(uint64_t)) {
52         status = ucp_atomic_add64(e->ep(), add, (uintptr_t)memheap_addr, rkey);
53     } else {
54         status = UCS_ERR_UNSUPPORTED;
55     }
56     ASSERT_UCS_OK(status);
57 
58     expected_data.resize(sizeof(T));
59     *(T*)&expected_data[0] = add + prev;
60 }
61 
unaligned_blocking_add64(entity * e,size_t max_size,void * memheap_addr,ucp_rkey_h rkey,std::string & expected_data)62 void test_ucp_atomic::unaligned_blocking_add64(entity *e,  size_t max_size,
63                                                void *memheap_addr, ucp_rkey_h rkey,
64                                                std::string& expected_data)
65 {
66     ucs_status_t status;
67     {
68         /* Test that unaligned addresses generate error */
69         scoped_log_handler slh(hide_errors_logger);
70         status = ucp_atomic_add64(e->ep(), 0, (uintptr_t)memheap_addr + 1, rkey);
71     }
72     EXPECT_EQ(UCS_ERR_INVALID_PARAM, status);
73     expected_data.clear();
74 }
75 
76 template <typename T>
ucp_atomic_post_nbi(ucp_ep_h ep,ucp_atomic_post_op_t opcode,T value,void * remote_addr,ucp_rkey_h rkey)77 ucs_status_t test_ucp_atomic::ucp_atomic_post_nbi(ucp_ep_h ep, ucp_atomic_post_op_t opcode,
78                                                   T value, void *remote_addr,
79                                                   ucp_rkey_h rkey)
80 {
81     return ucp_atomic_post(ep, opcode, value, sizeof(T), (uintptr_t)remote_addr, rkey);
82 }
83 
84 template <typename T>
ucp_atomic_post_nbx(ucp_ep_h ep,ucp_atomic_op_t opcode,T value,void * remote_addr,ucp_rkey_h rkey)85 ucs_status_t test_ucp_atomic::ucp_atomic_post_nbx(ucp_ep_h ep, ucp_atomic_op_t opcode,
86                                                   T value, void *remote_addr,
87                                                   ucp_rkey_h rkey)
88 {
89     ucp_request_param_t param;
90 
91     param.op_attr_mask    = UCP_OP_ATTR_FIELD_DATATYPE;
92     param.datatype        = ucp_dt_make_contig(sizeof(T));
93     ucs_status_ptr_t sptr = ucp_atomic_op_nbx(ep, opcode, &value, 1,
94                                               (uint64_t)remote_addr, rkey,
95                                               &param);
96     EXPECT_FALSE(UCS_PTR_IS_PTR(sptr));
97 
98     return UCS_PTR_STATUS(sptr);
99 }
100 
101 template <typename T, ucp_atomic_post_op_t OP>
nb_post(entity * e,size_t max_size,void * memheap_addr,ucp_rkey_h rkey,std::string & expected_data)102 void test_ucp_atomic::nb_post(entity *e,  size_t max_size, void *memheap_addr,
103                               ucp_rkey_h rkey, std::string& expected_data)
104 {
105     ucs_status_t status;
106     T val, prev;
107 
108     prev   = *(T*)memheap_addr;
109     val    = (T)ucs::rand() * (T)ucs::rand();
110 
111     status = test_ucp_atomic::ucp_atomic_post_nbi<T>(e->ep(), OP, val, memheap_addr, rkey);
112 
113     if (status == UCS_INPROGRESS) {
114         flush_worker(*e);
115     } else {
116         ASSERT_UCS_OK(status);
117     }
118     expected_data.resize(sizeof(T));
119     *(T*)&expected_data[0] = atomic_op_val<T, OP>(val, prev);
120 }
121 
122 template <typename T, ucp_atomic_op_t OP>
nbx_post(entity * e,size_t max_size,void * memheap_addr,ucp_rkey_h rkey,std::string & expected_data)123 void test_ucp_atomic::nbx_post(entity *e,  size_t max_size, void *memheap_addr,
124                                ucp_rkey_h rkey, std::string& expected_data)
125 {
126     T val, prev;
127 
128     prev   = *(T*)memheap_addr;
129     val    = (T)ucs::rand() * (T)ucs::rand();
130 
131     ASSERT_UCS_OK(test_ucp_atomic::ucp_atomic_post_nbx<T>(e->ep(), OP, val,
132                                                           memheap_addr, rkey));
133 
134     expected_data.resize(sizeof(T));
135     *(T*)&expected_data[0] = nbx_atomic_op_val<T, OP>(val, prev);
136 }
137 
138 template <ucp_atomic_post_op_t OP>
unaligned_nb_post(entity * e,size_t max_size,void * memheap_addr,ucp_rkey_h rkey,std::string & expected_data)139 void test_ucp_atomic::unaligned_nb_post(entity *e,  size_t max_size,
140                                         void *memheap_addr, ucp_rkey_h rkey,
141                                         std::string& expected_data)
142 {
143     ucs_status_t status;
144     {
145         /* Test that unaligned addresses generate error */
146         scoped_log_handler slh(hide_errors_logger);
147         status = test_ucp_atomic::ucp_atomic_post_nbi<uint64_t>
148                 (e->ep(), OP, 0, (void *)((uintptr_t)memheap_addr + 1), rkey);
149     }
150     EXPECT_EQ(UCS_ERR_INVALID_PARAM, status);
151     expected_data.clear();
152 }
153 
154 template <typename T>
ucp_atomic_fetch(ucp_ep_h ep,ucp_atomic_fetch_op_t opcode,T value,T * result,void * remote_addr,ucp_rkey_h rkey)155 ucs_status_ptr_t test_ucp_atomic::ucp_atomic_fetch(ucp_ep_h ep,
156                                                    ucp_atomic_fetch_op_t opcode,
157                                                    T value, T *result,
158                                                    void *remote_addr, ucp_rkey_h rkey)
159 {
160     return ucp_atomic_fetch_nb(ep, opcode, value, result, sizeof(T),
161                                (uintptr_t)remote_addr, rkey, send_completion);
162 }
163 
164 template <typename T, ucp_atomic_fetch_op_t FOP>
nb_fetch(entity * e,size_t max_size,void * memheap_addr,ucp_rkey_h rkey,std::string & expected_data)165 void test_ucp_atomic::nb_fetch(entity *e,  size_t max_size,
166                                void *memheap_addr, ucp_rkey_h rkey,
167                                std::string& expected_data)
168 {
169     void *amo_req;
170     T val, prev, result;
171 
172     prev    = *(T*)memheap_addr;
173     val     = (T)ucs::rand() * (T)ucs::rand();
174 
175     amo_req = test_ucp_atomic::ucp_atomic_fetch<T>(e->ep(), FOP,
176                                                    val, &result, memheap_addr, rkey);
177     if(UCS_PTR_IS_PTR(amo_req)){
178         wait(amo_req);
179     }
180 
181     EXPECT_EQ(prev, result);
182 
183     expected_data.resize(sizeof(T));
184     *(T*)&expected_data[0] = atomic_fop_val<T, FOP>(val, prev);
185 }
186 
187 template <typename T>
nb_cswap(entity * e,size_t max_size,void * memheap_addr,ucp_rkey_h rkey,std::string & expected_data)188 void test_ucp_atomic::nb_cswap(entity *e,  size_t max_size, void *memheap_addr,
189                     ucp_rkey_h rkey, std::string& expected_data)
190 {
191     T compare, swap, prev, result;
192     void *amo_req;
193 
194     prev = *(T*)memheap_addr;
195     if ((ucs::rand() % 2) == 0) {
196         compare = prev; /* success mode */
197     } else {
198         compare = ~prev; /* fail mode */
199     }
200     swap = result = (T)ucs::rand() * (T)ucs::rand();
201 
202     amo_req = test_ucp_atomic::ucp_atomic_fetch<T>(e->ep(), UCP_ATOMIC_FETCH_OP_CSWAP,
203                                                    compare, &result,
204                                                    memheap_addr, rkey);
205     if(UCS_PTR_IS_PTR(amo_req)){
206         wait(amo_req);
207     }
208 
209     EXPECT_EQ(prev, result);
210 
211     expected_data.resize(sizeof(T));
212     if (compare == prev) {
213         *(T*)&expected_data[0] = swap;
214     } else {
215         *(T*)&expected_data[0] = prev;
216     }
217 }
218 
219 template <typename T, typename F>
test(F f,bool malloc_allocate)220 void test_ucp_atomic::test(F f, bool malloc_allocate) {
221     test_blocking_xfer(static_cast<blocking_send_func_t>(f),
222                        DEFAULT_SIZE, DEFAULT_ITERS,
223                        sizeof(T),
224                        malloc_allocate, false);
225 }
226 
227 
228 class test_ucp_atomic32 : public test_ucp_atomic {
229 public:
get_ctx_params()230     static ucp_params_t get_ctx_params() {
231         ucp_params_t params = ucp_test::get_ctx_params();
232         params.features |= UCP_FEATURE_AMO32;
233         return params;
234     }
235 };
236 
UCS_TEST_P(test_ucp_atomic32,atomic_add)237 UCS_TEST_P(test_ucp_atomic32, atomic_add) {
238     test<uint32_t>(&test_ucp_atomic32::blocking_add<uint32_t>, false);
239     test<uint32_t>(&test_ucp_atomic32::blocking_add<uint32_t>, true);
240 }
241 
UCS_TEST_P(test_ucp_atomic32,atomic_add_nb)242 UCS_TEST_P(test_ucp_atomic32, atomic_add_nb) {
243     test<uint32_t>(&test_ucp_atomic32::nb_post<uint32_t, UCP_ATOMIC_POST_OP_ADD>, false);
244     test<uint32_t>(&test_ucp_atomic32::nb_post<uint32_t, UCP_ATOMIC_POST_OP_ADD>, true);
245 }
246 
UCS_TEST_P(test_ucp_atomic32,atomic_add_nbx)247 UCS_TEST_P(test_ucp_atomic32, atomic_add_nbx) {
248     test<uint32_t>(&test_ucp_atomic32::nbx_post<uint32_t, UCP_ATOMIC_OP_ADD>, false);
249     test<uint32_t>(&test_ucp_atomic32::nbx_post<uint32_t, UCP_ATOMIC_OP_ADD>, true);
250 }
251 
UCS_TEST_P(test_ucp_atomic32,atomic_and_nb)252 UCS_TEST_P(test_ucp_atomic32, atomic_and_nb) {
253     test<uint32_t>(&test_ucp_atomic32::nb_post<uint32_t, UCP_ATOMIC_POST_OP_AND>, false);
254     test<uint32_t>(&test_ucp_atomic32::nb_post<uint32_t, UCP_ATOMIC_POST_OP_AND>, true);
255 }
256 
UCS_TEST_P(test_ucp_atomic32,atomic_and_nbx)257 UCS_TEST_P(test_ucp_atomic32, atomic_and_nbx) {
258     test<uint32_t>(&test_ucp_atomic32::nbx_post<uint32_t, UCP_ATOMIC_OP_AND>, false);
259     test<uint32_t>(&test_ucp_atomic32::nbx_post<uint32_t, UCP_ATOMIC_OP_AND>, true);
260 }
261 
UCS_TEST_P(test_ucp_atomic32,atomic_or_nb)262 UCS_TEST_P(test_ucp_atomic32, atomic_or_nb) {
263     test<uint32_t>(&test_ucp_atomic32::nb_post<uint32_t, UCP_ATOMIC_POST_OP_OR>, false);
264     test<uint32_t>(&test_ucp_atomic32::nb_post<uint32_t, UCP_ATOMIC_POST_OP_OR>, true);
265 }
266 
UCS_TEST_P(test_ucp_atomic32,atomic_or_nbx)267 UCS_TEST_P(test_ucp_atomic32, atomic_or_nbx) {
268     test<uint32_t>(&test_ucp_atomic32::nbx_post<uint32_t, UCP_ATOMIC_OP_OR>, false);
269     test<uint32_t>(&test_ucp_atomic32::nbx_post<uint32_t, UCP_ATOMIC_OP_OR>, true);
270 }
271 
UCS_TEST_P(test_ucp_atomic32,atomic_xor_nb)272 UCS_TEST_P(test_ucp_atomic32, atomic_xor_nb) {
273     test<uint32_t>(&test_ucp_atomic32::nb_post<uint32_t, UCP_ATOMIC_POST_OP_XOR>, false);
274     test<uint32_t>(&test_ucp_atomic32::nb_post<uint32_t, UCP_ATOMIC_POST_OP_XOR>, true);
275 }
276 
UCS_TEST_P(test_ucp_atomic32,atomic_xor_nbx)277 UCS_TEST_P(test_ucp_atomic32, atomic_xor_nbx) {
278     test<uint32_t>(&test_ucp_atomic32::nbx_post<uint32_t, UCP_ATOMIC_OP_XOR>, false);
279     test<uint32_t>(&test_ucp_atomic32::nbx_post<uint32_t, UCP_ATOMIC_OP_XOR>, true);
280 }
281 
UCS_TEST_P(test_ucp_atomic32,atomic_fadd_nb)282 UCS_TEST_P(test_ucp_atomic32, atomic_fadd_nb) {
283     test<uint32_t>(&test_ucp_atomic32::nb_fetch<uint32_t, UCP_ATOMIC_FETCH_OP_FADD>, false);
284     test<uint32_t>(&test_ucp_atomic32::nb_fetch<uint32_t, UCP_ATOMIC_FETCH_OP_FADD>, true);
285 }
286 
UCS_TEST_P(test_ucp_atomic32,atomic_fand_nb)287 UCS_TEST_P(test_ucp_atomic32, atomic_fand_nb) {
288     test<uint32_t>(&test_ucp_atomic32::nb_fetch<uint32_t, UCP_ATOMIC_FETCH_OP_FAND>, false);
289     test<uint32_t>(&test_ucp_atomic32::nb_fetch<uint32_t, UCP_ATOMIC_FETCH_OP_FAND>, true);
290 }
291 
UCS_TEST_P(test_ucp_atomic32,atomic_for_nb)292 UCS_TEST_P(test_ucp_atomic32, atomic_for_nb) {
293     test<uint32_t>(&test_ucp_atomic32::nb_fetch<uint32_t, UCP_ATOMIC_FETCH_OP_FOR>, false);
294     test<uint32_t>(&test_ucp_atomic32::nb_fetch<uint32_t, UCP_ATOMIC_FETCH_OP_FOR>, true);
295 }
296 
UCS_TEST_P(test_ucp_atomic32,atomic_fxor_nb)297 UCS_TEST_P(test_ucp_atomic32, atomic_fxor_nb) {
298     test<uint32_t>(&test_ucp_atomic32::nb_fetch<uint32_t, UCP_ATOMIC_FETCH_OP_FXOR>, false);
299     test<uint32_t>(&test_ucp_atomic32::nb_fetch<uint32_t, UCP_ATOMIC_FETCH_OP_FXOR>, true);
300 }
301 
UCS_TEST_P(test_ucp_atomic32,atomic_swap_nb)302 UCS_TEST_P(test_ucp_atomic32, atomic_swap_nb) {
303     test<uint32_t>(&test_ucp_atomic32::nb_fetch<uint32_t, UCP_ATOMIC_FETCH_OP_SWAP>, false);
304     test<uint32_t>(&test_ucp_atomic32::nb_fetch<uint32_t, UCP_ATOMIC_FETCH_OP_SWAP>, true);
305 }
306 
UCS_TEST_P(test_ucp_atomic32,atomic_cswap_nb)307 UCS_TEST_P(test_ucp_atomic32, atomic_cswap_nb) {
308     test<uint32_t>(&test_ucp_atomic32::nb_cswap<uint32_t>, false);
309     test<uint32_t>(&test_ucp_atomic32::nb_cswap<uint32_t>, true);
310 }
311 
312 UCP_INSTANTIATE_TEST_CASE(test_ucp_atomic32)
313 
314 class test_ucp_atomic64 : public test_ucp_atomic {
315 public:
get_ctx_params()316     static ucp_params_t get_ctx_params() {
317         ucp_params_t params = ucp_test::get_ctx_params();
318         params.features |= UCP_FEATURE_AMO64;
319         return params;
320     }
321 };
322 
UCS_TEST_P(test_ucp_atomic64,atomic_add)323 UCS_TEST_P(test_ucp_atomic64, atomic_add) {
324     test<uint64_t>(&test_ucp_atomic64::blocking_add<uint64_t>, false);
325     test<uint64_t>(&test_ucp_atomic64::blocking_add<uint64_t>, true);
326 }
327 
UCS_TEST_P(test_ucp_atomic64,atomic_add_nb)328 UCS_TEST_P(test_ucp_atomic64, atomic_add_nb) {
329     test<uint64_t>(&test_ucp_atomic64::nb_post<uint64_t, UCP_ATOMIC_POST_OP_ADD>, false);
330     test<uint64_t>(&test_ucp_atomic64::nb_post<uint64_t, UCP_ATOMIC_POST_OP_ADD>, true);
331 }
332 
UCS_TEST_P(test_ucp_atomic64,atomic_add_nbx)333 UCS_TEST_P(test_ucp_atomic64, atomic_add_nbx) {
334     test<uint64_t>(&test_ucp_atomic64::nbx_post<uint64_t, UCP_ATOMIC_OP_ADD>, false);
335     test<uint64_t>(&test_ucp_atomic64::nbx_post<uint64_t, UCP_ATOMIC_OP_ADD>, true);
336 }
337 
UCS_TEST_P(test_ucp_atomic64,atomic_and_nb)338 UCS_TEST_P(test_ucp_atomic64, atomic_and_nb) {
339     test<uint64_t>(&test_ucp_atomic64::nb_post<uint64_t, UCP_ATOMIC_POST_OP_AND>, false);
340     test<uint64_t>(&test_ucp_atomic64::nb_post<uint64_t, UCP_ATOMIC_POST_OP_AND>, true);
341 }
342 
UCS_TEST_P(test_ucp_atomic64,atomic_and_nbx)343 UCS_TEST_P(test_ucp_atomic64, atomic_and_nbx) {
344     test<uint64_t>(&test_ucp_atomic64::nbx_post<uint64_t, UCP_ATOMIC_OP_AND>, false);
345     test<uint64_t>(&test_ucp_atomic64::nbx_post<uint64_t, UCP_ATOMIC_OP_AND>, true);
346 }
347 
UCS_TEST_P(test_ucp_atomic64,atomic_or_nb)348 UCS_TEST_P(test_ucp_atomic64, atomic_or_nb) {
349     test<uint64_t>(&test_ucp_atomic64::nb_post<uint64_t, UCP_ATOMIC_POST_OP_OR>, false);
350     test<uint64_t>(&test_ucp_atomic64::nb_post<uint64_t, UCP_ATOMIC_POST_OP_OR>, true);
351 }
352 
UCS_TEST_P(test_ucp_atomic64,atomic_or_nbx)353 UCS_TEST_P(test_ucp_atomic64, atomic_or_nbx) {
354     test<uint64_t>(&test_ucp_atomic64::nbx_post<uint64_t, UCP_ATOMIC_OP_OR>, false);
355     test<uint64_t>(&test_ucp_atomic64::nbx_post<uint64_t, UCP_ATOMIC_OP_OR>, true);
356 }
357 
UCS_TEST_P(test_ucp_atomic64,atomic_xor_nb)358 UCS_TEST_P(test_ucp_atomic64, atomic_xor_nb) {
359     test<uint64_t>(&test_ucp_atomic64::nb_post<uint64_t, UCP_ATOMIC_POST_OP_XOR>, false);
360     test<uint64_t>(&test_ucp_atomic64::nb_post<uint64_t, UCP_ATOMIC_POST_OP_XOR>, true);
361 }
362 
UCS_TEST_P(test_ucp_atomic64,atomic_xor_nbx)363 UCS_TEST_P(test_ucp_atomic64, atomic_xor_nbx) {
364     test<uint64_t>(&test_ucp_atomic64::nbx_post<uint64_t, UCP_ATOMIC_OP_XOR>, false);
365     test<uint64_t>(&test_ucp_atomic64::nbx_post<uint64_t, UCP_ATOMIC_OP_XOR>, true);
366 }
367 
UCS_TEST_P(test_ucp_atomic64,atomic_fadd_nb)368 UCS_TEST_P(test_ucp_atomic64, atomic_fadd_nb) {
369     test<uint64_t>(&test_ucp_atomic64::nb_fetch<uint64_t, UCP_ATOMIC_FETCH_OP_FADD>, false);
370     test<uint64_t>(&test_ucp_atomic64::nb_fetch<uint64_t, UCP_ATOMIC_FETCH_OP_FADD>, true);
371 }
372 
UCS_TEST_P(test_ucp_atomic64,atomic_fand_nb)373 UCS_TEST_P(test_ucp_atomic64, atomic_fand_nb) {
374     test<uint64_t>(&test_ucp_atomic64::nb_fetch<uint64_t, UCP_ATOMIC_FETCH_OP_FAND>, false);
375     test<uint64_t>(&test_ucp_atomic64::nb_fetch<uint64_t, UCP_ATOMIC_FETCH_OP_FAND>, true);
376 }
377 
UCS_TEST_P(test_ucp_atomic64,atomic_for_nb)378 UCS_TEST_P(test_ucp_atomic64, atomic_for_nb) {
379     test<uint64_t>(&test_ucp_atomic64::nb_fetch<uint64_t, UCP_ATOMIC_FETCH_OP_FOR>, false);
380     test<uint64_t>(&test_ucp_atomic64::nb_fetch<uint64_t, UCP_ATOMIC_FETCH_OP_FOR>, true);
381 }
382 
UCS_TEST_P(test_ucp_atomic64,atomic_fxor_nb)383 UCS_TEST_P(test_ucp_atomic64, atomic_fxor_nb) {
384     test<uint64_t>(&test_ucp_atomic64::nb_fetch<uint64_t, UCP_ATOMIC_FETCH_OP_FXOR>, false);
385     test<uint64_t>(&test_ucp_atomic64::nb_fetch<uint64_t, UCP_ATOMIC_FETCH_OP_FXOR>, true);
386 }
387 
UCS_TEST_P(test_ucp_atomic64,atomic_swap_nb)388 UCS_TEST_P(test_ucp_atomic64, atomic_swap_nb) {
389     test<uint64_t>(&test_ucp_atomic64::nb_fetch<uint64_t, UCP_ATOMIC_FETCH_OP_SWAP>, false);
390     test<uint64_t>(&test_ucp_atomic64::nb_fetch<uint64_t, UCP_ATOMIC_FETCH_OP_SWAP>, true);
391 }
392 
UCS_TEST_P(test_ucp_atomic64,atomic_cswap_nb)393 UCS_TEST_P(test_ucp_atomic64, atomic_cswap_nb) {
394     test<uint64_t>(&test_ucp_atomic64::nb_cswap<uint64_t>, false);
395     test<uint64_t>(&test_ucp_atomic64::nb_cswap<uint64_t>, true);
396 }
397 
398 #if ENABLE_PARAMS_CHECK
UCS_TEST_P(test_ucp_atomic64,unaligned_atomic_add)399 UCS_TEST_P(test_ucp_atomic64, unaligned_atomic_add) {
400     test<uint64_t>(&test_ucp_atomic::unaligned_blocking_add64, false);
401     test<uint64_t>(&test_ucp_atomic::unaligned_blocking_add64, true);
402 }
403 
UCS_TEST_P(test_ucp_atomic64,unaligned_atomic_add_nb)404 UCS_TEST_P(test_ucp_atomic64, unaligned_atomic_add_nb) {
405     test<uint64_t>(&test_ucp_atomic::unaligned_nb_post<UCP_ATOMIC_POST_OP_ADD>, false);
406     test<uint64_t>(&test_ucp_atomic::unaligned_nb_post<UCP_ATOMIC_POST_OP_ADD>, true);
407 }
408 
UCS_TEST_P(test_ucp_atomic64,unaligned_atomic_and_nb)409 UCS_TEST_P(test_ucp_atomic64, unaligned_atomic_and_nb) {
410     test<uint64_t>(&test_ucp_atomic::unaligned_nb_post<UCP_ATOMIC_POST_OP_AND>, false);
411     test<uint64_t>(&test_ucp_atomic::unaligned_nb_post<UCP_ATOMIC_POST_OP_AND>, true);
412 }
413 
UCS_TEST_P(test_ucp_atomic64,unaligned_atomic_or_nb)414 UCS_TEST_P(test_ucp_atomic64, unaligned_atomic_or_nb) {
415     test<uint64_t>(&test_ucp_atomic::unaligned_nb_post<UCP_ATOMIC_POST_OP_OR>, false);
416     test<uint64_t>(&test_ucp_atomic::unaligned_nb_post<UCP_ATOMIC_POST_OP_OR>, true);
417 }
418 
UCS_TEST_P(test_ucp_atomic64,unaligned_atomic_xor_nb)419 UCS_TEST_P(test_ucp_atomic64, unaligned_atomic_xor_nb) {
420     test<uint64_t>(&test_ucp_atomic::unaligned_nb_post<UCP_ATOMIC_POST_OP_XOR>, false);
421     test<uint64_t>(&test_ucp_atomic::unaligned_nb_post<UCP_ATOMIC_POST_OP_XOR>, true);
422 }
423 #endif
424 
425 UCP_INSTANTIATE_TEST_CASE(test_ucp_atomic64)
426