6.35. 绿色上下文
本节介绍 CUDA 驱动程序中用于创建和操作绿色上下文的 API。绿色上下文是传统上下文的轻量级替代方案,能够传入一组应使用其初始化的资源。这允许开发人员表示 GPU 的不同空间分区,为其配置资源,并通过 CUDA 公开的相同编程模型(流、内核启动等)来定位它们。
使用这些新 API 集合主要有 4 个步骤。
-
(1) 从初始资源集开始,例如通过 cuDeviceGetDevResource。目前仅支持 SM 类型。
-
(2) 通过将此资源集作为输入提供给分区 API 来对其进行分区,例如:cuDevSmResourceSplitByCount。
-
(3) 通过 cuDevResourceGenerateDesc 创建描述符来最终确定资源规范。
-
(4) 通过 cuGreenCtxCreate 配置资源并创建绿色上下文。
对于CU_DEV_RESOURCE_TYPE_SM,创建的分区具有最小 SM 计数要求,通常向上舍入并将提供的 minCount 与 cuDevSmResourceSplitByCount 对齐。以下是每种架构的指南,可能会有所更改
-
在计算架构 6.X 上:最小计数为 1 个 SM。
-
在计算架构 7.X 上:最小计数为 2 个 SM,并且必须是 2 的倍数。
-
在计算架构 8.X 上:最小计数为 4 个 SM,并且必须是 2 的倍数。
-
在计算架构 9.0+ 上:最小计数为 8 个 SM,并且必须是 8 的倍数。
将来,可以提供标志来权衡功能和性能特性与更精细的 SM 分区。
即使绿色上下文具有不相交的 SM 分区,也不能保证在其中启动的内核将并发运行或具有向前进度保证。这是由于其他资源(如硬件连接,请参阅 CUDA_DEVICE_MAX_CONNECTIONS)可能导致依赖性。此外,在某些情况下,工作负载可能在比配置的更多的 SM 上运行(但绝不会更少)。以下是可能表现出这种行为的两种情况
-
在 Volta+ MPS 上:当CUDA_MPS_ACTIVE_THREAD_PERCENTAGE被使用时,用于运行内核的 SM 集合可以扩展到用于 MPS 客户端的 SM 值。
-
在计算架构 9.x 上:当加载具有动态并行性 (CDP) 的模块时,未来在绿色上下文中运行的所有内核可能会使用和共享额外的 2 个 SM 集合。
类
类型定义
- typedef CUdevResourceDesc_st * CUdevResourceDesc
枚举
- enum CUdevResourceType
函数
- CUresult cuCtxFromGreenCtx ( CUcontext* pContext, CUgreenCtx hCtx )
- 将绿色上下文转换为主上下文。
- CUresult cuCtxGetDevResource ( CUcontext hCtx, CUdevResource* resource, CUdevResourceType type )
- 获取上下文资源。
- CUresult cuDevResourceGenerateDesc ( CUdevResourceDesc* phDesc, CUdevResource* resources, unsigned int nbResources )
- 生成资源描述符。
- CUresult cuDevSmResourceSplitByCount ( CUdevResource* result, unsigned int* nbGroups, const CUdevResource* input, CUdevResource* remaining, unsigned int useFlags, unsigned int minCount )
- 拆分 CU_DEV_RESOURCE_TYPE_SM 资源。
- CUresult cuDeviceGetDevResource ( CUdevice device, CUdevResource* resource, CUdevResourceType type )
- 获取设备资源。
- CUresult cuGreenCtxCreate ( CUgreenCtx* phCtx, CUdevResourceDesc desc, CUdevice dev, unsigned int flags )
- 使用指定的资源集创建绿色上下文。
- CUresult cuGreenCtxDestroy ( CUgreenCtx hCtx )
- 销毁绿色上下文。
- CUresult cuGreenCtxGetDevResource ( CUgreenCtx hCtx, CUdevResource* resource, CUdevResourceType type )
- 获取绿色上下文资源。
- CUresult cuGreenCtxRecordEvent ( CUgreenCtx hCtx, CUevent hEvent )
- 记录事件。
- CUresult cuGreenCtxStreamCreate ( CUstream* phStream, CUgreenCtx greenCtx, unsigned int flags, int priority )
- 创建用于绿色上下文中的流。
- CUresult cuGreenCtxWaitEvent ( CUgreenCtx hCtx, CUevent hEvent )
- 使绿色上下文等待事件。
- CUresult cuStreamGetGreenCtx ( CUstream hStream, CUgreenCtx* phCtx )
- 查询与流关联的绿色上下文。
类型定义
- typedef CUdevResourceDesc_st * CUdevResourceDesc
-
不透明的描述符句柄。描述符封装了多个已创建和配置的资源。通过 cuDevResourceGenerateDesc 创建
枚举
函数
- CUresult cuCtxFromGreenCtx ( CUcontext* pContext, CUgreenCtx hCtx )
-
将绿色上下文转换为主上下文。
参数
- pContext
- 返回的具有绿色上下文资源的主上下文
- hCtx
- 要转换的绿色上下文
返回值
CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED, CUDA_ERROR_INVALID_CONTEXT, CUDA_ERROR_INVALID_VALUE
描述
该 API 将绿色上下文转换为在pContext中返回的主上下文。请务必注意,转换后的上下文pContext是正常的主上下文,但具有指定绿色上下文的资源hCtx。转换后,它可用于通过 cuCtxSetCurrent 或任何接受 CUcontext 参数的 CUDA API 将上下文设置为当前上下文。
用户应在调用任何接受 CUcontext 的 CUDA API 之前调用此 API。否则将导致 API 返回 CUDA_ERROR_INVALID_CONTEXT。
另请参阅
- CUresult cuCtxGetDevResource ( CUcontext hCtx, CUdevResource* resource, CUdevResourceType type )
-
获取上下文资源。
参数
- hCtx
- - 获取资源的上下文
- resource
- - 指向 CUdevResource 结构的输出指针
- type
- - 要检索的资源类型
- CUresult cuDevResourceGenerateDesc ( CUdevResourceDesc* phDesc, CUdevResource* resources, unsigned int nbResources )
-
生成资源描述符。
参数
- phDesc
- - 输出描述符
- resources
- - 要包含在描述符中的资源数组
- nbResources
- - 传入的资源数量resources
返回值
CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED, CUDA_ERROR_INVALID_VALUE, CUDA_ERROR_INVALID_RESOURCE_TYPE, CUDA_ERROR_INVALID_RESOURCE_CONFIGURATION
描述
使用在resources中指定的一组资源生成单个资源描述符。生成的资源描述符对于通过 cuGreenCtxCreate API 创建绿色上下文是必需的。可以传入相同类型的资源,前提是它们满足如下所述的要求。
成功的 API 调用必须具有
-
描述符的有效输出指针以及有效的phDesc指针数组,并传入数组大小resources。如果在nbResources中提供了多个资源,则它们来自的设备必须相同,否则将返回 CUDA_ERROR_INVALID_RESOURCE_CONFIGURATION。如果在resources中提供了多个资源,并且它们的类型为 CU_DEV_RESOURCE_TYPE_SM,则它们必须是同一拆分 API 实例的输出(无论是resourcesresult还是remaining),否则将返回 CUDA_ERROR_INVALID_RESOURCE_CONFIGURATION。cuDevSmResourceSplitByCount
表示的上下文可用的资源。注意:32 位平台不支持此 API。
另请参阅
CUresult cuDevSmResourceSplitByCount ( CUdevResource* result, unsigned int* nbGroups, const CUdevResource* input, CUdevResource* remaining, unsigned int useFlags, unsigned int minCount )
- 拆分
-
资源。CU_DEV_RESOURCE_TYPE_SM-
CUdevResource
参数
- 还是
- - Output array of资源的输出数组。可以为 NULL 以查询组的数量。nbGroups
- - 这是一个指针,指定将要创建或应该创建的组的数量,如下所述。
- input
- - 要拆分的输入 SM 资源。必须是有效的
- 资源。CU_DEV_RESOURCE_TYPE_SMremaining
- ),否则将返回 CUDA_ERROR_INVALID_RESOURCE_CONFIGURATION。
- - 如果输入资源无法在- 这是一个指针,指定将要创建或应该创建的组的数量,如下所述。之间干净地拆分,则剩余部分将放在此处。如果用户不需要剩余集合,则可以省略(NULL)。
- useFlags
- - 标志,指定如何使用这些分区或在拆分输入时遵守哪些约束。零对于默认行为有效。
- minCount
- - 所需的最小 SM 数
返回值
CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED, CUDA_ERROR_INVALID_DEVICE, CUDA_ERROR_INVALID_VALUE, CUDA_ERROR_INVALID_RESOURCE_TYPE, CUDA_ERROR_INVALID_RESOURCE_CONFIGURATION
描述
资源。CU_DEV_RESOURCE_TYPE_SM资源拆分为- 这是一个指针,指定将要创建或应该创建的组的数量,如下所述。,遵守在minCount中指定的最小 SM 计数和在useFlags中的使用标志。如果还是为 NULL,则 API 模拟拆分并提供将在- 这是一个指针,指定将要创建或应该创建的组的数量,如下所述。中创建的组的数量。否则,- 这是一个指针,指定将要创建或应该创建的组的数量,如下所述。必须指向还是中的元素数量,并且在返回时,API 将覆盖- 这是一个指针,指定将要创建或应该创建的组的数量,如下所述。为实际创建的数量。组写入还是. - 这是一个指针,指定将要创建或应该创建的组的数量,如下所述。中的数组,如果需要较少数量的组,则可以小于总数。
此 API 用于在空间上划分输入资源。输入资源需要来自 cuDeviceGetDevResource、cuCtxGetDevResource 或 cuGreenCtxGetDevResource 之一。API 的一个限制是,如果不首先创建描述符和使用该描述符的绿色上下文,则无法再次拆分输出结果。
在创建组时,API 将考虑输入资源的性能和功能特性,并保证拆分将创建一组不相交的对称分区。由于集群要求或 minCount 的对齐和粒度要求,这可能会导致创建的组少于纯粹将总 SM 计数除以minCount。
中的remainder集合不具有与还是中的组相同的功能或性能保证。应仔细计划其使用,并且不鼓励将来对remainder集合进行分区。
支持以下标志
-
CU_DEV_SM_RESOURCE_SPLIT_IGNORE_SM_COSCHEDULING:降低最小 SM 计数和对齐,并将每个 SM 视为独立于其层次结构。这允许更精细的分区,但以高级功能(例如计算能力 9.0+ 上的大型集群)为代价。
-
CU_DEV_SM_RESOURCE_SPLIT_MAX_POTENTIAL_CLUSTER_SIZE:仅限计算能力 9.0+。尝试创建可能允许最大尺寸线程集群的组。可以使用 cuOccupancyMaxPotentialClusterSize 在绿色上下文创建后查询此项。
成功的 API 调用必须具有以下任一条件
-
大小在还是中传递的有效- 这是一个指针,指定将要创建或应该创建的组的数量,如下所述。指针数组,其中- 要拆分的输入 SM 资源。必须是有效的的类型为CU_DEV_RESOURCE_TYPE_SM。minCount的值必须介于 0 和在- 要拆分的输入 SM 资源。必须是有效的. ),否则将返回 CUDA_ERROR_INVALID_RESOURCE_CONFIGURATION。中指定的 SM 计数之间。
-
可能为 NULL。还是中传入的 NULL,以及- 这是一个指针,指定将要创建或应该创建的组的数量,如下所述。中的有效整数指针,且- 要拆分的输入 SM 资源。必须是有效的的类型为CU_DEV_RESOURCE_TYPE_SM。minCount的值必须介于 0 和在- 要拆分的输入 SM 资源。必须是有效的. ),否则将返回 CUDA_ERROR_INVALID_RESOURCE_CONFIGURATION。可能为 NULL。这将查询 API 将创建的组的数量。
表示的上下文可用的资源。注意:32 位平台不支持此 API。
另请参阅
cuGreenCtxGetDevResource、cuCtxGetDevResource、cuDeviceGetDevResource
- CUresult cuDeviceGetDevResource ( CUdevice device, CUdevResource* resource, CUdevResourceType type )
-
获取设备资源。
参数
- device
- - 获取资源的设备
- resource
- - 指向 CUdevResource 结构的输出指针
- type
- - 要检索的资源类型
返回值
CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED, CUDA_ERROR_INVALID_RESOURCE_TYPE, CUDA_ERROR_INVALID_VALUE, CUDA_ERROR_INVALID_DEVICE
描述
获取type设备可用的资源device。这通常可能是进一步分区或配置资源的起点。
表示的上下文可用的资源。注意:32 位平台不支持此 API。
另请参阅
- CUresult cuGreenCtxCreate ( CUgreenCtx* phCtx, CUdevResourceDesc desc, CUdevice dev, unsigned int flags )
-
使用指定的资源集创建绿色上下文。
参数
- phCtx
- - 绿色上下文的输出句柄指针
- desc
- - 通过 cuDevResourceGenerateDesc 生成的描述符,其中包含要使用的一组资源
- dev
- - 在其上创建绿色上下文的设备。
- flags
- - 支持的绿色上下文创建标志之一。CU_GREEN_CTX_DEFAULT_STREAM是必需的。
返回值
CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED, CUDA_ERROR_INVALID_DEVICE, CUDA_ERROR_INVALID_VALUE, CUDA_ERROR_NOT_SUPPORTED, CUDA_ERROR_OUT_OF_MEMORY
描述
此 API 使用描述符desc中指定的资源创建绿色上下文,并在由phCtx表示的句柄中返回它。此 API 将在设备dev上保留主上下文,该主上下文将在绿色上下文销毁时释放。建议在此 API 之前激活主上下文,以避免多次触发主上下文初始化和反初始化的巨大开销。
API 不会设置绿色上下文为当前上下文。为了将其设置为当前上下文,您需要通过首先使用 cuCtxFromGreenCtx 将绿色上下文转换为 CUcontext,然后调用 cuCtxSetCurrent / cuCtxPushCurrent 显式地将其设置为当前上下文。应该注意的是,一个绿色上下文在同一时间只能是单个线程的当前上下文。没有内部同步机制来使从多个线程访问同一绿色上下文的 API 调用能够正常工作。
表示的上下文可用的资源。注意:32 位平台不支持此 API。
支持的标志有
-
CU_GREEN_CTX_DEFAULT_STREAM:创建一个默认流以在绿色上下文内部使用。必需。
另请参阅
cuGreenCtxDestroy, cuCtxFromGreenCtx, cuCtxSetCurrent, cuCtxPushCurrent, cuDevResourceGenerateDesc, cuDevicePrimaryCtxRetain, cuCtxCreate, cuCtxCreate_v3
- CUresult cuGreenCtxDestroy ( CUgreenCtx hCtx )
-
销毁绿色上下文。
参数
- hCtx
- - 要销毁的绿色上下文
返回值
CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED, CUDA_ERROR_INVALID_CONTEXT, CUDA_ERROR_CONTEXT_IS_DESTROYED
描述
销毁绿色上下文,释放为此绿色上下文创建设备的的主上下文。为此绿色上下文配置的任何资源(最初通过资源描述符可用)也将被释放。
另请参阅
- CUresult cuGreenCtxGetDevResource ( CUgreenCtx hCtx, CUdevResource* resource, CUdevResourceType type )
-
获取绿色上下文资源。
参数
- hCtx
- - 要获取资源的绿色上下文
- resource
- - 指向 CUdevResource 结构的输出指针
- type
- - 要检索的资源类型
- CUresult cuGreenCtxRecordEvent ( CUgreenCtx hCtx, CUevent hEvent )
-
记录一个事件。
参数
- hCtx
- - 要记录事件的绿色上下文
- hEvent
- - 要记录的事件
返回值
CUDA_SUCCESSCUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED, CUDA_ERROR_INVALID_CONTEXT, CUDA_ERROR_INVALID_HANDLE, CUDA_ERROR_STREAM_CAPTURE_UNSUPPORTED
描述
捕获在hEvent绿色上下文的所有活动hCtx在此调用时。hEvent中的有效整数指针,且hCtx必须来自相同的主上下文,否则将返回 CUDA_ERROR_INVALID_HANDLE。诸如 cuEventQuery() 或 cuGreenCtxWaitEvent() 之类的调用将检查或等待捕获的工作完成。在调用之后使用hCtx不会修改hEvent.
注意如果指定的绿色上下文hCtx具有处于捕获模式的流,则 API 将返回 CUDA_ERROR_STREAM_CAPTURE_UNSUPPORTED。在这种情况下,此调用将使所有冲突的捕获无效。
另请参阅
cuGreenCtxWaitEvent, cuEventRecord, cuCtxRecordEvent, cuCtxWaitEvent
- CUresult cuGreenCtxStreamCreate ( CUstream* phStream, CUgreenCtx greenCtx, unsigned int flags, int priority )
-
为绿色上下文创建流以供使用。
参数
- phStream
- - 返回新创建的流
- greenCtx
- - 为其创建流的绿色上下文
- flags
- - 流创建的标志。CU_STREAM_NON_BLOCKING必须指定。
- priority
- - 流优先级。数字越小表示优先级越高。有关可以传递的有意义的流优先级的更多信息,请参阅 cuCtxGetStreamPriorityRange。
返回值
CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED, CUDA_ERROR_INVALID_CONTEXT, CUDA_ERROR_INVALID_VALUE, CUDA_ERROR_OUT_OF_MEMORY
描述
为指定的绿色上下文创建流greenCtx并在phStream中返回句柄。可以通过调用 cuStreamDestroy() 来销毁该流。请注意,API 会忽略调用线程的当前上下文,并在指定的绿色上下文中创建流greenCtx.
支持的flags值有
-
CU_STREAM_NON_BLOCKING:必须指定此项。它表示在创建的流中运行的工作可以与默认流中的工作并发运行,并且创建的流不应与默认流执行隐式同步。
指定priority会影响流中工作的调度优先级。优先级为尽可能优先运行优先级较高的工作提供了一个提示,但不会抢占已经在运行的工作,也不会对执行顺序提供任何其他功能保证。priority遵循数字越小表示优先级越高的约定。“0”表示默认优先级。可以使用 cuCtxGetStreamPriorityRange 查询有意义的数字优先级范围。如果指定的优先级超出 cuCtxGetStreamPriorityRange 返回的数值范围,它将自动钳制到范围中的最低或最高数字。
注意-
请注意,此函数也可能返回先前异步启动的错误代码。
-
在当前实现中,只有在优先级流中启动的计算内核会受到流优先级的影响。流优先级对主机到设备和设备到主机的内存操作没有影响。
另请参阅
cuStreamDestroy, cuGreenCtxCreatecuStreamCreate, cuStreamGetPriority, cuCtxGetStreamPriorityRange, cuStreamGetFlags, cuStreamGetDevicecuStreamWaitEvent, cuStreamQuery, cuStreamSynchronize, cuStreamAddCallback, cudaStreamCreateWithPriority
- CUresult cuGreenCtxWaitEvent ( CUgreenCtx hCtx, CUevent hEvent )
-
使绿色上下文等待事件。
参数
- hCtx
- - 要等待的绿色上下文
- hEvent
- - 要等待的事件
返回值
CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED, CUDA_ERROR_INVALID_CONTEXT, CUDA_ERROR_INVALID_HANDLE, CUDA_ERROR_STREAM_CAPTURE_UNSUPPORTED
描述
使所有未来提交到绿色上下文的工作hCtx等待hEvent中捕获的所有工作完成。同步将在设备上执行,并且不会阻止调用 CPU 线程。有关事件捕获内容的详细信息,请参阅 cuGreenCtxRecordEvent() 或 cuEventRecord()。
注意-
hEvent可能来自与hCtx.
-
不同的上下文或设备。如果指定的事件hEvent是正在进行的捕获序列的一部分,或者如果指定的绿色上下文hCtx具有处于捕获模式的流,则 API 将返回 CUDA_ERROR_STREAM_CAPTURE_UNSUPPORTED 并使捕获无效。
另请参阅
cuGreenCtxRecordEvent, cuStreamWaitEventcuCtxRecordEvent, cuCtxWaitEvent
- CUresult cuStreamGetGreenCtx ( CUstream hStream, CUgreenCtx* phCtx )
-
查询与流关联的绿色上下文。
参数
- hStream
- - 要查询的流的句柄
- phCtx
- - 返回与流关联的绿色上下文
返回值
CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED, CUDA_ERROR_INVALID_CONTEXT, CUDA_ERROR_INVALID_HANDLE,
描述
返回与流关联的 CUDA 绿色上下文,如果流未与任何绿色上下文关联,则返回 NULL。
流句柄hStream可以引用以下任何一项
-
通过任何 CUDA 驱动程序 API(例如 cuStreamCreate, cuStreamCreateWithPriority 和 cuGreenCtxStreamCreate)或其运行时 API 等效项(例如 cudaStreamCreate, cudaStreamCreateWithFlags 和 cudaStreamCreateWithPriority)创建的流。如果在流创建期间,调用线程中处于活动状态的上下文是通过 cuCtxFromGreenCtx 获取的,则该绿色上下文将在phCtx中创建的组的数量。否则,*phCtx中返回,否则设置为 NULL。
-
特殊流,例如 NULL 流或 CU_STREAM_LEGACY。在这种情况下,如果调用线程中处于活动状态的上下文是通过 cuCtxFromGreenCtx 获取的,则返回该绿色上下文。否则,*phCtx中返回,否则设置为 NULL。
注意请注意,此函数也可能返回先前异步启动的错误代码。
另请参阅
cuStreamDestroy, cuStreamCreate, cuStreamCreateWithPriority, cuStreamGetCtx_v2, cuGreenCtxStreamCreate, cuStreamGetPriority, cuStreamGetFlags, cuStreamGetDevicecuStreamWaitEvent, cuStreamQuery, cuStreamSynchronize, cuStreamAddCallback, cudaStreamCreate, cudaStreamCreateWithFlags