Skip to content

Commit

Permalink
temp
Browse files Browse the repository at this point in the history
  • Loading branch information
sasha0552 authored Sep 4, 2024
1 parent ea15d89 commit 3a1a180
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 97 deletions.
13 changes: 1 addition & 12 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,8 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

- if: runner.os == 'Linux'
name: Install CUDA toolkit on Linux
- name: Install CUDA toolkit on Linux
uses: Jimver/cuda-toolkit@v0.2.16
with:
method: network
sub-packages: '["nvcc", "nvml-dev"]'

- if: runner.os == 'Windows'
name: Install CUDA toolkit on Windows
uses: Jimver/cuda-toolkit@v0.2.16
with:
method: network
sub-packages: '["cudart", "nvcc", "nvml_dev"]'

- name: Configure project
run: >
Expand Down
13 changes: 2 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ include(FetchContent)
# Define the project name and programming language
project(nvidia-pstated C)

# Find the CUDAToolkit package
find_package(CUDAToolkit REQUIRED COMPONENTS nvml)

# Declare the nvapi package
FetchContent_Declare(
nvapi
Expand All @@ -35,12 +32,6 @@ target_include_directories(nvidia-pstated SYSTEM PRIVATE

# Link libraries
target_link_libraries(nvidia-pstated PRIVATE
CUDA::nvml
libnvidia-api
libnvidia-ml
)

# Conditional linking for Linux platform
if(UNIX AND NOT APPLE)
target_link_libraries(nvidia-pstated PRIVATE
dl
)
endif()
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,24 @@ A daemon that automatically manages the performance states of NVIDIA GPUs.

#### Linux

Make sure you have the proprietary NVIDIA driver and the packages providing `libnvidia-api.so.1` and `libnvidia-ml.so.1` installed.
Make sure the proprietary NVIDIA driver is installed.

You will need the following libraries:

- `libnvidia-api.so.1`
- `libnvidia-ml.so.1`

Packages that provide these libraries:

- ArchLinux: `nvidia-utils`
- Debian: `libnvidia-api1` or `libnvidia-tesla-api1` (depending on the GPU and driver installed)

On Debian derivatives, you can use `apt search libnvidia-api.so.1` and `apt search libnvidia-ml.so.1` to find the package you need.

Note that you MUST run this daemon at the host level, i.e. where the CUDA Driver is available. You can NOT run this daemon in a container.

![nvidia-container-stack](https://cloud.githubusercontent.com/assets/3028125/12213714/5b208976-b632-11e5-8406-38d379ec46aa.png)

#### Windows

Make sure the NVIDIA driver is installed.
Expand Down
79 changes: 6 additions & 73 deletions src/nvapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,10 @@
#include <stddef.h>
#include <stdio.h>

#ifdef _WIN32
#include <windows.h>
#elif __linux__
#include <dlfcn.h>
#endif

#include "nvapi.h"

/***** ***** ***** ***** ***** TYPES ***** ***** ***** ***** *****/

typedef void * (*nvapi_QueryInterface_t)(int);

typedef NvAPI_Status (*NvAPI_EnumPhysicalGPUs_t)(NvPhysicalGpuHandle[NVAPI_MAX_PHYSICAL_GPUS], NvU32 *);
typedef NvAPI_Status (*NvAPI_GPU_SetForcePstate_t)(NvPhysicalGpuHandle, NvU32, NvU32);
typedef NvAPI_Status (*NvAPI_GetErrorMessage_t)(NvAPI_Status, NvAPI_ShortString);
Expand All @@ -22,8 +14,6 @@ typedef NvAPI_Status (*NvAPI_Unload_t)();

/***** ***** ***** ***** ***** VARIABLES ***** ***** ***** ***** *****/

static void * lib;

static NvAPI_EnumPhysicalGPUs_t _NvAPI_EnumPhysicalGPUs;
static NvAPI_GPU_SetForcePstate_t _NvAPI_GPU_SetForcePstate;
static NvAPI_GetErrorMessage_t _NvAPI_GetErrorMessage;
Expand Down Expand Up @@ -65,53 +55,6 @@ NvAPI_Status NvAPI_GetErrorMessage(NvAPI_Status nr, NvAPI_ShortString szDesc) {
}

NvAPI_Status NvAPI_Initialize() {
// Check the platform and load the appropriate NvAPI library
#ifdef _WIN32
if (!lib) {
lib = LoadLibrary("nvapi64.dll");
}

if (!lib) {
lib = LoadLibrary("nvapi.dll");
}
#elif __linux__
if (!lib) {
lib = dlopen("libnvidia-api.so.1", RTLD_LAZY);
}

if (!lib) {
lib = dlopen("libnvidia-api.so", RTLD_LAZY);
}
#endif

// If the library handle is still not initialized, loading the library failed
if (!lib) {
// Print an error message indicating failure to load the NvAPI library
fprintf(stderr, "Unable to load NvAPI library\n");

// Return an error status indicating that the library was not found
return NVAPI_LIBRARY_NOT_FOUND;
}

// Declare a function pointer for nvapi_QueryInterface
nvapi_QueryInterface_t nvapi_QueryInterface;

// Get the address of the nvapi_QueryInterface function from the loaded library
#ifdef _WIN32
nvapi_QueryInterface = (nvapi_QueryInterface_t) GetProcAddress((HMODULE) lib, "nvapi_QueryInterface");
#elif __linux__
nvapi_QueryInterface = (nvapi_QueryInterface_t) dlsym(lib, "nvapi_QueryInterface");
#endif

// If the function pointer is still null, gathering the address failed
if (!nvapi_QueryInterface) {
// Print an error message indicating failure to gather the function address
fprintf(stderr, "Unable to retrieve nvapi_QueryInterface function\n");

// Return an error status indicating that the library was not found
return NVAPI_LIBRARY_NOT_FOUND;
}

// Retrieve the addresses of specific NvAPI functions using nvapi_QueryInterface
_NvAPI_EnumPhysicalGPUs = (NvAPI_EnumPhysicalGPUs_t) nvapi_QueryInterface(0xe5ac921f);
_NvAPI_GPU_SetForcePstate = (NvAPI_GPU_SetForcePstate_t) nvapi_QueryInterface(0x025bfb10);
Expand All @@ -135,22 +78,12 @@ NvAPI_Status NvAPI_Unload() {

// If the function call was successful, proceed with cleanup
if (ret == NVAPI_OK) {
// If the library handle is initialized
if (lib) {
// Nullify all the function pointers to prevent further use
_NvAPI_EnumPhysicalGPUs = NULL;
_NvAPI_GPU_SetForcePstate = NULL;
_NvAPI_GetErrorMessage = NULL;
_NvAPI_Initialize = NULL;
_NvAPI_Unload = NULL;

// Free the loaded library based on the platform
#ifdef _WIN32
FreeLibrary((HMODULE) lib);
#elif __linux__
dlclose(lib);
#endif
}
// Nullify all the function pointers to prevent further use
_NvAPI_EnumPhysicalGPUs = NULL;
_NvAPI_GPU_SetForcePstate = NULL;
_NvAPI_GetErrorMessage = NULL;
_NvAPI_Initialize = NULL;
_NvAPI_Unload = NULL;
}

// Return the status of the function call
Expand Down
4 changes: 4 additions & 0 deletions src/nvapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,8 @@

/***** ***** ***** ***** ***** FUNCTIONS ***** ***** ***** ***** *****/

// Queries a function pointer from NVAPI by function offset
void * nvapi_QueryInterface(NvU32 FunctionOffset);

// Sets the forced performance state for a GPU
NvAPI_Status NvAPI_GPU_SetForcePstate(NvPhysicalGpuHandle hPhysicalGpu, NvU32 pstateId, NvU32 fallbackState);

0 comments on commit 3a1a180

Please sign in to comment.