Loading...
Searching...
No Matches
CudaFunctions.hpp
Go to the documentation of this file.
1#pragma once
2
23#if defined(_WIN32)
24#include <windows.h>
25#else
26#include <dlfcn.h>
27#endif
28
29#include <cstddef>
30#include <cstdint>
31
32#if defined(_WIN32)
33// D3D11 interop driver-API entry points take ID3D11Resource*; consumers
34// that want the Windows interop path must include <d3d11.h> themselves.
35struct ID3D11Resource;
36#endif
37
38extern "C" {
39
40// =============================================================================
41// CUDA driver-API types (subset used by score-plugin-gfx)
42//
43// Forward-declared so consumers don't need the CUDA toolkit. The opaque
44// pointer types match libcuda's ABI; the enum/struct values match the
45// values in <cuda.h> 12.x.
46// =============================================================================
47
48// Opaque handles
49typedef struct CUctx_st* CUcontext;
50typedef struct CUstream_st* CUstream;
51typedef struct CUmod_st* CUmodule;
52typedef struct CUfunc_st* CUfunction;
53typedef struct CUextMemory_st* CUexternalMemory;
54typedef struct CUextSemaphore_st* CUexternalSemaphore;
55typedef struct CUmipmappedArray_st* CUmipmappedArray;
56typedef struct CUarray_st* CUarray;
57typedef struct CUgraphicsResource_st* CUgraphicsResource;
58typedef int CUdevice;
59
60#if defined(_WIN64) || defined(__LP64__)
61typedef unsigned long long CUdeviceptr;
62#else
63typedef unsigned int CUdeviceptr;
64#endif
65
66// Enums
67typedef enum cudaError_enum
68{
69 CUDA_SUCCESS = 0,
70 CUDA_ERROR_INVALID_VALUE = 1,
71 CUDA_ERROR_OUT_OF_MEMORY = 2,
72 CUDA_ERROR_NOT_INITIALIZED = 3,
73 CUDA_ERROR_NO_DEVICE = 100,
74 CUDA_ERROR_INVALID_DEVICE = 101,
75 CUDA_ERROR_UNKNOWN = 999,
76} CUresult;
77
78typedef enum CUdevice_attribute_enum
79{
80 CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR = 75,
81 CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR = 76,
82 CU_DEVICE_ATTRIBUTE_UNIFIED_ADDRESSING = 41,
83 // Whether cuMemGetHandleForAddressRange(..., DMA_BUF_FD) is usable on
84 // this device. 0 on Turing/Ada consumer and Quadro RTX parts, so
85 // CUDA→dma-buf export to Vulkan/GL is unavailable there. Non-zero on
86 // data-center parts (A100/H100 class) with a dma-buf-capable kernel.
87 CU_DEVICE_ATTRIBUTE_DMA_BUF_SUPPORTED = 124,
88} CUdevice_attribute;
89
90typedef enum CUexternalMemoryHandleType_enum
91{
92 CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD = 1,
93 CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32 = 2,
94 CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT = 3,
95 CU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP = 4,
96 CU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE = 5,
97 CU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_RESOURCE = 6,
98 CU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_RESOURCE_KMT = 7,
99 CU_EXTERNAL_MEMORY_HANDLE_TYPE_NVSCIBUF = 8,
100} CUexternalMemoryHandleType;
101
102typedef enum CUexternalSemaphoreHandleType_enum
103{
104 CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD = 1,
105 CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32 = 2,
106 CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT = 3,
107 CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE = 4,
108 CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_FENCE = 5,
109 CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_NVSCISYNC = 6,
110 CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_KEYED_MUTEX = 7,
111 CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_KEYED_MUTEX_KMT = 8,
112 CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_FD = 9,
113 CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_WIN32 = 10,
114} CUexternalSemaphoreHandleType;
115
116typedef enum CUarray_format_enum
117{
118 CU_AD_FORMAT_UNSIGNED_INT8 = 0x01,
119 CU_AD_FORMAT_UNSIGNED_INT16 = 0x02,
120 CU_AD_FORMAT_UNSIGNED_INT32 = 0x03,
121 CU_AD_FORMAT_SIGNED_INT8 = 0x08,
122 CU_AD_FORMAT_SIGNED_INT16 = 0x09,
123 CU_AD_FORMAT_SIGNED_INT32 = 0x0a,
124 CU_AD_FORMAT_HALF = 0x10,
125 CU_AD_FORMAT_FLOAT = 0x20,
126} CUarray_format;
127
128typedef enum CUmemorytype_enum
129{
130 CU_MEMORYTYPE_HOST = 0x01,
131 CU_MEMORYTYPE_DEVICE = 0x02,
132 CU_MEMORYTYPE_ARRAY = 0x03,
133 CU_MEMORYTYPE_UNIFIED = 0x04,
134} CUmemorytype;
135
136// -- VMM (Virtual Memory Management) — CUDA 10.2+ ----------------------
137// Used by Rivermax-style direct allocation: cuMemCreate produces a
138// physical handle on the GPU, cuMemAddressReserve carves a virtual
139// range, cuMemMap binds them, cuMemSetAccess grants R/W. The resulting
140// CUdeviceptr is BAR1-mappable and accepted by GPUDirect-RDMA-class
141// peers (ConnectX NIC, AJA card with AJA_RDMA, etc).
142
143typedef unsigned long long CUmemGenericAllocationHandle;
144
145typedef enum CUmemAllocationType_enum
146{
147 CU_MEM_ALLOCATION_TYPE_INVALID = 0,
148 CU_MEM_ALLOCATION_TYPE_PINNED = 1,
149} CUmemAllocationType;
150
151typedef enum CUmemAllocationHandleType_enum
152{
153 CU_MEM_HANDLE_TYPE_NONE = 0,
154 CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR = 1,
155 CU_MEM_HANDLE_TYPE_WIN32 = 2,
156 CU_MEM_HANDLE_TYPE_WIN32_KMT = 4,
157} CUmemAllocationHandleType;
158
159typedef enum CUmemLocationType_enum
160{
161 CU_MEM_LOCATION_TYPE_INVALID = 0,
162 CU_MEM_LOCATION_TYPE_DEVICE = 1,
163} CUmemLocationType;
164
165typedef enum CUmemAccess_flags_enum
166{
167 CU_MEM_ACCESS_FLAGS_PROT_NONE = 0,
168 CU_MEM_ACCESS_FLAGS_PROT_READ = 1,
169 CU_MEM_ACCESS_FLAGS_PROT_READWRITE = 3,
170} CUmemAccess_flags;
171
172typedef enum CUmemAllocationGranularity_flags_enum
173{
174 CU_MEM_ALLOC_GRANULARITY_MINIMUM = 0,
175 CU_MEM_ALLOC_GRANULARITY_RECOMMENDED = 1,
176} CUmemAllocationGranularity_flags;
177
178// Handle type for cuMemGetHandleForAddressRange — export a *mapped* device
179// VA range (VMM- or cuMemAlloc-backed) as an OS handle. Unlike
180// cuMemExportToShareableHandle (opaque POSIX fd only), this can produce a
181// dma-buf fd, which is the cross-API handle type Vulkan can import as an
182// aliasing VkImage (VK_EXT_external_memory_dma_buf). Gated on
183// CU_DEVICE_ATTRIBUTE_DMA_BUF_SUPPORTED.
184typedef enum CUmemRangeHandleType_enum
185{
186 CU_MEM_RANGE_HANDLE_TYPE_DMA_BUF_FD = 0x1,
187} CUmemRangeHandleType;
188
189// Optional flag for cuMemGetHandleForAddressRange: request a PCIe (BAR1)
190// mapping type for the exported dma-buf rather than the default.
191enum
192{
193 CU_MEM_RANGE_FLAG_DMA_BUF_MAPPING_TYPE_PCIE = 0x1,
194};
195
196typedef struct CUmemLocation_st
197{
198 CUmemLocationType type;
199 int id;
201
203{
204 CUmemAllocationType type;
205 CUmemAllocationHandleType requestedHandleTypes;
206 CUmemLocation location;
207 void* win32HandleMetaData;
208 struct
209 {
210 unsigned char compressionType;
211 unsigned char gpuDirectRDMACapable;
212 unsigned short usage;
213 unsigned char reserved[4];
214 } allocFlags;
216
217typedef struct CUmemAccessDesc_st
218{
219 CUmemLocation location;
220 CUmemAccess_flags flags;
222
223// Graphics-resource registration flags
224#define CU_GRAPHICS_REGISTER_FLAGS_NONE 0x00
225#define CU_GRAPHICS_REGISTER_FLAGS_READ_ONLY 0x01
226#define CU_GRAPHICS_REGISTER_FLAGS_WRITE_DISCARD 0x02
227#define CU_GRAPHICS_REGISTER_FLAGS_SURFACE_LDST 0x04
228#define CU_GRAPHICS_REGISTER_FLAGS_TEXTURE_GATHER 0x08
229
230// Primary context retain/release flag bits
231#define CU_CTX_SCHED_AUTO 0x00
232
233// Structs
235{
236 CUexternalMemoryHandleType type;
237 union
238 {
239 int fd;
240 struct
241 {
242 void* handle;
243 const void* name;
244 } win32;
245 const void* nvSciBufObject;
246 } handle;
247 unsigned long long size;
248 unsigned int flags;
249 unsigned int reserved[16];
251
253{
254 unsigned long long offset;
255 unsigned long long size;
256 unsigned int flags;
257 unsigned int reserved[16];
259
261{
262 size_t Width;
263 size_t Height;
264 size_t Depth;
265 CUarray_format Format;
266 unsigned int NumChannels;
267 unsigned int Flags;
269
271{
272 unsigned long long offset;
273 CUDA_ARRAY3D_DESCRIPTOR arrayDesc;
274 unsigned int numLevels;
275 unsigned int reserved[16];
277
278typedef struct CUDA_MEMCPY2D_st
279{
280 size_t srcXInBytes;
281 size_t srcY;
282 CUmemorytype srcMemoryType;
283 const void* srcHost;
284 CUdeviceptr srcDevice;
285 CUarray srcArray;
286 size_t srcPitch;
287 size_t dstXInBytes;
288 size_t dstY;
289 CUmemorytype dstMemoryType;
290 void* dstHost;
291 CUdeviceptr dstDevice;
292 CUarray dstArray;
293 size_t dstPitch;
294 size_t WidthInBytes;
295 size_t Height;
297
299{
300 CUexternalSemaphoreHandleType type;
301 union
302 {
303 int fd;
304 struct
305 {
306 void* handle;
307 const void* name;
308 } win32;
309 const void* nvSciSyncObj;
310 } handle;
311 unsigned int flags;
312 unsigned int reserved[16];
314
316{
317 struct
318 {
319 struct
320 {
321 unsigned long long value;
322 } fence;
323 union
324 {
325 void* fence_reserved;
326 unsigned long long reserved_a[2];
327 } nvSciSync;
328 struct
329 {
330 unsigned long long key;
331 unsigned int timeoutMs;
332 } keyedMutex;
333 unsigned int reserved[10];
334 } params;
335 unsigned int flags;
336 unsigned int reserved[16];
338
339} // extern "C"
340
341namespace score::gfx
342{
343
359{
360 void* lib{};
361
362 // -- Context / device ---------------------------------------------------
363 using FN_cuInit = CUresult (*)(unsigned int);
364 using FN_cuDeviceGetCount = CUresult (*)(int*);
365 using FN_cuDeviceGet = CUresult (*)(CUdevice*, int);
366 using FN_cuDeviceGetAttribute = CUresult (*)(int*, CUdevice_attribute, CUdevice);
367 using FN_cuDevicePrimaryCtxRetain = CUresult (*)(CUcontext*, CUdevice);
368 using FN_cuDevicePrimaryCtxRelease = CUresult (*)(CUdevice);
369 using FN_cuCtxSetCurrent = CUresult (*)(CUcontext);
370 using FN_cuCtxGetDevice = CUresult (*)(CUdevice*);
371 using FN_cuCtxPushCurrent = CUresult (*)(CUcontext);
372 using FN_cuCtxPopCurrent = CUresult (*)(CUcontext*);
373
374 FN_cuInit init{};
375 FN_cuDeviceGetCount deviceGetCount{};
376 FN_cuDeviceGet deviceGet{};
377 FN_cuDeviceGetAttribute deviceGetAttribute{};
378 FN_cuDevicePrimaryCtxRetain primaryCtxRetain{};
379 FN_cuDevicePrimaryCtxRelease primaryCtxRelease{};
380 FN_cuCtxSetCurrent ctxSetCurrent{};
381 FN_cuCtxGetDevice ctxGetDevice{};
382 FN_cuCtxPushCurrent ctxPush{};
383 FN_cuCtxPopCurrent ctxPop{};
384
385 // -- Stream -------------------------------------------------------------
386 using FN_cuStreamCreate = CUresult (*)(CUstream*, unsigned int);
387 using FN_cuStreamDestroy = CUresult (*)(CUstream);
388 using FN_cuStreamSynchronize = CUresult (*)(CUstream);
389
390 FN_cuStreamCreate streamCreate{};
391 FN_cuStreamDestroy streamDestroy{};
392 FN_cuStreamSynchronize streamSync{};
393
394 // -- Errors -------------------------------------------------------------
395 using FN_cuGetErrorString = CUresult (*)(CUresult, const char**);
396 FN_cuGetErrorString getErrorString{};
397
398 // -- Graphics interop (D3D11 / OpenGL / generic) -----------------------
399 using FN_cuGraphicsMapResources
400 = CUresult (*)(unsigned int, CUgraphicsResource*, CUstream);
401 using FN_cuGraphicsUnmapResources
402 = CUresult (*)(unsigned int, CUgraphicsResource*, CUstream);
403 using FN_cuGraphicsUnregisterResource = CUresult (*)(CUgraphicsResource);
404 using FN_cuGraphicsResourceGetMappedPointer
405 = CUresult (*)(CUdeviceptr*, size_t*, CUgraphicsResource);
406
407 FN_cuGraphicsMapResources graphicsMap{};
408 FN_cuGraphicsUnmapResources graphicsUnmap{};
409 FN_cuGraphicsUnregisterResource graphicsUnregister{};
410 FN_cuGraphicsResourceGetMappedPointer graphicsGetMappedPointer{};
411
412#if defined(_WIN32)
413 using FN_cuGraphicsD3D11RegisterResource
414 = CUresult (*)(CUgraphicsResource*, ID3D11Resource*, unsigned int);
415 FN_cuGraphicsD3D11RegisterResource graphicsD3D11Register{};
416#endif
417
418 using FN_cuGraphicsGLRegisterBuffer
419 = CUresult (*)(CUgraphicsResource*, unsigned int, unsigned int);
420 FN_cuGraphicsGLRegisterBuffer graphicsGLRegisterBuffer{};
421
422 // Register a GL *texture* (image) for CUDA interop and fetch its level-0
423 // CUarray so a cuMemcpy2D can blit straight into the texture (one
424 // DtoD→array copy instead of DtoD→SSBO + glTexSubImage2D). Driver-API
425 // symbols in libcuda.so; OPTIONAL
426 // (null when the driver/GL-interop pairing doesn't expose them — callers
427 // null-check and fall back to the buffer+PBO path).
428 using FN_cuGraphicsGLRegisterImage = CUresult (*)(
429 CUgraphicsResource*, unsigned int /*image*/, unsigned int /*target*/,
430 unsigned int /*flags*/);
431 FN_cuGraphicsGLRegisterImage graphicsGLRegisterImage{};
432
433 using FN_cuGraphicsSubResourceGetMappedArray = CUresult (*)(
434 CUarray*, CUgraphicsResource, unsigned int /*arrayIndex*/,
435 unsigned int /*mipLevel*/);
436 FN_cuGraphicsSubResourceGetMappedArray graphicsSubResourceGetMappedArray{};
437
438 // -- External memory ----------------------------------------------------
439 using FN_cuImportExternalMemory
440 = CUresult (*)(CUexternalMemory*, const CUDA_EXTERNAL_MEMORY_HANDLE_DESC*);
441 using FN_cuExternalMemoryGetMappedBuffer = CUresult (*)(
442 CUdeviceptr*, CUexternalMemory, const CUDA_EXTERNAL_MEMORY_BUFFER_DESC*);
443 using FN_cuExternalMemoryGetMappedMipmappedArray = CUresult (*)(
444 CUmipmappedArray*, CUexternalMemory,
446 using FN_cuMipmappedArrayGetLevel
447 = CUresult (*)(CUarray*, CUmipmappedArray, unsigned int);
448 using FN_cuMipmappedArrayDestroy = CUresult (*)(CUmipmappedArray);
449 using FN_cuDestroyExternalMemory = CUresult (*)(CUexternalMemory);
450
451 FN_cuImportExternalMemory importExtMem{};
452 FN_cuExternalMemoryGetMappedBuffer extMemGetMappedBuffer{};
453 FN_cuExternalMemoryGetMappedMipmappedArray getMapArray{};
454 FN_cuMipmappedArrayGetLevel getLevel{};
455 FN_cuMipmappedArrayDestroy destroyMipArray{};
456 FN_cuDestroyExternalMemory destroyExtMem{};
457
458 // -- External semaphores -----------------------------------------------
459 using FN_cuImportExternalSemaphore = CUresult (*)(
460 CUexternalSemaphore*, const CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC*);
461 using FN_cuWaitExternalSemaphoresAsync = CUresult (*)(
462 const CUexternalSemaphore*,
463 const CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS*, unsigned int, CUstream);
464 using FN_cuDestroyExternalSemaphore = CUresult (*)(CUexternalSemaphore);
465
466 FN_cuImportExternalSemaphore importExtSem{};
467 FN_cuWaitExternalSemaphoresAsync waitExtSems{};
468 FN_cuDestroyExternalSemaphore destroyExtSem{};
469
470 // -- Memcpy -------------------------------------------------------------
471 using FN_cuMemcpy2DAsync = CUresult (*)(const CUDA_MEMCPY2D*, CUstream);
472 FN_cuMemcpy2DAsync memcpy2DAsync{};
473 // Synchronous variant without cuMemcpy2D's device-pitch restriction
474 // (pitches cuMemAllocPitch would not produce, e.g. SD UYVY's 1440-byte
475 // rows, make cuMemcpy2DAsync return CUDA_ERROR_INVALID_VALUE).
476 using FN_cuMemcpy2DUnaligned = CUresult (*)(const CUDA_MEMCPY2D*);
477 FN_cuMemcpy2DUnaligned memcpy2DUnaligned{};
478 using FN_cuMemcpyHtoD = CUresult (*)(CUdeviceptr, const void*, size_t);
479 FN_cuMemcpyHtoD memcpyHtoD{};
480 using FN_cuMemcpyDtoH = CUresult (*)(void*, CUdeviceptr, size_t);
481 FN_cuMemcpyDtoH memcpyDtoH{};
482 using FN_cuMemcpyDtoDAsync
483 = CUresult (*)(CUdeviceptr, CUdeviceptr, size_t, CUstream);
484 FN_cuMemcpyDtoDAsync memcpyDtoDAsync{};
485
486 // -- Linear device allocation --------------------------------------------
487 // cuMemAlloc'd memory is what third-party kernel DMA engines can pin
488 // (nvidia_p2p_get_pages accepts only CUDA-allocator VA ranges — never
489 // GL/D3D-owned memory mapped into CUDA).
490 using FN_cuMemAlloc = CUresult (*)(CUdeviceptr*, size_t);
491 using FN_cuMemFree = CUresult (*)(CUdeviceptr);
492 FN_cuMemAlloc memAlloc{};
493 FN_cuMemFree memFree{};
494
495 // -- VMM (Virtual Memory Management) — CUDA 10.2+, OPTIONAL ------------
496 // All-or-nothing: either every entry point resolves and `vmmSupported`
497 // is true, or the bundle is unavailable and consumers fall back to
498 // cuMemAlloc + non-RDMA paths.
499 using FN_cuMemCreate
500 = CUresult (*)(CUmemGenericAllocationHandle*, size_t,
501 const CUmemAllocationProp*, unsigned long long);
502 using FN_cuMemAddressReserve
503 = CUresult (*)(CUdeviceptr*, size_t, size_t, CUdeviceptr,
504 unsigned long long);
505 using FN_cuMemMap
506 = CUresult (*)(CUdeviceptr, size_t, size_t,
507 CUmemGenericAllocationHandle, unsigned long long);
508 using FN_cuMemSetAccess
509 = CUresult (*)(CUdeviceptr, size_t, const CUmemAccessDesc*, size_t);
510 using FN_cuMemUnmap = CUresult (*)(CUdeviceptr, size_t);
511 using FN_cuMemAddressFree = CUresult (*)(CUdeviceptr, size_t);
512 using FN_cuMemRelease = CUresult (*)(CUmemGenericAllocationHandle);
513 using FN_cuMemExportToShareableHandle
514 = CUresult (*)(void*, CUmemGenericAllocationHandle, int, unsigned long long);
515 using FN_cuMemGetAllocationGranularity
516 = CUresult (*)(size_t*, const CUmemAllocationProp*,
517 CUmemAllocationGranularity_flags);
518
519 FN_cuMemCreate memCreate{};
520 FN_cuMemAddressReserve memAddressReserve{};
521 FN_cuMemMap memMap{};
522 FN_cuMemSetAccess memSetAccess{};
523 FN_cuMemUnmap memUnmap{};
524 FN_cuMemAddressFree memAddressFree{};
525 FN_cuMemRelease memRelease{};
529 FN_cuMemExportToShareableHandle memExportToShareableHandle{};
530 FN_cuMemGetAllocationGranularity memGetGranularity{};
531
538 = CUresult (*)(void*, CUdeviceptr, size_t, CUmemRangeHandleType,
539 unsigned long long);
540 FN_cuMemGetHandleForAddressRange memGetHandleForAddressRange{};
541
542 // -- Pointer attributes — OPTIONAL --------------------------------------
543 // cuPointerSetAttribute(CU_POINTER_ATTRIBUTE_SYNC_MEMOPS) marks a device
544 // range for synchronous memory ops so third-party DMA engines (Deltacast
545 // VHD_CreateSlotEx RDMAEnabled, Rivermax, ...) can target it. Null on very
546 // old drivers; callers null-check.
547 using FN_cuPointerSetAttribute
548 = CUresult (*)(const void*, int /*CUpointer_attribute*/, CUdeviceptr);
549 FN_cuPointerSetAttribute pointerSetAttribute{};
550
554
555 bool loaded() const noexcept { return lib != nullptr; }
556
564 bool load()
565 {
566 if(lib)
567 return true;
568#if defined(_WIN32)
569 lib = (void*)LoadLibraryA("nvcuda.dll");
570 if(!lib)
571 return false;
572 auto sym = [this](const char* n) {
573 return (void*)GetProcAddress((HMODULE)lib, n);
574 };
575#else
576 lib = dlopen("libcuda.so.1", RTLD_NOW);
577 if(!lib)
578 return false;
579 auto sym = [this](const char* n) { return dlsym(lib, n); };
580#endif
581
582 // Context / device — REQUIRED
583 init = (FN_cuInit)sym("cuInit");
584 deviceGetCount = (FN_cuDeviceGetCount)sym("cuDeviceGetCount");
585 deviceGet = (FN_cuDeviceGet)sym("cuDeviceGet");
586 deviceGetAttribute = (FN_cuDeviceGetAttribute)sym("cuDeviceGetAttribute");
587 primaryCtxRetain = (FN_cuDevicePrimaryCtxRetain)sym("cuDevicePrimaryCtxRetain");
588 primaryCtxRelease = (FN_cuDevicePrimaryCtxRelease)sym("cuDevicePrimaryCtxRelease_v2");
589 ctxSetCurrent = (FN_cuCtxSetCurrent)sym("cuCtxSetCurrent");
590 ctxGetDevice = (FN_cuCtxGetDevice)sym("cuCtxGetDevice");
591 ctxPush = (FN_cuCtxPushCurrent)sym("cuCtxPushCurrent_v2");
592 ctxPop = (FN_cuCtxPopCurrent)sym("cuCtxPopCurrent_v2");
593
594 // Stream — REQUIRED
595 streamCreate = (FN_cuStreamCreate)sym("cuStreamCreate");
596 streamDestroy = (FN_cuStreamDestroy)sym("cuStreamDestroy_v2");
597 streamSync = (FN_cuStreamSynchronize)sym("cuStreamSynchronize");
598
599 // Errors — REQUIRED
600 getErrorString = (FN_cuGetErrorString)sym("cuGetErrorString");
601
602 // Graphics interop — REQUIRED (generic ops); D3D11/GL optional
603 graphicsMap = (FN_cuGraphicsMapResources)sym("cuGraphicsMapResources");
604 graphicsUnmap = (FN_cuGraphicsUnmapResources)sym("cuGraphicsUnmapResources");
605 graphicsUnregister
606 = (FN_cuGraphicsUnregisterResource)sym("cuGraphicsUnregisterResource");
607 graphicsGetMappedPointer = (FN_cuGraphicsResourceGetMappedPointer)sym(
608 "cuGraphicsResourceGetMappedPointer_v2");
609
610#if defined(_WIN32)
611 graphicsD3D11Register = (FN_cuGraphicsD3D11RegisterResource)sym(
612 "cuGraphicsD3D11RegisterResource");
613#endif
614 graphicsGLRegisterBuffer
615 = (FN_cuGraphicsGLRegisterBuffer)sym("cuGraphicsGLRegisterBuffer");
616 graphicsGLRegisterImage
617 = (FN_cuGraphicsGLRegisterImage)sym("cuGraphicsGLRegisterImage");
618 graphicsSubResourceGetMappedArray
619 = (FN_cuGraphicsSubResourceGetMappedArray)sym(
620 "cuGraphicsSubResourceGetMappedArray");
621
622 // External memory — REQUIRED
623 importExtMem = (FN_cuImportExternalMemory)sym("cuImportExternalMemory");
624 extMemGetMappedBuffer = (FN_cuExternalMemoryGetMappedBuffer)sym(
625 "cuExternalMemoryGetMappedBuffer");
626 getMapArray = (FN_cuExternalMemoryGetMappedMipmappedArray)sym(
627 "cuExternalMemoryGetMappedMipmappedArray");
628 getLevel = (FN_cuMipmappedArrayGetLevel)sym("cuMipmappedArrayGetLevel");
629 destroyMipArray = (FN_cuMipmappedArrayDestroy)sym("cuMipmappedArrayDestroy");
630 destroyExtMem = (FN_cuDestroyExternalMemory)sym("cuDestroyExternalMemory");
631
632 // External semaphores — REQUIRED
633 importExtSem
634 = (FN_cuImportExternalSemaphore)sym("cuImportExternalSemaphore");
635 waitExtSems = (FN_cuWaitExternalSemaphoresAsync)sym(
636 "cuWaitExternalSemaphoresAsync");
637 destroyExtSem
638 = (FN_cuDestroyExternalSemaphore)sym("cuDestroyExternalSemaphore");
639
640 // Memcpy — REQUIRED
641 memcpy2DAsync = (FN_cuMemcpy2DAsync)sym("cuMemcpy2DAsync_v2");
642 memcpy2DUnaligned = (FN_cuMemcpy2DUnaligned)sym("cuMemcpy2DUnaligned_v2");
643 memcpyHtoD = (FN_cuMemcpyHtoD)sym("cuMemcpyHtoD_v2");
644 memcpyDtoH = (FN_cuMemcpyDtoH)sym("cuMemcpyDtoH_v2");
645 memcpyDtoDAsync = (FN_cuMemcpyDtoDAsync)sym("cuMemcpyDtoDAsync_v2");
646
647 // Linear alloc — REQUIRED (core API since CUDA 3.2)
648 memAlloc = (FN_cuMemAlloc)sym("cuMemAlloc_v2");
649 memFree = (FN_cuMemFree)sym("cuMemFree_v2");
650
651 // VMM — OPTIONAL (CUDA 10.2+). All-or-nothing: if any entry is
652 // missing, mark the whole bundle unsupported. The driver exports
653 // these unversioned on both Linux and Windows in 10.2+.
654 memCreate = (FN_cuMemCreate)sym("cuMemCreate");
655 memAddressReserve = (FN_cuMemAddressReserve)sym("cuMemAddressReserve");
656 memMap = (FN_cuMemMap)sym("cuMemMap");
657 memSetAccess = (FN_cuMemSetAccess)sym("cuMemSetAccess");
658 memUnmap = (FN_cuMemUnmap)sym("cuMemUnmap");
659 memAddressFree = (FN_cuMemAddressFree)sym("cuMemAddressFree");
660 memRelease = (FN_cuMemRelease)sym("cuMemRelease");
662 = (FN_cuMemExportToShareableHandle)sym("cuMemExportToShareableHandle");
663 memGetGranularity = (FN_cuMemGetAllocationGranularity)sym(
664 "cuMemGetAllocationGranularity");
665 memGetHandleForAddressRange = (FN_cuMemGetHandleForAddressRange)sym(
666 "cuMemGetHandleForAddressRange");
667 pointerSetAttribute
668 = (FN_cuPointerSetAttribute)sym("cuPointerSetAttribute");
669 vmmSupported = memCreate && memAddressReserve && memMap && memSetAccess
670 && memUnmap && memAddressFree && memRelease
671 && memGetGranularity;
672
673 const bool ok = init && deviceGetCount && deviceGet && deviceGetAttribute
674 && primaryCtxRetain && primaryCtxRelease && ctxSetCurrent
675 && ctxGetDevice && ctxPush && ctxPop && streamCreate
676 && streamDestroy && streamSync && getErrorString
677 && graphicsMap && graphicsUnmap && graphicsUnregister
678 && graphicsGetMappedPointer && importExtMem
679 && extMemGetMappedBuffer && getMapArray && getLevel
680 && destroyMipArray && destroyExtMem && importExtSem
681 && waitExtSems && destroyExtSem && memcpy2DAsync
682 && memcpyHtoD && memcpyDtoH && memcpyDtoDAsync && memAlloc
683 && memFree;
684 if(!ok)
685 {
686 unload();
687 return false;
688 }
689 return true;
690 }
691
699 bool dmaBufExportSupported(CUdevice device) const noexcept
700 {
701 if(!deviceGetAttribute || !memGetHandleForAddressRange)
702 return false;
703 int v = 0;
704 if(deviceGetAttribute(&v, CU_DEVICE_ATTRIBUTE_DMA_BUF_SUPPORTED, device)
705 != CUDA_SUCCESS)
706 return false;
707 return v != 0;
708 }
709
710 void unload() noexcept
711 {
712 if(!lib)
713 return;
714#if defined(_WIN32)
715 FreeLibrary((HMODULE)lib);
716#else
717 dlclose(lib);
718#endif
719 lib = nullptr;
720 }
721
722 ~CudaFunctions() { unload(); }
723
724 CudaFunctions() = default;
725 CudaFunctions(const CudaFunctions&) = delete;
726 CudaFunctions& operator=(const CudaFunctions&) = delete;
727};
728
729} // namespace score::gfx
Graphics rendering pipeline for ossia score.
Definition Filter/PreviewWidget.hpp:11
Definition CudaFunctions.hpp:261
Definition CudaFunctions.hpp:253
Definition CudaFunctions.hpp:235
Definition CudaFunctions.hpp:271
Definition CudaFunctions.hpp:299
Definition CudaFunctions.hpp:316
Definition CudaFunctions.hpp:279
Definition CudaFunctions.hpp:218
Definition CudaFunctions.hpp:203
Definition CudaFunctions.hpp:197
Runtime-loaded CUDA driver-API table. Owns the libcuda handle.
Definition CudaFunctions.hpp:359
FN_cuMemExportToShareableHandle memExportToShareableHandle
Definition CudaFunctions.hpp:529
bool vmmSupported
Definition CudaFunctions.hpp:553
bool load()
Load libcuda + resolve all symbols. Idempotent.
Definition CudaFunctions.hpp:564
bool dmaBufExportSupported(CUdevice device) const noexcept
Definition CudaFunctions.hpp:699
CUresult(*)(void *, CUdeviceptr, size_t, CUmemRangeHandleType, unsigned long long) FN_cuMemGetHandleForAddressRange
Definition CudaFunctions.hpp:539