Download src/platform/memory.cpp from WineryLabs/Winery-Strata: direct link, hf CLI and curl.
- Browser
- Download file 5.5 kB
-
https://huggingface.co/WineryLabs/Winery-Strata/resolve/main/src/platform/memory.cpp
- Command line
-
hf download hf://WineryLabs/Winery-Strata/src/platform/memory.cpp
-
curl -L -o memory.cpp https://huggingface.co/WineryLabs/Winery-Strata/resolve/main/src/platform/memory.cpp
5.5 kB
| // src/platform/memory.cpp - see include/strata/platform/memory.hpp. | |
| namespace strata::platform { | |
| LockResult lock_resident(void* p, uint64_t bytes) { | |
| LockResult r; | |
| if (p == nullptr || bytes == 0) { r.note = "nothing to lock"; return r; } | |
| HANDLE self = GetCurrentProcess(); | |
| SIZE_T min_ws = 0, max_ws = 0; | |
| DWORD flags = 0; | |
| if (!GetProcessWorkingSetSizeEx(self, &min_ws, &max_ws, &flags)) { | |
| r.note = "GetProcessWorkingSetSizeEx failed (error " + std::to_string(GetLastError()) + ")"; | |
| return r; | |
| } | |
| // Locked pages count against the minimum working set, so it must grow by the region plus headroom for the | |
| // rest of the process. Soft limits: the maximum is not enforced, only the minimum is raised. | |
| const SIZE_T margin = (SIZE_T) 512 << 20; | |
| const SIZE_T new_min = min_ws + (SIZE_T) bytes + margin; | |
| const SIZE_T new_max = max_ws > new_min + margin ? max_ws : new_min + margin; | |
| if (!SetProcessWorkingSetSizeEx(self, new_min, new_max, | |
| QUOTA_LIMITS_HARDWS_MIN_DISABLE | QUOTA_LIMITS_HARDWS_MAX_DISABLE)) { | |
| r.note = "SetProcessWorkingSetSizeEx(" + std::to_string((unsigned long long) (new_min >> 20)) + | |
| " MiB) failed (error " + std::to_string(GetLastError()) + ")"; | |
| return r; | |
| } | |
| const uint64_t chunk = 1ull << 30; | |
| uint8_t* base = (uint8_t*) p; | |
| for (uint64_t off = 0; off < bytes; off += chunk) { | |
| const uint64_t n = bytes - off < chunk ? bytes - off : chunk; | |
| if (!VirtualLock(base + off, (SIZE_T) n)) { | |
| r.note = "VirtualLock stopped at " + std::to_string((unsigned long long) (off >> 20)) + " of " + | |
| std::to_string((unsigned long long) (bytes >> 20)) + " MiB (error " + | |
| std::to_string(GetLastError()) + ")"; | |
| r.ok = off > 0; | |
| return r; | |
| } | |
| r.locked_bytes = off + n; | |
| } | |
| r.ok = true; | |
| r.note = "locked " + std::to_string((unsigned long long) (bytes >> 20)) + " MiB via working-set minimum + VirtualLock"; | |
| return r; | |
| } | |
| void unlock_resident(void* p, uint64_t bytes) { | |
| if (p == nullptr || bytes == 0) return; | |
| const uint64_t chunk = 1ull << 30; | |
| for (uint64_t off = 0; off < bytes; off += chunk) | |
| VirtualUnlock((uint8_t*) p + off, (SIZE_T) (bytes - off < chunk ? bytes - off : chunk)); | |
| } | |
| bool gpu_shared_memory_budget(const void* luid, uint64_t& budget, uint64_t& usage, std::string& why) { | |
| budget = usage = 0; | |
| // dxgi.dll is loaded when asked, not linked: a start that never needs this keeps the imports it had | |
| HMODULE dxgi = LoadLibraryA("dxgi.dll"); | |
| if (dxgi == nullptr) { why = "dxgi.dll not found"; return false; } | |
| using CreateFactory = HRESULT(WINAPI*)(REFIID, void**); | |
| const auto create = (CreateFactory) (void*) GetProcAddress(dxgi, "CreateDXGIFactory1"); | |
| IDXGIFactory1* factory = nullptr; | |
| if (create == nullptr || FAILED(create(__uuidof(IDXGIFactory1), (void**) &factory)) || factory == nullptr) { | |
| why = "CreateDXGIFactory1 failed"; | |
| FreeLibrary(dxgi); | |
| return false; | |
| } | |
| bool ok = false; | |
| why = "no DXGI adapter has the CUDA device's LUID"; | |
| for (UINT i = 0; !ok; ++i) { | |
| IDXGIAdapter1* a = nullptr; | |
| if (factory->EnumAdapters1(i, &a) == DXGI_ERROR_NOT_FOUND || a == nullptr) break; | |
| DXGI_ADAPTER_DESC1 d{}; | |
| if (SUCCEEDED(a->GetDesc1(&d)) && std::memcmp(&d.AdapterLuid, luid, sizeof d.AdapterLuid) == 0) { | |
| IDXGIAdapter3* a3 = nullptr; | |
| DXGI_QUERY_VIDEO_MEMORY_INFO info{}; | |
| if (SUCCEEDED(a->QueryInterface(__uuidof(IDXGIAdapter3), (void**) &a3)) && a3 != nullptr && | |
| SUCCEEDED(a3->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &info))) { | |
| budget = info.Budget; | |
| usage = info.CurrentUsage; | |
| ok = budget > 0; | |
| why = ok ? "" : "the adapter reports no shared-memory budget"; | |
| } else { | |
| why = "QueryVideoMemoryInfo failed"; | |
| } | |
| if (a3 != nullptr) a3->Release(); | |
| a->Release(); | |
| break; | |
| } | |
| a->Release(); | |
| } | |
| factory->Release(); | |
| FreeLibrary(dxgi); | |
| return ok; | |
| } | |
| uint64_t total_physical_memory() { | |
| MEMORYSTATUSEX ms{}; | |
| ms.dwLength = sizeof ms; | |
| return GlobalMemoryStatusEx(&ms) ? (uint64_t) ms.ullTotalPhys : 0; | |
| } | |
| LockResult lock_resident(void* p, uint64_t bytes) { | |
| LockResult r; | |
| if (p == nullptr || bytes == 0) { r.note = "nothing to lock"; return r; } | |
| if (mlock(p, bytes) != 0) { r.note = "mlock failed (raise ulimit -l)"; return r; } | |
| r.ok = true; | |
| r.locked_bytes = bytes; | |
| r.note = "mlock"; | |
| return r; | |
| } | |
| void unlock_resident(void* p, uint64_t bytes) { | |
| if (p != nullptr && bytes != 0) munlock(p, bytes); | |
| } | |
| bool gpu_shared_memory_budget(const void*, uint64_t& budget, uint64_t& usage, std::string& why) { | |
| budget = usage = 0; | |
| why = "DXGI is Windows-only"; | |
| return false; | |
| } | |
| uint64_t total_physical_memory() { | |
| const long pages = sysconf(_SC_PHYS_PAGES), page = sysconf(_SC_PAGE_SIZE); | |
| return pages > 0 && page > 0 ? (uint64_t) pages * (uint64_t) page : 0; | |
| } | |
| } // namespace strata::platform | |