Skip to content

Commit

Permalink
feat: compute core ratio for local regressor (#1743)
Browse files Browse the repository at this point in the history
Signed-off-by: Sunyanan Choochotkaew <[email protected]>
  • Loading branch information
sunya-ch authored Aug 28, 2024
1 parent 79cace5 commit aa822ee
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 32 deletions.
2 changes: 1 addition & 1 deletion pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ var _ = Describe("Test Configuration", func() {
It("Test machine spec generation and read", func() {
tmpPath := "./test_spec"
// generate spec
spec := generateSpec()
spec := GenerateSpec()
Expect(spec).NotTo(BeNil())
err := spec.saveToFile(tmpPath)
Expect(err).To(BeNil())
Expand Down
4 changes: 2 additions & 2 deletions pkg/config/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func roundToNearestHundred(value float64) int {
return int(math.Round(value/100) * 100)
}

func generateSpec() *MachineSpec {
func GenerateSpec() *MachineSpec {
spec := &MachineSpec{}

cpus, err := cpu.Info()
Expand Down Expand Up @@ -134,7 +134,7 @@ func getDefaultMachineSpec() *MachineSpec {
klog.Errorf("failed to read default spec from %s: %v", DefaultMachineSpecFilePath, err)
}
}
return generateSpec()
return GenerateSpec()
}

func readMachineSpec(path string) (*MachineSpec, error) {
Expand Down
27 changes: 9 additions & 18 deletions pkg/model/estimator/local/regressor/model_weights.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package regressor
import (
"errors"
"fmt"

"github.com/sustainable-computing-io/kepler/pkg/config"
)

var (
Expand Down Expand Up @@ -95,25 +97,14 @@ type NormalizedNumericalFeature struct {
Weight float64 `json:"weight,omitempty"`
}

// TODO: remove when PR #1684 merge
type MachineSpec struct {
Vendor string `json:"vendor"`
Processor string `json:"processor"`
Cores int `json:"cores"`
Chips int `json:"chips"`
Memory int `json:"memory"`
Frequency int `json:"frequency"`
ThreadsPerCore int `json:"threads_per_core"`
}

type ComponentModelWeights struct {
ModelName string `json:"model_name,omitempty"`
ModelMachineSpec *MachineSpec `json:"machine_spec,omitempty"`
Platform *ModelWeights `json:"platform,omitempty"`
Core *ModelWeights `json:"core,omitempty"`
Uncore *ModelWeights `json:"uncore,omitempty"`
Package *ModelWeights `json:"package,omitempty"`
DRAM *ModelWeights `json:"dram,omitempty"`
ModelName string `json:"model_name,omitempty"`
ModelMachineSpec *config.MachineSpec `json:"machine_spec,omitempty"`
Platform *ModelWeights `json:"platform,omitempty"`
Core *ModelWeights `json:"core,omitempty"`
Uncore *ModelWeights `json:"uncore,omitempty"`
Package *ModelWeights `json:"package,omitempty"`
DRAM *ModelWeights `json:"dram,omitempty"`
}

func (w ComponentModelWeights) String() string {
Expand Down
27 changes: 20 additions & 7 deletions pkg/model/estimator/local/regressor/regressor.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,12 @@ type Regressor struct {
// xidx represents the instance slide window position, where an instance can be process/process/pod/node
xidx int

enabled bool
modelWeight *ComponentModelWeights
coreRatio float64
modelPredictors map[string]Predictor
*config.MachineSpec
enabled bool
modelWeight *ComponentModelWeights
coreRatio float64
modelPredictors map[string]Predictor
RequestMachineSpec *config.MachineSpec
DiscoveredMachineSpec *config.MachineSpec
}

// Start returns nil if model weight is obtainable
Expand Down Expand Up @@ -153,7 +154,7 @@ func (r *Regressor) getWeightFromServer() (*ComponentModelWeights, error) {
TrainerName: r.TrainerName,
SelectFilter: r.SelectFilter,
Weight: true,
MachineSpec: *r.MachineSpec,
MachineSpec: *r.RequestMachineSpec,
}
modelRequestJSON, err := json.Marshal(modelRequest)
if err != nil {
Expand Down Expand Up @@ -187,7 +188,7 @@ func (r *Regressor) getWeightFromServer() (*ComponentModelWeights, error) {
if weightResponse.ModelName != "" {
klog.V(3).Infof("Using weights trained by %s", weightResponse.ModelName)
}
// TODO: set r.coreRatio from discover spec/model machine spec based on PR #1684
r.updateCoreRatio(weightResponse.ModelMachineSpec)
return &weightResponse, nil
}

Expand All @@ -209,6 +210,7 @@ func (r *Regressor) loadWeightFromURLorLocal() (*ComponentModelWeights, error) {
if err != nil {
return nil, fmt.Errorf("model unmarshal error: %v (%s)", err, string(body))
}
r.updateCoreRatio(content.ModelMachineSpec)
return &content, nil
}

Expand Down Expand Up @@ -317,6 +319,17 @@ func (r *Regressor) GetComponentsPower(isIdlePower bool) ([]source.NodeComponent
return nodeComponentsPower, nil
}

// updateCoreRatio sets coreRatio attribute as a ratio of the discovered number of cores over the cores of machine used for training a model
func (r *Regressor) updateCoreRatio(mSpec *config.MachineSpec) {
if mSpec == nil || r.DiscoveredMachineSpec == nil {
return
}
if r.DiscoveredMachineSpec.Cores > 0 && mSpec.Cores >= r.DiscoveredMachineSpec.Cores {
r.coreRatio = float64(r.DiscoveredMachineSpec.Cores) / float64(mSpec.Cores)
klog.Infof("Update core ratio to %.2f for computing %s idle power", r.coreRatio, r.EnergySource)
}
}

// GetComponentsPower returns GPU Power in Watts associated to each each process
func (r *Regressor) GetGPUPower(isIdlePower bool) ([]uint64, error) {
return []uint64{}, fmt.Errorf("current power model does not support GPUs")
Expand Down
47 changes: 45 additions & 2 deletions pkg/model/estimator/local/regressor/regressor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,19 @@ var (
SampleDramNumbericalVars = map[string]NormalizedNumericalFeature{
"cache_miss": {Weight: 1.0, Scale: 2},
}
DummyWeightHandler = http.HandlerFunc(genHandlerFunc([]float64{}))
DummyWeightHandler = http.HandlerFunc(genHandlerFunc([]float64{}))
DummyModelName = "dummy"
ModelCores = config.GenerateSpec().Cores
ExpectedAbsPowerFromDummyWeightHandler = 2500
ExpectedIdlePowerFromDummyWeightHandler = 2000
)

func GenPlatformModelWeights(curveFitWeights []float64) ComponentModelWeights {
return ComponentModelWeights{
ModelName: DummyModelName,
ModelMachineSpec: &config.MachineSpec{
Cores: ModelCores,
},
Platform: genWeights(SampleCoreNumericalVars, curveFitWeights),
}
}
Expand Down Expand Up @@ -127,7 +135,8 @@ func genRegressor(outputType types.ModelOutputType, energySource, modelServerEnd
ModelWeightsURL: modelWeightsURL,
ModelWeightsFilepath: modelWeightFilepath,
TrainerName: trainerName,
MachineSpec: config.GetMachineSpec(),
RequestMachineSpec: config.GetMachineSpec(),
DiscoveredMachineSpec: config.GenerateSpec(),
}
}

Expand Down Expand Up @@ -274,4 +283,38 @@ var _ = Describe("Test Regressor Weight Unit (default trainer)", func() {
Expect(err).NotTo(HaveOccurred())
})
})

Context("with core ratio", Ordered, func() {
DescribeTable("Test core ratio computation", func(discoveredCore, modelCores int, expectedCoreRatio float64) {
ModelCores = modelCores
testServer := httptest.NewServer(DummyWeightHandler)
modelWeightFilepath := config.GetDefaultPowerModelURL(types.DynPower.String(), types.PlatformEnergySource)
r := genRegressor(types.DynPower, types.PlatformEnergySource, testServer.URL, "", modelWeightFilepath, "")
r.DiscoveredMachineSpec = &config.MachineSpec{
Cores: discoveredCore,
}
err := r.Start()
Expect(err).To(BeNil())
r.ResetSampleIdx()
for _, processFeatureValues := range processFeatureValues {
r.AddProcessFeatureValues(processFeatureValues) // add samples to the power model
}
powers, err := r.GetPlatformPower(false)
Expect(err).NotTo(HaveOccurred())
Expect(len(powers)).Should(Equal(len(processFeatureValues)))
// TODO: verify if the power makes sense
Expect(powers[0]).Should(BeEquivalentTo(ExpectedAbsPowerFromDummyWeightHandler))
idlePowers, err := r.GetPlatformPower(true)
Expect(err).NotTo(HaveOccurred())
Expect(len(idlePowers)).Should(Equal(len(processFeatureValues)))
expectedIdlePower := uint64(float64(ExpectedIdlePowerFromDummyWeightHandler) * expectedCoreRatio)
Expect(idlePowers[0]).Should(BeEquivalentTo(expectedIdlePower))
},
Entry("equal core", 16, 16, 1.0),
Entry("VM core ratio 0.25)", 4, 16, 0.25),
Entry("VM core ratio 4)", 16, 4, 1.0),
Entry("invalid discovered core", 0, 16, 1.0),
Entry("invalid model core", 16, 0, 1.0),
)
})
})
5 changes: 3 additions & 2 deletions pkg/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,15 @@ func createPowerModelEstimator(modelConfig *types.ModelConfig) (PowerModelInterf
FloatFeatureNames: featuresNames,
SystemMetaDataFeatureNames: modelConfig.SystemMetaDataFeatureNames,
SystemMetaDataFeatureValues: modelConfig.SystemMetaDataFeatureValues,
MachineSpec: config.GetMachineSpec(),
RequestMachineSpec: config.GetMachineSpec(),
DiscoveredMachineSpec: config.GenerateSpec(),
}
err := model.Start()
if err != nil {
return nil, err
}
klog.V(3).Infof("Using Power Model %s", modelConfig.ModelOutputType.String())
klog.Infof("Machine Spec: %v", model.MachineSpec)
klog.Infof("Requesting for Machine Spec: %v", model.RequestMachineSpec)
return model, nil

case types.EstimatorSidecar:
Expand Down

0 comments on commit aa822ee

Please sign in to comment.