Commit 0d415192 by Tomasz Ciesielczyk

power usage prediction update, pcp algorithm API, algorithm result saving…

power usage prediction update, pcp algorithm API, algorithm result saving function, solver bug fix, removed redundant power usage check in algorithm
parent 1268df7f
......@@ -5,8 +5,10 @@ import psnc.m2dc.rtm.dao.DAO
import psnc.m2dc.rtm.model.rest.NodeUtil
import psnc.m2dc.rtm.model.rpm.Resource
import psnc.m2dc.rtm.properties.RTMProperties
import psnc.m2dc.rtm.properties.keys.Keys
import psnc.m2dc.rtm.rpm.RPMApi
import psnc.m2dc.rtm.utils.logError
import psnc.m2dc.rtm.utils.logWarn
import psnc.m2dc.rtm.utils.printConsole
import psnc.m2dc.rtm.utils.toJson
import java.nio.file.Paths
......@@ -19,7 +21,13 @@ import java.util.*
abstract class RTMAlgorithm(currentState: CurrentState) {
fun saveState() {
this.state.toJson(RTMProperties.parsePath("${RTMProperties.basePath}/${this::class.java.simpleName}_${Date().time}.dmp").toString())
if (Keys.RTM.dump_current_state.getBoolean()) {
nextDumpIndex?.let {idx->
this.state.toJson(RTMProperties.parsePath("${RTMProperties.basePath}/${this::class.java.simpleName}_$idx.dmp").toString())
}?: logWarn("invalid dump dump_current_state_count: ${ Keys.RTM.dump_current_state_count}")
}
}
......@@ -27,6 +35,24 @@ abstract class RTMAlgorithm(currentState: CurrentState) {
private set
companion object {
private val lock = Any()
private var currentDumpIndex = -1
val nextDumpIndex: Long?
get() = synchronized(lock) {
if (Keys.RTM.dump_current_state_count.get() == -1) {
Date().time
} else {
val count = Keys.RTM.dump_current_state_count.get()
if (count == 0)
null
else {
currentDumpIndex = (currentDumpIndex + 1) % count
currentDumpIndex.toLong()
}
}
}
val log = LoggerFactory.getLogger(RTMAlgorithm::class.java.name)!!
private val cache = Array<PowerSettingsCacheRow>(10, { PowerSettingsCacheRow("") })
private var idx = 0
......@@ -57,38 +83,73 @@ abstract class RTMAlgorithm(currentState: CurrentState) {
}
private fun getSuspendSavings(
powerUsage: HashMap<String, Double> = RPMApi.instance().getPowerUsageList())
: Double {
// private fun getSuspendSavings(
// powerUsage: HashMap<String, Double> = RPMApi.instance().getPowerUsageList())
// : Double {
// var sum = 0.0
// powerUsage.filter {
// this.state.canSuspend(it.key)
// }.forEach { resourceId, power ->
// // val node = value.first
// val typeId = DAO.Resource.getType(resourceId)!!
// val model = DAO.Resource.getComponentPowerModel(typeId, null)!!
// val savings = power - (model.suspendPowerUsage ?: power)
//// val savings = ManagementMethodType.suspend.getPowerSavings(model, power)
// sum += savings
// }
// return sum
// }
private fun getSuspendSavings(resourceId: String): Double {
var sum = 0.0
powerUsage.filter {
this.state.canSuspend(it.key)
}.forEach { resourceId, power ->
// val node = value.first
val typeId = DAO.Resource.getType(resourceId)!!
val model = DAO.Resource.getComponentPowerModel(typeId, null)!!
val savings = power - (model.suspendPowerUsage ?: power)
val power = this.getPower(resourceId)
this.state.canSuspend(resourceId)
val typeId = DAO.Resource.getType(resourceId)!!
val model = DAO.Resource.getComponentPowerModel(typeId, null)!!
val savings = power - (model.suspendPowerUsage ?: power)
// val savings = ManagementMethodType.suspend.getPowerSavings(model, power)
sum += savings
}
sum += savings
return sum
}
private fun getPower(resourceId: String): Double {
var p = this.state.eval.getState(resourceId)?.power
if (p == null) {
p = this.state.getNodeUtil(resourceId)?.powerUsage
}
if (p == null) {
logError("Null power, unnecesery power check")
p = RPMApi.instance().getPowerUsageList().get(resourceId)
}
return p ?: {
logError("Power usage not provided for resource: $resourceId, default power: 0.0!!!"); 0.0
}.invoke()
}
/**
* return power savings from disabling/suspending unused resources (nodes and subcomponents - like cpu or gpu)
*/
protected fun unusedResourcesSuspendSavings(): Double {
val powerUsage = RPMApi.instance().getPowerUsageList()
val unusedPowerUsage = HashMap<String, Double>()
// val powerUsage = RPMApi.instance().getPowerUsageList()
val savingsMap = HashMap<String, Double>()
var suspendSavings = 0.0
this.state.unusedMachines.forEach {
unusedPowerUsage[it.nodeId] = powerUsage[it.nodeId] ?: {
logError("Power usage not provided for resource: ${it
.nodeId}, default power: 0.0!!!"); 0.0
}.invoke()
// val p = this.getPower(it.nodeId)
val savings = this.getSuspendSavings(it.nodeId)
suspendSavings += savings
savingsMap[it.nodeId] = savings
// unusedPowerUsage[it.nodeId]=p
// unusedPowerUsage[it.nodeId] = powerUsage[it.nodeId] ?: {
// logError("Power usage not provided for resource: ${it
// .nodeId}, default power: 0.0!!!"); 0.0
// }.invoke()
}
printConsole("unusedResources: " + unusedPowerUsage.toJson())
return this.getSuspendSavings(unusedPowerUsage)
printConsole("unusedResources suspend savings: " + savingsMap.toJson())
return suspendSavings//this.getSuspendSavings(unusedPowerUsage)
}
......@@ -96,10 +157,12 @@ abstract class RTMAlgorithm(currentState: CurrentState) {
val node = this.state.nodeMap[nodeUtil.nodeId]!!.node
if (this.state.canSuspend(node.id)) {
val power = RPMApi.instance().getPowerUsageList()[node.id] ?: {
logError("Power usage not provided for " +
"resource: ${node.id}, default power: 0.0!!!"); 0.0
}.invoke()
// val power = RPMApi.instance().getPowerUsageList()[node.id] ?: {
// logError("Power usage not provided for " +
// "resource: ${node.id}, default power: 0.0!!!"); 0.0
// }.invoke()
val power = this.getPower(node.id)
val model = DAO.Resource.getComponentPowerModel(node.typeId, null)!!
val savings = power - (model.suspendPowerUsage ?: power)
return Pair(node, savings)
......
......@@ -6,6 +6,7 @@ import psnc.m2dc.rtm.dao.DAO
import psnc.m2dc.rtm.dao.LightStorage
import psnc.m2dc.rtm.model.rest.ResourceAction
import psnc.m2dc.rtm.model.rpm.SSHCommand
import psnc.m2dc.rtm.pcm.algorithm.Solver
import psnc.m2dc.rtm.properties.RTMProperties
import psnc.m2dc.rtm.properties.keys.Keys
import psnc.m2dc.rtm.rpm.RPMApi
......@@ -34,7 +35,7 @@ object ActionPredictor {
// powerUsage + pcmBuffer
// val state = CurrentState(pcmBuffer + powerSpan + minPower)
val state = CurrentState(powerSpan + minPower)
val algoResult = PCMAlgorithm(state).next()
val algoResult = PCMAlgorithm(state, Solver.Algorithm.valueOf(Keys.PCM.algorithm.get())).next()
val toList = algoResult.getResources().map { resource ->
resource.id to algoResult.getActions(resource)
}
......
......@@ -380,7 +380,7 @@ open class Solver(e: Evaluation, var mode: SolverMode, val powerBuffer: Double,v
val currentSlot = slots[node.id]!!
var settingIndex = currentSlot.performanceSetting.settingIndex - 1
var budgetChange = 0.0
while (settingIndex >= 0 && powerBudget - budgetChange < 0) {
while (settingIndex > 0 && powerBudget - budgetChange < 0) {
budgetChange = currentSlot.powerReduction - node.state.getSavings(settingIndex)
settingIndex--
}
......
......@@ -16,6 +16,7 @@ import psnc.m2dc.rtm.rpm.RPMApi
import psnc.m2dc.rtm.utils.loadJsonFile
import psnc.m2dc.rtm.utils.logDebug
import psnc.m2dc.rtm.utils.toJson
import java.io.File
import java.nio.file.Paths
class RTMApi private constructor() {
......@@ -115,24 +116,66 @@ class RTMApi private constructor() {
s
}
ServerInitializer.check()
val initialState = state()
if (algorithm != null) {
var res = PCMAlgorithm(state(), algorithm).next()
res.toJson(RTMProperties.parsePath("${RTMProperties.basePath}/pcm_$algorithm.out").toAbsolutePath().toString(), true)
this.saveResult(res, algorithm, "pcm", initialState)
res = ESMAlgorithm(state(), algorithm).next()
res.toJson(RTMProperties.parsePath("${RTMProperties.basePath}/esm_$algorithm.out").toAbsolutePath().toString(), true)
this.saveResult(res, algorithm, "esm", initialState)
// res.toJson(RTMProperties.parsePath("${RTMProperties.basePath}/esm_$algorithm.out").toAbsolutePath().toString(), true)
} else {
Solver.Algorithm.values().forEach { algorithm ->
var res = PCMAlgorithm(state(), algorithm).next()
res.toJson(RTMProperties.parsePath("${RTMProperties.basePath}/pcm_$algorithm.out").toAbsolutePath().toString(), true)
this.saveResult(res, algorithm, "pcm", initialState)
res = ESMAlgorithm(state(), algorithm).next()
res.toJson(RTMProperties.parsePath("${RTMProperties.basePath}/esm_$algorithm.out").toAbsolutePath().toString(), true)
this.saveResult(res, algorithm, "esm", initialState)
}
}
}
fun saveResult(powerSettings: PowerSettings, algorithm: Solver.Algorithm, procedure: String, initialState: CurrentState) {
var avgPerf = 0.0
var expectedPowerConsumption = 0.0
var expectedPowerConsumption100 = 0.0
var expectedInitialPowerConsumption = 0.0
powerSettings.getSettings().forEach { resourceId, newPerformanceLevel ->
val nodeInitialState = initialState.eval.getState(resourceId)!!
val model = nodeInitialState.model
val initialUtil = nodeInitialState.util
val initialPerfLevel = nodeInitialState.perfLevel
val initialPerformanceValue = nodeInitialState.performance
val newUtil = model.calculateUtil(newPerformanceLevel, initialPerfLevel, initialUtil)
val performanceValue = model.getPerformance(newPerformanceLevel)
avgPerf += performanceValue * newUtil
expectedPowerConsumption += model.getPower(newPerformanceLevel, newUtil)/performanceValue
expectedInitialPowerConsumption += model.getPower(initialPerfLevel, initialUtil)/initialPerformanceValue
expectedPowerConsumption100 += model.getPower(100.0, model.calculateUtil(100.0, initialPerfLevel, initialUtil))
}
avgPerf /= powerSettings.getSettings().size
val path = RTMProperties.parsePath("${RTMProperties.basePath}/${procedure}_$algorithm.out").toAbsolutePath().toString()
val f = File(path)
val sb = StringBuilder()
powerSettings.getSettings().forEach {
sb.append("${it.key} => ${it.value}\n")
}
sb.append("avg perf => ${avgPerf}\n")
sb.append("expected power consumption => ${expectedPowerConsumption}\n")
sb.append("expected initial power consumption => ${expectedInitialPowerConsumption}\n")
sb.append("expected max power consumption => ${expectedPowerConsumption100}\n")
sb.append("expected power consumption savings => ${(expectedInitialPowerConsumption-expectedPowerConsumption)/expectedInitialPowerConsumption}\n")
sb.append("expected absolute powe consumption savings => ${(expectedPowerConsumption100-expectedPowerConsumption)/expectedPowerConsumption100}\n")
f.writeText(sb.toString())
PowerSettings
}
}
......
......@@ -33,7 +33,9 @@ public class AlgorithmCheckCommand extends ICommandLine {
public void execute() {
if (algo == null) {
RTMApi.Companion.instance().checkAlgorithm(path, null, limit);
} else RTMApi.Companion.instance().checkAlgorithm(path, Solver.Algorithm.valueOf(algo), limit);
} else {
RTMApi.Companion.instance().checkAlgorithm(path, Solver.Algorithm.valueOf(algo), limit);
}
}
}
package psnc.m2dc.rtm.commands.java
val APP_VERSION = "1.0.529_73222"
\ No newline at end of file
val APP_VERSION = "1.0.529_76456"
\ No newline at end of file
package psnc.m2dc.rtm.client
const val APP_VERSION = "1.1.529_73223"
\ No newline at end of file
const val APP_VERSION = "1.1.529_76456"
\ No newline at end of file
......@@ -348,8 +348,14 @@ class ComponentPowerModel(val name: String, private val perfList: List<Double>,
}
val i = this.getPerfIdxOrNull(perfLvl)
?: return ComponentPowerModel.HIGH_VALUE //Double.MAX_VALUE
val j = (utilization / this.utilStep).toInt()
return this.powerUsage[i][j]
val j_lower = (utilization / this.utilStep).toInt()
val x = (utilization % this.utilStep) / this.utilStep.toDouble()
val j_upper = Math.min(j_lower+1, this.powerUsage[i].size - 1)
val p_lower = this.powerUsage[i][j_lower]
val p_upper = this.powerUsage[i][j_upper]
val p = p_lower + (p_upper-p_lower)*x
// return this.powerUsage[i][j]
return p
}
// fun getEfficiency(perfLvl0: Double, perfLvlx: Double): Double {
......
......@@ -13,7 +13,7 @@ class PCM {
return description
}
val algorithm = RTMProperty(PCM + "algorithm", "greedy")
val algorithm = RTMProperty(PCM + "algorithm", "greedy",description= "available values: greedy, simple, random, milp, proportional")
//val auto_perform_actions = RTMProperty(PCM + "auto_perform_actions", true)
val fire_null_limit_restore = RTMProperty(PCM + "fire_null_limit_restore ",
true)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment