Repository navigation
[FEA]: cuda.core sample for Grace Hopper memory (ATS, host/GPU NUMA, C2C) #3219
Description
Is this a duplicate?
- I confirmed there appear to be no duplicate issues for this request and that I agree to the Code of Conduct
Area
cuda.core
Is your feature request related to a problem? Please describe.
cuda.core already exposes the Grace Hopper memory topology:
Device.propertieshasnuma_config,numa_id,host_numa_id,pageable_memory_accessandpageable_memory_access_uses_host_page_tables.system.Devicehasis_c2c_enabled.PinnedMemoryResourceOptionstakesnuma_id.ManagedBuffer.prefetchtakesHost(numa_id=...).
The tests only check the types these return, and no sample shows what they mean on a system where they matter:
memoryResourcesuses host-NUMA pinning.- The bindings sample
systemWideAtomicsuses pageable access. - Nothing shows ATS, meaning pageable memory served through the host page tables, or a C2C link.
Describe the solution you'd like
A new sample, samples/cuda_core/graceHopperMemory, following the sample conventions: its own directory, README.md, requirements.txt, and waiver exit code 2.
- Topology: print the properties above, plus
system.Device.is_c2c_enabled. - ATS:
- A kernel reads and writes a plain NumPy array (system-allocated, pageable) in place, with no copy, and the result is checked.
- If
pageable_memory_access_uses_host_page_tablesis False, the sample exits with the waiver code.
- Read bandwidth: time the same read kernel over three memory types: pinned memory bound to
host_numa_id(PinnedMemoryResourceOptions(numa_id=...)), pageable (ATS), and device memory. - Managed memory: time a kernel on a
ManagedMemoryResourcebuffer afterprefetch(Host(numa_id=host_numa_id)), and again afterprefetch(device). - README: example output measured on GH200, not theoretical numbers.
Describe alternatives you've considered
Extend memoryResources. It is already long, and the ATS and C2C parts only run on Grace-based systems, so a separate sample with its own waiver seems cleaner.
Additional context
A probe with the same steps already runs.
On an x86 B300 host:
pageable_memory_accessis True, through HMM.pageable_memory_access_uses_host_page_tablesis False.is_c2c_enabledis False.- So the sample would correctly exit 2 there.
On GH200 (cc 9.0, driver 595.58.03, CUDA 13.4.2):
numa_config= 1,numa_id= 1,host_numa_id= 0.pageable_memory_access,pageable_memory_access_uses_host_page_tables,concurrent_managed_accessandis_c2c_enabledare all True.- The kernel on the plain NumPy array returns the correct result.
One read-sum kernel over 1 GiB, median of 10 launches, three runs:
| Memory | GB/s |
|---|---|
| Pinned, host NUMA node 0 | 339–345 |
| Pageable NumPy array (ATS) | 224–225 |
| Device | 2386–2417 |
Managed, first kernel after prefetch(Host(numa_id=0)) |
5.1–5.4 (about 200 ms) |
Managed, after prefetch(device) |
2380–2393 |
The managed host row is the one the sample would explain. Managed memory that sits on the host is migrated on the GPU's first touch, so that first kernel pays for moving 1 GiB. The same bytes as a pageable NumPy array are read in place over C2C at about 224 GB/s.
The kernel is a plain grid-stride read with one atomic per block, not a tuned copy, so the device number is below HBM peak. The sample would present these as relative numbers.
Before writing the sample: would you take it? Is samples/cuda_core/ the right place, and are CuPy-free kernels via Program preferred, as in the other samples?
Activity