diff --git a/docs/source/faq.md b/docs/source/faq.md index 7a9955d77fc..e9bd45702e7 100644 --- a/docs/source/faq.md +++ b/docs/source/faq.md @@ -201,8 +201,6 @@ by `ucx_info -d` command. > **IMPORTANT NOTE** > In some cases restricting the transports can lead to unexpected and undefined behavior: > * Using *rc_verbs* or *rc_mlx5* also requires *ud_verbs* or *ud_mlx5* transport for bootstrap. -> * Applications using GPU memory must also specify GPU transports for detecting and -> handling non-host memory. In addition to the built-in transports it's possible to use aliases which specify multiple transports. @@ -347,9 +345,6 @@ GPU memory (for example, and UCX compiled with GPU support. Then you can run the application as usual (for example, with MPI) and whenever GPU memory is passed to UCX, it either use GPU-direct for zero copy operations, or copy the data to/from host memory. -> NOTE When specifying UCX_TLS explicitly, must also specify cuda/rocm for GPU memory -> support, otherwise the GPU memory will not be recognized. -> For example: `UCX_TLS=rc,cuda` or `UCX_TLS=dc,rocm` #### I'm running UCX with GPU memory and getting a segfault, why? diff --git a/src/ucp/core/ucp_context.c b/src/ucp/core/ucp_context.c index aa66d5ccfe9..b5edbcc1343 100644 --- a/src/ucp/core/ucp_context.c +++ b/src/ucp/core/ucp_context.c @@ -138,13 +138,13 @@ static size_t ucp_rndv_frag_default_num_elems[] = { [UCS_MEMORY_TYPE_LAST] = 0 }; -const char *ucp_object_versions[] = { +static const char *ucp_object_versions[] = { [UCP_OBJECT_VERSION_V1] = "v1", [UCP_OBJECT_VERSION_V2] = "v2", [UCP_OBJECT_VERSION_LAST] = NULL }; -const char *ucp_extra_op_attr_flags_names[] = { +static const char *ucp_extra_op_attr_flags_names[] = { [UCP_OP_ATTR_INDEX(UCP_OP_ATTR_FLAG_NO_IMM_CMPL)] = "no_imm_cmpl", [UCP_OP_ATTR_INDEX(UCP_OP_ATTR_FLAG_FAST_CMPL)] = "fast_cmpl", [UCP_OP_ATTR_INDEX(UCP_OP_ATTR_FLAG_FORCE_IMM_CMPL)] = "force_imm_cmpl", @@ -624,6 +624,10 @@ static ucs_config_field_t ucp_config_table[] = { " and disables aliasing.", ucs_offsetof(ucp_config_t, tls), UCS_CONFIG_TYPE_ALLOW_LIST}, + {"MEM_TLS", "cuda_copy,gdr_copy,rocm_copy,ze_copy", + "Comma-separated list of transports to use for memory copy. The order is not meaningful\n", + ucs_offsetof(ucp_config_t, mem_tls), UCS_CONFIG_TYPE_ALLOW_LIST}, + {"PROTOS", UCP_RSC_CONFIG_ALL, "Comma-separated list of glob patterns specifying protocols to use.\n" "The order is not meaningful.\n" @@ -709,8 +713,8 @@ static ucp_tl_alias_t ucp_tl_aliases[] = { { "dc_x", { "dc_mlx5", UCP_TL_AUX("ud_mlx5"), NULL } }, { "ugni", { "ugni_smsg", UCP_TL_AUX("ugni_udt"), "ugni_rdma", NULL } }, { "cuda", { "cuda_copy", "cuda_ipc", "gdr_copy", NULL } }, - { "rocm", { "rocm_copy", "rocm_ipc", "rocm_gdr", NULL } }, - { "ze", { "ze_copy", "ze_ipc", "ze_gdr", NULL } }, + { "rocm", { "rocm_copy", "rocm_ipc", NULL } }, + { "ze", { "ze_copy", "ze_ipc", NULL } }, { "gga", { "gga_mlx5", NULL } }, { NULL } }; @@ -728,6 +732,13 @@ const char *ucp_feature_str[] = { }; +const char *ucp_tl_rsc_flag_names[] = { + [ucs_ilog2(UCP_TL_RSC_FLAG_COMM)] = "comm", + [ucs_ilog2(UCP_TL_RSC_FLAG_MEM)] = "mem", + [ucs_ilog2(UCP_TL_RSC_FLAG_AUX)] = "aux" +}; + + const ucp_tl_bitmap_t ucp_tl_bitmap_max = {{UINT64_MAX, UINT64_MAX}}; const ucp_tl_bitmap_t ucp_tl_bitmap_min = {{0}}; @@ -918,8 +929,9 @@ void ucp_apply_uct_config_list(ucp_context_h context, void *config) * 'str:str_suffix' string. * @return bitmap of indexes in which the string appears in the array. */ -static uint64_t ucp_str_array_search(const char **array, unsigned array_len, - const char *str, const char *str_suffix) +static uint64_t ucp_str_array_search(const char *const *array, + unsigned array_len, const char *str, + const char *str_suffix) { const size_t len = strlen(str); uint64_t result; @@ -943,14 +955,14 @@ static uint64_t ucp_str_array_search(const char **array, unsigned array_len, return result; } -static unsigned ucp_tl_alias_count(ucp_tl_alias_t *alias) +static unsigned ucp_tl_alias_count(const ucp_tl_alias_t *alias) { unsigned count; for (count = 0; alias->tls[count] != NULL; ++count); return count; } -static int ucp_tls_array_is_present(const char **tls, unsigned count, +static int ucp_tls_array_is_present(const char *const *tls, unsigned count, const char *tl_name, const char *str_suffix, uint64_t *tl_cfg_mask) { @@ -1012,8 +1024,8 @@ static int ucp_is_resource_in_device_list(const uct_tl_resource_desc_t *resource return !!mask; } -static int ucp_tls_alias_is_present(ucp_tl_alias_t *alias, const char *tl_name, - const char *str_suffix) +static int ucp_tls_alias_is_present(const ucp_tl_alias_t *alias, + const char *tl_name, const char *str_suffix) { unsigned tl_alias_count = ucp_tl_alias_count(alias); uint64_t dummy_mask = 0; @@ -1025,11 +1037,12 @@ static int ucp_tls_alias_is_present(ucp_tl_alias_t *alias, const char *tl_name, static uint8_t ucp_transports_list_search(const char *tl_name, const ucs_config_names_array_t *tl_array, + const ucp_tl_alias_t *tl_aliases, uint64_t *tl_cfg_mask) { + const ucp_tl_alias_t *alias; uint8_t search_result = 0; uint64_t tmp_tl_cfg_mask; - ucp_tl_alias_t *alias; int tl_in_alias, tl_aux_in_alias; if (ucp_config_is_tl_name_present(tl_array, tl_name, 0, NULL, @@ -1044,7 +1057,7 @@ ucp_transports_list_search(const char *tl_name, search_result |= UCP_TRANSPORTS_LIST_SEARCH_RESULT_AUX_IN_MAIN; } - for (alias = ucp_tl_aliases; alias->alias != NULL; ++alias) { + for (alias = tl_aliases; alias->alias != NULL; ++alias) { tmp_tl_cfg_mask = 0; if (ucp_config_is_tl_name_present(tl_array, alias->alias, 1, NULL, &tmp_tl_cfg_mask)) { @@ -1085,45 +1098,48 @@ ucp_transports_list_search(const char *tl_name, return search_result; } -static int -ucp_is_resource_in_transports_list(const char *tl_name, - const ucs_config_allow_list_t *allow_list, - const ucs_string_set_t *aux_tls, - uint8_t *rsc_flags, uint64_t *tl_cfg_mask) +/* Returns which flags are enabled for the resource, out of the flags provided + in rsc_flags */ +static uint8_t ucp_tl_resource_check_transports_list( + const char *tl_name, const ucs_config_allow_list_t *allow_list, + const ucs_string_set_t *aux_tls, const ucp_tl_alias_t *tl_aliases, + uint8_t rsc_usage_mask, uint64_t *tl_cfg_mask) { uint8_t search_result; if (allow_list->mode == UCS_CONFIG_ALLOW_LIST_ALLOW_ALL) { - return 1; + return rsc_usage_mask; } - ucs_assert(allow_list->array.count > 0); search_result = ucp_transports_list_search(tl_name, &allow_list->array, - tl_cfg_mask); + tl_aliases, tl_cfg_mask); if (allow_list->mode == UCS_CONFIG_ALLOW_LIST_ALLOW) { /* Enable the transport, if UCX_TLS=tl_name, or alias={tl_name} and * UCX_TLS=alias. */ if (search_result & UCP_TRANSPORTS_LIST_SEARCH_RESULT_PRIMARY) { - return 1; + return rsc_usage_mask; } - /* Enable the transport as an auxiliary, if UCX_TLS=tl_name:aux, or + /* Enable the transport only as an auxiliary, if UCX_TLS=tl_name:aux, or * alias={tl_name} and UCX_TLS=alias:aux, or alias={tl_name:aux} and * UCX_TLS=alias. */ if (search_result & (UCP_TRANSPORTS_LIST_SEARCH_RESULT_AUX_IN_MAIN | UCP_TRANSPORTS_LIST_SEARCH_RESULT_AUX_IN_ALIAS)) { - *rsc_flags |= UCP_TL_RSC_FLAG_AUX; - return 1; + return rsc_usage_mask & UCP_TL_RSC_FLAG_AUX; } return 0; } + /*** Deny-list mode ***/ + if (!ucs_string_set_contains(aux_tls, tl_name)) { /* Disable the transport which is not used as an auxiliary, if * UCX_TLS=^tl_name, or alias={tl_name} and UCX_TLS=^alias. */ - return !(search_result & UCP_TRANSPORTS_LIST_SEARCH_RESULT_PRIMARY); + return (search_result & UCP_TRANSPORTS_LIST_SEARCH_RESULT_PRIMARY) ? + 0 : + rsc_usage_mask; } /* A transport that can be used as an auxiliary is disabled by @@ -1142,38 +1158,55 @@ ucp_is_resource_in_transports_list(const char *tl_name, * UCX_TLS=^tl_name2 or UCX_TLS=^alias2 should not break the usage of * tl_name1 keeping tl_name2 enabled as auxiliary transport. */ if (search_result & UCP_TRANSPORTS_LIST_SEARCH_RESULT_PRIMARY) { - *rsc_flags |= UCP_TL_RSC_FLAG_AUX; + return rsc_usage_mask & UCP_TL_RSC_FLAG_AUX; } /* Enable the transport, if it is not in the deny list, or if it is only * presented as an auxiliary transport in the deny list. */ - return 1; + return rsc_usage_mask; } -static int ucp_is_resource_enabled(const uct_tl_resource_desc_t *resource, - const ucp_config_t *config, - const ucs_string_set_t *aux_tls, - uint8_t *rsc_flags, uint64_t dev_cfg_masks[], - uint64_t *tl_cfg_mask) +/* Returns which flags are enabled for the resource, given the provided + configuration and set of auxiliary transports */ +static uint8_t +ucp_tl_resource_usage_flags(const uct_tl_resource_desc_t *resource, + const ucp_config_t *config, + const ucs_string_set_t *aux_tls, + uint64_t dev_cfg_masks[], uint64_t *tl_cfg_mask) { - int device_enabled, tl_enabled; + UCS_STRING_BUFFER_ONSTACK(rsc_flags_strb, 256); + const ucp_tl_alias_t empty_tl_aliases[] = {{NULL}}; + uint8_t rsc_flags = 0; /* Find the enabled devices */ - device_enabled = ucp_is_resource_in_device_list( - resource, config->devices, &dev_cfg_masks[resource->dev_type], - resource->dev_type); - + if (!ucp_is_resource_in_device_list(resource, config->devices, + &dev_cfg_masks[resource->dev_type], + resource->dev_type)) { + goto out; + } /* Find the enabled UCTs */ - *rsc_flags = 0; - tl_enabled = ucp_is_resource_in_transports_list(resource->tl_name, - &config->tls, aux_tls, - rsc_flags, tl_cfg_mask); + rsc_flags |= ucp_tl_resource_check_transports_list( + resource->tl_name, &config->tls, aux_tls, ucp_tl_aliases, + UCP_TL_RSC_FLAG_COMM | UCP_TL_RSC_FLAG_AUX, tl_cfg_mask); - ucs_trace(UCT_TL_RESOURCE_DESC_FMT " is %sabled", + /* Find the enabled memory transports */ + rsc_flags |= ucp_tl_resource_check_transports_list( + resource->tl_name, &config->mem_tls, aux_tls, empty_tl_aliases, + UCP_TL_RSC_FLAG_MEM, tl_cfg_mask); + +out: + if (rsc_flags == 0) { + ucs_string_buffer_appendf(&rsc_flags_strb, "disabled"); + } else { + ucs_string_buffer_appendf(&rsc_flags_strb, "enabled for "); + ucs_string_buffer_append_flags(&rsc_flags_strb, rsc_flags, + ucp_tl_rsc_flag_names); + } + ucs_trace(UCT_TL_RESOURCE_DESC_FMT " is %s", UCT_TL_RESOURCE_DESC_ARG(resource), - (device_enabled && tl_enabled) ? "en" : "dis"); - return device_enabled && tl_enabled; + ucs_string_buffer_cstr(&rsc_flags_strb)); + return rsc_flags; } static int ucp_tl_resource_is_same_device(const uct_tl_resource_desc_t *resource1, @@ -1184,18 +1217,21 @@ static int ucp_tl_resource_is_same_device(const uct_tl_resource_desc_t *resource (resource1->sys_device == resource2->sys_device)); } -static void ucp_add_tl_resource_if_enabled( - ucp_context_h context, ucp_md_index_t md_index, - const ucp_config_t *config, const ucs_string_set_t *aux_tls, - const uct_tl_resource_desc_t *resource, unsigned *num_resources_p, - uint64_t dev_cfg_masks[], uint64_t *tl_cfg_mask) +static void +ucp_add_tl_resource_if_enabled(ucp_context_h context, ucp_md_index_t md_index, + const ucp_config_t *config, + const ucs_string_set_t *aux_tls, + const uct_tl_resource_desc_t *resource, + uint64_t dev_cfg_masks[], uint64_t *tl_cfg_mask, + uint8_t *tl_rsc_flags) { ucp_tl_md_t *md = &context->tl_mds[md_index]; uint8_t rsc_flags; ucp_rsc_index_t dev_index, i; - if (ucp_is_resource_enabled(resource, config, aux_tls, &rsc_flags, - dev_cfg_masks, tl_cfg_mask)) { + rsc_flags = ucp_tl_resource_usage_flags(resource, config, aux_tls, + dev_cfg_masks, tl_cfg_mask); + if (rsc_flags != 0) { if ((resource->sys_device != UCS_SYS_DEVICE_ID_UNKNOWN) && (resource->sys_device >= UCP_MAX_SYS_DEVICES)) { ucs_diag(UCT_TL_RESOURCE_DESC_FMT @@ -1209,6 +1245,7 @@ static void ucp_add_tl_resource_if_enabled( context->tl_rscs[context->num_tls].tl_name_csum = ucs_crc16_string(resource->tl_name); context->tl_rscs[context->num_tls].flags = rsc_flags; + *tl_rsc_flags |= rsc_flags; dev_index = 0; for (i = 0; i < context->num_tls; ++i) { @@ -1226,17 +1263,16 @@ static void ucp_add_tl_resource_if_enabled( } ++context->num_tls; - ++(*num_resources_p); } } static ucs_status_t ucp_add_tl_resources(ucp_context_h context, ucp_md_index_t md_index, const ucp_config_t *config, - const ucs_string_set_t *aux_tls, unsigned *num_resources_p, + const ucs_string_set_t *aux_tls, ucs_string_set_t avail_devices[], ucs_string_set_t *avail_tls, uint64_t dev_cfg_masks[], - uint64_t *tl_cfg_mask) + uint64_t *tl_cfg_mask, uint8_t *tl_rsc_flags) { ucp_tl_md_t *md = &context->tl_mds[md_index]; uct_tl_resource_desc_t *tl_resources; @@ -1245,8 +1281,6 @@ ucp_add_tl_resources(ucp_context_h context, ucp_md_index_t md_index, ucs_status_t status; ucp_rsc_index_t i; - *num_resources_p = 0; - /* check what are the available uct resources */ status = uct_md_query_tl_resources(md->md, &tl_resources, &num_tl_resources); if (status != UCS_OK) { @@ -1282,8 +1316,8 @@ ucp_add_tl_resources(ucp_context_h context, ucp_md_index_t md_index, context->tl_cmpts[md->cmpt_index].attr.name); ucs_string_set_add(avail_tls, tl_resources[i].tl_name); ucp_add_tl_resource_if_enabled(context, md_index, config, aux_tls, - &tl_resources[i], num_resources_p, - dev_cfg_masks, tl_cfg_mask); + &tl_resources[i], dev_cfg_masks, + tl_cfg_mask, tl_rsc_flags); } status = UCS_OK; @@ -1469,59 +1503,52 @@ static ucs_status_t ucp_fill_tl_md(ucp_context_h context, } static void ucp_resource_config_array_str(const ucs_config_names_array_t *array, - const char *title, char *buf, size_t max) + const char *title, + ucs_string_buffer_t *strb) { - char *p, *endp; - unsigned i; - if (ucp_str_array_search((const char**)array->names, array->count, UCP_RSC_CONFIG_ALL, NULL)) { - strncpy(buf, "", max); return; } - p = buf; - endp = buf + max; + ucs_string_buffer_appendf(strb, "%s:", title); + ucs_string_buffer_append_array(strb, ",", "%s", array->names, array->count); +} - if (strlen(title)) { - snprintf(p, endp - p, "%s:", title); - p += strlen(p); - } +static void +ucp_resource_allow_list_str(const ucs_config_allow_list_t *allow_list, + ucs_string_buffer_t *strb) +{ + if (allow_list->mode == UCS_CONFIG_ALLOW_LIST_ALLOW_ALL) { + ucs_string_buffer_appendf(strb, "all transports"); + } else { + if (allow_list->mode == UCS_CONFIG_ALLOW_LIST_NEGATE) { + ucs_string_buffer_appendf(strb, "not "); + } - for (i = 0; i < array->count; ++i) { - snprintf(p, endp - p, "%s%c", array->names[i], - (i == array->count - 1) ? ' ' : ','); - p += strlen(p); + ucs_string_buffer_append_array(strb, ",", "%s", allow_list->array.names, + allow_list->array.count); } } -static void ucp_resource_config_str(const ucp_config_t *config, char *buf, - size_t max) +static void +ucp_resource_config_str(const ucp_config_t *config, ucs_string_buffer_t *strb) { + size_t length_before; int dev_type_idx; - char *p, *endp, *devs_p; - p = buf; - endp = buf + max; + ucp_resource_allow_list_str(&config->tls, strb); + ucs_string_buffer_appendf(strb, " on "); - ucp_resource_config_array_str(&config->tls.array, "", p, endp - p); - - if (strlen(p)) { - p += strlen(p); - snprintf(p, endp - p, "on "); - p += strlen(p); - } - - devs_p = p; + length_before = ucs_string_buffer_length(strb); for (dev_type_idx = 0; dev_type_idx < UCT_DEVICE_TYPE_LAST; ++dev_type_idx) { ucp_resource_config_array_str(&config->devices[dev_type_idx], - uct_device_type_names[dev_type_idx], p, - endp - p); - p += strlen(p); + uct_device_type_names[dev_type_idx], + strb); } - if (devs_p == p) { - snprintf(p, endp - p, "all devices"); + if (length_before == ucs_string_buffer_length(strb)) { + ucs_string_buffer_appendf(strb, "all devices"); } } @@ -1574,25 +1601,27 @@ ucp_fill_sockaddr_prio_list(ucp_context_h context, const ucp_config_t *config) static ucs_status_t ucp_check_resources(ucp_context_h context, const ucp_config_t *config) { - char info_str[128]; + UCS_STRING_BUFFER_ONSTACK(info_strb, 128); ucp_rsc_index_t tl_id; ucp_tl_resource_desc_t *resource; - unsigned num_usable_tls; + int have_comm_tl; /* Error check: Make sure there is at least one transport that is not * auxiliary */ - num_usable_tls = 0; + have_comm_tl = 0; for (tl_id = 0; tl_id < context->num_tls; ++tl_id) { ucs_assert(context->tl_rscs != NULL); resource = &context->tl_rscs[tl_id]; - if (!(resource->flags & UCP_TL_RSC_FLAG_AUX)) { - num_usable_tls++; + if (resource->flags & UCP_TL_RSC_FLAG_COMM) { + have_comm_tl = 1; + break; } } - if (num_usable_tls == 0) { - ucp_resource_config_str(config, info_str, sizeof(info_str)); - ucs_error("no usable transports/devices (asked %s)", info_str); + if (!have_comm_tl) { + ucp_resource_config_str(config, &info_strb); + ucs_error("no usable transports/devices (asked %s)", + ucs_string_buffer_cstr(&info_strb)); return UCS_ERR_NO_DEVICE; } @@ -1618,14 +1647,13 @@ ucp_add_component_resources(ucp_context_h context, ucp_rsc_index_t cmpt_index, const ucp_tl_cmpt_t *tl_cmpt = &context->tl_cmpts[cmpt_index]; size_t avail_mds = config->max_component_mds; uct_component_attr_t uct_component_attr; - unsigned num_tl_resources; + uint8_t tl_rsc_flags; ucs_status_t status; ucp_rsc_index_t i; unsigned md_index; uint64_t mem_type_mask; - uint64_t mem_type_bitmap; ucs_memory_type_t mem_type; - const uct_md_attr_v2_t *md_attr; + ucp_tl_md_t *tl_md; /* List memory domain resources */ uct_component_attr.field_mask = UCT_COMPONENT_ATTR_FIELD_MD_RESOURCES | @@ -1650,48 +1678,50 @@ ucp_add_component_resources(ucp_context_h context, ucp_rsc_index_t cmpt_index, } md_index = context->num_mds; - md_attr = &context->tl_mds[md_index].attr; + tl_md = &context->tl_mds[md_index]; status = ucp_fill_tl_md(context, cmpt_index, - &uct_component_attr.md_resources[i], - &context->tl_mds[md_index]); + &uct_component_attr.md_resources[i], tl_md); if (status != UCS_OK) { continue; } /* Add communication resources of each MD */ - status = ucp_add_tl_resources(context, md_index, config, aux_tls, - &num_tl_resources, avail_devices, - avail_tls, dev_cfg_masks, tl_cfg_mask); + tl_rsc_flags = 0; + status = ucp_add_tl_resources(context, md_index, config, aux_tls, + avail_devices, avail_tls, dev_cfg_masks, + tl_cfg_mask, &tl_rsc_flags); if (status != UCS_OK) { - uct_md_close(context->tl_mds[md_index].md); + uct_md_close(tl_md->md); goto out; } - if (num_tl_resources == 0) { - /* If the MD does not have transport resources (device or sockaddr), - * don't use it */ - ucs_debug("closing md %s because it has no selected transport resources", - context->tl_mds[md_index].rsc.md_name); - uct_md_close(context->tl_mds[md_index].md); + if (tl_rsc_flags == 0) { + /* If the MD does not have transport resources, don't use it */ + ucs_debug("closing md %s/%s because it has no selected transport " + "resources", + tl_cmpt->attr.name, tl_md->rsc.md_name); + uct_md_close(tl_md->md); continue; } avail_mds--; - /* List of memory type MDs */ - mem_type_bitmap = md_attr->detect_mem_types; - if (~mem_type_mask & mem_type_bitmap) { - context->mem_type_detect_mds[context->num_mem_type_detect_mds] = md_index; + if (tl_rsc_flags & UCP_TL_RSC_FLAG_MEM) { + ucs_debug("adding md %s/%s to memory detection list", + tl_cmpt->attr.name, tl_md->rsc.md_name); + context->mem_type_detect_mds[context->num_mem_type_detect_mds] = + md_index; ++context->num_mem_type_detect_mds; - mem_type_mask |= mem_type_bitmap; + mem_type_mask |= tl_md->attr.detect_mem_types; } ucs_memory_type_for_each(mem_type) { - if (md_attr->flags & UCT_MD_FLAG_REG) { - if ((context->config.ext.reg_nb_mem_types & UCS_BIT(mem_type)) && - !(md_attr->reg_nonblock_mem_types & UCS_BIT(mem_type))) { - if (md_attr->reg_mem_types & UCS_BIT(mem_type)) { + if (tl_md->attr.flags & UCT_MD_FLAG_REG) { + if ((context->config.ext.reg_nb_mem_types & + UCS_BIT(mem_type)) && + !(tl_md->attr.reg_nonblock_mem_types & UCS_BIT(mem_type))) { + if (tl_md->attr.reg_mem_types & UCS_BIT(mem_type)) { /* Keep map of MDs supporting blocking registration * if non-blocking registration is requested for the * given memory type. In some cases blocking @@ -1702,30 +1732,30 @@ ucp_add_component_resources(ucp_context_h context, ucp_rsc_index_t cmpt_index, continue; } - if (md_attr->reg_mem_types & UCS_BIT(mem_type)) { + if (tl_md->attr.reg_mem_types & UCS_BIT(mem_type)) { context->reg_md_map[mem_type] |= UCS_BIT(md_index); } - if (md_attr->cache_mem_types & UCS_BIT(mem_type)) { + if (tl_md->attr.cache_mem_types & UCS_BIT(mem_type)) { context->cache_md_map[mem_type] |= UCS_BIT(md_index); } if ((context->config.ext.gva_enable != UCS_CONFIG_OFF) && - (md_attr->gva_mem_types & UCS_BIT(mem_type))) { + (tl_md->attr.gva_mem_types & UCS_BIT(mem_type))) { context->gva_md_map[mem_type] |= UCS_BIT(md_index); } } } - if (md_attr->flags & UCT_MD_FLAG_EXPORTED_MKEY) { + if (tl_md->attr.flags & UCT_MD_FLAG_EXPORTED_MKEY) { context->export_md_map |= UCS_BIT(md_index); } - if (md_attr->flags & UCT_MD_FLAG_REG_DMABUF) { + if (tl_md->attr.flags & UCT_MD_FLAG_REG_DMABUF) { context->dmabuf_reg_md_map |= UCS_BIT(md_index); } - ucs_for_each_bit(mem_type, md_attr->dmabuf_mem_types) { + ucs_for_each_bit(mem_type, tl_md->attr.dmabuf_mem_types) { /* In case of multiple providers, take the first one */ if (context->dmabuf_mds[mem_type] == UCP_NULL_RESOURCE) { context->dmabuf_mds[mem_type] = md_index; diff --git a/src/ucp/core/ucp_context.h b/src/ucp/core/ucp_context.h index 7df775955db..be44fd93fc1 100644 --- a/src/ucp/core/ucp_context.h +++ b/src/ucp/core/ucp_context.h @@ -38,9 +38,12 @@ KHASH_IMPL(ucp_context_imported_mem_hash, uint64_t, ucs_rcache_t*, 1, enum { - /* The flag indicates that the resource may be used for auxiliary - * wireup communications only */ - UCP_TL_RSC_FLAG_AUX = UCS_BIT(0) + /* The flag indicates that the resource may be used for normal communication */ + UCP_TL_RSC_FLAG_COMM = UCS_BIT(0), + /* The flag indicates that the resource may be used for auxiliary wireup */ + UCP_TL_RSC_FLAG_AUX = UCS_BIT(1), + /* The flag indicates that the resource may be used for memory copy */ + UCP_TL_RSC_FLAG_MEM = UCS_BIT(2), }; #define UCP_OP_ATTR_INDEX_MASK (UCP_OP_ATTR_FLAG_NO_IMM_CMPL | \ @@ -228,6 +231,8 @@ struct ucp_config { ucs_config_names_array_t devices[UCT_DEVICE_TYPE_LAST]; /** Array of transport names to use */ ucs_config_allow_list_t tls; + /** Array of transport names to use for memory copy */ + ucs_config_allow_list_t mem_tls; /** Array of protocol names to use */ ucs_config_allow_list_t protos; /** Array of memory allocation methods */ @@ -587,6 +592,7 @@ typedef struct ucp_tl_iface_atomic_flags { extern ucp_am_handler_t *ucp_am_handlers[]; extern const char *ucp_feature_str[]; +extern const char *ucp_tl_rsc_flag_names[]; void ucp_dump_payload(ucp_context_h context, char *buffer, size_t max, diff --git a/src/ucp/core/ucp_worker.c b/src/ucp/core/ucp_worker.c index 81bb56ec9be..e6158ec947c 100644 --- a/src/ucp/core/ucp_worker.c +++ b/src/ucp/core/ucp_worker.c @@ -573,13 +573,26 @@ ucp_worker_iface_error_handler(void *arg, uct_ep_h uct_ep, ucs_status_t status) return status; } +static int ucp_worker_iface_can_recv_tag(const ucp_worker_iface_t *wiface) +{ + const uint64_t cap_flags = UCT_IFACE_FLAG_CB_SYNC | + UCT_IFACE_FLAG_TAG_EAGER_SHORT | + UCT_IFACE_FLAG_TAG_EAGER_BCOPY | + UCT_IFACE_FLAG_TAG_EAGER_ZCOPY | + UCT_IFACE_FLAG_TAG_RNDV_ZCOPY; + ucp_context_h context = wiface->worker->context; + + return (wiface->attr.cap.flags & cap_flags) && + (context->tl_rscs[wiface->rsc_index].flags & UCP_TL_RSC_FLAG_COMM); +} + void ucp_worker_iface_activate(ucp_worker_iface_t *wiface, unsigned uct_flags) { ucp_worker_h worker = wiface->worker; - ucs_trace("activate " UCP_WIFACE_FMT " a_count=%u a_ifaces=%u", + ucs_trace("activate " UCP_WIFACE_FMT " a_count %u tag_ifaces %u", UCP_WIFACE_ARG(wiface), wiface->activate_count, - worker->num_active_ifaces); + worker->num_active_tag_ifaces); if (wiface->activate_count++ > 0) { return; /* was already activated */ @@ -602,7 +615,9 @@ void ucp_worker_iface_activate(ucp_worker_iface_t *wiface, unsigned uct_flags) ucs_list_add_tail(&worker->arm_ifaces, &wiface->arm_list); } - ++worker->num_active_ifaces; + if (ucp_worker_iface_can_recv_tag(wiface)) { + ++worker->num_active_tag_ifaces; + } uct_iface_progress_enable(wiface->iface, UCT_PROGRESS_SEND | UCT_PROGRESS_RECV | uct_flags); @@ -731,9 +746,9 @@ static void ucp_worker_iface_deactivate(ucp_worker_iface_t *wiface, int force) { ucp_worker_h worker = wiface->worker; - ucs_trace("deactivate " UCP_WIFACE_FMT " force=%d a_count=%u a_ifaces=%u", + ucs_trace("deactivate " UCP_WIFACE_FMT " force=%d a_count %u tag_ifaces %u", UCP_WIFACE_ARG(wiface), force, wiface->activate_count, - worker->num_active_ifaces); + worker->num_active_tag_ifaces); if (!force) { ucs_assertv(wiface->activate_count > 0, UCP_WIFACE_FMT, @@ -744,7 +759,9 @@ static void ucp_worker_iface_deactivate(ucp_worker_iface_t *wiface, int force) return; } - --worker->num_active_ifaces; + if (ucp_worker_iface_can_recv_tag(wiface)) { + --worker->num_active_tag_ifaces; + } } /* Avoid progress on the interface to reduce overhead */ @@ -2485,17 +2502,17 @@ ucs_status_t ucp_worker_create(ucp_context_h context, return UCS_ERR_NO_MEMORY; } - worker->context = context; - worker->uuid = ucs_generate_uuid((uintptr_t)worker); - worker->flush_ops_count = 0; - worker->fence_seq = 0; - worker->inprogress = 0; - worker->rkey_config_count = 0; - worker->num_active_ifaces = 0; - worker->num_ifaces = 0; - worker->am_message_id = ucs_generate_uuid(0); - worker->rkey_ptr_cb_id = UCS_CALLBACKQ_ID_NULL; - worker->num_all_eps = 0; + worker->context = context; + worker->uuid = ucs_generate_uuid((uintptr_t)worker); + worker->flush_ops_count = 0; + worker->fence_seq = 0; + worker->inprogress = 0; + worker->rkey_config_count = 0; + worker->num_active_tag_ifaces = 0; + worker->num_ifaces = 0; + worker->am_message_id = ucs_generate_uuid(0); + worker->rkey_ptr_cb_id = UCS_CALLBACKQ_ID_NULL; + worker->num_all_eps = 0; ucp_worker_keepalive_reset(worker); ucs_queue_head_init(&worker->rkey_ptr_reqs); ucs_list_head_init(&worker->arm_ifaces); diff --git a/src/ucp/core/ucp_worker.h b/src/ucp/core/ucp_worker.h index 561f0ec8043..eff371c0d40 100644 --- a/src/ucp/core/ucp_worker.h +++ b/src/ucp/core/ucp_worker.h @@ -334,7 +334,7 @@ typedef struct ucp_worker { ucp_worker_iface_t **ifaces; /* Array of pointers to interfaces, one for each resource */ unsigned num_ifaces; /* Number of elements in ifaces array */ - unsigned num_active_ifaces; /* Number of activated ifaces */ + unsigned num_active_tag_ifaces; /* Number of activated ifaces that can receive tag messages */ ucp_tl_bitmap_t scalable_tl_bitmap; /* Map of scalable tl resources */ ucp_worker_cm_t *cms; /* Array of CMs, one for each component */ ucs_mpool_set_t am_mps; /* Memory pool set for AM receives */ diff --git a/src/ucp/tag/offload.c b/src/ucp/tag/offload.c index 08604b19a61..27c20836b87 100644 --- a/src/ucp/tag/offload.c +++ b/src/ucp/tag/offload.c @@ -53,7 +53,7 @@ ucp_tag_offload_iface(ucp_worker_t *worker, ucp_tag_t tag) khiter_t hash_it; ucp_tag_t key_tag; - if (worker->num_active_ifaces == 1) { + if (worker->num_active_tag_ifaces == 1) { ucs_assert(worker->tm.offload.iface != NULL); return worker->tm.offload.iface; } diff --git a/src/ucp/tag/offload.h b/src/ucp/tag/offload.h index 3c3af328196..421da422da8 100644 --- a/src/ucp/tag/offload.h +++ b/src/ucp/tag/offload.h @@ -159,7 +159,7 @@ ucp_tag_offload_unexp(ucp_worker_iface_t *wiface, ucp_tag_t tag, size_t length) avoid unwanted postings of receive buffers (those, which are expected to arrive from offload incapable iface) to the HW. */ if (ucs_unlikely((length >= worker->tm.offload.thresh) && - (worker->num_active_ifaces > 1))) { + (worker->num_active_tag_ifaces > 1))) { tag_key = worker->context->config.tag_sender_mask & tag; hash_it = kh_get(ucp_tag_offload_hash, &worker->tm.offload.tag_hash, tag_key); diff --git a/src/ucp/wireup/select.c b/src/ucp/wireup/select.c index 82585bd4075..3aa84d3dedb 100644 --- a/src/ucp/wireup/select.c +++ b/src/ucp/wireup/select.c @@ -410,6 +410,7 @@ static UCS_F_NOINLINE ucs_status_t ucp_wireup_select_transport( ucp_lane_index_t lane; char tls_info[256]; char uct_info[256]; + char flags_str[64]; char *p, *endp; uct_iface_attr_t *iface_attr; uct_md_attr_v2_t *md_attr; @@ -417,6 +418,7 @@ static UCS_F_NOINLINE ucs_status_t ucp_wireup_select_transport( int is_reachable; double score; uint8_t priority; + uint8_t tl_rsc_flags; ucp_md_index_t md_index; p = tls_info; @@ -494,8 +496,14 @@ static UCS_F_NOINLINE ucs_status_t ucp_wireup_select_transport( md_attr = &context->tl_mds[md_index].attr; cmpt_attr = ucp_cmpt_attr_by_md_index(context, md_index); - if ((context->tl_rscs[rsc_index].flags & UCP_TL_RSC_FLAG_AUX) && - !(criteria->tl_rsc_flags & UCP_TL_RSC_FLAG_AUX)) { + tl_rsc_flags = context->tl_rscs[rsc_index].flags; + if (!(tl_rsc_flags & criteria->tl_rsc_flags)) { + ucs_trace(UCT_TL_RESOURCE_DESC_FMT + " : disabled because it doesn't support %s", + UCT_TL_RESOURCE_DESC_ARG(resource), + ucs_flags_str(flags_str, sizeof(flags_str), + criteria->tl_rsc_flags, + ucp_tl_rsc_flag_names)); continue; } @@ -1083,7 +1091,9 @@ static void ucp_wireup_fill_aux_criteria(ucp_wireup_criteria_t *criteria, ucp_wireup_fill_peer_err_criteria(criteria, ep_init_flags); } -static void ucp_wireup_criteria_init(ucp_wireup_criteria_t *criteria) +static void +ucp_wireup_criteria_init(const ucp_wireup_select_params_t *select_params, + ucp_wireup_criteria_t *criteria) { criteria->title = ""; criteria->local_md_flags = 0; @@ -1093,7 +1103,10 @@ static void ucp_wireup_criteria_init(ucp_wireup_criteria_t *criteria) criteria->alloc_mem_types = 0; criteria->is_keepalive = 0; criteria->calc_score = NULL; - criteria->tl_rsc_flags = 0; + criteria->tl_rsc_flags = (select_params->ep_init_flags & + UCP_EP_INIT_FLAG_MEM_TYPE) ? + UCP_TL_RSC_FLAG_MEM : + UCP_TL_RSC_FLAG_COMM; ucp_wireup_init_select_flags(&criteria->local_iface_flags, 0, 0); ucp_wireup_init_select_flags(&criteria->remote_iface_flags, 0, 0); memset(&criteria->remote_atomic_flags, 0, @@ -1154,7 +1167,7 @@ ucp_wireup_add_rma_lanes(const ucp_wireup_select_params_t *select_params, return UCS_OK; } - ucp_wireup_criteria_init(&criteria); + ucp_wireup_criteria_init(select_params, &criteria); if (ep_init_flags & UCP_EP_INIT_FLAG_MEM_TYPE) { criteria.title = "copy across memory types"; ucp_wireup_init_select_flags(&criteria.local_iface_flags, @@ -1221,7 +1234,7 @@ ucp_wireup_add_amo_lanes(const ucp_wireup_select_params_t *select_params, return UCS_OK; } - ucp_wireup_criteria_init(&criteria); + ucp_wireup_criteria_init(select_params, &criteria); criteria.title = "atomic operations on %s memory"; criteria.local_atomic_flags = criteria.remote_atomic_flags; criteria.calc_score = ucp_wireup_amo_score_func; @@ -1464,13 +1477,15 @@ ucp_wireup_add_am_lane(const ucp_wireup_select_params_t *select_params, /* Select one lane for active messages */ for (;;) { - ucp_wireup_criteria_init(&criteria); - criteria.title = "active messages"; - criteria.calc_score = ucp_wireup_am_score_func; - criteria.lane_type = UCP_LANE_TYPE_AM; - criteria.tl_rsc_flags = - (ep_init_flags & UCP_EP_INIT_ALLOW_AM_AUX_TL) ? - UCP_TL_RSC_FLAG_AUX : 0; + ucp_wireup_criteria_init(select_params, &criteria); + criteria.calc_score = ucp_wireup_am_score_func; + criteria.lane_type = UCP_LANE_TYPE_AM; + if (ep_init_flags & UCP_EP_INIT_ALLOW_AM_AUX_TL) { + criteria.title = "auxiliary active messages"; + criteria.tl_rsc_flags |= UCP_TL_RSC_FLAG_AUX; + } else { + criteria.title = "active messages"; + } ucp_wireup_init_select_flags(&criteria.local_iface_flags, UCT_IFACE_FLAG_AM_BCOPY, 0); ucp_wireup_init_select_flags(&criteria.remote_iface_flags, @@ -1905,7 +1920,7 @@ ucp_wireup_add_am_bw_lanes(const ucp_wireup_select_params_t *select_params, } /* Select one lane for active messages */ - ucp_wireup_criteria_init(&bw_info.criteria); + ucp_wireup_criteria_init(select_params, &bw_info.criteria); bw_info.criteria.title = "high-bw active messages"; bw_info.criteria.calc_score = ucp_wireup_am_bw_score_func; bw_info.criteria.lane_type = UCP_LANE_TYPE_AM_BW; @@ -2074,7 +2089,7 @@ ucp_wireup_add_rma_bw_lanes(const ucp_wireup_select_params_t *select_params, return UCS_OK; } - ucp_wireup_criteria_init(&bw_info.criteria); + ucp_wireup_criteria_init(select_params, &bw_info.criteria); bw_info.criteria.calc_score = ucp_wireup_rma_bw_score_func; ucp_wireup_init_select_flags(&bw_info.criteria.local_iface_flags, UCT_IFACE_FLAG_PENDING, 0); @@ -2237,7 +2252,7 @@ ucp_wireup_add_tag_lane(const ucp_wireup_select_params_t *select_params, return UCS_OK; } - ucp_wireup_criteria_init(&criteria); + ucp_wireup_criteria_init(select_params, &criteria); criteria.title = "tag_offload"; criteria.calc_score = ucp_wireup_am_score_func; criteria.lane_type = UCP_LANE_TYPE_TAG; @@ -2401,7 +2416,7 @@ ucp_wireup_add_keepalive_lane(const ucp_wireup_select_params_t *select_params, tl_bitmap = &select_params->tl_bitmap; } - ucp_wireup_criteria_init(&criteria); + ucp_wireup_criteria_init(select_params, &criteria); criteria.title = "keepalive"; criteria.local_md_flags = 0; criteria.is_keepalive = 1; diff --git a/test/gtest/ucp/test_ucp_sockaddr.cc b/test/gtest/ucp/test_ucp_sockaddr.cc index 76c0ccaf265..847f8437b55 100644 --- a/test/gtest/ucp/test_ucp_sockaddr.cc +++ b/test/gtest/ucp/test_ucp_sockaddr.cc @@ -3307,7 +3307,10 @@ class test_ucp_sockaddr_iface_activate : public test_ucp_sockaddr { { ucp_worker_h worker = e.worker(); for (unsigned i = 0; i < worker->num_ifaces; ++i) { - if (ucp_worker_iface_is_activated(worker->ifaces[i])) { + auto wiface = worker->ifaces[i]; + if ((worker->context->tl_rscs[wiface->rsc_index].flags & + UCP_TL_RSC_FLAG_COMM) && + ucp_worker_iface_is_activated(wiface)) { return true; } } diff --git a/test/gtest/ucp/test_ucp_tag.cc b/test/gtest/ucp/test_ucp_tag.cc index 216a8c36189..0d079a0f5a8 100644 --- a/test/gtest/ucp/test_ucp_tag.cc +++ b/test/gtest/ucp/test_ucp_tag.cc @@ -431,6 +431,9 @@ class test_ucp_tag_limits : public test_ucp_tag { } void init() { + // Disable GPU memory support + modify_config("MEM_TLS", ""); + /* TODO: Currently all the tests are for intra-node communication only. * Find a way to create inter-node endpoint on a single node */ test_ucp_tag::init(); diff --git a/test/gtest/ucp/test_ucp_tag_offload.cc b/test/gtest/ucp/test_ucp_tag_offload.cc index 0cb38dd22a6..d7bebbdbf47 100644 --- a/test/gtest/ucp/test_ucp_tag_offload.cc +++ b/test/gtest/ucp/test_ucp_tag_offload.cc @@ -553,7 +553,7 @@ UCS_TEST_P(test_ucp_tag_offload_multi, recv_from_multi) // Activate first offload iface. Tag hashing is performed only if there is // more than one active interface. activate_offload_hashing(e(0), make_tag(e(0), tag)); - int init_hash_size = receiver().worker()->num_active_ifaces > 1; + int init_hash_size = receiver().worker()->num_active_tag_ifaces > 1; EXPECT_EQ(init_hash_size, kh_size(&receiver().worker()->tm.offload.tag_hash)); diff --git a/test/gtest/ucp/test_ucp_wireup.cc b/test/gtest/ucp/test_ucp_wireup.cc index 989dadcff3f..bb0cc66b37d 100644 --- a/test/gtest/ucp/test_ucp_wireup.cc +++ b/test/gtest/ucp/test_ucp_wireup.cc @@ -1031,9 +1031,11 @@ class test_ucp_wireup_fallback : public test_ucp_wireup { ucp_md_index_t md_index = worker->context->tl_rscs[rsc_index].md_index; const uct_md_attr_v2_t *md_attr = &worker->context->tl_mds[md_index].attr; - if ((worker->context->tl_rscs[rsc_index].flags & UCP_TL_RSC_FLAG_AUX) || + if (!(worker->context->tl_rscs[rsc_index].flags & + UCP_TL_RSC_FLAG_COMM) || (md_attr->flags & UCT_MD_FLAG_SOCKADDR) || - (worker->context->tl_rscs[rsc_index].tl_rsc.dev_type == UCT_DEVICE_TYPE_ACC)) { + (worker->context->tl_rscs[rsc_index].tl_rsc.dev_type == + UCT_DEVICE_TYPE_ACC)) { // Skip TLs for wireup and CM and acceleration TLs continue; } @@ -1052,15 +1054,15 @@ class test_ucp_wireup_fallback : public test_ucp_wireup { return false; } - bool test_est_num_eps_fallback(size_t est_num_eps, - unsigned long &min_max_num_eps) { + void test_est_num_eps_fallback(size_t est_num_eps, + unsigned long &min_max_num_eps) + { size_t num_lanes = 0; - bool res = true; bool has_only_unscalable; min_max_num_eps = UCS_ULUNITS_INF; - UCS_TEST_MESSAGE << "Testing " << est_num_eps << " number of EPs"; + UCS_TEST_MESSAGE << "Testing with NUM_EPS=" << est_num_eps; modify_config("NUM_EPS", ucs::to_string(est_num_eps).c_str()); test_ucp_wireup::init(); @@ -1085,19 +1087,19 @@ class test_ucp_wireup_fallback : public test_ucp_wireup { ucs_status_t status = uct_iface_query(uct_ep->iface, &iface_attr); ASSERT_UCS_OK(status); - num_lanes++; - - if (!has_only_unscalable && (iface_attr.max_num_eps < est_num_eps)) { - res = false; - goto out; - } + EXPECT_TRUE(has_only_unscalable || + (iface_attr.max_num_eps >= est_num_eps)) + << "has_only_unscalable: " << has_only_unscalable + << " iface_attr.max_num_eps: " << iface_attr.max_num_eps + << " est_num_eps: " << est_num_eps; if (iface_attr.max_num_eps < min_max_num_eps) { min_max_num_eps = iface_attr.max_num_eps; } + + num_lanes++; } -out: test_ucp_wireup::cleanup(); if (est_num_eps == 1) { @@ -1105,10 +1107,8 @@ class test_ucp_wireup_fallback : public test_ucp_wireup { } else if (has_only_unscalable) { /* If has only unscalable transports, check that the number of * lanes is the same as for the case when "est_num_eps == 1" */ - res = (num_lanes == m_num_lanes); + EXPECT_EQ(num_lanes, m_num_lanes); } - - return res; } private: @@ -1127,15 +1127,12 @@ UCS_TEST_P(test_ucp_wireup_fallback, est_num_eps_fallback) { /* number of EPs was changed between iterations */ (test_min_max_eps != prev_min_max_eps)) { if (test_min_max_eps > 1) { - EXPECT_TRUE(test_est_num_eps_fallback(test_min_max_eps - 1, - min_max_eps)); + test_est_num_eps_fallback(test_min_max_eps - 1, min_max_eps); } - EXPECT_TRUE(test_est_num_eps_fallback(test_min_max_eps, - min_max_eps)); + test_est_num_eps_fallback(test_min_max_eps, min_max_eps); + test_est_num_eps_fallback(test_min_max_eps + 1, min_max_eps); - EXPECT_TRUE(test_est_num_eps_fallback(test_min_max_eps + 1, - min_max_eps)); prev_min_max_eps = test_min_max_eps; test_min_max_eps = min_max_eps; } @@ -1764,13 +1761,14 @@ class test_ucp_address_v2 : public test_ucp_wireup { "tag,unified"); } - void check_fp_values(double unpacked, double original) + void + check_fp_values(const std::string &name, double unpacked, double original) { double max_error = original / pow(2, _UCS_FP8_MANTISSA_BITS); - EXPECT_NEAR(original, unpacked, max_error); + EXPECT_NEAR(original, unpacked, max_error) << name; } - const uct_iface_attr_t *get_iface_attr(const ucp_address_entry_t *ae) + const ucp_worker_iface_t *get_wiface(const ucp_address_entry_t *ae) { ucp_worker_h worker = sender().worker(); ucp_context_h context = worker->context; @@ -1792,7 +1790,7 @@ class test_ucp_address_v2 : public test_ucp_wireup { ae->tl_name_csum) && uct_iface_is_reachable_v2(wiface->iface, ¶ms)) { EXPECT_EQ(ae->md_index, context->tl_rscs[rsc_index].md_index); - return &wiface->attr; + return wiface; } } @@ -1828,20 +1826,22 @@ UCS_TEST_SKIP_COND_P(test_ucp_address_v2, pack_iface_attrs, const ucp_address_entry_t *ae; ucp_unpacked_address_for_each(ae, &unpacked_address) { - auto attr = get_iface_attr(ae); - ASSERT_NE(nullptr, attr); + auto wiface = get_wiface(ae); + ASSERT_NE(nullptr, wiface); // Segment size is packed as a multiplicator of // UCP_ADDRESS_IFACE_SEG_SIZE_FACTOR, thus the unpacked value may be // smaller than the original value by up to 64 bytes. - EXPECT_LT(ucp_address_iface_seg_size(attr) - ae->iface_attr.seg_size, + EXPECT_LT(ucp_address_iface_seg_size(&wiface->attr) - + ae->iface_attr.seg_size, UCP_ADDRESS_IFACE_SEG_SIZE_FACTOR); - check_fp_values(ae->iface_attr.overhead, attr->overhead); - check_fp_values(ae->iface_attr.lat_ovh, - ucp_tl_iface_latency(worker->context, &attr->latency)); - check_fp_values( - ae->iface_attr.bandwidth, - ucp_tl_iface_bandwidth(worker->context, &attr->bandwidth)); + + check_fp_values("overhead", ae->iface_attr.overhead, + wiface->attr.overhead); + check_fp_values("latency", ae->iface_attr.lat_ovh, + ucp_wireup_iface_lat_distance_v2(wiface, 0)); + check_fp_values("bandwidth", ae->iface_attr.bandwidth, + ucp_wireup_iface_bw_distance(wiface)); } ucs_free(unpacked_address.address_list);