mirror of
https://github.com/newnius/YAO-scheduler.git
synced 2025-06-06 22:01:55 +00:00
add random, spread, pack strategy
This commit is contained in:
parent
08335ab6cc
commit
eb4e60a97a
125
src/allocator.go
125
src/allocator.go
@ -30,11 +30,20 @@ func (allocator *Allocator) init(conf Configuration) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (allocator *Allocator) updateStrategy(strategy string) bool {
|
func (allocator *Allocator) updateStrategy(strategy string) bool {
|
||||||
if strategy == "bestfit" || strategy == "ga" || strategy == "mixed" {
|
validStrategies := map[string]bool{
|
||||||
|
"bestfit": true,
|
||||||
|
"ga": true,
|
||||||
|
"mixed": true,
|
||||||
|
"random": true,
|
||||||
|
"spread": true,
|
||||||
|
"pack": true,
|
||||||
|
}
|
||||||
|
if _, ok := validStrategies[strategy]; ok {
|
||||||
allocator.allocationStrategy = strategy
|
allocator.allocationStrategy = strategy
|
||||||
log.Info("Allocator strategy switched to ", strategy)
|
log.Info("Allocator strategy switched to ", strategy)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
log.Warn("Invalid Allocator strategy ", strategy)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +52,15 @@ func (allocator *Allocator) allocate(nodes []NodeStatus, tasks []Task) Allocatio
|
|||||||
//log.Info(tasks)
|
//log.Info(tasks)
|
||||||
var allocation Allocation
|
var allocation Allocation
|
||||||
switch allocator.allocationStrategy {
|
switch allocator.allocationStrategy {
|
||||||
|
case "random":
|
||||||
|
allocation = allocator.randomFitStrategy(nodes, tasks)
|
||||||
|
break
|
||||||
|
case "spread":
|
||||||
|
allocation = allocator.spreadStrategy(nodes, tasks, false)
|
||||||
|
break
|
||||||
|
case "pack":
|
||||||
|
allocation = allocator.spreadStrategy(nodes, tasks, true)
|
||||||
|
break
|
||||||
case "bestfit":
|
case "bestfit":
|
||||||
allocation = allocator.fastBestFit(nodes, tasks)
|
allocation = allocator.fastBestFit(nodes, tasks)
|
||||||
break
|
break
|
||||||
@ -66,6 +84,111 @@ func (allocator *Allocator) allocate(nodes []NodeStatus, tasks []Task) Allocatio
|
|||||||
return allocation
|
return allocation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (allocator *Allocator) randomFitStrategy(nodes []NodeStatus, tasks []Task) Allocation {
|
||||||
|
allocation := Allocation{TasksOnNode: map[string][]Task{}, Nodes: map[string]NodeStatus{}, Flags: map[string]bool{"valid": true}}
|
||||||
|
var nodesT []NodeStatus
|
||||||
|
for _, node := range nodes {
|
||||||
|
/* copy in order not to modify original data */
|
||||||
|
nodesT = append(nodesT, node.Copy())
|
||||||
|
}
|
||||||
|
for _, node := range nodesT {
|
||||||
|
allocation.Nodes[node.ClientID] = node
|
||||||
|
}
|
||||||
|
for _, task := range tasks {
|
||||||
|
allocation.Tasks = append(allocation.Tasks, task)
|
||||||
|
}
|
||||||
|
for _, node := range nodesT {
|
||||||
|
allocation.Nodes[node.ClientID] = node
|
||||||
|
allocation.NodeIDs = append(allocation.NodeIDs, node.ClientID)
|
||||||
|
}
|
||||||
|
/* random-fit */
|
||||||
|
for _, task := range tasks {
|
||||||
|
if nodeID, ok := randomFit(allocation, task); ok {
|
||||||
|
allocation.TasksOnNode[nodeID] = append(allocation.TasksOnNode[nodeID], task)
|
||||||
|
cnt := task.NumberGPU
|
||||||
|
for i := range allocation.Nodes[nodeID].Status {
|
||||||
|
if allocation.Nodes[nodeID].Status[i].MemoryAllocated == 0 {
|
||||||
|
allocation.Nodes[nodeID].Status[i].MemoryAllocated += task.MemoryGPU
|
||||||
|
cnt--
|
||||||
|
}
|
||||||
|
if cnt == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
allocation.Flags["valid"] = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allocation
|
||||||
|
}
|
||||||
|
|
||||||
|
func (allocator *Allocator) spreadStrategy(nodes []NodeStatus, tasks []Task, isPack bool) Allocation {
|
||||||
|
allocation := Allocation{TasksOnNode: map[string][]Task{}, Nodes: map[string]NodeStatus{}, Flags: map[string]bool{"valid": true}}
|
||||||
|
var nodesT []NodeStatus
|
||||||
|
for _, node := range nodes {
|
||||||
|
/* copy in order not to modify original data */
|
||||||
|
nodesT = append(nodesT, node.Copy())
|
||||||
|
}
|
||||||
|
for _, node := range nodesT {
|
||||||
|
allocation.Nodes[node.ClientID] = node
|
||||||
|
}
|
||||||
|
for _, task := range tasks {
|
||||||
|
allocation.Tasks = append(allocation.Tasks, task)
|
||||||
|
}
|
||||||
|
for _, node := range nodesT {
|
||||||
|
allocation.Nodes[node.ClientID] = node
|
||||||
|
allocation.NodeIDs = append(allocation.NodeIDs, node.ClientID)
|
||||||
|
}
|
||||||
|
for _, task := range tasks {
|
||||||
|
if nodeID, ok := allocator.pickNode(allocation, task, isPack); ok {
|
||||||
|
allocation.TasksOnNode[nodeID] = append(allocation.TasksOnNode[nodeID], task)
|
||||||
|
cnt := task.NumberGPU
|
||||||
|
for i := range allocation.Nodes[nodeID].Status {
|
||||||
|
if allocation.Nodes[nodeID].Status[i].MemoryAllocated == 0 {
|
||||||
|
allocation.Nodes[nodeID].Status[i].MemoryAllocated += task.MemoryGPU
|
||||||
|
cnt--
|
||||||
|
}
|
||||||
|
if cnt == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
allocation.Flags["valid"] = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allocation
|
||||||
|
}
|
||||||
|
|
||||||
|
func (allocator *Allocator) pickNode(allocation Allocation, task Task, isPack bool) (string, bool) {
|
||||||
|
flag := false
|
||||||
|
bestNodeID := ""
|
||||||
|
bestUtil := math.MaxFloat64
|
||||||
|
for _, nodeID := range allocation.NodeIDs {
|
||||||
|
if _, ok := allocation.Nodes[nodeID]; !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
available := 0
|
||||||
|
total := 0
|
||||||
|
for _, gpu := range allocation.Nodes[nodeID].Status {
|
||||||
|
if gpu.MemoryAllocated == 0 {
|
||||||
|
available += 1
|
||||||
|
}
|
||||||
|
total += 1
|
||||||
|
}
|
||||||
|
util := float64(available) / float64(total)
|
||||||
|
if task.NumberGPU <= available {
|
||||||
|
if bestNodeID == "" || (!isPack && util > bestUtil) || (isPack && util < bestUtil) {
|
||||||
|
flag = true
|
||||||
|
bestNodeID = nodeID
|
||||||
|
bestUtil = util
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bestNodeID, flag
|
||||||
|
}
|
||||||
|
|
||||||
func (allocator *Allocator) fastBestFit(nodes []NodeStatus, tasks []Task) Allocation {
|
func (allocator *Allocator) fastBestFit(nodes []NodeStatus, tasks []Task) Allocation {
|
||||||
eva := Evaluator{}
|
eva := Evaluator{}
|
||||||
eva.init(nodes, tasks)
|
eva.init(nodes, tasks)
|
||||||
|
@ -236,6 +236,7 @@ func (pool *ResourcePool) saveStatusHistory() {
|
|||||||
/* waiting for nodes */
|
/* waiting for nodes */
|
||||||
time.Sleep(time.Second * 30)
|
time.Sleep(time.Second * 30)
|
||||||
for {
|
for {
|
||||||
|
log.Debug("pool.saveStatusHistory")
|
||||||
summary := PoolStatus{}
|
summary := PoolStatus{}
|
||||||
|
|
||||||
UtilCPU := 0.0
|
UtilCPU := 0.0
|
||||||
|
Loading…
Reference in New Issue
Block a user