Address golangci-lint warnings

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
This commit is contained in:
Carlos Eduardo Arango Gutierrez 2024-04-04 13:09:04 +02:00
parent ab773cb50a
commit 48789b76df
No known key found for this signature in database
GPG Key ID: 42D9CB42F300A852
34 changed files with 328 additions and 292 deletions

23
.golangci.yml Normal file
View File

@ -0,0 +1,23 @@
# please keep this alphabetized
linters:
enable:
- asciicheck
- contextcheck
- godot
- gofmt
- goimports
- misspell
# TODO: re-enable once we have addressed the warnings
disable:
- unused
- gocritic
- stylecheck
- forcetypeassert
run:
tests: true
timeout: 10m
linters-settings:
goimports:
local-prefixes: "github.com/NVIDIA/go-nvlib"

View File

@ -20,7 +20,7 @@ PCI_IDS_URL ?= https://pci-ids.ucw.cz/v2.2/pci.ids
TARGETS := binary build all check fmt assert-fmt generate lint vet test coverage TARGETS := binary build all check fmt assert-fmt generate lint vet test coverage
DOCKER_TARGETS := $(patsubst %,docker-%, $(TARGETS)) DOCKER_TARGETS := $(patsubst %,docker-%, $(TARGETS))
.PHONY: $(TARGETS) $(DOCKER_TARGETS) .PHONY: $(TARGETS) $(DOCKER_TARGETS) vendor check-vendor
GOOS := linux GOOS := linux
@ -30,6 +30,11 @@ build:
all: check build binary all: check build binary
check: assert-fmt lint vet check: assert-fmt lint vet
vendor:
go mod tidy
go mod vendor
go mod verify
check-vendor: vendor check-vendor: vendor
git diff --quiet HEAD -- go.mod go.sum vendor git diff --quiet HEAD -- go.mod go.sum vendor
@ -57,6 +62,14 @@ lint:
# We use `go list -f '{{.Dir}}' $(MODULE)/...` to skip the `vendor` folder. # We use `go list -f '{{.Dir}}' $(MODULE)/...` to skip the `vendor` folder.
go list -f '{{.Dir}}' $(MODULE)/... | grep -v pkg/nvml | xargs golint -set_exit_status go list -f '{{.Dir}}' $(MODULE)/... | grep -v pkg/nvml | xargs golint -set_exit_status
## goimports: Apply goimports -local to the codebase
goimports:
find . -name \*.go \
-not -name "zz_generated.deepcopy.go" \
-not -path "./vendor/*" \
-not -path "./pkg/nvidia.com/resource/clientset/versioned/*" \
-exec goimports -local $(MODULE) -w {} \;
vet: vet:
go vet $(MODULE)/... go vet $(MODULE)/...
@ -89,6 +102,7 @@ $(DOCKER_TARGETS): docker-%:
--rm \ --rm \
-e GOCACHE=/tmp/.cache/go \ -e GOCACHE=/tmp/.cache/go \
-e GOMODCACHE=/tmp/.cache/gomod \ -e GOMODCACHE=/tmp/.cache/gomod \
-e GOLANGCI_LINT_CACHE=/tmp/.cache/golangci-lint \
-v $(PWD):/work \ -v $(PWD):/work \
-w /work \ -w /work \
--user $$(id -u):$$(id -g) \ --user $$(id -u):$$(id -g) \

View File

@ -1,18 +0,0 @@
# Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
ARG GOLANG_VERSION=1.21.1
FROM golang:${GOLANG_VERSION}
RUN go install golang.org/x/lint/golint@latest
RUN go install github.com/matryer/moq@v0.2.7

View File

@ -20,7 +20,7 @@ import (
"github.com/NVIDIA/go-nvlib/pkg/nvml" "github.com/NVIDIA/go-nvlib/pkg/nvml"
) )
// Interface provides the API to the 'device' package // Interface provides the API to the 'device' package.
type Interface interface { type Interface interface {
AssertValidMigProfileFormat(profile string) error AssertValidMigProfileFormat(profile string) error
GetDevices() ([]Device, error) GetDevices() ([]Device, error)
@ -46,7 +46,7 @@ type devicelib struct {
var _ Interface = &devicelib{} var _ Interface = &devicelib{}
// New creates a new instance of the 'device' interface // New creates a new instance of the 'device' interface.
func New(opts ...Option) Interface { func New(opts ...Option) Interface {
d := &devicelib{} d := &devicelib{}
for _, opt := range opts { for _, opt := range opts {
@ -68,21 +68,21 @@ func New(opts ...Option) Interface {
return d return d
} }
// WithNvml provides an Option to set the NVML library used by the 'device' interface // WithNvml provides an Option to set the NVML library used by the 'device' interface.
func WithNvml(nvml nvml.Interface) Option { func WithNvml(nvml nvml.Interface) Option {
return func(d *devicelib) { return func(d *devicelib) {
d.nvml = nvml d.nvml = nvml
} }
} }
// WithVerifySymbols provides an option to toggle whether to verify select symbols exist in dynamic libraries before calling them // WithVerifySymbols provides an option to toggle whether to verify select symbols exist in dynamic libraries before calling them.
func WithVerifySymbols(verify bool) Option { func WithVerifySymbols(verify bool) Option {
return func(d *devicelib) { return func(d *devicelib) {
d.verifySymbols = &verify d.verifySymbols = &verify
} }
} }
// WithSkippedDevices provides an Option to set devices to be skipped by model name // WithSkippedDevices provides an Option to set devices to be skipped by model name.
func WithSkippedDevices(names ...string) Option { func WithSkippedDevices(names ...string) Option {
return func(d *devicelib) { return func(d *devicelib) {
if d.skippedDevices == nil { if d.skippedDevices == nil {
@ -94,5 +94,5 @@ func WithSkippedDevices(names ...string) Option {
} }
} }
// Option defines a function for passing options to the New() call // Option defines a function for passing options to the New() call.
type Option func(*devicelib) type Option func(*devicelib)

View File

@ -22,7 +22,7 @@ import (
"github.com/NVIDIA/go-nvlib/pkg/nvml" "github.com/NVIDIA/go-nvlib/pkg/nvml"
) )
// Device defines the set of extended functions associated with a device.Device // Device defines the set of extended functions associated with a device.Device.
type Device interface { type Device interface {
nvml.Device nvml.Device
GetArchitectureAsString() (string, error) GetArchitectureAsString() (string, error)
@ -44,12 +44,12 @@ type device struct {
var _ Device = &device{} var _ Device = &device{}
// NewDevice builds a new Device from an nvml.Device // NewDevice builds a new Device from an nvml.Device.
func (d *devicelib) NewDevice(dev nvml.Device) (Device, error) { func (d *devicelib) NewDevice(dev nvml.Device) (Device, error) {
return d.newDevice(dev) return d.newDevice(dev)
} }
// NewDeviceByUUID builds a new Device from a UUID // NewDeviceByUUID builds a new Device from a UUID.
func (d *devicelib) NewDeviceByUUID(uuid string) (Device, error) { func (d *devicelib) NewDeviceByUUID(uuid string) (Device, error) {
dev, ret := d.nvml.DeviceGetHandleByUUID(uuid) dev, ret := d.nvml.DeviceGetHandleByUUID(uuid)
if ret != nvml.SUCCESS { if ret != nvml.SUCCESS {
@ -58,12 +58,12 @@ func (d *devicelib) NewDeviceByUUID(uuid string) (Device, error) {
return d.newDevice(dev) return d.newDevice(dev)
} }
// newDevice creates a device from an nvml.Device // newDevice creates a device from an nvml.Device.
func (d *devicelib) newDevice(dev nvml.Device) (*device, error) { func (d *devicelib) newDevice(dev nvml.Device) (*device, error) {
return &device{dev, d, nil}, nil return &device{dev, d, nil}, nil
} }
// GetArchitectureAsString returns the Device architecture as a string // GetArchitectureAsString returns the Device architecture as a string.
func (d *device) GetArchitectureAsString() (string, error) { func (d *device) GetArchitectureAsString() (string, error) {
arch, ret := d.GetArchitecture() arch, ret := d.GetArchitecture()
if ret != nvml.SUCCESS { if ret != nvml.SUCCESS {
@ -92,7 +92,7 @@ func (d *device) GetArchitectureAsString() (string, error) {
return "", fmt.Errorf("error interpreting device architecture as string: %v", arch) return "", fmt.Errorf("error interpreting device architecture as string: %v", arch)
} }
// GetBrandAsString returns the Device architecture as a string // GetBrandAsString returns the Device architecture as a string.
func (d *device) GetBrandAsString() (string, error) { func (d *device) GetBrandAsString() (string, error) {
brand, ret := d.GetBrand() brand, ret := d.GetBrand()
if ret != nvml.SUCCESS { if ret != nvml.SUCCESS {
@ -140,7 +140,7 @@ func (d *device) GetBrandAsString() (string, error) {
return "", fmt.Errorf("error interpreting device brand as string: %v", brand) return "", fmt.Errorf("error interpreting device brand as string: %v", brand)
} }
// GetCudaComputeCapabilityAsString returns the Device's CUDA compute capability as a version string // GetCudaComputeCapabilityAsString returns the Device's CUDA compute capability as a version string.
func (d *device) GetCudaComputeCapabilityAsString() (string, error) { func (d *device) GetCudaComputeCapabilityAsString() (string, error) {
major, minor, ret := d.GetCudaComputeCapability() major, minor, ret := d.GetCudaComputeCapability()
if ret != nvml.SUCCESS { if ret != nvml.SUCCESS {
@ -149,7 +149,7 @@ func (d *device) GetCudaComputeCapabilityAsString() (string, error) {
return fmt.Sprintf("%d.%d", major, minor), nil return fmt.Sprintf("%d.%d", major, minor), nil
} }
// IsMigCapable checks if a device is capable of having MIG paprtitions created on it // IsMigCapable checks if a device is capable of having MIG paprtitions created on it.
func (d *device) IsMigCapable() (bool, error) { func (d *device) IsMigCapable() (bool, error) {
if !d.lib.hasSymbol("nvmlDeviceGetMigMode") { if !d.lib.hasSymbol("nvmlDeviceGetMigMode") {
return false, nil return false, nil
@ -166,7 +166,7 @@ func (d *device) IsMigCapable() (bool, error) {
return true, nil return true, nil
} }
// IsMigEnabled checks if a device has MIG mode currently enabled on it // IsMigEnabled checks if a device has MIG mode currently enabled on it.
func (d *device) IsMigEnabled() (bool, error) { func (d *device) IsMigEnabled() (bool, error) {
if !d.lib.hasSymbol("nvmlDeviceGetMigMode") { if !d.lib.hasSymbol("nvmlDeviceGetMigMode") {
return false, nil return false, nil
@ -183,7 +183,7 @@ func (d *device) IsMigEnabled() (bool, error) {
return (mode == nvml.DEVICE_MIG_ENABLE), nil return (mode == nvml.DEVICE_MIG_ENABLE), nil
} }
// VisitMigDevices walks a top-level device and invokes a callback function for each MIG device configured on it // VisitMigDevices walks a top-level device and invokes a callback function for each MIG device configured on it.
func (d *device) VisitMigDevices(visit func(int, MigDevice) error) error { func (d *device) VisitMigDevices(visit func(int, MigDevice) error) error {
capable, err := d.IsMigCapable() capable, err := d.IsMigCapable()
if err != nil { if err != nil {
@ -221,7 +221,7 @@ func (d *device) VisitMigDevices(visit func(int, MigDevice) error) error {
return nil return nil
} }
// VisitMigProfiles walks a top-level device and invokes a callback function for each unique MIG Profile that can be configured on it // VisitMigProfiles walks a top-level device and invokes a callback function for each unique MIG Profile that can be configured on it.
func (d *device) VisitMigProfiles(visit func(MigProfile) error) error { func (d *device) VisitMigProfiles(visit func(MigProfile) error) error {
capable, err := d.IsMigCapable() capable, err := d.IsMigCapable()
if err != nil { if err != nil {
@ -283,7 +283,7 @@ func (d *device) VisitMigProfiles(visit func(MigProfile) error) error {
return nil return nil
} }
// GetMigDevices gets the set of MIG devices associated with a top-level device // GetMigDevices gets the set of MIG devices associated with a top-level device.
func (d *device) GetMigDevices() ([]MigDevice, error) { func (d *device) GetMigDevices() ([]MigDevice, error) {
var migs []MigDevice var migs []MigDevice
err := d.VisitMigDevices(func(j int, m MigDevice) error { err := d.VisitMigDevices(func(j int, m MigDevice) error {
@ -296,7 +296,7 @@ func (d *device) GetMigDevices() ([]MigDevice, error) {
return migs, nil return migs, nil
} }
// GetMigProfiles gets the set of unique MIG profiles associated with a top-level device // GetMigProfiles gets the set of unique MIG profiles associated with a top-level device.
func (d *device) GetMigProfiles() ([]MigProfile, error) { func (d *device) GetMigProfiles() ([]MigProfile, error) {
// Return the cached list if available // Return the cached list if available
if d.migProfiles != nil { if d.migProfiles != nil {
@ -313,7 +313,7 @@ func (d *device) GetMigProfiles() ([]MigProfile, error) {
return nil, err return nil, err
} }
// And cache it before returning // And cache it before returning.
d.migProfiles = profiles d.migProfiles = profiles
return profiles, nil return profiles, nil
} }
@ -332,7 +332,7 @@ func (d *device) isSkipped() (bool, error) {
return false, nil return false, nil
} }
// VisitDevices visits each top-level device and invokes a callback function for it // VisitDevices visits each top-level device and invokes a callback function for it.
func (d *devicelib) VisitDevices(visit func(int, Device) error) error { func (d *devicelib) VisitDevices(visit func(int, Device) error) error {
count, ret := d.nvml.DeviceGetCount() count, ret := d.nvml.DeviceGetCount()
if ret != nvml.SUCCESS { if ret != nvml.SUCCESS {
@ -365,7 +365,7 @@ func (d *devicelib) VisitDevices(visit func(int, Device) error) error {
return nil return nil
} }
// VisitMigDevices walks a top-level device and invokes a callback function for each MIG device configured on it // VisitMigDevices walks a top-level device and invokes a callback function for each MIG device configured on it.
func (d *devicelib) VisitMigDevices(visit func(int, Device, int, MigDevice) error) error { func (d *devicelib) VisitMigDevices(visit func(int, Device, int, MigDevice) error) error {
err := d.VisitDevices(func(i int, dev Device) error { err := d.VisitDevices(func(i int, dev Device) error {
err := dev.VisitMigDevices(func(j int, mig MigDevice) error { err := dev.VisitMigDevices(func(j int, mig MigDevice) error {
@ -386,7 +386,7 @@ func (d *devicelib) VisitMigDevices(visit func(int, Device, int, MigDevice) erro
return nil return nil
} }
// VisitMigProfiles walks a top-level device and invokes a callback function for each unique MIG profile found on them // VisitMigProfiles walks a top-level device and invokes a callback function for each unique MIG profile found on them.
func (d *devicelib) VisitMigProfiles(visit func(MigProfile) error) error { func (d *devicelib) VisitMigProfiles(visit func(MigProfile) error) error {
visited := make(map[string]bool) visited := make(map[string]bool)
err := d.VisitDevices(func(i int, dev Device) error { err := d.VisitDevices(func(i int, dev Device) error {
@ -414,7 +414,7 @@ func (d *devicelib) VisitMigProfiles(visit func(MigProfile) error) error {
return nil return nil
} }
// GetDevices gets the set of all top-level devices // GetDevices gets the set of all top-level devices.
func (d *devicelib) GetDevices() ([]Device, error) { func (d *devicelib) GetDevices() ([]Device, error) {
var devs []Device var devs []Device
err := d.VisitDevices(func(i int, dev Device) error { err := d.VisitDevices(func(i int, dev Device) error {
@ -427,7 +427,7 @@ func (d *devicelib) GetDevices() ([]Device, error) {
return devs, nil return devs, nil
} }
// GetMigDevices gets the set of MIG devices across all top-level devices // GetMigDevices gets the set of MIG devices across all top-level devices.
func (d *devicelib) GetMigDevices() ([]MigDevice, error) { func (d *devicelib) GetMigDevices() ([]MigDevice, error) {
var migs []MigDevice var migs []MigDevice
err := d.VisitMigDevices(func(i int, dev Device, j int, m MigDevice) error { err := d.VisitMigDevices(func(i int, dev Device, j int, m MigDevice) error {
@ -440,7 +440,7 @@ func (d *devicelib) GetMigDevices() ([]MigDevice, error) {
return migs, nil return migs, nil
} }
// GetMigProfiles gets the set of unique MIG profiles across all top-level devices // GetMigProfiles gets the set of unique MIG profiles across all top-level devices.
func (d *devicelib) GetMigProfiles() ([]MigProfile, error) { func (d *devicelib) GetMigProfiles() ([]MigProfile, error) {
// Return the cached list if available // Return the cached list if available
if d.migProfiles != nil { if d.migProfiles != nil {
@ -457,7 +457,7 @@ func (d *devicelib) GetMigProfiles() ([]MigProfile, error) {
return nil, err return nil, err
} }
// And cache it before returning // And cache it before returning.
d.migProfiles = profiles d.migProfiles = profiles
return profiles, nil return profiles, nil
} }

View File

@ -27,7 +27,7 @@ import (
// This includes a device index or UUID. // This includes a device index or UUID.
type Identifier string type Identifier string
// IsGpuIndex checks if an identifier is a full GPU index // IsGpuIndex checks if an identifier is a full GPU index.
func (i Identifier) IsGpuIndex() bool { func (i Identifier) IsGpuIndex() bool {
if _, err := strconv.ParseUint(string(i), 10, 0); err != nil { if _, err := strconv.ParseUint(string(i), 10, 0); err != nil {
return false return false
@ -35,7 +35,7 @@ func (i Identifier) IsGpuIndex() bool {
return true return true
} }
// IsMigIndex checks if an identifier is a MIG index // IsMigIndex checks if an identifier is a MIG index.
func (i Identifier) IsMigIndex() bool { func (i Identifier) IsMigIndex() bool {
split := strings.Split(string(i), ":") split := strings.Split(string(i), ":")
if len(split) != 2 { if len(split) != 2 {
@ -49,13 +49,13 @@ func (i Identifier) IsMigIndex() bool {
return true return true
} }
// IsUUID checks if an identifier is a UUID // IsUUID checks if an identifier is a UUID.
func (i Identifier) IsUUID() bool { func (i Identifier) IsUUID() bool {
return i.IsGpuUUID() || i.IsMigUUID() return i.IsGpuUUID() || i.IsMigUUID()
} }
// IsGpuUUID checks if an identifier is a GPU UUID // IsGpuUUID checks if an identifier is a GPU UUID.
// A GPU UUID must be of the form GPU-b1028956-cfa2-0990-bf4a-5da9abb51763 // A GPU UUID must be of the form GPU-b1028956-cfa2-0990-bf4a-5da9abb51763.
func (i Identifier) IsGpuUUID() bool { func (i Identifier) IsGpuUUID() bool {
if !strings.HasPrefix(string(i), "GPU-") { if !strings.HasPrefix(string(i), "GPU-") {
return false return false
@ -64,7 +64,7 @@ func (i Identifier) IsGpuUUID() bool {
return err == nil return err == nil
} }
// IsMigUUID checks if an identifier is a MIG UUID // IsMigUUID checks if an identifier is a MIG UUID.
// A MIG UUID can be of one of two forms: // A MIG UUID can be of one of two forms:
// - MIG-b1028956-cfa2-0990-bf4a-5da9abb51763 // - MIG-b1028956-cfa2-0990-bf4a-5da9abb51763
// - MIG-GPU-b1028956-cfa2-0990-bf4a-5da9abb51763/3/0 // - MIG-GPU-b1028956-cfa2-0990-bf4a-5da9abb51763/3/0

View File

@ -22,7 +22,7 @@ import (
"github.com/NVIDIA/go-nvlib/pkg/nvml" "github.com/NVIDIA/go-nvlib/pkg/nvml"
) )
// MigDevice defines the set of extended functions associated with a MIG device // MigDevice defines the set of extended functions associated with a MIG device.
type MigDevice interface { type MigDevice interface {
nvml.Device nvml.Device
GetProfile() (MigProfile, error) GetProfile() (MigProfile, error)
@ -36,7 +36,7 @@ type migdevice struct {
var _ MigDevice = &migdevice{} var _ MigDevice = &migdevice{}
// NewMigDevice builds a new MigDevice from an nvml.Device // NewMigDevice builds a new MigDevice from an nvml.Device.
func (d *devicelib) NewMigDevice(handle nvml.Device) (MigDevice, error) { func (d *devicelib) NewMigDevice(handle nvml.Device) (MigDevice, error) {
isMig, ret := handle.IsMigDeviceHandle() isMig, ret := handle.IsMigDeviceHandle()
if ret != nvml.SUCCESS { if ret != nvml.SUCCESS {
@ -48,7 +48,7 @@ func (d *devicelib) NewMigDevice(handle nvml.Device) (MigDevice, error) {
return &migdevice{handle, d, nil}, nil return &migdevice{handle, d, nil}, nil
} }
// NewMigDeviceByUUID builds a new MigDevice from a UUID // NewMigDeviceByUUID builds a new MigDevice from a UUID.
func (d *devicelib) NewMigDeviceByUUID(uuid string) (MigDevice, error) { func (d *devicelib) NewMigDeviceByUUID(uuid string) (MigDevice, error) {
dev, ret := d.nvml.DeviceGetHandleByUUID(uuid) dev, ret := d.nvml.DeviceGetHandleByUUID(uuid)
if ret != nvml.SUCCESS { if ret != nvml.SUCCESS {
@ -57,7 +57,7 @@ func (d *devicelib) NewMigDeviceByUUID(uuid string) (MigDevice, error) {
return d.NewMigDevice(dev) return d.NewMigDevice(dev)
} }
// GetProfile returns the MIG profile associated with a MIG device // GetProfile returns the MIG profile associated with a MIG device.
func (m *migdevice) GetProfile() (MigProfile, error) { func (m *migdevice) GetProfile() (MigProfile, error) {
if m.profile != nil { if m.profile != nil {
return m.profile, nil return m.profile, nil

View File

@ -40,7 +40,7 @@ type MigProfile interface {
Matches(profile string) bool Matches(profile string) bool
} }
// MigProfileInfo holds all info associated with a specific MIG profile // MigProfileInfo holds all info associated with a specific MIG profile.
type MigProfileInfo struct { type MigProfileInfo struct {
C int C int
G int G int
@ -119,13 +119,13 @@ func (d *devicelib) NewMigProfile(giProfileID, ciProfileID, ciEngProfileID int,
return p, nil return p, nil
} }
// AssertValidMigProfileFormat checks if the string is in the proper format to represent a MIG profile // AssertValidMigProfileFormat checks if the string is in the proper format to represent a MIG profile.
func (d *devicelib) AssertValidMigProfileFormat(profile string) error { func (d *devicelib) AssertValidMigProfileFormat(profile string) error {
_, _, _, _, err := parseMigProfile(profile) _, _, _, _, err := parseMigProfile(profile)
return err return err
} }
// ParseMigProfile converts a string representation of a MigProfile into an object // ParseMigProfile converts a string representation of a MigProfile into an object.
func (d *devicelib) ParseMigProfile(profile string) (MigProfile, error) { func (d *devicelib) ParseMigProfile(profile string) (MigProfile, error) {
profiles, err := d.GetMigProfiles() profiles, err := d.GetMigProfiles()
if err != nil { if err != nil {
@ -141,7 +141,7 @@ func (d *devicelib) ParseMigProfile(profile string) (MigProfile, error) {
return nil, fmt.Errorf("unable to parse profile string into a valid profile") return nil, fmt.Errorf("unable to parse profile string into a valid profile")
} }
// String returns the string representation of a Profile // String returns the string representation of a Profile.
func (p MigProfileInfo) String() string { func (p MigProfileInfo) String() string {
var suffix string var suffix string
if len(p.Attributes) > 0 { if len(p.Attributes) > 0 {
@ -153,12 +153,12 @@ func (p MigProfileInfo) String() string {
return fmt.Sprintf("%dc.%dg.%dgb%s", p.C, p.G, p.GB, suffix) return fmt.Sprintf("%dc.%dg.%dgb%s", p.C, p.G, p.GB, suffix)
} }
// GetInfo returns detailed info about a Profile // GetInfo returns detailed info about a Profile.
func (p MigProfileInfo) GetInfo() MigProfileInfo { func (p MigProfileInfo) GetInfo() MigProfileInfo {
return p return p
} }
// Equals checks if two Profiles are identical or not // Equals checks if two Profiles are identical or not.
func (p MigProfileInfo) Equals(other MigProfile) bool { func (p MigProfileInfo) Equals(other MigProfile) bool {
o := other.GetInfo() o := other.GetInfo()
if p.C != o.C { if p.C != o.C {
@ -182,7 +182,7 @@ func (p MigProfileInfo) Equals(other MigProfile) bool {
return true return true
} }
// Matches checks if a MigProfile matches the string passed in // Matches checks if a MigProfile matches the string passed in.
func (p MigProfileInfo) Matches(profile string) bool { func (p MigProfileInfo) Matches(profile string) bool {
c, g, gb, attrs, err := parseMigProfile(profile) c, g, gb, attrs, err := parseMigProfile(profile)
if err != nil { if err != nil {
@ -211,26 +211,26 @@ func (p MigProfileInfo) Matches(profile string) bool {
} }
func parseMigProfile(profile string) (int, int, int, []string, error) { func parseMigProfile(profile string) (int, int, int, []string, error) {
// If we are handed the empty string, we cannot parse it // If we are handed the empty string, we cannot parse it.
if profile == "" { if profile == "" {
return -1, -1, -1, nil, fmt.Errorf("profile is the empty string") return -1, -1, -1, nil, fmt.Errorf("profile is the empty string")
} }
// Split by + to separate out attributes // Split by + to separate out attributes.
split := strings.SplitN(profile, "+", 2) split := strings.SplitN(profile, "+", 2)
// Check to make sure the c, g, and gb values match // Check to make sure the c, g, and gb values match.
c, g, gb, err := parseMigProfileFields(split[0]) c, g, gb, err := parseMigProfileFields(split[0])
if err != nil { if err != nil {
return -1, -1, -1, nil, fmt.Errorf("cannot parse fields of '%v': %v", profile, err) return -1, -1, -1, nil, fmt.Errorf("cannot parse fields of '%v': %v", profile, err)
} }
// If we have no attributes we are done // If we have no attributes we are done.
if len(split) == 1 { if len(split) == 1 {
return c, g, gb, nil, nil return c, g, gb, nil, nil
} }
// Make sure we have the same set of attributes // Make sure we have the same set of attributes.
attrs, err := parseMigProfileAttributes(split[1]) attrs, err := parseMigProfileAttributes(split[1])
if err != nil { if err != nil {
return -1, -1, -1, nil, fmt.Errorf("cannot parse attributes of '%v': %v", profile, err) return -1, -1, -1, nil, fmt.Errorf("cannot parse attributes of '%v': %v", profile, err)

View File

@ -20,8 +20,9 @@ import (
"fmt" "fmt"
"testing" "testing"
"github.com/NVIDIA/go-nvlib/pkg/nvml"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/NVIDIA/go-nvlib/pkg/nvml"
) )
type MigProfileInfoWrapper struct { type MigProfileInfoWrapper struct {

View File

@ -25,7 +25,7 @@ import (
"github.com/NVIDIA/go-nvml/pkg/dl" "github.com/NVIDIA/go-nvml/pkg/dl"
) )
// Interface provides the API to the info package // Interface provides the API to the info package.
type Interface interface { type Interface interface {
HasDXCore() (bool, string) HasDXCore() (bool, string)
HasNvml() (bool, string) HasNvml() (bool, string)
@ -50,7 +50,7 @@ func (i *infolib) HasDXCore() (bool, string) {
return true, "found DXCore library" return true, "found DXCore library"
} }
// HasNvml returns true if NVML is detected on the system // HasNvml returns true if NVML is detected on the system.
func (i *infolib) HasNvml() (bool, string) { func (i *infolib) HasNvml() (bool, string) {
const ( const (
libraryName = "libnvidia-ml.so.1" libraryName = "libnvidia-ml.so.1"
@ -62,7 +62,7 @@ func (i *infolib) HasNvml() (bool, string) {
return true, "found NVML library" return true, "found NVML library"
} }
// IsTegraSystem returns true if the system is detected as a Tegra-based system // IsTegraSystem returns true if the system is detected as a Tegra-based system.
func (i *infolib) IsTegraSystem() (bool, string) { func (i *infolib) IsTegraSystem() (bool, string) {
tegraReleaseFile := filepath.Join(i.root, "/etc/nv_tegra_release") tegraReleaseFile := filepath.Join(i.root, "/etc/nv_tegra_release")
tegraFamilyFile := filepath.Join(i.root, "/sys/devices/soc0/family") tegraFamilyFile := filepath.Join(i.root, "/sys/devices/soc0/family")
@ -87,7 +87,7 @@ func (i *infolib) IsTegraSystem() (bool, string) {
return false, fmt.Sprintf("%v has no 'tegra' prefix", tegraFamilyFile) return false, fmt.Sprintf("%v has no 'tegra' prefix", tegraFamilyFile)
} }
// assertHasLibrary returns an error if the specified library cannot be loaded // assertHasLibrary returns an error if the specified library cannot be loaded.
func assertHasLibrary(libraryName string) error { func assertHasLibrary(libraryName string) error {
const ( const (
libraryLoadFlags = dl.RTLD_LAZY libraryLoadFlags = dl.RTLD_LAZY

View File

@ -16,10 +16,10 @@
package info package info
// Option defines a function for passing options to the New() call // Option defines a function for passing options to the New() call.
type Option func(*infolib) type Option func(*infolib)
// New creates a new instance of the 'info' interface // New creates a new instance of the 'info' interface.
func New(opts ...Option) Interface { func New(opts ...Option) Interface {
i := &infolib{} i := &infolib{}
for _, opt := range opts { for _, opt := range opts {
@ -31,7 +31,7 @@ func New(opts ...Option) Interface {
return i return i
} }
// WithRoot provides a Option to set the root of the 'info' interface // WithRoot provides a Option to set the root of the 'info' interface.
func WithRoot(root string) Option { func WithRoot(root string) Option {
return func(i *infolib) { return func(i *infolib) {
i.root = root i.root = root

View File

@ -25,14 +25,14 @@ import (
"github.com/NVIDIA/go-nvlib/pkg/nvpci/bytes" "github.com/NVIDIA/go-nvlib/pkg/nvpci/bytes"
) )
// MockNvmdev mock mdev device // MockNvmdev mock mdev device.
type MockNvmdev struct { type MockNvmdev struct {
*nvmdev *nvmdev
} }
var _ Interface = (*MockNvmdev)(nil) var _ Interface = (*MockNvmdev)(nil)
// NewMock creates new mock mediated (vGPU) and parent PCI devices and removes old devices // NewMock creates new mock mediated (vGPU) and parent PCI devices and removes old devices.
func NewMock() (mock *MockNvmdev, rerr error) { func NewMock() (mock *MockNvmdev, rerr error) {
mdevParentsRootDir, err := os.MkdirTemp(os.TempDir(), "") mdevParentsRootDir, err := os.MkdirTemp(os.TempDir(), "")
if err != nil { if err != nil {
@ -60,13 +60,13 @@ func NewMock() (mock *MockNvmdev, rerr error) {
return mock, nil return mock, nil
} }
// Cleanup removes the mocked mediated (vGPU) and parent PCI devices root folders // Cleanup removes the mocked mediated (vGPU) and parent PCI devices root folders.
func (m *MockNvmdev) Cleanup() { func (m *MockNvmdev) Cleanup() {
os.RemoveAll(m.mdevParentsRoot) os.RemoveAll(m.mdevParentsRoot)
os.RemoveAll(m.mdevDevicesRoot) os.RemoveAll(m.mdevDevicesRoot)
} }
// AddMockA100Parent creates an A100 like parent GPU mock device // AddMockA100Parent creates an A100 like parent GPU mock device.
func (m *MockNvmdev) AddMockA100Parent(address string, numaNode int) error { func (m *MockNvmdev) AddMockA100Parent(address string, numaNode int) error {
deviceDir := filepath.Join(m.mdevParentsRoot, address) deviceDir := filepath.Join(m.mdevParentsRoot, address)
err := os.MkdirAll(deviceDir, 0755) err := os.MkdirAll(deviceDir, 0755)
@ -220,6 +220,9 @@ func (m *MockNvmdev) AddMockA100Mdev(uuid string, mdevType string, mdevTypeDir s
return err return err
} }
err = os.Symlink(filepath.Join(mdevDeviceDir, "vfio_mdev"), filepath.Join(mdevDeviceDir, "driver")) err = os.Symlink(filepath.Join(mdevDeviceDir, "vfio_mdev"), filepath.Join(mdevDeviceDir, "driver"))
if err != nil {
return err
}
_, err = os.Create(filepath.Join(mdevDeviceDir, "200")) _, err = os.Create(filepath.Join(mdevDeviceDir, "200"))
if err != nil { if err != nil {

View File

@ -33,7 +33,7 @@ const (
mdevDevicesRoot = "/sys/bus/mdev/devices" mdevDevicesRoot = "/sys/bus/mdev/devices"
) )
// Interface allows us to get a list of NVIDIA MDEV (vGPU) and parent devices // Interface allows us to get a list of NVIDIA MDEV (vGPU) and parent devices.
type Interface interface { type Interface interface {
GetAllDevices() ([]*Device, error) GetAllDevices() ([]*Device, error)
GetAllParentDevices() ([]*ParentDevice, error) GetAllParentDevices() ([]*ParentDevice, error)
@ -46,13 +46,13 @@ type nvmdev struct {
var _ Interface = (*nvmdev)(nil) var _ Interface = (*nvmdev)(nil)
// ParentDevice represents an NVIDIA parent PCI device // ParentDevice represents an NVIDIA parent PCI device.
type ParentDevice struct { type ParentDevice struct {
*nvpci.NvidiaPCIDevice *nvpci.NvidiaPCIDevice
mdevPaths map[string]string mdevPaths map[string]string
} }
// Device represents an NVIDIA MDEV (vGPU) device // Device represents an NVIDIA MDEV (vGPU) device.
type Device struct { type Device struct {
Path string Path string
UUID string UUID string
@ -62,12 +62,12 @@ type Device struct {
Parent *ParentDevice Parent *ParentDevice
} }
// New interface that allows us to get a list of all NVIDIA parent and MDEV (vGPU) devices // New interface that allows us to get a list of all NVIDIA parent and MDEV (vGPU) devices.
func New() Interface { func New() Interface {
return &nvmdev{mdevParentsRoot, mdevDevicesRoot} return &nvmdev{mdevParentsRoot, mdevDevicesRoot}
} }
// GetAllParentDevices returns all NVIDIA Parent PCI devices on the system // GetAllParentDevices returns all NVIDIA Parent PCI devices on the system.
func (m *nvmdev) GetAllParentDevices() ([]*ParentDevice, error) { func (m *nvmdev) GetAllParentDevices() ([]*ParentDevice, error) {
deviceDirs, err := os.ReadDir(m.mdevParentsRoot) deviceDirs, err := os.ReadDir(m.mdevParentsRoot)
if err != nil { if err != nil {
@ -101,7 +101,7 @@ func (m *nvmdev) GetAllParentDevices() ([]*ParentDevice, error) {
return nvdevices, nil return nvdevices, nil
} }
// GetAllDevices returns all NVIDIA mdev (vGPU) devices on the system // GetAllDevices returns all NVIDIA mdev (vGPU) devices on the system.
func (m *nvmdev) GetAllDevices() ([]*Device, error) { func (m *nvmdev) GetAllDevices() ([]*Device, error) {
deviceDirs, err := os.ReadDir(m.mdevDevicesRoot) deviceDirs, err := os.ReadDir(m.mdevDevicesRoot)
if err != nil { if err != nil {
@ -123,7 +123,7 @@ func (m *nvmdev) GetAllDevices() ([]*Device, error) {
return nvdevices, nil return nvdevices, nil
} }
// NewDevice constructs a Device, which represents an NVIDIA mdev (vGPU) device // NewDevice constructs a Device, which represents an NVIDIA mdev (vGPU) device.
func NewDevice(root string, uuid string) (*Device, error) { func NewDevice(root string, uuid string) (*Device, error) {
path := path.Join(root, uuid) path := path.Join(root, uuid)
@ -240,14 +240,14 @@ func (m mdev) iommuGroup() (int, error) {
return int(iommuGroup), nil return int(iommuGroup), nil
} }
// NewParentDevice constructs a ParentDevice // NewParentDevice constructs a ParentDevice.
func NewParentDevice(devicePath string) (*ParentDevice, error) { func NewParentDevice(devicePath string) (*ParentDevice, error) {
nvdevice, err := newNvidiaPCIDeviceFromPath(devicePath) nvdevice, err := newNvidiaPCIDeviceFromPath(devicePath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to construct NVIDIA PCI device: %v", err) return nil, fmt.Errorf("failed to construct NVIDIA PCI device: %v", err)
} }
if nvdevice == nil { if nvdevice == nil {
// not a NVIDIA device // not a NVIDIA device.
return nil, err return nil, err
} }
@ -275,7 +275,7 @@ func NewParentDevice(devicePath string) (*ParentDevice, error) {
return &ParentDevice{nvdevice, mdevTypesMap}, err return &ParentDevice{nvdevice, mdevTypesMap}, err
} }
// CreateMDEVDevice creates a mediated device (vGPU) on the parent GPU // CreateMDEVDevice creates a mediated device (vGPU) on the parent GPU.
func (p *ParentDevice) CreateMDEVDevice(mdevType string, id string) error { func (p *ParentDevice) CreateMDEVDevice(mdevType string, id string) error {
mdevPath, ok := p.mdevPaths[mdevType] mdevPath, ok := p.mdevPaths[mdevType]
if !ok { if !ok {
@ -292,7 +292,7 @@ func (p *ParentDevice) CreateMDEVDevice(mdevType string, id string) error {
return nil return nil
} }
// DeleteMDEVDevice deletes a mediated device (vGPU) // DeleteMDEVDevice deletes a mediated device (vGPU).
func (p *ParentDevice) DeleteMDEVDevice(id string) error { func (p *ParentDevice) DeleteMDEVDevice(id string) error {
removeFile, err := os.OpenFile(filepath.Join(p.Path, id, "remove"), os.O_WRONLY|os.O_SYNC, 0200) removeFile, err := os.OpenFile(filepath.Join(p.Path, id, "remove"), os.O_WRONLY|os.O_SYNC, 0200)
if err != nil { if err != nil {
@ -306,7 +306,7 @@ func (p *ParentDevice) DeleteMDEVDevice(id string) error {
return nil return nil
} }
// Delete deletes a mediated device (vGPU) // Delete deletes a mediated device (vGPU).
func (m *Device) Delete() error { func (m *Device) Delete() error {
removeFile, err := os.OpenFile(filepath.Join(m.Path, "remove"), os.O_WRONLY|os.O_SYNC, 0200) removeFile, err := os.OpenFile(filepath.Join(m.Path, "remove"), os.O_WRONLY|os.O_SYNC, 0200)
if err != nil { if err != nil {
@ -320,7 +320,7 @@ func (m *Device) Delete() error {
return nil return nil
} }
// GetPhysicalFunction gets the physical PCI device backing a 'parent' device // GetPhysicalFunction gets the physical PCI device backing a 'parent' device.
func (p *ParentDevice) GetPhysicalFunction() (*nvpci.NvidiaPCIDevice, error) { func (p *ParentDevice) GetPhysicalFunction() (*nvpci.NvidiaPCIDevice, error) {
if !p.IsVF { if !p.IsVF {
return p.NvidiaPCIDevice, nil return p.NvidiaPCIDevice, nil
@ -334,18 +334,18 @@ func (p *ParentDevice) GetPhysicalFunction() (*nvpci.NvidiaPCIDevice, error) {
return newNvidiaPCIDeviceFromPath(physfnPath) return newNvidiaPCIDeviceFromPath(physfnPath)
} }
// GetPhysicalFunction gets the physical PCI device that a vGPU is created on // GetPhysicalFunction gets the physical PCI device that a vGPU is created on.
func (m *Device) GetPhysicalFunction() (*nvpci.NvidiaPCIDevice, error) { func (m *Device) GetPhysicalFunction() (*nvpci.NvidiaPCIDevice, error) {
return m.Parent.GetPhysicalFunction() return m.Parent.GetPhysicalFunction()
} }
// IsMDEVTypeSupported checks if the mdevType is supported by the GPU // IsMDEVTypeSupported checks if the mdevType is supported by the GPU.
func (p *ParentDevice) IsMDEVTypeSupported(mdevType string) bool { func (p *ParentDevice) IsMDEVTypeSupported(mdevType string) bool {
_, found := p.mdevPaths[mdevType] _, found := p.mdevPaths[mdevType]
return found return found
} }
// IsMDEVTypeAvailable checks if a vGPU instance of mdevType can be created on the parent GPU // IsMDEVTypeAvailable checks if a vGPU instance of mdevType can be created on the parent GPU.
func (p *ParentDevice) IsMDEVTypeAvailable(mdevType string) (bool, error) { func (p *ParentDevice) IsMDEVTypeAvailable(mdevType string) (bool, error) {
availableInstances, err := p.GetAvailableMDEVInstances(mdevType) availableInstances, err := p.GetAvailableMDEVInstances(mdevType)
if err != nil { if err != nil {

View File

@ -17,8 +17,9 @@
package nvmdev package nvmdev
import ( import (
"github.com/stretchr/testify/require"
"testing" "testing"
"github.com/stretchr/testify/require"
) )
func TestNvmdev(t *testing.T) { func TestNvmdev(t *testing.T) {

View File

@ -24,7 +24,7 @@ type nvmlComputeInstance nvml.ComputeInstance
var _ ComputeInstance = (*nvmlComputeInstance)(nil) var _ ComputeInstance = (*nvmlComputeInstance)(nil)
// GetInfo() returns info about a Compute Instance // GetInfo() returns info about a Compute Instance.
func (ci nvmlComputeInstance) GetInfo() (ComputeInstanceInfo, Return) { func (ci nvmlComputeInstance) GetInfo() (ComputeInstanceInfo, Return) {
i, r := nvml.ComputeInstance(ci).GetInfo() i, r := nvml.ComputeInstance(ci).GetInfo()
info := ComputeInstanceInfo{ info := ComputeInstanceInfo{
@ -37,7 +37,7 @@ func (ci nvmlComputeInstance) GetInfo() (ComputeInstanceInfo, Return) {
return info, Return(r) return info, Return(r)
} }
// Destroy() destroys a Compute Instance // Destroy() destroys a Compute Instance.
func (ci nvmlComputeInstance) Destroy() Return { func (ci nvmlComputeInstance) Destroy() Return {
r := nvml.ComputeInstance(ci).Destroy() r := nvml.ComputeInstance(ci).Destroy()
return Return(r) return Return(r)

View File

@ -20,12 +20,12 @@ import (
"github.com/NVIDIA/go-nvml/pkg/nvml" "github.com/NVIDIA/go-nvml/pkg/nvml"
) )
// General untyped constants // General untyped constants.
const ( const (
NVLINK_MAX_LINKS = nvml.NVLINK_MAX_LINKS NVLINK_MAX_LINKS = nvml.NVLINK_MAX_LINKS
) )
// Return constants // Return constants.
const ( const (
SUCCESS = Return(nvml.SUCCESS) SUCCESS = Return(nvml.SUCCESS)
ERROR_UNINITIALIZED = Return(nvml.ERROR_UNINITIALIZED) ERROR_UNINITIALIZED = Return(nvml.ERROR_UNINITIALIZED)
@ -54,7 +54,7 @@ const (
ERROR_UNKNOWN = Return(nvml.ERROR_UNKNOWN) ERROR_UNKNOWN = Return(nvml.ERROR_UNKNOWN)
) )
// Device architecture constants // Device architecture constants.
const ( const (
DEVICE_ARCH_KEPLER = nvml.DEVICE_ARCH_KEPLER DEVICE_ARCH_KEPLER = nvml.DEVICE_ARCH_KEPLER
DEVICE_ARCH_MAXWELL = nvml.DEVICE_ARCH_MAXWELL DEVICE_ARCH_MAXWELL = nvml.DEVICE_ARCH_MAXWELL
@ -67,7 +67,7 @@ const (
DEVICE_ARCH_UNKNOWN = nvml.DEVICE_ARCH_UNKNOWN DEVICE_ARCH_UNKNOWN = nvml.DEVICE_ARCH_UNKNOWN
) )
// Device brand constants // Device brand constants.
const ( const (
BRAND_UNKNOWN = BrandType(nvml.BRAND_UNKNOWN) BRAND_UNKNOWN = BrandType(nvml.BRAND_UNKNOWN)
BRAND_QUADRO = BrandType(nvml.BRAND_QUADRO) BRAND_QUADRO = BrandType(nvml.BRAND_QUADRO)
@ -90,13 +90,13 @@ const (
BRAND_COUNT = BrandType(nvml.BRAND_COUNT) BRAND_COUNT = BrandType(nvml.BRAND_COUNT)
) )
// MIG Mode constants // MIG Mode constants.
const ( const (
DEVICE_MIG_ENABLE = nvml.DEVICE_MIG_ENABLE DEVICE_MIG_ENABLE = nvml.DEVICE_MIG_ENABLE
DEVICE_MIG_DISABLE = nvml.DEVICE_MIG_DISABLE DEVICE_MIG_DISABLE = nvml.DEVICE_MIG_DISABLE
) )
// GPU Instance Profiles // GPU Instance Profiles.
const ( const (
GPU_INSTANCE_PROFILE_1_SLICE = nvml.GPU_INSTANCE_PROFILE_1_SLICE GPU_INSTANCE_PROFILE_1_SLICE = nvml.GPU_INSTANCE_PROFILE_1_SLICE
GPU_INSTANCE_PROFILE_2_SLICE = nvml.GPU_INSTANCE_PROFILE_2_SLICE GPU_INSTANCE_PROFILE_2_SLICE = nvml.GPU_INSTANCE_PROFILE_2_SLICE
@ -111,7 +111,7 @@ const (
GPU_INSTANCE_PROFILE_COUNT = nvml.GPU_INSTANCE_PROFILE_COUNT GPU_INSTANCE_PROFILE_COUNT = nvml.GPU_INSTANCE_PROFILE_COUNT
) )
// Compute Instance Profiles // Compute Instance Profiles.
const ( const (
COMPUTE_INSTANCE_PROFILE_1_SLICE = nvml.COMPUTE_INSTANCE_PROFILE_1_SLICE COMPUTE_INSTANCE_PROFILE_1_SLICE = nvml.COMPUTE_INSTANCE_PROFILE_1_SLICE
COMPUTE_INSTANCE_PROFILE_2_SLICE = nvml.COMPUTE_INSTANCE_PROFILE_2_SLICE COMPUTE_INSTANCE_PROFILE_2_SLICE = nvml.COMPUTE_INSTANCE_PROFILE_2_SLICE
@ -124,20 +124,20 @@ const (
COMPUTE_INSTANCE_PROFILE_COUNT = nvml.COMPUTE_INSTANCE_PROFILE_COUNT COMPUTE_INSTANCE_PROFILE_COUNT = nvml.COMPUTE_INSTANCE_PROFILE_COUNT
) )
// Compute Instance Engine Profiles // Compute Instance Engine Profiles.
const ( const (
COMPUTE_INSTANCE_ENGINE_PROFILE_SHARED = nvml.COMPUTE_INSTANCE_ENGINE_PROFILE_SHARED COMPUTE_INSTANCE_ENGINE_PROFILE_SHARED = nvml.COMPUTE_INSTANCE_ENGINE_PROFILE_SHARED
COMPUTE_INSTANCE_ENGINE_PROFILE_COUNT = nvml.COMPUTE_INSTANCE_ENGINE_PROFILE_COUNT COMPUTE_INSTANCE_ENGINE_PROFILE_COUNT = nvml.COMPUTE_INSTANCE_ENGINE_PROFILE_COUNT
) )
// Event Types // Event Types.
const ( const (
EventTypeXidCriticalError = nvml.EventTypeXidCriticalError EventTypeXidCriticalError = nvml.EventTypeXidCriticalError
EventTypeSingleBitEccError = nvml.EventTypeSingleBitEccError EventTypeSingleBitEccError = nvml.EventTypeSingleBitEccError
EventTypeDoubleBitEccError = nvml.EventTypeDoubleBitEccError EventTypeDoubleBitEccError = nvml.EventTypeDoubleBitEccError
) )
// GPU Topology enumeration // GPU Topology enumeration.
const ( const (
TOPOLOGY_INTERNAL = GpuTopologyLevel(nvml.TOPOLOGY_INTERNAL) TOPOLOGY_INTERNAL = GpuTopologyLevel(nvml.TOPOLOGY_INTERNAL)
TOPOLOGY_SINGLE = GpuTopologyLevel(nvml.TOPOLOGY_SINGLE) TOPOLOGY_SINGLE = GpuTopologyLevel(nvml.TOPOLOGY_SINGLE)
@ -147,13 +147,13 @@ const (
TOPOLOGY_SYSTEM = GpuTopologyLevel(nvml.TOPOLOGY_SYSTEM) TOPOLOGY_SYSTEM = GpuTopologyLevel(nvml.TOPOLOGY_SYSTEM)
) )
// Generic enable/disable constants // Generic enable/disable constants.
const ( const (
FEATURE_DISABLED = EnableState(nvml.FEATURE_DISABLED) FEATURE_DISABLED = EnableState(nvml.FEATURE_DISABLED)
FEATURE_ENABLED = EnableState(nvml.FEATURE_ENABLED) FEATURE_ENABLED = EnableState(nvml.FEATURE_ENABLED)
) )
// Compute mode constants // Compute mode constants.
const ( const (
COMPUTEMODE_DEFAULT = ComputeMode(nvml.COMPUTEMODE_DEFAULT) COMPUTEMODE_DEFAULT = ComputeMode(nvml.COMPUTEMODE_DEFAULT)
COMPUTEMODE_EXCLUSIVE_THREAD = ComputeMode(nvml.COMPUTEMODE_EXCLUSIVE_THREAD) COMPUTEMODE_EXCLUSIVE_THREAD = ComputeMode(nvml.COMPUTEMODE_EXCLUSIVE_THREAD)

View File

@ -27,73 +27,73 @@ func (d nvmlDevice) nvmlDeviceHandle() *nvml.Device {
return (*nvml.Device)(&d) return (*nvml.Device)(&d)
} }
// GetIndex returns the index of a Device // GetIndex returns the index of a Device.
func (d nvmlDevice) GetIndex() (int, Return) { func (d nvmlDevice) GetIndex() (int, Return) {
i, r := nvml.Device(d).GetIndex() i, r := nvml.Device(d).GetIndex()
return i, Return(r) return i, Return(r)
} }
// GetPciInfo returns the PCI info of a Device // GetPciInfo returns the PCI info of a Device.
func (d nvmlDevice) GetPciInfo() (PciInfo, Return) { func (d nvmlDevice) GetPciInfo() (PciInfo, Return) {
p, r := nvml.Device(d).GetPciInfo() p, r := nvml.Device(d).GetPciInfo()
return PciInfo(p), Return(r) return PciInfo(p), Return(r)
} }
// GetMemoryInfo returns the memory info of a Device // GetMemoryInfo returns the memory info of a Device.
func (d nvmlDevice) GetMemoryInfo() (Memory, Return) { func (d nvmlDevice) GetMemoryInfo() (Memory, Return) {
p, r := nvml.Device(d).GetMemoryInfo() p, r := nvml.Device(d).GetMemoryInfo()
return Memory(p), Return(r) return Memory(p), Return(r)
} }
// GetUUID returns the UUID of a Device // GetUUID returns the UUID of a Device.
func (d nvmlDevice) GetUUID() (string, Return) { func (d nvmlDevice) GetUUID() (string, Return) {
u, r := nvml.Device(d).GetUUID() u, r := nvml.Device(d).GetUUID()
return u, Return(r) return u, Return(r)
} }
// GetMinorNumber returns the minor number of a Device // GetMinorNumber returns the minor number of a Device.
func (d nvmlDevice) GetMinorNumber() (int, Return) { func (d nvmlDevice) GetMinorNumber() (int, Return) {
m, r := nvml.Device(d).GetMinorNumber() m, r := nvml.Device(d).GetMinorNumber()
return m, Return(r) return m, Return(r)
} }
// IsMigDeviceHandle returns whether a Device is a MIG device or not // IsMigDeviceHandle returns whether a Device is a MIG device or not.
func (d nvmlDevice) IsMigDeviceHandle() (bool, Return) { func (d nvmlDevice) IsMigDeviceHandle() (bool, Return) {
b, r := nvml.Device(d).IsMigDeviceHandle() b, r := nvml.Device(d).IsMigDeviceHandle()
return b, Return(r) return b, Return(r)
} }
// GetDeviceHandleFromMigDeviceHandle returns the parent Device of a MIG device // GetDeviceHandleFromMigDeviceHandle returns the parent Device of a MIG device.
func (d nvmlDevice) GetDeviceHandleFromMigDeviceHandle() (Device, Return) { func (d nvmlDevice) GetDeviceHandleFromMigDeviceHandle() (Device, Return) {
p, r := nvml.Device(d).GetDeviceHandleFromMigDeviceHandle() p, r := nvml.Device(d).GetDeviceHandleFromMigDeviceHandle()
return nvmlDevice(p), Return(r) return nvmlDevice(p), Return(r)
} }
// SetMigMode sets the MIG mode of a Device // SetMigMode sets the MIG mode of a Device.
func (d nvmlDevice) SetMigMode(mode int) (Return, Return) { func (d nvmlDevice) SetMigMode(mode int) (Return, Return) {
r1, r2 := nvml.Device(d).SetMigMode(mode) r1, r2 := nvml.Device(d).SetMigMode(mode)
return Return(r1), Return(r2) return Return(r1), Return(r2)
} }
// GetMigMode returns the MIG mode of a Device // GetMigMode returns the MIG mode of a Device.
func (d nvmlDevice) GetMigMode() (int, int, Return) { func (d nvmlDevice) GetMigMode() (int, int, Return) {
s1, s2, r := nvml.Device(d).GetMigMode() s1, s2, r := nvml.Device(d).GetMigMode()
return s1, s2, Return(r) return s1, s2, Return(r)
} }
// GetGpuInstanceById returns the GPU Instance associated with a particular ID // GetGpuInstanceById returns the GPU Instance associated with a particular ID.
func (d nvmlDevice) GetGpuInstanceById(id int) (GpuInstance, Return) { func (d nvmlDevice) GetGpuInstanceById(id int) (GpuInstance, Return) {
gi, r := nvml.Device(d).GetGpuInstanceById(id) gi, r := nvml.Device(d).GetGpuInstanceById(id)
return nvmlGpuInstance(gi), Return(r) return nvmlGpuInstance(gi), Return(r)
} }
// GetGpuInstanceProfileInfo returns the profile info of a GPU Instance // GetGpuInstanceProfileInfo returns the profile info of a GPU Instance.
func (d nvmlDevice) GetGpuInstanceProfileInfo(profile int) (GpuInstanceProfileInfo, Return) { func (d nvmlDevice) GetGpuInstanceProfileInfo(profile int) (GpuInstanceProfileInfo, Return) {
p, r := nvml.Device(d).GetGpuInstanceProfileInfo(profile) p, r := nvml.Device(d).GetGpuInstanceProfileInfo(profile)
return GpuInstanceProfileInfo(p), Return(r) return GpuInstanceProfileInfo(p), Return(r)
} }
// GetGpuInstancePossiblePlacements returns the possible placements of a GPU Instance // GetGpuInstancePossiblePlacements returns the possible placements of a GPU Instance.
func (d nvmlDevice) GetGpuInstancePossiblePlacements(info *GpuInstanceProfileInfo) ([]GpuInstancePlacement, Return) { func (d nvmlDevice) GetGpuInstancePossiblePlacements(info *GpuInstanceProfileInfo) ([]GpuInstancePlacement, Return) {
nvmlPlacements, r := nvml.Device(d).GetGpuInstancePossiblePlacements((*nvml.GpuInstanceProfileInfo)(info)) nvmlPlacements, r := nvml.Device(d).GetGpuInstancePossiblePlacements((*nvml.GpuInstanceProfileInfo)(info))
var placements []GpuInstancePlacement var placements []GpuInstancePlacement
@ -103,7 +103,7 @@ func (d nvmlDevice) GetGpuInstancePossiblePlacements(info *GpuInstanceProfileInf
return placements, Return(r) return placements, Return(r)
} }
// GetGpuInstances returns the set of GPU Instances associated with a Device // GetGpuInstances returns the set of GPU Instances associated with a Device.
func (d nvmlDevice) GetGpuInstances(info *GpuInstanceProfileInfo) ([]GpuInstance, Return) { func (d nvmlDevice) GetGpuInstances(info *GpuInstanceProfileInfo) ([]GpuInstance, Return) {
nvmlGis, r := nvml.Device(d).GetGpuInstances((*nvml.GpuInstanceProfileInfo)(info)) nvmlGis, r := nvml.Device(d).GetGpuInstances((*nvml.GpuInstanceProfileInfo)(info))
var gis []GpuInstance var gis []GpuInstance
@ -113,72 +113,72 @@ func (d nvmlDevice) GetGpuInstances(info *GpuInstanceProfileInfo) ([]GpuInstance
return gis, Return(r) return gis, Return(r)
} }
// CreateGpuInstanceWithPlacement creates a GPU Instance with a specific placement // CreateGpuInstanceWithPlacement creates a GPU Instance with a specific placement.
func (d nvmlDevice) CreateGpuInstanceWithPlacement(info *GpuInstanceProfileInfo, placement *GpuInstancePlacement) (GpuInstance, Return) { func (d nvmlDevice) CreateGpuInstanceWithPlacement(info *GpuInstanceProfileInfo, placement *GpuInstancePlacement) (GpuInstance, Return) {
gi, r := nvml.Device(d).CreateGpuInstanceWithPlacement((*nvml.GpuInstanceProfileInfo)(info), (*nvml.GpuInstancePlacement)(placement)) gi, r := nvml.Device(d).CreateGpuInstanceWithPlacement((*nvml.GpuInstanceProfileInfo)(info), (*nvml.GpuInstancePlacement)(placement))
return nvmlGpuInstance(gi), Return(r) return nvmlGpuInstance(gi), Return(r)
} }
// GetMaxMigDeviceCount returns the maximum number of MIG devices that can be created on a Device // GetMaxMigDeviceCount returns the maximum number of MIG devices that can be created on a Device.
func (d nvmlDevice) GetMaxMigDeviceCount() (int, Return) { func (d nvmlDevice) GetMaxMigDeviceCount() (int, Return) {
m, r := nvml.Device(d).GetMaxMigDeviceCount() m, r := nvml.Device(d).GetMaxMigDeviceCount()
return m, Return(r) return m, Return(r)
} }
// GetMigDeviceHandleByIndex returns the handle to a MIG device given its index // GetMigDeviceHandleByIndex returns the handle to a MIG device given its index.
func (d nvmlDevice) GetMigDeviceHandleByIndex(Index int) (Device, Return) { func (d nvmlDevice) GetMigDeviceHandleByIndex(Index int) (Device, Return) {
h, r := nvml.Device(d).GetMigDeviceHandleByIndex(Index) h, r := nvml.Device(d).GetMigDeviceHandleByIndex(Index)
return nvmlDevice(h), Return(r) return nvmlDevice(h), Return(r)
} }
// GetGpuInstanceId returns the GPU Instance ID of a MIG device // GetGpuInstanceId returns the GPU Instance ID of a MIG device.
func (d nvmlDevice) GetGpuInstanceId() (int, Return) { func (d nvmlDevice) GetGpuInstanceId() (int, Return) {
gi, r := nvml.Device(d).GetGpuInstanceId() gi, r := nvml.Device(d).GetGpuInstanceId()
return gi, Return(r) return gi, Return(r)
} }
// GetComputeInstanceId returns the Compute Instance ID of a MIG device // GetComputeInstanceId returns the Compute Instance ID of a MIG device.
func (d nvmlDevice) GetComputeInstanceId() (int, Return) { func (d nvmlDevice) GetComputeInstanceId() (int, Return) {
ci, r := nvml.Device(d).GetComputeInstanceId() ci, r := nvml.Device(d).GetComputeInstanceId()
return ci, Return(r) return ci, Return(r)
} }
// GetCudaComputeCapability returns the compute capability major and minor versions for a device // GetCudaComputeCapability returns the compute capability major and minor versions for a device.
func (d nvmlDevice) GetCudaComputeCapability() (int, int, Return) { func (d nvmlDevice) GetCudaComputeCapability() (int, int, Return) {
major, minor, r := nvml.Device(d).GetCudaComputeCapability() major, minor, r := nvml.Device(d).GetCudaComputeCapability()
return major, minor, Return(r) return major, minor, Return(r)
} }
// GetAttributes returns the device attributes for a MIG device // GetAttributes returns the device attributes for a MIG device.
func (d nvmlDevice) GetAttributes() (DeviceAttributes, Return) { func (d nvmlDevice) GetAttributes() (DeviceAttributes, Return) {
a, r := nvml.Device(d).GetAttributes() a, r := nvml.Device(d).GetAttributes()
return DeviceAttributes(a), Return(r) return DeviceAttributes(a), Return(r)
} }
// GetName returns the product name of a Device // GetName returns the product name of a Device.
func (d nvmlDevice) GetName() (string, Return) { func (d nvmlDevice) GetName() (string, Return) {
n, r := nvml.Device(d).GetName() n, r := nvml.Device(d).GetName()
return n, Return(r) return n, Return(r)
} }
// GetBrand returns the brand of a Device // GetBrand returns the brand of a Device.
func (d nvmlDevice) GetBrand() (BrandType, Return) { func (d nvmlDevice) GetBrand() (BrandType, Return) {
b, r := nvml.Device(d).GetBrand() b, r := nvml.Device(d).GetBrand()
return BrandType(b), Return(r) return BrandType(b), Return(r)
} }
// GetArchitecture returns the architecture of a Device // GetArchitecture returns the architecture of a Device.
func (d nvmlDevice) GetArchitecture() (DeviceArchitecture, Return) { func (d nvmlDevice) GetArchitecture() (DeviceArchitecture, Return) {
a, r := nvml.Device(d).GetArchitecture() a, r := nvml.Device(d).GetArchitecture()
return DeviceArchitecture(a), Return(r) return DeviceArchitecture(a), Return(r)
} }
// RegisterEvents registers the specified event set and type with the device // RegisterEvents registers the specified event set and type with the device.
func (d nvmlDevice) RegisterEvents(EventTypes uint64, Set EventSet) Return { func (d nvmlDevice) RegisterEvents(EventTypes uint64, Set EventSet) Return {
return Return(nvml.Device(d).RegisterEvents(EventTypes, nvml.EventSet(Set))) return Return(nvml.Device(d).RegisterEvents(EventTypes, nvml.EventSet(Set)))
} }
// GetSupportedEventTypes returns the events supported by the device // GetSupportedEventTypes returns the events supported by the device.
func (d nvmlDevice) GetSupportedEventTypes() (uint64, Return) { func (d nvmlDevice) GetSupportedEventTypes() (uint64, Return) {
e, r := nvml.Device(d).GetSupportedEventTypes() e, r := nvml.Device(d).GetSupportedEventTypes()
return e, Return(r) return e, Return(r)

View File

@ -4,8 +4,9 @@
package nvml package nvml
import ( import (
"github.com/NVIDIA/go-nvml/pkg/nvml"
"sync" "sync"
"github.com/NVIDIA/go-nvml/pkg/nvml"
) )
// Ensure, that DeviceMock does implement Device. // Ensure, that DeviceMock does implement Device.

View File

@ -20,7 +20,7 @@ import (
"github.com/NVIDIA/go-nvml/pkg/nvml" "github.com/NVIDIA/go-nvml/pkg/nvml"
) )
// Wait watches for an event with the specified timeout // Wait watches for an event with the specified timeout.
func (e EventSet) Wait(Timeoutms uint32) (EventData, Return) { func (e EventSet) Wait(Timeoutms uint32) (EventData, Return) {
d, r := nvml.EventSet(e).Wait(Timeoutms) d, r := nvml.EventSet(e).Wait(Timeoutms)
eventData := EventData{ eventData := EventData{
@ -33,7 +33,7 @@ func (e EventSet) Wait(Timeoutms uint32) (EventData, Return) {
return eventData, Return(r) return eventData, Return(r)
} }
// Free deletes the event set // Free deletes the event set.
func (e EventSet) Free() Return { func (e EventSet) Free() Return {
return Return(nvml.EventSet(e).Free()) return Return(nvml.EventSet(e).Free())
} }

View File

@ -24,7 +24,7 @@ type nvmlGpuInstance nvml.GpuInstance
var _ GpuInstance = (*nvmlGpuInstance)(nil) var _ GpuInstance = (*nvmlGpuInstance)(nil)
// GetInfo returns info about a GPU Intsance // GetInfo returns info about a GPU Intsance.
func (gi nvmlGpuInstance) GetInfo() (GpuInstanceInfo, Return) { func (gi nvmlGpuInstance) GetInfo() (GpuInstanceInfo, Return) {
i, r := nvml.GpuInstance(gi).GetInfo() i, r := nvml.GpuInstance(gi).GetInfo()
info := GpuInstanceInfo{ info := GpuInstanceInfo{
@ -42,19 +42,19 @@ func (gi nvmlGpuInstance) GetComputeInstanceById(id int) (ComputeInstance, Retur
return nvmlComputeInstance(ci), Return(r) return nvmlComputeInstance(ci), Return(r)
} }
// GetComputeInstanceProfileInfo returns info about a given Compute Instance profile // GetComputeInstanceProfileInfo returns info about a given Compute Instance profile.
func (gi nvmlGpuInstance) GetComputeInstanceProfileInfo(profile int, engProfile int) (ComputeInstanceProfileInfo, Return) { func (gi nvmlGpuInstance) GetComputeInstanceProfileInfo(profile int, engProfile int) (ComputeInstanceProfileInfo, Return) {
p, r := nvml.GpuInstance(gi).GetComputeInstanceProfileInfo(profile, engProfile) p, r := nvml.GpuInstance(gi).GetComputeInstanceProfileInfo(profile, engProfile)
return ComputeInstanceProfileInfo(p), Return(r) return ComputeInstanceProfileInfo(p), Return(r)
} }
// CreateComputeInstance creates a Compute Instance within the GPU Instance // CreateComputeInstance creates a Compute Instance within the GPU Instance.
func (gi nvmlGpuInstance) CreateComputeInstance(info *ComputeInstanceProfileInfo) (ComputeInstance, Return) { func (gi nvmlGpuInstance) CreateComputeInstance(info *ComputeInstanceProfileInfo) (ComputeInstance, Return) {
ci, r := nvml.GpuInstance(gi).CreateComputeInstance((*nvml.ComputeInstanceProfileInfo)(info)) ci, r := nvml.GpuInstance(gi).CreateComputeInstance((*nvml.ComputeInstanceProfileInfo)(info))
return nvmlComputeInstance(ci), Return(r) return nvmlComputeInstance(ci), Return(r)
} }
// GetComputeInstances returns the set of Compute Instances associated with a GPU Instance // GetComputeInstances returns the set of Compute Instances associated with a GPU Instance.
func (gi nvmlGpuInstance) GetComputeInstances(info *ComputeInstanceProfileInfo) ([]ComputeInstance, Return) { func (gi nvmlGpuInstance) GetComputeInstances(info *ComputeInstanceProfileInfo) ([]ComputeInstance, Return) {
nvmlCis, r := nvml.GpuInstance(gi).GetComputeInstances((*nvml.ComputeInstanceProfileInfo)(info)) nvmlCis, r := nvml.GpuInstance(gi).GetComputeInstances((*nvml.ComputeInstanceProfileInfo)(info))
var cis []ComputeInstance var cis []ComputeInstance
@ -64,7 +64,7 @@ func (gi nvmlGpuInstance) GetComputeInstances(info *ComputeInstanceProfileInfo)
return cis, Return(r) return cis, Return(r)
} }
// Destroy destroys a GPU Instance // Destroy destroys a GPU Instance.
func (gi nvmlGpuInstance) Destroy() Return { func (gi nvmlGpuInstance) Destroy() Return {
r := nvml.GpuInstance(gi).Destroy() r := nvml.GpuInstance(gi).Destroy()
return Return(r) return Return(r)

View File

@ -29,7 +29,7 @@ type nvmlLib struct {
var _ Interface = (*nvmlLib)(nil) var _ Interface = (*nvmlLib)(nil)
// New creates a new instance of the NVML Interface // New creates a new instance of the NVML Interface.
func New(opts ...Option) Interface { func New(opts ...Option) Interface {
o := &options{} o := &options{}
for _, opt := range opts { for _, opt := range opts {
@ -40,7 +40,7 @@ func New(opts ...Option) Interface {
if o.libraryPath != "" { if o.libraryPath != "" {
nvmlOptions = append(nvmlOptions, nvml.WithLibraryPath(o.libraryPath)) nvmlOptions = append(nvmlOptions, nvml.WithLibraryPath(o.libraryPath))
} }
nvml.SetLibraryOptions(nvmlOptions...) _ = nvml.SetLibraryOptions(nvmlOptions...)
return &nvmlLib{} return &nvmlLib{}
} }
@ -51,7 +51,7 @@ func (n *nvmlLib) Lookup(name string) error {
return nvml.GetLibrary().Lookup(name) return nvml.GetLibrary().Lookup(name)
} }
// Init initializes an NVML Interface // Init initializes an NVML Interface.
func (n *nvmlLib) Init() Return { func (n *nvmlLib) Init() Return {
ret := nvml.Init() ret := nvml.Init()
if ret != nvml.SUCCESS { if ret != nvml.SUCCESS {
@ -68,7 +68,7 @@ func (n *nvmlLib) Init() Return {
return SUCCESS return SUCCESS
} }
// Shutdown shuts down an NVML Interface // Shutdown shuts down an NVML Interface.
func (n *nvmlLib) Shutdown() Return { func (n *nvmlLib) Shutdown() Return {
ret := nvml.Shutdown() ret := nvml.Shutdown()
if ret != nvml.SUCCESS { if ret != nvml.SUCCESS {
@ -85,42 +85,42 @@ func (n *nvmlLib) Shutdown() Return {
return SUCCESS return SUCCESS
} }
// DeviceGetCount returns the total number of GPU Devices // DeviceGetCount returns the total number of GPU Devices.
func (n *nvmlLib) DeviceGetCount() (int, Return) { func (n *nvmlLib) DeviceGetCount() (int, Return) {
c, r := nvml.DeviceGetCount() c, r := nvml.DeviceGetCount()
return c, Return(r) return c, Return(r)
} }
// DeviceGetHandleByIndex returns a Device handle given its index // DeviceGetHandleByIndex returns a Device handle given its index.
func (n *nvmlLib) DeviceGetHandleByIndex(index int) (Device, Return) { func (n *nvmlLib) DeviceGetHandleByIndex(index int) (Device, Return) {
d, r := nvml.DeviceGetHandleByIndex(index) d, r := nvml.DeviceGetHandleByIndex(index)
return nvmlDevice(d), Return(r) return nvmlDevice(d), Return(r)
} }
// DeviceGetHandleByUUID returns a Device handle given its UUID // DeviceGetHandleByUUID returns a Device handle given its UUID.
func (n *nvmlLib) DeviceGetHandleByUUID(uuid string) (Device, Return) { func (n *nvmlLib) DeviceGetHandleByUUID(uuid string) (Device, Return) {
d, r := nvml.DeviceGetHandleByUUID(uuid) d, r := nvml.DeviceGetHandleByUUID(uuid)
return nvmlDevice(d), Return(r) return nvmlDevice(d), Return(r)
} }
// SystemGetDriverVersion returns the version of the installed NVIDIA driver // SystemGetDriverVersion returns the version of the installed NVIDIA driver.
func (n *nvmlLib) SystemGetDriverVersion() (string, Return) { func (n *nvmlLib) SystemGetDriverVersion() (string, Return) {
v, r := nvml.SystemGetDriverVersion() v, r := nvml.SystemGetDriverVersion()
return v, Return(r) return v, Return(r)
} }
// SystemGetCudaDriverVersion returns the version of CUDA associated with the NVIDIA driver // SystemGetCudaDriverVersion returns the version of CUDA associated with the NVIDIA driver.
func (n *nvmlLib) SystemGetCudaDriverVersion() (int, Return) { func (n *nvmlLib) SystemGetCudaDriverVersion() (int, Return) {
v, r := nvml.SystemGetCudaDriverVersion() v, r := nvml.SystemGetCudaDriverVersion()
return v, Return(r) return v, Return(r)
} }
// ErrorString returns the error string associated with a given return value // ErrorString returns the error string associated with a given return value.
func (n *nvmlLib) ErrorString(ret Return) string { func (n *nvmlLib) ErrorString(ret Return) string {
return nvml.ErrorString(nvml.Return(ret)) return nvml.ErrorString(nvml.Return(ret))
} }
// EventSetCreate creates an event set // EventSetCreate creates an event set.
func (n *nvmlLib) EventSetCreate() (EventSet, Return) { func (n *nvmlLib) EventSetCreate() (EventSet, Return) {
e, r := nvml.EventSetCreate() e, r := nvml.EventSetCreate()
return EventSet(e), Return(r) return EventSet(e), Return(r)

View File

@ -22,17 +22,17 @@ import (
"github.com/NVIDIA/go-nvml/pkg/nvml" "github.com/NVIDIA/go-nvml/pkg/nvml"
) )
// String returns the string representation of a Return // String returns the string representation of a Return.
func (r Return) String() string { func (r Return) String() string {
return errorStringFunc(nvml.Return(r)) return errorStringFunc(nvml.Return(r))
} }
// Error returns the string representation of a Return // Error returns the string representation of a Return.
func (r Return) Error() string { func (r Return) Error() string {
return errorStringFunc(nvml.Return(r)) return errorStringFunc(nvml.Return(r))
} }
// Assigned to nvml.ErrorString if the system nvml library is in use // Assigned to nvml.ErrorString if the system nvml library is in use.
var errorStringFunc = defaultErrorStringFunc var errorStringFunc = defaultErrorStringFunc
var defaultErrorStringFunc = func(r nvml.Return) string { var defaultErrorStringFunc = func(r nvml.Return) string {

View File

@ -22,7 +22,7 @@ import (
// Interface defines the functions implemented by an NVML library // Interface defines the functions implemented by an NVML library
// //
//go:generate moq -out nvml_mock.go . Interface //go:generate moq -out nvml_mock.go . Interface.
type Interface interface { type Interface interface {
DeviceGetCount() (int, Return) DeviceGetCount() (int, Return)
DeviceGetHandleByIndex(Index int) (Device, Return) DeviceGetHandleByIndex(Index int) (Device, Return)
@ -93,7 +93,7 @@ type ComputeInstance interface {
GetInfo() (ComputeInstanceInfo, Return) GetInfo() (ComputeInstanceInfo, Return)
} }
// GpuInstanceInfo holds info about a GPU Instance // GpuInstanceInfo holds info about a GPU Instance.
type GpuInstanceInfo struct { type GpuInstanceInfo struct {
Device Device Device Device
Id uint32 Id uint32
@ -101,7 +101,7 @@ type GpuInstanceInfo struct {
Placement GpuInstancePlacement Placement GpuInstancePlacement
} }
// ComputeInstanceInfo holds info about a Compute Instance // ComputeInstanceInfo holds info about a Compute Instance.
type ComputeInstanceInfo struct { type ComputeInstanceInfo struct {
Device Device Device Device
GpuInstance GpuInstance GpuInstance GpuInstance
@ -110,7 +110,7 @@ type ComputeInstanceInfo struct {
Placement ComputeInstancePlacement Placement ComputeInstancePlacement
} }
// EventData defines NVML event Data // EventData defines NVML event Data.
type EventData struct { type EventData struct {
Device Device Device Device
EventType uint64 EventType uint64
@ -119,44 +119,44 @@ type EventData struct {
ComputeInstanceId uint32 ComputeInstanceId uint32
} }
// EventSet defines NVML event Data // EventSet defines NVML event Data.
type EventSet nvml.EventSet type EventSet nvml.EventSet
// Return defines an NVML return type // Return defines an NVML return type.
type Return nvml.Return type Return nvml.Return
// Memory holds info about GPU device memory // Memory holds info about GPU device memory.
type Memory nvml.Memory type Memory nvml.Memory
// PciInfo holds info about the PCI connections of a GPU dvice // PciInfo holds info about the PCI connections of a GPU dvice.
type PciInfo nvml.PciInfo type PciInfo nvml.PciInfo
// GpuInstanceProfileInfo holds info about a GPU Instance Profile // GpuInstanceProfileInfo holds info about a GPU Instance Profile.
type GpuInstanceProfileInfo nvml.GpuInstanceProfileInfo type GpuInstanceProfileInfo nvml.GpuInstanceProfileInfo
// GpuInstancePlacement holds placement info about a GPU Instance // GpuInstancePlacement holds placement info about a GPU Instance.
type GpuInstancePlacement nvml.GpuInstancePlacement type GpuInstancePlacement nvml.GpuInstancePlacement
// ComputeInstanceProfileInfo holds info about a Compute Instance Profile // ComputeInstanceProfileInfo holds info about a Compute Instance Profile.
type ComputeInstanceProfileInfo nvml.ComputeInstanceProfileInfo type ComputeInstanceProfileInfo nvml.ComputeInstanceProfileInfo
// ComputeInstancePlacement holds placement info about a Compute Instance // ComputeInstancePlacement holds placement info about a Compute Instance.
type ComputeInstancePlacement nvml.ComputeInstancePlacement type ComputeInstancePlacement nvml.ComputeInstancePlacement
// DeviceAttributes stores information about MIG devices // DeviceAttributes stores information about MIG devices.
type DeviceAttributes nvml.DeviceAttributes type DeviceAttributes nvml.DeviceAttributes
// DeviceArchitecture represents the hardware architecture of a GPU device // DeviceArchitecture represents the hardware architecture of a GPU device.
type DeviceArchitecture nvml.DeviceArchitecture type DeviceArchitecture nvml.DeviceArchitecture
// BrandType represents the brand of a GPU device // BrandType represents the brand of a GPU device.
type BrandType nvml.BrandType type BrandType nvml.BrandType
// GpuTopologyLevel represents level relationships within a system between two GPUs // GpuTopologyLevel represents level relationships within a system between two GPUs.
type GpuTopologyLevel nvml.GpuTopologyLevel type GpuTopologyLevel nvml.GpuTopologyLevel
// EnableState represents a generic enable/disable enum // EnableState represents a generic enable/disable enum.
type EnableState nvml.EnableState type EnableState nvml.EnableState
// ComputeMode represents the compute mode for a device // ComputeMode represents the compute mode for a device.
type ComputeMode nvml.ComputeMode type ComputeMode nvml.ComputeMode

View File

@ -21,12 +21,12 @@ import (
"unsafe" "unsafe"
) )
// Raw returns just the bytes without any assumptions about layout // Raw returns just the bytes without any assumptions about layout.
type Raw interface { type Raw interface {
Raw() *[]byte Raw() *[]byte
} }
// Reader used to read various data sizes in the byte array // Reader used to read various data sizes in the byte array.
type Reader interface { type Reader interface {
Read8(pos int) uint8 Read8(pos int) uint8
Read16(pos int) uint16 Read16(pos int) uint16
@ -35,7 +35,7 @@ type Reader interface {
Len() int Len() int
} }
// Writer used to write various sizes of data in the byte array // Writer used to write various sizes of data in the byte array.
type Writer interface { type Writer interface {
Write8(pos int, value uint8) Write8(pos int, value uint8)
Write16(pos int, value uint16) Write16(pos int, value uint16)
@ -44,7 +44,7 @@ type Writer interface {
Len() int Len() int
} }
// Bytes object for manipulating arbitrary byte arrays // Bytes object for manipulating arbitrary byte arrays.
type Bytes interface { type Bytes interface {
Raw Raw
Reader Reader
@ -70,12 +70,12 @@ func init() {
} }
} }
// New raw bytearray // New raw bytearray.
func New(data *[]byte) Bytes { func New(data *[]byte) Bytes {
return (*native)(data) return (*native)(data)
} }
// NewLittleEndian little endian ordering of bytes // NewLittleEndian little endian ordering of bytes.
func NewLittleEndian(data *[]byte) Bytes { func NewLittleEndian(data *[]byte) Bytes {
if nativeByteOrder == binary.LittleEndian { if nativeByteOrder == binary.LittleEndian {
return (*native)(data) return (*native)(data)
@ -84,7 +84,7 @@ func NewLittleEndian(data *[]byte) Bytes {
return (*swapbo)(data) return (*swapbo)(data)
} }
// NewBigEndian big endian ordering of bytes // NewBigEndian big endian ordering of bytes.
func NewBigEndian(data *[]byte) Bytes { func NewBigEndian(data *[]byte) Bytes {
if nativeByteOrder == binary.BigEndian { if nativeByteOrder == binary.BigEndian {
return (*native)(data) return (*native)(data)

View File

@ -24,24 +24,24 @@ import (
) )
const ( const (
// PCICfgSpaceStandardSize represents the size in bytes of the standard config space // PCICfgSpaceStandardSize represents the size in bytes of the standard config space.
PCICfgSpaceStandardSize = 256 PCICfgSpaceStandardSize = 256
// PCICfgSpaceExtendedSize represents the size in bytes of the extended config space // PCICfgSpaceExtendedSize represents the size in bytes of the extended config space.
PCICfgSpaceExtendedSize = 4096 PCICfgSpaceExtendedSize = 4096
// PCICapabilityListPointer represents offset for the capability list pointer // PCICapabilityListPointer represents offset for the capability list pointer.
PCICapabilityListPointer = 0x34 PCICapabilityListPointer = 0x34
// PCIStatusCapabilityList represents the status register bit which indicates capability list support // PCIStatusCapabilityList represents the status register bit which indicates capability list support.
PCIStatusCapabilityList = 0x10 PCIStatusCapabilityList = 0x10
// PCIStatusBytePosition represents the position of the status register // PCIStatusBytePosition represents the position of the status register.
PCIStatusBytePosition = 0x06 PCIStatusBytePosition = 0x06
) )
// ConfigSpace PCI configuration space (standard extended) file path // ConfigSpace PCI configuration space (standard extended) file path.
type ConfigSpace struct { type ConfigSpace struct {
Path string Path string
} }
// ConfigSpaceIO Interface for reading and writing raw and preconfigured values // ConfigSpaceIO Interface for reading and writing raw and preconfigured values.
type ConfigSpaceIO interface { type ConfigSpaceIO interface {
bytes.Bytes bytes.Bytes
GetVendorID() uint16 GetVendorID() uint16
@ -53,18 +53,18 @@ type configSpaceIO struct {
bytes.Bytes bytes.Bytes
} }
// PCIStandardCapability standard PCI config space // PCIStandardCapability standard PCI config space.
type PCIStandardCapability struct { type PCIStandardCapability struct {
bytes.Bytes bytes.Bytes
} }
// PCIExtendedCapability extended PCI config space // PCIExtendedCapability extended PCI config space.
type PCIExtendedCapability struct { type PCIExtendedCapability struct {
bytes.Bytes bytes.Bytes
Version uint8 Version uint8
} }
// PCICapabilities combines the standard and extended config space // PCICapabilities combines the standard and extended config space.
type PCICapabilities struct { type PCICapabilities struct {
Standard map[uint8]*PCIStandardCapability Standard map[uint8]*PCIStandardCapability
Extended map[uint16]*PCIExtendedCapability Extended map[uint16]*PCIExtendedCapability

View File

@ -22,15 +22,15 @@ import (
) )
const ( const (
// PCIMellanoxVendorID represents PCI vendor id for Mellanox // PCIMellanoxVendorID represents PCI vendor id for Mellanox.
PCIMellanoxVendorID uint16 = 0x15b3 PCIMellanoxVendorID uint16 = 0x15b3
// PCINetworkControllerClass represents the PCI class for network controllers // PCINetworkControllerClass represents the PCI class for network controllers.
PCINetworkControllerClass uint32 = 0x020000 PCINetworkControllerClass uint32 = 0x020000
// PCIBridgeClass represents the PCI class for network controllers // PCIBridgeClass represents the PCI class for network controllers.
PCIBridgeClass uint32 = 0x060400 PCIBridgeClass uint32 = 0x060400
) )
// GetNetworkControllers returns all Mellanox Network Controller PCI devices on the system // GetNetworkControllers returns all Mellanox Network Controller PCI devices on the system.
func (p *nvpci) GetNetworkControllers() ([]*NvidiaPCIDevice, error) { func (p *nvpci) GetNetworkControllers() ([]*NvidiaPCIDevice, error) {
devices, err := p.GetAllDevices() devices, err := p.GetAllDevices()
if err != nil { if err != nil {
@ -47,7 +47,7 @@ func (p *nvpci) GetNetworkControllers() ([]*NvidiaPCIDevice, error) {
return filtered, nil return filtered, nil
} }
// GetPciBridges retrieves all Mellanox PCI(e) Bridges // GetPciBridges retrieves all Mellanox PCI(e) Bridges.
func (p *nvpci) GetPciBridges() ([]*NvidiaPCIDevice, error) { func (p *nvpci) GetPciBridges() ([]*NvidiaPCIDevice, error) {
devices, err := p.GetAllDevices() devices, err := p.GetAllDevices()
if err != nil { if err != nil {
@ -64,17 +64,17 @@ func (p *nvpci) GetPciBridges() ([]*NvidiaPCIDevice, error) {
return filtered, nil return filtered, nil
} }
// IsNetworkController if class == 0x300 // IsNetworkController if class == 0x300.
func (d *NvidiaPCIDevice) IsNetworkController() bool { func (d *NvidiaPCIDevice) IsNetworkController() bool {
return d.Class == PCINetworkControllerClass return d.Class == PCINetworkControllerClass
} }
// IsPciBridge if class == 0x0604 // IsPciBridge if class == 0x0604.
func (d *NvidiaPCIDevice) IsPciBridge() bool { func (d *NvidiaPCIDevice) IsPciBridge() bool {
return d.Class == PCIBridgeClass return d.Class == PCIBridgeClass
} }
// IsDPU returns if a device is a DPU // IsDPU returns if a device is a DPU.
func (d *NvidiaPCIDevice) IsDPU() bool { func (d *NvidiaPCIDevice) IsDPU() bool {
if !strings.Contains(d.DeviceName, "BlueField") { if !strings.Contains(d.DeviceName, "BlueField") {
return false return false
@ -87,7 +87,7 @@ func (d *NvidiaPCIDevice) IsDPU() bool {
return false return false
} }
// GetDPUs returns all Mellanox DPU devices on the system // GetDPUs returns all Mellanox DPU devices on the system.
func (p *nvpci) GetDPUs() ([]*NvidiaPCIDevice, error) { func (p *nvpci) GetDPUs() ([]*NvidiaPCIDevice, error) {
devices, err := p.GetNetworkControllers() devices, err := p.GetNetworkControllers()
if err != nil { if err != nil {

View File

@ -25,7 +25,7 @@ import (
"github.com/NVIDIA/go-nvlib/pkg/nvpci/bytes" "github.com/NVIDIA/go-nvlib/pkg/nvpci/bytes"
) )
// Mmio memory map a region // Mmio memory map a region.
type Mmio interface { type Mmio interface {
bytes.Raw bytes.Raw
bytes.Reader bytes.Reader
@ -84,12 +84,12 @@ func open(path string, offset int, size int, flags int) (Mmio, error) {
return &mmio{bytes.New(&mmap)}, nil return &mmio{bytes.New(&mmap)}, nil
} }
// OpenRO open region readonly // OpenRO open region readonly.
func OpenRO(path string, offset int, size int) (Mmio, error) { func OpenRO(path string, offset int, size int) (Mmio, error) {
return open(path, offset, size, os.O_RDONLY) return open(path, offset, size, os.O_RDONLY)
} }
// OpenRW open region read write // OpenRW open region read write.
func OpenRW(path string, offset int, size int) (Mmio, error) { func OpenRW(path string, offset int, size int) (Mmio, error) {
return open(path, offset, size, os.O_RDWR) return open(path, offset, size, os.O_RDWR)
} }

View File

@ -102,41 +102,48 @@ func TestMmioWrite(t *testing.T) {
require.Equal(t, r8, source[tc.offset]) require.Equal(t, r8, source[tc.offset])
r8 = mmio.Read8(tc.offset) r8 = mmio.Read8(tc.offset)
require.Equal(t, r8, uint8((1<<8)-1)) require.Equal(t, r8, uint8((1<<8)-1))
mmio.Sync() err = mmio.Sync()
require.Nil(t, err, "Unexpected error from Sync")
require.Equal(t, r8, source[tc.offset]) require.Equal(t, r8, source[tc.offset])
mmio.Write8(tc.offset, uint8(tc.offset)) mmio.Write8(tc.offset, uint8(tc.offset))
mmio.Sync() err = mmio.Sync()
require.Nil(t, err, "Unexpected error from Sync")
r16 := mmio.Read16(tc.offset) r16 := mmio.Read16(tc.offset)
mmio.Write16(tc.offset, (1<<16)-1) mmio.Write16(tc.offset, (1<<16)-1)
require.Equal(t, r16, binary.LittleEndian.Uint16(source[tc.offset:tc.offset+2])) require.Equal(t, r16, binary.LittleEndian.Uint16(source[tc.offset:tc.offset+2]))
r16 = mmio.Read16(tc.offset) r16 = mmio.Read16(tc.offset)
require.Equal(t, r16, uint16((1<<16)-1)) require.Equal(t, r16, uint16((1<<16)-1))
mmio.Sync() err = mmio.Sync()
require.Nil(t, err, "Unexpected error from Sync")
require.Equal(t, r16, binary.LittleEndian.Uint16(source[tc.offset:tc.offset+2])) require.Equal(t, r16, binary.LittleEndian.Uint16(source[tc.offset:tc.offset+2]))
mmio.Write8(tc.offset+0, uint8(tc.offset+0)) mmio.Write8(tc.offset+0, uint8(tc.offset+0))
mmio.Write8(tc.offset+1, uint8(tc.offset+1)) mmio.Write8(tc.offset+1, uint8(tc.offset+1))
mmio.Sync() err = mmio.Sync()
require.Nil(t, err, "Unexpected error from Sync")
r32 := mmio.Read32(tc.offset) r32 := mmio.Read32(tc.offset)
mmio.Write32(tc.offset, (1<<32)-1) mmio.Write32(tc.offset, (1<<32)-1)
require.Equal(t, r32, binary.LittleEndian.Uint32(source[tc.offset:tc.offset+4])) require.Equal(t, r32, binary.LittleEndian.Uint32(source[tc.offset:tc.offset+4]))
r32 = mmio.Read32(tc.offset) r32 = mmio.Read32(tc.offset)
require.Equal(t, r32, uint32((1<<32)-1)) require.Equal(t, r32, uint32((1<<32)-1))
mmio.Sync() err = mmio.Sync()
require.Nil(t, err, "Unexpected error from Sync")
require.Equal(t, r32, binary.LittleEndian.Uint32(source[tc.offset:tc.offset+4])) require.Equal(t, r32, binary.LittleEndian.Uint32(source[tc.offset:tc.offset+4]))
mmio.Write8(tc.offset+0, uint8(tc.offset+0)) mmio.Write8(tc.offset+0, uint8(tc.offset+0))
mmio.Write8(tc.offset+1, uint8(tc.offset+1)) mmio.Write8(tc.offset+1, uint8(tc.offset+1))
mmio.Write8(tc.offset+2, uint8(tc.offset+2)) mmio.Write8(tc.offset+2, uint8(tc.offset+2))
mmio.Write8(tc.offset+3, uint8(tc.offset+3)) mmio.Write8(tc.offset+3, uint8(tc.offset+3))
mmio.Sync() err = mmio.Sync()
require.Nil(t, err, "Unexpected error from Sync")
r64 := mmio.Read64(tc.offset) r64 := mmio.Read64(tc.offset)
mmio.Write64(tc.offset, (1<<64)-1) mmio.Write64(tc.offset, (1<<64)-1)
require.Equal(t, r64, binary.LittleEndian.Uint64(source[tc.offset:tc.offset+8])) require.Equal(t, r64, binary.LittleEndian.Uint64(source[tc.offset:tc.offset+8]))
r64 = mmio.Read64(tc.offset) r64 = mmio.Read64(tc.offset)
require.Equal(t, r64, uint64((1<<64)-1)) require.Equal(t, r64, uint64((1<<64)-1))
mmio.Sync() err = mmio.Sync()
require.Nil(t, err, "Unexpected error from Sync")
require.Equal(t, r64, binary.LittleEndian.Uint64(source[tc.offset:tc.offset+8])) require.Equal(t, r64, binary.LittleEndian.Uint64(source[tc.offset:tc.offset+8]))
mmio.Write8(tc.offset+0, uint8(tc.offset+0)) mmio.Write8(tc.offset+0, uint8(tc.offset+0))
mmio.Write8(tc.offset+1, uint8(tc.offset+1)) mmio.Write8(tc.offset+1, uint8(tc.offset+1))
@ -146,7 +153,8 @@ func TestMmioWrite(t *testing.T) {
mmio.Write8(tc.offset+5, uint8(tc.offset+5)) mmio.Write8(tc.offset+5, uint8(tc.offset+5))
mmio.Write8(tc.offset+6, uint8(tc.offset+6)) mmio.Write8(tc.offset+6, uint8(tc.offset+6))
mmio.Write8(tc.offset+7, uint8(tc.offset+7)) mmio.Write8(tc.offset+7, uint8(tc.offset+7))
mmio.Sync() err = mmio.Sync()
require.Nil(t, err, "Unexpected error from Sync")
}) })
} }
} }

View File

@ -48,18 +48,21 @@ func mockOpen(source *[]byte, offset int, size int, rw bool) (Mmio, error) {
return m, nil return m, nil
} }
// MockOpenRO open read only // MockOpenRO open read only.
func MockOpenRO(source *[]byte, offset int, size int) (Mmio, error) { func MockOpenRO(source *[]byte, offset int, size int) (Mmio, error) {
return mockOpen(source, offset, size, false) return mockOpen(source, offset, size, false)
} }
// MockOpenRW open read write // MockOpenRW open read write.
func MockOpenRW(source *[]byte, offset int, size int) (Mmio, error) { func MockOpenRW(source *[]byte, offset int, size int) (Mmio, error) {
return mockOpen(source, offset, size, true) return mockOpen(source, offset, size, true)
} }
func (m *mockMmio) Close() error { func (m *mockMmio) Close() error {
m = &mockMmio{} m.Bytes = nil
m.source = nil
m.offset = 0
m.rw = false
return nil return nil
} }

View File

@ -24,14 +24,14 @@ import (
"github.com/NVIDIA/go-nvlib/pkg/nvpci/bytes" "github.com/NVIDIA/go-nvlib/pkg/nvpci/bytes"
) )
// MockNvpci mock pci device // MockNvpci mock pci device.
type MockNvpci struct { type MockNvpci struct {
*nvpci *nvpci
} }
var _ Interface = (*MockNvpci)(nil) var _ Interface = (*MockNvpci)(nil)
// NewMockNvpci create new mock PCI and remove old devices // NewMockNvpci create new mock PCI and remove old devices.
func NewMockNvpci() (mock *MockNvpci, rerr error) { func NewMockNvpci() (mock *MockNvpci, rerr error) {
rootDir, err := os.MkdirTemp(os.TempDir(), "") rootDir, err := os.MkdirTemp(os.TempDir(), "")
if err != nil { if err != nil {
@ -50,12 +50,12 @@ func NewMockNvpci() (mock *MockNvpci, rerr error) {
return mock, nil return mock, nil
} }
// Cleanup remove the mocked PCI devices root folder // Cleanup remove the mocked PCI devices root folder.
func (m *MockNvpci) Cleanup() { func (m *MockNvpci) Cleanup() {
os.RemoveAll(m.pciDevicesRoot) os.RemoveAll(m.pciDevicesRoot)
} }
// AddMockA100 Create an A100 like GPU mock device // AddMockA100 Create an A100 like GPU mock device.
func (m *MockNvpci) AddMockA100(address string, numaNode int) error { func (m *MockNvpci) AddMockA100(address string, numaNode int) error {
deviceDir := filepath.Join(m.pciDevicesRoot, address) deviceDir := filepath.Join(m.pciDevicesRoot, address)
err := os.MkdirAll(deviceDir, 0755) err := os.MkdirAll(deviceDir, 0755)

View File

@ -29,23 +29,23 @@ import (
) )
const ( const (
// PCIDevicesRoot represents base path for all pci devices under sysfs // PCIDevicesRoot represents base path for all pci devices under sysfs.
PCIDevicesRoot = "/sys/bus/pci/devices" PCIDevicesRoot = "/sys/bus/pci/devices"
// PCINvidiaVendorID represents PCI vendor id for NVIDIA // PCINvidiaVendorID represents PCI vendor id for NVIDIA.
PCINvidiaVendorID uint16 = 0x10de PCINvidiaVendorID uint16 = 0x10de
// PCIVgaControllerClass represents the PCI class for VGA Controllers // PCIVgaControllerClass represents the PCI class for VGA Controllers.
PCIVgaControllerClass uint32 = 0x030000 PCIVgaControllerClass uint32 = 0x030000
// PCI3dControllerClass represents the PCI class for 3D Graphics accellerators // PCI3dControllerClass represents the PCI class for 3D Graphics accellerators.
PCI3dControllerClass uint32 = 0x030200 PCI3dControllerClass uint32 = 0x030200
// PCINvSwitchClass represents the PCI class for NVSwitches // PCINvSwitchClass represents the PCI class for NVSwitches.
PCINvSwitchClass uint32 = 0x068000 PCINvSwitchClass uint32 = 0x068000
// UnknownDeviceString is the device name to set for devices not found in the PCI database // UnknownDeviceString is the device name to set for devices not found in the PCI database.
UnknownDeviceString = "UNKNOWN_DEVICE" UnknownDeviceString = "UNKNOWN_DEVICE"
// UnknownClassString is the class name to set for devices not found in the PCI database // UnknownClassString is the class name to set for devices not found in the PCI database.
UnknownClassString = "UNKNOWN_CLASS" UnknownClassString = "UNKNOWN_CLASS"
) )
// Interface allows us to get a list of all NVIDIA PCI devices // Interface allows us to get a list of all NVIDIA PCI devices.
type Interface interface { type Interface interface {
GetAllDevices() ([]*NvidiaPCIDevice, error) GetAllDevices() ([]*NvidiaPCIDevice, error)
Get3DControllers() ([]*NvidiaPCIDevice, error) Get3DControllers() ([]*NvidiaPCIDevice, error)
@ -59,10 +59,10 @@ type Interface interface {
GetDPUs() ([]*NvidiaPCIDevice, error) GetDPUs() ([]*NvidiaPCIDevice, error)
} }
// MemoryResources a more human readable handle // MemoryResources a more human readable handle.
type MemoryResources map[int]*MemoryResource type MemoryResources map[int]*MemoryResource
// ResourceInterface exposes some higher level functions of resources // ResourceInterface exposes some higher level functions of resources.
type ResourceInterface interface { type ResourceInterface interface {
GetTotalAddressableMemory(bool) (uint64, uint64) GetTotalAddressableMemory(bool) (uint64, uint64)
} }
@ -76,7 +76,7 @@ type nvpci struct {
var _ Interface = (*nvpci)(nil) var _ Interface = (*nvpci)(nil)
var _ ResourceInterface = (*MemoryResources)(nil) var _ ResourceInterface = (*MemoryResources)(nil)
// NvidiaPCIDevice represents a PCI device for an NVIDIA product // NvidiaPCIDevice represents a PCI device for an NVIDIA product.
type NvidiaPCIDevice struct { type NvidiaPCIDevice struct {
Path string Path string
Address string Address string
@ -93,34 +93,34 @@ type NvidiaPCIDevice struct {
IsVF bool IsVF bool
} }
// IsVGAController if class == 0x300 // IsVGAController if class == 0x300.
func (d *NvidiaPCIDevice) IsVGAController() bool { func (d *NvidiaPCIDevice) IsVGAController() bool {
return d.Class == PCIVgaControllerClass return d.Class == PCIVgaControllerClass
} }
// Is3DController if class == 0x302 // Is3DController if class == 0x302.
func (d *NvidiaPCIDevice) Is3DController() bool { func (d *NvidiaPCIDevice) Is3DController() bool {
return d.Class == PCI3dControllerClass return d.Class == PCI3dControllerClass
} }
// IsNVSwitch if class == 0x068 // IsNVSwitch if class == 0x068.
func (d *NvidiaPCIDevice) IsNVSwitch() bool { func (d *NvidiaPCIDevice) IsNVSwitch() bool {
return d.Class == PCINvSwitchClass return d.Class == PCINvSwitchClass
} }
// IsGPU either VGA for older cards or 3D for newer // IsGPU either VGA for older cards or 3D for newer.
func (d *NvidiaPCIDevice) IsGPU() bool { func (d *NvidiaPCIDevice) IsGPU() bool {
return d.IsVGAController() || d.Is3DController() return d.IsVGAController() || d.Is3DController()
} }
// IsResetAvailable some devices can be reset without rebooting, // IsResetAvailable some devices can be reset without rebooting,
// check if applicable // check if applicable.
func (d *NvidiaPCIDevice) IsResetAvailable() bool { func (d *NvidiaPCIDevice) IsResetAvailable() bool {
_, err := os.Stat(path.Join(d.Path, "reset")) _, err := os.Stat(path.Join(d.Path, "reset"))
return err == nil return err == nil
} }
// Reset perform a reset to apply a new configuration at HW level // Reset perform a reset to apply a new configuration at HW level.
func (d *NvidiaPCIDevice) Reset() error { func (d *NvidiaPCIDevice) Reset() error {
err := os.WriteFile(path.Join(d.Path, "reset"), []byte("1"), 0) err := os.WriteFile(path.Join(d.Path, "reset"), []byte("1"), 0)
if err != nil { if err != nil {
@ -129,7 +129,7 @@ func (d *NvidiaPCIDevice) Reset() error {
return nil return nil
} }
// New interface that allows us to get a list of all NVIDIA PCI devices // New interface that allows us to get a list of all NVIDIA PCI devices.
func New(opts ...Option) Interface { func New(opts ...Option) Interface {
n := &nvpci{} n := &nvpci{}
for _, opt := range opts { for _, opt := range opts {
@ -144,10 +144,10 @@ func New(opts ...Option) Interface {
return n return n
} }
// Option defines a function for passing options to the New() call // Option defines a function for passing options to the New() call.
type Option func(*nvpci) type Option func(*nvpci)
// WithLogger provides an Option to set the logger for the library // WithLogger provides an Option to set the logger for the library.
func WithLogger(logger logger) Option { func WithLogger(logger logger) Option {
return func(n *nvpci) { return func(n *nvpci) {
n.logger = logger n.logger = logger
@ -170,7 +170,7 @@ func WithPCIDatabasePath(path string) Option {
} }
} }
// GetAllDevices returns all Nvidia PCI devices on the system // GetAllDevices returns all Nvidia PCI devices on the system.
func (p *nvpci) GetAllDevices() ([]*NvidiaPCIDevice, error) { func (p *nvpci) GetAllDevices() ([]*NvidiaPCIDevice, error) {
deviceDirs, err := os.ReadDir(p.pciDevicesRoot) deviceDirs, err := os.ReadDir(p.pciDevicesRoot)
if err != nil { if err != nil {
@ -204,7 +204,7 @@ func (p *nvpci) GetAllDevices() ([]*NvidiaPCIDevice, error) {
return nvdevices, nil return nvdevices, nil
} }
// GetGPUByPciBusID constructs an NvidiaPCIDevice for the specified address (PCI Bus ID) // GetGPUByPciBusID constructs an NvidiaPCIDevice for the specified address (PCI Bus ID).
func (p *nvpci) GetGPUByPciBusID(address string) (*NvidiaPCIDevice, error) { func (p *nvpci) GetGPUByPciBusID(address string) (*NvidiaPCIDevice, error) {
devicePath := filepath.Join(p.pciDevicesRoot, address) devicePath := filepath.Join(p.pciDevicesRoot, address)
@ -265,7 +265,7 @@ func (p *nvpci) GetGPUByPciBusID(address string) (*NvidiaPCIDevice, error) {
return nil, fmt.Errorf("unable to detect iommu_group for %s: %v", address, err) return nil, fmt.Errorf("unable to detect iommu_group for %s: %v", address, err)
} }
// device is a virtual function (VF) if "physfn" symlink exists // device is a virtual function (VF) if "physfn" symlink exists.
var isVF bool var isVF bool
_, err = filepath.EvalSymlinks(path.Join(devicePath, "physfn")) _, err = filepath.EvalSymlinks(path.Join(devicePath, "physfn"))
if err == nil { if err == nil {
@ -347,7 +347,7 @@ func (p *nvpci) GetGPUByPciBusID(address string) (*NvidiaPCIDevice, error) {
return nvdevice, nil return nvdevice, nil
} }
// Get3DControllers returns all NVIDIA 3D Controller PCI devices on the system // Get3DControllers returns all NVIDIA 3D Controller PCI devices on the system.
func (p *nvpci) Get3DControllers() ([]*NvidiaPCIDevice, error) { func (p *nvpci) Get3DControllers() ([]*NvidiaPCIDevice, error) {
devices, err := p.GetAllDevices() devices, err := p.GetAllDevices()
if err != nil { if err != nil {
@ -364,7 +364,7 @@ func (p *nvpci) Get3DControllers() ([]*NvidiaPCIDevice, error) {
return filtered, nil return filtered, nil
} }
// GetVGAControllers returns all NVIDIA VGA Controller PCI devices on the system // GetVGAControllers returns all NVIDIA VGA Controller PCI devices on the system.
func (p *nvpci) GetVGAControllers() ([]*NvidiaPCIDevice, error) { func (p *nvpci) GetVGAControllers() ([]*NvidiaPCIDevice, error) {
devices, err := p.GetAllDevices() devices, err := p.GetAllDevices()
if err != nil { if err != nil {
@ -381,7 +381,7 @@ func (p *nvpci) GetVGAControllers() ([]*NvidiaPCIDevice, error) {
return filtered, nil return filtered, nil
} }
// GetNVSwitches returns all NVIDIA NVSwitch PCI devices on the system // GetNVSwitches returns all NVIDIA NVSwitch PCI devices on the system.
func (p *nvpci) GetNVSwitches() ([]*NvidiaPCIDevice, error) { func (p *nvpci) GetNVSwitches() ([]*NvidiaPCIDevice, error) {
devices, err := p.GetAllDevices() devices, err := p.GetAllDevices()
if err != nil { if err != nil {
@ -398,7 +398,7 @@ func (p *nvpci) GetNVSwitches() ([]*NvidiaPCIDevice, error) {
return filtered, nil return filtered, nil
} }
// GetGPUs returns all NVIDIA GPU devices on the system // GetGPUs returns all NVIDIA GPU devices on the system.
func (p *nvpci) GetGPUs() ([]*NvidiaPCIDevice, error) { func (p *nvpci) GetGPUs() ([]*NvidiaPCIDevice, error) {
devices, err := p.GetAllDevices() devices, err := p.GetAllDevices()
if err != nil { if err != nil {
@ -415,7 +415,7 @@ func (p *nvpci) GetGPUs() ([]*NvidiaPCIDevice, error) {
return filtered, nil return filtered, nil
} }
// GetGPUByIndex returns an NVIDIA GPU device at a particular index // GetGPUByIndex returns an NVIDIA GPU device at a particular index.
func (p *nvpci) GetGPUByIndex(i int) (*NvidiaPCIDevice, error) { func (p *nvpci) GetGPUByIndex(i int) (*NvidiaPCIDevice, error) {
gpus, err := p.GetGPUs() gpus, err := p.GetGPUs()
if err != nil { if err != nil {

View File

@ -71,7 +71,7 @@ func TestNvpci(t *testing.T) {
require.Nil(t, err, "Error getting GPU at index 0") require.Nil(t, err, "Error getting GPU at index 0")
require.Equal(t, "0000:80:05.1", device.Address, "Wrong Address found for device") require.Equal(t, "0000:80:05.1", device.Address, "Wrong Address found for device")
device, err = nvpci.GetGPUByIndex(1) _, err = nvpci.GetGPUByIndex(1)
require.Error(t, err, "No error returned when getting GPU at invalid index") require.Error(t, err, "No error returned when getting GPU at invalid index")
} }

View File

@ -29,7 +29,7 @@ const (
pmcBigEndian = 0x01000001 pmcBigEndian = 0x01000001
) )
// MemoryResource represents a mmio region // MemoryResource represents a mmio region.
type MemoryResource struct { type MemoryResource struct {
Start uintptr Start uintptr
End uintptr End uintptr
@ -37,7 +37,7 @@ type MemoryResource struct {
Path string Path string
} }
// OpenRW read write mmio region // OpenRW read write mmio region.
func (mr *MemoryResource) OpenRW() (mmio.Mmio, error) { func (mr *MemoryResource) OpenRW() (mmio.Mmio, error) {
rw, err := mmio.OpenRW(mr.Path, 0, int(mr.End-mr.Start+1)) rw, err := mmio.OpenRW(mr.Path, 0, int(mr.End-mr.Start+1))
if err != nil { if err != nil {
@ -52,7 +52,7 @@ func (mr *MemoryResource) OpenRW() (mmio.Mmio, error) {
return nil, fmt.Errorf("unknown endianness for mmio: %v", err) return nil, fmt.Errorf("unknown endianness for mmio: %v", err)
} }
// OpenRO read only mmio region // OpenRO read only mmio region.
func (mr *MemoryResource) OpenRO() (mmio.Mmio, error) { func (mr *MemoryResource) OpenRO() (mmio.Mmio, error) {
ro, err := mmio.OpenRO(mr.Path, 0, int(mr.End-mr.Start+1)) ro, err := mmio.OpenRO(mr.Path, 0, int(mr.End-mr.Start+1))
if err != nil { if err != nil {
@ -67,7 +67,7 @@ func (mr *MemoryResource) OpenRO() (mmio.Mmio, error) {
return nil, fmt.Errorf("unknown endianness for mmio: %v", err) return nil, fmt.Errorf("unknown endianness for mmio: %v", err)
} }
// From Bit Twiddling Hacks, great resource for all low level bit manipulations // From Bit Twiddling Hacks, great resource for all low level bit manipulations.
func calcNextPowerOf2(n uint64) uint64 { func calcNextPowerOf2(n uint64) uint64 {
n-- n--
n |= n >> 1 n |= n >> 1
@ -83,7 +83,7 @@ func calcNextPowerOf2(n uint64) uint64 {
// GetTotalAddressableMemory will accumulate the 32bit and 64bit memory windows // GetTotalAddressableMemory will accumulate the 32bit and 64bit memory windows
// of each BAR and round the value if needed to the next power of 2; first // of each BAR and round the value if needed to the next power of 2; first
// return value is the accumulated 32bit addresable memory size the second one // return value is the accumulated 32bit addressable memory size the second one
// is the accumulated 64bit addressable memory size in bytes. These values are // is the accumulated 64bit addressable memory size in bytes. These values are
// needed to configure virtualized environments. // needed to configure virtualized environments.
func (mrs MemoryResources) GetTotalAddressableMemory(roundUp bool) (uint64, uint64) { func (mrs MemoryResources) GetTotalAddressableMemory(roundUp bool) (uint64, uint64) {

View File

@ -11,42 +11,42 @@ import (
"strings" "strings"
) )
// token what the Lexer retruns // token what the Lexer retruns.
type token int type token int
const ( const (
// ILLEGAL a token which the Lexer does not understand // ILLEGAL a token which the Lexer does not understand.
ILLEGAL token = iota ILLEGAL token = iota
// EOF end of file // EOF end of file.
EOF EOF
// WS whitespace // WS whitespace.
WS WS
// NEWLINE '\n' // NEWLINE '\n'.
NEWLINE NEWLINE
// COMMENT '# something' // COMMENT '# something'.
COMMENT COMMENT
// VENDOR PCI vendor // VENDOR PCI vendor.
VENDOR VENDOR
// SUBVENDOR PCI subvendor // SUBVENDOR PCI subvendor.
SUBVENDOR SUBVENDOR
// DEVICE PCI device // DEVICE PCI device.
DEVICE DEVICE
// CLASS PCI class // CLASS PCI class.
CLASS CLASS
// SUBCLASS PCI subclass // SUBCLASS PCI subclass.
SUBCLASS SUBCLASS
// PROGIF PCI programming interface // PROGIF PCI programming interface.
PROGIF PROGIF
) )
// literal values from the Lexer // literal values from the Lexer.
type literal struct { type literal struct {
ID string ID string
name string name string
SubName string SubName string
} }
// scanner a lexical scanner // scanner a lexical scanner.
type scanner struct { type scanner struct {
r *bufio.Reader r *bufio.Reader
isVendor bool isVendor bool
@ -58,7 +58,7 @@ func newScanner(r io.Reader) *scanner {
} }
// Since the pci.ids is line base we're consuming a whole line rather then only // Since the pci.ids is line base we're consuming a whole line rather then only
// a single rune/char // a single rune/char.
func (s *scanner) readline() []byte { func (s *scanner) readline() []byte {
ln, err := s.r.ReadBytes('\n') ln, err := s.r.ReadBytes('\n')
if err == io.EOF { if err == io.EOF {
@ -107,7 +107,7 @@ func isSubVendor(ln []byte) bool { return isLeadingTwoTabs(ln) }
func isDevice(ln []byte) bool { return isLeadingOneTab(ln) } func isDevice(ln []byte) bool { return isLeadingOneTab(ln) }
func isNewline(ln []byte) bool { return (ln[0] == '\n') } func isNewline(ln []byte) bool { return (ln[0] == '\n') }
// List of known device classes, subclasses and programming interfaces // List of known device classes, subclasses and programming interfaces.
func isClass(ln []byte) bool { return (ln[0] == 'C') } func isClass(ln []byte) bool { return (ln[0] == 'C') }
func isProgIf(ln []byte) bool { return isLeadingTwoTabs(ln) } func isProgIf(ln []byte) bool { return isLeadingTwoTabs(ln) }
func isSubClass(ln []byte) bool { return isLeadingOneTab(ln) } func isSubClass(ln []byte) bool { return isLeadingOneTab(ln) }
@ -162,7 +162,7 @@ func (s *scanner) scan() (tok token, lit literal) {
return ILLEGAL, literal{ID: string(line)} return ILLEGAL, literal{ID: string(line)}
} }
// parser reads the tokens returned by the Lexer and constructs the AST // parser reads the tokens returned by the Lexer and constructs the AST.
type parser struct { type parser struct {
s *scanner s *scanner
buf struct { buf struct {
@ -173,7 +173,7 @@ type parser struct {
} }
// Various locations of pci.ids for different distributions. These may be more // Various locations of pci.ids for different distributions. These may be more
// up to date then the embedded pci.ids db // up to date then the embedded pci.ids db.
var defaultPCIdbPaths = []string{ var defaultPCIdbPaths = []string{
"/usr/share/misc/pci.ids", // Ubuntu "/usr/share/misc/pci.ids", // Ubuntu
"/usr/local/share/pci.ids", // RHEL like with manual update "/usr/local/share/pci.ids", // RHEL like with manual update
@ -202,7 +202,7 @@ func NewDB(opts ...Option) Interface {
return newParser(pcidbs).parse() return newParser(pcidbs).parse()
} }
// Option defines a function for passing options to the NewDB() call // Option defines a function for passing options to the NewDB() call.
type Option func(*pcidb) type Option func(*pcidb)
// WithFilePath provides an Option to set the file path // WithFilePath provides an Option to set the file path
@ -216,7 +216,7 @@ func WithFilePath(path string) Option {
} }
// newParser will attempt to read the db pci.ids from well known places or fall // newParser will attempt to read the db pci.ids from well known places or fall
// back to an internal db // back to an internal db.
func newParser(pcidbs []string) *parser { func newParser(pcidbs []string) *parser {
for _, db := range pcidbs { for _, db := range pcidbs {
@ -229,7 +229,7 @@ func newParser(pcidbs []string) *parser {
} }
// We're using go embed above to have the byte array // We're using go embed above to have the byte array
// correctly initialized with the internal shipped db // correctly initialized with the internal shipped db
// if we cannot find an up to date in the filesystem // if we cannot find an up to date in the filesystem.
return newParserFromReader(bufio.NewReader(bytes.NewReader(defaultPCIdb))) return newParserFromReader(bufio.NewReader(bytes.NewReader(defaultPCIdb)))
} }
@ -252,13 +252,13 @@ func (p *parser) unscan() { p.buf.n = 1 }
var _ Interface = (*pcidb)(nil) var _ Interface = (*pcidb)(nil)
// Interface returns textual description of specific attributes of PCI devices // Interface returns textual description of specific attributes of PCI devices.
type Interface interface { type Interface interface {
GetDeviceName(uint16, uint16) (string, error) GetDeviceName(uint16, uint16) (string, error)
GetClassName(uint32) (string, error) GetClassName(uint32) (string, error)
} }
// GetDeviceName return the textual description of the PCI device // GetDeviceName return the textual description of the PCI device.
func (d *pcidb) GetDeviceName(vendorID uint16, deviceID uint16) (string, error) { func (d *pcidb) GetDeviceName(vendorID uint16, deviceID uint16) (string, error) {
vendor, ok := d.vendors[vendorID] vendor, ok := d.vendors[vendorID]
if !ok { if !ok {
@ -273,7 +273,7 @@ func (d *pcidb) GetDeviceName(vendorID uint16, deviceID uint16) (string, error)
return device.name, nil return device.name, nil
} }
// GetClassName resturn the textual description of the PCI device class // GetClassName resturn the textual description of the PCI device class.
func (d *pcidb) GetClassName(classID uint32) (string, error) { func (d *pcidb) GetClassName(classID uint32) (string, error) {
class, ok := d.classes[classID] class, ok := d.classes[classID]
if !ok { if !ok {
@ -282,53 +282,53 @@ func (d *pcidb) GetClassName(classID uint32) (string, error) {
return class.name, nil return class.name, nil
} }
// pcidb The complete set of PCI vendors and PCI classes // pcidb The complete set of PCI vendors and PCI classes.
type pcidb struct { type pcidb struct {
vendors map[uint16]vendor vendors map[uint16]vendor
classes map[uint32]class classes map[uint32]class
path string path string
} }
// vendor PCI vendors/devices/subVendors/SubDevices // vendor PCI vendors/devices/subVendors/SubDevices.
type vendor struct { type vendor struct {
name string name string
devices map[uint16]device devices map[uint16]device
} }
// subVendor PCI subVendor // subVendor PCI subVendor.
type subVendor struct { type subVendor struct {
SubDevices map[uint16]SubDevice SubDevices map[uint16]SubDevice
} }
// SubDevice PCI SubDevice // SubDevice PCI SubDevice.
type SubDevice struct { type SubDevice struct {
name string name string
} }
// device PCI device // device PCI device.
type device struct { type device struct {
name string name string
subVendors map[uint16]subVendor subVendors map[uint16]subVendor
} }
// class PCI classes/subClasses/Programming Interfaces // class PCI classes/subClasses/Programming Interfaces.
type class struct { type class struct {
name string name string
subClasses map[uint32]subClass subClasses map[uint32]subClass
} }
// subClass PCI subClass // subClass PCI subClass.
type subClass struct { type subClass struct {
name string name string
progIfs map[uint8]progIf progIfs map[uint8]progIf
} }
// progIf PCI Programming Interface // progIf PCI Programming Interface.
type progIf struct { type progIf struct {
name string name string
} }
// parse parses a PCI IDS entry // parse parses a PCI IDS entry.
func (p *parser) parse() Interface { func (p *parser) parse() Interface {
db := &pcidb{ db := &pcidb{
@ -336,7 +336,7 @@ func (p *parser) parse() Interface {
classes: map[uint32]class{}, classes: map[uint32]class{},
} }
// Used for housekeeping, breadcrumb for aggregated types // Used for housekeeping, breadcrumb for aggregated types.
var hkVendor vendor var hkVendor vendor
var hkDevice device var hkDevice device
@ -349,8 +349,8 @@ func (p *parser) parse() Interface {
for { for {
tok, lit := p.scan() tok, lit := p.scan()
// We're ignoring COMMENT, NEWLINE // We're ignoring COMMENT, NEWLINE.
// An EOF will break the loop // An EOF will break the loop.
if tok == EOF { if tok == EOF {
break break
} }
@ -408,10 +408,10 @@ func (p *parser) parse() Interface {
} }
hkSubClass = hkClass.subClasses[uint32(id)] hkSubClass = hkClass.subClasses[uint32(id)]
// Clear the last detected sub class // Clear the last detected sub class.
hkFullID = hkFullID & 0xFFFF0000 hkFullID = hkFullID & 0xFFFF0000
hkFullID = hkFullID | uint32(id)<<8 hkFullID = hkFullID | uint32(id)<<8
// Clear the last detected prog iface // Clear the last detected prog iface.
hkFullID = hkFullID & 0xFFFFFF00 hkFullID = hkFullID & 0xFFFFFF00
hkFullName[1] = fmt.Sprintf("%s (%02x)", lit.name, id) hkFullName[1] = fmt.Sprintf("%s (%02x)", lit.name, id)