Skip to content

Commit bbe56b6

Browse files
committed
Adds cost in the ILP offloading policy objective function
1 parent c1f6ab8 commit bbe56b6

3 files changed

Lines changed: 65 additions & 1 deletion

File tree

internal/config/config.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package config
33
import (
44
"log"
55
"path/filepath"
6+
"strconv"
67

78
"github.com/spf13/viper"
89
)
@@ -50,6 +51,33 @@ func GetBool(key string, defaultValue bool) bool {
5051
}
5152
}
5253

54+
func GetStringMapFloat64(key string) map[string]float64 {
55+
raw := viper.GetStringMap(key)
56+
if raw == nil {
57+
return make(map[string]float64)
58+
}
59+
60+
m := make(map[string]float64)
61+
for k, v := range raw {
62+
switch vTyped := v.(type) {
63+
case float64:
64+
m[k] = vTyped
65+
case string:
66+
vfloat, err := strconv.ParseFloat(vTyped, 64)
67+
if err != nil {
68+
log.Printf("Invaid float value for key %s: %v", k, v)
69+
continue
70+
}
71+
m[k] = vfloat
72+
default:
73+
log.Printf("Invaid value for key %s: %v", k, v)
74+
continue
75+
}
76+
}
77+
78+
return m
79+
}
80+
5381
// ReadConfiguration reads a configuration file stored in one of the predefined paths.
5482
func ReadConfiguration(fileName string) {
5583
// paths where the config file can be placed

internal/config/keys.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ const OFFLOADING_POLICY_ILP_OPTIMIZER_HOST = "offloading.policy.ilp.host"
9191
// Number of times a scheduling plan can be reused before being re-computed
9292
const OFFLOADING_POLICY_ILP_PLACEMENT_TTL = "offloading.policy.ilp.placement.ttl"
9393

94+
// Monetary computation cost per region (Map: string -> float)
95+
const OFFLOADING_POLICY_ILP_REGION_COST = "offloading.policy.ilp.region.cost"
96+
97+
// Weight of objective terms in the ILP offloading policy
98+
const OFFLOADING_POLICY_ILP_OBJ_WEIGHT_VIOLATIONS = "offloading.policy.ilp.obj.violations"
99+
const OFFLOADING_POLICY_ILP_OBJ_WEIGHT_DATA_TRANSFERS = "offloading.policy.ilp.obj.data"
100+
const OFFLOADING_POLICY_ILP_OBJ_WEIGHT_COST = "offloading.policy.ilp.obj.cost"
101+
94102
// Estimated bandwidth between the current node and the data store
95103
const OFFLOADING_POLICY_NODE_TO_DATA_STORE_BANDWIDTH = "offloading.policy.node2datastore.bandwidth"
96104

internal/workflow/ilp_offloading_policy.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"log"
99
"net/http"
1010
"strconv"
11+
"strings"
1112
"time"
1213

1314
"github.com/serverledge-faas/serverledge/internal/config"
@@ -34,7 +35,8 @@ type ilpParams struct {
3435
OutputSize map[string]float64 `json:"output_size"` // Output size per task
3536
InputSize float64 `json:"input_size"` // Input data size
3637

37-
Alpha float64 `json:"alpha"` // Weighting factor
38+
ObjWeights []float64 `json:"obj_weights"` // Objective terms weights
39+
Cost map[string]float64 `json:"cost"` // Computation cost
3840
NodeLabels map[string][]string `json:"node_labels"` // Labels per node
3941
TaskLabels map[string][]string `json:"task_labels"` // Labels per task
4042

@@ -49,12 +51,14 @@ func initParams() ilpParams {
4951
ExecTime: make(map[string]float64),
5052
OutputSize: make(map[string]float64),
5153
NodeMemory: make(map[string]float64),
54+
Cost: make(map[string]float64),
5255
TaskMemory: make(map[string]float64),
5356
NodeLabels: make(map[string][]string),
5457
TaskLabels: make(map[string][]string),
5558
DSBandwidth: make(map[string]float64),
5659
DSLatency: make(map[string]float64),
5760
NodeLatency: make(map[string]float64),
61+
ObjWeights: []float64{0.33, 0.33, 0.33},
5862
}
5963
}
6064

@@ -201,6 +205,19 @@ func (policy *IlpOffloadingPolicy) Evaluate(r *Request, p *Progress) (Offloading
201205
params.HandlingNode = LOCAL
202206
params.NodeMemory[LOCAL] = (float64)(node.Resources.AvailableMemMB)
203207

208+
wViolations := config.GetFloat(config.OFFLOADING_POLICY_ILP_OBJ_WEIGHT_VIOLATIONS, 0.33)
209+
wDataTransfers := config.GetFloat(config.OFFLOADING_POLICY_ILP_OBJ_WEIGHT_DATA_TRANSFERS, 0.33)
210+
wCost := config.GetFloat(config.OFFLOADING_POLICY_ILP_OBJ_WEIGHT_COST, 0.33)
211+
params.ObjWeights = []float64{wViolations, wDataTransfers, wCost}
212+
213+
regionCost := config.GetStringMapFloat64(config.OFFLOADING_POLICY_ILP_REGION_COST)
214+
// TODO: ToLower() is needed because viper (used to parse configuration files) is not case sensitive
215+
localCost, ok := regionCost[strings.ToLower(registration.SelfRegistration.Area)]
216+
if !ok {
217+
localCost = 0.0
218+
}
219+
params.Cost[LOCAL] = localCost
220+
204221
// TODO: introduce task and node labels
205222

206223
// Add available Edge peers
@@ -210,6 +227,9 @@ func (policy *IlpOffloadingPolicy) Evaluate(r *Request, p *Progress) (Offloading
210227
if v.AvailableMemMB > 0 && v.AvailableCPUs > 0 {
211228
params.EdgeNodes = append(params.EdgeNodes, k)
212229
params.NodeMemory[k] = float64(v.AvailableMemMB)
230+
231+
// Cost (assuming that Edge nodes are all in the same area)
232+
params.Cost[k] = localCost
213233
}
214234
}
215235
}
@@ -239,6 +259,14 @@ func (policy *IlpOffloadingPolicy) Evaluate(r *Request, p *Progress) (Offloading
239259
}
240260

241261
if len(params.CloudNodes) > 0 {
262+
// Cost
263+
// TODO: ToLower() is needed because viper (used to parse configuration files) is not case sensitive
264+
remoteCost, ok := regionCost[strings.ToLower(registration.GetRemoteOffloadingTarget().Area)]
265+
if !ok {
266+
remoteCost = 0.0
267+
}
268+
params.Cost[CLOUD] = remoteCost
269+
242270
// Distances to Cloud and Data Store
243271
distanceToCloud := registration.GetRemoteOffloadingTargetLatencyMs() / 1000.0
244272
for _, n := range params.EdgeNodes {

0 commit comments

Comments
 (0)