device.go 2.7 KB

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