Exemplo n.º 1
0
static int bind_ep_res(void)
{
	int i, ret;

	ret = fi_scalable_ep_bind(sep, &av->fid, 0);
	if (ret) {
		FT_PRINTERR("fi_scalable_ep_bind", ret);
		return ret;
	}

	for (i = 0; i < ctx_cnt; i++) {
		ret = fi_ep_bind(tx_ep[i], &txcq_array[i]->fid, FI_SEND);
		if (ret) {
			FT_PRINTERR("fi_ep_bind", ret);
			return ret;
		}

		ret = fi_enable(tx_ep[i]);
		if (ret) {
			FT_PRINTERR("fi_enable", ret);
			return ret;
		}
	}

	for (i = 0; i < ctx_cnt; i++) {
		ret = fi_ep_bind(rx_ep[i], &rxcq_array[i]->fid, FI_RECV);
		if (ret) {
			FT_PRINTERR("fi_ep_bind", ret);
			return ret;
		}

		ret = fi_enable(rx_ep[i]);
		if (ret) {
			FT_PRINTERR("fi_enable", ret);
			return ret;
		}

		ret = fi_recv(rx_ep[i], rx_buf, MAX(rx_size, FT_MAX_CTRL_MSG),
			      mr_desc, 0, NULL);
		if (ret) {
			FT_PRINTERR("fi_recv", ret);
			return ret;
		}
	}

	ret = fi_enable(sep);
	if (ret) {
		FT_PRINTERR("fi_enable", ret);
		return ret;
	}

	return 0;
}
Exemplo n.º 2
0
static int bind_ep_res(void)
{
	int i, ret;

	for (i = 0; i < ctx_cnt; i++) {
		ret = fi_ep_bind(tx_ep[i], &scq[i]->fid, FI_SEND);
		if (ret) {
			FT_PRINTERR("fi_ep_bind", ret);
			return ret;
		}

		ret = fi_enable(tx_ep[i]);
		if (ret) {
			FT_PRINTERR("fi_enable", ret);
			return ret;
		}
	}

	for (i = 0; i < ctx_cnt; i++) {
		ret = fi_ep_bind(rx_ep[i], &rcq[i]->fid, FI_RECV);
		if (ret) {
			FT_PRINTERR("fi_ep_bind", ret);
			return ret;
		}

		ret = fi_enable(rx_ep[i]);
		if (ret) {
			FT_PRINTERR("fi_enable", ret);
			return ret;
		}
	}

	/* Bind scalable EP with AV */
	ret = fi_scalable_ep_bind(sep, &av->fid, 0);
	if (ret) {
		FT_PRINTERR("fi_ep_bind", ret);
		return ret;
	}

	if (ret)
		return ret;

	return ret;
}
Exemplo n.º 3
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));
		}
	}
}
Exemplo n.º 4
0
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);
}
Exemplo n.º 5
0
/* 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;
}
Exemplo n.º 6
0
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);
	}
}