mirror of
https://github.com/NVIDIA/cuda-samples.git
synced 2024-12-01 18:49:17 +08:00
60 lines
2.3 KiB
Markdown
60 lines
2.3 KiB
Markdown
Unified Virtual Memory Lite (UVM-lite) From NVVM IR
|
|
===================================================
|
|
|
|
This document is for the programming language and compiler
|
|
implementers who target NVVM IR and plan to support Unified Virtual
|
|
Memory Lite (UVM-lite) in their language. It provides the low-level
|
|
details related to supporting kernel launches at the NVVM IR level.
|
|
|
|
This document assumes the CUDA runtime is used. For the limits and
|
|
restrictions, please refer to the official CUDA documents.
|
|
|
|
Allocating a variable in the unified virtual memory environment.
|
|
----------------------------------------------------------------
|
|
|
|
In a system that supports unified virtual memory environment, a
|
|
variable can be allocated at a location where host and other devices
|
|
in the system can reference the variable directly. We call such a
|
|
variable a managed variable and say that the variable has the
|
|
managed attribute or is managed. The attribute can be specified
|
|
using a metadata.
|
|
|
|
@xxx = internal addrspace(1) global i32 10, align 4
|
|
|
|
...
|
|
|
|
!1 = !{i32 addrspace(1)* @xxx, !"managed", i32 1}
|
|
|
|
A global variable, e.g., @xxx, can be defined and used as usual, but
|
|
here we have a metadata that specifies the managed attributes. (Note
|
|
that the attribute can only be used with variables in the global
|
|
address space.)
|
|
|
|
Accessing a managed variable in the host
|
|
----------------------------------------
|
|
|
|
To access a managed variable defined in the NVVM IR code, we should
|
|
retrieve a device pointer first, which can be done using cuModuleGetGlobal().
|
|
|
|
CUdeviceptr devp_xxx; // device pointer to xxx
|
|
size_t size_xxx; // size of xxx
|
|
result = cuModuleGetGlobal(&devp_xxx, &size_xxx, hModule, "xxx");
|
|
|
|
Whether or not the pointer points to managed memory may be queried
|
|
by calling cuPointerGetAttribute() with the pointer attribute
|
|
CU_POINTER_ATTRIBUTE_IS_MANAGED.
|
|
|
|
unsigned int attrVal;
|
|
result = cuPointerGetAttribute(&attrVal, CU_POINTER_ATTRIBUTE_IS_MANAGED, devp_xxx);
|
|
// result will be 1 if the pointer is managed or zero otherwise.
|
|
|
|
It is safe to use cuPointerGetAttribute to get the host pointers,
|
|
since the device pointers are opaque.
|
|
|
|
void *host_ptr_xxx;
|
|
int *p_xxx;
|
|
|
|
result = cuPointerGetAttribute(&host_ptr_xxx, CU_POINTER_ATTRIBUTE_HOST_POINTER, devp_xxx);
|
|
p_xxx = (int *)devp_xxx;
|
|
*p_xxx += 1; // read & write without explicit copying
|