Download rtx/windows_rtx/cuda_driver_loader.c from Snapkitty/sov-kernel-monster: direct link, hf CLI and curl.
- Browser
- Download file 23.7 kB
-
https://huggingface.co/Snapkitty/sov-kernel-monster/resolve/main/rtx/windows_rtx/cuda_driver_loader.c
- Command line
-
hf download hf://Snapkitty/sov-kernel-monster/rtx/windows_rtx/cuda_driver_loader.c
-
curl -L -o cuda_driver_loader.c https://huggingface.co/Snapkitty/sov-kernel-monster/resolve/main/rtx/windows_rtx/cuda_driver_loader.c
23.7 kB
| /* | |
| * Zero-CRT CUDA driver loader for 64-bit Windows. | |
| * | |
| * nvcuda.dll is loaded through ntdll!LdrLoadDll when it is not already in | |
| * the PEB module list. CUDA entry points are then resolved directly from the | |
| * image export table, so neither the CUDA SDK nor an import library is needed. | |
| */ | |
| typedef void* PVOID; | |
| typedef int32_t NTSTATUS; | |
| typedef struct sov_list_entry { | |
| struct sov_list_entry* Flink; | |
| struct sov_list_entry* Blink; | |
| } LIST_ENTRY; | |
| typedef struct { | |
| uint16_t Length; | |
| uint16_t MaximumLength; | |
| wchar_t* Buffer; | |
| } UNICODE_STRING; | |
| typedef struct { | |
| uint32_t Length; | |
| uint8_t Initialized; | |
| uint8_t Reserved1[3]; | |
| PVOID SsHandle; | |
| LIST_ENTRY InLoadOrderModuleList; | |
| LIST_ENTRY InMemoryOrderModuleList; | |
| LIST_ENTRY InInitializationOrderModuleList; | |
| } PEB_LDR_DATA; | |
| typedef struct { | |
| LIST_ENTRY InLoadOrderLinks; | |
| LIST_ENTRY InMemoryOrderLinks; | |
| LIST_ENTRY InInitializationOrderLinks; | |
| PVOID DllBase; | |
| PVOID EntryPoint; | |
| uint32_t SizeOfImage; | |
| uint32_t Reserved; | |
| UNICODE_STRING FullDllName; | |
| UNICODE_STRING BaseDllName; | |
| } LDR_DATA_TABLE_ENTRY; | |
| typedef struct { | |
| uint8_t Reserved1[2]; | |
| uint8_t BeingDebugged; | |
| uint8_t Reserved2; | |
| PVOID Reserved3[2]; | |
| PEB_LDR_DATA* Ldr; | |
| } PEB; | |
| typedef struct { | |
| uint16_t e_magic; | |
| uint16_t e_cblp; | |
| uint16_t e_cp; | |
| uint16_t e_crlc; | |
| uint16_t e_cparhdr; | |
| uint16_t e_minalloc; | |
| uint16_t e_maxalloc; | |
| uint16_t e_ss; | |
| uint16_t e_sp; | |
| uint16_t e_csum; | |
| uint16_t e_ip; | |
| uint16_t e_cs; | |
| uint16_t e_lfarlc; | |
| uint16_t e_ovno; | |
| uint16_t e_res[4]; | |
| uint16_t e_oemid; | |
| uint16_t e_oeminfo; | |
| uint16_t e_res2[10]; | |
| int32_t e_lfanew; | |
| } IMAGE_DOS_HEADER; | |
| typedef struct { | |
| uint32_t VirtualAddress; | |
| uint32_t Size; | |
| } IMAGE_DATA_DIRECTORY; | |
| typedef struct { | |
| uint16_t Machine; | |
| uint16_t NumberOfSections; | |
| uint32_t TimeDateStamp; | |
| uint32_t PointerToSymbolTable; | |
| uint32_t NumberOfSymbols; | |
| uint16_t SizeOfOptionalHeader; | |
| uint16_t Characteristics; | |
| } IMAGE_FILE_HEADER; | |
| typedef struct { | |
| uint16_t Magic; | |
| uint8_t MajorLinkerVersion; | |
| uint8_t MinorLinkerVersion; | |
| uint32_t SizeOfCode; | |
| uint32_t SizeOfInitializedData; | |
| uint32_t SizeOfUninitializedData; | |
| uint32_t AddressOfEntryPoint; | |
| uint32_t BaseOfCode; | |
| uint64_t ImageBase; | |
| uint32_t SectionAlignment; | |
| uint32_t FileAlignment; | |
| uint16_t MajorOperatingSystemVersion; | |
| uint16_t MinorOperatingSystemVersion; | |
| uint16_t MajorImageVersion; | |
| uint16_t MinorImageVersion; | |
| uint16_t MajorSubsystemVersion; | |
| uint16_t MinorSubsystemVersion; | |
| uint32_t Win32VersionValue; | |
| uint32_t SizeOfImage; | |
| uint32_t SizeOfHeaders; | |
| uint32_t CheckSum; | |
| uint16_t Subsystem; | |
| uint16_t DllCharacteristics; | |
| uint64_t SizeOfStackReserve; | |
| uint64_t SizeOfStackCommit; | |
| uint64_t SizeOfHeapReserve; | |
| uint64_t SizeOfHeapCommit; | |
| uint32_t LoaderFlags; | |
| uint32_t NumberOfRvaAndSizes; | |
| IMAGE_DATA_DIRECTORY DataDirectory[16]; | |
| } IMAGE_OPTIONAL_HEADER64; | |
| typedef struct { | |
| uint32_t Signature; | |
| IMAGE_FILE_HEADER FileHeader; | |
| IMAGE_OPTIONAL_HEADER64 OptionalHeader; | |
| } IMAGE_NT_HEADERS64; | |
| typedef struct { | |
| uint32_t Characteristics; | |
| uint32_t TimeDateStamp; | |
| uint16_t MajorVersion; | |
| uint16_t MinorVersion; | |
| uint32_t Name; | |
| uint32_t Base; | |
| uint32_t NumberOfFunctions; | |
| uint32_t NumberOfNames; | |
| uint32_t AddressOfFunctions; | |
| uint32_t AddressOfNames; | |
| uint32_t AddressOfNameOrdinals; | |
| } IMAGE_EXPORT_DIRECTORY; | |
| typedef NTSTATUS (SOV_WINAPI *LdrLoadDll_t)( | |
| wchar_t*, uint32_t*, UNICODE_STRING*, PVOID*); | |
| typedef struct { uint8_t bytes[16]; } CUuuid; | |
| typedef CUresult (SOV_WINAPI *cuInit_t)(unsigned int); | |
| typedef CUresult (SOV_WINAPI *cuDriverGetVersion_t)(int*); | |
| typedef CUresult (SOV_WINAPI *cuDeviceGet_t)(CUdevice*, int); | |
| typedef CUresult (SOV_WINAPI *cuDeviceGetCount_t)(int*); | |
| typedef CUresult (SOV_WINAPI *cuDeviceGetName_t)(char*, int, CUdevice); | |
| typedef CUresult (SOV_WINAPI *cuDeviceGetAttribute_t)(int*, CUdevice_attribute, CUdevice); | |
| typedef CUresult (SOV_WINAPI *cuDeviceGetUuid_t)(CUuuid*, CUdevice); | |
| typedef CUresult (SOV_WINAPI *cuCtxCreate_v2_t)(CUcontext*, unsigned int, CUdevice); | |
| typedef CUresult (SOV_WINAPI *cuCtxDestroy_v2_t)(CUcontext); | |
| typedef CUresult (SOV_WINAPI *cuCtxSetCurrent_t)(CUcontext); | |
| typedef CUresult (SOV_WINAPI *cuModuleLoadData_t)(CUmodule*, const void*); | |
| typedef CUresult (SOV_WINAPI *cuModuleGetFunction_t)(CUfunction*, CUmodule, const char*); | |
| typedef CUresult (SOV_WINAPI *cuModuleGetGlobal_v2_t)(CUdeviceptr*, size_t*, CUmodule, const char*); | |
| typedef CUresult (SOV_WINAPI *cuModuleUnload_t)(CUmodule); | |
| typedef CUresult (SOV_WINAPI *cuLaunchKernel_t)( | |
| CUfunction, | |
| unsigned int, unsigned int, unsigned int, | |
| unsigned int, unsigned int, unsigned int, | |
| unsigned int, CUstream, void**, void**); | |
| typedef CUresult (SOV_WINAPI *cuMemAlloc_v2_t)(CUdeviceptr*, size_t); | |
| typedef CUresult (SOV_WINAPI *cuMemFree_v2_t)(CUdeviceptr); | |
| typedef CUresult (SOV_WINAPI *cuMemcpyHtoD_v2_t)(CUdeviceptr, const void*, size_t); | |
| typedef CUresult (SOV_WINAPI *cuMemcpyDtoH_v2_t)(void*, CUdeviceptr, size_t); | |
| static cuInit_t g_cuInit; | |
| static cuDriverGetVersion_t g_cuDriverGetVersion; | |
| static cuDeviceGet_t g_cuDeviceGet; | |
| static cuDeviceGetCount_t g_cuDeviceGetCount; | |
| static cuDeviceGetName_t g_cuDeviceGetName; | |
| static cuDeviceGetAttribute_t g_cuDeviceGetAttribute; | |
| static cuDeviceGetUuid_t g_cuDeviceGetUuid; | |
| static cuCtxCreate_v2_t g_cuCtxCreate_v2; | |
| static cuCtxDestroy_v2_t g_cuCtxDestroy_v2; | |
| static cuCtxSetCurrent_t g_cuCtxSetCurrent; | |
| static cuModuleLoadData_t g_cuModuleLoadData; | |
| static cuModuleGetFunction_t g_cuModuleGetFunction; | |
| static cuModuleGetGlobal_v2_t g_cuModuleGetGlobal_v2; | |
| static cuModuleUnload_t g_cuModuleUnload; | |
| static cuLaunchKernel_t g_cuLaunchKernel; | |
| static cuMemAlloc_v2_t g_cuMemAlloc_v2; | |
| static cuMemFree_v2_t g_cuMemFree_v2; | |
| static cuMemcpyHtoD_v2_t g_cuMemcpyHtoD_v2; | |
| static cuMemcpyDtoH_v2_t g_cuMemcpyDtoH_v2; | |
| static CUcontext g_cuda_context; | |
| static CUdevice g_cuda_device; | |
| static uint32_t g_cuda_device_ordinal; | |
| static CUdeviceptr g_power_state_device; | |
| static volatile int32_t g_power_state_host; | |
| static int g_cuda_initialized; | |
| static uint64_t g_cuda_context_generation; | |
| float g_janet_kernel_config[8] = { | |
| 1.0f, 0.5f, 0.25f, 0.125f, 8.0f, 16.0f, 32.0f, 64.0f | |
| }; | |
| static void power_state_store(int32_t state) { | |
| (void)_InterlockedExchange((volatile long*)&g_power_state_host, (long)state); | |
| __atomic_store_n(&g_power_state_host, state, __ATOMIC_RELEASE); | |
| } | |
| static int32_t power_state_load(void) { | |
| return (int32_t)_InterlockedCompareExchange( | |
| (volatile long*)&g_power_state_host, 0, 0); | |
| return __atomic_load_n(&g_power_state_host, __ATOMIC_ACQUIRE); | |
| } | |
| static PVOID peb_get(void) { | |
| return (PVOID)__readgsqword(0x60); | |
| PVOID peb; | |
| __asm__ volatile ("mov %%gs:0x60, %0" : "=r"(peb)); | |
| return peb; | |
| } | |
| static wchar_t ascii_lower_w(wchar_t value) { | |
| if (value >= L'A' && value <= L'Z') return (wchar_t)(value + (L'a' - L'A')); | |
| return value; | |
| } | |
| static PVOID find_module(const wchar_t* target) { | |
| PEB* peb = (PEB*)peb_get(); | |
| LIST_ENTRY* head; | |
| LIST_ENTRY* current; | |
| if (!peb || !peb->Ldr || !target) return 0; | |
| head = &peb->Ldr->InMemoryOrderModuleList; | |
| current = head->Flink; | |
| while (current && current != head) { | |
| LDR_DATA_TABLE_ENTRY* entry = | |
| (LDR_DATA_TABLE_ENTRY*)((uint8_t*)current - | |
| offsetof(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks)); | |
| if (entry->BaseDllName.Buffer && entry->BaseDllName.Length) { | |
| size_t length = (size_t)entry->BaseDllName.Length / sizeof(wchar_t); | |
| size_t i; | |
| int matches = 1; | |
| for (i = 0; i < length; ++i) { | |
| if (!target[i] || | |
| ascii_lower_w(entry->BaseDllName.Buffer[i]) != | |
| ascii_lower_w(target[i])) { | |
| matches = 0; | |
| break; | |
| } | |
| } | |
| if (matches && target[length] == L'\0') return entry->DllBase; | |
| } | |
| current = current->Flink; | |
| } | |
| return 0; | |
| } | |
| static int ascii_compare(const char* left, const char* right) { | |
| size_t i = 0; | |
| while (left[i] && right[i] && left[i] == right[i]) ++i; | |
| return (int)(uint8_t)left[i] - (int)(uint8_t)right[i]; | |
| } | |
| static PVOID get_export(PVOID base, const char* name) { | |
| IMAGE_DOS_HEADER* dos; | |
| IMAGE_NT_HEADERS64* nt; | |
| IMAGE_DATA_DIRECTORY* export_data; | |
| IMAGE_EXPORT_DIRECTORY* exports; | |
| uint32_t* names; | |
| uint32_t* functions; | |
| uint16_t* ordinals; | |
| int low, high; | |
| if (!base || !name) return 0; | |
| dos = (IMAGE_DOS_HEADER*)base; | |
| if (dos->e_magic != 0x5a4d || dos->e_lfanew <= 0) return 0; | |
| nt = (IMAGE_NT_HEADERS64*)((uint8_t*)base + dos->e_lfanew); | |
| if (nt->Signature != 0x00004550 || | |
| nt->OptionalHeader.Magic != 0x020b || | |
| nt->OptionalHeader.NumberOfRvaAndSizes == 0) return 0; | |
| export_data = &nt->OptionalHeader.DataDirectory[0]; | |
| if (!export_data->VirtualAddress || !export_data->Size) return 0; | |
| exports = (IMAGE_EXPORT_DIRECTORY*)((uint8_t*)base + export_data->VirtualAddress); | |
| names = (uint32_t*)((uint8_t*)base + exports->AddressOfNames); | |
| functions = (uint32_t*)((uint8_t*)base + exports->AddressOfFunctions); | |
| ordinals = (uint16_t*)((uint8_t*)base + exports->AddressOfNameOrdinals); | |
| low = 0; | |
| high = (int)exports->NumberOfNames - 1; | |
| while (low <= high) { | |
| int middle = low + ((high - low) / 2); | |
| const char* cand = (const char*)((uint8_t*)base + names[middle]); | |
| int cmp = ascii_compare(cand, name); | |
| if (cmp == 0) { | |
| uint16_t ordinal = ordinals[middle]; | |
| uint32_t fn_rva; | |
| if ((uint32_t)ordinal >= exports->NumberOfFunctions) return 0; | |
| fn_rva = functions[ordinal]; | |
| if (fn_rva >= export_data->VirtualAddress && | |
| fn_rva < export_data->VirtualAddress + export_data->Size) return 0; | |
| return (PVOID)((uint8_t*)base + fn_rva); | |
| } | |
| if (cmp < 0) low = middle + 1; | |
| else high = middle - 1; | |
| } | |
| return 0; | |
| } | |
| static PVOID load_nvcuda(void) { | |
| static wchar_t dll_name_buffer[] = L"nvcuda.dll"; | |
| PVOID nvcuda = find_module(dll_name_buffer); | |
| PVOID ntdll; | |
| LdrLoadDll_t load_dll; | |
| UNICODE_STRING dll_name; | |
| if (nvcuda) return nvcuda; | |
| ntdll = find_module(L"ntdll.dll"); | |
| load_dll = (LdrLoadDll_t)get_export(ntdll, "LdrLoadDll"); | |
| if (!load_dll) return 0; | |
| dll_name.Length = (uint16_t)(10u * sizeof(wchar_t)); | |
| dll_name.MaximumLength = (uint16_t)(11u * sizeof(wchar_t)); | |
| dll_name.Buffer = dll_name_buffer; | |
| if (load_dll(0, 0, &dll_name, &nvcuda) < 0) return 0; | |
| return nvcuda; | |
| } | |
| g_# | |
| static int resolve_cuda(void) { | |
| PVOID nvcuda = load_nvcuda(); | |
| if (!nvcuda) return -1; | |
| RESOLVE_CUDA(nvcuda, cuInit); | |
| RESOLVE_CUDA(nvcuda, cuDriverGetVersion); | |
| RESOLVE_CUDA(nvcuda, cuDeviceGet); | |
| RESOLVE_CUDA(nvcuda, cuDeviceGetCount); | |
| RESOLVE_CUDA(nvcuda, cuDeviceGetName); | |
| RESOLVE_CUDA(nvcuda, cuDeviceGetAttribute); | |
| g_cuDeviceGetUuid = (cuDeviceGetUuid_t)get_export(nvcuda, "cuDeviceGetUuid_v2"); | |
| if (!g_cuDeviceGetUuid) | |
| g_cuDeviceGetUuid = (cuDeviceGetUuid_t)get_export(nvcuda, "cuDeviceGetUuid"); | |
| RESOLVE_CUDA(nvcuda, cuCtxCreate_v2); | |
| RESOLVE_CUDA(nvcuda, cuCtxDestroy_v2); | |
| RESOLVE_CUDA(nvcuda, cuCtxSetCurrent); | |
| RESOLVE_CUDA(nvcuda, cuModuleLoadData); | |
| RESOLVE_CUDA(nvcuda, cuModuleGetFunction); | |
| RESOLVE_CUDA(nvcuda, cuModuleGetGlobal_v2); | |
| RESOLVE_CUDA(nvcuda, cuModuleUnload); | |
| RESOLVE_CUDA(nvcuda, cuLaunchKernel); | |
| RESOLVE_CUDA(nvcuda, cuMemAlloc_v2); | |
| RESOLVE_CUDA(nvcuda, cuMemFree_v2); | |
| RESOLVE_CUDA(nvcuda, cuMemcpyHtoD_v2); | |
| RESOLVE_CUDA(nvcuda, cuMemcpyDtoH_v2); | |
| return (g_cuInit && g_cuDriverGetVersion && | |
| g_cuDeviceGet && g_cuDeviceGetCount && | |
| g_cuDeviceGetName && g_cuDeviceGetAttribute && | |
| g_cuDeviceGetUuid && | |
| g_cuCtxCreate_v2 && g_cuCtxDestroy_v2 && g_cuCtxSetCurrent && | |
| g_cuModuleLoadData && g_cuModuleGetFunction && | |
| g_cuModuleGetGlobal_v2 && g_cuModuleUnload && | |
| g_cuLaunchKernel && g_cuMemAlloc_v2 && g_cuMemFree_v2 && | |
| g_cuMemcpyHtoD_v2 && g_cuMemcpyDtoH_v2) | |
| ? 1 : 0; | |
| } | |
| static CUresult make_cuda_context_current(void) { | |
| if (!g_cuda_initialized || !g_cuda_context || !g_cuCtxSetCurrent) | |
| return CUDA_ERROR_NOT_INITIALIZED; | |
| return g_cuCtxSetCurrent(g_cuda_context); | |
| } | |
| do { \ | |
| CUresult _ctx_result = make_cuda_context_current(); \ | |
| if (_ctx_result != CUDA_SUCCESS) return _ctx_result; \ | |
| } while (0) | |
| int sov_cuda_init(void) { | |
| CUdevice device; | |
| CUcontext context; | |
| CUresult result; | |
| int device_count; | |
| int resolve_result; | |
| if (g_cuda_initialized) return CUDA_SUCCESS; | |
| resolve_result = resolve_cuda(); | |
| if (resolve_result < 0) return CUDA_ERROR_NOT_FOUND; | |
| if (resolve_result == 0) return CUDA_ERROR_UNKNOWN; | |
| result = g_cuInit(0); | |
| if (result != CUDA_SUCCESS) return result; | |
| device_count = 0; | |
| result = g_cuDeviceGetCount(&device_count); | |
| if (result != CUDA_SUCCESS) return result; | |
| if (device_count <= 0) return CUDA_ERROR_NO_DEVICE; | |
| device = 0; | |
| result = g_cuDeviceGet(&device, 0); | |
| if (result != CUDA_SUCCESS) return result; | |
| context = 0; | |
| result = g_cuCtxCreate_v2(&context, 0, device); | |
| if (result != CUDA_SUCCESS) return result; | |
| g_cuda_context = context; | |
| g_cuda_device = device; | |
| g_cuda_device_ordinal = 0; | |
| power_state_store(0); | |
| g_power_state_device = 0; | |
| ++g_cuda_context_generation; | |
| if (g_cuda_context_generation == 0u) ++g_cuda_context_generation; | |
| g_cuda_initialized = 1; | |
| return CUDA_SUCCESS; | |
| } | |
| void sov_cuda_shutdown(void) { | |
| CUcontext context; | |
| if (!g_cuda_initialized) { sov_cuda_validation_clear(); return; } | |
| context = g_cuda_context; | |
| if (context && g_cuCtxSetCurrent) (void)g_cuCtxSetCurrent(context); | |
| g_power_state_device = 0; | |
| g_cuda_context = 0; | |
| g_cuda_device = 0; | |
| g_cuda_device_ordinal = 0; | |
| if (context && g_cuCtxDestroy_v2) (void)g_cuCtxDestroy_v2(context); | |
| g_cuda_initialized = 0; | |
| sov_cuda_validation_clear(); | |
| } | |
| int sov_cuda_is_initialized(void) { return g_cuda_initialized; } | |
| uint64_t sov_cuda_context_generation(void) { return g_cuda_context_generation; } | |
| CUresult sov_cuda_get_runtime_identity(sov_cuda_runtime_identity_t* identity_out) { | |
| CUuuid uuid; | |
| CUresult result; | |
| int driver_version; | |
| int major, minor; | |
| size_t index; | |
| if (!identity_out) return CUDA_ERROR_INVALID_VALUE; | |
| for (index = 0; index < sizeof(*identity_out); ++index) | |
| ((uint8_t*)identity_out)[index] = 0; | |
| if (!g_cuda_initialized || !g_cuDriverGetVersion || | |
| !g_cuDeviceGetName || !g_cuDeviceGetAttribute || !g_cuDeviceGetUuid) | |
| return CUDA_ERROR_NOT_INITIALIZED; | |
| REQUIRE_CURRENT_CONTEXT(); | |
| driver_version = 0; | |
| result = g_cuDriverGetVersion(&driver_version); | |
| if (result != CUDA_SUCCESS || driver_version <= 0) | |
| return result != CUDA_SUCCESS ? result : CUDA_ERROR_UNKNOWN; | |
| result = g_cuDeviceGetName(identity_out->device_name, | |
| (int)sizeof(identity_out->device_name), | |
| g_cuda_device); | |
| if (result != CUDA_SUCCESS) return result; | |
| identity_out->device_name[sizeof(identity_out->device_name) - 1u] = '\0'; | |
| major = 0; | |
| result = g_cuDeviceGetAttribute(&major, (CUdevice_attribute)75, g_cuda_device); | |
| if (result != CUDA_SUCCESS || major <= 0) | |
| return result != CUDA_SUCCESS ? result : CUDA_ERROR_UNKNOWN; | |
| minor = 0; | |
| result = g_cuDeviceGetAttribute(&minor, (CUdevice_attribute)76, g_cuda_device); | |
| if (result != CUDA_SUCCESS || minor < 0) | |
| return result != CUDA_SUCCESS ? result : CUDA_ERROR_UNKNOWN; | |
| result = g_cuDeviceGetUuid(&uuid, g_cuda_device); | |
| if (result != CUDA_SUCCESS) return result; | |
| identity_out->driver_version = (uint32_t)driver_version; | |
| identity_out->device_ordinal = g_cuda_device_ordinal; | |
| identity_out->compute_capability_major = (uint32_t)major; | |
| identity_out->compute_capability_minor = (uint32_t)minor; | |
| for (index = 0; index < sizeof(identity_out->device_uuid); ++index) | |
| identity_out->device_uuid[index] = uuid.bytes[index]; | |
| identity_out->context_generation = g_cuda_context_generation; | |
| return CUDA_SUCCESS; | |
| } | |
| CUresult sov_cuda_module_load_data(CUmodule* module, const void* image) { | |
| if (!module || !image) return CUDA_ERROR_INVALID_VALUE; | |
| *module = 0; | |
| if (!g_cuda_initialized || !g_cuModuleLoadData) return CUDA_ERROR_NOT_INITIALIZED; | |
| REQUIRE_CURRENT_CONTEXT(); | |
| return g_cuModuleLoadData(module, image); | |
| } | |
| CUresult sov_cuda_module_get_function(CUfunction* function, CUmodule module, | |
| const char* name) { | |
| if (!function || !module || !name || !name[0]) return CUDA_ERROR_INVALID_VALUE; | |
| *function = 0; | |
| if (!g_cuda_initialized || !g_cuModuleGetFunction) return CUDA_ERROR_NOT_INITIALIZED; | |
| REQUIRE_CURRENT_CONTEXT(); | |
| return g_cuModuleGetFunction(function, module, name); | |
| } | |
| CUresult sov_cuda_module_get_global(CUdeviceptr* device_ptr, size_t* bytes, | |
| CUmodule module, const char* name) { | |
| if (!device_ptr || !module || !name || !name[0]) return CUDA_ERROR_INVALID_VALUE; | |
| *device_ptr = 0; | |
| if (bytes) *bytes = 0; | |
| if (!g_cuda_initialized || !g_cuModuleGetGlobal_v2) return CUDA_ERROR_NOT_INITIALIZED; | |
| REQUIRE_CURRENT_CONTEXT(); | |
| return g_cuModuleGetGlobal_v2(device_ptr, bytes, module, name); | |
| } | |
| CUresult sov_cuda_module_unload(CUmodule module) { | |
| if (!module) return CUDA_SUCCESS; | |
| if (!g_cuda_initialized || !g_cuModuleUnload) return CUDA_ERROR_NOT_INITIALIZED; | |
| REQUIRE_CURRENT_CONTEXT(); | |
| return g_cuModuleUnload(module); | |
| } | |
| CUresult sov_cuda_launch_kernel(CUfunction function, | |
| unsigned int grid_x, unsigned int grid_y, | |
| unsigned int grid_z, | |
| unsigned int block_x, unsigned int block_y, | |
| unsigned int block_z, | |
| unsigned int shared_mem_bytes, | |
| CUstream stream, | |
| void** kernel_params, | |
| void** extra) { | |
| if (!function || !grid_x || !grid_y || !grid_z || | |
| !block_x || !block_y || !block_z) return CUDA_ERROR_INVALID_VALUE; | |
| if (!g_cuda_initialized || !g_cuLaunchKernel) return CUDA_ERROR_NOT_INITIALIZED; | |
| REQUIRE_CURRENT_CONTEXT(); | |
| return g_cuLaunchKernel(function, | |
| grid_x, grid_y, grid_z, | |
| block_x, block_y, block_z, | |
| shared_mem_bytes, stream, | |
| kernel_params, extra); | |
| } | |
| CUresult sov_cuda_mem_alloc(CUdeviceptr* device_ptr, size_t bytes) { | |
| if (!device_ptr || !bytes) return CUDA_ERROR_INVALID_VALUE; | |
| *device_ptr = 0; | |
| if (!g_cuda_initialized || !g_cuMemAlloc_v2) return CUDA_ERROR_NOT_INITIALIZED; | |
| REQUIRE_CURRENT_CONTEXT(); | |
| return g_cuMemAlloc_v2(device_ptr, bytes); | |
| } | |
| CUresult sov_cuda_mem_free(CUdeviceptr device_ptr) { | |
| if (!device_ptr) return CUDA_SUCCESS; | |
| if (!g_cuda_initialized || !g_cuMemFree_v2) return CUDA_ERROR_NOT_INITIALIZED; | |
| REQUIRE_CURRENT_CONTEXT(); | |
| return g_cuMemFree_v2(device_ptr); | |
| } | |
| int sov_cuda_memcpy_h2d(void* device_dst, const void* host_src, size_t bytes) { | |
| if (!bytes) return CUDA_SUCCESS; | |
| if (!device_dst || !host_src) return CUDA_ERROR_INVALID_VALUE; | |
| if (!g_cuda_initialized || !g_cuMemcpyHtoD_v2) return CUDA_ERROR_NOT_INITIALIZED; | |
| REQUIRE_CURRENT_CONTEXT(); | |
| return g_cuMemcpyHtoD_v2((CUdeviceptr)(uintptr_t)device_dst, host_src, bytes); | |
| } | |
| CUresult sov_cuda_memcpy_d2h(void* host_dst, CUdeviceptr device_src, size_t bytes) { | |
| if (!bytes) return CUDA_SUCCESS; | |
| if (!host_dst || !device_src) return CUDA_ERROR_INVALID_VALUE; | |
| if (!g_cuda_initialized || !g_cuMemcpyDtoH_v2) return CUDA_ERROR_NOT_INITIALIZED; | |
| REQUIRE_CURRENT_CONTEXT(); | |
| return g_cuMemcpyDtoH_v2(host_dst, device_src, bytes); | |
| } | |
| CUresult sov_cuda_register_power_state_device(CUdeviceptr device_ptr) { | |
| g_power_state_device = device_ptr; | |
| if (!device_ptr) return CUDA_SUCCESS; | |
| return sov_cuda_sync_power_state(); | |
| } | |
| CUresult sov_cuda_sync_power_state(void) { | |
| int32_t state; | |
| if (!g_power_state_device) return CUDA_SUCCESS; | |
| if (!g_cuda_initialized || !g_cuMemcpyHtoD_v2) return CUDA_ERROR_NOT_INITIALIZED; | |
| REQUIRE_CURRENT_CONTEXT(); | |
| state = power_state_load(); | |
| return g_cuMemcpyHtoD_v2(g_power_state_device, &state, sizeof(state)); | |
| } | |
| int sov_cuda_load_ptx(const char* ptx_data, unsigned int ptx_size, void** module_out) { | |
| CUmodule module; | |
| CUresult result; | |
| unsigned int i; | |
| if (!module_out) return CUDA_ERROR_INVALID_VALUE; | |
| *module_out = 0; | |
| if (!ptx_data || !ptx_size || ptx_data[ptx_size - 1u] != '\0') | |
| return CUDA_ERROR_INVALID_VALUE; | |
| for (i = 0; i + 1u < ptx_size; ++i) | |
| if (ptx_data[i] == '\0') return CUDA_ERROR_INVALID_VALUE; | |
| result = sov_cuda_module_load_data(&module, ptx_data); | |
| if (result == CUDA_SUCCESS) *module_out = (void*)module; | |
| return result; | |
| } | |
| void* sov_cuda_malloc(size_t bytes) { | |
| CUdeviceptr device_ptr; | |
| if (sov_cuda_mem_alloc(&device_ptr, bytes) != CUDA_SUCCESS) return 0; | |
| return (void*)(uintptr_t)device_ptr; | |
| } | |
| int sov_set_power_state(sov_power_state_t state) { | |
| if ((unsigned int)state > (unsigned int)SOV_POWER_LOW_BATTERY) | |
| return CUDA_ERROR_INVALID_VALUE; | |
| power_state_store((int32_t)state); | |
| return CUDA_SUCCESS; | |
| } | |
| sov_power_state_t sov_get_power_state(void) { | |
| return (sov_power_state_t)power_state_load(); | |
| } | |