6.20. 外部资源互操作性

本节介绍底层CUDA驱动应用程序编程接口的外部资源互操作功能。

Functions

CUresult cuDestroyExternalMemory ( CUexternalMemory extMem )
Destroys an external memory object.
CUresult cuDestroyExternalSemaphore ( CUexternalSemaphore extSem )
Destroys an external semaphore.
CUresult cuExternalMemoryGetMappedBuffer ( CUdeviceptr* devPtr, CUexternalMemory extMem, const CUDA_EXTERNAL_MEMORY_BUFFER_DESC* bufferDesc )
Maps a buffer onto an imported memory object.
CUresult cuExternalMemoryGetMappedMipmappedArray ( CUmipmappedArray* mipmap, CUexternalMemory extMem, const CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC* mipmapDesc )
Maps a CUDA mipmapped array onto an external memory object.
CUresult cuImportExternalMemory ( CUexternalMemory* extMem_out, const CUDA_EXTERNAL_MEMORY_HANDLE_DESC* memHandleDesc )
Imports an external memory object.
CUresult cuImportExternalSemaphore ( CUexternalSemaphore* extSem_out, const CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC* semHandleDesc )
Imports an external semaphore.
CUresult cuSignalExternalSemaphoresAsync ( const CUexternalSemaphore* extSemArray, const CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS* paramsArray, unsigned int  numExtSems, CUstream stream )
Signals a set of external semaphore objects.
CUresult cuWaitExternalSemaphoresAsync ( const CUexternalSemaphore* extSemArray, const CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS* paramsArray, unsigned int  numExtSems, CUstream stream )
Waits on a set of external semaphore objects.

Functions

CUresult cuDestroyExternalMemory ( CUexternalMemory extMem )
销毁一个外部内存对象。
参数
extMem
- External memory object to be destroyed
描述

销毁指定的外部内存对象。任何已映射到此对象上的现有缓冲区和CUDA mipmapped数组将不再可用,必须分别使用cuMemFreecuMipmappedArrayDestroy显式释放。

Note:

请注意,此函数也可能返回之前异步启动的错误代码。

另请参阅:

cuImportExternalMemory, cuExternalMemoryGetMappedBuffer, cuExternalMemoryGetMappedMipmappedArray

CUresult cuDestroyExternalSemaphore ( CUexternalSemaphore extSem )
销毁一个外部信号量。
参数
extSem
- External semaphore to be destroyed
描述

销毁一个外部信号量对象并释放对底层资源的任何引用。在销毁信号量之前,所有未完成的信号或等待操作必须已完成。

Note:

请注意,此函数也可能返回之前异步启动的错误代码。

另请参阅:

cuImportExternalSemaphore, cuSignalExternalSemaphoresAsync, cuWaitExternalSemaphoresAsync

CUresult cuExternalMemoryGetMappedBuffer ( CUdeviceptr* devPtr, CUexternalMemory extMem, const CUDA_EXTERNAL_MEMORY_BUFFER_DESC* bufferDesc )
将缓冲区映射到导入的内存对象上。
参数
devPtr
- Returned device pointer to buffer
extMem
- Handle to external memory object
bufferDesc
- Buffer descriptor
描述

将缓冲区映射到导入的内存对象上,并在devPtr中返回设备指针。

被映射缓冲区的属性必须在bufferDesc中描述。CUDA_EXTERNAL_MEMORY_BUFFER_DESC结构定义如下:

‎        typedef struct CUDA_EXTERNAL_MEMORY_BUFFER_DESC_st {
                  unsigned long long offset;
                  unsigned long long size;
                  unsigned int flags;
              } CUDA_EXTERNAL_MEMORY_BUFFER_DESC;

其中CUDA_EXTERNAL_MEMORY_BUFFER_DESC::offset表示内存对象中缓冲区基地址的偏移量。CUDA_EXTERNAL_MEMORY_BUFFER_DESC::size表示缓冲区的大小。CUDA_EXTERNAL_MEMORY_BUFFER_DESC::flags必须为零。

偏移量和大小必须适当对齐以满足外部API的要求。映射两个范围重叠的缓冲区可能会导致重叠部分返回相同的虚拟地址,也可能不会。在这种情况下,应用程序必须确保GPU对该区域的所有访问都是易失性的。否则,即使是由同一线程发出的写入操作,也不能保证通过一个地址进行的写入能通过另一个地址可见。建议应用程序映射合并后的范围,而不是单独映射缓冲区,然后对返回的指针应用适当的偏移量来获取各个缓冲区。

返回的指针devPtr必须使用cuMemFree释放。

Note:

请注意,此函数也可能返回之前异步启动的错误代码。

另请参阅:

cuImportExternalMemory, cuDestroyExternalMemory, cuExternalMemoryGetMappedMipmappedArray

CUresult cuExternalMemoryGetMappedMipmappedArray ( CUmipmappedArray* mipmap, CUexternalMemory extMem, const CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC* mipmapDesc )
将CUDA的mipmapped数组映射到外部内存对象上。
参数
mipmap
- Returned CUDA mipmapped array
extMem
- Handle to external memory object
mipmapDesc
- CUDA array descriptor
描述

将CUDA的mipmapped数组映射到一个外部对象,并在mipmap中返回其句柄。

要映射的CUDA mipmapped数组属性必须在mipmapDesc中描述。结构体CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC定义如下:

‎        typedef struct CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC_st {
                  unsigned long long offset;
                  CUDA_ARRAY3D_DESCRIPTOR arrayDesc;
                  unsigned int numLevels;
              } CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC;

其中CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC::offset表示mipmap链基础层在内存对象中的偏移量。CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC::arrayDesc描述了mipmap链基础层的格式、维度和类型。有关这些参数的更多详细信息,请参阅cuMipmappedArrayCreate的文档。请注意,如果mipmapped数组在图形API中被绑定为颜色目标,则必须在CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC::arrayDesc::Flags中指定CUDA_ARRAY3D_COLOR_ATTACHMENT标志。CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC::numLevels指定了mipmap链中的总层级数。

如果extMem是从类型为CU_EXTERNAL_MEMORY_HANDLE_TYPE_NVSCIBUF的句柄导入的,那么CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC::numLevels必须等于1。

返回的CUDA mipmapped数组必须使用cuMipmappedArrayDestroy释放。

Note:

请注意,此函数也可能返回之前异步启动的错误代码。

另请参阅:

cuImportExternalMemory, cuDestroyExternalMemory, cuExternalMemoryGetMappedBuffer

CUresult cuImportExternalMemory ( CUexternalMemory* extMem_out, const CUDA_EXTERNAL_MEMORY_HANDLE_DESC* memHandleDesc )
导入外部内存对象。
参数
extMem_out
- Returned handle to an external memory object
memHandleDesc
- Memory import handle descriptor
描述

导入一个外部分配的内存对象,并在extMem_out中返回该对象的句柄。

导入句柄的属性必须在memHandleDesc中描述。CUDA_EXTERNAL_MEMORY_HANDLE_DESC结构定义如下:

‎        typedef struct CUDA_EXTERNAL_MEMORY_HANDLE_DESC_st {
                  CUexternalMemoryHandleType type;
                  union {
                      int fd;
                      struct {
                          void *handle;
                          const void *name;
                      } win32;
                      const void *nvSciBufObject;
                  } handle;
                  unsigned long long size;
                  unsigned int flags;
              } CUDA_EXTERNAL_MEMORY_HANDLE_DESC;

其中 CUDA_EXTERNAL_MEMORY_HANDLE_DESC::type 指定了要导入的句柄类型。CUexternalMemoryHandleType 定义为:

‎        typedef enum CUexternalMemoryHandleType_enum {
                  CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD          = 1,
                  CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32       = 2,
                  CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT   = 3,
                  CU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP         = 4,
                  CU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE     = 5,
                  CU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_RESOURCE     = 6,
                  CU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_RESOURCE_KMT = 7,
                  CU_EXTERNAL_MEMORY_HANDLE_TYPE_NVSCIBUF           = 8,
              } CUexternalMemoryHandleType;

如果CUDA_EXTERNAL_MEMORY_HANDLE_DESC::typeCU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD,那么CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::fd必须是一个引用内存对象的有效文件描述符。当该句柄成功导入时,文件描述符的所有权将转移给CUDA驱动程序。在导入后对文件描述符执行任何操作都会导致未定义行为。

如果CUDA_EXTERNAL_MEMORY_HANDLE_DESC::typeCU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32,那么CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::win32::handle和CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::win32::name中必须有一个不为NULL。如果CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::win32::handle不为NULL,则它必须代表一个有效的共享NT句柄,该句柄引用内存对象。导入操作后,此句柄的所有权不会转移给CUDA,因此应用程序必须使用适当的系统调用来释放该句柄。如果CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::win32::name不为NULL,则它必须指向一个以NULL结尾的UTF-16字符数组,该数组引用一个内存对象。

如果CUDA_EXTERNAL_MEMORY_HANDLE_DESC::typeCU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT,那么CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::win32::handle必须非空,而CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::win32::name必须为空。指定的句柄必须是全局共享的KMT句柄。该句柄不会持有对底层对象的引用,因此当所有对该内存对象的引用被销毁时,该句柄将失效。

如果CUDA_EXTERNAL_MEMORY_HANDLE_DESC::typeCU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP,那么CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::win32::handle和CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::win32::name中必须有一个不为NULL。如果CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::win32::handle不为NULL,那么它必须代表一个有效的共享NT句柄,该句柄由ID3D12Device::CreateSharedHandle在引用ID3D12Heap对象时返回。此句柄持有对底层对象的引用。如果CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::win32::name不为NULL,那么它必须指向一个以NULL结尾的UTF-16字符数组,该数组引用一个ID3D12Heap对象。

如果CUDA_EXTERNAL_MEMORY_HANDLE_DESC::typeCU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE,那么CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::win32::handle和CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::win32::name中必须有一个不为NULL。如果CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::win32::handle不为NULL,则它必须表示一个有效的共享NT句柄,该句柄由ID3D12Device::CreateSharedHandle在引用ID3D12Resource对象时返回。此句柄持有对底层对象的引用。如果CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::win32::name不为NULL,则它必须指向一个以NULL结尾的UTF-16字符数组,该数组引用一个ID3D12Resource对象。

如果CUDA_EXTERNAL_MEMORY_HANDLE_DESC::typeCU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_RESOURCE,那么CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::win32::handle必须表示一个有效的共享NT句柄,该句柄由IDXGIResource1::CreateSharedHandle在引用ID3D11Resource对象时返回。如果CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::win32::name不为NULL,则它必须指向一个以NULL结尾的UTF-16字符数组,该数组引用一个ID3D11Resource对象。

如果CUDA_EXTERNAL_MEMORY_HANDLE_DESC::typeCU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_RESOURCE_KMT,那么CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::win32::handle必须表示一个有效的共享KMT句柄,该句柄由IDXGIResource::GetSharedHandle在引用ID3D11Resource对象时返回,且CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::win32::name必须为NULL。

如果CUDA_EXTERNAL_MEMORY_HANDLE_DESC::typeCU_EXTERNAL_MEMORY_HANDLE_TYPE_NVSCIBUF,那么CUDA_EXTERNAL_MEMORY_HANDLE_DESC::handle::nvSciBufObject必须非空且引用有效的NvSciBuf对象。如果 导入到CUDA的NvSciBuf对象也被其他驱动程序映射,那么应用程序必须使用cuWaitExternalSemaphoresAsynccuSignalExternalSemaphoresAsync作为适当的屏障,以保持CUDA与其他驱动程序之间的数据一致性。有关内存同步的详细信息,请参阅CUDA_EXTERNAL_SEMAPHORE_SIGNAL_SKIP_NVSCIBUF_MEMSYNCCUDA_EXTERNAL_SEMAPHORE_WAIT_SKIP_NVSCIBUF_MEMSYNC

内存对象的大小必须在CUDA_EXTERNAL_MEMORY_HANDLE_DESC::size中指定。

CUDA_EXTERNAL_MEMORY_HANDLE_DESC::flags中指定标志CUDA_EXTERNAL_MEMORY_DEDICATED表示该资源是专用资源。专用资源的定义不在本扩展范围内。如果CUDA_EXTERNAL_MEMORY_HANDLE_DESC::type是以下类型之一,则必须设置此标志:CU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCECU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_RESOURCECU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_RESOURCE_KMT

Note:
  • 请注意,此函数也可能返回之前异步启动的错误代码。

  • 如果导入到CUDA的Vulkan内存被映射到CPU上,应用程序必须使用vkInvalidateMappedMemoryRanges/vkFlushMappedMemoryRanges以及适当的Vulkan管线屏障来维护CPU和GPU之间的数据一致性。有关这些API的更多信息,请参阅Vulkan规范中的"同步与缓存控制"章节。

另请参阅:

cuDestroyExternalMemory, cuExternalMemoryGetMappedBuffer, cuExternalMemoryGetMappedMipmappedArray

CUresult cuImportExternalSemaphore ( CUexternalSemaphore* extSem_out, const CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC* semHandleDesc )
导入外部信号量。
参数
extSem_out
- Returned handle to an external semaphore
semHandleDesc
- Semaphore import handle descriptor
描述

导入一个外部分配同步对象,并在extSem_out中返回其句柄。

导入句柄的属性必须在semHandleDesc中描述。CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC定义如下:

‎        typedef struct CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC_st {
                  CUexternalSemaphoreHandleType type;
                  union {
                      int fd;
                      struct {
                          void *handle;
                          const void *name;
                      } win32;
                      const void* NvSciSyncObj;
                  } handle;
                  unsigned int flags;
              } CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC;

其中 CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::type 指定了要导入的句柄类型。CUexternalSemaphoreHandleType 定义为:

‎        typedef enum CUexternalSemaphoreHandleType_enum {
                  CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD                = 1,
                  CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32             = 2,
                  CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT         = 3,
                  CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE              = 4,
                  CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_FENCE              = 5,
                  CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_NVSCISYNC                = 6,
                  CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_KEYED_MUTEX        = 7,
                  CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_KEYED_MUTEX_KMT    = 8,
                  CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_FD    = 9,
                  CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_WIN32 = 10
              } CUexternalSemaphoreHandleType;

如果CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::typeCU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD,那么CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::fd必须是一个引用同步对象的有效文件描述符。 当句柄成功导入时,文件描述符的所有权将转移给CUDA驱动程序。在导入后对文件描述符执行任何操作都会导致未定义行为。

如果CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::typeCU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32,那么CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::handle和CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::name中必须有一个不为NULL。如果CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::handle不为NULL,则它必须代表一个有效的共享NT句柄,该句柄引用一个同步对象。导入操作后,该句柄的所有权不会转移给CUDA,因此应用程序必须使用适当的系统调用来释放该句柄。如果CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::name不为NULL,则它必须命名一个有效的同步对象。

如果CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::typeCU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT,那么CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::handle必须非空且CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::name必须为空。指定的句柄必须是全局共享的KMT句柄。该句柄不会持有对底层对象的引用,因此当同步对象的所有引用都被销毁时,该句柄将失效。

如果CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::typeCU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE,那么CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::handle和CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::name中必须有一个不为NULL。如果CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::handle不为NULL,那么它必须表示一个有效的共享NT句柄,该句柄由ID3D12Device::CreateSharedHandle在引用ID3D12Fence对象时返回。此句柄持有对底层对象的引用。如果CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::name不为NULL,那么它必须命名一个有效的同步对象,该对象引用一个有效的ID3D12Fence对象。

如果CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::typeCU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_FENCE,那么CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::handle表示一个由ID3D11Fence::CreateSharedHandle返回的有效共享NT句柄。如果CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::name不为NULL,则它必须命名一个引用有效ID3D11Fence对象的有效同步对象。

如果CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::typeCU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_NVSCISYNC,那么CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::nvSciSyncObj表示一个有效的NvSciSyncObj。

CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_KEYED_MUTEX,那么CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::handle表示一个有效的共享NT句柄,该句柄由IDXGIResource1::CreateSharedHandle在引用IDXGIKeyedMutex对象时返回。如果CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::name不为NULL,则它必须命名一个有效的同步对象,该对象引用一个有效的IDXGIKeyedMutex对象。

如果CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::typeCU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_KEYED_MUTEX_KMT,那么CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::handle表示一个有效的共享KMT句柄,该句柄由IDXGIResource::GetSharedHandle在引用IDXGIKeyedMutex对象时返回,且CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::name必须为NULL。

如果CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::typeCU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_FD,那么CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::fd必须是一个引用同步对象的有效文件描述符。 当句柄成功导入时,文件描述符的所有权将转移给CUDA驱动程序。在导入后对文件描述符执行任何操作都会导致未定义行为。

如果CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::typeCU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_WIN32,那么CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::handle和CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::name中必须有一个不为NULL。如果CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::handle不为NULL,则它必须代表一个有效的共享NT句柄,该句柄引用同步对象。导入操作后,此句柄的所有权不会转移给CUDA,因此应用程序必须使用适当的系统调用来释放该句柄。如果CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC::handle::win32::name不为NULL,则它必须命名一个有效的同步对象。

Note:

请注意,此函数也可能返回之前异步启动的错误代码。

另请参阅:

cuDestroyExternalSemaphore, cuSignalExternalSemaphoresAsync, cuWaitExternalSemaphoresAsync

CUresult cuSignalExternalSemaphoresAsync ( const CUexternalSemaphore* extSemArray, const CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS* paramsArray, unsigned int  numExtSems, CUstream stream )
发送一组外部信号量对象的信号。
参数
extSemArray
- Set of external semaphores to be signaled
paramsArray
- Array of semaphore parameters
numExtSems
- Number of semaphores to signal
stream
- Stream to enqueue the signal operations in
描述

在指定流中对一组外部分配的信号量对象执行信号操作入队。当流中所有先前操作完成后,这些操作将被执行。

信号量的精确语义取决于对象的类型。

如果信号量对象是以下任意一种类型:CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FDCU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT,那么触发信号量会将其设置为已触发状态。

如果信号量对象是以下任意一种类型:CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE, CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_FENCE, CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_FD, CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_WIN32,则该信号量将被设置为CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS::params::fence::value中指定的值。

如果信号量对象的类型是CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_NVSCISYNC,此API会将CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS::params::nvSciSync::fence设置为一个值,该值可被同一NvSciSync对象的后续等待者用于与当前在stream中提交的操作进行排序。此类更新将覆盖CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS::params::nvSciSync::fence的先前内容。默认情况下,触发此类外部信号量对象会导致对所有导入为CU_EXTERNAL_MEMORY_HANDLE_TYPE_NVSCIBUF的外部内存对象执行适当的内存同步操作。这确保了同一组NvSciBuf内存对象的其他导入者进行的任何后续访问都是连贯的。当不需要数据一致性时,可以通过指定标志CUDA_EXTERNAL_SEMAPHORE_SIGNAL_SKIP_NVSCIBUF_MEMSYNC来跳过这些操作,作为性能优化手段。但在需要数据一致性的场景下指定此标志会导致未定义行为。此外,对于类型为CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_NVSCISYNC的信号量对象,如果用于创建NvSciSyncObj的NvSciSyncAttrList未在cuDeviceGetNvSciSyncAttributes中将标志设置为CUDA_NVSCISYNC_ATTR_SIGNAL,此API将返回CUDA_ERROR_NOT_SUPPORTED。与类型为CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_NVSCISYNC的信号量对象关联的NvSciSyncFence可以是确定性的。为此,用于创建信号量对象的NvSciSyncAttrList必须将NvSciSyncAttrKey_RequireDeterministicFences键的值设置为true。确定性围栏允许用户在对应该信号量对象上排队等待操作,甚至在对应的触发操作排队之前。对于此类信号量对象,CUDA保证每次触发操作将使围栏值递增'1'。用户需要跟踪信号量对象上排队的触发计数并相应地插入等待操作。当此类信号量对象从多个流中触发时,由于流的并发执行,信号量被触发的顺序可能是不确定的。这可能导致信号量的等待者被错误地解除阻塞。用户需要处理这种情况,要么不在启用确定性围栏支持的不同流中使用同一信号量对象,要么通过在这些流之间添加显式依赖关系以确保信号量按顺序触发。

如果信号量对象是以下任一类型:CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_KEYED_MUTEX, CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_KEYED_MUTEX_KMT,那么键控互斥锁将使用CUDA_EXTERNAL_SEMAPHORE_PARAMS::params::keyedmutex::key中指定的键值进行释放。

Note:

请注意,此函数也可能返回之前异步启动的错误代码。

另请参阅:

cuImportExternalSemaphore, cuDestroyExternalSemaphore, cuWaitExternalSemaphoresAsync

CUresult cuWaitExternalSemaphoresAsync ( const CUexternalSemaphore* extSemArray, const CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS* paramsArray, unsigned int  numExtSems, CUstream stream )
等待一组外部信号量对象。
参数
extSemArray
- External semaphores to be waited on
paramsArray
- Array of semaphore parameters
numExtSems
- Number of semaphores to wait on
stream
- Stream to enqueue the wait operations in
描述

在指定流中对一组外部分配的信号量对象执行等待操作入队。这些操作将在流中所有先前操作完成后执行。

等待信号量的确切语义取决于对象的类型。

如果信号量对象是以下任意一种类型:CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FDCU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT,那么等待该信号量将一直阻塞,直到信号量进入已触发状态。随后信号量会被重置为非触发状态。因此每个信号操作只能对应一个等待操作。

如果信号量对象是以下任意一种类型:CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCECU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_FENCECU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_FDCU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_WIN32,那么等待该信号量将一直持续,直到信号量的值大于或等于CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS::params::fence::value。

如果信号量对象类型为CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_NVSCISYNC,那么等待该信号量将一直阻塞,直到与此信号量对象关联的NvSciSyncObj的信号发送方发出CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS::params::nvSciSync::fence信号。默认情况下,等待此类外部信号量对象会针对所有以CU_EXTERNAL_MEMORY_HANDLE_TYPE_NVSCIBUF方式导入的外部内存对象执行适当的内存同步操作,从而确保同一组NvSciBuf内存对象的其他导入方进行的后续访问具有一致性。通过指定标志CUDA_EXTERNAL_SEMAPHORE_WAIT_SKIP_NVSCIBUF_MEMSYNC可以跳过这些操作,这在不需要数据一致性时可用作性能优化手段。但在需要数据一致性的场景下指定该标志将导致未定义行为。此外,对于类型为CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_NVSCISYNC的信号量对象,如果创建NvSciSyncObj时使用的NvSciSyncAttrList未在cuDeviceGetNvSciSyncAttributes中设置CUDA_NVSCISYNC_ATTR_WAIT标志,则该API将返回CUDA_ERROR_NOT_SUPPORTED。

如果信号量对象是以下任一类型:CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_KEYED_MUTEXCU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_KEYED_MUTEX_KMT,则当使用CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS::params::keyedmutex::key中指定的键释放时,或直到CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS::params::keyedmutex::timeoutMs指定的超时时间到期时,将获取键控互斥体。超时间隔可以是以毫秒为单位的有限值,也可以是无限值。如果指定了无限值,则超时永远不会到期。必须使用Windows的INFINITE宏来指定无限超时。

Note:

请注意,此函数也可能返回之前异步启动的错误代码。

另请参阅:

cuImportExternalSemaphore, cuDestroyExternalSemaphore, cuSignalExternalSemaphoresAsync