Repository navigation
UCP/CORE: Ignore DPU in topology assignments #11990
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b71d0f5
995a4bf
9cfcfa1
611c20d
06b673f
fb1a4c7
7bf730a
01c138e
bab4a09
526583f
d197055
399fcd9
21fe488
ce8921d
e8ef314
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -629,7 +629,10 @@ static ucs_config_field_t ucp_context_config_table[] = { | |
| {"GPU_NIC_ASSIGNMENT_MODE", "auto", | ||
| "Assign NICs to GPUs within each topology group, and restrict the lanes\n" | ||
| "for a GPU's memory to the NICs assigned to that GPU.\n" | ||
| "All ports of a NIC are assigned together.\n" | ||
| "All ports of a NIC are assigned together, and all GPUs with the same PCI\n" | ||
| "address are assigned together (e.g. MLOPart partitions of a GPU).\n" | ||
| "NICs without memory registration and DPUs are skipped during assignment.\n" | ||
| "NICs excluded by UCX_NET_DEVICES or UCX_TLS are ignored.\n" | ||
|
guy-ealey-morag marked this conversation as resolved.
Resolved
|
||
| "The 'flip', 'round_robin' and 'shared' modes apply on any hardware.\n" | ||
| "With 'flip' and 'round_robin', a group with fewer NICs than GPUs leaves\n" | ||
| "some GPUs without any NICs.\n" | ||
|
|
@@ -2783,16 +2786,67 @@ ucp_version_check(unsigned api_major_version, unsigned api_minor_version) | |
| ucs_debug("Configured with: %s", UCX_CONFIGURE_FLAGS); | ||
| } | ||
|
|
||
| static ucs_status_t | ||
| ucp_context_gpu_nic_assignment_init(ucp_gpu_nic_assignment_mode_t mode, | ||
| ucp_gpu_nic_assignment_t **assignment_p) | ||
| static int | ||
| ucp_context_is_net_device_assignable(ucp_context_h context, | ||
| const ucp_tl_resource_desc_t *rsc) | ||
| { | ||
| const uct_tl_resource_desc_t *resource = &rsc->tl_rsc; | ||
| const ucp_tl_md_t *md = &context->tl_mds[rsc->md_index]; | ||
|
|
||
| if ((resource->dev_type != UCT_DEVICE_TYPE_NET) || | ||
| (resource->sys_device == UCS_SYS_DEVICE_ID_UNKNOWN)) { | ||
| return 0; | ||
| } | ||
|
|
||
| if (rsc->flags & UCP_TL_RSC_FLAG_AUX) { | ||
| ucs_debug(UCT_TL_RESOURCE_DESC_FMT | ||
| " is ignored for gpu-nic assignment: auxiliary transport", | ||
| UCT_TL_RESOURCE_DESC_ARG(resource)); | ||
| return 0; | ||
| } | ||
|
|
||
| if (!(md->attr.flags & UCT_MD_FLAG_REG)) { | ||
| ucs_debug(UCT_TL_RESOURCE_DESC_FMT | ||
| " is ignored for gpu-nic assignment: no memory registration", | ||
| UCT_TL_RESOURCE_DESC_ARG(resource)); | ||
| return 0; | ||
| } | ||
|
|
||
| if (ucs_topo_sys_device_get_flags(resource->sys_device) & | ||
| UCS_TOPO_DEVICE_FLAG_DPU) { | ||
| ucs_debug(UCT_TL_RESOURCE_DESC_FMT | ||
| " is ignored for gpu-nic assignment: dpu device", | ||
| UCT_TL_RESOURCE_DESC_ARG(resource)); | ||
| return 0; | ||
| } | ||
|
|
||
| ucs_trace(UCT_TL_RESOURCE_DESC_FMT " is used for gpu-nic assignment", | ||
| UCT_TL_RESOURCE_DESC_ARG(resource)); | ||
| return 1; | ||
| } | ||
|
|
||
| static void ucp_context_gpu_nic_assignment_net_device_filter_init( | ||
| ucp_context_h context, ucs_sys_device_bitmap_t *net_device_filter) | ||
| { | ||
| const ucp_tl_resource_desc_t *rsc; | ||
|
|
||
| ucs_carray_for_each(rsc, context->tl_rscs, context->num_tls) { | ||
| if (ucp_context_is_net_device_assignable(context, rsc)) { | ||
| UCS_STATIC_BITMAP_SET(net_device_filter, rsc->tl_rsc.sys_device); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| static ucs_status_t ucp_context_gpu_nic_assignment_init(ucp_context_h context) | ||
| { | ||
| ucp_gpu_nic_assignment_mode_t mode = | ||
| context->config.ext.gpu_nic_assignment_mode; | ||
| ucs_sys_device_bitmap_t net_device_filter = | ||
| UCS_STATIC_BITMAP_ZERO_INITIALIZER; | ||
| ucp_gpu_nic_assignment_t *assignment; | ||
| ucs_topo_groups_t groups; | ||
| ucs_status_t status; | ||
|
|
||
| *assignment_p = NULL; | ||
|
|
||
| if (mode == UCP_GPU_NIC_ASSIGNMENT_MODE_AUTO) { | ||
| /* TODO: Improve Vera Rubin detection by checking NICs/GPUs models. */ | ||
| if (ucs_arch_get_cpu_model() != UCS_CPU_MODEL_NVIDIA_VERA) { | ||
|
|
@@ -2810,7 +2864,23 @@ ucp_context_gpu_nic_assignment_init(ucp_gpu_nic_assignment_mode_t mode, | |
|
|
||
| ucs_debug("gpu-nic assignment mode %s", ucp_gpu_nic_assignment_modes[mode]); | ||
|
|
||
| status = ucs_topo_build_groups(&groups); | ||
| ucp_context_gpu_nic_assignment_net_device_filter_init(context, | ||
| &net_device_filter); | ||
| if (UCS_STATIC_BITMAP_IS_ZERO(net_device_filter)) { | ||
| if (context->config.ext.gpu_nic_assignment_mode == | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. minor:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok as it's reading the ask from user, not its resolution |
||
| UCP_GPU_NIC_ASSIGNMENT_MODE_AUTO) { | ||
| ucs_diag("gpu-nic assignment is disabled: no assignable network " | ||
| "devices"); | ||
| return UCS_OK; | ||
| } | ||
|
|
||
| ucs_error("no assignable network devices for gpu-nic assignment mode " | ||
| "%s, set UCX_GPU_NIC_ASSIGNMENT_MODE=off to disable it", | ||
| ucp_gpu_nic_assignment_modes[mode]); | ||
| return UCS_ERR_INVALID_PARAM; | ||
| } | ||
|
|
||
| status = ucs_topo_build_groups(&net_device_filter, &groups); | ||
| if (status != UCS_OK) { | ||
| return status; | ||
| } | ||
|
|
@@ -2833,7 +2903,7 @@ ucp_context_gpu_nic_assignment_init(ucp_gpu_nic_assignment_mode_t mode, | |
| goto out_release_groups; | ||
| } | ||
|
|
||
| *assignment_p = assignment; | ||
| context->gpu_nic_assignment = assignment; | ||
|
|
||
| out_release_groups: | ||
| ucs_topo_release_groups(&groups); | ||
|
|
@@ -2894,9 +2964,7 @@ ucs_status_t ucp_init_version(unsigned api_major_version, unsigned api_minor_ver | |
| goto err_thread_lock_finalize; | ||
| } | ||
|
|
||
| status = ucp_context_gpu_nic_assignment_init( | ||
| context->config.ext.gpu_nic_assignment_mode, | ||
| &context->gpu_nic_assignment); | ||
| status = ucp_context_gpu_nic_assignment_init(context); | ||
| if (status != UCS_OK) { | ||
| goto err_free_res; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -517,6 +517,7 @@ ucs_topo_find_device_by_bus_id_value(const ucs_sys_bus_id_t *bus_id, | |
| device->pci_id = pci_id; | ||
| device->user_value = user_value; | ||
| device->device_class = UCS_TOPO_DEVICE_CLASS_UNKNOWN; | ||
| device->flags = 0; | ||
| device->class_ordinal = UCS_SYS_DEVICE_ORDINAL_INVALID; | ||
| device->sibling_role = UCS_TOPO_SIBLING_ROLE_NONE; | ||
| device->sibling_sys_dev = UCS_SYS_DEVICE_ID_UNKNOWN; | ||
|
|
@@ -1119,6 +1120,51 @@ ucs_status_t ucs_topo_sys_device_set_class(ucs_sys_device_t sys_dev, | |
| return status; | ||
| } | ||
|
|
||
| ucs_status_t | ||
| ucs_topo_sys_device_add_flags(ucs_sys_device_t sys_dev, unsigned flags) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. minor/later PR: seems we have a lot of setter/getter in this file, maybe some macro would help deduplicating eventually
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea |
||
| { | ||
| ucs_status_t status = UCS_OK; | ||
|
|
||
| if (sys_dev == UCS_SYS_DEVICE_ID_UNKNOWN) { | ||
| ucs_error("system device %d is unknown", sys_dev); | ||
| return UCS_ERR_INVALID_PARAM; | ||
| } | ||
|
|
||
| ucs_spin_lock(&ucs_topo_global_ctx.lock); | ||
|
|
||
| if (sys_dev >= ucs_topo_global_ctx.num_devices) { | ||
| ucs_error("system device %d is invalid (max: %u)", sys_dev, | ||
| ucs_topo_global_ctx.num_devices); | ||
| status = UCS_ERR_INVALID_PARAM; | ||
| goto out_unlock; | ||
| } | ||
|
|
||
| ucs_topo_global_ctx.devices[sys_dev].flags |= flags; | ||
|
|
||
| out_unlock: | ||
| ucs_spin_unlock(&ucs_topo_global_ctx.lock); | ||
| return status; | ||
| } | ||
|
|
||
| unsigned ucs_topo_sys_device_get_flags(ucs_sys_device_t sys_dev) | ||
| { | ||
| unsigned flags; | ||
|
|
||
| if (sys_dev == UCS_SYS_DEVICE_ID_UNKNOWN) { | ||
| return 0; | ||
| } | ||
|
|
||
| ucs_spin_lock(&ucs_topo_global_ctx.lock); | ||
| if (sys_dev < ucs_topo_global_ctx.num_devices) { | ||
| flags = ucs_topo_global_ctx.devices[sys_dev].flags; | ||
| } else { | ||
| flags = 0; | ||
| } | ||
| ucs_spin_unlock(&ucs_topo_global_ctx.lock); | ||
|
|
||
| return flags; | ||
| } | ||
|
|
||
| ucs_status_t | ||
| ucs_topo_device_class_mark_incomplete(ucs_topo_device_class_t device_class) | ||
| { | ||
|
|
@@ -1446,14 +1492,16 @@ static void ucs_topo_release_devices() | |
| } | ||
| } | ||
|
|
||
| ucs_status_t ucs_topo_build_groups(ucs_topo_groups_t *groups_p) | ||
| ucs_status_t | ||
| ucs_topo_build_groups(const ucs_sys_device_bitmap_t *net_device_filter, | ||
| ucs_topo_groups_t *groups_p) | ||
| { | ||
| ucs_status_t status; | ||
|
|
||
| ucs_spin_lock(&ucs_topo_global_ctx.lock); | ||
| status = ucs_topo_build_groups_inner(ucs_topo_global_ctx.devices, | ||
| ucs_topo_global_ctx.num_devices, | ||
| groups_p); | ||
| net_device_filter, groups_p); | ||
| ucs_spin_unlock(&ucs_topo_global_ctx.lock); | ||
|
|
||
| return status; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what happens when the allowed set ends up empty, e.g. UCX_TLS=tcp on Vera or a node where all NICs are DPUs? every GPU then gets an empty NIC bitmap instead of no restriction - should we fall back to 'off' in that case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tvegas1 Is this worth addressing now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIU tcp lanes are keyed by
sys_devlike any other net lane, so they are subject to the gpu/nic assignment. WithUCX_TLS=tcpthe allowed set is empty and every tcp lane is restricted, and in a mixed run a tcp lane over an mlx5 port resolves to the samesys_devas the ib device (both go throughucs_topo_get_sysfs_dev()on the same PCI function), so it inherits that NIC's assignment.Since nothing consumes the assignment yet, maybe fix it on the proto selection side when the restriction lands, either:
context->reg_md_map[mem_type]. TCP ranks far behind mlx5 anyway, the actual GPU/NIC assignment use-case.The second looks simpler and also covers the empty case, so no fallback would be needed, patch can be added to PR #11985 as it is small
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so you would fix it in #11985 right?