NVIDIA/go-nvml

Go Bindings for the NVIDIA Management Library (NVML)

What the project is

NVIDIA/go‑nvml is a Go‑language wrapper around NVIDIA’s NVML (NVIDIA Management Library). NVML is a C API that lives in the driver‑provided shared library libnvidia‑ml.so and lets programs query and control NVIDIA GPUs (temperature, utilization, power limits, UUIDs, etc.). This repository does not re‑implement NVML; it simply exposes the existing C functions to Go code via cgo and a small amount of hand‑written “wrapper” code that makes the API more Go‑idiomatic.

Who would use it

  • Go developers building monitoring, orchestration, or scheduling tools that need to see what GPUs are present on a Linux host.
  • Operators of AI/ML clusters who want to write custom health‑checks, auto‑scalers, or resource‑allocation services in Go.
  • Anyone writing Go‑based inference or training pipelines that need to pin work to a specific GPU or read power/temperature metrics.

How it works (high‑level)

  1. Generation step – The repository ships a copy of the NVIDIA header nvml.h and a c‑for‑go description file (nvml.yml). Running the c‑for‑go tool automatically produces low‑level Go bindings that mirror each C function.
  2. Dynamic loading – At runtime, the package loads libnvidia‑ml.so from the host system (the driver must be installed). It also detects which versioned symbols (e.g., nvmlInit_v2) are present and swaps the default v1 symbols for the newer ones.
  3. Manual wrappers – The auto‑generated bindings are very close to the raw C API and are cumbersome to use directly. The project adds a thin layer of hand‑written wrappers (e.g., Device.GetUUID(), Device.GetAccountingPids()) that handle buffer allocation, error conversion, and Go‑style return values.
  4. Error handling – The NVML return codes are wrapped in a Go error type so callers can use the familiar if err != nil pattern.

Quick example (from the README)

import (
    "fmt"
    "log"
    "github.com/NVIDIA/go-nvml/pkg/nvml"
)

func main() {
    if ret := nvml.Init(); ret != nvml.SUCCESS {
        log.Fatalf("NVML init failed: %v", nvml.ErrorString(ret))
    }
    defer nvml.Shutdown()

    count, _ := nvml.DeviceGetCount()
    for i := 0; i < count; i++ {
        dev, _ := nvml.DeviceGetHandleByIndex(i)
        uuid, _ := dev.GetUUID()
        fmt.Println(uuid)
    }
}

Running this on a machine with NVIDIA drivers prints the UUID of every GPU, exactly as shown in the README.

Build & test workflow

  • Install the c‑for‑go tool (the Makefile pins a specific version).
  • Run make – this regenerates the bindings and copies them into pkg/nvml.
  • Run make test – executes a small test suite that checks initialization, driver version queries, event‑set handling, etc. The tests run fine even without an actual GPU driver; they only need the shared library to be loadable.

Limitations

  • Linux‑only – The bindings rely on libnvidia‑ml.so, which is only shipped on Linux drivers.
  • Runtime dependency – You can compile code without a driver, but calling any function will panic if the library cannot be found at runtime.
  • Sparse test coverage – The README notes that the test suite is minimal and could be expanded.

When you might not need it

If you are writing GPU‑aware software in Python, C++, or using NVIDIA’s own tooling (e.g., nvidia‑smi), you don’t need this Go wrapper. It’s specifically for Go projects that want direct, low‑overhead access to NVML.


All details above are taken directly from the repository’s README; no additional features have been inferred.

Related

  • Project
  • Project
  • Project
  • Dispatch
  • Project