1
0
mirror of https://github.com/newnius/YAO-scheduler.git synced 2025-12-16 00:26:43 +00:00

update GA

This commit is contained in:
2020-05-27 18:04:05 +08:00
parent bbc8ad2317
commit d35e0a57d6
9 changed files with 402 additions and 371 deletions

View File

@@ -2,28 +2,25 @@ package main
import (
"strconv"
"math/rand"
"time"
log "github.com/sirupsen/logrus"
"github.com/MaxHalford/eaopt"
"math"
"testing"
)
func TgenerateCase() ([]NodeStatus, []Task) {
numTask := 2
numTask := 4
var nodes []NodeStatus
var tasks []Task
for i := 0; i < numTask; i++ {
for i := 0; i < numTask*3; i++ {
node := NodeStatus{ClientID: strconv.Itoa(i), Rack: "Rack-" + strconv.Itoa(i%40), Domain: "Domain-" + strconv.Itoa(i%4)}
node.NumCPU = 24
node.UtilCPU = 2.0
node.MemTotal = 188
node.MemAvailable = 20
node.TotalBW = 100
cnt := 1
cnt := 4
//cnt := rand.Intn(3) + 1
for i := 0; i < cnt; i++ {
node.Status = append(node.Status, GPUStatus{MemoryTotal: 11439, MemoryAllocated: 0, UUID: node.ClientID + "-" + strconv.Itoa(i)})
@@ -32,7 +29,7 @@ func TgenerateCase() ([]NodeStatus, []Task) {
}
for i := 0; i < numTask; i++ {
isPS := false
if i%4 == 0 {
if i < numTask/4 {
isPS = true
}
task := Task{Name: "task-" + strconv.Itoa(i), IsPS: isPS}
@@ -46,144 +43,29 @@ func TgenerateCase() ([]NodeStatus, []Task) {
}
func TestBestFit(t *testing.T) {
return
nodes, tasks := TgenerateCase()
for _, node := range nodes {
log.Info(node)
}
s := time.Now()
allocation := fastBestFit(nodes, tasks)
allocation := InstanceOfAllocator().fastBestFit(nodes, tasks)
log.Println(time.Since(s))
log.Println(allocation)
}
func TestGA(t *testing.T) {
return
nodes, tasks := TgenerateCase()
// Instantiate a GA with a GAConfig
var ga, err = eaopt.NewDefaultGAConfig().NewGA()
if err != nil {
log.Println(err)
return
}
allocation := InstanceOfAllocator().GA(nodes, tasks, true)
// Set the number of generations to run for
ga.NGenerations = math.MaxInt32
ga.NPops = 1
ga.PopSize = 30 + uint(len(tasks)/2)
log.Info(allocation.TasksOnNode)
log.Info(allocation.Nodes)
// Add a custom print function to track progress
ga.Callback = func(ga *eaopt.GA) {
log.Printf("Best fitness at generation %d: %f\n", ga.Generations, ga.HallOfFame[0].Fitness)
}
allocation = InstanceOfAllocator().fastBestFit(nodes, tasks)
bestFitness := math.MaxFloat64
count := 0
ts := time.Now()
ga.EarlyStop = func(ga *eaopt.GA) bool {
gap := math.Abs(ga.HallOfFame[0].Fitness - bestFitness)
if gap <= 0.000001 || ga.HallOfFame[0].Fitness >= bestFitness {
if count >= 30 || time.Since(ts) > time.Second*30 {
log.Println("Early Stop")
return true
} else {
count++
}
} else {
bestFitness = ga.HallOfFame[0].Fitness
count = 1
}
return false
}
var f = func(rng *rand.Rand) eaopt.Genome {
allocation := Allocation{TasksOnNode: map[string][]Task{}, Nodes: map[string]NodeStatus{}, Flags: map[string]bool{"valid": true}}
//log.Println(nodes)
var nodesT []NodeStatus
for _, node := range nodes {
nodesT = append(nodesT, node.Copy())
}
//nodesT[0].Status[0].MemoryAllocated = 100
//log.Println(nodes[0].Status[0].MemoryAllocated)
//log.Println(&nodesT[0])
//log.Println(&nodes[0])
for _, node := range nodesT {
allocation.Nodes[node.ClientID] = node
}
for _, task := range tasks {
allocation.Tasks = append(allocation.Tasks, task)
}
/* shuffle */
for n := len(tasks); n > 0; n-- {
randIndex := rng.Intn(n)
allocation.Tasks[n-1], allocation.Tasks[randIndex] = allocation.Tasks[randIndex], allocation.Tasks[n-1]
}
/* pick nodes */
for _, node := range nodesT {
allocation.Nodes[node.ClientID] = node
allocation.NodeIDs = append(allocation.NodeIDs, node.ClientID)
}
t := rng.Int() % 10
if t == 0 {
/* best-fit */
ts := time.Now()
allocation.TasksOnNode = fastBestFit(nodesT, tasks).TasksOnNode
log.Println(time.Since(ts))
//fmt.Println("Best Fit")
} else if t%2 == 0 {
/* first-fit */
for _, task := range tasks {
if nodeID, ok := randomFit(allocation, task); ok {
allocation.TasksOnNode[nodeID] = append(allocation.TasksOnNode[nodeID], task)
for i := range allocation.Nodes[nodeID].Status {
if allocation.Nodes[nodeID].Status[i].MemoryAllocated == 0 {
allocation.Nodes[nodeID].Status[i].MemoryAllocated += task.MemoryGPU
break
}
}
} else {
allocation.Flags["valid"] = false
}
}
} else {
/* random-fit */
for _, task := range tasks {
if nodeID, ok := randomFit(allocation, task); ok {
allocation.TasksOnNode[nodeID] = append(allocation.TasksOnNode[nodeID], task)
for i := range allocation.Nodes[nodeID].Status {
if allocation.Nodes[nodeID].Status[i].MemoryAllocated == 0 {
allocation.Nodes[nodeID].Status[i].MemoryAllocated += task.MemoryGPU
break
}
}
} else {
allocation.Flags["valid"] = false
}
}
}
//fmt.Println(evaluatue(allocation))
//fmt.Println(allocation)
return allocation
}
// Find the minimum
err = ga.Minimize(f)
log.Println(time.Since(ts))
log.Println(ga.HallOfFame[0].Genome.(Allocation).TasksOnNode)
//log.Println(ga.HallOfFame[0].Genome.(Allocation).Flags)
//log.Println(ga.HallOfFame[0].Genome.(Allocation).Nodes)
if err != nil {
log.Println(err)
return
}
InstanceOfResourcePool().init(Configuration{})
allocatedNodes := InstanceOfResourcePool().acquireResource(Job{Tasks: tasks})
log.Info(allocatedNodes)
}