static int alloc_ep_res(struct fid_ep *sep) { int i, ret; /* Get number of bits needed to represent ctx_cnt */ while (ctx_cnt >> ++rx_ctx_bits) ; av_attr.rx_ctx_bits = rx_ctx_bits; ret = ft_alloc_active_res(fi); if (ret) return ret; /* Closes non-scalable endpoint that was allocated in the common code */ FT_CLOSE_FID(ep); txcq_array = calloc(ctx_cnt, sizeof *txcq_array); rxcq_array = calloc(ctx_cnt, sizeof *rxcq_array); tx_ep = calloc(ctx_cnt, sizeof *tx_ep); rx_ep = calloc(ctx_cnt, sizeof *rx_ep); remote_rx_addr = calloc(ctx_cnt, sizeof *remote_rx_addr); if (!buf || !txcq_array || !rxcq_array || !tx_ep || !rx_ep || !remote_rx_addr) { perror("malloc"); return -1; } for (i = 0; i < ctx_cnt; i++) { ret = fi_tx_context(sep, i, NULL, &tx_ep[i], NULL); if (ret) { FT_PRINTERR("fi_tx_context", ret); return ret; } ret = fi_cq_open(domain, &cq_attr, &txcq_array[i], NULL); if (ret) { FT_PRINTERR("fi_cq_open", ret); return ret; } ret = fi_rx_context(sep, i, NULL, &rx_ep[i], NULL); if (ret) { FT_PRINTERR("fi_tx_context", ret); return ret; } ret = fi_cq_open(domain, &cq_attr, &rxcq_array[i], NULL); if (ret) { FT_PRINTERR("fi_cq_open", ret); return ret; } } return 0; }
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); }
/* mca_btl_ofi_context_alloc_scalable() * * This function allocate communication contexts and return the pointer * to the first btl context. It also take care of all the bindings needed. * USE WITH SCALABLE ENDPOINT ONLY */ mca_btl_ofi_context_t *mca_btl_ofi_context_alloc_scalable(struct fi_info *info, struct fid_domain *domain, struct fid_ep *sep, struct fid_av *av, size_t num_contexts) { BTL_VERBOSE(("creating %zu contexts", num_contexts)); int rc; size_t i; char *linux_device_name = info->domain_attr->name; struct fi_cq_attr cq_attr = {0}; struct fi_tx_attr tx_attr = {0}; struct fi_rx_attr rx_attr = {0}; mca_btl_ofi_context_t *contexts; tx_attr.op_flags = FI_DELIVERY_COMPLETE; contexts = (mca_btl_ofi_context_t*) calloc(num_contexts, sizeof(*contexts)); if (NULL == contexts) { BTL_VERBOSE(("cannot allocate communication contexts.")); return NULL; } /* Don't really need to check, just avoiding compiler warning because * BTL_VERBOSE is a no op in performance build and the compiler will * complain about unused variable. */ if (NULL == linux_device_name) { BTL_VERBOSE(("linux device name is NULL. This shouldn't happen.")); goto scalable_fail; } /* bind AV to endpoint */ rc = fi_scalable_ep_bind(sep, (fid_t)av, 0); if (0 != rc) { BTL_VERBOSE(("%s failed fi_scalable_ep_bind with err=%s", linux_device_name, fi_strerror(-rc) )); goto scalable_fail; } for (i=0; i < num_contexts; i++) { rc = fi_tx_context(sep, i, &tx_attr, &contexts[i].tx_ctx, NULL); if (0 != rc) { BTL_VERBOSE(("%s failed fi_tx_context with err=%s", linux_device_name, fi_strerror(-rc) )); goto scalable_fail; } /* We don't actually need a receiving context as we only do one-sided. * However, sockets provider will hang if we dont have one. It is * also nice to have equal number of tx/rx context. */ rc = fi_rx_context(sep, i, &rx_attr, &contexts[i].rx_ctx, NULL); if (0 != rc) { BTL_VERBOSE(("%s failed fi_rx_context with err=%s", linux_device_name, fi_strerror(-rc) )); goto scalable_fail; } /* create CQ */ cq_attr.format = FI_CQ_FORMAT_CONTEXT; cq_attr.wait_obj = FI_WAIT_NONE; rc = fi_cq_open(domain, &cq_attr, &contexts[i].cq, NULL); if (0 != rc) { BTL_VERBOSE(("%s failed fi_cq_open with err=%s", linux_device_name, fi_strerror(-rc) )); goto scalable_fail; } /* bind cq to transmit context */ uint32_t cq_flags = (FI_TRANSMIT); rc = fi_ep_bind(contexts[i].tx_ctx, (fid_t)contexts[i].cq, cq_flags); if (0 != rc) { BTL_VERBOSE(("%s failed fi_ep_bind with err=%s", linux_device_name, fi_strerror(-rc) )); goto scalable_fail; } /* enable the context. */ rc = fi_enable(contexts[i].tx_ctx); if (0 != rc) { BTL_VERBOSE(("%s failed fi_enable with err=%s", linux_device_name, fi_strerror(-rc) )); goto scalable_fail; } rc = fi_enable(contexts[i].rx_ctx); if (0 != rc) { BTL_VERBOSE(("%s failed fi_enable with err=%s", linux_device_name, fi_strerror(-rc) )); goto scalable_fail; } /* initialize completion freelist. */ rc = ofi_comp_list_init(&contexts[i].comp_list); if (rc != OPAL_SUCCESS) { goto scalable_fail; } /* assign the id */ contexts[i].context_id = i; } return contexts; scalable_fail: /* close and free */ for(i=0; i < num_contexts; i++) { mca_btl_ofi_context_finalize(&contexts[i], true); } free(contexts); return NULL; }
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 alloc_ep_res(struct fid_ep *sep) { struct fi_cq_attr cq_attr; struct fi_rx_attr rx_attr; struct fi_tx_attr tx_attr; struct fi_av_attr av_attr; int i, ret; buffer_size = test_size[TEST_CNT - 1].size; buf = malloc(buffer_size); scq = calloc(ctx_cnt, sizeof *scq); rcq = calloc(ctx_cnt, sizeof *rcq); tx_ep = calloc(ctx_cnt, sizeof *tx_ep); rx_ep = calloc(ctx_cnt, sizeof *rx_ep); remote_rx_addr = calloc(ctx_cnt, sizeof *remote_rx_addr); if (!buf || !scq || !rcq || !tx_ep || !rx_ep || !remote_rx_addr) { perror("malloc"); return -1; } memset(&cq_attr, 0, sizeof cq_attr); cq_attr.format = FI_CQ_FORMAT_CONTEXT; cq_attr.wait_obj = FI_WAIT_NONE; cq_attr.size = rx_depth; for (i = 0; i < ctx_cnt; i++) { /* Create TX contexts: tx_ep */ ret = fi_tx_context(sep, i, &tx_attr, &tx_ep[i], NULL); if (ret) { FT_PRINTERR("fi_tx_context", ret); goto err1; } ret = fi_cq_open(dom, &cq_attr, &scq[i], NULL); if (ret) { FT_PRINTERR("fi_cq_open", ret); goto err2; } } for (i = 0; i < ctx_cnt; i++) { /* Create RX contexts: rx_ep */ ret = fi_rx_context(sep, i, &rx_attr, &rx_ep[i], NULL); if (ret) { FT_PRINTERR("fi_tx_context", ret); goto err3; } ret = fi_cq_open(dom, &cq_attr, &rcq[i], NULL); if (ret) { FT_PRINTERR("fi_cq_open", ret); goto err4; } } ret = fi_mr_reg(dom, buf, buffer_size, 0, 0, 0, 0, &mr, NULL); if (ret) { FT_PRINTERR("fi_mr_reg", ret); goto err5; } /* Get number of bits needed to represent ctx_cnt */ while (ctx_cnt >> ++rx_ctx_bits) ; memset(&av_attr, 0, sizeof av_attr); av_attr.type = fi->domain_attr->av_type ? fi->domain_attr->av_type : FI_AV_MAP; av_attr.count = 1; av_attr.rx_ctx_bits = rx_ctx_bits; /* Open Address Vector */ ret = fi_av_open(dom, &av_attr, &av, NULL); if (ret) { FT_PRINTERR("fi_av_open", ret); goto err6; } return 0; err6: fi_close(&mr->fid); err5: FT_CLOSEV(rcq, ctx_cnt); err4: FT_CLOSEV(rx_ep, ctx_cnt); err3: FT_CLOSEV(scq, ctx_cnt); err2: FT_CLOSEV(tx_ep, ctx_cnt); err1: free(buf); free(rcq); free(scq); free(tx_ep); free(rx_ep); free(remote_rx_addr); return ret; }