github.com/filecoin-project/bacalhau@v0.3.23-0.20230228154132-45c989550ace/pkg/model/v1alpha1/resource_usage.go (about) 1 package v1alpha1 2 3 import ( 4 "fmt" 5 6 "github.com/rs/zerolog/log" 7 ) 8 9 // a record for the "amount" of compute resources an entity has / can consume / is using 10 11 type ResourceUsageConfig struct { 12 // https://github.com/BTBurke/k8sresource string 13 CPU string `json:"CPU,omitempty"` 14 // github.com/c2h5oh/datasize string 15 Memory string `json:"Memory,omitempty"` 16 // github.com/c2h5oh/datasize string 17 18 Disk string `json:"Disk,omitempty"` 19 GPU string `json:"GPU"` // unsigned integer string 20 21 } 22 23 // these are the numeric values in bytes for ResourceUsageConfig 24 type ResourceUsageData struct { 25 // cpu units 26 CPU float64 `json:"CPU,omitempty" example:"9.600000000000001"` 27 // bytes 28 Memory uint64 `json:"Memory,omitempty" example:"27487790694"` 29 // bytes 30 Disk uint64 `json:"Disk,omitempty" example:"212663867801"` 31 GPU uint64 `json:"GPU,omitempty" example:"1"` //nolint:lll // Support whole GPUs only, like https://kubernetes.io/docs/tasks/manage-gpus/scheduling-gpus/ 32 } 33 34 func (r ResourceUsageData) Add(other ResourceUsageData) ResourceUsageData { 35 return ResourceUsageData{ 36 CPU: r.CPU + other.CPU, 37 Memory: r.Memory + other.Memory, 38 Disk: r.Disk + other.Disk, 39 GPU: r.GPU + other.GPU, 40 } 41 } 42 43 func (r ResourceUsageData) Sub(other ResourceUsageData) ResourceUsageData { 44 usage := ResourceUsageData{ 45 CPU: r.CPU - other.CPU, 46 Memory: r.Memory - other.Memory, 47 Disk: r.Disk - other.Disk, 48 GPU: r.GPU - other.GPU, 49 } 50 51 if r.LessThanEq(other) { 52 log.Warn().Msgf("Subtracting larger resource usage %s from %s. Replacing negative values with zeros", 53 other.String(), r.String()) 54 if other.CPU > r.CPU { 55 usage.CPU = 0 56 } 57 if other.Memory > r.Memory { 58 usage.Memory = 0 59 } 60 if other.Disk > r.Disk { 61 usage.Disk = 0 62 } 63 if other.GPU > r.GPU { 64 usage.GPU = 0 65 } 66 } 67 68 return usage 69 } 70 71 func (r ResourceUsageData) Multi(factor float64) ResourceUsageData { 72 return ResourceUsageData{ 73 CPU: r.CPU * factor, 74 Memory: uint64(float64(r.Memory) * factor), 75 Disk: uint64(float64(r.Disk) * factor), 76 GPU: uint64(float64(r.GPU) * factor), 77 } 78 } 79 80 func (r ResourceUsageData) Intersect(other ResourceUsageData) ResourceUsageData { 81 if r.CPU <= 0 { 82 r.CPU = other.CPU 83 } 84 if r.Memory <= 0 { 85 r.Memory = other.Memory 86 } 87 if r.Disk <= 0 { 88 r.Disk = other.Disk 89 } 90 if r.GPU <= 0 { 91 r.GPU = other.GPU 92 } 93 94 return r 95 } 96 97 func (r ResourceUsageData) Max(other ResourceUsageData) ResourceUsageData { 98 if r.CPU < other.CPU { 99 r.CPU = other.CPU 100 } 101 if r.Memory < other.Memory { 102 r.Memory = other.Memory 103 } 104 if r.Disk < other.Disk { 105 r.Disk = other.Disk 106 } 107 if r.GPU < other.GPU { 108 r.GPU = other.GPU 109 } 110 111 return r 112 } 113 114 func (r ResourceUsageData) LessThanEq(other ResourceUsageData) bool { 115 return r.CPU <= other.CPU && r.Memory <= other.Memory && r.Disk <= other.Disk && r.GPU <= other.GPU 116 } 117 118 func (r ResourceUsageData) IsZero() bool { 119 return r.CPU == 0 && r.Memory == 0 && r.Disk == 0 && r.GPU == 0 120 } 121 122 // return string representation of ResourceUsageData 123 func (r ResourceUsageData) String() string { 124 return fmt.Sprintf("{CPU: %f, Memory: %d, Disk: %d, GPU: %d}", r.CPU, r.Memory, r.Disk, r.GPU) 125 } 126 127 type ResourceUsageProfile struct { 128 // how many resources does the job want to consume 129 Job ResourceUsageData `json:"Job,omitempty"` 130 // how many resources is the system currently using 131 SystemUsing ResourceUsageData `json:"SystemUsing,omitempty"` 132 // what is the total amount of resources available to the system 133 SystemTotal ResourceUsageData `json:"SystemTotal,omitempty"` 134 }