0 overall
1️⃣ cuMemAddressReserve → 2️⃣ cuMemCreate → 3️⃣ cuMemMap → 4️⃣ cuMemSetAccess → 5️⃣ cuMemUnmap → 6️⃣ cuMemRelease → 7️⃣ cuMemAddressFree (其中 cuMemExportToShareableHandle / cuMemImportFromShareableHandle 为可选,用于跨进程共享;多播内存 cuMulticast* 相关为可选分支)
1 functions
1.1 cuMemGetAllocationGranularity
CUresult cuMemGetAllocationGranularity ( size_t* granularity, const CUmemAllocationProp* prop, CUmemAllocationGranularity_flags option )
计算最小或者推荐的粒度。
- granularity 输出粒度。
- prop 要查询的内存分配属性。
- option 指定要返回的粒度类型(最小或推荐)。
根据指定的分配属性计算最小或推荐粒度,并将结果返回到 granularity。粒度值用于保证分配、映射、对齐参数的正确性。通常用于确定 size、offset 或 ptr 是否符合对齐要求。
1.2 cuMemAddressReserve
CUresult cuMemAddressReserve ( CUdeviceptr* ptr, size_t size, size_t alignment, CUdeviceptr addr, unsigned long long flags )
预留一段虚拟地址空间。
- ptr 返回的虚拟地址空间起始地址指针。
- size 请求的虚拟地址区间大小。
- alignment 请求的虚拟地址区间对齐要求。
- addr 地址提示(可为 0,驱动会自动选择)。
- flags 当前未使用,必须为 0。
该函数根据给定参数保留一段虚拟地址空间,并返回起始地址到 ptr。此 API 仅在支持 统一虚拟寻址(UVA) 的系统上可用。size 和 addr 参数必须是主机页大小(通常为 4KB)的整数倍;alignment 必须是 2 的幂,或为 0(表示默认对齐)。如果 addr 为 0,则驱动程序自动选择分配地址;如果非 0,则视为地址提示。
1.3 cuMemCreate
CUresult cuMemCreate ( CUmemGenericAllocationHandle* handle, size_t size, const CUmemAllocationProp* prop, unsigned long long flags )
根据给定属性创建一个 CUDA 内存分配,并返回一个通用内存句柄。
- handle 返回的通用内存句柄。所有对该分配的操作都通过此句柄执行。
- size 请求的分配大小。
- prop 描述要创建的分配属性的结构体。
- flags 目前保留,必须为 0。
在由 prop 指定的目标设备上创建一段内存分配。此分配不会自动映射到任何设备或主机地址空间。创建的通用内存句柄可通过 cuMemMap 映射到调用进程的虚拟地址空间中。该句柄不能直接跨进程传递,若要共享,需通过 cuMemExportToShareableHandle 导出。 分配的大小必须是cuMemGetAllocationGranularity 返回的最小粒度(使用CU_MEM_ALLOC_GRANULARITY_MINIMUM)的整数倍。 要在 CPU 上创建内存分配:
- 若不针对特定 NUMA 节点,设置 CUmemLocation::type = CU_MEM_LOCATION_TYPE_HOST;
- 若针对特定 NUMA 节点,设置 CUmemLocation::type = CU_MEM_LOCATION_TYPE_HOST_NUMA 并指定 NUMA ID;
- CUmemLocation::id 在 HOST 模式下会被忽略;
- HOST 分配不可用于 IPC,CUmemAllocationProp::requestedHandleTypes 必须为 0,否则报错。
要支持 Fabric 共享内存(CU_MEM_HANDLE_TYPE_FABRIC),系统需满足:
- 驱动创建 /dev/nvidia-caps-imex-channels 设备并在 /proc/devices 中列出;
- 应用用户能访问至少一个 IMEX 通道文件。
IMEX 通道基于用户隔离:同一用户下的进程可共享内存,不同用户需不同通道。
通道文件路径为 /dev/nvidia-caps-imex-channels/channel*,可用 Linux mknod 命令手动创建,例如:
mknod /dev/nvidia-caps-imex-channels/channel0 c <major_number> 0若 allocFlags.usage 包含 CU_MEM_CREATE_USAGE_TILE_POOL,则该内存分配仅用于稀疏 CUDA 数组或 mipmapped 数组的 tile 池。
1.4 cuMemMap
CUresult cuMemMap ( CUdeviceptr ptr, size_t size, size_t offset, CUmemGenericAllocationHandle handle, unsigned long long flags )
把物理内存分配映射到预留的虚拟地址区间内。
- ptr 要映射的虚拟地址起点(必须由 cuMemAddressReserve 保留)。
- size 映射大小。
- offset 物理内存句柄内的偏移(目前必须为 0)。
- handle 物理内存分配句柄。
- flags 保留字段,必须为 0。
把 handle表示的物理内存[offset, offset + size]映射到[ptr, ptr + size]。 ptr必须得是cuMemAddressReserve 预留出来的空间。size, offset必须是cuMemGetAllocationGranularity返回的最小粒度的整数倍。
如果 handle表示multicast object,则所有参数需满足由 cuMulticastGetGranularity 返回的粒度要求。
注:
- cuMemMap 仅执行“映射”操作,还需要调用 cuMemSetAccess 使该地址范围对设备可访问;
- 若 handle 是跨进程导入的,必须先 cuMemMap,再调用 cuMemSetAccess;
- cuMemMap 不能覆盖已有映射。
1.5 cuMemSetAccess
CUresult cuMemSetAccess ( CUdeviceptr ptr, size_t size, const CUmemAccessDesc* desc, size_t count )
为指定VA区间设置访问权限,跨进程的时候就要调这个了。
- ptr 虚拟地址区间起点。
- size 虚拟地址区间长度。
- desc 描述访问属性的 CUmemAccessDesc 数组。
- count 表示desc 数组的元素数量。
对VA区间[ptr, ptr + size]设置在不同GPU上访问的权限。范围是 cuMemMap映射的完整区间。当CUmemAccessDesc::CUmemLocation::type是 CU_MEM_LOCATION_TYPE_HOST_NUMA,那么CUmemAccessDesc::CUmemLocation::id会被忽略。对于multicast object,这里的ptr和size需要和 cuMulticastGetGranularity 返回的最小粒度对齐。
1.6 cuMemExportToShareableHandle and cuMemImportFromShareableHandle
CUresult cuMemExportToShareableHandle ( void* shareableHandle, CUmemGenericAllocationHandle handle, CUmemAllocationHandleType handleType, unsigned long long flags )
将 CUDA 内存分配导出为可共享句柄,以便其他进程导入使用。
- shareableHandle 存储导出后共享句柄的内存地址。
- handle 要导出的 CUDA 内存句柄。
- handleType 共享句柄类型(定义输出参数的类型与大小)。
- 根据给定的 CUDA 内存句柄,生成一个可跨进程共享的句柄。
- 接收方进程可使用 cuMemImportFromShareableHandle 将其重新导入为 CUDA 内存句柄,再使用 cuMemMap 进行映射。
- 共享句柄的具体实现和传递方式取决于 handleType。
- 当所有共享句柄被关闭且原始分配被释放后,内存将归还操作系统。之后继续使用该 CUDA 句柄将导致未定义行为。该 API 可与 Vulkan、OpenGL 等图形 API 配合,用于导入共享内存。
CUresult cuMemImportFromShareableHandle ( CUmemGenericAllocationHandle* handle, void* osHandle, CUmemAllocationHandleType shHandleType )
用共享handle导入一个CUDA内存分配。
- handle 返回的 CUDA 内存句柄。
- osHandle 表示要导入的共享内存分配的操作系统句柄。
- shHandleType 导出句柄的类型(对应导出时的 handleType)。
把另一个progress的shared handle变成自己的CUDA内存handle。若 shHandleType 为 CU_MEM_HANDLE_TYPE_FABRIC 且导入者进程没有访问相同 IMEX 通道的权限,则返回 CUDA_ERROR_NOT_PERMITTED。 此外,不保证同一个共享句柄在不同进程中得到的 CUDA handle 值相同。
1.7 cuMemRetainAllocationHandle
CUresult cuMemRetainAllocationHandle ( CUmemGenericAllocationHandle* handle, void* addr )
之前映射过的地址VA地址(addr),返回对应的 CUDA 内存句柄(handle)。
1.8 cuMemMapArrayAsync
在 GPU 上异步执行映射(map)或取消映射(unmap)操作,作用于稀疏 CUDA 数组(Sparse CUDA Arrays)和稀疏多级 Mipmapped 数组。貌似我用不着。
1.9 cuMemUnmap, cuMemRelease, cuMemAddressFree
CUresult cuMemUnmap(
CUdeviceptr ptr,
size_t size
)
取消指定虚拟地址区间的物理内存映射。
- ptr 要取消映射的虚拟地址起点。
- size 区间大小。
CUresult cuMemRelease(
CUmemGenericAllocationHandle handle
)
释放由 cuMemCreate 创建的内存句柄。
CUresult cuMemAddressFree (CUdeviceptr ptr, size_t size)
释放由 cuMemAddressReserve 预留的虚拟地址区间。size 必须与原始保留时的大小完全匹配,ptr 必须等于 cuMemAddressReserve 返回的地址。