static int table_reverse_lookup(struct gnix_fid_av *av_priv, struct gnix_address gnix_addr, fi_addr_t *fi_addr) { struct gnix_av_addr_entry *entry; int i; for (i = 0; i < av_priv->count; i++) { entry = &av_priv->table[i]; /* * for SEP endpoint entry we may have a delta in the cdm_id * component of the address to process */ if ((entry->name_type & GNIX_EPN_TYPE_SEP) && (entry->gnix_addr.device_addr == gnix_addr.device_addr)) { int index = gnix_addr.cdm_id - entry->gnix_addr.cdm_id; if ((index >= 0) && (index < entry->rx_ctx_cnt)) { /* we have a match */ *fi_addr = fi_rx_addr(i, index, av_priv->rx_ctx_bits); return FI_SUCCESS; } } else if (GNIX_ADDR_EQUAL(entry->gnix_addr, gnix_addr)) { *fi_addr = i; return FI_SUCCESS; } } return -FI_ENOENT; }
static void libfabric_init_addrvec(int rx_ctx_cnt, int rx_ctx_bits) { struct gather_info* my_addr_info; void* addr_infos; char* addrs; char* tai; size_t my_addr_len; size_t addr_info_len; int i, j; // Assumes my_addr_len is the same on all nodes my_addr_len = 0; OFICHKRET(fi_getname(&ofi.ep->fid, NULL, &my_addr_len), -FI_ETOOSMALL); addr_info_len = sizeof(struct gather_info) + my_addr_len; my_addr_info = chpl_mem_alloc(addr_info_len, CHPL_RT_MD_COMM_UTIL, 0, 0); my_addr_info->node = chpl_nodeID; OFICHKERR(fi_getname(&ofi.ep->fid, &my_addr_info->info, &my_addr_len)); addr_infos = chpl_mem_allocMany(chpl_numNodes, addr_info_len, CHPL_RT_MD_COMM_PER_LOC_INFO, 0, 0); chpl_comm_ofi_oob_allgather(my_addr_info, addr_infos, addr_info_len); addrs = chpl_mem_allocMany(chpl_numNodes, my_addr_len, CHPL_RT_MD_COMM_PER_LOC_INFO, 0, 0); for (tai = addr_infos, i = 0; i < chpl_numNodes; i++) { struct gather_info* ai = (struct gather_info*) tai; assert(i >= 0); assert(i < chpl_numNodes); memcpy(addrs + ai->node * my_addr_len, ai->info, my_addr_len); tai += addr_info_len; } ofi.fi_addrs = chpl_mem_allocMany(chpl_numNodes, sizeof(ofi.fi_addrs[0]), CHPL_RT_MD_COMM_PER_LOC_INFO, 0, 0); OFICHKRET(fi_av_insert(ofi.av, addrs, chpl_numNodes, ofi.fi_addrs, 0, NULL), chpl_numNodes); ofi.rx_addrs = chpl_mem_allocMany(chpl_numNodes, sizeof(ofi.rx_addrs[0]), CHPL_RT_MD_COMM_PER_LOC_INFO, 0, 0); for (i = 0; i < chpl_numNodes; i++) { ofi.rx_addrs[i] = chpl_mem_allocMany(rx_ctx_cnt, sizeof(ofi.rx_addrs[i][0]), CHPL_RT_MD_COMM_PER_LOC_INFO, 0, 0); for (j = 0; j < rx_ctx_cnt; j++) { ofi.rx_addrs[i][j] = fi_rx_addr(ofi.fi_addrs[i], j, rx_ctx_bits); } } chpl_mem_free(my_addr_info, 0, 0); chpl_mem_free(addr_infos, 0, 0); chpl_mem_free(addrs, 0, 0); }
static int init_av(void) { size_t addrlen; int ret, i; if (opts.dst_addr) { ret = ft_av_insert(av, fi->dest_addr, 1, &remote_fi_addr, 0, NULL); if (ret) return ret; addrlen = FT_MAX_CTRL_MSG; ret = fi_getname(&sep->fid, tx_buf, &addrlen); if (ret) { FT_PRINTERR("fi_getname", ret); return ret; } ret = fi_send(tx_ep[0], tx_buf, addrlen, fi_mr_desc(mr), remote_fi_addr, NULL); if (ret) { FT_PRINTERR("fi_send", ret); return ret; } ret = wait_for_comp(rxcq_array[0]); if (ret) return ret; } else { ret = wait_for_comp(rxcq_array[0]); if (ret) return ret; ret = ft_av_insert(av, rx_buf, 1, &remote_fi_addr, 0, NULL); if (ret) return ret; ret = fi_send(tx_ep[0], tx_buf, 1, fi_mr_desc(mr), remote_fi_addr, NULL); if (ret) { FT_PRINTERR("fi_send", ret); return ret; } } for (i = 0; i < ctx_cnt; i++) remote_rx_addr[i] = fi_rx_addr(remote_fi_addr, i, rx_ctx_bits); ret = fi_recv(rx_ep[0], rx_buf, rx_size, fi_mr_desc(mr), 0, NULL); if (ret) { FT_PRINTERR("fi_recv", ret); return ret; } ret = wait_for_comp(txcq_array[0]); return ret; }
static int map_reverse_lookup(struct gnix_fid_av *av_priv, struct gnix_address gnix_addr, fi_addr_t *fi_addr) { GNIX_HASHTABLE_ITERATOR(av_priv->map_ht, iter); struct gnix_av_addr_entry *entry; fi_addr_t rx_addr; while ((entry = _gnix_ht_iterator_next(&iter))) { /* * for SEP endpoint entry we may have a delta in the cdm_id * component of the address to process */ if ((entry->name_type & GNIX_EPN_TYPE_SEP) && (entry->gnix_addr.device_addr == gnix_addr.device_addr)) { int index = gnix_addr.cdm_id - entry->gnix_addr.cdm_id; if ((index >= 0) && (index < entry->rx_ctx_cnt)) { /* we have a match */ memcpy(&rx_addr, &entry->gnix_addr, sizeof(fi_addr_t)); *fi_addr = fi_rx_addr(rx_addr, index, av_priv->rx_ctx_bits); return FI_SUCCESS; } } else { if (GNIX_ADDR_EQUAL(entry->gnix_addr, gnix_addr)) { *fi_addr = GNIX_HASHTABLE_ITERATOR_KEY(iter); return FI_SUCCESS; } } } return -FI_ENOENT; }
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_av(void) { int ret; int i; if (opts.dst_addr) { /* Get local address blob. Find the addrlen first. We set addrlen * as 0 and fi_getname will return the actual addrlen. */ addrlen = 0; ret = fi_getname(&sep->fid, local_addr, &addrlen); if (ret != -FI_ETOOSMALL) { FT_PRINTERR("fi_getname", ret); return ret; } local_addr = malloc(addrlen); ret = fi_getname(&sep->fid, local_addr, &addrlen); if (ret) { FT_PRINTERR("fi_getname", ret); return ret; } ret = fi_av_insert(av, remote_addr, 1, &remote_fi_addr, 0, &fi_ctx_av); if (ret != 1) { FT_PRINTERR("fi_av_insert", ret); return ret; } for (i = 0; i < ctx_cnt; i++) remote_rx_addr[i] = fi_rx_addr(remote_fi_addr, i, rx_ctx_bits); /* Send local addr size and local addr */ memcpy(buf, &addrlen, sizeof(size_t)); memcpy(buf + sizeof(size_t), local_addr, addrlen); ret = send_msg(sizeof(size_t) + addrlen); if (ret) return ret; /* Receive ACK from server */ ret = recv_msg(); if (ret) return ret; } else { /* Post a recv to get the remote address */ ret = recv_msg(); if (ret) return ret; memcpy(&addrlen, buf, sizeof(size_t)); remote_addr = malloc(addrlen); memcpy(remote_addr, buf + sizeof(size_t), addrlen); ret = fi_av_insert(av, remote_addr, 1, &remote_fi_addr, 0, &fi_ctx_av); if (ret != 1) { FT_PRINTERR("fi_av_insert", ret); return ret; } /* Send ACK */ ret = send_msg(16); if (ret) return ret; } return 0; }