/* init the transport by its name */ static ucs_status_t init_iface(char *dev_name, char *tl_name, struct iface_info *iface_p) { ucs_status_t status; uct_iface_config_t *config; /* Defines interface configuration options */ /* Read transport-specific interface configuration */ status = uct_iface_config_read(tl_name, NULL, NULL, &config); CHKERR_JUMP(UCS_OK != status, "setup iface_config", error_ret); /* Open communication interface */ status = uct_iface_open(iface_p->pd, iface_p->worker, tl_name, dev_name, 0, config, &iface_p->iface); uct_config_release(config); CHKERR_JUMP(UCS_OK != status, "open temporary interface", error_ret); /* Get interface attributes */ status = uct_iface_query(iface_p->iface, &iface_p->attr); CHKERR_JUMP(UCS_OK != status, "query iface", error_iface); /* Check if current device and transport support short active messages */ if (iface_p->attr.cap.flags & UCT_IFACE_FLAG_AM_SHORT) { return UCS_OK; } error_iface: uct_iface_close(iface_p->iface); error_ret: return UCS_ERR_UNSUPPORTED; }
/* Checks if the device and transports are supported by UCX */ static ucs_status_t resource_supported(char *dev_name, char *tl_name, int kill_iface) { ucs_status_t status; /* Read transport-specific interface configuration */ status = uct_iface_config_read(tl_name, NULL, NULL, &iface_config); if (UCS_OK != status) { fprintf(stderr, "Failed to setup iface_config.\n");fflush(stderr); goto error0; } /* Open communication interface */ status = uct_iface_open(pd, worker, tl_name, dev_name, 0, iface_config, &iface); uct_iface_config_release(iface_config); if (UCS_OK != status) { fprintf(stderr, "Failed to open temporary interface.\n");fflush(stderr); goto error0; } /* Get interface attributes */ status = uct_iface_query(iface, &iface_attr); if (UCS_OK != status) { fprintf(stderr, "Failed to query iface.\n");fflush(stderr); goto error_iface0; } /* Check if current device and transport support short active messages */ if (iface_attr.cap.flags & UCT_IFACE_FLAG_AM_SHORT) { if (kill_iface) { uct_iface_close(iface); } return UCS_OK; } return UCS_ERR_UNSUPPORTED; error_iface0: uct_iface_close(iface); error0: return status; }
static ucs_status_t uct_perf_test_setup_endpoints(ucx_perf_context_t *perf) { const size_t buffer_size = 2048; ucx_perf_ep_info_t info, *remote_info; unsigned group_size, i, group_index; uct_device_addr_t *dev_addr; uct_iface_addr_t *iface_addr; uct_ep_addr_t *ep_addr; uct_iface_attr_t iface_attr; uct_md_attr_t md_attr; void *rkey_buffer; ucs_status_t status; struct iovec vec[5]; void *buffer; void *req; buffer = malloc(buffer_size); if (buffer == NULL) { ucs_error("Failed to allocate RTE buffer"); status = UCS_ERR_NO_MEMORY; goto err; } status = uct_iface_query(perf->uct.iface, &iface_attr); if (status != UCS_OK) { ucs_error("Failed to uct_iface_query: %s", ucs_status_string(status)); goto err_free; } status = uct_md_query(perf->uct.md, &md_attr); if (status != UCS_OK) { ucs_error("Failed to uct_md_query: %s", ucs_status_string(status)); goto err_free; } if (md_attr.cap.flags & (UCT_MD_FLAG_ALLOC|UCT_MD_FLAG_REG)) { info.rkey_size = md_attr.rkey_packed_size; } else { info.rkey_size = 0; } info.uct.dev_addr_len = iface_attr.device_addr_len; info.uct.iface_addr_len = iface_attr.iface_addr_len; info.uct.ep_addr_len = iface_attr.ep_addr_len; info.recv_buffer = (uintptr_t)perf->recv_buffer; rkey_buffer = buffer; dev_addr = (void*)rkey_buffer + info.rkey_size; iface_addr = (void*)dev_addr + info.uct.dev_addr_len; ep_addr = (void*)iface_addr + info.uct.iface_addr_len; ucs_assert_always((void*)ep_addr + info.uct.ep_addr_len <= buffer + buffer_size); status = uct_iface_get_device_address(perf->uct.iface, dev_addr); if (status != UCS_OK) { ucs_error("Failed to uct_iface_get_device_address: %s", ucs_status_string(status)); goto err_free; } status = uct_iface_get_address(perf->uct.iface, iface_addr); if (status != UCS_OK) { ucs_error("Failed to uct_iface_get_address: %s", ucs_status_string(status)); goto err_free; } if (info.rkey_size > 0) { status = uct_md_mkey_pack(perf->uct.md, perf->uct.recv_mem.memh, rkey_buffer); if (status != UCS_OK) { ucs_error("Failed to uct_rkey_pack: %s", ucs_status_string(status)); goto err_free; } } group_size = rte_call(perf, group_size); group_index = rte_call(perf, group_index); perf->uct.peers = calloc(group_size, sizeof(*perf->uct.peers)); if (perf->uct.peers == NULL) { goto err_free; } if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_EP) { for (i = 0; i < group_size; ++i) { if (i == group_index) { continue; } status = uct_ep_create(perf->uct.iface, &perf->uct.peers[i].ep); if (status != UCS_OK) { ucs_error("Failed to uct_ep_create: %s", ucs_status_string(status)); goto err_destroy_eps; } status = uct_ep_get_address(perf->uct.peers[i].ep, ep_addr); if (status != UCS_OK) { ucs_error("Failed to uct_ep_get_address: %s", ucs_status_string(status)); goto err_destroy_eps; } } } vec[0].iov_base = &info; vec[0].iov_len = sizeof(info); vec[1].iov_base = buffer; vec[1].iov_len = info.rkey_size + info.uct.dev_addr_len + info.uct.iface_addr_len + info.uct.ep_addr_len; rte_call(perf, post_vec, vec, 2, &req); rte_call(perf, exchange_vec, req); for (i = 0; i < group_size; ++i) { if (i == group_index) { continue; } rte_call(perf, recv, i, buffer, buffer_size, req); remote_info = buffer; rkey_buffer = remote_info + 1; dev_addr = (void*)rkey_buffer + remote_info->rkey_size; iface_addr = (void*)dev_addr + remote_info->uct.dev_addr_len; ep_addr = (void*)iface_addr + remote_info->uct.iface_addr_len; perf->uct.peers[i].remote_addr = remote_info->recv_buffer; if (!uct_iface_is_reachable(perf->uct.iface, dev_addr, remote_info->uct.iface_addr_len ? iface_addr : NULL)) { ucs_error("Destination is unreachable"); status = UCS_ERR_UNREACHABLE; goto err_destroy_eps; } if (remote_info->rkey_size > 0) { status = uct_rkey_unpack(rkey_buffer, &perf->uct.peers[i].rkey); if (status != UCS_OK) { ucs_error("Failed to uct_rkey_unpack: %s", ucs_status_string(status)); goto err_destroy_eps; } } else { perf->uct.peers[i].rkey.handle = NULL; perf->uct.peers[i].rkey.type = NULL; perf->uct.peers[i].rkey.rkey = UCT_INVALID_RKEY; } if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_EP) { status = uct_ep_connect_to_ep(perf->uct.peers[i].ep, dev_addr, ep_addr); } else if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_IFACE) { status = uct_ep_create_connected(perf->uct.iface, dev_addr, iface_addr, &perf->uct.peers[i].ep); } else { status = UCS_ERR_UNSUPPORTED; } if (status != UCS_OK) { ucs_error("Failed to connect endpoint: %s", ucs_status_string(status)); goto err_destroy_eps; } } uct_perf_iface_flush_b(perf); free(buffer); rte_call(perf, barrier); return UCS_OK; err_destroy_eps: for (i = 0; i < group_size; ++i) { if (perf->uct.peers[i].rkey.type != NULL) { uct_rkey_release(&perf->uct.peers[i].rkey); } if (perf->uct.peers[i].ep != NULL) { uct_ep_destroy(perf->uct.peers[i].ep); } } free(perf->uct.peers); err_free: free(buffer); err: return status; }
static ucs_status_t uct_perf_test_check_capabilities(ucx_perf_params_t *params, uct_iface_h iface) { uct_iface_attr_t attr; ucs_status_t status; uint64_t required_flags; size_t min_size, max_size, max_iov, message_size; status = uct_iface_query(iface, &attr); if (status != UCS_OK) { return status; } min_size = 0; max_iov = 1; message_size = ucx_perf_get_message_size(params); switch (params->command) { case UCX_PERF_CMD_AM: required_flags = __get_flag(params->uct.data_layout, UCT_IFACE_FLAG_AM_SHORT, UCT_IFACE_FLAG_AM_BCOPY, UCT_IFACE_FLAG_AM_ZCOPY); required_flags |= UCT_IFACE_FLAG_CB_SYNC; min_size = __get_max_size(params->uct.data_layout, 0, 0, attr.cap.am.min_zcopy); max_size = __get_max_size(params->uct.data_layout, attr.cap.am.max_short, attr.cap.am.max_bcopy, attr.cap.am.max_zcopy); max_iov = attr.cap.am.max_iov; break; case UCX_PERF_CMD_PUT: required_flags = __get_flag(params->uct.data_layout, UCT_IFACE_FLAG_PUT_SHORT, UCT_IFACE_FLAG_PUT_BCOPY, UCT_IFACE_FLAG_PUT_ZCOPY); min_size = __get_max_size(params->uct.data_layout, 0, 0, attr.cap.put.min_zcopy); max_size = __get_max_size(params->uct.data_layout, attr.cap.put.max_short, attr.cap.put.max_bcopy, attr.cap.put.max_zcopy); max_iov = attr.cap.put.max_iov; break; case UCX_PERF_CMD_GET: required_flags = __get_flag(params->uct.data_layout, 0, UCT_IFACE_FLAG_GET_BCOPY, UCT_IFACE_FLAG_GET_ZCOPY); min_size = __get_max_size(params->uct.data_layout, 0, 0, attr.cap.get.min_zcopy); max_size = __get_max_size(params->uct.data_layout, 0, attr.cap.get.max_bcopy, attr.cap.get.max_zcopy); max_iov = attr.cap.get.max_iov; break; case UCX_PERF_CMD_ADD: required_flags = __get_atomic_flag(message_size, UCT_IFACE_FLAG_ATOMIC_ADD32, UCT_IFACE_FLAG_ATOMIC_ADD64); max_size = 8; break; case UCX_PERF_CMD_FADD: required_flags = __get_atomic_flag(message_size, UCT_IFACE_FLAG_ATOMIC_FADD32, UCT_IFACE_FLAG_ATOMIC_FADD64); max_size = 8; break; case UCX_PERF_CMD_SWAP: required_flags = __get_atomic_flag(message_size, UCT_IFACE_FLAG_ATOMIC_SWAP32, UCT_IFACE_FLAG_ATOMIC_SWAP64); max_size = 8; break; case UCX_PERF_CMD_CSWAP: required_flags = __get_atomic_flag(message_size, UCT_IFACE_FLAG_ATOMIC_CSWAP32, UCT_IFACE_FLAG_ATOMIC_CSWAP64); max_size = 8; break; default: if (params->flags & UCX_PERF_TEST_FLAG_VERBOSE) { ucs_error("Invalid test command"); } return UCS_ERR_INVALID_PARAM; } status = ucx_perf_test_check_params(params); if (status != UCS_OK) { return status; } if (!ucs_test_all_flags(attr.cap.flags, required_flags) || !required_flags) { if (params->flags & UCX_PERF_TEST_FLAG_VERBOSE) { ucs_error("Device does not support required operation"); } return UCS_ERR_UNSUPPORTED; } if (message_size < min_size) { if (params->flags & UCX_PERF_TEST_FLAG_VERBOSE) { ucs_error("Message size too small"); } return UCS_ERR_UNSUPPORTED; } if (message_size > max_size) { if (params->flags & UCX_PERF_TEST_FLAG_VERBOSE) { ucs_error("Message size too big"); } return UCS_ERR_UNSUPPORTED; } if (params->command == UCX_PERF_CMD_AM) { if ((params->uct.data_layout == UCT_PERF_DATA_LAYOUT_SHORT) && (params->am_hdr_size != sizeof(uint64_t))) { if (params->flags & UCX_PERF_TEST_FLAG_VERBOSE) { ucs_error("Short AM header size must be 8 bytes"); } return UCS_ERR_INVALID_PARAM; } if ((params->uct.data_layout == UCT_PERF_DATA_LAYOUT_ZCOPY) && (params->am_hdr_size > attr.cap.am.max_hdr)) { if (params->flags & UCX_PERF_TEST_FLAG_VERBOSE) { ucs_error("AM header size too big"); } return UCS_ERR_UNSUPPORTED; } if (params->am_hdr_size > message_size) { if (params->flags & UCX_PERF_TEST_FLAG_VERBOSE) { ucs_error("AM header size larger than message size"); } return UCS_ERR_INVALID_PARAM; } if (params->uct.fc_window > UCT_PERF_TEST_MAX_FC_WINDOW) { if (params->flags & UCX_PERF_TEST_FLAG_VERBOSE) { ucs_error("AM flow-control window too large (should be <= %d)", UCT_PERF_TEST_MAX_FC_WINDOW); } return UCS_ERR_INVALID_PARAM; } if ((params->flags & UCX_PERF_TEST_FLAG_ONE_SIDED) && (params->flags & UCX_PERF_TEST_FLAG_VERBOSE)) { ucs_warn("Running active-message test with on-sided progress"); } } if (UCT_PERF_DATA_LAYOUT_ZCOPY == params->uct.data_layout) { if (params->msg_size_cnt > max_iov) { if ((params->flags & UCX_PERF_TEST_FLAG_VERBOSE) || !params->msg_size_cnt) { ucs_error("Wrong number of IOV entries. Requested is %lu, " "should be in the range 1...%lu", params->msg_size_cnt, max_iov); } return UCS_ERR_UNSUPPORTED; } /* if msg_size_cnt == 1 the message size checked above */ if ((UCX_PERF_CMD_AM == params->command) && (params->msg_size_cnt > 1)) { if (params->am_hdr_size > params->msg_size_list[0]) { if (params->flags & UCX_PERF_TEST_FLAG_VERBOSE) { ucs_error("AM header size (%lu) larger than the first IOV " "message size (%lu)", params->am_hdr_size, params->msg_size_list[0]); } return UCS_ERR_INVALID_PARAM; } } } return UCS_OK; }
static ucs_status_t uct_perf_test_check_capabilities(ucx_perf_params_t *params, uct_iface_h iface) { uct_iface_attr_t attr; ucs_status_t status; uint64_t required_flags; size_t max_size; status = uct_iface_query(iface, &attr); if (status != UCS_OK) { return status; } switch (params->command) { case UCX_PERF_CMD_AM: required_flags = __get_flag(params->uct.data_layout, UCT_IFACE_FLAG_AM_SHORT, UCT_IFACE_FLAG_AM_BCOPY, UCT_IFACE_FLAG_AM_ZCOPY); max_size = __get_max_size(params->uct.data_layout, attr.cap.am.max_short, attr.cap.am.max_bcopy, attr.cap.am.max_zcopy); break; case UCX_PERF_CMD_PUT: required_flags = __get_flag(params->uct.data_layout, UCT_IFACE_FLAG_PUT_SHORT, UCT_IFACE_FLAG_PUT_BCOPY, UCT_IFACE_FLAG_PUT_ZCOPY); max_size = __get_max_size(params->uct.data_layout, attr.cap.put.max_short, attr.cap.put.max_bcopy, attr.cap.put.max_zcopy); break; case UCX_PERF_CMD_GET: required_flags = __get_flag(params->uct.data_layout, 0, UCT_IFACE_FLAG_GET_BCOPY, UCT_IFACE_FLAG_GET_ZCOPY); max_size = __get_max_size(params->uct.data_layout, 0, attr.cap.get.max_bcopy, attr.cap.get.max_zcopy); break; case UCX_PERF_CMD_ADD: required_flags = __get_atomic_flag(params->message_size, UCT_IFACE_FLAG_ATOMIC_ADD32, UCT_IFACE_FLAG_ATOMIC_ADD64); max_size = 8; break; case UCX_PERF_CMD_FADD: required_flags = __get_atomic_flag(params->message_size, UCT_IFACE_FLAG_ATOMIC_FADD32, UCT_IFACE_FLAG_ATOMIC_FADD64); max_size = 8; break; case UCX_PERF_CMD_SWAP: required_flags = __get_atomic_flag(params->message_size, UCT_IFACE_FLAG_ATOMIC_SWAP32, UCT_IFACE_FLAG_ATOMIC_SWAP64); max_size = 8; break; case UCX_PERF_CMD_CSWAP: required_flags = __get_atomic_flag(params->message_size, UCT_IFACE_FLAG_ATOMIC_CSWAP32, UCT_IFACE_FLAG_ATOMIC_CSWAP64); max_size = 8; break; default: if (params->flags & UCX_PERF_TEST_FLAG_VERBOSE) { ucs_error("Invalid test command"); } return UCS_ERR_INVALID_PARAM; } status = ucx_perf_test_check_params(params); if (status != UCS_OK) { return status; } if ((attr.cap.flags & required_flags) == 0) { if (params->flags & UCX_PERF_TEST_FLAG_VERBOSE) { ucs_error("Device does not support required operation"); } return UCS_ERR_UNSUPPORTED; } if (params->message_size > max_size) { if (params->flags & UCX_PERF_TEST_FLAG_VERBOSE) { ucs_error("Message size too big"); } return UCS_ERR_INVALID_PARAM; } if (params->command == UCX_PERF_CMD_AM) { if ((params->uct.data_layout == UCT_PERF_DATA_LAYOUT_SHORT) && (params->am_hdr_size != sizeof(uint64_t))) { if (params->flags & UCX_PERF_TEST_FLAG_VERBOSE) { ucs_error("Short AM header size must be 8 bytes"); } return UCS_ERR_INVALID_PARAM; } if ((params->uct.data_layout == UCT_PERF_DATA_LAYOUT_ZCOPY) && (params->am_hdr_size > attr.cap.am.max_hdr)) { if (params->flags & UCX_PERF_TEST_FLAG_VERBOSE) { ucs_error("AM header size too big"); } return UCS_ERR_INVALID_PARAM; } if (params->am_hdr_size > params->message_size) { if (params->flags & UCX_PERF_TEST_FLAG_VERBOSE) { ucs_error("AM header size larger than message size"); } return UCS_ERR_INVALID_PARAM; } if (params->uct.fc_window > UCT_PERF_TEST_MAX_FC_WINDOW) { if (params->flags & UCX_PERF_TEST_FLAG_VERBOSE) { ucs_error("AM flow-control window too large (should be <= %d)", UCT_PERF_TEST_MAX_FC_WINDOW); } return UCS_ERR_INVALID_PARAM; } if ((params->flags & UCX_PERF_TEST_FLAG_ONE_SIDED) && (params->flags & UCX_PERF_TEST_FLAG_VERBOSE)) { ucs_warn("Running active-message test with on-sided progress"); } } return UCS_OK; }
static ucs_status_t uct_perf_test_setup_endpoints(ucx_perf_context_t *perf) { unsigned group_size, i, group_index; uct_device_addr_t *dev_addr; uct_iface_addr_t *iface_addr; uct_ep_addr_t *ep_addr; uct_iface_attr_t iface_attr; uct_pd_attr_t pd_attr; unsigned long va; void *rkey_buffer; ucs_status_t status; struct iovec vec[5]; void *req; status = uct_iface_query(perf->uct.iface, &iface_attr); if (status != UCS_OK) { ucs_error("Failed to uct_iface_query: %s", ucs_status_string(status)); goto err; } status = uct_pd_query(perf->uct.pd, &pd_attr); if (status != UCS_OK) { ucs_error("Failed to uct_pd_query: %s", ucs_status_string(status)); goto err; } dev_addr = calloc(1, iface_attr.device_addr_len); iface_addr = calloc(1, iface_attr.iface_addr_len); ep_addr = calloc(1, iface_attr.ep_addr_len); rkey_buffer = calloc(1, pd_attr.rkey_packed_size); if ((iface_addr == NULL) || (ep_addr == NULL) || (rkey_buffer == NULL)) { goto err_free; } status = uct_iface_get_device_address(perf->uct.iface, dev_addr); if (status != UCS_OK) { ucs_error("Failed to uct_iface_get_device_address: %s", ucs_status_string(status)); goto err_free; } if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_IFACE) { status = uct_iface_get_address(perf->uct.iface, iface_addr); if (status != UCS_OK) { ucs_error("Failed to uct_iface_get_address: %s", ucs_status_string(status)); goto err_free; } } status = uct_pd_mkey_pack(perf->uct.pd, perf->uct.recv_mem.memh, rkey_buffer); if (status != UCS_OK) { ucs_error("Failed to uct_rkey_pack: %s", ucs_status_string(status)); goto err_free; } group_size = rte_call(perf, group_size); group_index = rte_call(perf, group_index); perf->uct.peers = calloc(group_size, sizeof(*perf->uct.peers)); if (perf->uct.peers == NULL) { goto err_free; } if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_EP) { for (i = 0; i < group_size; ++i) { if (i == group_index) { continue; } status = uct_ep_create(perf->uct.iface, &perf->uct.peers[i].ep); if (status != UCS_OK) { ucs_error("Failed to uct_ep_create: %s", ucs_status_string(status)); goto err_destroy_eps; } status = uct_ep_get_address(perf->uct.peers[i].ep, ep_addr); if (status != UCS_OK) { ucs_error("Failed to uct_ep_get_address: %s", ucs_status_string(status)); goto err_destroy_eps; } } } va = (uintptr_t)perf->recv_buffer; vec[0].iov_base = &va; vec[0].iov_len = sizeof(va); vec[1].iov_base = rkey_buffer; vec[1].iov_len = pd_attr.rkey_packed_size; vec[2].iov_base = dev_addr; vec[2].iov_len = iface_attr.device_addr_len; vec[3].iov_base = iface_addr; vec[3].iov_len = iface_attr.iface_addr_len; vec[4].iov_base = ep_addr; vec[4].iov_len = iface_attr.ep_addr_len; rte_call(perf, post_vec, vec, 5, &req); rte_call(perf, exchange_vec, req); for (i = 0; i < group_size; ++i) { if (i == group_index) { continue; } vec[0].iov_base = &va; vec[0].iov_len = sizeof(va); vec[1].iov_base = rkey_buffer; vec[1].iov_len = pd_attr.rkey_packed_size; vec[2].iov_base = dev_addr; vec[2].iov_len = iface_attr.device_addr_len; vec[3].iov_base = iface_addr; vec[3].iov_len = iface_attr.iface_addr_len; vec[4].iov_base = ep_addr; vec[4].iov_len = iface_attr.ep_addr_len; rte_call(perf, recv_vec, i, vec, 5, req); perf->uct.peers[i].remote_addr = va; status = uct_rkey_unpack(rkey_buffer, &perf->uct.peers[i].rkey); if (status != UCS_OK) { ucs_error("Failed to uct_rkey_unpack: %s", ucs_status_string(status)); return status; } if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_EP) { status = uct_ep_connect_to_ep(perf->uct.peers[i].ep, dev_addr, ep_addr); } else if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_IFACE) { status = uct_ep_create_connected(perf->uct.iface, dev_addr, iface_addr, &perf->uct.peers[i].ep); } else { status = UCS_ERR_UNSUPPORTED; } if (status != UCS_OK) { ucs_error("Failed to connect endpoint: %s", ucs_status_string(status)); goto err_destroy_eps; } } uct_perf_iface_flush_b(perf); rte_call(perf, barrier); free(ep_addr); free(iface_addr); free(dev_addr); free(rkey_buffer); return UCS_OK; err_destroy_eps: for (i = 0; i < group_size; ++i) { if (perf->uct.peers[i].rkey.type != NULL) { uct_rkey_release(&perf->uct.peers[i].rkey); } if (perf->uct.peers[i].ep != NULL) { uct_ep_destroy(perf->uct.peers[i].ep); } } free(perf->uct.peers); err_free: free(ep_addr); free(iface_addr); free(dev_addr); free(rkey_buffer); err: return status; }
static void print_iface_info(uct_worker_h worker, uct_md_h md, uct_tl_resource_desc_t *resource) { uct_iface_config_t *iface_config; uct_iface_attr_t iface_attr; ucs_status_t status; uct_iface_h iface; char buf[200] = {0}; status = uct_iface_config_read(resource->tl_name, NULL, NULL, &iface_config); if (status != UCS_OK) { return; } printf("# Device: %s\n", resource->dev_name); status = uct_iface_open(md, worker, resource->tl_name, resource->dev_name, 0, iface_config, &iface); uct_config_release(iface_config); if (status != UCS_OK) { printf("# < failed to open interface >\n"); return; } printf("#\n"); printf("# capabilities:\n"); status = uct_iface_query(iface, &iface_attr); if (status != UCS_OK) { printf("# < failed to query interface >\n"); } else { printf("# bandwidth: %.2f MB/sec\n", iface_attr.bandwidth / (1024 * 1024)); printf("# latency: %.0f nsec\n", iface_attr.latency * 1e9); printf("# overhead: %.0f nsec\n", iface_attr.overhead * 1e9); PRINT_CAP(PUT_SHORT, iface_attr.cap.flags, iface_attr.cap.put.max_short); PRINT_CAP(PUT_BCOPY, iface_attr.cap.flags, iface_attr.cap.put.max_bcopy); PRINT_CAP(PUT_ZCOPY, iface_attr.cap.flags, iface_attr.cap.put.max_zcopy); PRINT_CAP(GET_BCOPY, iface_attr.cap.flags, iface_attr.cap.get.max_bcopy); PRINT_CAP(GET_ZCOPY, iface_attr.cap.flags, iface_attr.cap.get.max_zcopy); PRINT_CAP(AM_SHORT, iface_attr.cap.flags, iface_attr.cap.am.max_short); PRINT_CAP(AM_BCOPY, iface_attr.cap.flags, iface_attr.cap.am.max_bcopy); PRINT_CAP(AM_ZCOPY, iface_attr.cap.flags, iface_attr.cap.am.max_zcopy); if (iface_attr.cap.flags & (UCT_IFACE_FLAG_AM_BCOPY|UCT_IFACE_FLAG_AM_ZCOPY)) { printf("# am header: %s\n", size_limit_to_str(iface_attr.cap.am.max_hdr)); } PRINT_ATOMIC_CAP(ATOMIC_ADD, iface_attr.cap.flags); PRINT_ATOMIC_CAP(ATOMIC_FADD, iface_attr.cap.flags); PRINT_ATOMIC_CAP(ATOMIC_SWAP, iface_attr.cap.flags); PRINT_ATOMIC_CAP(ATOMIC_CSWAP, iface_attr.cap.flags); buf[0] = '\0'; if (iface_attr.cap.flags & (UCT_IFACE_FLAG_CONNECT_TO_EP | UCT_IFACE_FLAG_CONNECT_TO_IFACE)) { if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_EP) { strncat(buf, " to ep,", sizeof(buf) - 1); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_IFACE) { strncat(buf, " to iface,", sizeof(buf) - 1); } buf[strlen(buf) - 1] = '\0'; } else { strncat(buf, " none", sizeof(buf) - 1); } printf("# connection:%s\n", buf); printf("# device address: %zu bytes\n", iface_attr.device_addr_len); if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_IFACE) { printf("# iface address: %zu bytes\n", iface_attr.iface_addr_len); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_EP) { printf("# ep address: %zu bytes\n", iface_attr.ep_addr_len); } buf[0] = '\0'; if (iface_attr.cap.flags & (UCT_IFACE_FLAG_ERRHANDLE_SHORT_BUF | UCT_IFACE_FLAG_ERRHANDLE_BCOPY_BUF | UCT_IFACE_FLAG_ERRHANDLE_ZCOPY_BUF | UCT_IFACE_FLAG_ERRHANDLE_AM_ID | UCT_IFACE_FLAG_ERRHANDLE_REMOTE_MEM | UCT_IFACE_FLAG_ERRHANDLE_PEER_FAILURE)) { if (iface_attr.cap.flags & (UCT_IFACE_FLAG_ERRHANDLE_SHORT_BUF | UCT_IFACE_FLAG_ERRHANDLE_BCOPY_BUF | UCT_IFACE_FLAG_ERRHANDLE_ZCOPY_BUF)) { strncat(buf, " buffer (", sizeof(buf) - 1); if (iface_attr.cap.flags & UCT_IFACE_FLAG_ERRHANDLE_SHORT_BUF) { strncat(buf, "short,", sizeof(buf) - 1); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_ERRHANDLE_BCOPY_BUF) { strncat(buf, "bcopy,", sizeof(buf) - 1); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_ERRHANDLE_ZCOPY_BUF) { strncat(buf, "zcopy,", sizeof(buf) - 1); } buf[strlen(buf) - 1] = '\0'; strncat(buf, "),", sizeof(buf) - 1); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_ERRHANDLE_AM_ID) { strncat(buf, " active-message id,", sizeof(buf) - 1); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_ERRHANDLE_REMOTE_MEM) { strncat(buf, " remote access,", sizeof(buf) - 1); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_ERRHANDLE_PEER_FAILURE) { strncat(buf, " peer failure,", sizeof(buf) - 1); } buf[strlen(buf) - 1] = '\0'; } else { strncat(buf, " none", sizeof(buf) - 1); } printf("# error handling:%s\n", buf); } uct_iface_close(iface); printf("#\n"); }
static void print_iface_info(uct_worker_h worker, uct_md_h md, uct_tl_resource_desc_t *resource) { uct_iface_config_t *iface_config; uct_iface_attr_t iface_attr; ucs_status_t status; uct_iface_h iface; char buf[200] = {0}; uct_iface_params_t iface_params = { .tl_name = resource->tl_name, .dev_name = resource->dev_name, .rx_headroom = 0 }; status = uct_iface_config_read(resource->tl_name, NULL, NULL, &iface_config); if (status != UCS_OK) { return; } printf("# Device: %s\n", resource->dev_name); status = uct_iface_open(md, worker, &iface_params, iface_config, &iface); uct_config_release(iface_config); if (status != UCS_OK) { printf("# < failed to open interface >\n"); return; } printf("#\n"); printf("# capabilities:\n"); status = uct_iface_query(iface, &iface_attr); if (status != UCS_OK) { printf("# < failed to query interface >\n"); } else { printf("# bandwidth: %-.2f MB/sec\n", iface_attr.bandwidth / (1024 * 1024)); printf("# latency: %-.0f nsec\n", iface_attr.latency * 1e9); printf("# overhead: %-.0f nsec\n", iface_attr.overhead * 1e9); PRINT_CAP(PUT_SHORT, iface_attr.cap.flags, iface_attr.cap.put.max_short); PRINT_CAP(PUT_BCOPY, iface_attr.cap.flags, iface_attr.cap.put.max_bcopy); PRINT_CAP(PUT_ZCOPY, iface_attr.cap.flags, iface_attr.cap.put.max_zcopy); PRINT_CAP(GET_BCOPY, iface_attr.cap.flags, iface_attr.cap.get.max_bcopy); PRINT_CAP(GET_ZCOPY, iface_attr.cap.flags, iface_attr.cap.get.max_zcopy); PRINT_CAP(AM_SHORT, iface_attr.cap.flags, iface_attr.cap.am.max_short); PRINT_CAP(AM_BCOPY, iface_attr.cap.flags, iface_attr.cap.am.max_bcopy); PRINT_CAP(AM_ZCOPY, iface_attr.cap.flags, iface_attr.cap.am.max_zcopy); if (iface_attr.cap.flags & (UCT_IFACE_FLAG_AM_BCOPY|UCT_IFACE_FLAG_AM_ZCOPY)) { printf("# am header: %s\n", size_limit_to_str(iface_attr.cap.am.max_hdr)); } PRINT_ATOMIC_CAP(ATOMIC_ADD, iface_attr.cap.flags); PRINT_ATOMIC_CAP(ATOMIC_FADD, iface_attr.cap.flags); PRINT_ATOMIC_CAP(ATOMIC_SWAP, iface_attr.cap.flags); PRINT_ATOMIC_CAP(ATOMIC_CSWAP, iface_attr.cap.flags); buf[0] = '\0'; if (iface_attr.cap.flags & (UCT_IFACE_FLAG_CONNECT_TO_EP | UCT_IFACE_FLAG_CONNECT_TO_IFACE)) { if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_EP) { strncat(buf, " to ep,", sizeof(buf) - 1); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_IFACE) { strncat(buf, " to iface,", sizeof(buf) - 1); } buf[strlen(buf) - 1] = '\0'; } else { strncat(buf, " none", sizeof(buf) - 1); } printf("# connection:%s\n", buf); printf("# device address: %zu bytes\n", iface_attr.device_addr_len); if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_IFACE) { printf("# iface address: %zu bytes\n", iface_attr.iface_addr_len); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_EP) { printf("# ep address: %zu bytes\n", iface_attr.ep_addr_len); } buf[0] = '\0'; if (iface_attr.cap.flags & (UCT_IFACE_FLAG_ERRHANDLE_SHORT_BUF | UCT_IFACE_FLAG_ERRHANDLE_BCOPY_BUF | UCT_IFACE_FLAG_ERRHANDLE_ZCOPY_BUF | UCT_IFACE_FLAG_ERRHANDLE_AM_ID | UCT_IFACE_FLAG_ERRHANDLE_REMOTE_MEM | UCT_IFACE_FLAG_ERRHANDLE_PEER_FAILURE)) { if (iface_attr.cap.flags & (UCT_IFACE_FLAG_ERRHANDLE_SHORT_BUF | UCT_IFACE_FLAG_ERRHANDLE_BCOPY_BUF | UCT_IFACE_FLAG_ERRHANDLE_ZCOPY_BUF)) { strncat(buf, " buffer (", sizeof(buf) - 1); if (iface_attr.cap.flags & UCT_IFACE_FLAG_ERRHANDLE_SHORT_BUF) { strncat(buf, "short,", sizeof(buf) - 1); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_ERRHANDLE_BCOPY_BUF) { strncat(buf, "bcopy,", sizeof(buf) - 1); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_ERRHANDLE_ZCOPY_BUF) { strncat(buf, "zcopy,", sizeof(buf) - 1); } buf[strlen(buf) - 1] = '\0'; strncat(buf, "),", sizeof(buf) - 1); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_ERRHANDLE_AM_ID) { strncat(buf, " active-message id,", sizeof(buf) - 1); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_ERRHANDLE_REMOTE_MEM) { strncat(buf, " remote access,", sizeof(buf) - 1); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_ERRHANDLE_PEER_FAILURE) { strncat(buf, " peer failure,", sizeof(buf) - 1); } buf[strlen(buf) - 1] = '\0'; } else { strncat(buf, " none", sizeof(buf) - 1); } printf("# error handling:%s\n", buf); } uct_iface_close(iface); printf("#\n"); } static ucs_status_t print_tl_info(uct_md_h md, const char *tl_name, uct_tl_resource_desc_t *resources, unsigned num_resources, int print_opts, ucs_config_print_flags_t print_flags) { ucs_async_context_t async; uct_worker_h worker; ucs_status_t status; unsigned i; status = ucs_async_context_init(&async, UCS_ASYNC_MODE_THREAD); if (status != UCS_OK) { return status; } /* coverity[alloc_arg] */ status = uct_worker_create(&async, UCS_THREAD_MODE_MULTI, &worker); if (status != UCS_OK) { goto out; } printf("#\n"); printf("# Transport: %s\n", tl_name); printf("#\n"); if (num_resources == 0) { printf("# (No supported devices found)\n"); } for (i = 0; i < num_resources; ++i) { ucs_assert(!strcmp(tl_name, resources[i].tl_name)); print_iface_info(worker, md, &resources[i]); } uct_worker_destroy(worker); out: ucs_async_context_cleanup(&async); return status; }
static void print_iface_info(uct_worker_h worker, uct_md_h md, uct_tl_resource_desc_t *resource) { uct_iface_config_t *iface_config; uct_iface_attr_t iface_attr; ucs_status_t status; uct_iface_h iface; char buf[200] = {0}; uct_iface_params_t iface_params = { .field_mask = UCT_IFACE_PARAM_FIELD_OPEN_MODE | UCT_IFACE_PARAM_FIELD_DEVICE | UCT_IFACE_PARAM_FIELD_STATS_ROOT | UCT_IFACE_PARAM_FIELD_RX_HEADROOM | UCT_IFACE_PARAM_FIELD_CPU_MASK, .open_mode = UCT_IFACE_OPEN_MODE_DEVICE, .mode.device.tl_name = resource->tl_name, .mode.device.dev_name = resource->dev_name, .stats_root = ucs_stats_get_root(), .rx_headroom = 0 }; UCS_CPU_ZERO(&iface_params.cpu_mask); status = uct_md_iface_config_read(md, resource->tl_name, NULL, NULL, &iface_config); if (status != UCS_OK) { return; } printf("# Device: %s\n", resource->dev_name); status = uct_iface_open(md, worker, &iface_params, iface_config, &iface); uct_config_release(iface_config); if (status != UCS_OK) { printf("# < failed to open interface >\n"); return; } printf("#\n"); printf("# capabilities:\n"); status = uct_iface_query(iface, &iface_attr); if (status != UCS_OK) { printf("# < failed to query interface >\n"); } else { printf("# bandwidth: %-.2f MB/sec\n", iface_attr.bandwidth / UCS_MBYTE); printf("# latency: %-.0f nsec", iface_attr.latency.overhead * 1e9); if (iface_attr.latency.growth > 0) { printf(" + %.0f * N\n", iface_attr.latency.growth * 1e9); } else { printf("\n"); } printf("# overhead: %-.0f nsec\n", iface_attr.overhead * 1e9); PRINT_CAP(PUT_SHORT, iface_attr.cap.flags, iface_attr.cap.put.max_short); PRINT_CAP(PUT_BCOPY, iface_attr.cap.flags, iface_attr.cap.put.max_bcopy); PRINT_ZCAP(PUT_ZCOPY, iface_attr.cap.flags, iface_attr.cap.put.min_zcopy, iface_attr.cap.put.max_zcopy, iface_attr.cap.put.max_iov); if (iface_attr.cap.flags & UCT_IFACE_FLAG_PUT_ZCOPY) { printf("# put_opt_zcopy_align: %s\n", size_limit_to_str(0, iface_attr.cap.put.opt_zcopy_align)); printf("# put_align_mtu: %s\n", size_limit_to_str(0, iface_attr.cap.put.align_mtu)); } PRINT_CAP(GET_SHORT, iface_attr.cap.flags, iface_attr.cap.get.max_short); PRINT_CAP(GET_BCOPY, iface_attr.cap.flags, iface_attr.cap.get.max_bcopy); PRINT_ZCAP(GET_ZCOPY, iface_attr.cap.flags, iface_attr.cap.get.min_zcopy, iface_attr.cap.get.max_zcopy, iface_attr.cap.get.max_iov); if (iface_attr.cap.flags & UCT_IFACE_FLAG_GET_ZCOPY) { printf("# get_opt_zcopy_align: %s\n", size_limit_to_str(0, iface_attr.cap.get.opt_zcopy_align)); printf("# get_align_mtu: %s\n", size_limit_to_str(0, iface_attr.cap.get.align_mtu)); } PRINT_CAP(AM_SHORT, iface_attr.cap.flags, iface_attr.cap.am.max_short); PRINT_CAP(AM_BCOPY, iface_attr.cap.flags, iface_attr.cap.am.max_bcopy); PRINT_ZCAP(AM_ZCOPY, iface_attr.cap.flags, iface_attr.cap.am.min_zcopy, iface_attr.cap.am.max_zcopy, iface_attr.cap.am.max_iov); if (iface_attr.cap.flags & UCT_IFACE_FLAG_AM_ZCOPY) { printf("# am_opt_zcopy_align: %s\n", size_limit_to_str(0, iface_attr.cap.am.opt_zcopy_align)); printf("# am_align_mtu: %s\n", size_limit_to_str(0, iface_attr.cap.am.align_mtu)); printf("# am header: %s\n", size_limit_to_str(0, iface_attr.cap.am.max_hdr)); } PRINT_CAP(TAG_EAGER_SHORT, iface_attr.cap.flags, iface_attr.cap.tag.eager.max_short); PRINT_CAP(TAG_EAGER_BCOPY, iface_attr.cap.flags, iface_attr.cap.tag.eager.max_bcopy); PRINT_ZCAP(TAG_EAGER_ZCOPY, iface_attr.cap.flags, 0, iface_attr.cap.tag.eager.max_zcopy, iface_attr.cap.tag.eager.max_iov); if (iface_attr.cap.flags & UCT_IFACE_FLAG_TAG_RNDV_ZCOPY) { PRINT_ZCAP_NO_CHECK(TAG_RNDV_ZCOPY, 0, iface_attr.cap.tag.rndv.max_zcopy, iface_attr.cap.tag.rndv.max_iov); printf("# rndv private header: %s\n", size_limit_to_str(0, iface_attr.cap.tag.rndv.max_hdr)); } if (iface_attr.cap.flags & (UCT_IFACE_FLAG_TAG_EAGER_SHORT | UCT_IFACE_FLAG_TAG_EAGER_BCOPY | UCT_IFACE_FLAG_TAG_EAGER_ZCOPY | UCT_IFACE_FLAG_TAG_RNDV_ZCOPY)) { PRINT_ZCAP_NO_CHECK(TAG_RECV, iface_attr.cap.tag.recv.min_recv, iface_attr.cap.tag.recv.max_zcopy, iface_attr.cap.tag.recv.max_iov); printf("# tag_max_outstanding: %s\n", size_limit_to_str(0, iface_attr.cap.tag.recv.max_outstanding)); } if (iface_attr.cap.atomic32.op_flags || iface_attr.cap.atomic64.op_flags || iface_attr.cap.atomic32.fop_flags || iface_attr.cap.atomic64.fop_flags) { if (iface_attr.cap.flags & UCT_IFACE_FLAG_ATOMIC_DEVICE) { printf("# domain: device\n"); } else if (iface_attr.cap.flags & UCT_IFACE_FLAG_ATOMIC_CPU) { printf("# domain: cpu\n"); } PRINT_ATOMIC_POST(ADD, iface_attr.cap); PRINT_ATOMIC_POST(AND, iface_attr.cap); PRINT_ATOMIC_POST(OR, iface_attr.cap); PRINT_ATOMIC_POST(XOR, iface_attr.cap); PRINT_ATOMIC_FETCH(ADD, iface_attr.cap, "f"); PRINT_ATOMIC_FETCH(AND, iface_attr.cap, "f"); PRINT_ATOMIC_FETCH(OR, iface_attr.cap, "f"); PRINT_ATOMIC_FETCH(XOR, iface_attr.cap, "f"); PRINT_ATOMIC_FETCH(SWAP , iface_attr.cap, ""); PRINT_ATOMIC_FETCH(CSWAP, iface_attr.cap, ""); } buf[0] = '\0'; if (iface_attr.cap.flags & (UCT_IFACE_FLAG_CONNECT_TO_EP | UCT_IFACE_FLAG_CONNECT_TO_IFACE)) { if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_EP) { strncat(buf, " to ep,", sizeof(buf) - 1); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_IFACE) { strncat(buf, " to iface,", sizeof(buf) - 1); } buf[strlen(buf) - 1] = '\0'; } else { strncat(buf, " none", sizeof(buf) - 1); } printf("# connection:%s\n", buf); printf("# priority: %d\n", iface_attr.priority); printf("# device address: %zu bytes\n", iface_attr.device_addr_len); if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_IFACE) { printf("# iface address: %zu bytes\n", iface_attr.iface_addr_len); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_EP) { printf("# ep address: %zu bytes\n", iface_attr.ep_addr_len); } buf[0] = '\0'; if (iface_attr.cap.flags & (UCT_IFACE_FLAG_ERRHANDLE_SHORT_BUF | UCT_IFACE_FLAG_ERRHANDLE_BCOPY_BUF | UCT_IFACE_FLAG_ERRHANDLE_ZCOPY_BUF | UCT_IFACE_FLAG_ERRHANDLE_AM_ID | UCT_IFACE_FLAG_ERRHANDLE_REMOTE_MEM | UCT_IFACE_FLAG_ERRHANDLE_PEER_FAILURE)) { if (iface_attr.cap.flags & (UCT_IFACE_FLAG_ERRHANDLE_SHORT_BUF | UCT_IFACE_FLAG_ERRHANDLE_BCOPY_BUF | UCT_IFACE_FLAG_ERRHANDLE_ZCOPY_BUF)) { strncat(buf, " buffer (", sizeof(buf) - 1); if (iface_attr.cap.flags & UCT_IFACE_FLAG_ERRHANDLE_SHORT_BUF) { strncat(buf, "short,", sizeof(buf) - 1); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_ERRHANDLE_BCOPY_BUF) { strncat(buf, "bcopy,", sizeof(buf) - 1); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_ERRHANDLE_ZCOPY_BUF) { strncat(buf, "zcopy,", sizeof(buf) - 1); } buf[strlen(buf) - 1] = '\0'; strncat(buf, "),", sizeof(buf) - 1); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_ERRHANDLE_AM_ID) { strncat(buf, " active-message id,", sizeof(buf) - 1); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_ERRHANDLE_REMOTE_MEM) { strncat(buf, " remote access,", sizeof(buf) - 1); } if (iface_attr.cap.flags & UCT_IFACE_FLAG_ERRHANDLE_PEER_FAILURE) { strncat(buf, " peer failure,", sizeof(buf) - 1); } buf[strlen(buf) - 1] = '\0'; } else { strncat(buf, " none", sizeof(buf) - 1); } printf("# error handling:%s\n", buf); } uct_iface_close(iface); printf("#\n"); } static ucs_status_t print_tl_info(uct_md_h md, const char *tl_name, uct_tl_resource_desc_t *resources, unsigned num_resources, int print_opts, ucs_config_print_flags_t print_flags) { ucs_async_context_t async; uct_worker_h worker; ucs_status_t status; unsigned i; status = ucs_async_context_init(&async, UCS_ASYNC_THREAD_LOCK_TYPE); if (status != UCS_OK) { return status; } /* coverity[alloc_arg] */ status = uct_worker_create(&async, UCS_THREAD_MODE_SINGLE, &worker); if (status != UCS_OK) { goto out; } printf("#\n"); printf("# Transport: %s\n", tl_name); printf("#\n"); if (num_resources == 0) { printf("# (No supported devices found)\n"); } for (i = 0; i < num_resources; ++i) { ucs_assert(!strcmp(tl_name, resources[i].tl_name)); print_iface_info(worker, md, &resources[i]); } uct_worker_destroy(worker); out: ucs_async_context_cleanup(&async); return status; }