Update vendoring for nvpci

Signed-off-by: Evan Lezar <elezar@nvidia.com>
This commit is contained in:
Evan Lezar 2023-01-24 10:37:46 +01:00
parent 1d7e419008
commit 540f4349f5
25 changed files with 37514 additions and 187 deletions

4
go.mod
View File

@ -6,12 +6,13 @@ require (
github.com/BurntSushi/toml v1.0.0 github.com/BurntSushi/toml v1.0.0
github.com/NVIDIA/go-nvml v0.11.6-0.0.20220823120812-7e2082095e82 github.com/NVIDIA/go-nvml v0.11.6-0.0.20220823120812-7e2082095e82
github.com/container-orchestrated-devices/container-device-interface v0.5.4-0.20230111111500-5b3b5d81179a github.com/container-orchestrated-devices/container-device-interface v0.5.4-0.20230111111500-5b3b5d81179a
github.com/fsnotify/fsnotify v1.5.4
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb
github.com/pelletier/go-toml v1.9.4 github.com/pelletier/go-toml v1.9.4
github.com/sirupsen/logrus v1.9.0 github.com/sirupsen/logrus v1.9.0
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
github.com/urfave/cli/v2 v2.3.0 github.com/urfave/cli/v2 v2.3.0
gitlab.com/nvidia/cloud-native/go-nvlib v0.0.0-20220922133427-1049a7fa76a9 gitlab.com/nvidia/cloud-native/go-nvlib v0.0.0-20230119114711-6fe07bb33342
golang.org/x/mod v0.5.0 golang.org/x/mod v0.5.0
golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6 golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6
sigs.k8s.io/yaml v1.3.0 sigs.k8s.io/yaml v1.3.0
@ -20,7 +21,6 @@ require (
require ( require (
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/kr/text v0.2.0 // indirect github.com/kr/text v0.2.0 // indirect
github.com/opencontainers/runc v1.1.4 // indirect github.com/opencontainers/runc v1.1.4 // indirect

4
go.sum
View File

@ -86,8 +86,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
gitlab.com/nvidia/cloud-native/go-nvlib v0.0.0-20220922133427-1049a7fa76a9 h1:3C1cK0/n1HGfH0MPCCPRntK8xPNlrVq9OWR4RA72jW0= gitlab.com/nvidia/cloud-native/go-nvlib v0.0.0-20230119114711-6fe07bb33342 h1:083n9fJt2dWOpJd/X/q9Xgl5XtQLL22uSFYbzVqJssg=
gitlab.com/nvidia/cloud-native/go-nvlib v0.0.0-20220922133427-1049a7fa76a9/go.mod h1:GStidGxhaqJhYFW1YpOnLvYCbL2EsM0od7IW4u7+JgU= gitlab.com/nvidia/cloud-native/go-nvlib v0.0.0-20230119114711-6fe07bb33342/go.mod h1:GStidGxhaqJhYFW1YpOnLvYCbL2EsM0od7IW4u7+JgU=
golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q= golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q=
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=

View File

@ -0,0 +1,4 @@
The file pkg/pciids/default_pci.ids is distributed under the 3-clause BSD License.
Maintained by Albert Pool, Martin Mares, and other volunteers from
the PCI ID Project at https://pci-ids.ucw.cz/.

View File

@ -26,7 +26,9 @@ type Interface interface {
GetMigDevices() ([]MigDevice, error) GetMigDevices() ([]MigDevice, error)
GetMigProfiles() ([]MigProfile, error) GetMigProfiles() ([]MigProfile, error)
NewDevice(d nvml.Device) (Device, error) NewDevice(d nvml.Device) (Device, error)
NewDeviceByUUID(uuid string) (Device, error)
NewMigDevice(d nvml.Device) (MigDevice, error) NewMigDevice(d nvml.Device) (MigDevice, error)
NewMigDeviceByUUID(uuid string) (MigDevice, error)
NewMigProfile(giProfileID, ciProfileID, ciEngProfileID int, migMemorySizeMB, deviceMemorySizeBytes uint64) (MigProfile, error) NewMigProfile(giProfileID, ciProfileID, ciEngProfileID int, migMemorySizeMB, deviceMemorySizeBytes uint64) (MigProfile, error)
ParseMigProfile(profile string) (MigProfile, error) ParseMigProfile(profile string) (MigProfile, error)
VisitDevices(func(i int, d Device) error) error VisitDevices(func(i int, d Device) error) error
@ -35,7 +37,8 @@ type Interface interface {
} }
type devicelib struct { type devicelib struct {
nvml nvml.Interface nvml nvml.Interface
skippedDevices map[string]struct{}
} }
var _ Interface = &devicelib{} var _ Interface = &devicelib{}
@ -49,6 +52,12 @@ func New(opts ...Option) Interface {
if d.nvml == nil { if d.nvml == nil {
d.nvml = nvml.New() d.nvml = nvml.New()
} }
if d.skippedDevices == nil {
WithSkippedDevices(
"DGX Display",
"NVIDIA DGX Display",
)(d)
}
return d return d
} }
@ -59,5 +68,17 @@ func WithNvml(nvml nvml.Interface) Option {
} }
} }
// WithSkippedDevices provides an Option to set devices to be skipped by model name
func WithSkippedDevices(names ...string) Option {
return func(d *devicelib) {
if d.skippedDevices == nil {
d.skippedDevices = make(map[string]struct{})
}
for _, name := range names {
d.skippedDevices[name] = struct{}{}
}
}
}
// 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

@ -43,6 +43,20 @@ 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)
}
// NewDeviceByUUID builds a new Device from a UUID
func (d *devicelib) NewDeviceByUUID(uuid string) (Device, error) {
dev, ret := d.nvml.DeviceGetHandleByUUID(uuid)
if ret != nvml.SUCCESS {
return nil, fmt.Errorf("error getting device handle for uuid '%v': %v", uuid, ret)
}
return d.newDevice(dev)
}
// newDevice creates a device from an nvml.Device
func (d *devicelib) newDevice(dev nvml.Device) (*device, error) {
return &device{dev, d}, nil return &device{dev, d}, nil
} }
@ -130,6 +144,12 @@ func (d *device) VisitMigProfiles(visit func(MigProfile) error) error {
for i := 0; i < nvml.GPU_INSTANCE_PROFILE_COUNT; i++ { for i := 0; i < nvml.GPU_INSTANCE_PROFILE_COUNT; i++ {
giProfileInfo, ret := d.GetGpuInstanceProfileInfo(i) giProfileInfo, ret := d.GetGpuInstanceProfileInfo(i)
if ret == nvml.ERROR_NOT_SUPPORTED {
continue
}
if ret == nvml.ERROR_INVALID_ARGUMENT {
continue
}
if ret != nvml.SUCCESS { if ret != nvml.SUCCESS {
return fmt.Errorf("error getting GPU Instance profile info: %v", ret) return fmt.Errorf("error getting GPU Instance profile info: %v", ret)
} }
@ -177,6 +197,20 @@ func (d *device) GetMigProfiles() ([]MigProfile, error) {
return profiles, nil return profiles, nil
} }
// isSkipped checks whether the device should be skipped.
func (d *device) isSkipped() (bool, error) {
name, ret := d.GetName()
if ret != nvml.SUCCESS {
return false, fmt.Errorf("error getting device name: %v", ret)
}
if _, exists := d.lib.skippedDevices[name]; exists {
return true, 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()
@ -189,10 +223,19 @@ func (d *devicelib) VisitDevices(visit func(int, Device) error) error {
if ret != nvml.SUCCESS { if ret != nvml.SUCCESS {
return fmt.Errorf("error getting device handle for index '%v': %v", i, ret) return fmt.Errorf("error getting device handle for index '%v': %v", i, ret)
} }
dev, err := d.NewDevice(device) dev, err := d.newDevice(device)
if err != nil { if err != nil {
return fmt.Errorf("error creating new device wrapper: %v", err) return fmt.Errorf("error creating new device wrapper: %v", err)
} }
isSkipped, err := dev.isSkipped()
if err != nil {
return fmt.Errorf("error checking whether device is skipped: %v", err)
}
if isSkipped {
continue
}
err = visit(i, dev) err = visit(i, dev)
if err != nil { if err != nil {
return fmt.Errorf("error visiting device: %v", err) return fmt.Errorf("error visiting device: %v", err)

View File

@ -48,6 +48,15 @@ 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
func (d *devicelib) NewMigDeviceByUUID(uuid string) (MigDevice, error) {
dev, ret := d.nvml.DeviceGetHandleByUUID(uuid)
if ret != nvml.SUCCESS {
return nil, fmt.Errorf("error getting device handle for uuid '%v': %v", uuid, ret)
}
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 {
@ -101,6 +110,12 @@ func (m *migdevice) GetProfile() (MigProfile, error) {
for i := 0; i < nvml.GPU_INSTANCE_PROFILE_COUNT; i++ { for i := 0; i < nvml.GPU_INSTANCE_PROFILE_COUNT; i++ {
giProfileInfo, ret := parent.GetGpuInstanceProfileInfo(i) giProfileInfo, ret := parent.GetGpuInstanceProfileInfo(i)
if ret == nvml.ERROR_NOT_SUPPORTED {
continue
}
if ret == nvml.ERROR_INVALID_ARGUMENT {
continue
}
if ret != nvml.SUCCESS { if ret != nvml.SUCCESS {
return nil, fmt.Errorf("error getting GPU Instance profile info: %v", ret) return nil, fmt.Errorf("error getting GPU Instance profile info: %v", ret)
} }
@ -112,6 +127,12 @@ func (m *migdevice) GetProfile() (MigProfile, error) {
for j := 0; j < nvml.COMPUTE_INSTANCE_PROFILE_COUNT; j++ { for j := 0; j < nvml.COMPUTE_INSTANCE_PROFILE_COUNT; j++ {
for k := 0; k < nvml.COMPUTE_INSTANCE_ENGINE_PROFILE_COUNT; k++ { for k := 0; k < nvml.COMPUTE_INSTANCE_ENGINE_PROFILE_COUNT; k++ {
ciProfileInfo, ret := gi.GetComputeInstanceProfileInfo(j, k) ciProfileInfo, ret := gi.GetComputeInstanceProfileInfo(j, k)
if ret == nvml.ERROR_NOT_SUPPORTED {
continue
}
if ret == nvml.ERROR_INVALID_ARGUMENT {
continue
}
if ret != nvml.SUCCESS { if ret != nvml.SUCCESS {
return nil, fmt.Errorf("error getting Compute Instance profile info: %v", ret) return nil, fmt.Errorf("error getting Compute Instance profile info: %v", ret)

View File

@ -13,22 +13,22 @@ var _ ComputeInstance = &ComputeInstanceMock{}
// ComputeInstanceMock is a mock implementation of ComputeInstance. // ComputeInstanceMock is a mock implementation of ComputeInstance.
// //
// func TestSomethingThatUsesComputeInstance(t *testing.T) { // func TestSomethingThatUsesComputeInstance(t *testing.T) {
// //
// // make and configure a mocked ComputeInstance // // make and configure a mocked ComputeInstance
// mockedComputeInstance := &ComputeInstanceMock{ // mockedComputeInstance := &ComputeInstanceMock{
// DestroyFunc: func() Return { // DestroyFunc: func() Return {
// panic("mock out the Destroy method") // panic("mock out the Destroy method")
// }, // },
// GetInfoFunc: func() (ComputeInstanceInfo, Return) { // GetInfoFunc: func() (ComputeInstanceInfo, Return) {
// panic("mock out the GetInfo method") // panic("mock out the GetInfo method")
// }, // },
// } // }
// //
// // use mockedComputeInstance in code that requires ComputeInstance // // use mockedComputeInstance in code that requires ComputeInstance
// // and then make assertions. // // and then make assertions.
// //
// } // }
type ComputeInstanceMock struct { type ComputeInstanceMock struct {
// DestroyFunc mocks the Destroy method. // DestroyFunc mocks the Destroy method.
DestroyFunc func() Return DestroyFunc func() Return
@ -64,7 +64,8 @@ func (mock *ComputeInstanceMock) Destroy() Return {
// DestroyCalls gets all the calls that were made to Destroy. // DestroyCalls gets all the calls that were made to Destroy.
// Check the length with: // Check the length with:
// len(mockedComputeInstance.DestroyCalls()) //
// len(mockedComputeInstance.DestroyCalls())
func (mock *ComputeInstanceMock) DestroyCalls() []struct { func (mock *ComputeInstanceMock) DestroyCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -90,7 +91,8 @@ func (mock *ComputeInstanceMock) GetInfo() (ComputeInstanceInfo, Return) {
// GetInfoCalls gets all the calls that were made to GetInfo. // GetInfoCalls gets all the calls that were made to GetInfo.
// Check the length with: // Check the length with:
// len(mockedComputeInstance.GetInfoCalls()) //
// len(mockedComputeInstance.GetInfoCalls())
func (mock *ComputeInstanceMock) GetInfoCalls() []struct { func (mock *ComputeInstanceMock) GetInfoCalls() []struct {
} { } {
var calls []struct { var calls []struct {

View File

@ -88,6 +88,16 @@ func (d nvmlDevice) GetGpuInstanceProfileInfo(profile int) (GpuInstanceProfileIn
return GpuInstanceProfileInfo(p), Return(r) return GpuInstanceProfileInfo(p), Return(r)
} }
// GetGpuInstancePossiblePlacements returns the possible placements of a GPU Instance
func (d nvmlDevice) GetGpuInstancePossiblePlacements(info *GpuInstanceProfileInfo) ([]GpuInstancePlacement, Return) {
nvmlPlacements, r := nvml.Device(d).GetGpuInstancePossiblePlacements((*nvml.GpuInstanceProfileInfo)(info))
var placements []GpuInstancePlacement
for _, p := range nvmlPlacements {
placements = append(placements, GpuInstancePlacement(p))
}
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))
@ -98,6 +108,12 @@ func (d nvmlDevice) GetGpuInstances(info *GpuInstanceProfileInfo) ([]GpuInstance
return gis, Return(r) return gis, Return(r)
} }
// CreateGpuInstanceWithPlacement creates a GPU Instance with a specific placement
func (d nvmlDevice) CreateGpuInstanceWithPlacement(info *GpuInstanceProfileInfo, placement *GpuInstancePlacement) (GpuInstance, Return) {
gi, r := nvml.Device(d).CreateGpuInstanceWithPlacement((*nvml.GpuInstanceProfileInfo)(info), (*nvml.GpuInstancePlacement)(placement))
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()

View File

@ -13,80 +13,89 @@ var _ Device = &DeviceMock{}
// DeviceMock is a mock implementation of Device. // DeviceMock is a mock implementation of Device.
// //
// func TestSomethingThatUsesDevice(t *testing.T) { // func TestSomethingThatUsesDevice(t *testing.T) {
// //
// // make and configure a mocked Device // // make and configure a mocked Device
// mockedDevice := &DeviceMock{ // mockedDevice := &DeviceMock{
// GetAttributesFunc: func() (DeviceAttributes, Return) { // CreateGpuInstanceWithPlacementFunc: func(gpuInstanceProfileInfo *GpuInstanceProfileInfo, gpuInstancePlacement *GpuInstancePlacement) (GpuInstance, Return) {
// panic("mock out the GetAttributes method") // panic("mock out the CreateGpuInstanceWithPlacement method")
// }, // },
// GetComputeInstanceIdFunc: func() (int, Return) { // GetAttributesFunc: func() (DeviceAttributes, Return) {
// panic("mock out the GetComputeInstanceId method") // panic("mock out the GetAttributes method")
// }, // },
// GetCudaComputeCapabilityFunc: func() (int, int, Return) { // GetComputeInstanceIdFunc: func() (int, Return) {
// panic("mock out the GetCudaComputeCapability method") // panic("mock out the GetComputeInstanceId method")
// }, // },
// GetDeviceHandleFromMigDeviceHandleFunc: func() (Device, Return) { // GetCudaComputeCapabilityFunc: func() (int, int, Return) {
// panic("mock out the GetDeviceHandleFromMigDeviceHandle method") // panic("mock out the GetCudaComputeCapability method")
// }, // },
// GetGpuInstanceByIdFunc: func(ID int) (GpuInstance, Return) { // GetDeviceHandleFromMigDeviceHandleFunc: func() (Device, Return) {
// panic("mock out the GetGpuInstanceById method") // panic("mock out the GetDeviceHandleFromMigDeviceHandle method")
// }, // },
// GetGpuInstanceIdFunc: func() (int, Return) { // GetGpuInstanceByIdFunc: func(ID int) (GpuInstance, Return) {
// panic("mock out the GetGpuInstanceId method") // panic("mock out the GetGpuInstanceById method")
// }, // },
// GetGpuInstanceProfileInfoFunc: func(Profile int) (GpuInstanceProfileInfo, Return) { // GetGpuInstanceIdFunc: func() (int, Return) {
// panic("mock out the GetGpuInstanceProfileInfo method") // panic("mock out the GetGpuInstanceId method")
// }, // },
// GetGpuInstancesFunc: func(Info *GpuInstanceProfileInfo) ([]GpuInstance, Return) { // GetGpuInstancePossiblePlacementsFunc: func(gpuInstanceProfileInfo *GpuInstanceProfileInfo) ([]GpuInstancePlacement, Return) {
// panic("mock out the GetGpuInstances method") // panic("mock out the GetGpuInstancePossiblePlacements method")
// }, // },
// GetIndexFunc: func() (int, Return) { // GetGpuInstanceProfileInfoFunc: func(Profile int) (GpuInstanceProfileInfo, Return) {
// panic("mock out the GetIndex method") // panic("mock out the GetGpuInstanceProfileInfo method")
// }, // },
// GetMaxMigDeviceCountFunc: func() (int, Return) { // GetGpuInstancesFunc: func(Info *GpuInstanceProfileInfo) ([]GpuInstance, Return) {
// panic("mock out the GetMaxMigDeviceCount method") // panic("mock out the GetGpuInstances method")
// }, // },
// GetMemoryInfoFunc: func() (Memory, Return) { // GetIndexFunc: func() (int, Return) {
// panic("mock out the GetMemoryInfo method") // panic("mock out the GetIndex method")
// }, // },
// GetMigDeviceHandleByIndexFunc: func(Index int) (Device, Return) { // GetMaxMigDeviceCountFunc: func() (int, Return) {
// panic("mock out the GetMigDeviceHandleByIndex method") // panic("mock out the GetMaxMigDeviceCount method")
// }, // },
// GetMigModeFunc: func() (int, int, Return) { // GetMemoryInfoFunc: func() (Memory, Return) {
// panic("mock out the GetMigMode method") // panic("mock out the GetMemoryInfo method")
// }, // },
// GetMinorNumberFunc: func() (int, Return) { // GetMigDeviceHandleByIndexFunc: func(Index int) (Device, Return) {
// panic("mock out the GetMinorNumber method") // panic("mock out the GetMigDeviceHandleByIndex method")
// }, // },
// GetNameFunc: func() (string, Return) { // GetMigModeFunc: func() (int, int, Return) {
// panic("mock out the GetName method") // panic("mock out the GetMigMode method")
// }, // },
// GetPciInfoFunc: func() (PciInfo, Return) { // GetMinorNumberFunc: func() (int, Return) {
// panic("mock out the GetPciInfo method") // panic("mock out the GetMinorNumber method")
// }, // },
// GetSupportedEventTypesFunc: func() (uint64, Return) { // GetNameFunc: func() (string, Return) {
// panic("mock out the GetSupportedEventTypes method") // panic("mock out the GetName method")
// }, // },
// GetUUIDFunc: func() (string, Return) { // GetPciInfoFunc: func() (PciInfo, Return) {
// panic("mock out the GetUUID method") // panic("mock out the GetPciInfo method")
// }, // },
// IsMigDeviceHandleFunc: func() (bool, Return) { // GetSupportedEventTypesFunc: func() (uint64, Return) {
// panic("mock out the IsMigDeviceHandle method") // panic("mock out the GetSupportedEventTypes method")
// }, // },
// RegisterEventsFunc: func(v uint64, eventSet EventSet) Return { // GetUUIDFunc: func() (string, Return) {
// panic("mock out the RegisterEvents method") // panic("mock out the GetUUID method")
// }, // },
// SetMigModeFunc: func(Mode int) (Return, Return) { // IsMigDeviceHandleFunc: func() (bool, Return) {
// panic("mock out the SetMigMode method") // panic("mock out the IsMigDeviceHandle method")
// }, // },
// } // RegisterEventsFunc: func(v uint64, eventSet EventSet) Return {
// panic("mock out the RegisterEvents method")
// },
// SetMigModeFunc: func(Mode int) (Return, Return) {
// panic("mock out the SetMigMode method")
// },
// }
// //
// // use mockedDevice in code that requires Device // // use mockedDevice in code that requires Device
// // and then make assertions. // // and then make assertions.
// //
// } // }
type DeviceMock struct { type DeviceMock struct {
// CreateGpuInstanceWithPlacementFunc mocks the CreateGpuInstanceWithPlacement method.
CreateGpuInstanceWithPlacementFunc func(gpuInstanceProfileInfo *GpuInstanceProfileInfo, gpuInstancePlacement *GpuInstancePlacement) (GpuInstance, Return)
// GetAttributesFunc mocks the GetAttributes method. // GetAttributesFunc mocks the GetAttributes method.
GetAttributesFunc func() (DeviceAttributes, Return) GetAttributesFunc func() (DeviceAttributes, Return)
@ -105,6 +114,9 @@ type DeviceMock struct {
// GetGpuInstanceIdFunc mocks the GetGpuInstanceId method. // GetGpuInstanceIdFunc mocks the GetGpuInstanceId method.
GetGpuInstanceIdFunc func() (int, Return) GetGpuInstanceIdFunc func() (int, Return)
// GetGpuInstancePossiblePlacementsFunc mocks the GetGpuInstancePossiblePlacements method.
GetGpuInstancePossiblePlacementsFunc func(gpuInstanceProfileInfo *GpuInstanceProfileInfo) ([]GpuInstancePlacement, Return)
// GetGpuInstanceProfileInfoFunc mocks the GetGpuInstanceProfileInfo method. // GetGpuInstanceProfileInfoFunc mocks the GetGpuInstanceProfileInfo method.
GetGpuInstanceProfileInfoFunc func(Profile int) (GpuInstanceProfileInfo, Return) GetGpuInstanceProfileInfoFunc func(Profile int) (GpuInstanceProfileInfo, Return)
@ -152,6 +164,13 @@ type DeviceMock struct {
// calls tracks calls to the methods. // calls tracks calls to the methods.
calls struct { calls struct {
// CreateGpuInstanceWithPlacement holds details about calls to the CreateGpuInstanceWithPlacement method.
CreateGpuInstanceWithPlacement []struct {
// GpuInstanceProfileInfo is the gpuInstanceProfileInfo argument value.
GpuInstanceProfileInfo *GpuInstanceProfileInfo
// GpuInstancePlacement is the gpuInstancePlacement argument value.
GpuInstancePlacement *GpuInstancePlacement
}
// GetAttributes holds details about calls to the GetAttributes method. // GetAttributes holds details about calls to the GetAttributes method.
GetAttributes []struct { GetAttributes []struct {
} }
@ -172,6 +191,11 @@ type DeviceMock struct {
// GetGpuInstanceId holds details about calls to the GetGpuInstanceId method. // GetGpuInstanceId holds details about calls to the GetGpuInstanceId method.
GetGpuInstanceId []struct { GetGpuInstanceId []struct {
} }
// GetGpuInstancePossiblePlacements holds details about calls to the GetGpuInstancePossiblePlacements method.
GetGpuInstancePossiblePlacements []struct {
// GpuInstanceProfileInfo is the gpuInstanceProfileInfo argument value.
GpuInstanceProfileInfo *GpuInstanceProfileInfo
}
// GetGpuInstanceProfileInfo holds details about calls to the GetGpuInstanceProfileInfo method. // GetGpuInstanceProfileInfo holds details about calls to the GetGpuInstanceProfileInfo method.
GetGpuInstanceProfileInfo []struct { GetGpuInstanceProfileInfo []struct {
// Profile is the Profile argument value. // Profile is the Profile argument value.
@ -230,12 +254,14 @@ type DeviceMock struct {
Mode int Mode int
} }
} }
lockCreateGpuInstanceWithPlacement sync.RWMutex
lockGetAttributes sync.RWMutex lockGetAttributes sync.RWMutex
lockGetComputeInstanceId sync.RWMutex lockGetComputeInstanceId sync.RWMutex
lockGetCudaComputeCapability sync.RWMutex lockGetCudaComputeCapability sync.RWMutex
lockGetDeviceHandleFromMigDeviceHandle sync.RWMutex lockGetDeviceHandleFromMigDeviceHandle sync.RWMutex
lockGetGpuInstanceById sync.RWMutex lockGetGpuInstanceById sync.RWMutex
lockGetGpuInstanceId sync.RWMutex lockGetGpuInstanceId sync.RWMutex
lockGetGpuInstancePossiblePlacements sync.RWMutex
lockGetGpuInstanceProfileInfo sync.RWMutex lockGetGpuInstanceProfileInfo sync.RWMutex
lockGetGpuInstances sync.RWMutex lockGetGpuInstances sync.RWMutex
lockGetIndex sync.RWMutex lockGetIndex sync.RWMutex
@ -253,6 +279,42 @@ type DeviceMock struct {
lockSetMigMode sync.RWMutex lockSetMigMode sync.RWMutex
} }
// CreateGpuInstanceWithPlacement calls CreateGpuInstanceWithPlacementFunc.
func (mock *DeviceMock) CreateGpuInstanceWithPlacement(gpuInstanceProfileInfo *GpuInstanceProfileInfo, gpuInstancePlacement *GpuInstancePlacement) (GpuInstance, Return) {
if mock.CreateGpuInstanceWithPlacementFunc == nil {
panic("DeviceMock.CreateGpuInstanceWithPlacementFunc: method is nil but Device.CreateGpuInstanceWithPlacement was just called")
}
callInfo := struct {
GpuInstanceProfileInfo *GpuInstanceProfileInfo
GpuInstancePlacement *GpuInstancePlacement
}{
GpuInstanceProfileInfo: gpuInstanceProfileInfo,
GpuInstancePlacement: gpuInstancePlacement,
}
mock.lockCreateGpuInstanceWithPlacement.Lock()
mock.calls.CreateGpuInstanceWithPlacement = append(mock.calls.CreateGpuInstanceWithPlacement, callInfo)
mock.lockCreateGpuInstanceWithPlacement.Unlock()
return mock.CreateGpuInstanceWithPlacementFunc(gpuInstanceProfileInfo, gpuInstancePlacement)
}
// CreateGpuInstanceWithPlacementCalls gets all the calls that were made to CreateGpuInstanceWithPlacement.
// Check the length with:
//
// len(mockedDevice.CreateGpuInstanceWithPlacementCalls())
func (mock *DeviceMock) CreateGpuInstanceWithPlacementCalls() []struct {
GpuInstanceProfileInfo *GpuInstanceProfileInfo
GpuInstancePlacement *GpuInstancePlacement
} {
var calls []struct {
GpuInstanceProfileInfo *GpuInstanceProfileInfo
GpuInstancePlacement *GpuInstancePlacement
}
mock.lockCreateGpuInstanceWithPlacement.RLock()
calls = mock.calls.CreateGpuInstanceWithPlacement
mock.lockCreateGpuInstanceWithPlacement.RUnlock()
return calls
}
// GetAttributes calls GetAttributesFunc. // GetAttributes calls GetAttributesFunc.
func (mock *DeviceMock) GetAttributes() (DeviceAttributes, Return) { func (mock *DeviceMock) GetAttributes() (DeviceAttributes, Return) {
if mock.GetAttributesFunc == nil { if mock.GetAttributesFunc == nil {
@ -268,7 +330,8 @@ func (mock *DeviceMock) GetAttributes() (DeviceAttributes, Return) {
// GetAttributesCalls gets all the calls that were made to GetAttributes. // GetAttributesCalls gets all the calls that were made to GetAttributes.
// Check the length with: // Check the length with:
// len(mockedDevice.GetAttributesCalls()) //
// len(mockedDevice.GetAttributesCalls())
func (mock *DeviceMock) GetAttributesCalls() []struct { func (mock *DeviceMock) GetAttributesCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -294,7 +357,8 @@ func (mock *DeviceMock) GetComputeInstanceId() (int, Return) {
// GetComputeInstanceIdCalls gets all the calls that were made to GetComputeInstanceId. // GetComputeInstanceIdCalls gets all the calls that were made to GetComputeInstanceId.
// Check the length with: // Check the length with:
// len(mockedDevice.GetComputeInstanceIdCalls()) //
// len(mockedDevice.GetComputeInstanceIdCalls())
func (mock *DeviceMock) GetComputeInstanceIdCalls() []struct { func (mock *DeviceMock) GetComputeInstanceIdCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -320,7 +384,8 @@ func (mock *DeviceMock) GetCudaComputeCapability() (int, int, Return) {
// GetCudaComputeCapabilityCalls gets all the calls that were made to GetCudaComputeCapability. // GetCudaComputeCapabilityCalls gets all the calls that were made to GetCudaComputeCapability.
// Check the length with: // Check the length with:
// len(mockedDevice.GetCudaComputeCapabilityCalls()) //
// len(mockedDevice.GetCudaComputeCapabilityCalls())
func (mock *DeviceMock) GetCudaComputeCapabilityCalls() []struct { func (mock *DeviceMock) GetCudaComputeCapabilityCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -346,7 +411,8 @@ func (mock *DeviceMock) GetDeviceHandleFromMigDeviceHandle() (Device, Return) {
// GetDeviceHandleFromMigDeviceHandleCalls gets all the calls that were made to GetDeviceHandleFromMigDeviceHandle. // GetDeviceHandleFromMigDeviceHandleCalls gets all the calls that were made to GetDeviceHandleFromMigDeviceHandle.
// Check the length with: // Check the length with:
// len(mockedDevice.GetDeviceHandleFromMigDeviceHandleCalls()) //
// len(mockedDevice.GetDeviceHandleFromMigDeviceHandleCalls())
func (mock *DeviceMock) GetDeviceHandleFromMigDeviceHandleCalls() []struct { func (mock *DeviceMock) GetDeviceHandleFromMigDeviceHandleCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -375,7 +441,8 @@ func (mock *DeviceMock) GetGpuInstanceById(ID int) (GpuInstance, Return) {
// GetGpuInstanceByIdCalls gets all the calls that were made to GetGpuInstanceById. // GetGpuInstanceByIdCalls gets all the calls that were made to GetGpuInstanceById.
// Check the length with: // Check the length with:
// len(mockedDevice.GetGpuInstanceByIdCalls()) //
// len(mockedDevice.GetGpuInstanceByIdCalls())
func (mock *DeviceMock) GetGpuInstanceByIdCalls() []struct { func (mock *DeviceMock) GetGpuInstanceByIdCalls() []struct {
ID int ID int
} { } {
@ -403,7 +470,8 @@ func (mock *DeviceMock) GetGpuInstanceId() (int, Return) {
// GetGpuInstanceIdCalls gets all the calls that were made to GetGpuInstanceId. // GetGpuInstanceIdCalls gets all the calls that were made to GetGpuInstanceId.
// Check the length with: // Check the length with:
// len(mockedDevice.GetGpuInstanceIdCalls()) //
// len(mockedDevice.GetGpuInstanceIdCalls())
func (mock *DeviceMock) GetGpuInstanceIdCalls() []struct { func (mock *DeviceMock) GetGpuInstanceIdCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -414,6 +482,38 @@ func (mock *DeviceMock) GetGpuInstanceIdCalls() []struct {
return calls return calls
} }
// GetGpuInstancePossiblePlacements calls GetGpuInstancePossiblePlacementsFunc.
func (mock *DeviceMock) GetGpuInstancePossiblePlacements(gpuInstanceProfileInfo *GpuInstanceProfileInfo) ([]GpuInstancePlacement, Return) {
if mock.GetGpuInstancePossiblePlacementsFunc == nil {
panic("DeviceMock.GetGpuInstancePossiblePlacementsFunc: method is nil but Device.GetGpuInstancePossiblePlacements was just called")
}
callInfo := struct {
GpuInstanceProfileInfo *GpuInstanceProfileInfo
}{
GpuInstanceProfileInfo: gpuInstanceProfileInfo,
}
mock.lockGetGpuInstancePossiblePlacements.Lock()
mock.calls.GetGpuInstancePossiblePlacements = append(mock.calls.GetGpuInstancePossiblePlacements, callInfo)
mock.lockGetGpuInstancePossiblePlacements.Unlock()
return mock.GetGpuInstancePossiblePlacementsFunc(gpuInstanceProfileInfo)
}
// GetGpuInstancePossiblePlacementsCalls gets all the calls that were made to GetGpuInstancePossiblePlacements.
// Check the length with:
//
// len(mockedDevice.GetGpuInstancePossiblePlacementsCalls())
func (mock *DeviceMock) GetGpuInstancePossiblePlacementsCalls() []struct {
GpuInstanceProfileInfo *GpuInstanceProfileInfo
} {
var calls []struct {
GpuInstanceProfileInfo *GpuInstanceProfileInfo
}
mock.lockGetGpuInstancePossiblePlacements.RLock()
calls = mock.calls.GetGpuInstancePossiblePlacements
mock.lockGetGpuInstancePossiblePlacements.RUnlock()
return calls
}
// GetGpuInstanceProfileInfo calls GetGpuInstanceProfileInfoFunc. // GetGpuInstanceProfileInfo calls GetGpuInstanceProfileInfoFunc.
func (mock *DeviceMock) GetGpuInstanceProfileInfo(Profile int) (GpuInstanceProfileInfo, Return) { func (mock *DeviceMock) GetGpuInstanceProfileInfo(Profile int) (GpuInstanceProfileInfo, Return) {
if mock.GetGpuInstanceProfileInfoFunc == nil { if mock.GetGpuInstanceProfileInfoFunc == nil {
@ -432,7 +532,8 @@ func (mock *DeviceMock) GetGpuInstanceProfileInfo(Profile int) (GpuInstanceProfi
// GetGpuInstanceProfileInfoCalls gets all the calls that were made to GetGpuInstanceProfileInfo. // GetGpuInstanceProfileInfoCalls gets all the calls that were made to GetGpuInstanceProfileInfo.
// Check the length with: // Check the length with:
// len(mockedDevice.GetGpuInstanceProfileInfoCalls()) //
// len(mockedDevice.GetGpuInstanceProfileInfoCalls())
func (mock *DeviceMock) GetGpuInstanceProfileInfoCalls() []struct { func (mock *DeviceMock) GetGpuInstanceProfileInfoCalls() []struct {
Profile int Profile int
} { } {
@ -463,7 +564,8 @@ func (mock *DeviceMock) GetGpuInstances(Info *GpuInstanceProfileInfo) ([]GpuInst
// GetGpuInstancesCalls gets all the calls that were made to GetGpuInstances. // GetGpuInstancesCalls gets all the calls that were made to GetGpuInstances.
// Check the length with: // Check the length with:
// len(mockedDevice.GetGpuInstancesCalls()) //
// len(mockedDevice.GetGpuInstancesCalls())
func (mock *DeviceMock) GetGpuInstancesCalls() []struct { func (mock *DeviceMock) GetGpuInstancesCalls() []struct {
Info *GpuInstanceProfileInfo Info *GpuInstanceProfileInfo
} { } {
@ -491,7 +593,8 @@ func (mock *DeviceMock) GetIndex() (int, Return) {
// GetIndexCalls gets all the calls that were made to GetIndex. // GetIndexCalls gets all the calls that were made to GetIndex.
// Check the length with: // Check the length with:
// len(mockedDevice.GetIndexCalls()) //
// len(mockedDevice.GetIndexCalls())
func (mock *DeviceMock) GetIndexCalls() []struct { func (mock *DeviceMock) GetIndexCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -517,7 +620,8 @@ func (mock *DeviceMock) GetMaxMigDeviceCount() (int, Return) {
// GetMaxMigDeviceCountCalls gets all the calls that were made to GetMaxMigDeviceCount. // GetMaxMigDeviceCountCalls gets all the calls that were made to GetMaxMigDeviceCount.
// Check the length with: // Check the length with:
// len(mockedDevice.GetMaxMigDeviceCountCalls()) //
// len(mockedDevice.GetMaxMigDeviceCountCalls())
func (mock *DeviceMock) GetMaxMigDeviceCountCalls() []struct { func (mock *DeviceMock) GetMaxMigDeviceCountCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -543,7 +647,8 @@ func (mock *DeviceMock) GetMemoryInfo() (Memory, Return) {
// GetMemoryInfoCalls gets all the calls that were made to GetMemoryInfo. // GetMemoryInfoCalls gets all the calls that were made to GetMemoryInfo.
// Check the length with: // Check the length with:
// len(mockedDevice.GetMemoryInfoCalls()) //
// len(mockedDevice.GetMemoryInfoCalls())
func (mock *DeviceMock) GetMemoryInfoCalls() []struct { func (mock *DeviceMock) GetMemoryInfoCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -572,7 +677,8 @@ func (mock *DeviceMock) GetMigDeviceHandleByIndex(Index int) (Device, Return) {
// GetMigDeviceHandleByIndexCalls gets all the calls that were made to GetMigDeviceHandleByIndex. // GetMigDeviceHandleByIndexCalls gets all the calls that were made to GetMigDeviceHandleByIndex.
// Check the length with: // Check the length with:
// len(mockedDevice.GetMigDeviceHandleByIndexCalls()) //
// len(mockedDevice.GetMigDeviceHandleByIndexCalls())
func (mock *DeviceMock) GetMigDeviceHandleByIndexCalls() []struct { func (mock *DeviceMock) GetMigDeviceHandleByIndexCalls() []struct {
Index int Index int
} { } {
@ -600,7 +706,8 @@ func (mock *DeviceMock) GetMigMode() (int, int, Return) {
// GetMigModeCalls gets all the calls that were made to GetMigMode. // GetMigModeCalls gets all the calls that were made to GetMigMode.
// Check the length with: // Check the length with:
// len(mockedDevice.GetMigModeCalls()) //
// len(mockedDevice.GetMigModeCalls())
func (mock *DeviceMock) GetMigModeCalls() []struct { func (mock *DeviceMock) GetMigModeCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -626,7 +733,8 @@ func (mock *DeviceMock) GetMinorNumber() (int, Return) {
// GetMinorNumberCalls gets all the calls that were made to GetMinorNumber. // GetMinorNumberCalls gets all the calls that were made to GetMinorNumber.
// Check the length with: // Check the length with:
// len(mockedDevice.GetMinorNumberCalls()) //
// len(mockedDevice.GetMinorNumberCalls())
func (mock *DeviceMock) GetMinorNumberCalls() []struct { func (mock *DeviceMock) GetMinorNumberCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -652,7 +760,8 @@ func (mock *DeviceMock) GetName() (string, Return) {
// GetNameCalls gets all the calls that were made to GetName. // GetNameCalls gets all the calls that were made to GetName.
// Check the length with: // Check the length with:
// len(mockedDevice.GetNameCalls()) //
// len(mockedDevice.GetNameCalls())
func (mock *DeviceMock) GetNameCalls() []struct { func (mock *DeviceMock) GetNameCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -678,7 +787,8 @@ func (mock *DeviceMock) GetPciInfo() (PciInfo, Return) {
// GetPciInfoCalls gets all the calls that were made to GetPciInfo. // GetPciInfoCalls gets all the calls that were made to GetPciInfo.
// Check the length with: // Check the length with:
// len(mockedDevice.GetPciInfoCalls()) //
// len(mockedDevice.GetPciInfoCalls())
func (mock *DeviceMock) GetPciInfoCalls() []struct { func (mock *DeviceMock) GetPciInfoCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -704,7 +814,8 @@ func (mock *DeviceMock) GetSupportedEventTypes() (uint64, Return) {
// GetSupportedEventTypesCalls gets all the calls that were made to GetSupportedEventTypes. // GetSupportedEventTypesCalls gets all the calls that were made to GetSupportedEventTypes.
// Check the length with: // Check the length with:
// len(mockedDevice.GetSupportedEventTypesCalls()) //
// len(mockedDevice.GetSupportedEventTypesCalls())
func (mock *DeviceMock) GetSupportedEventTypesCalls() []struct { func (mock *DeviceMock) GetSupportedEventTypesCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -730,7 +841,8 @@ func (mock *DeviceMock) GetUUID() (string, Return) {
// GetUUIDCalls gets all the calls that were made to GetUUID. // GetUUIDCalls gets all the calls that were made to GetUUID.
// Check the length with: // Check the length with:
// len(mockedDevice.GetUUIDCalls()) //
// len(mockedDevice.GetUUIDCalls())
func (mock *DeviceMock) GetUUIDCalls() []struct { func (mock *DeviceMock) GetUUIDCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -756,7 +868,8 @@ func (mock *DeviceMock) IsMigDeviceHandle() (bool, Return) {
// IsMigDeviceHandleCalls gets all the calls that were made to IsMigDeviceHandle. // IsMigDeviceHandleCalls gets all the calls that were made to IsMigDeviceHandle.
// Check the length with: // Check the length with:
// len(mockedDevice.IsMigDeviceHandleCalls()) //
// len(mockedDevice.IsMigDeviceHandleCalls())
func (mock *DeviceMock) IsMigDeviceHandleCalls() []struct { func (mock *DeviceMock) IsMigDeviceHandleCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -787,7 +900,8 @@ func (mock *DeviceMock) RegisterEvents(v uint64, eventSet EventSet) Return {
// RegisterEventsCalls gets all the calls that were made to RegisterEvents. // RegisterEventsCalls gets all the calls that were made to RegisterEvents.
// Check the length with: // Check the length with:
// len(mockedDevice.RegisterEventsCalls()) //
// len(mockedDevice.RegisterEventsCalls())
func (mock *DeviceMock) RegisterEventsCalls() []struct { func (mock *DeviceMock) RegisterEventsCalls() []struct {
V uint64 V uint64
EventSet EventSet EventSet EventSet
@ -820,7 +934,8 @@ func (mock *DeviceMock) SetMigMode(Mode int) (Return, Return) {
// SetMigModeCalls gets all the calls that were made to SetMigMode. // SetMigModeCalls gets all the calls that were made to SetMigMode.
// Check the length with: // Check the length with:
// len(mockedDevice.SetMigModeCalls()) //
// len(mockedDevice.SetMigModeCalls())
func (mock *DeviceMock) SetMigModeCalls() []struct { func (mock *DeviceMock) SetMigModeCalls() []struct {
Mode int Mode int
} { } {

View File

@ -13,34 +13,34 @@ var _ GpuInstance = &GpuInstanceMock{}
// GpuInstanceMock is a mock implementation of GpuInstance. // GpuInstanceMock is a mock implementation of GpuInstance.
// //
// func TestSomethingThatUsesGpuInstance(t *testing.T) { // func TestSomethingThatUsesGpuInstance(t *testing.T) {
// //
// // make and configure a mocked GpuInstance // // make and configure a mocked GpuInstance
// mockedGpuInstance := &GpuInstanceMock{ // mockedGpuInstance := &GpuInstanceMock{
// CreateComputeInstanceFunc: func(Info *ComputeInstanceProfileInfo) (ComputeInstance, Return) { // CreateComputeInstanceFunc: func(Info *ComputeInstanceProfileInfo) (ComputeInstance, Return) {
// panic("mock out the CreateComputeInstance method") // panic("mock out the CreateComputeInstance method")
// }, // },
// DestroyFunc: func() Return { // DestroyFunc: func() Return {
// panic("mock out the Destroy method") // panic("mock out the Destroy method")
// }, // },
// GetComputeInstanceByIdFunc: func(ID int) (ComputeInstance, Return) { // GetComputeInstanceByIdFunc: func(ID int) (ComputeInstance, Return) {
// panic("mock out the GetComputeInstanceById method") // panic("mock out the GetComputeInstanceById method")
// }, // },
// GetComputeInstanceProfileInfoFunc: func(Profile int, EngProfile int) (ComputeInstanceProfileInfo, Return) { // GetComputeInstanceProfileInfoFunc: func(Profile int, EngProfile int) (ComputeInstanceProfileInfo, Return) {
// panic("mock out the GetComputeInstanceProfileInfo method") // panic("mock out the GetComputeInstanceProfileInfo method")
// }, // },
// GetComputeInstancesFunc: func(Info *ComputeInstanceProfileInfo) ([]ComputeInstance, Return) { // GetComputeInstancesFunc: func(Info *ComputeInstanceProfileInfo) ([]ComputeInstance, Return) {
// panic("mock out the GetComputeInstances method") // panic("mock out the GetComputeInstances method")
// }, // },
// GetInfoFunc: func() (GpuInstanceInfo, Return) { // GetInfoFunc: func() (GpuInstanceInfo, Return) {
// panic("mock out the GetInfo method") // panic("mock out the GetInfo method")
// }, // },
// } // }
// //
// // use mockedGpuInstance in code that requires GpuInstance // // use mockedGpuInstance in code that requires GpuInstance
// // and then make assertions. // // and then make assertions.
// //
// } // }
type GpuInstanceMock struct { type GpuInstanceMock struct {
// CreateComputeInstanceFunc mocks the CreateComputeInstance method. // CreateComputeInstanceFunc mocks the CreateComputeInstance method.
CreateComputeInstanceFunc func(Info *ComputeInstanceProfileInfo) (ComputeInstance, Return) CreateComputeInstanceFunc func(Info *ComputeInstanceProfileInfo) (ComputeInstance, Return)
@ -117,7 +117,8 @@ func (mock *GpuInstanceMock) CreateComputeInstance(Info *ComputeInstanceProfileI
// CreateComputeInstanceCalls gets all the calls that were made to CreateComputeInstance. // CreateComputeInstanceCalls gets all the calls that were made to CreateComputeInstance.
// Check the length with: // Check the length with:
// len(mockedGpuInstance.CreateComputeInstanceCalls()) //
// len(mockedGpuInstance.CreateComputeInstanceCalls())
func (mock *GpuInstanceMock) CreateComputeInstanceCalls() []struct { func (mock *GpuInstanceMock) CreateComputeInstanceCalls() []struct {
Info *ComputeInstanceProfileInfo Info *ComputeInstanceProfileInfo
} { } {
@ -145,7 +146,8 @@ func (mock *GpuInstanceMock) Destroy() Return {
// DestroyCalls gets all the calls that were made to Destroy. // DestroyCalls gets all the calls that were made to Destroy.
// Check the length with: // Check the length with:
// len(mockedGpuInstance.DestroyCalls()) //
// len(mockedGpuInstance.DestroyCalls())
func (mock *GpuInstanceMock) DestroyCalls() []struct { func (mock *GpuInstanceMock) DestroyCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -174,7 +176,8 @@ func (mock *GpuInstanceMock) GetComputeInstanceById(ID int) (ComputeInstance, Re
// GetComputeInstanceByIdCalls gets all the calls that were made to GetComputeInstanceById. // GetComputeInstanceByIdCalls gets all the calls that were made to GetComputeInstanceById.
// Check the length with: // Check the length with:
// len(mockedGpuInstance.GetComputeInstanceByIdCalls()) //
// len(mockedGpuInstance.GetComputeInstanceByIdCalls())
func (mock *GpuInstanceMock) GetComputeInstanceByIdCalls() []struct { func (mock *GpuInstanceMock) GetComputeInstanceByIdCalls() []struct {
ID int ID int
} { } {
@ -207,7 +210,8 @@ func (mock *GpuInstanceMock) GetComputeInstanceProfileInfo(Profile int, EngProfi
// GetComputeInstanceProfileInfoCalls gets all the calls that were made to GetComputeInstanceProfileInfo. // GetComputeInstanceProfileInfoCalls gets all the calls that were made to GetComputeInstanceProfileInfo.
// Check the length with: // Check the length with:
// len(mockedGpuInstance.GetComputeInstanceProfileInfoCalls()) //
// len(mockedGpuInstance.GetComputeInstanceProfileInfoCalls())
func (mock *GpuInstanceMock) GetComputeInstanceProfileInfoCalls() []struct { func (mock *GpuInstanceMock) GetComputeInstanceProfileInfoCalls() []struct {
Profile int Profile int
EngProfile int EngProfile int
@ -240,7 +244,8 @@ func (mock *GpuInstanceMock) GetComputeInstances(Info *ComputeInstanceProfileInf
// GetComputeInstancesCalls gets all the calls that were made to GetComputeInstances. // GetComputeInstancesCalls gets all the calls that were made to GetComputeInstances.
// Check the length with: // Check the length with:
// len(mockedGpuInstance.GetComputeInstancesCalls()) //
// len(mockedGpuInstance.GetComputeInstancesCalls())
func (mock *GpuInstanceMock) GetComputeInstancesCalls() []struct { func (mock *GpuInstanceMock) GetComputeInstancesCalls() []struct {
Info *ComputeInstanceProfileInfo Info *ComputeInstanceProfileInfo
} { } {
@ -268,7 +273,8 @@ func (mock *GpuInstanceMock) GetInfo() (GpuInstanceInfo, Return) {
// GetInfoCalls gets all the calls that were made to GetInfo. // GetInfoCalls gets all the calls that were made to GetInfo.
// Check the length with: // Check the length with:
// len(mockedGpuInstance.GetInfoCalls()) //
// len(mockedGpuInstance.GetInfoCalls())
func (mock *GpuInstanceMock) GetInfoCalls() []struct { func (mock *GpuInstanceMock) GetInfoCalls() []struct {
} { } {
var calls []struct { var calls []struct {

View File

@ -13,43 +13,43 @@ var _ Interface = &InterfaceMock{}
// InterfaceMock is a mock implementation of Interface. // InterfaceMock is a mock implementation of Interface.
// //
// func TestSomethingThatUsesInterface(t *testing.T) { // func TestSomethingThatUsesInterface(t *testing.T) {
// //
// // make and configure a mocked Interface // // make and configure a mocked Interface
// mockedInterface := &InterfaceMock{ // mockedInterface := &InterfaceMock{
// DeviceGetCountFunc: func() (int, Return) { // DeviceGetCountFunc: func() (int, Return) {
// panic("mock out the DeviceGetCount method") // panic("mock out the DeviceGetCount method")
// }, // },
// DeviceGetHandleByIndexFunc: func(Index int) (Device, Return) { // DeviceGetHandleByIndexFunc: func(Index int) (Device, Return) {
// panic("mock out the DeviceGetHandleByIndex method") // panic("mock out the DeviceGetHandleByIndex method")
// }, // },
// DeviceGetHandleByUUIDFunc: func(UUID string) (Device, Return) { // DeviceGetHandleByUUIDFunc: func(UUID string) (Device, Return) {
// panic("mock out the DeviceGetHandleByUUID method") // panic("mock out the DeviceGetHandleByUUID method")
// }, // },
// ErrorStringFunc: func(r Return) string { // ErrorStringFunc: func(r Return) string {
// panic("mock out the ErrorString method") // panic("mock out the ErrorString method")
// }, // },
// EventSetCreateFunc: func() (EventSet, Return) { // EventSetCreateFunc: func() (EventSet, Return) {
// panic("mock out the EventSetCreate method") // panic("mock out the EventSetCreate method")
// }, // },
// InitFunc: func() Return { // InitFunc: func() Return {
// panic("mock out the Init method") // panic("mock out the Init method")
// }, // },
// ShutdownFunc: func() Return { // ShutdownFunc: func() Return {
// panic("mock out the Shutdown method") // panic("mock out the Shutdown method")
// }, // },
// SystemGetCudaDriverVersionFunc: func() (int, Return) { // SystemGetCudaDriverVersionFunc: func() (int, Return) {
// panic("mock out the SystemGetCudaDriverVersion method") // panic("mock out the SystemGetCudaDriverVersion method")
// }, // },
// SystemGetDriverVersionFunc: func() (string, Return) { // SystemGetDriverVersionFunc: func() (string, Return) {
// panic("mock out the SystemGetDriverVersion method") // panic("mock out the SystemGetDriverVersion method")
// }, // },
// } // }
// //
// // use mockedInterface in code that requires Interface // // use mockedInterface in code that requires Interface
// // and then make assertions. // // and then make assertions.
// //
// } // }
type InterfaceMock struct { type InterfaceMock struct {
// DeviceGetCountFunc mocks the DeviceGetCount method. // DeviceGetCountFunc mocks the DeviceGetCount method.
DeviceGetCountFunc func() (int, Return) DeviceGetCountFunc func() (int, Return)
@ -140,7 +140,8 @@ func (mock *InterfaceMock) DeviceGetCount() (int, Return) {
// DeviceGetCountCalls gets all the calls that were made to DeviceGetCount. // DeviceGetCountCalls gets all the calls that were made to DeviceGetCount.
// Check the length with: // Check the length with:
// len(mockedInterface.DeviceGetCountCalls()) //
// len(mockedInterface.DeviceGetCountCalls())
func (mock *InterfaceMock) DeviceGetCountCalls() []struct { func (mock *InterfaceMock) DeviceGetCountCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -169,7 +170,8 @@ func (mock *InterfaceMock) DeviceGetHandleByIndex(Index int) (Device, Return) {
// DeviceGetHandleByIndexCalls gets all the calls that were made to DeviceGetHandleByIndex. // DeviceGetHandleByIndexCalls gets all the calls that were made to DeviceGetHandleByIndex.
// Check the length with: // Check the length with:
// len(mockedInterface.DeviceGetHandleByIndexCalls()) //
// len(mockedInterface.DeviceGetHandleByIndexCalls())
func (mock *InterfaceMock) DeviceGetHandleByIndexCalls() []struct { func (mock *InterfaceMock) DeviceGetHandleByIndexCalls() []struct {
Index int Index int
} { } {
@ -200,7 +202,8 @@ func (mock *InterfaceMock) DeviceGetHandleByUUID(UUID string) (Device, Return) {
// DeviceGetHandleByUUIDCalls gets all the calls that were made to DeviceGetHandleByUUID. // DeviceGetHandleByUUIDCalls gets all the calls that were made to DeviceGetHandleByUUID.
// Check the length with: // Check the length with:
// len(mockedInterface.DeviceGetHandleByUUIDCalls()) //
// len(mockedInterface.DeviceGetHandleByUUIDCalls())
func (mock *InterfaceMock) DeviceGetHandleByUUIDCalls() []struct { func (mock *InterfaceMock) DeviceGetHandleByUUIDCalls() []struct {
UUID string UUID string
} { } {
@ -231,7 +234,8 @@ func (mock *InterfaceMock) ErrorString(r Return) string {
// ErrorStringCalls gets all the calls that were made to ErrorString. // ErrorStringCalls gets all the calls that were made to ErrorString.
// Check the length with: // Check the length with:
// len(mockedInterface.ErrorStringCalls()) //
// len(mockedInterface.ErrorStringCalls())
func (mock *InterfaceMock) ErrorStringCalls() []struct { func (mock *InterfaceMock) ErrorStringCalls() []struct {
R Return R Return
} { } {
@ -259,7 +263,8 @@ func (mock *InterfaceMock) EventSetCreate() (EventSet, Return) {
// EventSetCreateCalls gets all the calls that were made to EventSetCreate. // EventSetCreateCalls gets all the calls that were made to EventSetCreate.
// Check the length with: // Check the length with:
// len(mockedInterface.EventSetCreateCalls()) //
// len(mockedInterface.EventSetCreateCalls())
func (mock *InterfaceMock) EventSetCreateCalls() []struct { func (mock *InterfaceMock) EventSetCreateCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -285,7 +290,8 @@ func (mock *InterfaceMock) Init() Return {
// InitCalls gets all the calls that were made to Init. // InitCalls gets all the calls that were made to Init.
// Check the length with: // Check the length with:
// len(mockedInterface.InitCalls()) //
// len(mockedInterface.InitCalls())
func (mock *InterfaceMock) InitCalls() []struct { func (mock *InterfaceMock) InitCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -311,7 +317,8 @@ func (mock *InterfaceMock) Shutdown() Return {
// ShutdownCalls gets all the calls that were made to Shutdown. // ShutdownCalls gets all the calls that were made to Shutdown.
// Check the length with: // Check the length with:
// len(mockedInterface.ShutdownCalls()) //
// len(mockedInterface.ShutdownCalls())
func (mock *InterfaceMock) ShutdownCalls() []struct { func (mock *InterfaceMock) ShutdownCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -337,7 +344,8 @@ func (mock *InterfaceMock) SystemGetCudaDriverVersion() (int, Return) {
// SystemGetCudaDriverVersionCalls gets all the calls that were made to SystemGetCudaDriverVersion. // SystemGetCudaDriverVersionCalls gets all the calls that were made to SystemGetCudaDriverVersion.
// Check the length with: // Check the length with:
// len(mockedInterface.SystemGetCudaDriverVersionCalls()) //
// len(mockedInterface.SystemGetCudaDriverVersionCalls())
func (mock *InterfaceMock) SystemGetCudaDriverVersionCalls() []struct { func (mock *InterfaceMock) SystemGetCudaDriverVersionCalls() []struct {
} { } {
var calls []struct { var calls []struct {
@ -363,7 +371,8 @@ func (mock *InterfaceMock) SystemGetDriverVersion() (string, Return) {
// SystemGetDriverVersionCalls gets all the calls that were made to SystemGetDriverVersion. // SystemGetDriverVersionCalls gets all the calls that were made to SystemGetDriverVersion.
// Check the length with: // Check the length with:
// len(mockedInterface.SystemGetDriverVersionCalls()) //
// len(mockedInterface.SystemGetDriverVersionCalls())
func (mock *InterfaceMock) SystemGetDriverVersionCalls() []struct { func (mock *InterfaceMock) SystemGetDriverVersionCalls() []struct {
} { } {
var calls []struct { var calls []struct {

View File

@ -39,12 +39,14 @@ type Interface interface {
// //
//go:generate moq -out device_mock.go . Device //go:generate moq -out device_mock.go . Device
type Device interface { type Device interface {
CreateGpuInstanceWithPlacement(*GpuInstanceProfileInfo, *GpuInstancePlacement) (GpuInstance, Return)
GetAttributes() (DeviceAttributes, Return) GetAttributes() (DeviceAttributes, Return)
GetComputeInstanceId() (int, Return) GetComputeInstanceId() (int, Return)
GetCudaComputeCapability() (int, int, Return) GetCudaComputeCapability() (int, int, Return)
GetDeviceHandleFromMigDeviceHandle() (Device, Return) GetDeviceHandleFromMigDeviceHandle() (Device, Return)
GetGpuInstanceById(ID int) (GpuInstance, Return) GetGpuInstanceById(ID int) (GpuInstance, Return)
GetGpuInstanceId() (int, Return) GetGpuInstanceId() (int, Return)
GetGpuInstancePossiblePlacements(*GpuInstanceProfileInfo) ([]GpuInstancePlacement, Return)
GetGpuInstanceProfileInfo(Profile int) (GpuInstanceProfileInfo, Return) GetGpuInstanceProfileInfo(Profile int) (GpuInstanceProfileInfo, Return)
GetGpuInstances(Info *GpuInstanceProfileInfo) ([]GpuInstance, Return) GetGpuInstances(Info *GpuInstanceProfileInfo) ([]GpuInstance, Return)
GetIndex() (int, Return) GetIndex() (int, Return)

View File

@ -0,0 +1,94 @@
/*
* 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.
*/
package bytes
import (
"encoding/binary"
"unsafe"
)
// Raw returns just the bytes without any assumptions about layout
type Raw interface {
Raw() *[]byte
}
// Reader used to read various data sizes in the byte array
type Reader interface {
Read8(pos int) uint8
Read16(pos int) uint16
Read32(pos int) uint32
Read64(pos int) uint64
Len() int
}
// Writer used to write various sizes of data in the byte array
type Writer interface {
Write8(pos int, value uint8)
Write16(pos int, value uint16)
Write32(pos int, value uint32)
Write64(pos int, value uint64)
Len() int
}
// Bytes object for manipulating arbitrary byte arrays
type Bytes interface {
Raw
Reader
Writer
Slice(offset int, size int) Bytes
LittleEndian() Bytes
BigEndian() Bytes
}
var nativeByteOrder binary.ByteOrder
func init() {
buf := [2]byte{}
*(*uint16)(unsafe.Pointer(&buf[0])) = uint16(0x00FF)
switch buf {
case [2]byte{0xFF, 0x00}:
nativeByteOrder = binary.LittleEndian
case [2]byte{0x00, 0xFF}:
nativeByteOrder = binary.BigEndian
default:
panic("Unable to infer byte order")
}
}
// New raw bytearray
func New(data *[]byte) Bytes {
return (*native)(data)
}
// NewLittleEndian little endian ordering of bytes
func NewLittleEndian(data *[]byte) Bytes {
if nativeByteOrder == binary.LittleEndian {
return (*native)(data)
}
return (*swapbo)(data)
}
// NewBigEndian big endian ordering of bytes
func NewBigEndian(data *[]byte) Bytes {
if nativeByteOrder == binary.BigEndian {
return (*native)(data)
}
return (*swapbo)(data)
}

View File

@ -0,0 +1,78 @@
/*
* 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.
*/
package bytes
import (
"unsafe"
)
type native []byte
var _ Bytes = (*native)(nil)
func (b *native) Read8(pos int) uint8 {
return (*b)[pos]
}
func (b *native) Read16(pos int) uint16 {
return *(*uint16)(unsafe.Pointer(&((*b)[pos])))
}
func (b *native) Read32(pos int) uint32 {
return *(*uint32)(unsafe.Pointer(&((*b)[pos])))
}
func (b *native) Read64(pos int) uint64 {
return *(*uint64)(unsafe.Pointer(&((*b)[pos])))
}
func (b *native) Write8(pos int, value uint8) {
(*b)[pos] = value
}
func (b *native) Write16(pos int, value uint16) {
*(*uint16)(unsafe.Pointer(&((*b)[pos]))) = value
}
func (b *native) Write32(pos int, value uint32) {
*(*uint32)(unsafe.Pointer(&((*b)[pos]))) = value
}
func (b *native) Write64(pos int, value uint64) {
*(*uint64)(unsafe.Pointer(&((*b)[pos]))) = value
}
func (b *native) Slice(offset int, size int) Bytes {
nb := (*b)[offset : offset+size]
return &nb
}
func (b *native) LittleEndian() Bytes {
return NewLittleEndian((*[]byte)(b))
}
func (b *native) BigEndian() Bytes {
return NewBigEndian((*[]byte)(b))
}
func (b *native) Raw() *[]byte {
return (*[]byte)(b)
}
func (b *native) Len() int {
return len(*b)
}

View File

@ -0,0 +1,112 @@
/*
* 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.
*/
package bytes
import (
"unsafe"
)
type swapbo []byte
var _ Bytes = (*swapbo)(nil)
func (b *swapbo) Read8(pos int) uint8 {
return (*b)[pos]
}
func (b *swapbo) Read16(pos int) uint16 {
buf := [2]byte{}
buf[0] = (*b)[pos+1]
buf[1] = (*b)[pos+0]
return *(*uint16)(unsafe.Pointer(&buf[0]))
}
func (b *swapbo) Read32(pos int) uint32 {
buf := [4]byte{}
buf[0] = (*b)[pos+3]
buf[1] = (*b)[pos+2]
buf[2] = (*b)[pos+1]
buf[3] = (*b)[pos+0]
return *(*uint32)(unsafe.Pointer(&buf[0]))
}
func (b *swapbo) Read64(pos int) uint64 {
buf := [8]byte{}
buf[0] = (*b)[pos+7]
buf[1] = (*b)[pos+6]
buf[2] = (*b)[pos+5]
buf[3] = (*b)[pos+4]
buf[4] = (*b)[pos+3]
buf[5] = (*b)[pos+2]
buf[6] = (*b)[pos+1]
buf[7] = (*b)[pos+0]
return *(*uint64)(unsafe.Pointer(&buf[0]))
}
func (b *swapbo) Write8(pos int, value uint8) {
(*b)[pos] = value
}
func (b *swapbo) Write16(pos int, value uint16) {
buf := [2]byte{}
*(*uint16)(unsafe.Pointer(&buf[0])) = value
(*b)[pos+0] = buf[1]
(*b)[pos+1] = buf[0]
}
func (b *swapbo) Write32(pos int, value uint32) {
buf := [4]byte{}
*(*uint32)(unsafe.Pointer(&buf[0])) = value
(*b)[pos+0] = buf[3]
(*b)[pos+1] = buf[2]
(*b)[pos+2] = buf[1]
(*b)[pos+3] = buf[0]
}
func (b *swapbo) Write64(pos int, value uint64) {
buf := [8]byte{}
*(*uint64)(unsafe.Pointer(&buf[0])) = value
(*b)[pos+0] = buf[7]
(*b)[pos+1] = buf[6]
(*b)[pos+2] = buf[5]
(*b)[pos+3] = buf[4]
(*b)[pos+4] = buf[3]
(*b)[pos+5] = buf[2]
(*b)[pos+6] = buf[1]
(*b)[pos+7] = buf[0]
}
func (b *swapbo) Slice(offset int, size int) Bytes {
nb := (*b)[offset : offset+size]
return &nb
}
func (b *swapbo) LittleEndian() Bytes {
return NewLittleEndian((*[]byte)(b))
}
func (b *swapbo) BigEndian() Bytes {
return NewBigEndian((*[]byte)(b))
}
func (b *swapbo) Raw() *[]byte {
return (*[]byte)(b)
}
func (b *swapbo) Len() int {
return len(*b)
}

View File

@ -0,0 +1,147 @@
/*
* 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.
*/
package nvpci
import (
"fmt"
"os"
"gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvpci/bytes"
)
const (
// PCICfgSpaceStandardSize represents the size in bytes of the standard config space
PCICfgSpaceStandardSize = 256
// PCICfgSpaceExtendedSize represents the size in bytes of the extended config space
PCICfgSpaceExtendedSize = 4096
// PCICapabilityListPointer represents offset for the capability list pointer
PCICapabilityListPointer = 0x34
// PCIStatusCapabilityList represents the status register bit which indicates capability list support
PCIStatusCapabilityList = 0x10
// PCIStatusBytePosition represents the position of the status register
PCIStatusBytePosition = 0x06
)
// ConfigSpace PCI configuration space (standard extended) file path
type ConfigSpace struct {
Path string
}
// ConfigSpaceIO Interface for reading and writing raw and preconfigured values
type ConfigSpaceIO interface {
bytes.Bytes
GetVendorID() uint16
GetDeviceID() uint16
GetPCICapabilities() (*PCICapabilities, error)
}
type configSpaceIO struct {
bytes.Bytes
}
// PCIStandardCapability standard PCI config space
type PCIStandardCapability struct {
bytes.Bytes
}
// PCIExtendedCapability extended PCI config space
type PCIExtendedCapability struct {
bytes.Bytes
Version uint8
}
// PCICapabilities combines the standard and extended config space
type PCICapabilities struct {
Standard map[uint8]*PCIStandardCapability
Extended map[uint16]*PCIExtendedCapability
}
func (cs *ConfigSpace) Read() (ConfigSpaceIO, error) {
config, err := os.ReadFile(cs.Path)
if err != nil {
return nil, fmt.Errorf("failed to open file: %v", err)
}
return &configSpaceIO{bytes.New(&config)}, nil
}
func (cs *configSpaceIO) GetVendorID() uint16 {
return cs.Read16(0)
}
func (cs *configSpaceIO) GetDeviceID() uint16 {
return cs.Read16(2)
}
func (cs *configSpaceIO) GetPCICapabilities() (*PCICapabilities, error) {
caps := &PCICapabilities{
make(map[uint8]*PCIStandardCapability),
make(map[uint16]*PCIExtendedCapability),
}
support := cs.Read8(PCIStatusBytePosition) & PCIStatusCapabilityList
if support == 0 {
return nil, fmt.Errorf("pci device does not support capability list")
}
soffset := cs.Read8(PCICapabilityListPointer)
if int(soffset) >= cs.Len() {
return nil, fmt.Errorf("capability list pointer out of bounds")
}
for soffset != 0 {
if soffset == 0xff {
return nil, fmt.Errorf("config space broken")
}
if int(soffset) >= PCICfgSpaceStandardSize {
return nil, fmt.Errorf("standard capability list pointer out of bounds")
}
data := cs.Read32(int(soffset))
id := uint8(data & 0xff)
caps.Standard[id] = &PCIStandardCapability{
cs.Slice(int(soffset), cs.Len()-int(soffset)),
}
soffset = uint8((data >> 8) & 0xff)
}
if cs.Len() <= PCICfgSpaceStandardSize {
return caps, nil
}
eoffset := uint16(PCICfgSpaceStandardSize)
for eoffset != 0 {
if eoffset == 0xffff {
return nil, fmt.Errorf("config space broken")
}
if int(eoffset) >= PCICfgSpaceExtendedSize {
return nil, fmt.Errorf("extended capability list pointer out of bounds")
}
// |31 20|19 16|15 0|
// |--------------------|------|-------------------------|
// | Next Cap Offset |Vers. |PCI Express Ext. Cap ID |
data := cs.Read32(int(eoffset))
id := uint16(data & 0xffff)
version := uint8((data >> 16) & 0xf)
caps.Extended[id] = &PCIExtendedCapability{
cs.Slice(int(eoffset), cs.Len()-int(eoffset)),
version,
}
eoffset = uint16((data >> 20) & 0xfff)
}
return caps, nil
}

View File

@ -0,0 +1,105 @@
/*
* Copyright (c) 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.
*/
package nvpci
import (
"fmt"
"strings"
)
const (
// PCIMellanoxVendorID represents PCI vendor id for Mellanox
PCIMellanoxVendorID uint16 = 0x15b3
// PCINetworkControllerClass represents the PCI class for network controllers
PCINetworkControllerClass uint32 = 0x020000
// PCIBridgeClass represents the PCI class for network controllers
PCIBridgeClass uint32 = 0x060400
)
// GetNetworkControllers returns all Mellanox Network Controller PCI devices on the system
func (p *nvpci) GetNetworkControllers() ([]*NvidiaPCIDevice, error) {
devices, err := p.GetAllDevices()
if err != nil {
return nil, fmt.Errorf("error getting all NVIDIA devices: %v", err)
}
var filtered []*NvidiaPCIDevice
for _, d := range devices {
if d.IsNetworkController() {
filtered = append(filtered, d)
}
}
return filtered, nil
}
// GetPciBridges retrieves all Mellanox PCI(e) Bridges
func (p *nvpci) GetPciBridges() ([]*NvidiaPCIDevice, error) {
devices, err := p.GetAllDevices()
if err != nil {
return nil, fmt.Errorf("error getting all NVIDIA devices: %v", err)
}
var filtered []*NvidiaPCIDevice
for _, d := range devices {
if d.IsPciBridge() {
filtered = append(filtered, d)
}
}
return filtered, nil
}
// IsNetworkController if class == 0x300
func (d *NvidiaPCIDevice) IsNetworkController() bool {
return d.Class == PCINetworkControllerClass
}
// IsPciBridge if class == 0x0604
func (d *NvidiaPCIDevice) IsPciBridge() bool {
return d.Class == PCIBridgeClass
}
// IsDPU returns if a device is a DPU
func (d *NvidiaPCIDevice) IsDPU() bool {
if !strings.Contains(d.DeviceName, "BlueField") {
return false
}
// DPU is a multifunction device hence look only for the .0 function
// and ignore subfunctions like .1, .2, etc.
if strings.HasSuffix(d.Address, ".0") {
return true
}
return false
}
// GetDPUs returns all Mellanox DPU devices on the system
func (p *nvpci) GetDPUs() ([]*NvidiaPCIDevice, error) {
devices, err := p.GetNetworkControllers()
if err != nil {
return nil, fmt.Errorf("error getting all network controllers: %v", err)
}
var filtered []*NvidiaPCIDevice
for _, d := range devices {
if d.IsDPU() {
filtered = append(filtered, d)
}
}
return filtered, nil
}

View File

@ -0,0 +1,127 @@
/*
* 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.
*/
package mmio
import (
"fmt"
"os"
"syscall"
"unsafe"
"gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvpci/bytes"
)
// Mmio memory map a region
type Mmio interface {
bytes.Raw
bytes.Reader
bytes.Writer
Sync() error
Close() error
Slice(offset int, size int) Mmio
LittleEndian() Mmio
BigEndian() Mmio
}
type mmio struct {
bytes.Bytes
}
func open(path string, offset int, size int, flags int) (Mmio, error) {
var mmapFlags int
switch flags {
case os.O_RDONLY:
mmapFlags = syscall.PROT_READ
case os.O_RDWR:
mmapFlags = syscall.PROT_READ | syscall.PROT_WRITE
default:
return nil, fmt.Errorf("invalid flags: %v", flags)
}
file, err := os.OpenFile(path, flags, 0)
if err != nil {
return nil, fmt.Errorf("failed to open file: %v", err)
}
defer file.Close()
fi, err := file.Stat()
if err != nil {
return nil, fmt.Errorf("failed to get file info: %v", err)
}
if size > int(fi.Size()) {
return nil, fmt.Errorf("requested size larger than file size")
}
if size < 0 {
size = int(fi.Size())
}
mmap, err := syscall.Mmap(
int(file.Fd()),
int64(offset),
size,
mmapFlags,
syscall.MAP_SHARED)
if err != nil {
return nil, fmt.Errorf("failed to mmap file: %v", err)
}
return &mmio{bytes.New(&mmap)}, nil
}
// OpenRO open region readonly
func OpenRO(path string, offset int, size int) (Mmio, error) {
return open(path, offset, size, os.O_RDONLY)
}
// OpenRW open region read write
func OpenRW(path string, offset int, size int) (Mmio, error) {
return open(path, offset, size, os.O_RDWR)
}
func (m *mmio) Slice(offset int, size int) Mmio {
return &mmio{m.Bytes.Slice(offset, size)}
}
func (m *mmio) LittleEndian() Mmio {
return &mmio{m.Bytes.LittleEndian()}
}
func (m *mmio) BigEndian() Mmio {
return &mmio{m.Bytes.BigEndian()}
}
func (m *mmio) Close() error {
err := syscall.Munmap(*m.Bytes.Raw())
if err != nil {
return fmt.Errorf("failed to munmap file: %v", err)
}
return nil
}
func (m *mmio) Sync() error {
_, _, errno := syscall.Syscall(
syscall.SYS_MSYNC,
uintptr(unsafe.Pointer(&(*m.Bytes.Raw())[0])),
uintptr(m.Len()),
uintptr(syscall.MS_SYNC|syscall.MS_INVALIDATE))
if errno != 0 {
return fmt.Errorf("failed to msync file: %v", errno)
}
return nil
}

View File

@ -0,0 +1,74 @@
/*
* 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.
*/
package mmio
import (
"fmt"
"gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvpci/bytes"
)
type mockMmio struct {
mmio
source *[]byte
offset int
rw bool
}
func mockOpen(source *[]byte, offset int, size int, rw bool) (Mmio, error) {
if size < 0 {
size = len(*source) - offset
}
if (offset + size) > len(*source) {
return nil, fmt.Errorf("offset+size out of range")
}
data := append([]byte{}, (*source)[offset:offset+size]...)
m := &mockMmio{}
m.Bytes = bytes.New(&data).LittleEndian()
m.source = source
m.offset = offset
m.rw = rw
return m, nil
}
// MockOpenRO open read only
func MockOpenRO(source *[]byte, offset int, size int) (Mmio, error) {
return mockOpen(source, offset, size, false)
}
// MockOpenRW open read write
func MockOpenRW(source *[]byte, offset int, size int) (Mmio, error) {
return mockOpen(source, offset, size, true)
}
func (m *mockMmio) Close() error {
m = &mockMmio{}
return nil
}
func (m *mockMmio) Sync() error {
if !m.rw {
return fmt.Errorf("opened read-only")
}
for i := range *m.Bytes.Raw() {
(*m.source)[m.offset+i] = (*m.Bytes.Raw())[i]
}
return nil
}

View File

@ -0,0 +1,158 @@
/*
* 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.
*/
package nvpci
import (
"fmt"
"os"
"path/filepath"
"gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvpci/bytes"
)
// MockNvpci mock pci device
type MockNvpci struct {
*nvpci
}
var _ Interface = (*MockNvpci)(nil)
// NewMockNvpci create new mock PCI and remove old devices
func NewMockNvpci() (mock *MockNvpci, rerr error) {
rootDir, err := os.MkdirTemp(os.TempDir(), "")
if err != nil {
return nil, err
}
defer func() {
if rerr != nil {
os.RemoveAll(rootDir)
}
}()
mock = &MockNvpci{
NewFrom(rootDir).(*nvpci),
}
return mock, nil
}
// Cleanup remove the mocked PCI devices root folder
func (m *MockNvpci) Cleanup() {
os.RemoveAll(m.pciDevicesRoot)
}
// AddMockA100 Create an A100 like GPU mock device
func (m *MockNvpci) AddMockA100(address string, numaNode int) error {
deviceDir := filepath.Join(m.pciDevicesRoot, address)
err := os.MkdirAll(deviceDir, 0755)
if err != nil {
return err
}
vendor, err := os.Create(filepath.Join(deviceDir, "vendor"))
if err != nil {
return err
}
_, err = vendor.WriteString(fmt.Sprintf("0x%x", PCINvidiaVendorID))
if err != nil {
return err
}
class, err := os.Create(filepath.Join(deviceDir, "class"))
if err != nil {
return err
}
_, err = class.WriteString(fmt.Sprintf("0x%x", PCI3dControllerClass))
if err != nil {
return err
}
device, err := os.Create(filepath.Join(deviceDir, "device"))
if err != nil {
return err
}
_, err = device.WriteString("0x20bf")
if err != nil {
return err
}
_, err = os.Create(filepath.Join(deviceDir, "nvidia"))
if err != nil {
return err
}
err = os.Symlink(filepath.Join(deviceDir, "nvidia"), filepath.Join(deviceDir, "driver"))
if err != nil {
return err
}
_, err = os.Create(filepath.Join(deviceDir, "20"))
if err != nil {
return err
}
err = os.Symlink(filepath.Join(deviceDir, "20"), filepath.Join(deviceDir, "iommu_group"))
if err != nil {
return err
}
numa, err := os.Create(filepath.Join(deviceDir, "numa_node"))
if err != nil {
return err
}
_, err = numa.WriteString(fmt.Sprintf("%v", numaNode))
if err != nil {
return err
}
config, err := os.Create(filepath.Join(deviceDir, "config"))
if err != nil {
return err
}
_data := make([]byte, PCICfgSpaceStandardSize)
data := bytes.New(&_data)
data.Write16(0, PCINvidiaVendorID)
data.Write16(2, uint16(0x20bf))
data.Write8(PCIStatusBytePosition, PCIStatusCapabilityList)
_, err = config.Write(*data.Raw())
if err != nil {
return err
}
bar0 := []uint64{0x00000000c2000000, 0x00000000c2ffffff, 0x0000000000040200}
resource, err := os.Create(filepath.Join(deviceDir, "resource"))
if err != nil {
return err
}
_, err = resource.WriteString(fmt.Sprintf("0x%x 0x%x 0x%x", bar0[0], bar0[1], bar0[2]))
if err != nil {
return err
}
pmcID := uint32(0x170000a1)
resource0, err := os.Create(filepath.Join(deviceDir, "resource0"))
if err != nil {
return err
}
_data = make([]byte, bar0[1]-bar0[0]+1)
data = bytes.New(&_data).LittleEndian()
data.Write32(0, pmcID)
_, err = resource0.Write(*data.Raw())
if err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,384 @@
/*
* 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.
*/
package nvpci
import (
"fmt"
"os"
"path"
"path/filepath"
"sort"
"strconv"
"strings"
"gitlab.com/nvidia/cloud-native/go-nvlib/pkg/pciids"
)
const (
// PCIDevicesRoot represents base path for all pci devices under sysfs
PCIDevicesRoot = "/sys/bus/pci/devices"
// PCINvidiaVendorID represents PCI vendor id for NVIDIA
PCINvidiaVendorID uint16 = 0x10de
// PCIVgaControllerClass represents the PCI class for VGA Controllers
PCIVgaControllerClass uint32 = 0x030000
// PCI3dControllerClass represents the PCI class for 3D Graphics accellerators
PCI3dControllerClass uint32 = 0x030200
// PCINvSwitchClass represents the PCI class for NVSwitches
PCINvSwitchClass uint32 = 0x068000
)
// Interface allows us to get a list of all NVIDIA PCI devices
type Interface interface {
GetAllDevices() ([]*NvidiaPCIDevice, error)
Get3DControllers() ([]*NvidiaPCIDevice, error)
GetVGAControllers() ([]*NvidiaPCIDevice, error)
GetNVSwitches() ([]*NvidiaPCIDevice, error)
GetGPUs() ([]*NvidiaPCIDevice, error)
GetGPUByIndex(int) (*NvidiaPCIDevice, error)
GetGPUByPciBusID(string) (*NvidiaPCIDevice, error)
GetNetworkControllers() ([]*NvidiaPCIDevice, error)
GetPciBridges() ([]*NvidiaPCIDevice, error)
GetDPUs() ([]*NvidiaPCIDevice, error)
}
// MemoryResources a more human readable handle
type MemoryResources map[int]*MemoryResource
// ResourceInterface exposes some higher level functions of resources
type ResourceInterface interface {
GetTotalAddressableMemory(bool) (uint64, uint64)
}
type nvpci struct {
pciDevicesRoot string
}
var _ Interface = (*nvpci)(nil)
var _ ResourceInterface = (*MemoryResources)(nil)
// NvidiaPCIDevice represents a PCI device for an NVIDIA product
type NvidiaPCIDevice struct {
Path string
Address string
Vendor uint16
Class uint32
ClassName string
Device uint16
DeviceName string
Driver string
IommuGroup int
NumaNode int
Config *ConfigSpace
Resources MemoryResources
IsVF bool
}
// IsVGAController if class == 0x300
func (d *NvidiaPCIDevice) IsVGAController() bool {
return d.Class == PCIVgaControllerClass
}
// Is3DController if class == 0x302
func (d *NvidiaPCIDevice) Is3DController() bool {
return d.Class == PCI3dControllerClass
}
// IsNVSwitch if class == 0x068
func (d *NvidiaPCIDevice) IsNVSwitch() bool {
return d.Class == PCINvSwitchClass
}
// IsGPU either VGA for older cards or 3D for newer
func (d *NvidiaPCIDevice) IsGPU() bool {
return d.IsVGAController() || d.Is3DController()
}
// IsResetAvailable some devices can be reset without rebooting,
// check if applicable
func (d *NvidiaPCIDevice) IsResetAvailable() bool {
_, err := os.Stat(path.Join(d.Path, "reset"))
return err == nil
}
// Reset perform a reset to apply a new configuration at HW level
func (d *NvidiaPCIDevice) Reset() error {
err := os.WriteFile(path.Join(d.Path, "reset"), []byte("1"), 0)
if err != nil {
return fmt.Errorf("unable to write to reset file: %v", err)
}
return nil
}
// New interface that allows us to get a list of all NVIDIA PCI devices
func New() Interface {
return NewFrom(PCIDevicesRoot)
}
// NewFrom interface allows us to get a list of all NVIDIA PCI devices at a specific root directory
func NewFrom(root string) Interface {
return &nvpci{
pciDevicesRoot: root,
}
}
// GetAllDevices returns all Nvidia PCI devices on the system
func (p *nvpci) GetAllDevices() ([]*NvidiaPCIDevice, error) {
deviceDirs, err := os.ReadDir(p.pciDevicesRoot)
if err != nil {
return nil, fmt.Errorf("unable to read PCI bus devices: %v", err)
}
var nvdevices []*NvidiaPCIDevice
for _, deviceDir := range deviceDirs {
deviceAddress := deviceDir.Name()
nvdevice, err := p.GetGPUByPciBusID(deviceAddress)
if err != nil {
return nil, fmt.Errorf("error constructing NVIDIA PCI device %s: %v", deviceAddress, err)
}
if nvdevice == nil {
continue
}
nvdevices = append(nvdevices, nvdevice)
}
addressToID := func(address string) uint64 {
address = strings.ReplaceAll(address, ":", "")
address = strings.ReplaceAll(address, ".", "")
id, _ := strconv.ParseUint(address, 16, 64)
return id
}
sort.Slice(nvdevices, func(i, j int) bool {
return addressToID(nvdevices[i].Address) < addressToID(nvdevices[j].Address)
})
return nvdevices, nil
}
// GetGPUByPciBusID constructs an NvidiaPCIDevice for the specified address (PCI Bus ID)
func (p *nvpci) GetGPUByPciBusID(address string) (*NvidiaPCIDevice, error) {
devicePath := filepath.Join(p.pciDevicesRoot, address)
vendor, err := os.ReadFile(path.Join(devicePath, "vendor"))
if err != nil {
return nil, fmt.Errorf("unable to read PCI device vendor id for %s: %v", address, err)
}
vendorStr := strings.TrimSpace(string(vendor))
vendorID, err := strconv.ParseUint(vendorStr, 0, 16)
if err != nil {
return nil, fmt.Errorf("unable to convert vendor string to uint16: %v", vendorStr)
}
if uint16(vendorID) != PCINvidiaVendorID && uint16(vendorID) != PCIMellanoxVendorID {
return nil, nil
}
class, err := os.ReadFile(path.Join(devicePath, "class"))
if err != nil {
return nil, fmt.Errorf("unable to read PCI device class for %s: %v", address, err)
}
classStr := strings.TrimSpace(string(class))
classID, err := strconv.ParseUint(classStr, 0, 32)
if err != nil {
return nil, fmt.Errorf("unable to convert class string to uint32: %v", classStr)
}
device, err := os.ReadFile(path.Join(devicePath, "device"))
if err != nil {
return nil, fmt.Errorf("unable to read PCI device id for %s: %v", address, err)
}
deviceStr := strings.TrimSpace(string(device))
deviceID, err := strconv.ParseUint(deviceStr, 0, 16)
if err != nil {
return nil, fmt.Errorf("unable to convert device string to uint16: %v", deviceStr)
}
driver, err := filepath.EvalSymlinks(path.Join(devicePath, "driver"))
if err == nil {
driver = filepath.Base(driver)
} else if os.IsNotExist(err) {
driver = ""
} else {
return nil, fmt.Errorf("unable to detect driver for %s: %v", address, err)
}
var iommuGroup int64
iommu, err := filepath.EvalSymlinks(path.Join(devicePath, "iommu_group"))
if err == nil {
iommuGroupStr := strings.TrimSpace(filepath.Base(iommu))
iommuGroup, err = strconv.ParseInt(iommuGroupStr, 0, 64)
if err != nil {
return nil, fmt.Errorf("unable to convert iommu_group string to int64: %v", iommuGroupStr)
}
} else if os.IsNotExist(err) {
iommuGroup = -1
} else {
return nil, fmt.Errorf("unable to detect iommu_group for %s: %v", address, err)
}
// device is a virtual function (VF) if "physfn" symlink exists
var isVF bool
_, err = filepath.EvalSymlinks(path.Join(devicePath, "physfn"))
if err == nil {
isVF = true
}
if err != nil && !os.IsNotExist(err) {
return nil, fmt.Errorf("unable to resolve %s: %v", path.Join(devicePath, "physfn"), err)
}
numa, err := os.ReadFile(path.Join(devicePath, "numa_node"))
if err != nil {
return nil, fmt.Errorf("unable to read PCI NUMA node for %s: %v", address, err)
}
numaStr := strings.TrimSpace(string(numa))
numaNode, err := strconv.ParseInt(numaStr, 0, 64)
if err != nil {
return nil, fmt.Errorf("unable to convert NUMA node string to int64: %v", numaNode)
}
config := &ConfigSpace{
Path: path.Join(devicePath, "config"),
}
resource, err := os.ReadFile(path.Join(devicePath, "resource"))
if err != nil {
return nil, fmt.Errorf("unable to read PCI resource file for %s: %v", address, err)
}
resources := make(map[int]*MemoryResource)
for i, line := range strings.Split(strings.TrimSpace(string(resource)), "\n") {
values := strings.Split(line, " ")
if len(values) != 3 {
return nil, fmt.Errorf("more than 3 entries in line '%d' of resource file", i)
}
start, _ := strconv.ParseUint(values[0], 0, 64)
end, _ := strconv.ParseUint(values[1], 0, 64)
flags, _ := strconv.ParseUint(values[2], 0, 64)
if (end - start) != 0 {
resources[i] = &MemoryResource{
uintptr(start),
uintptr(end),
flags,
fmt.Sprintf("%s/resource%d", devicePath, i),
}
}
}
pciDB := pciids.NewDB()
nvdevice := &NvidiaPCIDevice{
Path: devicePath,
Address: address,
Vendor: uint16(vendorID),
Class: uint32(classID),
Device: uint16(deviceID),
Driver: driver,
IommuGroup: int(iommuGroup),
NumaNode: int(numaNode),
Config: config,
Resources: resources,
IsVF: isVF,
DeviceName: pciDB.GetDeviceName(uint16(vendorID), uint16(deviceID)),
ClassName: pciDB.GetClassName(uint32(classID)),
}
return nvdevice, nil
}
// Get3DControllers returns all NVIDIA 3D Controller PCI devices on the system
func (p *nvpci) Get3DControllers() ([]*NvidiaPCIDevice, error) {
devices, err := p.GetAllDevices()
if err != nil {
return nil, fmt.Errorf("error getting all NVIDIA devices: %v", err)
}
var filtered []*NvidiaPCIDevice
for _, d := range devices {
if d.Is3DController() {
filtered = append(filtered, d)
}
}
return filtered, nil
}
// GetVGAControllers returns all NVIDIA VGA Controller PCI devices on the system
func (p *nvpci) GetVGAControllers() ([]*NvidiaPCIDevice, error) {
devices, err := p.GetAllDevices()
if err != nil {
return nil, fmt.Errorf("error getting all NVIDIA devices: %v", err)
}
var filtered []*NvidiaPCIDevice
for _, d := range devices {
if d.IsVGAController() {
filtered = append(filtered, d)
}
}
return filtered, nil
}
// GetNVSwitches returns all NVIDIA NVSwitch PCI devices on the system
func (p *nvpci) GetNVSwitches() ([]*NvidiaPCIDevice, error) {
devices, err := p.GetAllDevices()
if err != nil {
return nil, fmt.Errorf("error getting all NVIDIA devices: %v", err)
}
var filtered []*NvidiaPCIDevice
for _, d := range devices {
if d.IsNVSwitch() {
filtered = append(filtered, d)
}
}
return filtered, nil
}
// GetGPUs returns all NVIDIA GPU devices on the system
func (p *nvpci) GetGPUs() ([]*NvidiaPCIDevice, error) {
devices, err := p.GetAllDevices()
if err != nil {
return nil, fmt.Errorf("error getting all NVIDIA devices: %v", err)
}
var filtered []*NvidiaPCIDevice
for _, d := range devices {
if d.IsGPU() && !d.IsVF {
filtered = append(filtered, d)
}
}
return filtered, nil
}
// GetGPUByIndex returns an NVIDIA GPU device at a particular index
func (p *nvpci) GetGPUByIndex(i int) (*NvidiaPCIDevice, error) {
gpus, err := p.GetGPUs()
if err != nil {
return nil, fmt.Errorf("error getting all gpus: %v", err)
}
if i < 0 || i >= len(gpus) {
return nil, fmt.Errorf("invalid index '%d'", i)
}
return gpus[i], nil
}

View File

@ -0,0 +1,140 @@
/*
* 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.
*/
package nvpci
import (
"fmt"
"sort"
"gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvpci/mmio"
)
const (
pmcEndianRegister = 0x4
pmcLittleEndian = 0x0
pmcBigEndian = 0x01000001
)
// MemoryResource represents a mmio region
type MemoryResource struct {
Start uintptr
End uintptr
Flags uint64
Path string
}
// OpenRW read write mmio region
func (mr *MemoryResource) OpenRW() (mmio.Mmio, error) {
rw, err := mmio.OpenRW(mr.Path, 0, int(mr.End-mr.Start+1))
if err != nil {
return nil, fmt.Errorf("failed to open file for mmio: %v", err)
}
switch rw.Read32(pmcEndianRegister) {
case pmcBigEndian:
return rw.BigEndian(), nil
case pmcLittleEndian:
return rw.LittleEndian(), nil
}
return nil, fmt.Errorf("unknown endianness for mmio: %v", err)
}
// OpenRO read only mmio region
func (mr *MemoryResource) OpenRO() (mmio.Mmio, error) {
ro, err := mmio.OpenRO(mr.Path, 0, int(mr.End-mr.Start+1))
if err != nil {
return nil, fmt.Errorf("failed to open file for mmio: %v", err)
}
switch ro.Read32(pmcEndianRegister) {
case pmcBigEndian:
return ro.BigEndian(), nil
case pmcLittleEndian:
return ro.LittleEndian(), nil
}
return nil, fmt.Errorf("unknown endianness for mmio: %v", err)
}
// From Bit Twiddling Hacks, great resource for all low level bit manipulations
func calcNextPowerOf2(n uint64) uint64 {
n--
n |= n >> 1
n |= n >> 2
n |= n >> 4
n |= n >> 8
n |= n >> 16
n |= n >> 32
n++
return n
}
// 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
// return value is the accumulated 32bit addresable memory size the second one
// is the accumulated 64bit addressable memory size in bytes. These values are
// needed to configure virtualized environments.
func (mrs MemoryResources) GetTotalAddressableMemory(roundUp bool) (uint64, uint64) {
const pciIOVNumBAR = 6
const pciBaseAddressMemTypeMask = 0x06
const pciBaseAddressMemType32 = 0x00 /* 32 bit address */
const pciBaseAddressMemType64 = 0x04 /* 64 bit address */
// We need to sort the resources so the first 6 entries are the BARs
// How a map is represented in memory is not guaranteed, it is not an
// array. Keys do not have an order.
keys := make([]int, 0, len(mrs))
for k := range mrs {
keys = append(keys, k)
}
sort.Ints(keys)
numBAR := 0
memSize32bit := uint64(0)
memSize64bit := uint64(0)
for _, key := range keys {
// The PCIe spec only defines 5 BARs per device, we're
// discarding everything after the 5th entry of the resources
// file, see lspci.c
if key >= pciIOVNumBAR || numBAR == pciIOVNumBAR {
break
}
numBAR = numBAR + 1
region := mrs[key]
flags := region.Flags & pciBaseAddressMemTypeMask
memType32bit := flags == pciBaseAddressMemType32
memType64bit := flags == pciBaseAddressMemType64
memSize := (region.End - region.Start) + 1
if memType32bit {
memSize32bit = memSize32bit + uint64(memSize)
}
if memType64bit {
memSize64bit = memSize64bit + uint64(memSize)
}
}
if roundUp {
memSize32bit = calcNextPowerOf2(memSize32bit)
memSize64bit = calcNextPowerOf2(memSize64bit)
}
return memSize32bit, memSize64bit
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,404 @@
package pciids
import (
"bufio"
"bytes"
_ "embed" // Fallback is the embedded pci.ids db file
"fmt"
"io"
"os"
"strconv"
"strings"
)
// token what the Lexer retruns
type token int
const (
// ILLEGAL a token which the Lexer does not understand
ILLEGAL token = iota
// EOF end of file
EOF
// WS whitespace
WS
// NEWLINE '\n'
NEWLINE
// COMMENT '# something'
COMMENT
// VENDOR PCI vendor
VENDOR
// SUBVENDOR PCI subvendor
SUBVENDOR
// DEVICE PCI device
DEVICE
// CLASS PCI class
CLASS
// SUBCLASS PCI subclass
SUBCLASS
// PROGIF PCI programming interface
PROGIF
)
// literal values from the Lexer
type literal struct {
ID string
name string
SubName string
}
// scanner a lexical scanner
type scanner struct {
r *bufio.Reader
isVendor bool
}
// newScanner well a new scanner ...
func newScanner(r io.Reader) *scanner {
return &scanner{r: bufio.NewReader(r)}
}
// Since the pci.ids is line base we're consuming a whole line rather then only
// a single rune/char
func (s *scanner) readline() []byte {
ln, err := s.r.ReadBytes('\n')
if err == io.EOF {
return []byte{'E', 'O', 'F'}
}
if err != nil {
fmt.Printf("ReadBytes failed with %v", err)
return []byte{}
}
return ln
}
func scanClass(line []byte) (token, literal) {
class := string(line[1:])
return CLASS, scanEntry([]byte(class), 2)
}
func scanSubVendor(line []byte) (token, literal) {
trim0 := strings.TrimSpace(string(line))
subv := string(trim0[:4])
trim1 := strings.TrimSpace(trim0[4:])
subd := string(trim1[:4])
subn := strings.TrimSpace(trim1[4:])
return SUBVENDOR, literal{subv, subd, subn}
}
func scanEntry(line []byte, offset uint) literal {
trim := strings.TrimSpace(string(line))
id := string(trim[:offset])
name := strings.TrimSpace(trim[offset:])
return literal{id, name, ""}
}
func isLeadingOneTab(ln []byte) bool { return (ln[0] == '\t') && (ln[1] != '\t') }
func isLeadingTwoTabs(ln []byte) bool { return (ln[0] == '\t') && (ln[1] == '\t') }
func isHexDigit(ln []byte) bool { return (ln[0] >= '0' && ln[0] <= '9') }
func isHexLetter(ln []byte) bool { return (ln[0] >= 'a' && ln[0] <= 'f') }
func isVendor(ln []byte) bool { return isHexDigit(ln) || isHexLetter(ln) }
func isEOF(ln []byte) bool { return (ln[0] == 'E' && ln[1] == 'O' && ln[2] == 'F') }
func isComment(ln []byte) bool { return (ln[0] == '#') }
func isSubVendor(ln []byte) bool { return isLeadingTwoTabs(ln) }
func isDevice(ln []byte) bool { return isLeadingOneTab(ln) }
func isNewline(ln []byte) bool { return (ln[0] == '\n') }
// List of known device classes, subclasses and programming interfaces
func isClass(ln []byte) bool { return (ln[0] == 'C') }
func isProgIf(ln []byte) bool { return isLeadingTwoTabs(ln) }
func isSubClass(ln []byte) bool { return isLeadingOneTab(ln) }
// unread places the previously read rune back on the reader.
func (s *scanner) unread() { _ = s.r.UnreadRune() }
// scan returns the next token and literal value.
func (s *scanner) scan() (tok token, lit literal) {
line := s.readline()
if isEOF(line) {
return EOF, literal{}
}
if isNewline(line) {
return NEWLINE, literal{ID: string('\n')}
}
if isComment(line) {
return COMMENT, literal{ID: string(line)}
}
// vendors
if isVendor(line) {
s.isVendor = true
return VENDOR, scanEntry(line, 4)
}
if isSubVendor(line) && s.isVendor {
return scanSubVendor(line)
}
if isDevice(line) && s.isVendor {
return DEVICE, scanEntry(line, 4)
}
// classes
if isClass(line) {
s.isVendor = false
return scanClass(line)
}
if isProgIf(line) && !s.isVendor {
return PROGIF, scanEntry(line, 2)
}
if isSubClass(line) && !s.isVendor {
return SUBCLASS, scanEntry(line, 2)
}
return ILLEGAL, literal{ID: string(line)}
}
// parser reads the tokens returned by the Lexer and constructs the AST
type parser struct {
s *scanner
buf struct {
tok token
lit literal
n int
}
}
// This is a fallback if all of the locations fail
//go:embed default_pci.ids
var defaultPCIdb []byte
// NewDB Parse the PCI DB in its default locations or use the default
// builtin pci.ids db.
func NewDB() Interface {
// Various locations of pci.ids for differente distributions these may be more
// up to date then the embedded pci.ids db
pcidbs := []string{
"/usr/share/misc/pci.ids", // Ubuntu
"/usr/local/share/pci.ids", // RHEL like with manual update
"/usr/share/hwdata/pci.ids", // RHEL like
"/usr/share/pci.ids", // SUSE
}
return newParser(pcidbs).parse()
}
// newParser will attempt to read the db pci.ids from well known places or fall
// back to an internal db
func newParser(pcidbs []string) *parser {
for _, db := range pcidbs {
file, err := os.ReadFile(db)
if err != nil {
continue
}
return newParserFromReader(bufio.NewReader(bytes.NewReader(file)))
}
// We're using go embed above to have the byte array
// correctly initialized with the internal shipped db
// if we cannot find an up to date in the filesystem
return newParserFromReader(bufio.NewReader(bytes.NewReader(defaultPCIdb)))
}
func newParserFromReader(r *bufio.Reader) *parser {
return &parser{s: newScanner(r)}
}
func (p *parser) scan() (tok token, lit literal) {
if p.buf.n != 0 {
p.buf.n = 0
return p.buf.tok, p.buf.lit
}
tok, lit = p.s.scan()
p.buf.tok, p.buf.lit = tok, lit
return
}
func (p *parser) unscan() { p.buf.n = 1 }
var _ Interface = (*pcidb)(nil)
// Interface returns textual description of specific attributes of PCI devices
type Interface interface {
GetDeviceName(uint16, uint16) string
GetClassName(uint32) string
}
// GetDeviceName return the textual description of the PCI device
func (d *pcidb) GetDeviceName(vendorID uint16, deviceID uint16) string {
return d.vendors[vendorID].devices[deviceID].name
}
// GetClassName resturn the textual description of the PCI device class
func (d *pcidb) GetClassName(classID uint32) string {
return d.classes[classID].name
}
// pcidb The complete set of PCI vendors and PCI classes
type pcidb struct {
vendors map[uint16]vendor
classes map[uint32]class
}
// vendor PCI vendors/devices/subVendors/SubDevices
type vendor struct {
name string
devices map[uint16]device
}
// subVendor PCI subVendor
type subVendor struct {
SubDevices map[uint16]SubDevice
}
// SubDevice PCI SubDevice
type SubDevice struct {
name string
}
// device PCI device
type device struct {
name string
subVendors map[uint16]subVendor
}
// class PCI classes/subClasses/Programming Interfaces
type class struct {
name string
subClasses map[uint32]subClass
}
// subClass PCI subClass
type subClass struct {
name string
progIfs map[uint8]progIf
}
// progIf PCI Programming Interface
type progIf struct {
name string
}
// parse parses a PCI IDS entry
func (p *parser) parse() Interface {
db := &pcidb{
vendors: map[uint16]vendor{},
classes: map[uint32]class{},
}
// Used for housekeeping, breadcrumb for aggregated types
var hkVendor vendor
var hkDevice device
var hkClass class
var hkSubClass subClass
var hkFullID uint32 = 0
var hkFullName [2]string
for {
tok, lit := p.scan()
// We're ignoring COMMENT, NEWLINE
// An EOF will break the loop
if tok == EOF {
break
}
// PCI vendors -------------------------------------------------
if tok == VENDOR {
id, _ := strconv.ParseUint(lit.ID, 16, 16)
db.vendors[uint16(id)] = vendor{
name: lit.name,
devices: map[uint16]device{},
}
hkVendor = db.vendors[uint16(id)]
}
if tok == DEVICE {
id, _ := strconv.ParseUint(lit.ID, 16, 16)
hkVendor.devices[uint16(id)] = device{
name: lit.name,
subVendors: map[uint16]subVendor{},
}
hkDevice = hkVendor.devices[uint16(id)]
}
if tok == SUBVENDOR {
id, _ := strconv.ParseUint(lit.ID, 16, 16)
hkDevice.subVendors[uint16(id)] = subVendor{
SubDevices: map[uint16]SubDevice{},
}
subvendor := hkDevice.subVendors[uint16(id)]
subid, _ := strconv.ParseUint(lit.name, 16, 16)
subvendor.SubDevices[uint16(subid)] = SubDevice{
name: lit.SubName,
}
}
// PCI classes -------------------------------------------------
if tok == CLASS {
id, _ := strconv.ParseUint(lit.ID, 16, 32)
db.classes[uint32(id)] = class{
name: lit.name,
subClasses: map[uint32]subClass{},
}
hkClass = db.classes[uint32(id)]
hkFullID = uint32(id) << 16
hkFullID = hkFullID & 0xFFFF0000
hkFullName[0] = fmt.Sprintf("%s (%02x)", lit.name, id)
}
if tok == SUBCLASS {
id, _ := strconv.ParseUint(lit.ID, 16, 8)
hkClass.subClasses[uint32(id)] = subClass{
name: lit.name,
progIfs: map[uint8]progIf{},
}
hkSubClass = hkClass.subClasses[uint32(id)]
// Clear the last detected sub class
hkFullID = hkFullID & 0xFFFF0000
hkFullID = hkFullID | uint32(id)<<8
// Clear the last detected prog iface
hkFullID = hkFullID & 0xFFFFFF00
hkFullName[1] = fmt.Sprintf("%s (%02x)", lit.name, id)
db.classes[uint32(hkFullID)] = class{
name: hkFullName[0] + " | " + hkFullName[1],
}
}
if tok == PROGIF {
id, _ := strconv.ParseUint(lit.ID, 16, 8)
hkSubClass.progIfs[uint8(id)] = progIf{
name: lit.name,
}
finalID := hkFullID | uint32(id)
name := fmt.Sprintf("%s (%02x)", lit.name, id)
finalName := hkFullName[0] + " | " + hkFullName[1] + " | " + name
db.classes[finalID] = class{
name: finalName,
}
}
if tok == ILLEGAL {
fmt.Printf("warning: illegal token %s %s cannot parse PCI IDS, database may be incomplete ", lit.ID, lit.name)
}
}
return db
}

6
vendor/modules.txt vendored
View File

@ -62,11 +62,15 @@ github.com/syndtr/gocapability/capability
github.com/urfave/cli/v2 github.com/urfave/cli/v2
# github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb # github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb
## explicit ## explicit
# gitlab.com/nvidia/cloud-native/go-nvlib v0.0.0-20220922133427-1049a7fa76a9 # gitlab.com/nvidia/cloud-native/go-nvlib v0.0.0-20230119114711-6fe07bb33342
## explicit; go 1.16 ## explicit; go 1.16
gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvlib/device gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvlib/device
gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvlib/info gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvlib/info
gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvml gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvml
gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvpci
gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvpci/bytes
gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvpci/mmio
gitlab.com/nvidia/cloud-native/go-nvlib/pkg/pciids
# golang.org/x/mod v0.5.0 # golang.org/x/mod v0.5.0
## explicit; go 1.17 ## explicit; go 1.17
golang.org/x/mod/semver golang.org/x/mod/semver