Skip to content

UCP/UCT/UCS: Add memory registration flags - #11553

Merged
brminich merged 10 commits into
openucx:masterfrom
tomerg-nvidia:ucs_mem_flags_pr
Jun 23, 2026
Merged

brminich merged 10 commits into
openucx:masterfrom
tomerg-nvidia:ucs_mem_flags_pr

Conversation

@tomerg-nvidia

@tomerg-nvidia tomerg-nvidia commented Jun 11, 2026 •

Copy link
Copy Markdown
Contributor

What?

Add memory registration flags to UCS memory information and propagate them through UCT mem_query_v2 and UCP memory/protocol selection paths.

This adds a REGISTERABLE memory flag, lets CUDA async allocations classified as CUDA managed report that they are not registerable, and makes UCP avoid registration-dependent MDs/protocols when that flag is missing.

Why?

Some CUDA memory can be detected as a memory type that normally has registration-capable transports, while the specific allocation cannot actually be registered on IB MDs. Without carrying this per-allocation information into UCP, protocol selection can choose zcopy paths that require registration and later fail.

How?

  • Extend UCS memory info and the memtype cache to carry memory flags.
  • Extend UCT mem_query_v2 helpers/providers to return memory flags, defaulting to REGISTERABLE.
  • Mark CUDA async memory classified as CUDA_MANAGED as not registerable.
  • Add required_mem_flags to UCT MD attributes and require REGISTERABLE for IB MD registration paths.
  • Propagate memory flags through UCP memory detection, rcache/memh compatibility, datatype iterators, RNDV, tag offload, and proto selection.
  • Add focused gtests for memtype-cache flags, IB registration failure for CUDA async memory, and UCP protocol filtering.

Add memory flags to UCS memory information and propagate them through UCT mem_query_v2 so providers can report whether a memory region is safe to register.

Use the CAN_REGISTER flag in UCP memory registration and protocol selection paths to avoid selecting registration-dependent protocols for non-registerable memory. Mark CUDA async allocations classified as CUDA managed as non-registerable, and require CAN_REGISTER for IB memory domains that need registration.

Add focused gtests for memtype cache flag handling, IB registration failure for CUDA async memory, and UCP protocol filtering.
@tomerg-nvidia
tomerg-nvidia marked this pull request as ready for review June 12, 2026 08:02
Comment thread src/ucp/core/ucp_mm.h Resolved
Comment thread src/ucp/dt/dt.h Resolved
Comment thread src/ucp/dt/dt.h Resolved
Comment thread src/ucp/proto/proto_select.h Resolved
Comment thread src/ucp/proto/proto_select.h Resolved
Comment thread src/ucp/core/ucp_mm.c Resolved
Comment thread src/ucp/core/ucp_request.c Resolved
Comment thread src/uct/cuda/cuda_copy/cuda_copy_md.c Resolved
@guy-ealey-morag

Copy link
Copy Markdown
Contributor

Also update NVIDIA copyright years on changes files

Comment thread test/gtest/uct/ib/test_ib_md.cc Resolved
Comment thread test/gtest/uct/ib/test_ib_md.cc Resolved
Comment thread test/gtest/uct/ib/test_ib_md.cc Resolved
Comment thread test/gtest/ucs/test_memtype_cache.cc Resolved
Comment thread test/gtest/uct/ib/test_ib_md.cc Resolved
Comment thread src/uct/ib/base/ib_md.c Resolved
Comment thread test/gtest/ucp/test_ucp_proto.cc Outdated
ucp_md_index_t i, md_index;
uint8_t sg_count;

if (!mem_buffer::is_mem_type_supported(UCS_MEMORY_TYPE_CUDA)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove if we check for async after?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_async_supported doesn't check we have a gpu, just the compile-time cuda library version

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i see, can we merge the two checks in is_async_supported?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since all uses of is_async_supported (even in master) first check for cuda mem type supported, we can call is_mem_type_supported(UCS_MEMORY_TYPE_CUDA) inside is_async_supported(), and only keep this one everywhere.

Comment thread test/gtest/ucp/test_ucp_proto.cc Resolved
Comment thread test/gtest/ucp/test_ucp_proto.cc Resolved
Add the mem_flags to the rcache key.
Add more tests.
Apply CR fixes.
Comment thread src/ucp/core/ucp_mm.c Resolved
Comment thread src/ucp/core/ucp_mm.c Outdated
ucp_memory_detect(context, address, length, &info);
ucp_memh_init(memh, context, memh_flags, uct_flags, method, mem_type,
info.sys_dev);
ucp_memh_init(memh, context, memh_flags, uct_flags, method, mem_info->type,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we simply pass mem_info here, instead of type, sys_dev and mem_flags?

Comment thread src/ucp/core/ucp_mm.inl Resolved
Comment thread src/ucp/core/ucp_mm.inl Resolved
Comment thread test/gtest/ucp/test_ucp_rma.cc Resolved
Comment thread test/gtest/ucs/test_rcache.cc Resolved
Comment thread test/gtest/uct/ib/test_ib_md.cc Resolved
Comment thread test/gtest/ucs/test_rcache.cc Resolved
Comment thread test/gtest/ucp/test_ucp_proto.cc Resolved
Comment thread test/gtest/ucp/test_ucp_proto.cc Resolved

@brminich brminich left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we do not keep non-registrable memory in rcache?

Comment thread src/ucp/core/ucp_mm.c Outdated
.parent = &ucp_mem_dummy_handle.memh,
.mem_type = UCS_MEMORY_TYPE_HOST,
.sys_dev = UCS_SYS_DEVICE_ID_UNKNOWN,
.super.mem_flags = UCS_MEM_FLAG_REGISTRABLE,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason to keep flags separately in rcache?

Comment thread src/ucp/core/ucp_mm.c Outdated
reg_mem_info.type = internal_mem_info.type;
reg_mem_info.sys_dev = internal_mem_info.sys_dev;
reg_mem_info.mem_flags = internal_mem_info.mem_flags;
ucp_mem_info_update_for_type(&reg_mem_info, mem_type);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need it here? Is there a use case that mem_type can be different from internal_mem_info.type?

Comment thread src/ucp/core/ucp_mm.inl Outdated
}

ucp_memory_detect(context, address, length, mem_info);
ucp_mem_info_update_for_type(mem_info, mem_type);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need it ? what is the use case that we havee to change the info filled by detect function?

Comment thread src/ucp/core/ucp_request.c Outdated
Comment on lines +474 to +475
ucp_mem_info_detect_for_type(context, buffer, length, mem_type,
&mem_info);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need to redetect here?

Comment thread src/ucp/core/ucp_mm.c Outdated

status = ucs_rcache_get(rcache, address, length, alignment,
PROT_READ | PROT_WRITE, &reg_ctx, &rregion);
PROT_READ | PROT_WRITE, mem_info->mem_flags,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need to pass flags? Can we assume that we always need registrable?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually that's interesting, so we would never cache memory without REGISTRABLE flag?

Comment thread src/ucp/core/ucp_mm.c Outdated
Comment on lines +944 to +945
mem_info = ucp_memory_info_from_memh(memh);
status = ucp_memh_get(context, address, length, &mem_info, cache_md_map,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: align

Comment thread src/ucp/core/ucp_mm.c Outdated

status = ucs_rcache_get(rcache, address, length, alignment,
PROT_READ | PROT_WRITE, &reg_ctx, &rregion);
PROT_READ | PROT_WRITE, mem_info->mem_flags,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually that's interesting, so we would never cache memory without REGISTRABLE flag?

Comment thread src/ucp/core/ucp_mm.inl Resolved
Comment thread src/ucp/core/ucp_mm.inl Resolved
Comment thread src/ucp/core/ucp_mm.inl Resolved
Comment thread src/ucp/core/ucp_mm.inl Resolved
Comment thread src/ucp/core/ucp_request.c Resolved
Comment thread src/ucp/dt/dt.c Resolved
Comment thread src/ucp/proto/proto_common.c Resolved
Comment thread src/ucp/core/ucp_mm.c Resolved
Comment thread src/ucp/core/ucp_mm.c Resolved
Comment thread src/ucp/dt/dt.h Resolved
Comment thread src/ucp/rma/rma_rndv.c Resolved
Comment thread src/uct/api/v2/uct_v2.h Resolved
Comment thread src/uct/cuda/cuda_copy/cuda_copy_md.c Resolved
…m v1

Also assert on different mem_type from detected mem_type.
Comment thread src/ucp/core/ucp_mm.c Outdated
Comment on lines +1883 to +1885
*md_idx_p = context->alloc_md[alloc_mem_type].md_index;
mem_info_p->type = alloc_mem_type;
mem_info_p->flags = context->alloc_md[alloc_mem_type].mem_flags;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

align

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment thread src/ucp/proto/proto_common.c Resolved
Comment thread src/uct/cuda/cuda_copy/cuda_copy_md.c Outdated
CUdevice cuda_device = CU_DEVICE_INVALID;
CUpointer_attribute attr_type[] = {CU_POINTER_ATTRIBUTE_MEMORY_TYPE,
CU_POINTER_ATTRIBUTE_IS_MANAGED,
CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need cuda_device?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also can you avoid doing this query and cache the result from the previous query in the mem_query function?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're right, removed this function and reused the result from the earlier query

return UCS_MEM_FLAG_REGISTRABLE;
}

if (!md->config.dmabuf_supported) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why? what if it is cuda_managed memory?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cuda_managed is handled above

Comment thread src/ucs/memory/memtype_cache.h Resolved
Comment thread test/gtest/ucp/test_ucp_proto.cc Resolved
Comment thread test/gtest/ucp/test_ucp_rma.cc Resolved
Don't query twice the pointer for asyncness
Refactoring tests
@brminich
brminich merged commit b6b8531 into openucx:master Jun 23, 2026
160 checks passed
GenericRikka pushed a commit to GenericRikka/ucx-fork that referenced this pull request Jun 24, 2026
* UCP/UCT/UCS: Add memory registration flags

Add memory flags to UCS memory information and propagate them through UCT mem_query_v2 so providers can report whether a memory region is safe to register.

Use the CAN_REGISTER flag in UCP memory registration and protocol selection paths to avoid selecting registration-dependent protocols for non-registerable memory. Mark CUDA async allocations classified as CUDA managed as non-registerable, and require CAN_REGISTER for IB memory domains that need registration.

Add focused gtests for memtype cache flag handling, IB registration failure for CUDA async memory, and UCP protocol filtering.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants