Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added power limit related methods #6

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions bindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,31 @@ nvmlReturn_t nvmlDeviceGetPowerUsage(nvmlDevice_t device, unsigned int *power) {
return nvmlDeviceGetPowerUsageFunc(device, power);
}

nvmlReturn_t (*nvmlDeviceGetPowerManagementLimitFunc)(nvmlDevice_t device, unsigned int *power);
nvmlReturn_t nvmlDeviceGetPowerManagementLimit(nvmlDevice_t device, unsigned int *power) {
if (nvmlDeviceGetPowerManagementLimitFunc == NULL) {
return NVML_ERROR_FUNCTION_NOT_FOUND;
}
return nvmlDeviceGetPowerManagementLimitFunc(device, power);
}

nvmlReturn_t (*nvmlDeviceGetPowerManagementLimitConstraintsFunc)(nvmlDevice_t device, unsigned int *minLimit, unsigned int *maxLimit);
nvmlReturn_t nvmlDeviceGetPowerManagementLimitConstraints(nvmlDevice_t device, unsigned int *minLimit, unsigned int *maxLimit) {
if (nvmlDeviceGetPowerManagementLimitConstraintsFunc == NULL) {
return NVML_ERROR_FUNCTION_NOT_FOUND;
}
return nvmlDeviceGetPowerManagementLimitConstraintsFunc(device, minLimit, maxLimit);
}

nvmlReturn_t (*nvmlDeviceSetPowerManagementLimitFunc)(nvmlDevice_t device, unsigned int power);
nvmlReturn_t nvmlDeviceSetPowerManagementLimit(nvmlDevice_t device, unsigned int power) {
if (nvmlDeviceSetPowerManagementLimitFunc == NULL) {
return NVML_ERROR_FUNCTION_NOT_FOUND;
}
return nvmlDeviceSetPowerManagementLimitFunc(device, power);
}


nvmlReturn_t (*nvmlDeviceGetTemperatureFunc)(nvmlDevice_t device, nvmlTemperatureSensors_t sensorType, unsigned int *temp);
nvmlReturn_t nvmlDeviceGetTemperature(nvmlDevice_t device, nvmlTemperatureSensors_t sensorType, unsigned int *temp) {
if (nvmlDeviceGetTemperatureFunc == NULL) {
Expand Down Expand Up @@ -185,6 +210,18 @@ nvmlReturn_t nvmlInit_dl(void) {
if (nvmlDeviceGetPowerUsageFunc == NULL) {
return NVML_ERROR_FUNCTION_NOT_FOUND;
}
nvmlDeviceGetPowerManagementLimitFunc = dlsym(nvmlHandle, "nvmlDeviceGetPowerManagementLimit");
if (nvmlDeviceGetPowerManagementLimitFunc == NULL) {
return NVML_ERROR_FUNCTION_NOT_FOUND;
}
nvmlDeviceGetPowerManagementLimitConstraintsFunc = dlsym(nvmlHandle, "nvmlDeviceGetPowerManagementLimitConstraints");
if (nvmlDeviceGetPowerManagementLimitConstraintsFunc == NULL) {
return NVML_ERROR_FUNCTION_NOT_FOUND;
}
nvmlDeviceSetPowerManagementLimitFunc = dlsym(nvmlHandle, "nvmlDeviceSetPowerManagementLimit");
if (nvmlDeviceSetPowerManagementLimitFunc == NULL) {
return NVML_ERROR_FUNCTION_NOT_FOUND;
}
nvmlDeviceGetTemperatureFunc = dlsym(nvmlHandle, "nvmlDeviceGetTemperature");
if (nvmlDeviceGetTemperatureFunc == NULL) {
return NVML_ERROR_FUNCTION_NOT_FOUND;
Expand Down Expand Up @@ -429,6 +466,37 @@ func (d Device) PowerUsage() (uint, error) {
return uint(n), errorString(r)
}

// PowerLimit retrieves the power management limit associated with this device.
func (d Device) PowerLimit() (uint, error) {
if C.nvmlHandle == nil {
return 0, errLibraryNotLoaded
}
var n C.uint
r := C.nvmlDeviceGetPowerManagementLimit(d.dev, &n)
return uint(n), errorString(r)
}

// PowerLimitConstraints retrieves information about possible values of power management limits on this device.
func (d Device) PowerLimitConstraints() (uint, uint, error) {
if C.nvmlHandle == nil {
return 0, 0, errLibraryNotLoaded
}
var min C.uint
var max C.uint
r := C.nvmlDeviceGetPowerManagementLimitConstraints(d.dev, &min, &max)
return uint(min), uint(max), errorString(r)
}

// Set new power limit of this device.
func (d Device) SetPowerLimit(pl uint) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remove this method? I would like to keep this library to only read things and not change anything.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mindprince Sorry for even late comments :-) Why you do not want to have altering state functionality?


if C.nvmlHandle == nil {
return errLibraryNotLoaded
}
r := C.nvmlDeviceSetPowerManagementLimit(d.dev, C.uint(pl))
return errorString(r)
}

// AveragePowerUsage returns the power usage for this GPU and its associated circuitry
// in milliwatts averaged over the samples collected in the last `since` duration.
func (d Device) AveragePowerUsage(since time.Duration) (uint, error) {
Expand Down
22 changes: 22 additions & 0 deletions cmd/example/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,28 @@ func main() {
}
fmt.Printf("\tutilization.gpu: %v, utilization.memory: %v\n", gpuUtilization, memoryUtilization)

powerLimit, err := dev.PowerLimit()
if err != nil {
fmt.Printf("\tdev.PowerLimit() error: %v\n", err)
} else {
fmt.Printf("\tpower.limit: %v\n", powerLimit)
}

minLimit, maxLimit, err := dev.PowerLimitConstraints()
if err != nil {
fmt.Printf("\tdev.PowerLimitConstraints() error: %v\n", err)
} else {
fmt.Printf("\tpower.min_limit: %v\n", minLimit / 1000)
fmt.Printf("\tpower.max_limit: %v\n", maxLimit / 1000)
}

err = dev.SetPowerLimit(180000)
if err != nil {
fmt.Printf("\tdev.SetPowerLimit(%v) error: %v\n", powerLimit/1000, err)
} else {
fmt.Printf("\tnew power.limit: %v\n", powerLimit/1000)
}

powerDraw, err := dev.PowerUsage()
if err != nil {
fmt.Printf("\tdev.PowerUsage() error: %v\n", err)
Expand Down