the observation that is to be considered for the classification of a task can now be given as a function that takes the task and returns the observations as a slice of float64. Retrofitted the other functions in taskUtils to make use of this feature.

This commit is contained in:
Pradyumna Kaushik 2017-02-25 19:57:01 -05:00
parent e54697b0dc
commit 74eb616a72

View file

@ -15,10 +15,10 @@ type TaskCluster struct {
// Classification of Tasks using KMeans clustering using the watts consumption observations // Classification of Tasks using KMeans clustering using the watts consumption observations
type TasksToClassify []Task type TasksToClassify []Task
func (tc TasksToClassify) ClassifyTasks(numberOfClusters int) []TaskCluster { func (tc TasksToClassify) ClassifyTasks(numberOfClusters int, taskObservation func(task Task) []float64) []TaskCluster {
clusters := make(map[int][]Task) clusters := make(map[int][]Task)
observations := getObservations(tc) observations := getObservations(tc, taskObservation)
// TODO: Make the number of rounds configurable based on the size of the workload // TODO: Make the number rounds configurable based on the size of the workload
if trained, centroids := gokmeans.Train(observations, numberOfClusters, 100); trained { if trained, centroids := gokmeans.Train(observations, numberOfClusters, 100); trained {
for i := 0; i < len(observations); i++ { for i := 0; i < len(observations); i++ {
observation := observations[i] observation := observations[i]
@ -30,47 +30,32 @@ func (tc TasksToClassify) ClassifyTasks(numberOfClusters int) []TaskCluster {
} }
} }
} }
return labelAndOrder(clusters, numberOfClusters) return labelAndOrder(clusters, numberOfClusters, taskObservation)
} }
// The watts consumption observations are taken into consideration. // record observations
func getObservations(tasks []Task) []gokmeans.Node { func getObservations(tasks []Task, taskObservation func(task Task) []float64) []gokmeans.Node {
observations := []gokmeans.Node{} observations := []gokmeans.Node{}
for i := 0; i < len(tasks); i++ { for i := 0; i < len(tasks); i++ {
task := tasks[i] observations = append(observations, taskObservation(tasks[i]))
// If observations present for the power-classes, then using it
if task.ClassToWatts != nil {
observation := gokmeans.Node{}
for _, watts := range task.ClassToWatts {
observation = append(observation, watts)
}
observations = append(observations, observation)
} else {
// Using the watts attribute alone
observations = append(observations, gokmeans.Node{task.Watts})
}
} }
return observations return observations
} }
// Size tasks based on the power consumption // Size tasks based on the power consumption
// TODO: Size the cluster in a better way just taking an aggregate of the watts resource requirement. // TODO: Size the cluster in a better way just taking an aggregate of the watts resource requirement.
func clusterSize(tasks []Task) float64 { func clusterSize(tasks []Task, taskObservation func(task Task) []float64) float64 {
size := 0.0 size := 0.0
for _, task := range tasks { for _, task := range tasks {
if task.ClassToWatts != nil { for _, observation := range taskObservation(task) {
for _, powerClassWatts := range task.ClassToWatts { size += observation
size += powerClassWatts
}
} else {
size += task.Watts
} }
} }
return size return size
} }
// Order clusters in increasing order of task heaviness // Order clusters in increasing order of task heaviness
func labelAndOrder(clusters map[int][]Task, numberOfClusters int) []TaskCluster { func labelAndOrder(clusters map[int][]Task, numberOfClusters int, taskObservation func(task Task) []float64) []TaskCluster {
// Determine the position of the cluster in the ordered list of clusters // Determine the position of the cluster in the ordered list of clusters
sizedClusters := []TaskCluster{} sizedClusters := []TaskCluster{}
@ -85,11 +70,11 @@ func labelAndOrder(clusters map[int][]Task, numberOfClusters int) []TaskCluster
for i := 0; i < numberOfClusters-1; i++ { for i := 0; i < numberOfClusters-1; i++ {
// Sizing the current cluster // Sizing the current cluster
sizeI := clusterSize(clusters[i]) sizeI := clusterSize(clusters[i], taskObservation)
// Comparing with the other clusters // Comparing with the other clusters
for j := i + 1; j < numberOfClusters; j++ { for j := i + 1; j < numberOfClusters; j++ {
sizeJ := clusterSize(clusters[j]) sizeJ := clusterSize(clusters[j], taskObservation)
if sizeI > sizeJ { if sizeI > sizeJ {
sizedClusters[i].SizeScore++ sizedClusters[i].SizeScore++
} else { } else {