func NewDeviceSet(devices ...*Device) DeviceSet {
	set := make(DeviceSet)
	set.Insert(devices...)
	return set
}
NewDeviceSet creates a new DeviceSet.
package gpuallocator
import (
	"fmt"
	"sort"
	"strings"
	"github.com/NVIDIA/gpu-monitoring-tools/bindings/go/nvml"
)
type Device struct {
	*nvml.Device
	Index int
	Links map[int][]P2PLink
}
type P2PLink struct {
	GPU  *Device
	Type nvml.P2PLinkType
}
type DeviceSet map[string]*Device
func NewDevices() ([]*Device, error) {
	count, err := nvml.GetDeviceCount()
	if err != nil {
		return nil, fmt.Errorf("error calling nvml.GetDeviceCount: %v", err)
	}
	devices := []*Device{}
	for i := 0; i < int(count); i++ {
		device, err := nvml.NewDevice(uint(i))
		if err != nil {
			return nil, fmt.Errorf("error creating nvml.Device %v: %v", i, err)
		}
		devices = append(devices, &Device{device, i, make(map[int][]P2PLink)})
	}
	for i, d1 := range devices {
		for j, d2 := range devices {
			if d1 != d2 {
				p2plink, err := nvml.GetP2PLink(d1.Device, d2.Device)
				if err != nil {
					return nil, fmt.Errorf("error getting P2PLink for devices (%v, %v): %v", i, j, err)
				}
				if p2plink != nvml.P2PLinkUnknown {
					d1.Links[d2.Index] = append(d1.Links[d2.Index], P2PLink{d2, p2plink})
				}
				nvlink, err := nvml.GetNVLink(d1.Device, d2.Device)
				if err != nil {
					return nil, fmt.Errorf("error getting NVLink for devices (%v, %v): %v", i, j, err)
				}
				if nvlink != nvml.P2PLinkUnknown {
					d1.Links[d2.Index] = append(d1.Links[d2.Index], P2PLink{d2, nvlink})
				}
			}
		}
	}
	return devices, nil
}
func NewDevicesFrom(uuids []string) ([]*Device, error) {
	devices, err := NewDevices()
	if err != nil {
		return nil, err
	}
	filtered := []*Device{}
	for _, uuid := range uuids {
		for _, device := range devices {
			if device.UUID == uuid {
				filtered = append(filtered, device)
				break
			}
		}
		if len(filtered) == 0 || filtered[len(filtered)-1].UUID != uuid {
			return nil, fmt.Errorf("no device with uuid: %v", uuid)
		}
	}
	return filtered, nil
}
func (d *Device) String() string {
	return fmt.Sprintf("%v", d.Index)
}
func (d *Device) Details() string {
	s := ""
	s += fmt.Sprintf("Device %v:\n", d.Index)
	s += fmt.Sprintf("  UUID: %v\n", d.UUID)
	s += fmt.Sprintf("  PCI BusID: %v\n", d.PCI.BusID)
	s += fmt.Sprintf("  SocketAffinity: %v\n", *d.CPUAffinity)
	s += fmt.Sprintf("  Topology: \n")
	for gpu, links := range d.Links {
		s += fmt.Sprintf("    GPU %v Links:\n", gpu)
		for _, link := range links {
			s += fmt.Sprintf("      %v\n", link.Type)
		}
	}
	return strings.TrimSuffix(s, "\n")
}