static int init_fabric(void) { uint64_t flags = 0; char *node, *service; int ret; ret = ft_read_addr_opts(&node, &service, hints, &flags, &opts); if (ret) return ret; ret = fi_getinfo(FT_FIVERSION, node, service, flags, hints, &fi); if (ret) { FT_PRINTERR("fi_getinfo", ret); return ret; } /* Check the optimal number of TX and RX contexts supported by the provider */ ctx_cnt = MIN(ctx_cnt, fi->domain_attr->tx_ctx_cnt); ctx_cnt = MIN(ctx_cnt, fi->domain_attr->rx_ctx_cnt); if (!ctx_cnt) { fprintf(stderr, "Provider doesn't support contexts\n"); return 1; } fi->ep_attr->tx_ctx_cnt = ctx_cnt; fi->ep_attr->rx_ctx_cnt = ctx_cnt; ret = ft_open_fabric_res(); if (ret) return ret; ret = fi_scalable_ep(domain, fi, &sep, NULL); if (ret) { FT_PRINTERR("fi_scalable_ep", ret); return ret; } ret = alloc_ep_res(sep); if (ret) return ret; ret = bind_ep_res(); return ret; }
static int init_fabric(void) { int ret; ret = ft_getinfo(hints, &fi); if (ret) return ret; /* Check the optimal number of TX and RX contexts supported by the provider */ ctx_cnt = MIN(ctx_cnt, fi->domain_attr->tx_ctx_cnt); ctx_cnt = MIN(ctx_cnt, fi->domain_attr->rx_ctx_cnt); if (!ctx_cnt) { fprintf(stderr, "Provider doesn't support contexts\n"); return 1; } fi->ep_attr->tx_ctx_cnt = ctx_cnt; fi->ep_attr->rx_ctx_cnt = ctx_cnt; ret = ft_open_fabric_res(); if (ret) return ret; ret = fi_scalable_ep(domain, fi, &sep, NULL); if (ret) { FT_PRINTERR("fi_scalable_ep", ret); return ret; } ret = alloc_ep_res(sep); if (ret) return ret; ret = bind_ep_res(); return ret; }
static void fas_ep_setup(void) { int ret, i, j; size_t addrlen = 0; fas_setup_common(fi_version()); ctx_cnt = MIN(ctx_cnt, fi[0]->domain_attr->rx_ctx_cnt); ctx_cnt = MIN(ctx_cnt, fi[0]->domain_attr->tx_ctx_cnt); for (i = 0; i < NUMEPS; i++) { fi[i]->ep_attr->tx_ctx_cnt = ctx_cnt; fi[i]->ep_attr->rx_ctx_cnt = ctx_cnt; ret = fi_domain(fab, fi[i], dom + i, NULL); cr_assert(!ret, "fi_domain returned: %s", fi_strerror(-ret)); ret = fi_cntr_open(dom[i], &cntr_attr, send_cntr + i, 0); cr_assert(!ret, "fi_cntr_open returned: %s", fi_strerror(-ret)); ret = fi_cntr_open(dom[i], &cntr_attr, recv_cntr + i, 0); cr_assert(!ret, "fi_cntr_open returned: %s", fi_strerror(-ret)); switch (ep_type) { case EP: ret = fi_endpoint(dom[i], fi[i], ep + i, NULL); cr_assert(!ret, "fi_endpoint returned: %s", fi_strerror(-ret)); break; case SEP: ret = fi_scalable_ep(dom[i], fi[i], ep + i, NULL); cr_assert(!ret, "fi_endpoint returned: %s", fi_strerror(-ret)); break; case PEP: ret = fi_passive_ep(fab, fi[i], pep + i, NULL); cr_assert(!ret, "fi_endpoint returned: %s", fi_strerror(-ret)); ret = fi_getname(get_fid[ep_type](i), NULL, &addrlen); if (use_str_fmt) { cr_assert(addrlen == GNIX_FI_ADDR_STR_LEN, "fi_getname returned: %s", fi_strerror(-ret)); } else { cr_assert(addrlen == sizeof(struct gnix_ep_name), "fi_getname returned: %s", fi_strerror(-ret)); } ep_name_len[i] = addrlen; continue; default: cr_assert_fail("Unknown endpoint type."); } ret = fi_av_open(dom[i], &attr, av + i, NULL); cr_assert(!ret, "fi_av_open returned: %s", fi_strerror(-ret)); switch (ep_type) { case EP: case PEP: ret = fi_cq_open(dom[i], &cq_attr, msg_cq + i, 0); cr_assert(!ret, "fi_cq_open returned: %s", fi_strerror(-ret)); ret = fi_ep_bind(ep[i], &msg_cq[i]->fid, FI_SEND | FI_RECV); cr_assert(!ret, "fi_ep_bind returned: %s", fi_strerror(-ret)); break; case SEP: dbg_printf(BLUE "ctx_cnt = %d\n" COLOR_RESET, ctx_cnt); for (j = 0; j < ctx_cnt; j++) { ret = fi_tx_context(ep[i], j, NULL, &tx_ep[i][j], NULL); cr_assert(!ret, "fi_tx_context returned: %s", fi_strerror(-ret)); ret = fi_cq_open(dom[i], &cq_attr, &tx_cq[i][j], NULL); cr_assert(!ret, "fi_cq_open returned: %s", fi_strerror(-ret)); ret = fi_rx_context(ep[i], j, NULL, &rx_ep[i][j], NULL); cr_assert(!ret, "fi_rx_context returned: %s", fi_strerror(-ret)); ret = fi_cq_open(dom[i], &cq_attr, &rx_cq[i][j], NULL); cr_assert(!ret, "fi_cq_open returned: %s", fi_strerror(-ret)); } break; default: cr_assert_fail("Unknown endpoint type."); } ret = fi_getname(get_fid[ep_type](i), NULL, &addrlen); if (use_str_fmt) { cr_assert(addrlen > sizeof(struct gnix_ep_name), "fi_getname returned: %s", fi_strerror(-ret)); } else { cr_assert(addrlen == sizeof(struct gnix_ep_name), "fi_getname returned: %s", fi_strerror(-ret)); } ep_name[i] = malloc(addrlen); ep_name_len[i] = addrlen; dbg_printf(BLUE "ep_name_len[%d] = %lu\n" COLOR_RESET, i, ep_name_len[i]); cr_assert(ep_name[i] != NULL, "malloc returned: %s", strerror(errno)); ret = fi_getname(get_fid[ep_type](i), ep_name[i], &addrlen); cr_assert(ret == FI_SUCCESS, "fi_getname returned: %s", fi_strerror(-ret)); } /* Just testing setname / getname for passive endpoints */ if (ep_type == PEP) return; for (i = 0; i < NUMEPS; i++) { /*Insert all gni addresses into each av*/ for (j = 0; j < NUMEPS; j++) { ret = fi_av_insert(av[i], ep_name[j], 1, &gni_addr[j], 0, NULL); cr_assert(ret == 1, "fi_av_insert returned: %s", fi_strerror(-ret)); } switch (ep_type) { case EP: ret = fi_ep_bind(ep[i], &av[i]->fid, 0); cr_assert(!ret, "fi_ep_bind returned: %s", fi_strerror(-ret)); ret = fi_ep_bind(ep[i], &send_cntr[i]->fid, FI_SEND); cr_assert(!ret, "fi_ep_bind returned: %s", fi_strerror(-ret)); ret = fi_ep_bind(ep[i], &recv_cntr[i]->fid, FI_RECV); cr_assert(!ret, "fi_ep_bind returned: %s", fi_strerror(-ret)); break; case SEP: ret = fi_scalable_ep_bind(ep[i], &av[i]->fid, 0); cr_assert(!ret, "fi_scalable_ep_bind returned: %s", fi_strerror(-ret)); dbg_printf(BLUE "ctx_cnt = %d\n" COLOR_RESET, ctx_cnt); for (j = 0; j < ctx_cnt; j++) { ret = fi_ep_bind(tx_ep[i][j], &tx_cq[i][j]->fid, FI_TRANSMIT); cr_assert(!ret, "fi_ep_bind returned: %s", fi_strerror(-ret)); ret = fi_ep_bind(tx_ep[i][j], &send_cntr[i]->fid, FI_SEND); cr_assert(!ret, "fi_ep_bind returned: %s", fi_strerror(-ret)); ret = fi_enable(tx_ep[i][j]); cr_assert(!ret, "fi_enable returned: %s", fi_strerror(-ret)); ret = fi_ep_bind(rx_ep[i][j], &rx_cq[i][j]->fid, FI_RECV); cr_assert(!ret, "fi_ep_bind returned: %s", fi_strerror(-ret)); ret = fi_ep_bind(rx_ep[i][j], &recv_cntr[i]->fid, FI_RECV); cr_assert(!ret, "fi_ep_bind returned: %s", fi_strerror(-ret)); ret = fi_enable(rx_ep[i][j]); cr_assert(!ret, "fi_enable returned: %s", fi_strerror(-ret)); } break; case PEP: break; default: cr_assert_fail("Unknown endpoint type."); } ret = fi_enable(ep[i]); cr_assert(!ret, "fi_ep_enable returned: %s", fi_strerror(-ret)); if (ep_type != SEP) { ret = fi_enable(ep[i]); cr_assert_eq(ret, -FI_EOPBADSTATE, "fi_enable returned: %s", fi_strerror(-ret)); } } }
static void libfabric_init() { int i; struct fi_info *info = NULL; struct fi_info *hints = fi_allocinfo(); struct fi_av_attr av_attr = {0}; struct fi_cq_attr cq_attr = {0}; int max_tx_ctx, max_rx_ctx; int comm_concurrency; int rx_ctx_cnt; int rx_ctx_bits = 0; hints->mode = ~0; hints->caps = FI_RMA | FI_ATOMIC | FI_SOURCE /* do we want this? */ | FI_READ | FI_WRITE | FI_REMOTE_READ | FI_REMOTE_WRITE | FI_MULTI_RECV | FI_FENCE; hints->addr_format = FI_FORMAT_UNSPEC; #if defined(CHPL_COMM_SUBSTRATE_SOCKETS) // // fi_freeinfo(hints) will free() hints->fabric_attr->prov_name; this // is documented, though poorly. So, get that space from malloc(). // { const char s[] = "sockets"; char* sDup = sys_malloc(sizeof(s)); strcpy(sDup, s); hints->fabric_attr->prov_name = sDup; } #elif defined(CHPL_COMM_SUBSTRATE_GNI) #error "Substrate GNI not supported" #else #error "Substrate type not supported" #endif /* connectionless reliable */ hints->ep_attr->type = FI_EP_RDM; hints->domain_attr->threading = FI_THREAD_UNSPEC; hints->domain_attr->control_progress = FI_PROGRESS_MANUAL; hints->domain_attr->data_progress = FI_PROGRESS_MANUAL; hints->domain_attr->av_type = FI_AV_TABLE; hints->domain_attr->mr_mode = FI_MR_SCALABLE; hints->domain_attr->resource_mgmt = FI_RM_ENABLED; // hints->domain_attr->cq_data_size hints->tx_attr->op_flags = FI_COMPLETION; hints->rx_attr->op_flags = FI_COMPLETION; OFICHKERR(fi_getinfo(FI_VERSION(1,0), NULL, NULL, 0, hints, &info)); if (info == NULL) { chpl_internal_error("No fabrics detected."); } else { #ifdef PRINT_FI_GETINFO struct fi_info *cur; for (cur = info; cur; cur = cur->next) { printf("---\n"); printf("%s", fi_tostr(cur, FI_TYPE_INFO)); } printf("\n"); #endif } ofi.num_am_ctx = 1; // Would we ever want more? max_tx_ctx = info->domain_attr->max_ep_tx_ctx; max_rx_ctx = info->domain_attr->max_ep_rx_ctx; comm_concurrency = get_comm_concurrency(); ofi.num_tx_ctx = comm_concurrency+ofi.num_am_ctx > max_tx_ctx ? max_tx_ctx-ofi.num_am_ctx : comm_concurrency; ofi.num_rx_ctx = comm_concurrency+ofi.num_am_ctx > max_rx_ctx ? max_rx_ctx-ofi.num_am_ctx : comm_concurrency; info->ep_attr->tx_ctx_cnt = ofi.num_tx_ctx + ofi.num_am_ctx; info->ep_attr->rx_ctx_cnt = ofi.num_rx_ctx + ofi.num_am_ctx; OFICHKERR(fi_fabric(info->fabric_attr, &ofi.fabric, NULL)); OFICHKERR(fi_domain(ofi.fabric, info, &ofi.domain, NULL)); rx_ctx_cnt = ofi.num_rx_ctx + ofi.num_am_ctx; while (rx_ctx_cnt >> ++rx_ctx_bits); av_attr.rx_ctx_bits = rx_ctx_bits; av_attr.type = FI_AV_TABLE; av_attr.count = chpl_numNodes; OFICHKERR(fi_av_open(ofi.domain, &av_attr, &ofi.av, NULL)); OFICHKERR(fi_scalable_ep(ofi.domain, info, &ofi.ep, NULL)); OFICHKERR(fi_scalable_ep_bind(ofi.ep, &ofi.av->fid, 0)); /* set up tx and rx contexts */ cq_attr.format = FI_CQ_FORMAT_CONTEXT; cq_attr.size = 1024; /* ??? */ cq_attr.wait_obj = FI_WAIT_UNSPEC; ofi.tx_ep = (struct fid_ep **) chpl_mem_allocMany(ofi.num_tx_ctx, sizeof(ofi.tx_ep[0]), CHPL_RT_MD_COMM_PER_LOC_INFO, 0, 0); ofi.tx_cq = (struct fid_cq **) chpl_mem_allocMany(ofi.num_tx_ctx, sizeof(ofi.tx_cq[0]), CHPL_RT_MD_COMM_PER_LOC_INFO, 0, 0); for (i = 0; i < ofi.num_tx_ctx; i++) { OFICHKERR(fi_tx_context(ofi.ep, i, NULL, &ofi.tx_ep[i], NULL)); OFICHKERR(fi_cq_open(ofi.domain, &cq_attr, &ofi.tx_cq[i], NULL)); OFICHKERR(fi_ep_bind(ofi.tx_ep[i], &ofi.tx_cq[i]->fid, FI_TRANSMIT)); OFICHKERR(fi_enable(ofi.tx_ep[i])); } ofi.rx_ep = (struct fid_ep **) chpl_mem_allocMany(ofi.num_rx_ctx, sizeof(ofi.rx_ep[0]), CHPL_RT_MD_COMM_PER_LOC_INFO, 0, 0); ofi.rx_cq = (struct fid_cq **) chpl_mem_allocMany(ofi.num_rx_ctx, sizeof(ofi.rx_cq[0]), CHPL_RT_MD_COMM_PER_LOC_INFO, 0, 0); for (i = 0; i < ofi.num_rx_ctx; i++) { OFICHKERR(fi_rx_context(ofi.ep, i, NULL, &ofi.rx_ep[i], NULL)); OFICHKERR(fi_cq_open(ofi.domain, &cq_attr, &ofi.rx_cq[i], NULL)); OFICHKERR(fi_ep_bind(ofi.rx_ep[i], &ofi.rx_cq[i]->fid, FI_RECV)); OFICHKERR(fi_enable(ofi.rx_ep[i])); } ofi.am_tx_ep = (struct fid_ep **) chpl_mem_allocMany(ofi.num_am_ctx, sizeof(ofi.am_tx_ep[0]), CHPL_RT_MD_COMM_PER_LOC_INFO, 0, 0); ofi.am_tx_cq = (struct fid_cq **) chpl_mem_allocMany(ofi.num_am_ctx, sizeof(ofi.am_tx_cq[0]), CHPL_RT_MD_COMM_PER_LOC_INFO, 0, 0); /* set up AM contexts */ for (i = 0; i < ofi.num_am_ctx; i++) { OFICHKERR(fi_tx_context(ofi.ep, i+ofi.num_tx_ctx, NULL, &ofi.am_tx_ep[i], NULL)); OFICHKERR(fi_cq_open(ofi.domain, &cq_attr, &ofi.am_tx_cq[i], NULL)); OFICHKERR(fi_ep_bind(ofi.am_tx_ep[i], &ofi.am_tx_cq[i]->fid, FI_TRANSMIT)); OFICHKERR(fi_enable(ofi.am_tx_ep[i])); } ofi.am_rx_ep = (struct fid_ep **) chpl_mem_allocMany(ofi.num_am_ctx, sizeof(ofi.am_rx_ep[0]), CHPL_RT_MD_COMM_PER_LOC_INFO, 0, 0); ofi.am_rx_cq = (struct fid_cq **) chpl_mem_allocMany(ofi.num_am_ctx, sizeof(ofi.am_rx_cq[0]), CHPL_RT_MD_COMM_PER_LOC_INFO, 0, 0); for (i = 0; i < ofi.num_am_ctx; i++) { OFICHKERR(fi_rx_context(ofi.ep, i+ofi.num_rx_ctx, NULL, &ofi.am_rx_ep[i], NULL)); OFICHKERR(fi_cq_open(ofi.domain, &cq_attr, &ofi.am_rx_cq[i], NULL)); OFICHKERR(fi_ep_bind(ofi.am_rx_ep[i], &ofi.am_rx_cq[i]->fid, FI_RECV)); OFICHKERR(fi_enable(ofi.am_rx_ep[i])); } OFICHKERR(fi_enable(ofi.ep)); libfabric_init_addrvec(rx_ctx_cnt, rx_ctx_bits); OFICHKERR(fi_mr_reg(ofi.domain, 0, SIZE_MAX, FI_READ | FI_WRITE | FI_REMOTE_READ | FI_REMOTE_WRITE | FI_SEND | FI_RECV, 0, (uint64_t) chpl_nodeID, 0, &ofi.mr, NULL)); fi_freeinfo(info); /* No error returned */ fi_freeinfo(hints); /* No error returned */ chpl_msg(2, "%d: completed libfabric initialization\n", chpl_nodeID); }
void sep_setup_common(int av_type) { int ret, i, j; struct fi_av_attr av_attr = {0}; size_t addrlen = 0; hints = fi_allocinfo(); cr_assert(hints, "fi_allocinfo"); hints->ep_attr->type = FI_EP_RDM; hints->caps = FI_ATOMIC | FI_RMA | FI_MSG | FI_NAMED_RX_CTX; hints->mode = FI_LOCAL_MR; hints->domain_attr->cq_data_size = NUMEPS * 2; hints->domain_attr->data_progress = FI_PROGRESS_AUTO; hints->domain_attr->mr_mode = FI_MR_BASIC; hints->fabric_attr->prov_name = strdup("gni"); hints->ep_attr->tx_ctx_cnt = ctx_cnt; hints->ep_attr->rx_ctx_cnt = ctx_cnt; for (i = 0; i < NUMEPS; i++) { ret = fi_getinfo(FI_VERSION(1, 0), NULL, 0, 0, hints, &fi[i]); cr_assert(!ret, "fi_getinfo"); tx_cq[i] = calloc(ctx_cnt, sizeof(*tx_cq)); rx_cq[i] = calloc(ctx_cnt, sizeof(*rx_cq)); tx_ep[i] = calloc(ctx_cnt, sizeof(*tx_ep)); rx_ep[i] = calloc(ctx_cnt, sizeof(*rx_ep)); if (!tx_cq[i] || !tx_cq[i] || !tx_ep[i] || !rx_ep[i]) { cr_assert(0, "calloc"); } } ctx_cnt = MIN(ctx_cnt, fi[0]->domain_attr->rx_ctx_cnt); ctx_cnt = MIN(ctx_cnt, fi[0]->domain_attr->tx_ctx_cnt); cr_assert(ctx_cnt, "ctx_cnt is 0"); ret = fi_fabric(fi[0]->fabric_attr, &fab, NULL); cr_assert(!ret, "fi_fabric"); rx_ctx_bits = 0; while (ctx_cnt >> ++rx_ctx_bits); av_attr.rx_ctx_bits = rx_ctx_bits; av_attr.type = av_type; av_attr.count = NUMEPS; cq_attr.format = FI_CQ_FORMAT_TAGGED; cq_attr.size = 1024; cq_attr.wait_obj = FI_WAIT_NONE; rx_addr = calloc(ctx_cnt, sizeof(*rx_addr)); target = calloc(BUF_SZ, 1); source = calloc(BUF_SZ, 1); iov_src_buf = malloc(BUF_SZ * IOV_CNT); iov_dest_buf = malloc(BUF_SZ * IOV_CNT); src_iov = malloc(sizeof(struct iovec) * IOV_CNT); dest_iov = malloc(sizeof(struct iovec) * IOV_CNT); if (!rx_addr || !target || !source || !iov_src_buf || !iov_dest_buf || !src_iov || !dest_iov) { cr_assert(0, "allocation"); } for (i = 0; i < IOV_CNT; i++) { src_iov[i].iov_base = malloc(BUF_SZ); assert(src_iov[i].iov_base != NULL); dest_iov[i].iov_base = malloc(BUF_SZ * 3); assert(dest_iov[i].iov_base != NULL); } for (i = 0; i < NUMEPS; i++) { fi[i]->ep_attr->tx_ctx_cnt = ctx_cnt; fi[i]->ep_attr->rx_ctx_cnt = ctx_cnt; ret = fi_domain(fab, fi[i], &dom[i], NULL); cr_assert(!ret, "fi_domain"); ret = fi_scalable_ep(dom[i], fi[i], &sep[i], NULL); cr_assert(!ret, "fi_scalable_ep"); ret = fi_av_open(dom[i], &av_attr, &av[i], NULL); cr_assert(!ret, "fi_av_open"); ret = fi_cntr_open(dom[i], &cntr_attr, &send_cntr[i], 0); cr_assert(!ret, "fi_cntr_open"); ret = fi_cntr_open(dom[i], &cntr_attr, &recv_cntr[i], 0); cr_assert(!ret, "fi_cntr_open"); for (j = 0; j < ctx_cnt; j++) { ret = fi_tx_context(sep[i], j, NULL, &tx_ep[i][j], NULL); cr_assert(!ret, "fi_tx_context"); ret = fi_cq_open(dom[i], &cq_attr, &tx_cq[i][j], NULL); cr_assert(!ret, "fi_cq_open"); ret = fi_rx_context(sep[i], j, NULL, &rx_ep[i][j], NULL); cr_assert(!ret, "fi_rx_context"); ret = fi_cq_open(dom[i], &cq_attr, &rx_cq[i][j], NULL); cr_assert(!ret, "fi_cq_open"); } ret = fi_scalable_ep_bind(sep[i], &av[i]->fid, 0); cr_assert(!ret, "fi_scalable_ep_bind"); for (j = 0; j < ctx_cnt; j++) { ret = fi_ep_bind(tx_ep[i][j], &tx_cq[i][j]->fid, FI_TRANSMIT); cr_assert(!ret, "fi_ep_bind"); ret = fi_ep_bind(tx_ep[i][j], &send_cntr[i]->fid, FI_SEND | FI_WRITE); cr_assert(!ret, "fi_ep_bind"); ret = fi_enable(tx_ep[i][j]); cr_assert(!ret, "fi_enable"); ret = fi_ep_bind(rx_ep[i][j], &rx_cq[i][j]->fid, FI_RECV); cr_assert(!ret, "fi_ep_bind"); ret = fi_ep_bind(rx_ep[i][j], &recv_cntr[i]->fid, FI_RECV | FI_READ); cr_assert(!ret, "fi_ep_bind"); ret = fi_enable(rx_ep[i][j]); cr_assert(!ret, "fi_enable"); } } for (i = 0; i < NUMEPS; i++) { ret = fi_enable(sep[i]); cr_assert(!ret, "fi_enable"); ret = fi_getname(&sep[i]->fid, NULL, &addrlen); cr_assert(addrlen > 0); ep_name[i] = malloc(addrlen); cr_assert(ep_name[i] != NULL); ret = fi_getname(&sep[i]->fid, ep_name[i], &addrlen); cr_assert(ret == FI_SUCCESS); ret = fi_mr_reg(dom[i], target, BUF_SZ, FI_REMOTE_WRITE, 0, 0, 0, &rem_mr[i], &target); cr_assert_eq(ret, 0); ret = fi_mr_reg(dom[i], source, BUF_SZ, FI_REMOTE_WRITE, 0, 0, 0, &loc_mr[i], &source); cr_assert_eq(ret, 0); mr_key[i] = fi_mr_key(rem_mr[i]); ret = fi_mr_reg(dom[i], iov_dest_buf, IOV_CNT * BUF_SZ, FI_REMOTE_WRITE, 0, 0, 0, iov_dest_buf_mr + i, &iov_dest_buf); cr_assert_eq(ret, 0); ret = fi_mr_reg(dom[i], iov_src_buf, IOV_CNT * BUF_SZ, FI_REMOTE_WRITE, 0, 0, 0, iov_src_buf_mr + i, &iov_src_buf); cr_assert_eq(ret, 0); } for (i = 0; i < NUMEPS; i++) { for (j = 0; j < NUMEPS; j++) { ret = fi_av_insert(av[i], ep_name[j], 1, &gni_addr[j], 0, NULL); cr_assert(ret == 1); } } for (i = 0; i < ctx_cnt; i++) { rx_addr[i] = fi_rx_addr(gni_addr[1], i, rx_ctx_bits); } }
static int init_fabric(void) { uint64_t flags = 0; char *node, *service; int ret; ret = ft_read_addr_opts(&node, &service, hints, &flags, &opts); if (ret) return ret; ret = fi_getinfo(FT_FIVERSION, node, service, flags, hints, &fi); if (ret) { FT_PRINTERR("fi_getinfo", ret); return ret; } /* Check the optimal number of TX and RX contexts supported by the provider */ ctx_cnt = MIN(ctx_cnt, fi->domain_attr->tx_ctx_cnt); ctx_cnt = MIN(ctx_cnt, fi->domain_attr->rx_ctx_cnt); if (!ctx_cnt) { fprintf(stderr, "Provider doesn't support contexts\n"); return 1; } /* We use provider MR attributes and direct address (no offsets) for RMA calls */ if (!(fi->mode & FI_PROV_MR_ATTR)) fi->mode |= FI_PROV_MR_ATTR; /* Get remote address */ if (opts.dst_addr) { addrlen = fi->dest_addrlen; remote_addr = malloc(addrlen); memcpy(remote_addr, fi->dest_addr, addrlen); } ret = fi_fabric(fi->fabric_attr, &fab, NULL); if (ret) { FT_PRINTERR("fi_fabric", ret); goto err0; } ret = fi_domain(fab, fi, &dom, NULL); if (ret) { FT_PRINTERR("fi_domain", ret); goto err1; } /* Set the required number of TX and RX context counts */ fi->ep_attr->tx_ctx_cnt = ctx_cnt; fi->ep_attr->rx_ctx_cnt = ctx_cnt; ret = fi_scalable_ep(dom, fi, &sep, NULL); if (ret) { FT_PRINTERR("fi_scalable_ep", ret); goto err2; } ret = alloc_ep_res(sep); if (ret) goto err3; ret = bind_ep_res(); if (ret) goto err4; return 0; err4: free_ep_res(); err3: fi_close(&sep->fid); err2: fi_close(&dom->fid); err1: fi_close(&fab->fid); err0: return ret; }