device.go 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package kubemodel
  2. import (
  3. "errors"
  4. "fmt"
  5. "time"
  6. )
  7. // @bingen:generate:Device
  8. type Device struct {
  9. UID string `json:"uid"` // Device UUID (hardware identifier)
  10. Type string `json:"type,omitempty"` // Device type (e.g., "device", "tpu")
  11. NodeUID string `json:"nodeUid"` // Node hosting this device
  12. DeviceNumber int32 `json:"deviceNumber"`
  13. ModelName string `json:"modelName"`
  14. IsShared bool `json:"isShared"` // Device sharing information
  15. SharePercentage float64 `json:"sharePercentage"`
  16. UsageSeconds float64 `json:"usageSeconds"` // Device seconds available
  17. MemoryByteSeconds Measurement `json:"memoryByteSeconds"` // Device memory capacity in Byte-seconds
  18. PowerWattSeconds float64 `json:"powerWattSeconds"` // Device power consumption in watt-seconds (Joules)
  19. PowerWattMax float64 `json:"powerWattMax"` // Device max power consumption in watts
  20. // Version 2 fields - Lifecycle tracking
  21. Start time.Time `json:"start,omitempty"` // Device availability start
  22. End time.Time `json:"end,omitempty"` // Device availability end
  23. DurationSeconds Measurement `json:"durationSeconds"` // Duration device was available
  24. }
  25. // Validate validates the Device fields
  26. func (d *Device) Validate() error {
  27. if d.UID == "" {
  28. return errors.New("UID is required")
  29. }
  30. if d.NodeUID == "" {
  31. return errors.New("NodeUID is required")
  32. }
  33. if d.SharePercentage < 0 || d.SharePercentage > 100 {
  34. return fmt.Errorf("SharePercentage must be 0-100, got %.2f", d.SharePercentage)
  35. }
  36. if d.PowerWattSeconds < 0 {
  37. return fmt.Errorf("PowerWattSeconds cannot be negative, got %.2f", d.PowerWattSeconds)
  38. }
  39. if d.PowerWattMax < 0 {
  40. return fmt.Errorf("PowerWattMax cannot be negative, got %.2f", d.PowerWattMax)
  41. }
  42. return nil
  43. }
  44. // Clone creates a deep copy of the Device
  45. func (d *Device) Clone() *Device {
  46. if d == nil {
  47. return nil
  48. }
  49. cloned := &Device{
  50. UID: d.UID,
  51. Type: d.Type,
  52. NodeUID: d.NodeUID,
  53. DeviceNumber: d.DeviceNumber,
  54. ModelName: d.ModelName,
  55. IsShared: d.IsShared,
  56. SharePercentage: d.SharePercentage,
  57. UsageSeconds: d.UsageSeconds,
  58. MemoryByteSeconds: d.MemoryByteSeconds,
  59. PowerWattSeconds: d.PowerWattSeconds,
  60. PowerWattMax: d.PowerWattMax,
  61. DurationSeconds: d.DurationSeconds,
  62. }
  63. cloned.Start = d.Start
  64. cloned.End = d.End
  65. return cloned
  66. }
  67. func (kms *KubeModelSet) RegisterDevice(uid, nodeUID string) error {
  68. if uid == "" {
  69. err := fmt.Errorf("UID is nil for Device")
  70. kms.Error(err)
  71. return err
  72. }
  73. if _, ok := kms.Devices[uid]; !ok {
  74. kms.Devices[uid] = &Device{
  75. UID: uid,
  76. NodeUID: nodeUID,
  77. }
  78. kms.Metadata.ObjectCount++
  79. }
  80. return nil
  81. }