1 /*
2 * Copyright (c) 2015-2017 Los Alamos National Security, LLC.
3 * All rights reserved.
4 * Copyright (c) 2015-2017 Cray Inc. All rights reserved.
5 *
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * BSD license below:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 */
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <errno.h>
38 #include <getopt.h>
39 #include <poll.h>
40 #include <time.h>
41 #include <string.h>
42 #include <pthread.h>
43 #include <unistd.h>
44 #include <limits.h>
45 #include <assert.h>
46
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <inttypes.h>
50
51 #include <criterion/criterion.h>
52 #include "gnix_rdma_headers.h"
53 #include "fi_ext_gni.h"
54 #include "gnix_util.h"
55 #include "common.h"
56
57 #if 1
58 #define dbg_printf(...)
59 #else
60 #define dbg_printf(...) \
61 do { \
62 printf(__VA_ARGS__); \
63 fflush(stdout); \
64 } while (0)
65 #endif
66
67 #define NUMEPS 2
68
69 /* Note: Set to ~FI_NOTIFY_FLAGS_ONLY since this was written before api 1.5 */
70 static uint64_t mode_bits = ~FI_NOTIFY_FLAGS_ONLY;
71 static struct fid_fabric *fab;
72 static struct fid_domain *dom[NUMEPS];
73 struct fi_gni_ops_domain *gni_domain_ops[NUMEPS];
74 static struct fid_ep *ep[NUMEPS];
75 static struct fid_av *av[NUMEPS];
76 void *ep_name[NUMEPS];
77 fi_addr_t gni_addr[NUMEPS];
78 static struct fid_cq *msg_cq[NUMEPS];
79 static struct fi_info *fi[NUMEPS];
80 static struct fi_cq_attr cq_attr;
81 const char *api_cdm_id[NUMEPS] = { "5000", "5001" };
82 struct fi_info *hints[NUMEPS];
83
84 #define BUF_SZ (1<<20)
85 char *target, *target_base;
86 char *source, *source_base;
87 char *uc_target;
88 char *uc_source;
89 struct fid_mr *rem_mr[NUMEPS], *loc_mr[NUMEPS];
90 uint64_t mr_key[NUMEPS];
91
92 static struct fid_cntr *send_cntr[NUMEPS], *recv_cntr[NUMEPS];
93 static struct fi_cntr_attr cntr_attr = {
94 .events = FI_CNTR_EVENTS_COMP,
95 .flags = 0
96 };
97 static uint64_t sends[NUMEPS] = {0}, recvs[NUMEPS] = {0},
98 send_errs[NUMEPS] = {0}, recv_errs[NUMEPS] = {0};
99
rdm_api_setup_ep(uint32_t version,int mr_mode)100 static void rdm_api_setup_ep(uint32_t version, int mr_mode)
101 {
102 int ret, i, j;
103 struct fi_av_attr attr;
104 size_t addrlen = 0;
105
106 /* Get info about fabric services with the provided hints */
107 for (i = 0; i < NUMEPS; i++) {
108 hints[i]->domain_attr->mr_mode = mr_mode;
109
110 ret = fi_getinfo(version, NULL, 0, 0, hints[i],
111 &fi[i]);
112 cr_assert(!ret, "fi_getinfo");
113 }
114
115 memset(&attr, 0, sizeof(attr));
116 attr.type = FI_AV_MAP;
117 attr.count = NUMEPS;
118
119 cq_attr.format = FI_CQ_FORMAT_TAGGED;
120 cq_attr.size = 1024;
121 cq_attr.wait_obj = 0;
122
123 /* 3x BUF_SZ for multi recv testing */
124 target_base = malloc(GNIT_ALIGN_LEN(BUF_SZ * 3));
125 assert(target_base);
126 target = GNIT_ALIGN_BUFFER(char *, target_base);
127
128 source_base = malloc(GNIT_ALIGN_LEN(BUF_SZ));
129 assert(source_base);
130 source = GNIT_ALIGN_BUFFER(char *, source_base);
131
132 uc_target = malloc(BUF_SZ);
133 assert(uc_target);
134
135 uc_source = malloc(BUF_SZ);
136 assert(uc_source);
137
138 ret = fi_fabric(fi[0]->fabric_attr, &fab, NULL);
139 cr_assert(!ret, "fi_fabric");
140
141 for (i = 0; i < NUMEPS; i++) {
142 ret = fi_domain(fab, fi[i], dom + i, NULL);
143 cr_assert(!ret, "fi_domain");
144
145 ret = fi_open_ops(&dom[i]->fid, FI_GNI_DOMAIN_OPS_1,
146 0, (void **) (gni_domain_ops + i), NULL);
147
148 ret = fi_av_open(dom[i], &attr, av + i, NULL);
149 cr_assert(!ret, "fi_av_open");
150
151 ret = fi_endpoint(dom[i], fi[i], ep + i, NULL);
152 cr_assert(!ret, "fi_endpoint");
153
154 ret = fi_cq_open(dom[i], &cq_attr, msg_cq + i, 0);
155 cr_assert(!ret, "fi_cq_open");
156
157 ret = fi_ep_bind(ep[i], &msg_cq[i]->fid, FI_SEND | FI_RECV);
158 cr_assert(!ret, "fi_ep_bind");
159
160 ret = fi_getname(&ep[i]->fid, NULL, &addrlen);
161 cr_assert(addrlen > 0);
162
163 ep_name[i] = malloc(addrlen);
164 cr_assert(ep_name[i] != NULL);
165
166 ret = fi_getname(&ep[i]->fid, ep_name[i], &addrlen);
167 cr_assert(ret == FI_SUCCESS);
168 }
169
170 for (i = 0; i < NUMEPS; i++) {
171 /* Insert all gni addresses into each av */
172 for (j = 0; j < NUMEPS; j++) {
173 ret = fi_av_insert(av[i], ep_name[j], 1, &gni_addr[j],
174 0, NULL);
175 cr_assert(ret == 1);
176 }
177
178 ret = fi_ep_bind(ep[i], &av[i]->fid, 0);
179 cr_assert(!ret, "fi_ep_bind");
180
181 ret = fi_cntr_open(dom[i], &cntr_attr, send_cntr + i, 0);
182 cr_assert(!ret, "fi_cntr_open");
183
184 ret = fi_ep_bind(ep[i], &send_cntr[i]->fid, FI_SEND);
185 cr_assert(!ret, "fi_ep_bind");
186
187 ret = fi_cntr_open(dom[i], &cntr_attr, recv_cntr + i, 0);
188 cr_assert(!ret, "fi_cntr_open");
189
190 ret = fi_ep_bind(ep[i], &recv_cntr[i]->fid, FI_RECV);
191 cr_assert(!ret, "fi_ep_bind");
192
193 ret = fi_enable(ep[i]);
194 cr_assert(!ret, "fi_ep_enable");
195
196 ret = fi_enable(ep[i]);
197 cr_assert_eq(ret, -FI_EOPBADSTATE);
198
199
200 }
201
202 for (i = 0; i < NUMEPS; i++) {
203 int target_requested_key =
204 USING_SCALABLE(fi[i]) ? (i * 2) : 0;
205 int source_requested_key =
206 USING_SCALABLE(fi[i]) ? (i * 2) + 1 : 0;
207
208 ret = fi_mr_reg(dom[i],
209 target,
210 3 * BUF_SZ,
211 FI_REMOTE_WRITE,
212 0,
213 target_requested_key,
214 0,
215 rem_mr + i,
216 &target);
217 cr_assert_eq(ret, 0);
218
219 ret = fi_mr_reg(dom[i],
220 source,
221 BUF_SZ,
222 FI_REMOTE_WRITE,
223 0,
224 source_requested_key,
225 0,
226 loc_mr + i,
227 &source);
228 cr_assert_eq(ret, 0);
229
230 if (USING_SCALABLE(fi[i])) {
231 MR_ENABLE(rem_mr[i], target, 3 * BUF_SZ);
232 MR_ENABLE(loc_mr[i], source, BUF_SZ);
233 }
234
235 mr_key[i] = fi_mr_key(rem_mr[i]);
236 }
237 }
238
__rdm_api_setup(uint32_t version,int mr_mode)239 void __rdm_api_setup(uint32_t version, int mr_mode)
240 {
241 int i;
242
243 SKIP_IF_SCALABLE_LT_1_5(version, mr_mode);
244
245 for (i = 0; i < NUMEPS; i++) {
246 hints[i] = fi_allocinfo();
247 cr_assert(hints[i], "fi_allocinfo");
248
249 hints[i]->domain_attr->cq_data_size = NUMEPS * 2;
250 hints[i]->domain_attr->data_progress = FI_PROGRESS_AUTO;
251 hints[i]->mode = mode_bits;
252 hints[i]->fabric_attr->prov_name = strdup("gni");
253 }
254 }
255
rdm_api_setup_basic(void)256 static void rdm_api_setup_basic(void)
257 {
258 __rdm_api_setup(fi_version(), GNIX_MR_BASIC);
259 }
260
rdm_api_setup_scalable(void)261 static void rdm_api_setup_scalable(void)
262 {
263 __rdm_api_setup(fi_version(), GNIX_MR_SCALABLE);
264 }
265
api_setup(void)266 void api_setup(void)
267 {
268 }
269
api_teardown(void)270 void api_teardown(void)
271 {
272 }
273
rdm_api_teardown_common(bool unreg)274 static void rdm_api_teardown_common(bool unreg)
275 {
276 int ret = 0, i = 0;
277
278 for (; i < NUMEPS; i++) {
279 fi_close(&recv_cntr[i]->fid);
280 fi_close(&send_cntr[i]->fid);
281
282 if (unreg) {
283 fi_close(&loc_mr[i]->fid);
284 fi_close(&rem_mr[i]->fid);
285 }
286
287 ret = fi_close(&ep[i]->fid);
288 cr_assert(!ret, "failure in closing ep.");
289
290 ret = fi_close(&msg_cq[i]->fid);
291 cr_assert(!ret, "failure in send cq.");
292
293 ret = fi_close(&av[i]->fid);
294 cr_assert(!ret, "failure in closing av.");
295
296 ret = fi_close(&dom[i]->fid);
297 cr_assert(!ret, "failure in closing domain.");
298
299 fi_freeinfo(fi[i]);
300 free(ep_name[i]);
301 fi_freeinfo(hints[i]);
302 }
303
304 free(uc_source);
305 free(uc_target);
306 free(target_base);
307 free(source_base);
308
309 ret = fi_close(&fab->fid);
310 cr_assert(!ret, "failure in closing fabric.");
311 }
312
rdm_api_teardown(void)313 static void rdm_api_teardown(void)
314 {
315 rdm_api_teardown_common(true);
316 }
317
rdm_api_init_data(char * buf,int len,char seed)318 void rdm_api_init_data(char *buf, int len, char seed)
319 {
320 int i;
321
322 for (i = 0; i < len; i++)
323 buf[i] = seed++;
324 }
325
rdm_api_check_data(char * buf1,char * buf2,int len)326 int rdm_api_check_data(char *buf1, char *buf2, int len)
327 {
328 int i;
329
330 for (i = 0; i < len; i++) {
331 if (buf1[i] != buf2[i]) {
332 printf("data mismatch, elem: %d, exp: %hhx, act: %hhx\n"
333 , i, buf1[i], buf2[i]);
334 return 0;
335 }
336 }
337
338 return 1;
339 }
340
rdm_api_check_cqe(struct fi_cq_tagged_entry * cqe,void * ctx,uint64_t flags,void * addr,size_t len,uint64_t data,struct fid_ep * fid_ep)341 void rdm_api_check_cqe(struct fi_cq_tagged_entry *cqe, void *ctx,
342 uint64_t flags, void *addr, size_t len,
343 uint64_t data, struct fid_ep *fid_ep)
344 {
345 struct gnix_fid_ep *gnix_ep = get_gnix_ep(fid_ep);
346
347 cr_assert(cqe->op_context == ctx, "CQE Context mismatch");
348 cr_assert(cqe->flags == flags, "CQE flags mismatch");
349
350 if (flags & FI_RECV) {
351 cr_assert(cqe->len == len, "CQE length mismatch");
352 cr_assert(cqe->buf == addr, "CQE address mismatch");
353
354 /* TODO: Remove GNIX_ALLOW_FI_REMOTE_CQ_DATA and only check
355 * flags for FI_RMA_EVENT */
356 if (GNIX_ALLOW_FI_REMOTE_CQ_DATA(flags, gnix_ep->caps))
357 cr_assert(cqe->data == data, "CQE data mismatch");
358 } else {
359 cr_assert(cqe->len == 0, "Invalid CQE length");
360 cr_assert(cqe->buf == 0, "Invalid CQE address");
361 cr_assert(cqe->data == 0, "Invalid CQE data");
362 }
363
364 cr_assert(cqe->tag == 0, "Invalid CQE tag");
365 }
366
rdm_api_check_cntrs(uint64_t s[],uint64_t r[],uint64_t s_e[],uint64_t r_e[])367 void rdm_api_check_cntrs(uint64_t s[], uint64_t r[], uint64_t s_e[],
368 uint64_t r_e[])
369 {
370 int i = 0;
371
372 for (; i < NUMEPS; i++) {
373 sends[i] += s[i];
374 recvs[i] += r[i];
375 send_errs[i] += s_e[i];
376 recv_errs[i] += r_e[i];
377
378 cr_assert(fi_cntr_read(send_cntr[i]) == sends[i],
379 "Bad send count");
380 cr_assert(fi_cntr_read(recv_cntr[i]) == recvs[i],
381 "Bad recv count");
382 cr_assert(fi_cntr_readerr(send_cntr[i]) == send_errs[i],
383 "Bad send err count");
384 cr_assert(fi_cntr_readerr(recv_cntr[i]) == recv_errs[i],
385 "Bad recv err count");
386 }
387 }
388
389 /*******************************************************************************
390 * Test MSG functions
391 ******************************************************************************/
392
393 #define MSG_SEND_ALLOWED(caps) \
394 ((caps & FI_MSG) && ((caps & FI_SEND) || !(caps & FI_RECV)))
395 #define MSG_RECV_ALLOWED(caps) \
396 ((caps & FI_MSG) && ((caps & FI_RECV) || !(caps & FI_SEND)))
397 #define TAG_SEND_ALLOWED(caps) \
398 ((caps & FI_TAGGED) && ((caps & FI_SEND) || !(caps & FI_RECV)))
399 #define TAG_RECV_ALLOWED(caps) \
400 ((caps & FI_TAGGED) && ((caps & FI_RECV) || !(caps & FI_SEND)))
401 #define WRITE_ALLOWED(caps, rcaps) \
402 ((caps & FI_RMA) && \
403 ((caps & FI_WRITE) || !(caps & FI_READ)) && \
404 ((rcaps & FI_RMA) || (rcaps & FI_REMOTE_WRITE)) \
405 )
406 #define READ_ALLOWED(caps, rcaps) \
407 ((caps & FI_RMA) && \
408 ((caps & FI_READ) || !(caps & FI_WRITE)) && \
409 (((rcaps & FI_RMA) && \
410 !(rcaps & (FI_READ | FI_WRITE | FI_REMOTE_WRITE))) || \
411 (rcaps & FI_REMOTE_READ) \
412 ) \
413 )
write_allowed(uint64_t rma_amo,uint64_t caps,uint64_t rcaps)414 static int write_allowed(uint64_t rma_amo, uint64_t caps, uint64_t rcaps)
415 {
416 dbg_printf("write %s caps:%s, rcaps:%s\n",
417 fi_tostr(&rma_amo, FI_TYPE_CAPS),
418 fi_tostr(&caps, FI_TYPE_CAPS),
419 fi_tostr(&rcaps, FI_TYPE_CAPS));
420 if ((caps & rma_amo) &&
421 ((caps & FI_WRITE) || !(caps & FI_READ))) {
422 if ((rcaps & rma_amo) &&
423 ((rcaps & FI_REMOTE_WRITE) ||
424 (!(rcaps & (FI_READ | FI_WRITE | FI_REMOTE_READ)))
425 )
426 ) {
427 return 1;
428 }
429 }
430 return 0;
431 }
432
read_allowed(uint64_t rma_amo,uint64_t caps,uint64_t rcaps)433 static int read_allowed(uint64_t rma_amo, uint64_t caps, uint64_t rcaps)
434 {
435 dbg_printf("read %s caps:%s, rcaps:%s\n",
436 fi_tostr(&rma_amo, FI_TYPE_CAPS),
437 fi_tostr(&caps, FI_TYPE_CAPS),
438 fi_tostr(&rcaps, FI_TYPE_CAPS));
439 if ((caps & rma_amo) &&
440 ((caps & FI_READ) || !(caps & FI_WRITE))) {
441 if ((rcaps & rma_amo) &&
442 ((rcaps & FI_REMOTE_READ) ||
443 (!(rcaps & (FI_READ | FI_WRITE | FI_REMOTE_WRITE)))
444 )
445 ) {
446 return 1;
447 }
448 }
449 return 0;
450 }
451
452 TestSuite(rdm_api_basic,
453 .init = rdm_api_setup_basic,
454 .fini = rdm_api_teardown);
455
456 TestSuite(rdm_api_scalable,
457 .init = rdm_api_setup_scalable,
458 .fini = rdm_api_teardown);
459
460 /*
461 * ssize_t fi_send(struct fid_ep *ep, void *buf, size_t len,
462 * void *desc, fi_addr_t dest_addr, void *context);
463 *
464 * ssize_t fi_recv(struct fid_ep *ep, void * buf, size_t len,
465 * void *desc, fi_addr_t src_addr, void *context);
466 */
api_send_recv(int len)467 void api_send_recv(int len)
468 {
469 ssize_t sz;
470 uint64_t caps = fi[0]->caps;
471
472 rdm_api_init_data(source, len, 0xab);
473 rdm_api_init_data(target, len, 0);
474
475 sz = fi_send(ep[0], source, len, loc_mr[0], gni_addr[1], target);
476 if (MSG_SEND_ALLOWED(caps)) {
477 cr_assert(sz == 0, "fi_send failed caps:0x%lx err:%ld",
478 caps, sz);
479 } else {
480 cr_assert(sz < 0, "fi_send should fail caps:0x%lx err:%ld",
481 caps, sz);
482 }
483
484 sz = fi_recv(ep[1], target, len, rem_mr[1], gni_addr[0], source);
485 if (MSG_RECV_ALLOWED(caps)) {
486 cr_assert(sz == 0, "fi_recv failed caps:0x%lx err:%ld",
487 caps, sz);
488 } else {
489 cr_assert(sz < 0, "fi_recv should fail caps:0x%lx err:%ld",
490 caps, sz);
491 }
492 }
493
Test(api,dom_caps)494 Test(api, dom_caps)
495 {
496 int ret;
497
498 hints[0] = fi_allocinfo();
499 cr_assert(hints[0], "fi_allocinfo");
500
501 hints[0]->mode = mode_bits;
502 hints[0]->fabric_attr->prov_name = strdup("gni");
503 hints[0]->domain_attr->mr_mode = GNIX_DEFAULT_MR_MODE;
504
505 /* we only support REMOTE_COMM */
506 hints[0]->domain_attr->caps = FI_LOCAL_COMM;
507 ret = fi_getinfo(fi_version(), NULL, 0, 0, hints[0], &fi[0]);
508 cr_assert_eq(ret, -FI_ENODATA, "fi_getinfo");
509
510 hints[0]->domain_attr->caps = FI_REMOTE_COMM;
511 ret = fi_getinfo(fi_version(), NULL, 0, 0, hints[0], &fi[0]);
512 cr_assert_eq(ret, 0, "fi_getinfo");
513
514 fi_freeinfo(fi[0]);
515
516 hints[0]->domain_attr->mr_mode = FI_MR_UNSPEC;
517 ret = fi_getinfo(FI_VERSION(1, 0), NULL, 0, 0, hints[0], &fi[0]);
518 cr_assert_eq(ret, 0, "fi_getinfo");
519
520 fi_freeinfo(hints[0]);
521 fi_freeinfo(fi[0]);
522 }
523
__msg_no_caps(uint32_t version,int mr_mode)524 static inline void __msg_no_caps(uint32_t version, int mr_mode)
525 {
526 hints[0]->caps = 0;
527 hints[1]->caps = 0;
528 rdm_api_setup_ep(version, mr_mode);
529 api_send_recv(BUF_SZ);
530 }
531
Test(rdm_api_basic,msg_no_caps)532 Test(rdm_api_basic, msg_no_caps)
533 {
534 __msg_no_caps(fi_version(), GNIX_MR_BASIC);
535 }
536
Test(rdm_api_scalable,msg_no_caps)537 Test(rdm_api_scalable, msg_no_caps)
538 {
539 __msg_no_caps(fi_version(), GNIX_MR_SCALABLE);
540 }
541
__msg_send_rcv(uint32_t version,int mr_mode)542 static inline void __msg_send_rcv(uint32_t version, int mr_mode)
543 {
544 hints[0]->caps = FI_MSG;
545 hints[1]->caps = FI_MSG;
546 rdm_api_setup_ep(version, mr_mode);
547 api_send_recv(BUF_SZ);
548 }
549
Test(rdm_api_basic,msg_send_rcv)550 Test(rdm_api_basic, msg_send_rcv)
551 {
552 __msg_send_rcv(fi_version(), GNIX_MR_BASIC);
553 }
554
Test(rdm_api_scalable,msg_send_rcv)555 Test(rdm_api_scalable, msg_send_rcv)
556 {
557 __msg_send_rcv(fi_version(), GNIX_MR_SCALABLE);
558 }
559
__msg_send_only(uint32_t version,int mr_mode)560 static inline void __msg_send_only(uint32_t version, int mr_mode)
561 {
562 hints[0]->caps = FI_MSG | FI_SEND;
563 hints[1]->caps = FI_MSG | FI_SEND;
564 rdm_api_setup_ep(version, mr_mode);
565 api_send_recv(BUF_SZ);
566 }
567
Test(rdm_api_basic,msg_send_only)568 Test(rdm_api_basic, msg_send_only)
569 {
570 __msg_send_only(fi_version(), GNIX_MR_BASIC);
571 }
572
Test(rdm_api_scalable,msg_send_only)573 Test(rdm_api_scalable, msg_send_only)
574 {
575 __msg_send_only(fi_version(), GNIX_MR_SCALABLE);
576 }
577
__msg_recv_only(uint32_t version,int mr_mode)578 static inline void __msg_recv_only(uint32_t version, int mr_mode)
579 {
580 hints[0]->caps = FI_MSG | FI_RECV;
581 hints[1]->caps = FI_MSG | FI_RECV;
582 rdm_api_setup_ep(version, mr_mode);
583 api_send_recv(BUF_SZ);
584 }
585
Test(rdm_api_basic,msg_recv_only)586 Test(rdm_api_basic, msg_recv_only)
587 {
588 __msg_recv_only(fi_version(), GNIX_MR_BASIC);
589 }
590
Test(rdm_api_scalable,msg_recv_only)591 Test(rdm_api_scalable, msg_recv_only)
592 {
593 __msg_recv_only(fi_version(), GNIX_MR_SCALABLE);
594 }
595
__msg_send_rcv_w_tagged(uint32_t version,int mr_mode)596 static inline void __msg_send_rcv_w_tagged(uint32_t version, int mr_mode)
597 {
598 hints[0]->caps = FI_TAGGED;
599 hints[1]->caps = FI_TAGGED;
600 rdm_api_setup_ep(version, mr_mode);
601 api_send_recv(BUF_SZ);
602 }
603
Test(rdm_api_basic,msg_send_rcv_w_tagged)604 Test(rdm_api_basic, msg_send_rcv_w_tagged)
605 {
606 __msg_send_rcv_w_tagged(fi_version(), GNIX_MR_BASIC);
607 }
608
Test(rdm_api_scalable,msg_send_rcv_w_tagged)609 Test(rdm_api_scalable, msg_send_rcv_w_tagged)
610 {
611 __msg_send_rcv_w_tagged(fi_version(), GNIX_MR_SCALABLE);
612 }
613
api_tagged_send_recv(int len)614 void api_tagged_send_recv(int len)
615 {
616 ssize_t sz;
617 uint64_t caps = fi[0]->caps;
618
619 rdm_api_init_data(source, len, 0xab);
620 rdm_api_init_data(target, len, 0);
621
622 sz = fi_tsend(ep[0], source, len, loc_mr, gni_addr[1], len, target);
623 if (TAG_SEND_ALLOWED(caps)) {
624 cr_assert(sz == 0, "fi_tsend failed caps:0x%lx err:%ld",
625 caps, sz);
626 } else {
627 cr_assert(sz < 0, "fi_tsend should fail caps:0x%lx err:%ld",
628 caps, sz);
629 }
630
631 sz = fi_trecv(ep[1], target, len, rem_mr, gni_addr[0], len, 0, source);
632 if (TAG_RECV_ALLOWED(caps)) {
633 cr_assert(sz == 0, "fi_trecv failed caps:0x%lx err:%ld",
634 caps, sz);
635 } else {
636 cr_assert(sz < 0, "fi_trecv should fail caps:0x%lx err:%ld",
637 caps, sz);
638 }
639 }
640
__tsend(uint32_t version,int mr_mode)641 static inline void __tsend(uint32_t version, int mr_mode)
642 {
643 hints[0]->caps = FI_TAGGED;
644 hints[1]->caps = FI_TAGGED;
645 rdm_api_setup_ep(version, mr_mode);
646 api_tagged_send_recv(BUF_SZ);
647 }
648
Test(rdm_api_basic,tsend)649 Test(rdm_api_basic, tsend)
650 {
651 __tsend(fi_version(), GNIX_MR_BASIC);
652 }
653
Test(rdm_api_scalable,tsend)654 Test(rdm_api_scalable, tsend)
655 {
656 __tsend(fi_version(), GNIX_MR_SCALABLE);
657 }
658
__tsend_only(uint32_t version,int mr_mode)659 static inline void __tsend_only(uint32_t version, int mr_mode)
660 {
661 hints[0]->caps = FI_TAGGED | FI_SEND;
662 hints[1]->caps = FI_TAGGED | FI_SEND;
663 rdm_api_setup_ep(version, mr_mode);
664 api_tagged_send_recv(BUF_SZ);
665 }
666
Test(rdm_api_basic,tsend_only)667 Test(rdm_api_basic, tsend_only)
668 {
669 __tsend_only(fi_version(), GNIX_MR_BASIC);
670 }
671
Test(rdm_api_scalable,tsend_only)672 Test(rdm_api_scalable, tsend_only)
673 {
674 __tsend_only(fi_version(), GNIX_MR_SCALABLE);
675 }
676
__trecv_only(uint32_t version,int mr_mode)677 static inline void __trecv_only(uint32_t version, int mr_mode)
678 {
679 hints[0]->caps = FI_TAGGED | FI_RECV;
680 hints[1]->caps = FI_TAGGED | FI_RECV;
681 rdm_api_setup_ep(version, mr_mode);
682 api_tagged_send_recv(BUF_SZ);
683 }
684
Test(rdm_api_basic,trecv_only)685 Test(rdm_api_basic, trecv_only)
686 {
687 __trecv_only(fi_version(), GNIX_MR_BASIC);
688 }
689
Test(rdm_api_scalable,trecv_only)690 Test(rdm_api_scalable, trecv_only)
691 {
692 __trecv_only(fi_version(), GNIX_MR_SCALABLE);
693 }
694
__tsend_rcv_w_msg(uint32_t version,int mr_mode)695 static inline void __tsend_rcv_w_msg(uint32_t version, int mr_mode)
696 {
697 hints[0]->caps = FI_MSG;
698 hints[1]->caps = FI_MSG;
699 rdm_api_setup_ep(version, mr_mode);
700 api_tagged_send_recv(BUF_SZ);
701 }
702
Test(rdm_api_basic,tsend_rcv_w_msg)703 Test(rdm_api_basic, tsend_rcv_w_msg)
704 {
705 __tsend_rcv_w_msg(fi_version(), GNIX_MR_BASIC);
706 }
707
Test(rdm_api_scalable,tsend_rcv_w_msg)708 Test(rdm_api_scalable, tsend_rcv_w_msg)
709 {
710 __tsend_rcv_w_msg(fi_version(), GNIX_MR_SCALABLE);
711 }
712
713 #define READ_CTX 0x4e3dda1aULL
api_write_read(int len)714 void api_write_read(int len)
715 {
716 int ret;
717 struct fi_cq_tagged_entry cqe;
718 struct fi_cq_err_entry err_cqe = {0};
719
720 rdm_api_init_data(source, len, 0xab);
721 rdm_api_init_data(target, len, 0);
722
723 fi_write(ep[0], source, len,
724 loc_mr[0], gni_addr[1],
725 _REM_ADDR(fi[0], target, target), mr_key[1],
726 target);
727
728 while ((ret = fi_cq_read(msg_cq[0], &cqe, 1)) == -FI_EAGAIN)
729 pthread_yield();
730
731 if (ret == -FI_EAVAIL) {
732 fi_cq_readerr(msg_cq[0], &err_cqe, 0);
733 dbg_printf("fi_cq_readerr err:%d\n", err_cqe.err);
734 }
735
736 if (write_allowed(FI_RMA, fi[0]->caps, fi[1]->caps)) {
737 cr_assert(ret == 1,
738 "fi_write failed caps:0x%lx ret:%d",
739 fi[0]->caps, ret);
740 } else {
741 cr_assert(err_cqe.err == FI_EOPNOTSUPP,
742 "fi_write should fail caps:0x%lx err:%d",
743 fi[0]->caps, err_cqe.err);
744 }
745
746 fi_read(ep[0], source, len,
747 loc_mr[0], gni_addr[1],
748 _REM_ADDR(fi[0], target, target), mr_key[1],
749 (void *)READ_CTX);
750
751 while ((ret = fi_cq_read(msg_cq[0], &cqe, 1)) == -FI_EAGAIN)
752 pthread_yield();
753
754 if (ret == -FI_EAVAIL) {
755 fi_cq_readerr(msg_cq[0], &err_cqe, 0);
756 dbg_printf("fi_cq_readerr err:%d\n", err_cqe.err);
757 }
758
759 if (read_allowed(FI_RMA, fi[0]->caps, fi[1]->caps)) {
760 cr_assert(ret == 1,
761 "fi_read failed caps:0x%lx rcaps:0x%lx",
762 fi[0]->caps, fi[1]->caps);
763 } else {
764 cr_assert(err_cqe.err == FI_EOPNOTSUPP,
765 "fi_read should fail caps:0x%lx rcaps:0x%lx",
766 fi[0]->caps, fi[1]->caps);
767 }
768 }
769
__rma_only(uint32_t version,int mr_mode)770 static inline void __rma_only(uint32_t version, int mr_mode)
771 {
772 hints[0]->caps = FI_RMA;
773 hints[1]->caps = FI_RMA;
774 rdm_api_setup_ep(version, mr_mode);
775 api_write_read(BUF_SZ);
776 }
777
Test(rdm_api_basic,rma_only)778 Test(rdm_api_basic, rma_only)
779 {
780 __rma_only(fi_version(), GNIX_MR_BASIC);
781 }
782
Test(rdm_api_scalable,rma_only)783 Test(rdm_api_scalable, rma_only)
784 {
785 __rma_only(fi_version(), GNIX_MR_SCALABLE);
786 }
787
__rma_write_only(uint32_t version,int mr_mode)788 static inline void __rma_write_only(uint32_t version, int mr_mode)
789 {
790 hints[0]->caps = FI_RMA | FI_WRITE;
791 hints[1]->caps = FI_RMA | FI_REMOTE_WRITE;
792 rdm_api_setup_ep(version, mr_mode);
793 api_write_read(BUF_SZ);
794 }
795
796 Test(rdm_api_basic, rma_write_only, .disabled = true)
797 {
798 __rma_write_only(fi_version(), GNIX_MR_BASIC);
799 }
800
801 Test(rdm_api_scalable, rma_write_only, .disabled = true)
802 {
803 __rma_write_only(fi_version(), GNIX_MR_SCALABLE);
804 }
805
__rma_write_no_remote(uint32_t version,int mr_mode)806 static inline void __rma_write_no_remote(uint32_t version, int mr_mode)
807 {
808 hints[0]->caps = FI_RMA | FI_WRITE;
809 hints[1]->caps = FI_RMA | FI_WRITE;
810 rdm_api_setup_ep(version, mr_mode);
811 api_write_read(BUF_SZ);
812 }
813
Test(rdm_api_basic,rma_write_no_remote)814 Test(rdm_api_basic, rma_write_no_remote)
815 {
816 __rma_write_no_remote(fi_version(), GNIX_MR_BASIC);
817 }
818
Test(rdm_api_scalable,rma_write_no_remote)819 Test(rdm_api_scalable, rma_write_no_remote)
820 {
821 __rma_write_no_remote(fi_version(), GNIX_MR_SCALABLE);
822 }
823
__rma_read_only(uint32_t version,int mr_mode)824 static inline void __rma_read_only(uint32_t version, int mr_mode)
825 {
826 hints[0]->caps = FI_RMA | FI_READ;
827 hints[1]->caps = FI_RMA | FI_REMOTE_READ;
828 rdm_api_setup_ep(version, mr_mode);
829 api_write_read(BUF_SZ);
830 }
831
832 Test(rdm_api_basic, rma_read_only, .disabled = true)
833 {
834 __rma_read_only(fi_version(), GNIX_MR_BASIC);
835 }
836
Test(rdm_api_scalable,rma_read_only)837 Test(rdm_api_scalable, rma_read_only)
838 {
839 __rma_read_only(fi_version(), GNIX_MR_SCALABLE);
840 }
841
__rma_read_no_remote(uint32_t version,int mr_mode)842 static inline void __rma_read_no_remote(uint32_t version, int mr_mode)
843 {
844 hints[0]->caps = FI_RMA | FI_READ;
845 hints[1]->caps = FI_RMA | FI_READ;
846 rdm_api_setup_ep(version, mr_mode);
847 api_write_read(BUF_SZ);
848 }
849
Test(rdm_api_basic,rma_read_no_remote)850 Test(rdm_api_basic, rma_read_no_remote)
851 {
852 __rma_read_no_remote(fi_version(), GNIX_MR_BASIC);
853 }
854
Test(rdm_api_scalable,rma_read_no_remote)855 Test(rdm_api_scalable, rma_read_no_remote)
856 {
857 __rma_read_no_remote(fi_version(), GNIX_MR_SCALABLE);
858 }
859
__rma_write_read_w_msg(uint32_t version,int mr_mode)860 static inline void __rma_write_read_w_msg(uint32_t version, int mr_mode)
861 {
862 hints[0]->caps = FI_MSG;
863 hints[1]->caps = FI_MSG;
864 rdm_api_setup_ep(version, mr_mode);
865 api_write_read(BUF_SZ);
866 }
867
Test(rdm_api_basic,rma_write_read_w_msg)868 Test(rdm_api_basic, rma_write_read_w_msg)
869 {
870 __rma_write_read_w_msg(fi_version(), GNIX_MR_BASIC);
871 }
872
Test(rdm_api_scalable,rma_write_read_w_msg)873 Test(rdm_api_scalable, rma_write_read_w_msg)
874 {
875 __rma_write_read_w_msg(fi_version(), GNIX_MR_SCALABLE);
876 }
877
api_do_read_buf(void)878 void api_do_read_buf(void)
879 {
880 int ret;
881 int len = 8*1024;
882 ssize_t sz;
883 struct fi_cq_tagged_entry cqe;
884 struct fi_cq_err_entry err_cqe;
885
886 rdm_api_init_data(source, BUF_SZ, 0);
887 rdm_api_init_data(target, BUF_SZ, 0xad);
888
889 /* cause a chained transaction */
890 sz = fi_read(ep[0], source+6, len,
891 loc_mr[0], gni_addr[1],
892 _REM_ADDR(fi[0], target, target+6), mr_key[1],
893 (void *)READ_CTX);
894 cr_assert_eq(sz, 0);
895
896 while ((ret = fi_cq_read(msg_cq[0], &cqe, 1)) == -FI_EAGAIN)
897 pthread_yield();
898
899 if (ret == -FI_EAVAIL) {
900 fi_cq_readerr(msg_cq[0], &err_cqe, 0);
901 dbg_printf("fi_cq_readerr err:%d\n", err_cqe.err);
902 }
903
904 if (read_allowed(FI_RMA, fi[0]->caps, fi[1]->caps)) {
905 cr_assert(ret == 1,
906 "fi_read failed caps:0x%lx rcaps:0x%lx",
907 fi[0]->caps, fi[1]->caps);
908 } else {
909 cr_assert(err_cqe.err == FI_EOPNOTSUPP,
910 "fi_read should fail caps:0x%lx rcaps:0x%lx",
911 fi[0]->caps, fi[1]->caps);
912 }
913 }
914
__read_chained(uint32_t version,int mr_mode)915 static inline void __read_chained(uint32_t version, int mr_mode)
916 {
917 hints[0]->caps = FI_RMA;
918 hints[1]->caps = FI_RMA;
919 rdm_api_setup_ep(version, mr_mode);
920 api_do_read_buf();
921 }
922
Test(rdm_api_basic,read_chained)923 Test(rdm_api_basic, read_chained)
924 {
925 __read_chained(fi_version(), GNIX_MR_BASIC);
926 }
927
Test(rdm_api_scalable,read_chained)928 Test(rdm_api_scalable, read_chained)
929 {
930 __read_chained(fi_version(), GNIX_MR_SCALABLE);
931 }
932
__read_chained_remote(uint32_t version,int mr_mode)933 static inline void __read_chained_remote(uint32_t version, int mr_mode)
934 {
935 hints[0]->caps = FI_RMA | FI_READ;
936 hints[1]->caps = FI_RMA | FI_REMOTE_READ;
937 rdm_api_setup_ep(version, mr_mode);
938 api_do_read_buf();
939 }
940
941 Test(rdm_api_basic, read_chained_remote, .disabled = true)
942 {
943 __read_chained_remote(fi_version(), GNIX_MR_BASIC);
944 }
945
946 Test(rdm_api_scalable, read_chained_remote, .disabled = true)
947 {
948 __read_chained_remote(fi_version(), GNIX_MR_SCALABLE);
949 }
950
__read_chained_w_write(uint32_t version,int mr_mode)951 static inline void __read_chained_w_write(uint32_t version, int mr_mode)
952 {
953 hints[0]->caps = FI_RMA | FI_WRITE;
954 hints[1]->caps = FI_RMA | FI_REMOTE_READ;
955 rdm_api_setup_ep(version, mr_mode);
956 api_do_read_buf();
957 }
958
959 Test(rdm_api_basic, read_chained_w_write, .disabled = true)
960 {
961 __read_chained_w_write(fi_version(), GNIX_MR_BASIC);
962 }
963
Test(rdm_api_scalable,read_chained_w_write)964 Test(rdm_api_scalable, read_chained_w_write)
965 {
966 __read_chained_w_write(fi_version(), GNIX_MR_SCALABLE);
967 }
968
__read_chained_no_remote(uint32_t version,int mr_mode)969 static inline void __read_chained_no_remote(uint32_t version, int mr_mode)
970 {
971 hints[0]->caps = FI_RMA | FI_READ;
972 hints[1]->caps = FI_RMA | FI_READ;
973 rdm_api_setup_ep(version, mr_mode);
974 api_do_read_buf();
975 }
976
Test(rdm_api_basic,read_chained_no_remote)977 Test(rdm_api_basic, read_chained_no_remote)
978 {
979 __read_chained_no_remote(fi_version(), GNIX_MR_BASIC);
980 }
981
Test(rdm_api_scalable,read_chained_no_remote)982 Test(rdm_api_scalable, read_chained_no_remote)
983 {
984 __read_chained_no_remote(fi_version(), GNIX_MR_SCALABLE);
985 }
986
987 #define SOURCE_DATA 0xBBBB0000CCCCULL
988 #define TARGET_DATA 0xAAAA0000DDDDULL
989 #define FETCH_SOURCE_DATA 0xACEDACEDULL
990
do_atomic_write_fetch(void)991 void do_atomic_write_fetch(void)
992 {
993 int ret;
994 ssize_t sz;
995 uint64_t operand;
996 struct fi_cq_tagged_entry cqe;
997 struct fi_cq_err_entry err_cqe;
998
999 /* u64 */
1000 *((uint64_t *)source) = SOURCE_DATA;
1001 *((uint64_t *)target) = TARGET_DATA;
1002
1003 sz = fi_atomic(ep[0], source, 1,
1004 loc_mr[0], gni_addr[1],
1005 _REM_ADDR(fi[0], target, target), mr_key[1],
1006 FI_UINT64, FI_ATOMIC_WRITE, target);
1007 cr_assert_eq(sz, 0);
1008
1009 while ((ret = fi_cq_read(msg_cq[0], &cqe, 1)) == -FI_EAGAIN)
1010 pthread_yield();
1011
1012 if (ret == -FI_EAVAIL) {
1013 fi_cq_readerr(msg_cq[0], &err_cqe, 0);
1014 dbg_printf("fi_cq_readerr err:%d\n", err_cqe.err);
1015 }
1016
1017 if (write_allowed(FI_ATOMIC, fi[0]->caps, fi[1]->caps)) {
1018 cr_assert(ret == 1,
1019 "fi_atomic failed caps:0x%lx rcaps:0x%lx",
1020 fi[0]->caps, fi[1]->caps);
1021 } else {
1022 cr_assert(err_cqe.err == FI_EOPNOTSUPP,
1023 "fi_atomic should fail caps:0x%lx rcaps:0x%lx",
1024 fi[0]->caps, fi[1]->caps);
1025 }
1026
1027 /* u64 */
1028 operand = SOURCE_DATA;
1029 *((uint64_t *)source) = FETCH_SOURCE_DATA;
1030 *((uint64_t *)target) = TARGET_DATA;
1031 sz = fi_fetch_atomic(ep[0], &operand, 1, NULL,
1032 source, loc_mr[0], gni_addr[1],
1033 _REM_ADDR(fi[0], target, target),
1034 mr_key[1], FI_UINT64, FI_ATOMIC_READ, target);
1035 cr_assert_eq(sz, 0);
1036
1037 while ((ret = fi_cq_read(msg_cq[0], &cqe, 1)) == -FI_EAGAIN)
1038 pthread_yield();
1039
1040 if (ret == -FI_EAVAIL) {
1041 fi_cq_readerr(msg_cq[0], &err_cqe, 0);
1042 dbg_printf("fi_cq_readerr err:%d\n", err_cqe.err);
1043 }
1044
1045 if (read_allowed(FI_ATOMIC, fi[0]->caps, fi[1]->caps)) {
1046 cr_assert(ret == 1,
1047 "fi_fetch_atomic failed caps:0x%lx rcaps:0x%lx",
1048 fi[0]->caps, fi[1]->caps);
1049 } else {
1050 cr_assert(err_cqe.err == FI_EOPNOTSUPP,
1051 "fi_fetch_atomic should fail caps:0x%lx rcaps:0x%lx",
1052 fi[0]->caps, fi[1]->caps);
1053 }
1054 }
1055
__amo_write_read(uint32_t version,int mr_mode)1056 static inline void __amo_write_read(uint32_t version, int mr_mode)
1057 {
1058 hints[0]->caps = FI_ATOMIC;
1059 hints[1]->caps = FI_ATOMIC;
1060 rdm_api_setup_ep(version, mr_mode);
1061 do_atomic_write_fetch();
1062 }
1063
Test(rdm_api_basic,amo_write_read)1064 Test(rdm_api_basic, amo_write_read)
1065 {
1066 __amo_write_read(fi_version(), GNIX_MR_BASIC);
1067 }
1068
Test(rdm_api_scalable,amo_write_read)1069 Test(rdm_api_scalable, amo_write_read)
1070 {
1071 __amo_write_read(fi_version(), GNIX_MR_SCALABLE);
1072 }
1073
__amo_write_only(uint32_t version,int mr_mode)1074 static inline void __amo_write_only(uint32_t version, int mr_mode)
1075 {
1076 hints[0]->caps = FI_ATOMIC | FI_WRITE;
1077 hints[1]->caps = FI_ATOMIC | FI_REMOTE_WRITE;
1078 rdm_api_setup_ep(version, mr_mode);
1079 do_atomic_write_fetch();
1080 }
1081
1082 Test(rdm_api_basic, amo_write_only, .disabled = true)
1083 {
1084 __amo_write_only(fi_version(), GNIX_MR_BASIC);
1085 }
1086
Test(rdm_api_scalable,amo_write_only)1087 Test(rdm_api_scalable, amo_write_only)
1088 {
1089 __amo_write_only(fi_version(), GNIX_MR_SCALABLE);
1090 }
1091
__amo_write_no_remote(uint32_t version,int mr_mode)1092 static inline void __amo_write_no_remote(uint32_t version, int mr_mode)
1093 {
1094 hints[0]->caps = FI_ATOMIC | FI_WRITE;
1095 hints[1]->caps = FI_ATOMIC | FI_WRITE;
1096 rdm_api_setup_ep(version, mr_mode);
1097 do_atomic_write_fetch();
1098 }
1099
Test(rdm_api_basic,amo_write_no_remote)1100 Test(rdm_api_basic, amo_write_no_remote)
1101 {
1102 __amo_write_no_remote(fi_version(), GNIX_MR_BASIC);
1103 }
1104
Test(rdm_api_scalable,amo_write_no_remote)1105 Test(rdm_api_scalable, amo_write_no_remote)
1106 {
1107 __amo_write_no_remote(fi_version(), GNIX_MR_SCALABLE);
1108 }
1109
__amo_read_only(uint32_t version,int mr_mode)1110 static inline void __amo_read_only(uint32_t version, int mr_mode)
1111 {
1112 hints[0]->caps = FI_ATOMIC | FI_READ;
1113 hints[1]->caps = FI_ATOMIC | FI_REMOTE_READ;
1114 rdm_api_setup_ep(version, mr_mode);
1115 do_atomic_write_fetch();
1116 }
1117
1118 Test(rdm_api_basic, amo_read_only, .disabled = true)
1119 {
1120 __amo_read_only(fi_version(), GNIX_MR_BASIC);
1121 }
1122
Test(rdm_api_scalable,amo_read_only)1123 Test(rdm_api_scalable, amo_read_only)
1124 {
1125 __amo_read_only(fi_version(), GNIX_MR_SCALABLE);
1126 }
1127
__amo_read_no_remote(uint32_t version,int mr_mode)1128 static inline void __amo_read_no_remote(uint32_t version, int mr_mode)
1129 {
1130 hints[0]->caps = FI_ATOMIC | FI_READ;
1131 hints[1]->caps = FI_ATOMIC | FI_READ;
1132 rdm_api_setup_ep(version, mr_mode);
1133 do_atomic_write_fetch();
1134 }
1135
Test(rdm_api_basic,amo_read_no_remote)1136 Test(rdm_api_basic, amo_read_no_remote)
1137 {
1138 __amo_read_no_remote(fi_version(), GNIX_MR_BASIC);
1139 }
1140
Test(rdm_api_scalable,amo_read_no_remote)1141 Test(rdm_api_scalable, amo_read_no_remote)
1142 {
1143 __amo_read_no_remote(fi_version(), GNIX_MR_SCALABLE);
1144 }
1145
__amo_write_read_w_msg(uint32_t version,int mr_mode)1146 static inline void __amo_write_read_w_msg(uint32_t version, int mr_mode)
1147 {
1148 hints[0]->caps = FI_MSG;
1149 hints[1]->caps = FI_MSG;
1150 rdm_api_setup_ep(version, mr_mode);
1151 api_write_read(BUF_SZ);
1152 }
1153
Test(rdm_api_basic,amo_write_read_w_msg)1154 Test(rdm_api_basic, amo_write_read_w_msg)
1155 {
1156 __amo_write_read_w_msg(fi_version(), GNIX_MR_BASIC);
1157 }
1158
Test(rdm_api_scalable,amo_write_read_w_msg)1159 Test(rdm_api_scalable, amo_write_read_w_msg)
1160 {
1161 __amo_write_read_w_msg(fi_version(), GNIX_MR_SCALABLE);
1162 }
1163
1164 TestSuite(api, .init = api_setup, .fini = api_teardown, .disabled = false);
1165
Test(api,getinfo_w_null_hints)1166 Test(api, getinfo_w_null_hints)
1167 {
1168 int ret;
1169
1170 ret = fi_getinfo(fi_version(), NULL, 0, 0, NULL, &fi[0]);
1171 cr_assert(ret == FI_SUCCESS, "fi_getinfo returned: %s",
1172 fi_strerror(-ret));
1173 }
1174