static int av_test_open_close(enum fi_av_type type, int count, uint64_t flags) { int ret; struct fi_av_attr attr; struct fid_av *av; memset(&attr, 0, sizeof(attr)); attr.type = type; attr.count = count; attr.flags = flags; ret = fi_av_open(domain, &attr, &av, NULL); if (ret != 0) { sprintf(err_buf, "fi_av_open(%d, %s) = %d, %s", count, fi_tostr(&type, FI_TYPE_AV_TYPE), ret, fi_strerror(-ret)); return ret; } ret = fi_close(&av->fid); if (ret != 0) { sprintf(err_buf, "close(av) = %d, %s", ret, fi_strerror(-ret)); return ret; } return 0; }
static void av_full_table_setup(void) { struct fi_av_attr av_table_attr = { .type = FI_AV_TABLE, .count = 16, }; int ret; av_setup(); ret = fi_av_open(dom, &av_table_attr, &av, NULL); cr_assert_eq(ret, FI_SUCCESS, "failed to open av"); gnix_av = container_of(av, struct gnix_fid_av, av_fid); } static void av_full_table_teardown(void) { int ret; ret = fi_close(&av->fid); cr_assert_eq(ret, FI_SUCCESS, "failed to close av"); av_teardown(); }
Test(scalablem, bind) { int ret; struct fi_av_attr av_attr = {0}; /* test if bind fails */ ret = fi_ep_bind(tx_ep[0][0], &tx_cq[0][0]->fid, FI_TRANSMIT); cr_assert(ret, "fi_ep_bind should fail"); ret = fi_ep_bind(rx_ep[0][0], &rx_cq[0][0]->fid, FI_TRANSMIT); cr_assert(ret, "fi_ep_bind should fail"); /* test for inserting an ep_name that doesn't fit in the AV */ av_attr.type = FI_AV_MAP; av_attr.count = NUMEPS; av_attr.rx_ctx_bits = 1; ret = fi_av_open(dom[0], &av_attr, &t_av, NULL); cr_assert(!ret, "fi_av_open"); ret = fi_av_insert(t_av, ep_name[0], 1, &gni_addr[0], 0, NULL); cr_assert(ret == -FI_EINVAL); ret = fi_close(&t_av->fid); cr_assert(!ret, "failure in closing av."); }
static inline void cntr_setup_eps(void) { int i, ret; struct fi_av_attr attr; hints = fi_allocinfo(); cr_assert(hints, "fi_allocinfo"); hints->domain_attr->cq_data_size = 4; hints->mode = ~0; hints->fabric_attr->name = strdup("gni"); ret = fi_getinfo(FI_VERSION(1, 0), NULL, 0, 0, hints, &fi); cr_assert(!ret, "fi_getinfo"); ret = fi_fabric(fi->fabric_attr, &fab, NULL); cr_assert(!ret, "fi_fabric"); ret = fi_domain(fab, fi, &dom, NULL); cr_assert(!ret, "fi_domain"); attr.type = FI_AV_MAP; attr.count = 16; ret = fi_av_open(dom, &attr, &av, NULL); cr_assert(!ret, "fi_av_open"); for (i = 0; i < NUM_EPS; i++) { ret = fi_endpoint(dom, fi, &ep[i], NULL); cr_assert(!ret, "fi_endpoint"); } }
static int alloc_ep_res(struct fi_info *fi) { struct fi_cq_attr cq_attr; struct fi_av_attr av_attr; int ret; buffer_size = !custom ? test_size[TEST_CNT - 1].size : transfer_size; buffer_size += prefix_len; buf = malloc(buffer_size); if (!buf) { perror("malloc"); return -1; } buf_ptr = (char *)buf + prefix_len; memset(&cq_attr, 0, sizeof cq_attr); cq_attr.format = FI_CQ_FORMAT_CONTEXT; cq_attr.wait_obj = FI_WAIT_NONE; cq_attr.size = max_credits << 1; ret = fi_cq_open(dom, &cq_attr, &scq, NULL); if (ret) { printf("fi_cq_open send comp %s\n", fi_strerror(-ret)); goto err1; } ret = fi_cq_open(dom, &cq_attr, &rcq, NULL); if (ret) { printf("fi_cq_open recv comp %s\n", fi_strerror(-ret)); goto err2; } ret = fi_mr_reg(dom, buf, buffer_size, 0, 0, 0, 0, &mr, NULL); if (ret) { printf("fi_mr_reg %s\n", fi_strerror(-ret)); goto err3; } av_attr.type = FI_AV_MAP; av_attr.name = NULL; av_attr.flags = 0; ret = fi_av_open(dom, &av_attr, &av, NULL); if (ret) { printf("fi_av_open %s\n", fi_strerror(-ret)); goto err4; } return 0; err4: fi_close(&mr->fid); err3: fi_close(&rcq->fid); err2: fi_close(&scq->fid); err1: free(buf); return ret; }
int rxd_av_create(struct fid_domain *domain_fid, struct fi_av_attr *attr, struct fid_av **av_fid, void *context) { int ret; struct rxd_av *av; struct rxd_domain *domain; struct util_av_attr util_attr; struct fi_av_attr av_attr; if (!attr) return -FI_EINVAL; if (attr->name) return -FI_ENOSYS; domain = container_of(domain_fid, struct rxd_domain, util_domain.domain_fid); av = calloc(1, sizeof(*av)); if (!av) return -FI_ENOMEM; util_attr.addrlen = sizeof(fi_addr_t); util_attr.overhead = attr->count; util_attr.flags = FI_SOURCE; av->size = attr->count ? attr->count : RXD_AV_DEF_COUNT; if (attr->type == FI_AV_UNSPEC) attr->type = FI_AV_TABLE; ret = ofi_av_init(&domain->util_domain, attr, &util_attr, &av->util_av, context); if (ret) goto err1; av->size = av->util_av.count; av_attr = *attr; av_attr.type = FI_AV_TABLE; av_attr.count = 0; av_attr.flags = 0; ret = fi_av_open(domain->dg_domain, &av_attr, &av->dg_av, context); if (ret) goto err2; fastlock_init(&av->lock); av->addrlen = domain->addrlen; *av_fid = &av->util_av.av_fid; (*av_fid)->fid.fclass = FI_CLASS_AV; (*av_fid)->fid.ops = &rxd_av_fi_ops; (*av_fid)->ops = &rxd_av_ops; return 0; err2: ofi_av_close(&av->util_av); err1: free(av); return ret; }
static inline int allocate_fabric_resources(struct fabric_info *info) { int ret = 0; struct fi_av_attr av_attr = {0}; /* fabric domain: define domain of resources physical and logical*/ ret = fi_fabric(info->p_info->fabric_attr, &shmem_transport_ofi_fabfd, NULL); if(ret!=0){ OFI_ERRMSG("fabric initialization failed\n"); return ret; } /*access domain: define communication resource limits/boundary within fabric domain */ ret = fi_domain(shmem_transport_ofi_fabfd, info->p_info, &shmem_transport_ofi_domainfd,NULL); if(ret!=0){ OFI_ERRMSG("domain initialization failed\n"); return ret; } /*transmit context: allocate one transmit context for this SHMEM PE * and share it across different multiple endpoints. Since we have only * one thread per PE, a single context is sufficient and allows more * more PEs/node (i.e. doesn't exhaust contexts) */ ret = fi_stx_context(shmem_transport_ofi_domainfd, NULL, /* TODO: fill tx_attr */ &shmem_transport_ofi_stx, NULL); if(ret!=0) { OFI_ERRMSG("stx context initialization failed\n"); return ret; } /*AV table set-up for PE mapping*/ #ifdef USE_AV_MAP av_attr.type = FI_AV_MAP; addr_table = (fi_addr_t*) malloc(info->npes * sizeof(fi_addr_t)); #else /* open Address Vector and bind the AV to the domain */ av_attr.type = FI_AV_TABLE; addr_table = NULL; #endif ret = fi_av_open(shmem_transport_ofi_domainfd, &av_attr, &shmem_transport_ofi_avfd, NULL); if(ret!=0){ OFI_ERRMSG("av open failed\n"); return ret; } return ret; }
/* * Tests: * - synchronous resolution of bad address */ static int av_bad_sync() { int testret; int ret; struct fid_av *av; struct fi_av_attr attr; uint8_t addrbuf[4096]; int buflen; fi_addr_t fi_addr; testret = FAIL; memset(&attr, 0, sizeof(attr)); attr.type = av_type; attr.count = 32; av = NULL; ret = fi_av_open(domain, &attr, &av, NULL); if (ret != 0) { sprintf(err_buf, "fi_av_open(%s) = %d, %s", fi_tostr(&av_type, FI_TYPE_AV_TYPE), ret, fi_strerror(-ret)); goto fail; } fi_addr = ~FI_ADDR_NOTAVAIL; buflen = sizeof(addrbuf); ret = av_create_address_list(bad_address, 0, 1, addrbuf, 0, buflen); if (ret < 0) { goto fail; // av_create_address_list filled err_buf } ret = fi_av_insert(av, addrbuf, 1, &fi_addr, 0, NULL); if (ret != 0) { sprintf(err_buf, "fi_av_insert ret=%d, should be 0", ret); goto fail; } if (fi_addr != FI_ADDR_NOTAVAIL) { sprintf(err_buf, "fi_addr = 0x%lx, should be 0x%lx (FI_ADDR_NOTAVAIL)", fi_addr, FI_ADDR_NOTAVAIL); goto fail; } testret = PASS; fail: if (av != NULL) { fi_close(&av->fid); } return testret; }
/* * Tests: * - async good vector */ static int av_zero_async() { int testret; int ret; struct fid_av *av; struct fi_av_attr attr; uint8_t addrbuf[4096]; uint32_t ctx; fi_addr_t fi_addr[MAX_ADDR]; testret = FAIL; memset(&attr, 0, sizeof(attr)); attr.type = av_type; attr.count = 32; attr.flags = FI_EVENT; av = NULL; ret = fi_av_open(domain, &attr, &av, NULL); if (ret != 0) { sprintf(err_buf, "fi_av_open(%s) = %d, %s", fi_tostr(&av_type, FI_TYPE_AV_TYPE), ret, fi_strerror(-ret)); goto fail; } ret = fi_bind(&av->fid, &eq->fid, 0); if (ret != 0) { sprintf(err_buf, "fi_bind() = %d, %s", ret, fi_strerror(-ret)); goto fail; } ret = fi_av_insert(av, addrbuf, 0, fi_addr, 0, &ctx); if (ret != 0) { sprintf(err_buf, "fi_av_insert ret=%d, should be 0", ret); goto fail; } if (check_eq_sread(eq, &av->fid, &ctx, 0, 20000, 0) != 0) { goto fail; } testret = PASS; fail: if (av != NULL) { fi_close(&av->fid); } return testret; }
static int alloc_ep_res(void) { struct fi_cq_attr cq_attr; struct fi_av_attr av_attr; int ret; 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; /* Open completion queue for send completions */ ret = fi_cq_open(dom, &cq_attr, &scq, NULL); if (ret) { ct_print_fi_error("fi_cq_open", ret); goto err1; } /* Open completion queue for recv completions */ ret = fi_cq_open(dom, &cq_attr, &rcq, NULL); if (ret) { ct_print_fi_error("fi_cq_open", ret); goto err2; } memset(&av_attr, 0, sizeof(av_attr)); av_attr.type = fi->domain_attr->av_type ? fi->domain_attr->av_type : FI_AV_TABLE; av_attr.count = numprocs; av_attr.name = NULL; /* Open address vector (AV) for mapping address */ ret = fi_av_open(dom, &av_attr, &av, NULL); if (ret) { ct_print_fi_error("fi_av_open", ret); goto err3; } return 0; err3: fi_close(&rcq->fid); err2: fi_close(&scq->fid); err1: return ret; }
void vc_lookup_setup(int av_type, int av_size) { int ret = 0; struct fi_av_attr attr; hints = fi_allocinfo(); hints->mode = mode_bits; hints->domain_attr->mr_mode = GNIX_DEFAULT_MR_MODE; hints->fabric_attr->prov_name = strdup("gni"); /* Create endpoint */ ret = fi_getinfo(fi_version(), NULL, 0, 0, hints, &fi); cr_assert(!ret, "fi_getinfo"); ret = fi_fabric(fi->fabric_attr, &fab, NULL); cr_assert(!ret, "fi_fabric"); ret = fi_domain(fab, fi, &dom, NULL); cr_assert(!ret, "fi_domain"); attr.type = av_type; attr.count = av_size; ret = fi_av_open(dom, &attr, &av, NULL); cr_assert(!ret, "fi_av_open"); ret = fi_endpoint(dom, fi, &ep, NULL); cr_assert(!ret, "fi_endpoint"); gnix_ep = container_of(ep, struct gnix_fid_ep, ep_fid); ret = fi_getname(&ep->fid, NULL, &ep_name_len); ret = fi_getname(&ep->fid, &ep_name, &ep_name_len); cr_assert(ret == FI_SUCCESS); ret = fi_ep_bind(ep, &av->fid, 0); cr_assert(!ret, "fi_ep_bind"); ret = fi_enable(ep); cr_assert(!ret, "fi_ep_enable"); fi_freeinfo(hints); }
Test(av_bare, test_capacity) { int ret, i; fi_addr_t addresses[TABLE_SIZE_FINAL]; struct fi_av_attr av_table_attr = { .type = FI_AV_TABLE, .count = TABLE_SIZE_INIT, }; ret = fi_av_open(dom, &av_table_attr, &av, NULL); cr_assert_eq(ret, FI_SUCCESS, "failed to open av"); fake_names = (struct gnix_ep_name *)calloc(TABLE_SIZE_FINAL, sizeof(*fake_names)); cr_assert_neq(fake_names, NULL); for (i = 0; i < TABLE_SIZE_INIT; i++) { fake_names[i].gnix_addr.device_addr = i + 100; fake_names[i].gnix_addr.cdm_id = i; fake_names[i].cm_nic_cdm_id = 0xbeef; fake_names[i].cookie = 0xdeadbeef; } ret = fi_av_insert(av, fake_names, TABLE_SIZE_INIT, addresses, 0, NULL); cr_assert_eq(ret, TABLE_SIZE_INIT, "av insert failed"); /* * now add some more */ for (i = TABLE_SIZE_INIT; i < TABLE_SIZE_FINAL; i++) { fake_names[i].gnix_addr.device_addr = i + 100; fake_names[i].gnix_addr.cdm_id = i; fake_names[i].cm_nic_cdm_id = 0xbeef; fake_names[i].cookie = 0xdeadbeef; } ret = fi_av_insert(av, &fake_names[TABLE_SIZE_INIT], TABLE_SIZE_FINAL - TABLE_SIZE_INIT, &addresses[TABLE_SIZE_INIT], 0, NULL); cr_assert_eq(ret, TABLE_SIZE_FINAL - TABLE_SIZE_INIT, "av insert failed"); }
/* * The RXD code is agnostic wrt the datagram address format, but we need * to know the size of the address in order to iterate over them. Because * the datagram AV may be configured for asynchronous operation, open a * temporary one to insert/lookup the address to get the size. I agree it's * goofy. */ static int rxd_av_set_addrlen(struct rxd_av *av, const void *addr) { struct rxd_domain *domain; struct fid_av *tmp_av; struct fi_av_attr attr; uint8_t tmp_addr[RXD_NAME_LENGTH]; fi_addr_t fiaddr; size_t len; int ret; FI_INFO(&rxd_prov, FI_LOG_AV, "determine dgram address len\n"); memset(&attr, 0, sizeof attr); attr.count = 1; domain = container_of(av->util_av.domain, struct rxd_domain, util_domain); ret = fi_av_open(domain->dg_domain, &attr, &tmp_av, NULL); if (ret) { FI_WARN(&rxd_prov, FI_LOG_AV, "failed to open av: %d (%s)\n", -ret, fi_strerror(-ret)); return ret; } ret = fi_av_insert(tmp_av, addr, 1, &fiaddr, 0, NULL); if (ret != 1) { FI_WARN(&rxd_prov, FI_LOG_AV, "addr insert failed: %d (%s)\n", -ret, fi_strerror(-ret)); ret = -FI_EINVAL; goto close; } len = sizeof tmp_addr; ret = fi_av_lookup(tmp_av, fiaddr, tmp_addr, &len); if (ret) { FI_WARN(&rxd_prov, FI_LOG_AV, "addr lookup failed: %d (%s)\n", -ret, fi_strerror(-ret)); goto close; } FI_INFO(&rxd_prov, FI_LOG_AV, "set dgram address len: %zu\n", len); av->dg_addrlen = len; close: fi_close(&tmp_av->fid); return ret; }
static int ft_open_av(void) { struct fi_av_attr attr; int ret; if (av) return 0; memset(&attr, 0, sizeof attr); attr.type = test_info.av_type; attr.count = 2; ret = fi_av_open(domain, &attr, &av, NULL); if (ret) { FT_PRINTERR("fi_av_open", ret); return ret; } return ret; }
/* * Tests: * - async vector with 1 good and 1 bad */ static int av_goodbad_vector_async() { int testret; int ret; int i; struct fid_av *av; struct fi_av_attr attr; uint8_t addrbuf[4096]; uint32_t event; uint32_t ctx; struct fi_eq_entry entry; int buflen; fi_addr_t fi_addr[MAX_ADDR]; testret = FAIL; memset(&attr, 0, sizeof(attr)); attr.type = av_type; attr.count = 32; attr.flags = FI_EVENT; av = NULL; ret = fi_av_open(domain, &attr, &av, NULL); if (ret != 0) { sprintf(err_buf, "fi_av_open(%s) = %d, %s", fi_tostr(&av_type, FI_TYPE_AV_TYPE), ret, fi_strerror(-ret)); goto fail; } ret = fi_bind(&av->fid, &eq->fid, 0); if (ret != 0) { sprintf(err_buf, "fi_bind() = %d, %s", ret, fi_strerror(-ret)); goto fail; } for (i = 0; i < MAX_ADDR; ++i) { fi_addr[i] = FI_ADDR_NOTAVAIL; } fi_addr[1] = ~FI_ADDR_NOTAVAIL; buflen = sizeof(addrbuf); /* vector is good address + bad address */ ret = av_create_address_list(good_address, 0, 1, addrbuf, 0, buflen); if (ret < 0) { goto fail; // av_create_address_list filled err_buf } ret = av_create_address_list(bad_address, 0, 1, addrbuf, 1, buflen); if (ret < 0) { goto fail; // av_create_address_list filled err_buf } ret = fi_av_insert(av, addrbuf, 2, fi_addr, 0, &ctx); if (ret != 2) { sprintf(err_buf, "fi_av_insert ret=%d, %s", ret, fi_strerror(-ret)); goto fail; } /* * Read event after sync, verify we get FI_EAVAIL, then read and * verify the error completion */ ret = fi_eq_sread(eq, &event, &entry, sizeof(entry), 20000, 0); if (ret != -FI_EAVAIL) { sprintf(err_buf, "fi_eq_sread ret = %d, should be -FI_EAVAIL", ret); goto fail; } ret = check_eq_readerr(eq, &av->fid, &ctx, 1); if (ret != 0) { goto fail; } /* * Now we should get a good completion, and all fi_addr except fd_addr[1] * should have good values. */ if (check_eq_sread(eq, &av->fid, &ctx, 1, 20000, 0) != 0) { goto fail; } if (fi_addr[0] == FI_ADDR_NOTAVAIL) { sprintf(err_buf, "fi_addr[0] = FI_ADDR_NOTAVAIL"); goto fail; } if (fi_addr[1] != FI_ADDR_NOTAVAIL) { sprintf(err_buf, "fi_addr[1] != FI_ADDR_NOTAVAIL"); goto fail; } testret = PASS; fail: if (av != NULL) { fi_close(&av->fid); } return testret; }
/* * Tests: * - async 2 good vectors */ static int av_good_2vector_async() { int testret; int ret; int i; struct fid_av *av; struct fi_av_attr attr; uint8_t addrbuf[4096]; uint32_t event; struct fi_eq_entry entry; uint32_t ctx[2]; int buflen; fi_addr_t fi_addr[MAX_ADDR]; testret = FAIL; memset(&attr, 0, sizeof(attr)); attr.type = av_type; attr.count = 32; attr.flags = FI_EVENT; av = NULL; ret = fi_av_open(domain, &attr, &av, NULL); if (ret != 0) { sprintf(err_buf, "fi_av_open(%s) = %d, %s", fi_tostr(&av_type, FI_TYPE_AV_TYPE), ret, fi_strerror(-ret)); goto fail; } ret = fi_bind(&av->fid, &eq->fid, 0); if (ret != 0) { sprintf(err_buf, "fi_bind() = %d, %s", ret, fi_strerror(-ret)); goto fail; } for (i = 0; i < MAX_ADDR; ++i) { fi_addr[i] = FI_ADDR_NOTAVAIL; } buflen = sizeof(addrbuf); /* 1st vector is just first address */ ret = av_create_address_list(good_address, 0, 1, addrbuf, 0, buflen); if (ret < 0) { goto fail; // av_create_address_list filled err_buf } ret = fi_av_insert(av, addrbuf, 1, fi_addr, FI_MORE, &ctx[0]); if (ret != 1) { sprintf(err_buf, "fi_av_insert ret=%d, %s", ret, fi_strerror(-ret)); goto fail; } ctx[0] = 1; /* 2nd vector is remaining addresses */ ret = av_create_address_list(good_address, 1, num_good_addr-1, addrbuf, 0, buflen); if (ret < 0) { goto fail; // av_create_address_list filled err_buf } ret = fi_av_insert(av, addrbuf, num_good_addr-1, &fi_addr[1], 0, &ctx[1]); if (ret != num_good_addr-1) { sprintf(err_buf, "fi_av_insert ret=%d, %s", ret, fi_strerror(-ret)); goto fail; } ctx[1] = num_good_addr-1; /* * Handle completions in either order */ for (i = 0; i < 2; ++i) { ret = fi_eq_sread(eq, &event, &entry, sizeof(entry), 20000, 0); ret = check_eq_result(ret, event, &entry, &av->fid, NULL, ~0); if (ret != 0) { goto fail; } if (entry.context != &ctx[0] && entry.context != &ctx[1]) { sprintf(err_buf, "bad context: %p", entry.context); goto fail; } if (*(uint32_t *)(entry.context) == ~0) { sprintf(err_buf, "duplicate context: %p", entry.context); goto fail; } if (*(uint32_t *)(entry.context) != entry.data) { sprintf(err_buf, "count = %lu, should be %d", entry.data, *(uint32_t *)(entry.context)); goto fail; } *(uint32_t *)(entry.context) = ~0; } for (i = 0; i < num_good_addr; ++i) { if (fi_addr[i] == FI_ADDR_NOTAVAIL) { sprintf(err_buf, "fi_addr[%d] = FI_ADDR_NOTAVAIL", i); goto fail; } } testret = PASS; fail: if (av != NULL) { fi_close(&av->fid); } return testret; }
static void setup_ep(void) { int ret; struct fi_av_attr attr; size_t addrlen = 0; attr.type = FI_AV_MAP; attr.count = 16; ret = fi_av_open(dom, &attr, &av, NULL); cr_assert(!ret, "fi_av_open"); ret = fi_endpoint(dom, fi, &ep[0], NULL); cr_assert(!ret, "fi_endpoint"); cq_attr.format = FI_CQ_FORMAT_TAGGED; cq_attr.size = 1024; cq_attr.wait_obj = 0; ret = fi_cq_open(dom, &cq_attr, &msg_cq[0], 0); cr_assert(!ret, "fi_cq_open"); ret = fi_cq_open(dom, &cq_attr, &msg_cq[1], 0); cr_assert(!ret, "fi_cq_open"); ret = fi_ep_bind(ep[0], &msg_cq[0]->fid, FI_SEND | FI_RECV); cr_assert(!ret, "fi_ep_bind"); ret = fi_getname(&ep[0]->fid, NULL, &addrlen); cr_assert(addrlen > 0); ep_name[0] = malloc(addrlen); cr_assert(ep_name[0] != NULL); ret = fi_getname(&ep[0]->fid, ep_name[0], &addrlen); cr_assert(ret == FI_SUCCESS); ret = fi_endpoint(dom, fi, &ep[1], NULL); cr_assert(!ret, "fi_endpoint"); ret = fi_ep_bind(ep[1], &msg_cq[1]->fid, FI_SEND | FI_RECV); cr_assert(!ret, "fi_ep_bind"); ep_name[1] = malloc(addrlen); cr_assert(ep_name[1] != NULL); ret = fi_getname(&ep[1]->fid, ep_name[1], &addrlen); cr_assert(ret == FI_SUCCESS); ret = fi_av_insert(av, ep_name[0], 1, &gni_addr[0], 0, NULL); cr_assert(ret == 1); ret = fi_av_insert(av, ep_name[1], 1, &gni_addr[1], 0, NULL); cr_assert(ret == 1); ret = fi_ep_bind(ep[0], &av->fid, 0); cr_assert(!ret, "fi_ep_bind"); ret = fi_ep_bind(ep[1], &av->fid, 0); cr_assert(!ret, "fi_ep_bind"); ret = fi_enable(ep[0]); cr_assert(!ret, "fi_ep_enable"); ret = fi_enable(ep[1]); cr_assert(!ret, "fi_ep_enable"); }
/* * Tests: * - async good vector */ static int av_good_vector_async() { int testret; int ret; int i; struct fid_av *av; struct fi_av_attr attr; uint8_t addrbuf[4096]; uint32_t ctx; int buflen; fi_addr_t fi_addr[MAX_ADDR]; testret = FAIL; memset(&attr, 0, sizeof(attr)); attr.type = av_type; attr.count = 32; attr.flags = FI_EVENT; av = NULL; ret = fi_av_open(domain, &attr, &av, NULL); if (ret != 0) { sprintf(err_buf, "fi_av_open(%s) = %d, %s", fi_tostr(&av_type, FI_TYPE_AV_TYPE), ret, fi_strerror(-ret)); goto fail; } ret = fi_bind(&av->fid, &eq->fid, 0); if (ret != 0) { sprintf(err_buf, "fi_bind() = %d, %s", ret, fi_strerror(-ret)); goto fail; } for (i = 0; i < MAX_ADDR; ++i) { fi_addr[i] = FI_ADDR_NOTAVAIL; } buflen = sizeof(addrbuf); ret = av_create_address_list(good_address, 0, num_good_addr, addrbuf, 0, buflen); if (ret < 0) { goto fail; // av_create_address_list filled err_buf } for (i = 0; i < num_good_addr; ++i) { fi_addr[i] = FI_ADDR_NOTAVAIL; } ret = fi_av_insert(av, addrbuf, num_good_addr, fi_addr, 0, &ctx); if (ret != num_good_addr) { sprintf(err_buf, "fi_av_insert ret=%d, %s", ret, fi_strerror(-ret)); goto fail; } if (check_eq_sread(eq, &av->fid, &ctx, num_good_addr, 20000, 0) != 0) { goto fail; } for (i = 0; i < num_good_addr; ++i) { if (fi_addr[i] == FI_ADDR_NOTAVAIL) { sprintf(err_buf, "fi_addr[%d] = FI_ADDR_NOTAVAIL", i); goto fail; } } testret = PASS; fail: if (av != NULL) { fi_close(&av->fid); } return testret; }
/* * Tests: * - sync vector with 1 good and 1 bad */ static int av_goodbad_vector_sync() { int testret; int ret; int i; struct fid_av *av; struct fi_av_attr attr; uint8_t addrbuf[4096]; int buflen; fi_addr_t fi_addr[MAX_ADDR]; testret = FAIL; memset(&attr, 0, sizeof(attr)); attr.type = av_type; attr.count = 32; av = NULL; ret = fi_av_open(domain, &attr, &av, NULL); if (ret != 0) { sprintf(err_buf, "fi_av_open(%s) = %d, %s", fi_tostr(&av_type, FI_TYPE_AV_TYPE), ret, fi_strerror(-ret)); goto fail; } for (i = 0; i < MAX_ADDR; ++i) { fi_addr[i] = FI_ADDR_NOTAVAIL; } fi_addr[1] = ~FI_ADDR_NOTAVAIL; buflen = sizeof(addrbuf); /* vector is good address + bad address */ ret = av_create_address_list(good_address, 0, 1, addrbuf, 0, buflen); if (ret < 0) { goto fail; // av_create_address_list filled err_buf } ret = av_create_address_list(bad_address, 0, 1, addrbuf, 1, buflen); if (ret < 0) { goto fail; // av_create_address_list filled err_buf } ret = fi_av_insert(av, addrbuf, 2, fi_addr, 0, NULL); if (ret != 1) { sprintf(err_buf, "fi_av_insert ret=%d, should be 1", ret); goto fail; } /* * Check returned fi_addrs */ if (fi_addr[0] == FI_ADDR_NOTAVAIL) { sprintf(err_buf, "fi_addr[0] = FI_ADDR_NOTAVAIL"); goto fail; } if (fi_addr[1] != FI_ADDR_NOTAVAIL) { sprintf(err_buf, "fi_addr[1] != FI_ADDR_NOTAVAIL"); goto fail; } testret = PASS; fail: if (av != NULL) { fi_close(&av->fid); } return testret; }
void rdm_api_setup_ep(void) { int ret, i, j; struct fi_av_attr attr; size_t addrlen = 0; /* Get info about fabric services with the provided hints */ for (i = 0; i < NUMEPS; i++) { ret = fi_getinfo(FI_VERSION(1, 0), NULL, 0, 0, hints[i], &fi[i]); cr_assert(!ret, "fi_getinfo"); } attr.type = FI_AV_MAP; attr.count = NUMEPS; cq_attr.format = FI_CQ_FORMAT_TAGGED; cq_attr.size = 1024; cq_attr.wait_obj = 0; target = malloc(BUF_SZ * 3); /* 3x BUF_SZ for multi recv testing */ assert(target); source = malloc(BUF_SZ); assert(source); uc_target = malloc(BUF_SZ); assert(uc_target); uc_source = malloc(BUF_SZ); assert(uc_source); ret = fi_fabric(fi[0]->fabric_attr, &fab, NULL); cr_assert(!ret, "fi_fabric"); for (i = 0; i < NUMEPS; i++) { ret = fi_domain(fab, fi[i], dom + i, NULL); cr_assert(!ret, "fi_domain"); ret = fi_open_ops(&dom[i]->fid, FI_GNI_DOMAIN_OPS_1, 0, (void **) (gni_domain_ops + i), NULL); ret = fi_av_open(dom[i], &attr, av + i, NULL); cr_assert(!ret, "fi_av_open"); ret = fi_endpoint(dom[i], fi[i], ep + i, NULL); cr_assert(!ret, "fi_endpoint"); ret = fi_cq_open(dom[i], &cq_attr, msg_cq + i, 0); cr_assert(!ret, "fi_cq_open"); ret = fi_ep_bind(ep[i], &msg_cq[i]->fid, FI_SEND | FI_RECV); cr_assert(!ret, "fi_ep_bind"); ret = fi_getname(&ep[i]->fid, NULL, &addrlen); cr_assert(addrlen > 0); ep_name[i] = malloc(addrlen); cr_assert(ep_name[i] != NULL); ret = fi_getname(&ep[i]->fid, ep_name[i], &addrlen); cr_assert(ret == FI_SUCCESS); } 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); } ret = fi_ep_bind(ep[i], &av[i]->fid, 0); cr_assert(!ret, "fi_ep_bind"); ret = fi_enable(ep[i]); cr_assert(!ret, "fi_ep_enable"); ret = fi_cntr_open(dom[i], &cntr_attr, send_cntr + i, 0); cr_assert(!ret, "fi_cntr_open"); ret = fi_ep_bind(ep[i], &send_cntr[i]->fid, FI_SEND); cr_assert(!ret, "fi_ep_bind"); ret = fi_cntr_open(dom[i], &cntr_attr, recv_cntr + i, 0); cr_assert(!ret, "fi_cntr_open"); ret = fi_ep_bind(ep[i], &recv_cntr[i]->fid, FI_RECV); cr_assert(!ret, "fi_ep_bind"); } for (i = 0; i < NUMEPS; i++) { ret = fi_mr_reg(dom[i], target, 3 * 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]); } }
static int alloc_ep_res(struct fi_info *fi) { struct fi_cq_attr cq_attr; struct fi_av_attr av_attr; int ret; buffer_size = opts.user_options & FT_OPT_SIZE ? opts.transfer_size : test_size[TEST_CNT - 1].size; if (max_msg_size > 0 && buffer_size > max_msg_size) { buffer_size = max_msg_size; } if (buffer_size < fi->src_addrlen) { buffer_size = fi->src_addrlen; } buffer_size += prefix_len; buf = malloc(buffer_size); if (!buf) { perror("malloc"); return -1; } buf_ptr = (char *)buf + prefix_len; memset(&cq_attr, 0, sizeof cq_attr); cq_attr.format = FI_CQ_FORMAT_CONTEXT; cq_attr.wait_obj = FI_WAIT_NONE; cq_attr.size = max_credits << 1; ret = fi_cq_open(dom, &cq_attr, &scq, NULL); if (ret) { FT_PRINTERR("fi_cq_open", ret); goto err1; } ret = fi_cq_open(dom, &cq_attr, &rcq, NULL); if (ret) { FT_PRINTERR("fi_cq_open", ret); goto err2; } ret = fi_mr_reg(dom, buf, buffer_size, 0, 0, 0, 0, &mr, NULL); if (ret) { FT_PRINTERR("fi_mr_reg", ret); goto err3; } 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.name = NULL; av_attr.flags = 0; ret = fi_av_open(dom, &av_attr, &av, NULL); if (ret) { FT_PRINTERR("fi_av_open", ret); goto err4; } ret = fi_endpoint(dom, fi, &ep, NULL); if (ret) { FT_PRINTERR("fi_endpoint", ret); goto err5; } return 0; err5: fi_close(&av->fid); err4: fi_close(&mr->fid); err3: fi_close(&rcq->fid); err2: fi_close(&scq->fid); err1: free(buf); return ret; }
void cancel_setup(void) { int ret = 0; struct fi_av_attr attr; size_t addrlen = 0; int rem_requested_key, loc_requested_key; hints = fi_allocinfo(); cr_assert(hints, "fi_allocinfo"); hints->domain_attr->mr_mode = GNIX_DEFAULT_MR_MODE; hints->domain_attr->cq_data_size = 4; hints->mode = mode_bits; hints->fabric_attr->prov_name = strdup("gni"); ret = fi_getinfo(fi_version(), NULL, 0, 0, hints, &fi); cr_assert(!ret, "fi_getinfo"); ret = fi_fabric(fi->fabric_attr, &fab, NULL); cr_assert(!ret, "fi_fabric"); ret = fi_domain(fab, fi, &dom, NULL); cr_assert(!ret, "fi_domain"); memset(&attr, 0, sizeof(attr)); attr.type = FI_AV_MAP; attr.count = 16; ret = fi_av_open(dom, &attr, &av, NULL); cr_assert(!ret, "fi_av_open"); ret = fi_endpoint(dom, fi, &ep[0], NULL); cr_assert(!ret, "fi_endpoint"); cq_attr.format = FI_CQ_FORMAT_CONTEXT; cq_attr.size = 1024; cq_attr.wait_obj = 0; ret = fi_cq_open(dom, &cq_attr, &msg_cq[0], 0); cr_assert(!ret, "fi_cq_open"); ret = fi_cq_open(dom, &cq_attr, &msg_cq[1], 0); cr_assert(!ret, "fi_cq_open"); ret = fi_ep_bind(ep[0], &msg_cq[0]->fid, FI_SEND | FI_RECV); cr_assert(!ret, "fi_ep_bind"); ret = fi_getname(&ep[0]->fid, NULL, &addrlen); cr_assert(addrlen > 0); ep_name[0] = malloc(addrlen); cr_assert(ep_name[0] != NULL); ret = fi_getname(&ep[0]->fid, ep_name[0], &addrlen); cr_assert(ret == FI_SUCCESS); ret = fi_endpoint(dom, fi, &ep[1], NULL); cr_assert(!ret, "fi_endpoint"); ret = fi_ep_bind(ep[1], &msg_cq[1]->fid, FI_SEND | FI_RECV); cr_assert(!ret, "fi_ep_bind"); ep_name[1] = malloc(addrlen); cr_assert(ep_name[1] != NULL); ret = fi_getname(&ep[1]->fid, ep_name[1], &addrlen); cr_assert(ret == FI_SUCCESS); ret = fi_av_insert(av, ep_name[0], 1, &gni_addr[0], 0, NULL); cr_assert(ret == 1); ret = fi_av_insert(av, ep_name[1], 1, &gni_addr[1], 0, NULL); cr_assert(ret == 1); ret = fi_ep_bind(ep[0], &av->fid, 0); cr_assert(!ret, "fi_ep_bind"); ret = fi_ep_bind(ep[1], &av->fid, 0); cr_assert(!ret, "fi_ep_bind"); ret = fi_enable(ep[0]); cr_assert(!ret, "fi_ep_enable"); ret = fi_enable(ep[1]); cr_assert(!ret, "fi_ep_enable"); target_base = malloc(GNIT_ALIGN_LEN(BUF_SZ)); assert(target_base); target = GNIT_ALIGN_BUFFER(char *, target_base); source_base = malloc(GNIT_ALIGN_LEN(BUF_SZ)); assert(source_base); source = GNIT_ALIGN_BUFFER(char *, source_base); rem_requested_key = USING_SCALABLE(fi) ? 1 : 0; loc_requested_key = USING_SCALABLE(fi) ? 2 : 0; ret = fi_mr_reg(dom, target, BUF_SZ, FI_REMOTE_WRITE, 0, rem_requested_key, 0, &rem_mr, &target); cr_assert_eq(ret, 0); ret = fi_mr_reg(dom, source, BUF_SZ, FI_REMOTE_WRITE, 0, loc_requested_key, 0, &loc_mr, &source); cr_assert_eq(ret, 0); if (USING_SCALABLE(fi)) { MR_ENABLE(rem_mr, target, BUF_SZ); MR_ENABLE(loc_mr, source, BUF_SZ); } mr_key = fi_mr_key(rem_mr); }
static mca_mtl_base_module_t* ompi_mtl_ofi_component_init(bool enable_progress_threads, bool enable_mpi_threads) { int ret, fi_version; struct fi_info *hints; struct fi_info *providers = NULL, *prov = NULL; struct fi_cq_attr cq_attr = {0}; struct fi_av_attr av_attr = {0}; char ep_name[FI_NAME_MAX] = {0}; size_t namelen; /** * Hints to filter providers * See man fi_getinfo for a list of all filters * mode: Select capabilities MTL is prepared to support. * In this case, MTL will pass in context into communication calls * ep_type: reliable datagram operation * caps: Capabilities required from the provider. * Tag matching is specified to implement MPI semantics. * msg_order: Guarantee that messages with same tag are ordered. */ hints = fi_allocinfo(); if (!hints) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: Could not allocate fi_info\n", __FILE__, __LINE__); goto error; } hints->mode = FI_CONTEXT; hints->ep_attr->type = FI_EP_RDM; /* Reliable datagram */ hints->caps = FI_TAGGED; /* Tag matching interface */ hints->tx_attr->msg_order = FI_ORDER_SAS; hints->rx_attr->msg_order = FI_ORDER_SAS; hints->domain_attr->threading = FI_THREAD_UNSPEC; if (MTL_OFI_PROG_AUTO == control_progress) { hints->domain_attr->control_progress = FI_PROGRESS_AUTO; } else { hints->domain_attr->control_progress = FI_PROGRESS_MANUAL; } if (MTL_OFI_PROG_MANUAL == data_progress) { hints->domain_attr->data_progress = FI_PROGRESS_MANUAL; } else { hints->domain_attr->data_progress = FI_PROGRESS_AUTO; } if (MTL_OFI_AV_TABLE == av_type) { hints->domain_attr->av_type = FI_AV_TABLE; } else { hints->domain_attr->av_type = FI_AV_MAP; } hints->domain_attr->resource_mgmt = FI_RM_ENABLED; /** * FI_VERSION provides binary backward and forward compatibility support * Specify the version of OFI is coded to, the provider will select struct * layouts that are compatible with this version. */ fi_version = FI_VERSION(1, 0); /** * fi_getinfo: returns information about fabric services for reaching a * remote node or service. this does not necessarily allocate resources. * Pass NULL for name/service because we want a list of providers supported. */ ret = fi_getinfo(fi_version, /* OFI version requested */ NULL, /* Optional name or fabric to resolve */ NULL, /* Optional service name or port to request */ 0ULL, /* Optional flag */ hints, /* In: Hints to filter providers */ &providers); /* Out: List of matching providers */ if (0 != ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: fi_getinfo failed: %s\n", __FILE__, __LINE__, fi_strerror(-ret)); goto error; } /** * Select a provider from the list returned by fi_getinfo(). */ prov = select_ofi_provider(providers); if (!prov) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: select_ofi_provider: no provider found\n", __FILE__, __LINE__); goto error; } /** * Open fabric * The getinfo struct returns a fabric attribute struct that can be used to * instantiate the virtual or physical network. This opens a "fabric * provider". See man fi_fabric for details. */ ret = fi_fabric(prov->fabric_attr, /* In: Fabric attributes */ &ompi_mtl_ofi.fabric, /* Out: Fabric handle */ NULL); /* Optional context for fabric events */ if (0 != ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: fi_fabric failed: %s\n", __FILE__, __LINE__, fi_strerror(-ret)); goto error; } /** * Create the access domain, which is the physical or virtual network or * hardware port/collection of ports. Returns a domain object that can be * used to create endpoints. See man fi_domain for details. */ ret = fi_domain(ompi_mtl_ofi.fabric, /* In: Fabric object */ prov, /* In: Provider */ &ompi_mtl_ofi.domain, /* Out: Domain oject */ NULL); /* Optional context for domain events */ if (0 != ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: fi_domain failed: %s\n", __FILE__, __LINE__, fi_strerror(-ret)); goto error; } /** * Create a transport level communication endpoint. To use the endpoint, * it must be bound to completion counters or event queues and enabled, * and the resources consumed by it, such as address vectors, counters, * completion queues, etc. * see man fi_endpoint for more details. */ ret = fi_endpoint(ompi_mtl_ofi.domain, /* In: Domain object */ prov, /* In: Provider */ &ompi_mtl_ofi.ep, /* Out: Endpoint object */ NULL); /* Optional context */ if (0 != ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: fi_endpoint failed: %s\n", __FILE__, __LINE__, fi_strerror(-ret)); goto error; } /** * Save the maximum inject size. */ ompi_mtl_ofi.max_inject_size = prov->tx_attr->inject_size; /** * Create the objects that will be bound to the endpoint. * The objects include: * - completion queue for events * - address vector of other endpoint addresses * - dynamic memory-spanning memory region */ cq_attr.format = FI_CQ_FORMAT_TAGGED; ret = fi_cq_open(ompi_mtl_ofi.domain, &cq_attr, &ompi_mtl_ofi.cq, NULL); if (ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: fi_cq_open failed: %s\n", __FILE__, __LINE__, fi_strerror(-ret)); goto error; } /** * The remote fi_addr will be stored in the ofi_endpoint struct. */ av_attr.type = (MTL_OFI_AV_TABLE == av_type) ? FI_AV_TABLE: FI_AV_MAP; ret = fi_av_open(ompi_mtl_ofi.domain, &av_attr, &ompi_mtl_ofi.av, NULL); if (ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: fi_av_open failed: %s\n", __FILE__, __LINE__, fi_strerror(-ret)); goto error; } /** * Bind the CQ and AV to the endpoint object. */ ret = fi_ep_bind(ompi_mtl_ofi.ep, (fid_t)ompi_mtl_ofi.cq, FI_SEND | FI_RECV); if (0 != ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: fi_bind CQ-EP failed: %s\n", __FILE__, __LINE__, fi_strerror(-ret)); goto error; } ret = fi_ep_bind(ompi_mtl_ofi.ep, (fid_t)ompi_mtl_ofi.av, 0); if (0 != ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: fi_bind AV-EP failed: %s\n", __FILE__, __LINE__, fi_strerror(-ret)); goto error; } /** * Enable the endpoint for communication * This commits the bind operations. */ ret = fi_enable(ompi_mtl_ofi.ep); if (0 != ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: fi_enable failed: %s\n", __FILE__, __LINE__, fi_strerror(-ret)); goto error; } /** * Free providers info since it's not needed anymore. */ fi_freeinfo(hints); hints = NULL; fi_freeinfo(providers); providers = NULL; /** * Get our address and publish it with modex. */ namelen = sizeof(ep_name); ret = fi_getname((fid_t)ompi_mtl_ofi.ep, &ep_name[0], &namelen); if (ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: fi_getname failed: %s\n", __FILE__, __LINE__, fi_strerror(-ret)); goto error; } OFI_COMPAT_MODEX_SEND(ret, &mca_mtl_ofi_component.super.mtl_version, &ep_name, namelen); if (OMPI_SUCCESS != ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: modex_send failed: %d\n", __FILE__, __LINE__, ret); goto error; } ompi_mtl_ofi.epnamelen = namelen; /** * Set the ANY_SRC address. */ ompi_mtl_ofi.any_addr = FI_ADDR_UNSPEC; /** * Activate progress callback. */ ret = opal_progress_register(ompi_mtl_ofi_progress_no_inline); if (OMPI_SUCCESS != ret) { opal_output_verbose(1, ompi_mtl_base_framework.framework_output, "%s:%d: opal_progress_register failed: %d\n", __FILE__, __LINE__, ret); goto error; } return &ompi_mtl_ofi.base; error: if (providers) { (void) fi_freeinfo(providers); } if (hints) { (void) fi_freeinfo(hints); } if (ompi_mtl_ofi.av) { (void) fi_close((fid_t)ompi_mtl_ofi.av); } if (ompi_mtl_ofi.cq) { (void) fi_close((fid_t)ompi_mtl_ofi.cq); } if (ompi_mtl_ofi.ep) { (void) fi_close((fid_t)ompi_mtl_ofi.ep); } if (ompi_mtl_ofi.domain) { (void) fi_close((fid_t)ompi_mtl_ofi.domain); } if (ompi_mtl_ofi.fabric) { (void) fi_close((fid_t)ompi_mtl_ofi.fabric); } return NULL; }
static int alloc_ep_res(struct fi_info *fi) { struct fi_cq_attr cq_attr; struct fi_av_attr av_attr; int ret; buffer_size = opts.user_options & FT_OPT_SIZE ? opts.transfer_size : test_size[TEST_CNT - 1].size; buf = malloc(MAX(buffer_size, sizeof(uint64_t))); if (!buf) { perror("malloc"); return -1; } result = malloc(MAX(buffer_size, sizeof(uint64_t))); if (!result) { perror("malloc"); return -1; } compare = malloc(MAX(buffer_size, sizeof(uint64_t))); if (!compare) { 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 = 128; ret = fi_cq_open(dom, &cq_attr, &scq, NULL); if (ret) { FT_PRINTERR("fi_cq_open", ret); goto err1; } ret = fi_cq_open(dom, &cq_attr, &rcq, NULL); if (ret) { FT_PRINTERR("fi_cq_open", ret); goto err2; } // registers local data buffer buff that specifies // the first operand of the atomic operation ret = fi_mr_reg(dom, buf, MAX(buffer_size, sizeof(uint64_t)), FI_REMOTE_READ | FI_REMOTE_WRITE, 0, get_mr_key(), 0, &mr, NULL); if (ret) { FT_PRINTERR("fi_mr_reg", ret); goto err3; } // registers local data buffer that stores initial value of // the remote buffer ret = fi_mr_reg(dom, result, MAX(buffer_size, sizeof(uint64_t)), FI_REMOTE_READ | FI_REMOTE_WRITE, 0, get_mr_key(), 0, &mr_result, NULL); if (ret) { FT_PRINTERR("fi_mr_reg", -ret); goto err4; } // registers local data buffer that contains comparison data ret = fi_mr_reg(dom, compare, MAX(buffer_size, sizeof(uint64_t)), FI_REMOTE_READ | FI_REMOTE_WRITE, 0, get_mr_key(), 0, &mr_compare, NULL); if (ret) { FT_PRINTERR("fi_mr_reg", ret); goto err5; } 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.name = NULL; ret = fi_av_open(dom, &av_attr, &av, NULL); if (ret) { FT_PRINTERR("fi_av_open", ret); goto err6; } ret = fi_endpoint(dom, fi, &ep, NULL); if (ret) { FT_PRINTERR("fi_endpoint", ret); goto err7; } return 0; err7: fi_close(&av->fid); err6: fi_close(&mr_compare->fid); err5: fi_close(&mr_result->fid); err4: fi_close(&mr->fid); err3: fi_close(&rcq->fid); err2: fi_close(&scq->fid); err1: free(buf); free(result); free(compare); return ret; }
void rdm_str_addr_sr_setup_common(void) { int ret = 0, i = 0, j = 0; struct fi_av_attr attr; memset(&attr, 0, sizeof(attr)); attr.type = FI_AV_MAP; attr.count = NUMEPS; cq_attr.format = FI_CQ_FORMAT_TAGGED; cq_attr.size = 1024; cq_attr.wait_obj = 0; target_base = malloc(GNIT_ALIGN_LEN(BUF_SZ)); assert(target_base); target = GNIT_ALIGN_BUFFER(char *, target_base); source_base = malloc(GNIT_ALIGN_LEN(BUF_SZ)); assert(source_base); source = GNIT_ALIGN_BUFFER(char *, source_base); ret = fi_fabric(fi[0]->fabric_attr, &fab, NULL); cr_assert(!ret, "fi_fabric"); for (i = 0; i < NUMEPS; i++) { ret = fi_domain(fab, fi[i], dom + i, NULL); cr_assert(!ret, "fi_domain"); ret = fi_av_open(dom[i], &attr, av + i, NULL); cr_assert(!ret, "fi_av_open"); ret = fi_endpoint(dom[i], fi[i], ep + i, NULL); cr_assert(!ret, "fi_endpoint"); ret = fi_cq_open(dom[i], &cq_attr, msg_cq + i, 0); cr_assert(!ret, "fi_cq_open"); ret = fi_ep_bind(ep[i], &msg_cq[i]->fid, FI_SEND | FI_RECV); cr_assert(!ret, "fi_ep_bind"); ret = fi_getname(&ep[i]->fid, NULL, &addrlen); cr_assert(addrlen > 0); ep_name[i] = malloc(addrlen); cr_assert(ep_name[i] != NULL); ret = fi_getname(&ep[i]->fid, ep_name[i], &addrlen); cr_assert(ret == FI_SUCCESS); } for (i = 0; i < NUMEPS; i++) { /* * To test API-1.1: Reporting of unknown source addresses -- * only insert addresses into the sender's av */ if (i < (NUMEPS / 2)) { for (j = 0; j < NUMEPS; j++) { dbg_printf("Only does src EP insertions\n"); ret = fi_av_insert(av[i], ep_name[j], 1, &gni_addr[j], 0, NULL); cr_assert(ret == 1); } } ret = fi_ep_bind(ep[i], &av[i]->fid, 0); cr_assert(!ret, "fi_ep_bind"); ret = fi_enable(ep[i]); cr_assert(!ret, "fi_ep_enable"); } }
/* returns 0 on success or a negative value that can be stringified with * fi_strerror on error */ static int setup_ep_fixture(struct fid_ep **ep_o) { int ret; struct fi_info *myfi; struct fi_av_attr av_attr; struct fi_cq_attr cq_attr; assert(ep_o != NULL); ret = 0; myfi = fi_dupinfo(fi); if (myfi == NULL) { printf("fi_dupinfo returned NULL\n"); goto fail; } ret = fi_endpoint(domain, myfi, ep_o, NULL); if (ret != 0) { printf("fi_endpoint %s\n", fi_strerror(-ret)); goto fail; } memset(&cq_attr, 0, sizeof cq_attr); cq_attr.format = FI_CQ_FORMAT_CONTEXT; cq_attr.wait_obj = FI_WAIT_NONE; cq_attr.size = TX_CQ_DEPTH; ret = fi_cq_open(domain, &cq_attr, &wcq, /*context=*/NULL); if (ret != 0) { printf("fi_cq_open %s\n", fi_strerror(-ret)); goto fail; } 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_CQ_DEPTH; ret = fi_cq_open(domain, &cq_attr, &rcq, /*context=*/NULL); if (ret != 0) { printf("fi_cq_open %s\n", fi_strerror(-ret)); goto fail; } memset(&av_attr, 0, sizeof av_attr); av_attr.type = myfi->domain_attr->av_type ? myfi->domain_attr->av_type : FI_AV_MAP; av_attr.count = 1; av_attr.name = NULL; ret = fi_av_open(domain, &av_attr, &av, NULL); if (ret != 0) { printf("fi_av_open %s\n", fi_strerror(-ret)); goto fail; } ret = fi_ep_bind(*ep_o, &wcq->fid, FI_SEND); if (ret != 0) { printf("fi_ep_bind(wcq) %s\n", fi_strerror(-ret)); goto fail; } ret = fi_ep_bind(*ep_o, &rcq->fid, FI_RECV); if (ret != 0) { printf("fi_ep_bind(rcq) %s\n", fi_strerror(-ret)); goto fail; } ret = fi_ep_bind(*ep_o, &av->fid, 0); if (ret != 0) { printf("fi_ep_bind(av) %s\n", fi_strerror(-ret)); goto fail; } ret = fi_enable(*ep_o); if (ret != 0) { printf("fi_enable %s\n", fi_strerror(-ret)); goto fail; } if (myfi != NULL) { fi_freeinfo(myfi); } return ret; fail: if (myfi != NULL) { fi_freeinfo(myfi); } return teardown_ep_fixture(*ep_o); }
/* * Tests: * - async 2 vector, 1 good, 1 mix bad+good */ static int av_goodbad_2vector_async() { int testret; int ret; int i; struct fid_av *av; struct fi_av_attr attr; uint8_t addrbuf[4096]; uint32_t event; uint32_t ctx[2]; uint8_t good[2]; uint8_t err; struct fi_eq_entry entry; int buflen; fi_addr_t fi_addr[MAX_ADDR]; testret = FAIL; memset(&attr, 0, sizeof(attr)); attr.type = av_type; attr.count = 32; attr.flags = FI_EVENT; av = NULL; ret = fi_av_open(domain, &attr, &av, NULL); if (ret != 0) { sprintf(err_buf, "fi_av_open(%s) = %d, %s", fi_tostr(&av_type, FI_TYPE_AV_TYPE), ret, fi_strerror(-ret)); goto fail; } ret = fi_bind(&av->fid, &eq->fid, 0); if (ret != 0) { sprintf(err_buf, "fi_bind() = %d, %s", ret, fi_strerror(-ret)); goto fail; } for (i = 0; i < MAX_ADDR; ++i) { fi_addr[i] = FI_ADDR_NOTAVAIL; } fi_addr[1] = ~FI_ADDR_NOTAVAIL; buflen = sizeof(addrbuf); /* 1st vector is one good address */ ret = av_create_address_list(good_address, 0, 1, addrbuf, 0, buflen); if (ret < 0) { goto fail; // av_create_address_list filled err_buf } ret = fi_av_insert(av, addrbuf, 1, fi_addr, FI_MORE, &ctx[0]); if (ret != 1) { sprintf(err_buf, "fi_av_insert ret=%d, %s", ret, fi_strerror(-ret)); goto fail; } ctx[0] = 1; /* second vector is one bad address followed by N-1 good ones */ ret = av_create_address_list(bad_address, 0, 1, addrbuf, 0, buflen); if (ret < 0) { goto fail; // av_create_address_list filled err_buf } if (num_good_addr > 1) { ret = av_create_address_list(good_address, 1, num_good_addr - 1, addrbuf, 1, buflen); if (ret < 0) { goto fail; // av_create_address_list filled err_buf } } ret = fi_av_insert(av, addrbuf, num_good_addr, &fi_addr[1], 0, &ctx[1]); if (ret != num_good_addr) { sprintf(err_buf, "fi_av_insert ret=%d, %s", ret, fi_strerror(-ret)); goto fail; } ctx[1] = num_good_addr - 1; /* * A little tricky here because the good completions may come in any order, * all we can far for sure is that error must come before good completion 2. */ memset(good, 0, sizeof(good)); err = 0; for (i = 0; i < 3; ++i) { ret = fi_eq_sread(eq, &event, &entry, sizeof(entry), 20000, 0); if (ret == -FI_EAVAIL) { if (good[1] > 0 || err > 0) { sprintf(err_buf, "Unexpected error completion"); goto fail; } ret = check_eq_readerr(eq, &av->fid, &ctx[1], 0); if (ret != 0) { goto fail; } err = 1; } else { ret = check_eq_result(ret, event, &entry, &av->fid, NULL, ~0); if (ret != 0) { goto fail; } if (entry.context != &ctx[0] && entry.context != &ctx[1]) { sprintf(err_buf, "bad context: %p", entry.context); goto fail; } if (*(uint32_t *)(entry.context) == ~0) { sprintf(err_buf, "duplicate context: %p", entry.context); goto fail; } if (entry.context == &ctx[1] && err == 0) { sprintf(err_buf, "2nd good comp before error"); goto fail; } if (*(uint32_t *)(entry.context) != entry.data) { sprintf(err_buf, "count = %lu, should be %d", entry.data, *(uint32_t *)(entry.context)); goto fail; } *(uint32_t *)(entry.context) = ~0; } } ret = fi_eq_sread(eq, &event, &entry, sizeof(entry), 1000, 0); if (ret != -FI_ETIMEDOUT) { sprintf(err_buf, "too many events"); goto fail; } for (i = 0; i < num_good_addr + 1; ++i) { if (i == 1) { if (fi_addr[1] != FI_ADDR_NOTAVAIL) { sprintf(err_buf, "fi_addr[1] != FI_ADDR_NOTAVAIL"); goto fail; } } else { if (fi_addr[i] == FI_ADDR_NOTAVAIL) { sprintf(err_buf, "fi_addr[%d] = FI_ADDR_NOTAVAIL", i); goto fail; } } } testret = PASS; fail: if (av != NULL) { fi_close(&av->fid); } return testret; }
void rdm_sr_setup_common_eps(void) { int ret = 0, i = 0, j = 0; struct fi_av_attr attr; size_t addrlen = 0; attr.type = FI_AV_MAP; attr.count = NUMEPS; cq_attr.format = FI_CQ_FORMAT_TAGGED; cq_attr.size = 1024; cq_attr.wait_obj = 0; target = malloc(BUF_SZ * 3); /* 3x BUF_SZ for multi recv testing */ assert(target); source = malloc(BUF_SZ); assert(source); uc_target = malloc(BUF_SZ); assert(uc_target); uc_source = malloc(BUF_SZ); assert(uc_source); ret = fi_fabric(fi[0]->fabric_attr, &fab, NULL); cr_assert(!ret, "fi_fabric"); for (; i < NUMEPS; i++) { ret = fi_domain(fab, fi[i], dom + i, NULL); cr_assert(!ret, "fi_domain"); ret = fi_open_ops(&dom[i]->fid, FI_GNI_DOMAIN_OPS_1, 0, (void **) (gni_domain_ops + i), NULL); ret = fi_av_open(dom[i], &attr, av + i, NULL); cr_assert(!ret, "fi_av_open"); ret = fi_endpoint(dom[i], fi[i], ep + i, NULL); cr_assert(!ret, "fi_endpoint"); ret = fi_cq_open(dom[i], &cq_attr, msg_cq + i, 0); cr_assert(!ret, "fi_cq_open"); ret = fi_ep_bind(ep[i], &msg_cq[i]->fid, FI_SEND | FI_RECV); cr_assert(!ret, "fi_ep_bind"); ret = fi_getname(&ep[i]->fid, NULL, &addrlen); cr_assert(addrlen > 0); ep_name[i] = malloc(addrlen); cr_assert(ep_name[i] != NULL); ret = fi_getname(&ep[i]->fid, ep_name[i], &addrlen); cr_assert(ret == FI_SUCCESS); } 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); } ret = fi_ep_bind(ep[i], &av[i]->fid, 0); cr_assert(!ret, "fi_ep_bind"); ret = fi_enable(ep[i]); cr_assert(!ret, "fi_ep_enable"); ret = fi_cntr_open(dom[i], &cntr_attr, send_cntr + i, 0); cr_assert(!ret, "fi_cntr_open"); ret = fi_ep_bind(ep[i], &send_cntr[i]->fid, FI_SEND); cr_assert(!ret, "fi_ep_bind"); ret = fi_cntr_open(dom[i], &cntr_attr, recv_cntr + i, 0); cr_assert(!ret, "fi_cntr_open"); ret = fi_ep_bind(ep[i], &recv_cntr[i]->fid, FI_RECV); cr_assert(!ret, "fi_ep_bind"); } }
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 int alloc_ep_res(struct fi_info *fi) { struct fi_cntr_attr cntr_attr; struct fi_av_attr av_attr; uint64_t flags = 0; int ret; buffer_size = MAX(sizeof(char *) * strlen(welcome_text), sizeof(uint64_t)); buf = malloc(buffer_size); if (!buf) { perror("malloc"); return -1; } memset(&cntr_attr, 0, sizeof cntr_attr); cntr_attr.events = FI_CNTR_EVENTS_COMP; ret = fi_cntr_open(dom, &cntr_attr, &scntr, NULL); if (ret) { FT_PRINTERR("fi_cntr_open", ret); goto err1; } ret = fi_cntr_open(dom, &cntr_attr, &rcntr, NULL); if (ret) { FT_PRINTERR("fi_cntr_open", ret); goto err2; } /* Set FI_MR_KEY to associate the memory region with the specified key * Set FI_MR_OFFSET to use specified offset as the base address */ flags = FI_MR_KEY | FI_MR_OFFSET; ret = fi_mr_reg(dom, buf, buffer_size, FI_REMOTE_WRITE, 0, user_defined_key, flags, &mr, NULL); if (ret) { FT_PRINTERR("fi_mr_reg", ret); goto err3; } 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.name = NULL; ret = fi_av_open(dom, &av_attr, &av, NULL); if (ret) { FT_PRINTERR("fi_av_open", ret); goto err4; } ret = fi_endpoint(dom, fi, &ep, NULL); if (ret) { FT_PRINTERR("fi_endpoint", ret); goto err5; } return 0; err5: fi_close(&av->fid); err4: fi_close(&mr->fid); err3: fi_close(&rcntr->fid); err2: fi_close(&scntr->fid); err1: free(buf); return ret; }