1
2 /**
3 * Copyright (C) Mellanox Technologies Ltd. 2001-2014. ALL RIGHTS RESERVED.
4 * Copyright (C) UT-Battelle, LLC. 2014-2015. ALL RIGHTS RESERVED.
5 * See file LICENSE for terms.
6 */
7 extern "C" {
8 #include <uct/api/uct.h>
9 #include <uct/base/uct_iface.h>
10
11 #include <ucs/time/time.h>
12 }
13 #include <common/test.h>
14 #include "uct_test.h"
15 #include "uct_p2p_test.h"
16
17 #ifdef ENABLE_STATS
18
19 #define EXPECT_STAT(_side, _uct_obj, _stat, _exp_val) \
20 do { \
21 uint64_t v = UCS_STATS_GET_COUNTER(_uct_obj(_side())->stats, _stat); \
22 EXPECT_EQ(get_cntr_init(UCS_PP_MAKE_STRING(_side), \
23 UCS_PP_MAKE_STRING(_stat)) + (_exp_val), v); \
24 } while (0)
25
26
27 class test_uct_stats : public uct_p2p_test {
28 public:
test_uct_stats()29 test_uct_stats() : uct_p2p_test(0), lbuf(NULL), rbuf(NULL) {
30 m_comp.func = NULL;
31 m_comp.count = 0;
32 }
33
init()34 virtual void init() {
35 stats_activate();
36 uct_p2p_test::init();
37
38 // Sender EP
39 collect_cntr_init("sender", uct_ep(sender())->stats,
40 UCS_PP_MAKE_STRING(UCT_EP_STAT_FLUSH),
41 UCT_EP_STAT_FLUSH);
42 collect_cntr_init("sender", uct_ep(sender())->stats,
43 UCS_PP_MAKE_STRING(UCT_EP_STAT_FLUSH_WAIT),
44 UCT_EP_STAT_FLUSH_WAIT);
45 collect_cntr_init("sender", uct_ep(sender())->stats,
46 UCS_PP_MAKE_STRING(UCT_EP_STAT_FENCE),
47 UCT_EP_STAT_FENCE);
48 collect_cntr_init("sender", uct_ep(sender())->stats,
49 UCS_PP_MAKE_STRING(UCT_EP_STAT_AM),
50 UCT_EP_STAT_AM);
51 collect_cntr_init("sender", uct_ep(sender())->stats,
52 UCS_PP_MAKE_STRING(UCT_EP_STAT_NO_RES),
53 UCT_EP_STAT_NO_RES);
54 collect_cntr_init("sender", uct_ep(sender())->stats,
55 UCS_PP_MAKE_STRING(UCT_EP_STAT_PENDING),
56 UCT_EP_STAT_PENDING);
57 collect_cntr_init("sender", uct_ep(sender())->stats,
58 UCS_PP_MAKE_STRING(UCT_EP_STAT_ATOMIC),
59 UCT_EP_STAT_ATOMIC);
60
61 // Sender IFACE
62 collect_cntr_init("sender", uct_iface(sender())->stats,
63 UCS_PP_MAKE_STRING(UCT_IFACE_STAT_FLUSH),
64 UCT_IFACE_STAT_FLUSH);
65 collect_cntr_init("sender", uct_iface(sender())->stats,
66 UCS_PP_MAKE_STRING(UCT_IFACE_STAT_FLUSH_WAIT),
67 UCT_IFACE_STAT_FLUSH_WAIT);
68 collect_cntr_init("sender", uct_iface(sender())->stats,
69 UCS_PP_MAKE_STRING(UCT_IFACE_STAT_FENCE),
70 UCT_IFACE_STAT_FENCE);
71
72 // Receiver IFACE
73 collect_cntr_init("receiver", uct_iface(receiver())->stats,
74 UCS_PP_MAKE_STRING(UCT_IFACE_STAT_RX_AM),
75 UCT_IFACE_STAT_RX_AM);
76 collect_cntr_init("receiver", uct_iface(receiver())->stats,
77 UCS_PP_MAKE_STRING(UCT_IFACE_STAT_RX_AM_BYTES),
78 UCT_IFACE_STAT_RX_AM_BYTES);
79 }
80
collect_cntr_init(std::string side,ucs_stats_node_t * stats_node,std::string stat_name,unsigned stat)81 void collect_cntr_init(std::string side, ucs_stats_node_t *stats_node,
82 std::string stat_name, unsigned stat) {
83 cntr_init[side][stat_name] = UCS_STATS_GET_COUNTER(stats_node, stat);
84 }
85
get_cntr_init(std::string side,std::string stat_name)86 size_t get_cntr_init(std::string side, std::string stat_name) {
87 return cntr_init[side][stat_name];
88 }
89
init_bufs(size_t min,size_t max)90 void init_bufs(size_t min, size_t max)
91 {
92 size_t size = ucs_max(min, ucs_min(64ul, max));
93 lbuf = new mapped_buffer(size, 0, sender(), 0, sender().md_attr().cap.access_mem_type);
94 rbuf = new mapped_buffer(size, 0, receiver(), 0, sender().md_attr().cap.access_mem_type);
95 }
96
cleanup()97 virtual void cleanup() {
98 flush();
99 delete lbuf;
100 delete rbuf;
101 uct_p2p_test::cleanup();
102 stats_restore();
103 }
104
uct_ep(const entity & e)105 uct_base_ep_t *uct_ep(const entity &e)
106 {
107 return ucs_derived_of(e.ep(0), uct_base_ep_t);
108 }
109
uct_iface(const entity & e)110 uct_base_iface_t *uct_iface(const entity &e)
111 {
112 return ucs_derived_of(e.iface(), uct_base_iface_t);
113 }
114
am_handler(void * arg,void * data,size_t length,unsigned flags)115 static ucs_status_t am_handler(void *arg, void *data, size_t length,
116 unsigned flags) {
117 return UCS_OK;
118 }
119
purge_cb(uct_pending_req_t * r,void * arg)120 static void purge_cb(uct_pending_req_t *r, void *arg)
121 {
122 }
123
check_am_rx_counters(size_t len)124 void check_am_rx_counters(size_t len) {
125 uint64_t iface_rx_am_init = get_cntr_init("receiver",
126 UCS_PP_MAKE_STRING(UCT_IFACE_STAT_RX_AM));
127 uint64_t v;
128
129 ucs_time_t deadline = ucs::get_deadline();
130 do {
131 short_progress_loop();
132 v = UCS_STATS_GET_COUNTER(uct_iface(receiver())->stats, UCT_IFACE_STAT_RX_AM);
133 } while ((ucs_get_time() < deadline) && (v == iface_rx_am_init));
134
135 EXPECT_STAT(receiver, uct_iface, UCT_IFACE_STAT_RX_AM, 1UL);
136 EXPECT_STAT(receiver, uct_iface, UCT_IFACE_STAT_RX_AM_BYTES, len);
137 }
138
check_atomic_counters()139 void check_atomic_counters() {
140 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_ATOMIC, 1UL);
141 /* give atomic chance to complete */
142 short_progress_loop();
143 }
144
fill_tx_q(int n)145 int fill_tx_q(int n) {
146 int count_wait;
147 int i, max;
148 size_t len;
149
150 max = (n == 0) ? 1024 : n;
151
152 for (count_wait = i = 0; i < max; i++) {
153 len = uct_ep_am_bcopy(sender_ep(), 0, mapped_buffer::pack, lbuf, 0);
154 if (len != lbuf->length()) {
155 if (n == 0) {
156 return 1;
157 }
158 count_wait++;
159 }
160 }
161 return count_wait;
162 }
163
init_completion()164 void init_completion() {
165 m_comp.count = 2;
166 m_comp.func = NULL;
167 }
168
wait_for_completion(ucs_status_t status)169 void wait_for_completion(ucs_status_t status) {
170
171 EXPECT_TRUE(UCS_INPROGRESS == status || UCS_OK == status);
172 if (status == UCS_OK) {
173 --m_comp.count;
174 }
175
176 ucs_time_t deadline = ucs::get_deadline();
177 do {
178 short_progress_loop();
179 } while ((ucs_get_time() < deadline) && (m_comp.count > 1));
180 EXPECT_EQ(1, m_comp.count);
181 }
182
183 protected:
184 mapped_buffer *lbuf, *rbuf;
185 uct_completion_t m_comp;
186 std::map< std::string, std::map< std::string, uint64_t > > cntr_init;
187 };
188
189
190 /* test basic stat counters:
191 * am, put, get, amo, flush and fence
192 */
193 UCS_TEST_SKIP_COND_P(test_uct_stats, am_short,
194 !check_caps(UCT_IFACE_FLAG_AM_SHORT))
195 {
196 uint64_t hdr=0xdeadbeef, send_data=0xfeedf00d;
197 ucs_status_t status;
198
199 init_bufs(0, sender().iface_attr().cap.am.max_short);
200
201 status = uct_iface_set_am_handler(receiver().iface(), 0, am_handler,
202 0, UCT_CB_FLAG_ASYNC);
203 EXPECT_UCS_OK(status);
204
205 UCT_TEST_CALL_AND_TRY_AGAIN(uct_ep_am_short(sender_ep(), 0, hdr, &send_data,
206 sizeof(send_data)), status);
207 EXPECT_UCS_OK(status);
208
209 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_AM, 1UL);
210 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_BYTES_SHORT,
211 sizeof(hdr) + sizeof(send_data));
212 check_am_rx_counters(sizeof(hdr) + sizeof(send_data));
213 }
214
215 UCS_TEST_SKIP_COND_P(test_uct_stats, am_bcopy,
216 !check_caps(UCT_IFACE_FLAG_AM_BCOPY))
217 {
218 ssize_t v;
219 ucs_status_t status;
220
221 init_bufs(0, sender().iface_attr().cap.am.max_bcopy);
222
223 status = uct_iface_set_am_handler(receiver().iface(), 0, am_handler, 0, UCT_CB_FLAG_ASYNC);
224 EXPECT_UCS_OK(status);
225
226 UCT_TEST_CALL_AND_TRY_AGAIN(uct_ep_am_bcopy(sender_ep(), 0, mapped_buffer::pack,
227 lbuf, 0), v);
228 EXPECT_EQ((ssize_t)lbuf->length(), v);
229
230 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_AM, 1UL);
231 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_BYTES_BCOPY,
232 lbuf->length());
233 check_am_rx_counters(lbuf->length());
234 }
235
236 UCS_TEST_SKIP_COND_P(test_uct_stats, am_zcopy,
237 !check_caps(UCT_IFACE_FLAG_AM_ZCOPY))
238 {
239 ucs_status_t status;
240
241 init_bufs(0, sender().iface_attr().cap.am.max_zcopy);
242
243 status = uct_iface_set_am_handler(receiver().iface(), 0, am_handler, 0, UCT_CB_FLAG_ASYNC);
244 EXPECT_UCS_OK(status);
245
246 UCS_TEST_GET_BUFFER_IOV(iov, iovcnt, lbuf->ptr(), lbuf->length(), lbuf->memh(),
247 sender().iface_attr().cap.am.max_iov);
248
249 UCT_TEST_CALL_AND_TRY_AGAIN(uct_ep_am_zcopy(sender_ep(), 0, 0, 0,
250 iov, iovcnt, 0, NULL), status);
251 EXPECT_TRUE(UCS_INPROGRESS == status || UCS_OK == status);
252
253 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_AM, 1UL);
254 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_BYTES_ZCOPY,
255 lbuf->length());
256 check_am_rx_counters(lbuf->length());
257 }
258
259
260 UCS_TEST_SKIP_COND_P(test_uct_stats, put_short,
261 !check_caps(UCT_IFACE_FLAG_PUT_SHORT))
262 {
263 uint64_t send_data=0xfeedf00d;
264 ucs_status_t status;
265
266 init_bufs(0, sender().iface_attr().cap.put.max_short);
267
268 UCT_TEST_CALL_AND_TRY_AGAIN(uct_ep_put_short(sender_ep(), &send_data, sizeof(send_data),
269 rbuf->addr(), rbuf->rkey()), status);
270 EXPECT_UCS_OK(status);
271
272 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_PUT, 1UL);
273 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_BYTES_SHORT,
274 sizeof(send_data));
275 }
276
277 UCS_TEST_SKIP_COND_P(test_uct_stats, put_bcopy,
278 !check_caps(UCT_IFACE_FLAG_PUT_BCOPY))
279 {
280 ssize_t v;
281
282 init_bufs(0, sender().iface_attr().cap.put.max_bcopy);
283
284 UCT_TEST_CALL_AND_TRY_AGAIN(uct_ep_put_bcopy(sender_ep(), mapped_buffer::pack, lbuf,
285 rbuf->addr(), rbuf->rkey()), v);
286 EXPECT_EQ((ssize_t)lbuf->length(), v);
287
288 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_PUT, 1UL);
289 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_BYTES_BCOPY,
290 lbuf->length());
291 }
292
293 UCS_TEST_SKIP_COND_P(test_uct_stats, put_zcopy,
294 !check_caps(UCT_IFACE_FLAG_PUT_ZCOPY))
295 {
296 ucs_status_t status;
297
298 init_bufs(0, sender().iface_attr().cap.put.max_zcopy);
299
300 UCS_TEST_GET_BUFFER_IOV(iov, iovcnt, lbuf->ptr(), lbuf->length(), lbuf->memh(),
301 sender().iface_attr().cap.put.max_iov);
302
303 UCT_TEST_CALL_AND_TRY_AGAIN(
304 uct_ep_put_zcopy(sender_ep(), iov, iovcnt, rbuf->addr(),
305 rbuf->rkey(), 0), status);
306 EXPECT_TRUE(UCS_INPROGRESS == status || UCS_OK == status);
307
308 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_PUT, 1UL);
309 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_BYTES_ZCOPY,
310 lbuf->length());
311 }
312
313
314 UCS_TEST_SKIP_COND_P(test_uct_stats, get_bcopy,
315 !check_caps(UCT_IFACE_FLAG_GET_BCOPY))
316 {
317 ucs_status_t status;
318
319 init_bufs(0, sender().iface_attr().cap.get.max_bcopy);
320
321 init_completion();
322 UCT_TEST_CALL_AND_TRY_AGAIN(
323 uct_ep_get_bcopy(sender_ep(), (uct_unpack_callback_t)memcpy,
324 lbuf->ptr(), lbuf->length(),
325 rbuf->addr(), rbuf->rkey(), &m_comp), status);
326 wait_for_completion(status);
327
328 short_progress_loop();
329 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_GET, 1UL);
330 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_BYTES_BCOPY,
331 lbuf->length());
332 }
333
334 UCS_TEST_SKIP_COND_P(test_uct_stats, get_zcopy,
335 !check_caps(UCT_IFACE_FLAG_GET_ZCOPY))
336 {
337 ucs_status_t status;
338
339 init_bufs(sender().iface_attr().cap.get.min_zcopy,
340 sender().iface_attr().cap.get.max_zcopy);
341
342 UCS_TEST_GET_BUFFER_IOV(iov, iovcnt, lbuf->ptr(), lbuf->length(), lbuf->memh(),
343 sender().iface_attr().cap.get.max_iov);
344
345 init_completion();
346 UCT_TEST_CALL_AND_TRY_AGAIN(
347 uct_ep_get_zcopy(sender_ep(), iov, iovcnt, rbuf->addr(),
348 rbuf->rkey(), &m_comp), status);
349 wait_for_completion(status);
350
351 short_progress_loop();
352 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_GET, 1UL);
353 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_BYTES_ZCOPY,
354 lbuf->length());
355 }
356
357 #define TEST_STATS_ATOMIC_POST(_op, _val) \
358 UCS_TEST_SKIP_COND_P(test_uct_stats, atomic_post_ ## _op ## _val, \
359 !check_atomics(UCS_BIT(UCT_ATOMIC_OP_ ## _op), OP ## _val)) \
360 { \
361 ucs_status_t status; \
362 init_bufs(sizeof(uint##_val##_t), sizeof(uint##_val##_t)); \
363 status = uct_ep_atomic ##_val##_post(sender_ep(), (UCT_ATOMIC_OP_ ## _op), \
364 1, rbuf->addr(), rbuf->rkey()); \
365 EXPECT_UCS_OK(status); \
366 check_atomic_counters(); \
367 }
368
369 TEST_STATS_ATOMIC_POST(ADD, 32)
370 TEST_STATS_ATOMIC_POST(ADD, 64)
371 TEST_STATS_ATOMIC_POST(AND, 32)
372 TEST_STATS_ATOMIC_POST(AND, 64)
373 TEST_STATS_ATOMIC_POST(OR, 32)
374 TEST_STATS_ATOMIC_POST(OR, 64)
375 TEST_STATS_ATOMIC_POST(XOR, 32)
376 TEST_STATS_ATOMIC_POST(XOR, 64)
377
378
379 #define TEST_STATS_ATOMIC_FETCH(_op, _val) \
380 UCS_TEST_SKIP_COND_P(test_uct_stats, atomic_fetch_## _op ## _val, \
381 !check_atomics(UCS_BIT(UCT_ATOMIC_OP_ ## _op), FOP ## _val)) \
382 { \
383 ucs_status_t status; \
384 uint##_val##_t result; \
385 \
386 init_bufs(sizeof(result), sizeof(result)); \
387 \
388 init_completion(); \
389 status = uct_ep_atomic##_val##_fetch(sender_ep(), (UCT_ATOMIC_OP_ ## _op), 1, \
390 &result, rbuf->addr(), rbuf->rkey(), &m_comp); \
391 wait_for_completion(status); \
392 \
393 check_atomic_counters(); \
394 }
395
396 TEST_STATS_ATOMIC_FETCH(ADD, 32)
397 TEST_STATS_ATOMIC_FETCH(ADD, 64)
398 TEST_STATS_ATOMIC_FETCH(AND, 32)
399 TEST_STATS_ATOMIC_FETCH(AND, 64)
400 TEST_STATS_ATOMIC_FETCH(OR, 32)
401 TEST_STATS_ATOMIC_FETCH(OR, 64)
402 TEST_STATS_ATOMIC_FETCH(XOR, 32)
403 TEST_STATS_ATOMIC_FETCH(XOR, 64)
404 TEST_STATS_ATOMIC_FETCH(SWAP, 32)
405 TEST_STATS_ATOMIC_FETCH(SWAP, 64)
406
407 #define TEST_STATS_ATOMIC_CSWAP(val) \
408 UCS_TEST_SKIP_COND_P(test_uct_stats, atomic_cswap##val, \
409 !check_atomics(UCS_BIT(UCT_ATOMIC_OP_CSWAP), FOP ## val)) \
410 { \
411 ucs_status_t status; \
412 uint##val##_t result; \
413 \
414 init_bufs(sizeof(result), sizeof(result)); \
415 \
416 init_completion(); \
417 UCT_TEST_CALL_AND_TRY_AGAIN( \
418 uct_ep_atomic_cswap##val (sender_ep(), 1, 2, rbuf->addr(), \
419 rbuf->rkey(), &result, &m_comp), \
420 status); \
421 wait_for_completion(status); \
422 \
423 check_atomic_counters(); \
424 }
425
426 TEST_STATS_ATOMIC_CSWAP(32)
427 TEST_STATS_ATOMIC_CSWAP(64)
428
UCS_TEST_P(test_uct_stats,flush)429 UCS_TEST_P(test_uct_stats, flush)
430 {
431 ucs_status_t status;
432
433 if (sender_ep()) {
434 status = uct_ep_flush(sender_ep(), 0, NULL);
435 EXPECT_UCS_OK(status);
436 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_FLUSH, 1Ul);
437 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_FLUSH_WAIT, 0UL);
438 }
439
440 status = uct_iface_flush(sender().iface(), 0, NULL);
441 EXPECT_UCS_OK(status);
442 EXPECT_STAT(sender, uct_iface, UCT_IFACE_STAT_FLUSH, 1UL);
443 EXPECT_STAT(sender, uct_iface, UCT_IFACE_STAT_FLUSH_WAIT, 0UL);
444 }
445
UCS_TEST_P(test_uct_stats,fence)446 UCS_TEST_P(test_uct_stats, fence)
447 {
448 ucs_status_t status;
449
450 if (sender_ep()) {
451 status = uct_ep_fence(sender_ep(), 0);
452 EXPECT_UCS_OK(status);
453 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_FENCE, 1UL);
454 }
455
456 status = uct_iface_fence(sender().iface(), 0);
457 EXPECT_UCS_OK(status);
458 EXPECT_STAT(sender, uct_iface, UCT_IFACE_STAT_FENCE, 1UL);
459 }
460
461 /* flush test only check stats on tls with am_bcopy
462 * TODO: full test matrix
463 */
464 UCS_TEST_SKIP_COND_P(test_uct_stats, flush_wait_iface,
465 !check_caps(UCT_IFACE_FLAG_AM_BCOPY))
466 {
467 uint64_t count_wait;
468 ucs_status_t status;
469
470 init_bufs(0, sender().iface_attr().cap.am.max_bcopy);
471
472 status = uct_iface_set_am_handler(receiver().iface(), 0, am_handler, 0, UCT_CB_FLAG_ASYNC);
473 EXPECT_UCS_OK(status);
474
475 fill_tx_q(0);
476 count_wait = 0;
477 do {
478 status = uct_iface_flush(sender().iface(), 0, NULL);
479 if (status == UCS_INPROGRESS) {
480 count_wait++;
481 }
482 progress();
483 } while (status != UCS_OK);
484
485 EXPECT_STAT(sender, uct_iface, UCT_IFACE_STAT_FLUSH, 1UL);
486 EXPECT_STAT(sender, uct_iface, UCT_IFACE_STAT_FLUSH_WAIT, count_wait);
487 }
488
489 UCS_TEST_SKIP_COND_P(test_uct_stats, flush_wait_ep,
490 !check_caps(UCT_IFACE_FLAG_AM_BCOPY))
491 {
492 uint64_t count_wait;
493 ucs_status_t status;
494
495 init_bufs(0, sender().iface_attr().cap.am.max_bcopy);
496
497 status = uct_iface_set_am_handler(receiver().iface(), 0, am_handler, 0, UCT_CB_FLAG_ASYNC);
498 EXPECT_UCS_OK(status);
499
500 fill_tx_q(0);
501 count_wait = 0;
502 do {
503 status = uct_ep_flush(sender_ep(), 0, NULL);
504 if (status == UCS_INPROGRESS) {
505 count_wait++;
506 }
507 progress();
508 } while (status != UCS_OK);
509
510 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_FLUSH, 1UL);
511 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_FLUSH_WAIT, count_wait);
512 }
513
514 /* fence test only check stats on tls with am_bcopy
515 * TODO: full test matrix
516 */
517 UCS_TEST_SKIP_COND_P(test_uct_stats, fence_iface,
518 !check_caps(UCT_IFACE_FLAG_AM_BCOPY))
519 {
520 ucs_status_t status;
521
522 init_bufs(0, sender().iface_attr().cap.am.max_bcopy);
523
524 status = uct_iface_set_am_handler(receiver().iface(), 0, am_handler, 0, UCT_CB_FLAG_ASYNC);
525 EXPECT_UCS_OK(status);
526
527 fill_tx_q(0);
528
529 status = uct_iface_fence(sender().iface(), 0);
530 EXPECT_UCS_OK(status);
531
532 fill_tx_q(0);
533
534 EXPECT_STAT(sender, uct_iface, UCT_IFACE_STAT_FENCE, 1UL);
535 }
536
537 UCS_TEST_SKIP_COND_P(test_uct_stats, fence_ep,
538 !check_caps(UCT_IFACE_FLAG_AM_BCOPY))
539 {
540 ucs_status_t status;
541
542 init_bufs(0, sender().iface_attr().cap.am.max_bcopy);
543
544 status = uct_iface_set_am_handler(receiver().iface(), 0, am_handler, 0, UCT_CB_FLAG_ASYNC);
545 EXPECT_UCS_OK(status);
546
547 fill_tx_q(0);
548
549 status = uct_ep_fence(sender_ep(), 0);
550 EXPECT_UCS_OK(status);
551
552 fill_tx_q(0);
553
554 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_FENCE, 1UL);
555 }
556
557 UCS_TEST_SKIP_COND_P(test_uct_stats, tx_no_res,
558 !check_caps(UCT_IFACE_FLAG_AM_BCOPY))
559 {
560 uint64_t count;
561 ucs_status_t status;
562
563 init_bufs(0, sender().iface_attr().cap.am.max_bcopy);
564
565 status = uct_iface_set_am_handler(receiver().iface(), 0, am_handler, 0, UCT_CB_FLAG_ASYNC);
566 EXPECT_UCS_OK(status);
567 count = fill_tx_q(1024);
568
569 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_NO_RES, count);
570 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_AM, 1024 - count);
571 }
572
573 UCS_TEST_SKIP_COND_P(test_uct_stats, pending_add,
574 !check_caps(UCT_IFACE_FLAG_AM_BCOPY |
575 UCT_IFACE_FLAG_PENDING))
576 {
577 const size_t num_reqs = 5;
578 uct_pending_req_t p_reqs[num_reqs];
579 ssize_t len;
580
581 init_bufs(0, sender().iface_attr().cap.am.max_bcopy);
582
583 EXPECT_UCS_OK(uct_iface_set_am_handler(receiver().iface(), 0, am_handler, 0,
584 UCT_CB_FLAG_ASYNC));
585
586 // Check that counter is not increased if pending_add returns NOT_OK
587 EXPECT_EQ(uct_ep_pending_add(sender().ep(0), &p_reqs[0], 0),
588 UCS_ERR_BUSY);
589 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_PENDING, 0UL);
590
591 // Check that counter gets increased on every successfull pending_add returns NOT_OK
592 fill_tx_q(0);
593
594 UCT_TEST_CALL_AND_TRY_AGAIN(
595 uct_ep_am_bcopy(sender_ep(), 0, mapped_buffer::pack,
596 lbuf, 0), len);
597 if (len == (ssize_t)lbuf->length()) {
598 UCS_TEST_SKIP_R("Can't add to pending");
599 }
600
601 for (size_t i = 0; i < num_reqs; ++i) {
602 p_reqs[i].func = NULL;
603 EXPECT_UCS_OK(uct_ep_pending_add(sender().ep(0), &p_reqs[i], 0));
604 }
605 uct_ep_pending_purge(sender().ep(0), purge_cb, NULL);
606
607 EXPECT_STAT(sender, uct_ep, UCT_EP_STAT_PENDING, num_reqs);
608 }
609
610 UCT_INSTANTIATE_TEST_CASE(test_uct_stats);
611 #endif
612