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  }