Use GetLibrary().Lookup() in nvml package

This change uses the GetLibrary().Lookup() function in the nvml package
to check whether a particular function is available. This avoids
the need to explicitly open a library, for example.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
This commit is contained in:
Evan Lezar 2023-10-13 16:47:16 +02:00
parent 486ed3f0c8
commit 278851d719
4 changed files with 58 additions and 20 deletions

View File

@ -19,7 +19,6 @@ package device
import ( import (
"fmt" "fmt"
"github.com/NVIDIA/go-nvml/pkg/dl"
"gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvml" "gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvml"
) )
@ -152,8 +151,7 @@ func (d *device) GetCudaComputeCapabilityAsString() (string, error) {
// 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) {
err := d.lib.nvmlLookupSymbol("nvmlDeviceGetMigMode") if !d.lib.hasSymbol("nvmlDeviceGetMigMode") {
if err != nil {
return false, nil return false, nil
} }
@ -170,8 +168,7 @@ func (d *device) IsMigCapable() (bool, error) {
// 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) {
err := d.lib.nvmlLookupSymbol("nvmlDeviceGetMigMode") if !d.lib.hasSymbol("nvmlDeviceGetMigMode") {
if err != nil {
return false, nil return false, nil
} }
@ -465,22 +462,12 @@ func (d *devicelib) GetMigProfiles() ([]MigProfile, error) {
return profiles, nil return profiles, nil
} }
// nvmlLookupSymbol checks to see if the given symbol is present in the NVML library // hasSymbol checks to see if the given symbol is present in the NVML library.
func (d *devicelib) nvmlLookupSymbol(symbol string) error { // If devicelib is configured to not verify symbols, then all symbols are assumed to exist.
// If devicelib is configured to not verify symbols, then we short-circuit here func (d *devicelib) hasSymbol(symbol string) bool {
if !*d.verifySymbols { if !*d.verifySymbols {
return nil return true
} }
// Otherwise we lookup the provided symbol and verify it is available return d.nvml.Lookup(symbol) == nil
lib := dl.New("libnvidia-ml.so.1", dl.RTLD_LAZY|dl.RTLD_GLOBAL)
if lib == nil {
return fmt.Errorf("error instantiating DynamicLibrary for NVML")
}
err := lib.Open()
if err != nil {
return fmt.Errorf("error opening DynamicLibrary for NVML: %v", err)
}
defer lib.Close()
return lib.Lookup(symbol)
} }

View File

@ -34,6 +34,12 @@ func New() Interface {
return &nvmlLib{} return &nvmlLib{}
} }
// Lookup checks whether the specified symbol exists in the configured NVML library.
func (n *nvmlLib) Lookup(name string) error {
// TODO: For now we rely on the default NVML library and perform the lookups against this.
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()

View File

@ -35,6 +35,9 @@ var _ Interface = &InterfaceMock{}
// InitFunc: func() Return { // InitFunc: func() Return {
// panic("mock out the Init method") // panic("mock out the Init method")
// }, // },
// LookupFunc: func(s string) error {
// panic("mock out the Lookup method")
// },
// ShutdownFunc: func() Return { // ShutdownFunc: func() Return {
// panic("mock out the Shutdown method") // panic("mock out the Shutdown method")
// }, // },
@ -69,6 +72,9 @@ type InterfaceMock struct {
// InitFunc mocks the Init method. // InitFunc mocks the Init method.
InitFunc func() Return InitFunc func() Return
// LookupFunc mocks the Lookup method.
LookupFunc func(s string) error
// ShutdownFunc mocks the Shutdown method. // ShutdownFunc mocks the Shutdown method.
ShutdownFunc func() Return ShutdownFunc func() Return
@ -104,6 +110,11 @@ type InterfaceMock struct {
// Init holds details about calls to the Init method. // Init holds details about calls to the Init method.
Init []struct { Init []struct {
} }
// Lookup holds details about calls to the Lookup method.
Lookup []struct {
// S is the s argument value.
S string
}
// Shutdown holds details about calls to the Shutdown method. // Shutdown holds details about calls to the Shutdown method.
Shutdown []struct { Shutdown []struct {
} }
@ -120,6 +131,7 @@ type InterfaceMock struct {
lockErrorString sync.RWMutex lockErrorString sync.RWMutex
lockEventSetCreate sync.RWMutex lockEventSetCreate sync.RWMutex
lockInit sync.RWMutex lockInit sync.RWMutex
lockLookup sync.RWMutex
lockShutdown sync.RWMutex lockShutdown sync.RWMutex
lockSystemGetCudaDriverVersion sync.RWMutex lockSystemGetCudaDriverVersion sync.RWMutex
lockSystemGetDriverVersion sync.RWMutex lockSystemGetDriverVersion sync.RWMutex
@ -302,6 +314,38 @@ func (mock *InterfaceMock) InitCalls() []struct {
return calls return calls
} }
// Lookup calls LookupFunc.
func (mock *InterfaceMock) Lookup(s string) error {
if mock.LookupFunc == nil {
panic("InterfaceMock.LookupFunc: method is nil but Interface.Lookup was just called")
}
callInfo := struct {
S string
}{
S: s,
}
mock.lockLookup.Lock()
mock.calls.Lookup = append(mock.calls.Lookup, callInfo)
mock.lockLookup.Unlock()
return mock.LookupFunc(s)
}
// LookupCalls gets all the calls that were made to Lookup.
// Check the length with:
//
// len(mockedInterface.LookupCalls())
func (mock *InterfaceMock) LookupCalls() []struct {
S string
} {
var calls []struct {
S string
}
mock.lockLookup.RLock()
calls = mock.calls.Lookup
mock.lockLookup.RUnlock()
return calls
}
// Shutdown calls ShutdownFunc. // Shutdown calls ShutdownFunc.
func (mock *InterfaceMock) Shutdown() Return { func (mock *InterfaceMock) Shutdown() Return {
if mock.ShutdownFunc == nil { if mock.ShutdownFunc == nil {

View File

@ -30,6 +30,7 @@ type Interface interface {
ErrorString(r Return) string ErrorString(r Return) string
EventSetCreate() (EventSet, Return) EventSetCreate() (EventSet, Return)
Init() Return Init() Return
Lookup(string) error
Shutdown() Return Shutdown() Return
SystemGetCudaDriverVersion() (int, Return) SystemGetCudaDriverVersion() (int, Return)
SystemGetDriverVersion() (string, Return) SystemGetDriverVersion() (string, Return)