Commit 1268df7f by Tomasz Ciesielczyk

solver api

parent 8e1e2114
......@@ -5,7 +5,7 @@ import psnc.m2dc.rtm.PowerSettings
import psnc.m2dc.rtm.RTMAlgorithm
import psnc.m2dc.rtm.model.rpm.Resource
import psnc.m2dc.rtm.pcm.PCMApi
import psnc.m2dc.rtm.utils.loadJsonFile
import psnc.m2dc.rtm.pcm.algorithm.Solver
import psnc.m2dc.rtm.utils.logWarn
import psnc.m2dc.rtm.utils.printConsole
import psnc.m2dc.rtm.utils.toJson
......@@ -22,7 +22,7 @@ IV. Perform chosen actions.
#endregion
*/
class ESMAlgorithm(state: CurrentState) : RTMAlgorithm(state) {
class ESMAlgorithm(state: CurrentState,val algorithm: Solver.Algorithm) : RTMAlgorithm(state) {
private lateinit var solver: ESMSolver
init {
this.saveState()
......@@ -35,7 +35,7 @@ class ESMAlgorithm(state: CurrentState) : RTMAlgorithm(state) {
private fun setSolver(powerBudget: Double) {
state.eval.addPowerBudget(powerBudget)
solver = ESMSolver(state.eval)
solver = ESMSolver(state.eval,this.algorithm)
}
fun next(): PowerSettings {
......@@ -47,7 +47,7 @@ class ESMAlgorithm(state: CurrentState) : RTMAlgorithm(state) {
printConsole(PCMApi.instance().getNodePerformance().toJson())
setSolver(suspendSavings)
printConsole("esm powerbudget: ${-this.state.eval.powerOverLimit}")
solver.exactAlgo()?.let {
solver.solve()?.let {
it.forEach {
val state = this.state.nodeMap[it.key]!!.setPerformance(it.value)
result[state.node] = state
......
......@@ -9,6 +9,6 @@ import psnc.m2dc.rtm.properties.keys.Keys
*
* Created by Tomek on 2018-06-25.
*/
class ESMSolver(e: Evaluation) : Solver(e, SolverMode.esm,
class ESMSolver(e: Evaluation,algorithm: Algorithm) : Solver(e, SolverMode.esm,
Keys.ESM.power_buffer.get() *
(PCMApi.instance().getPowerLimit() ?: 0.0))
(PCMApi.instance().getPowerLimit() ?: 0.0),algorithm)
......@@ -3,6 +3,7 @@ package psnc.m2dc.rtm.esm
import psnc.m2dc.rtm.CurrentState
import psnc.m2dc.rtm.RTMWorker
import psnc.m2dc.rtm.pcm.PCMWorker
import psnc.m2dc.rtm.pcm.algorithm.Solver
import psnc.m2dc.rtm.properties.keys.Keys
import psnc.m2dc.rtm.utils.logInfo
import psnc.m2dc.rtm.utils.printConsole
......@@ -11,7 +12,7 @@ import psnc.m2dc.rtm.utils.toJson
class ESMWorker private constructor(val state: CurrentState) : RTMWorker() {
private var settingsWorker: Thread? = null
private val algorithm: ESMAlgorithm = ESMAlgorithm(state)
private val algorithm: ESMAlgorithm = ESMAlgorithm(state, Solver.Algorithm.valueOf(Keys.ESM.algorithm.get()))
companion object {
// private val log = LoggerFactory.getLogger(ESMWorker::class.java.name)
......
......@@ -4,6 +4,7 @@ import psnc.m2dc.rtm.CurrentState
import psnc.m2dc.rtm.PowerSettings
import psnc.m2dc.rtm.RTMAlgorithm
import psnc.m2dc.rtm.model.rpm.Resource
import psnc.m2dc.rtm.pcm.algorithm.Solver
import psnc.m2dc.rtm.utils.logInfo
import psnc.m2dc.rtm.utils.logWarn
import psnc.m2dc.rtm.utils.printConsole
......@@ -35,8 +36,8 @@ PCM algorithm:
#endregion
*/
class PCMAlgorithm(state: CurrentState) : RTMAlgorithm(state) {
private var solver: PCMSolver = PCMSolver(state.eval)
class PCMAlgorithm(state: CurrentState,val algorithm: Solver.Algorithm) : RTMAlgorithm(state) {
private var solver: PCMSolver = PCMSolver(state.eval,algorithm)
init {
this.saveState()
......@@ -48,7 +49,7 @@ class PCMAlgorithm(state: CurrentState) : RTMAlgorithm(state) {
// var algoState: AlgorithmState? = null
private fun setSolver(powerBudget: Double) {
this.state.eval.addPowerBudget(powerBudget)
solver = PCMSolver(state.eval)
solver = PCMSolver(state.eval,this.algorithm)
}
......@@ -67,7 +68,7 @@ class PCMAlgorithm(state: CurrentState) : RTMAlgorithm(state) {
if (this.solver.upperBoundCheck(null) > state.currentPowerOverLimit - suspendSavings) {
setSolver(suspendSavings)
printConsole("pcm poweroverlimit: ${this.state.eval.powerOverLimit}")
solver.approximateAlgo()?.let {
solver.solve()?.let {
it.forEach {
val state = this.state.nodeMap[it.key]!!.setPerformance(it.value)
result[state.node] = state
......@@ -102,7 +103,7 @@ class PCMAlgorithm(state: CurrentState) : RTMAlgorithm(state) {
suspendSavings = unusedResourcesSuspendSavings()
setSolver(suspendSavings)
printConsole("pcm poweroverlimit: ${this.state.eval.powerOverLimit}")
val performanceSettings = solver.approximateAlgo()
val performanceSettings = solver.solve()
performanceSettings?.let {
it.forEach {
val state = this.state.nodeMap[it.key]!!.setPerformance(it.value)
......
......@@ -8,7 +8,7 @@ import psnc.m2dc.rtm.properties.keys.Keys
*
* Created by Tomek on 2018-06-25.
*/
class PCMSolver(e: Evaluation) : Solver(e, SolverMode.pcm,Keys.PCM.power_buffer.get() *
(PCMApi.instance().getPowerLimit() ?: 0.0)) {
class PCMSolver(e: Evaluation,algorithm: Algorithm) : Solver(e, SolverMode.pcm,Keys.PCM.power_buffer.get() *
(PCMApi.instance().getPowerLimit() ?: 0.0),algorithm) {
}
\ No newline at end of file
......@@ -5,6 +5,7 @@ import psnc.m2dc.rtm.CurrentState
import psnc.m2dc.rtm.RTMWorker
import psnc.m2dc.rtm.esm.ESMWorker
import psnc.m2dc.rtm.model.rest.PCMState
import psnc.m2dc.rtm.pcm.algorithm.Solver
import psnc.m2dc.rtm.properties.keys.Keys
import psnc.m2dc.rtm.utils.Timer
import psnc.m2dc.rtm.utils.logInfo
......@@ -14,7 +15,7 @@ import psnc.m2dc.rtm.utils.toJson
class PCMWorker(var state: CurrentState) : RTMWorker() {
private var currentIteration = 0
private val algorithm: PCMAlgorithm = PCMAlgorithm(state)
private val algorithm: PCMAlgorithm = PCMAlgorithm(state, Solver.Algorithm.valueOf(Keys.PCM.algorithm.get()))
companion object {
......
......@@ -19,11 +19,14 @@ import java.util.concurrent.atomic.AtomicInteger
* https://github.com/optimatika/ojAlgo/wiki/Using-MPS
*
*/
open class Solver(e: Evaluation, var mode: SolverMode, val powerBuffer: Double) : Algorithm(e) {
open class Solver(e: Evaluation, var mode: SolverMode, val powerBuffer: Double,val algorithm: Algorithm) : Algorithm(e) {
enum class SolverMode {
pcm, esm
}
enum class Algorithm {
greedy, milp, random, simple, proportional
}
......@@ -142,9 +145,19 @@ open class Solver(e: Evaluation, var mode: SolverMode, val powerBuffer: Double)
// }
return sum
}
fun solve():HashMap<String, Double>?{
return when (this.algorithm){
Algorithm.milp -> exactAlgo()
Algorithm.greedy -> approximateAlgo()
Algorithm.random ->randomAlgo()
Algorithm.simple ->simpleAlgo()
Algorithm.proportional->proportionalAlgo()
}
}
fun exactAlgo(): HashMap<String, Double>? {
private fun exactAlgo(): HashMap<String, Double>? {
if (upperBoundCheck(null) < -currentBudget) {
/**impossible to fulfil requirements*/
return null
......@@ -200,7 +213,7 @@ open class Solver(e: Evaluation, var mode: SolverMode, val powerBuffer: Double)
return result
}
fun proportionalAlgo(): HashMap<String, Double>? {
private fun proportionalAlgo(): HashMap<String, Double>? {
if (upperBoundCheck(null) < -currentBudget) {
/**impossible to fulfil requirements*/
return null
......@@ -268,22 +281,19 @@ open class Solver(e: Evaluation, var mode: SolverMode, val powerBuffer: Double)
return null
}
fun randomAlgo(): HashMap<String, Double>? {
private fun randomAlgo(): HashMap<String, Double>? {
if (upperBoundCheck(null) < -currentBudget) {
/**impossible to fulfil requirements*/
return null
}
val result = HashMap<String, Double>()
val r = updatePowerToReduce(result)
// var powerToReduce = r.first
val group = r.second
val usePriorities = false
/**set minimum performance*/
var powerBudget = currentBudget // powerBudget should be greater than 0
val nodeSet = HashMap<String, Pair<Double, Double>>()
nodes.forEach { priority, nodeList ->
if (priority.priorityValue <= group.priorityValue || !usePriorities) {
nodeList.forEach { node ->
this.eval.getState(node.id)?.let { state ->
......@@ -333,7 +343,7 @@ open class Solver(e: Evaluation, var mode: SolverMode, val powerBuffer: Double)
return null
}
fun simpleAlgo(): HashMap<String, Double>? {
private fun simpleAlgo(): HashMap<String, Double>? {
if (upperBoundCheck(null) < -currentBudget) {
/**impossible to fulfil requirements*/
return null
......@@ -345,7 +355,6 @@ open class Solver(e: Evaluation, var mode: SolverMode, val powerBuffer: Double)
/**set minimum performance*/
var powerBudget = currentBudget // powerBudget should be greater than 0
val nodeSet = HashMap<String, Pair<Double, Double>>()
val nodeList = ArrayList<Node>()
nodes.forEach { priority, it ->
if (priority.priorityValue <= group.priorityValue) {
......@@ -353,7 +362,7 @@ open class Solver(e: Evaluation, var mode: SolverMode, val powerBuffer: Double)
}
}
val sorted = nodeList.sortedByDescending { it.state.priority }
var slots = HashMap<String, Slot>()
val slots = HashMap<String, Slot>()
nodes.forEach { priority, nodes ->
if (priority.priorityValue <= group.priorityValue)
nodes.forEach { node ->
......@@ -364,7 +373,7 @@ open class Solver(e: Evaluation, var mode: SolverMode, val powerBuffer: Double)
}
}
}
var size = sorted.size
val size = sorted.size
var idx = 0
while (idx < size && powerBudget < 0) {
val node = nodeList[idx]
......@@ -389,7 +398,7 @@ open class Solver(e: Evaluation, var mode: SolverMode, val powerBuffer: Double)
return result
}
fun approximateAlgo(): HashMap<String, Double>? {
private fun approximateAlgo(): HashMap<String, Double>? {
if (upperBoundCheck(null) < -currentBudget) {
/**impossible to fulfil requirements*/
return null
......@@ -467,111 +476,22 @@ open class Solver(e: Evaluation, var mode: SolverMode, val powerBuffer: Double)
}
// fun approximateAlgo(): HashMap<String, Double>? {
// if (upperBoundCheck(null) < eval.powerOverLimit) {
// /**impossible to fulfil requirements*/
// return null
// }
// //PRZESLEDZIC
// val result = HashMap<String, Double>()
// var powerSavings = 0.0
//
// nodes.forEach { priority, nodes ->
// nodes.forEach { node ->
// if (this.eval.getState(node.id) != null)
// settings.forEach { setting ->
// slots[priority]!!.add(Slot(setting, node))
// }
// }
// }
// // val slotMap = slots.map { s ->
// // s.key to s.value.map { slot -> slot.node to s.value.filter { slot.node == it.node } }
// // .toMap()
// // }.toMap()
//
// /**set minimum performance*/
// nodes.forEach { priority, nodes ->
// nodes.forEach { node ->
// if (this.eval.getState(node.id) != null) {
// result.put(node.id, 0.0)
// powerSavings += node.state.getSavings(0)
// settings.forEach { setting ->
// slots[priority]!!.add(Slot(setting, node))
// }
// }
// }
// }
// // slotMap.values.forEach {
// // it.forEach { slots ->
// // result.put(slots.key.id, 0.0)
// // powerSavings += slots.value.filter { slot ->
// // slot.settingValue.toInt() == 0
// // }.first().powerReduction
// // }
// // }
// val nodeSet = HashMap<String, Pair<Double, Double>>()
// //how much energy should be decreased within each group
// val r = updatePowerToReduce(result)
// // var powerToReduce = r.first
// val group = r.second
// // var powerBudget = powerSavings - powerToReduce
// var powerBudget = powerSavings - eval.powerOverLimit // powerToReduce
// //println("min:$powerBudget")
// // posortować tak zeby uwaglednic rowniez ujemny zysk
// // val sorted = slots.values.flatMap { it }.sortedByDescending { it.ratioMin }
// val sorted = slots.filter { it.key.priorityValue >= group.priorityValue }.flatMap { it.value }
// .sortedByDescending {
// it.ratioMin
// }
// /**greedy power distribution*/
// sorted.forEach { slot ->
// if (!nodeSet.contains(slot.node.id)) {
// val budgetChange = slot.node.state.savingsVector[0] - slot.powerReduction
// if (powerBudget - budgetChange >= 0) {
// nodeSet[slot.node.id] = Pair(slot.powerReduction, slot.gain)
// result.put(slot.node.id, slot.settingValue)
// powerSavings -= budgetChange
// powerBudget -= budgetChange
// }
// } else if (nodeSet[slot.node.id]!!.second < slot.gain) {
//
// val budgetChange = nodeSet[slot.node.id]!!.first - slot.powerReduction
// if (powerBudget - budgetChange >= 0) {
// nodeSet[slot.node.id] = Pair(slot.powerReduction, slot.gain)
// result.put(slot.node.id, slot.settingValue)
// powerSavings -= budgetChange
// powerBudget -= budgetChange
// }
// }
// }
//
// /**
// * power savings can be less than zero in case of performance increase
// */
// this.powerSavings = eval.totalPowerSavings(result)
// this.currentGain = eval.totalGain(result)
// // println(result)
// // println("heuristic: " + this.eval.totalGain(result))
// return result
// }
}
data class PerformanceSetting(val settingIndex: Int, val solver: Solver) {
val slots by lazy {
solver.slots.flatMap { it.value }.filter { slot -> slot.performanceSetting == this }
}
fun addConstraints() {
// addExpression().upper(1).apply {
// slots.forEach {
// set(it.occupied, 1)
// }
// }
}
// val slots by lazy {
// solver.slots.flatMap { it.value }.filter { slot -> slot.performanceSetting == this }
// }
// fun addConstraints() {
// // addExpression().upper(1).apply {
// // slots.forEach {
// // set(it.occupied, 1)
// // }
// // }
// }
override fun toString(): String {
return "$settingIndex"
......@@ -618,22 +538,15 @@ data class Slot(val performanceSetting: PerformanceSetting, val node: Node) {
init {
this.occupied.weight(gain)
}
// companion object {
//
//
// val all = Solver.nodes.asSequence().flatMap { node: Node ->
// node.settings.asSequence().map { setting -> Slot(setting, node) }
// }.toList()
//
// }
override fun toString() = "$node-$performanceSetting: ${
occupied?.value?.toInt()
}"
fun print() {
println("""
${node.id}:${node.state.priority} ${settingValue}:${powerReduction}:${gain}""")
}
// fun print() {
// println("""
// ${node.id}:${node.state.priority} ${settingValue}:${powerReduction}:${gain}""")
// }
}
......@@ -3,13 +3,13 @@ package psnc.m2dc.rtm
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import org.slf4j.LoggerFactory
import psnc.m2dc.rtm.commands.java.AlgorithmCheckCommand
import psnc.m2dc.rtm.dao.DAO
import psnc.m2dc.rtm.esm.ESMAlgorithm
import psnc.m2dc.rtm.model.rest.ResourceAction
import psnc.m2dc.rtm.model.rest.ResourceActionResult
import psnc.m2dc.rtm.pcm.PCMAlgorithm
import psnc.m2dc.rtm.pcm.PCMApi
import psnc.m2dc.rtm.pcm.algorithm.Solver
import psnc.m2dc.rtm.pcm.algorithm.Utils
import psnc.m2dc.rtm.properties.RTMProperties
import psnc.m2dc.rtm.rpm.RPMApi
......@@ -80,7 +80,7 @@ class RTMApi private constructor() {
var limits = PCMApi.instance().checkLimits()
var state = CurrentState(limits.currentPowerUsage)
PCMAlgorithm(state)
PCMAlgorithm(state, Solver.Algorithm.greedy)
actionList = ArrayList<ResourceAction>()
actionResultList = ArrayList<ResourceActionResult>()
......@@ -97,20 +97,38 @@ class RTMApi private constructor() {
Thread.sleep(90000)
limits = PCMApi.instance().checkLimits()
state = CurrentState(limits.currentPowerUsage)
PCMAlgorithm(state)
PCMAlgorithm(state, Solver.Algorithm.greedy)
RPMApi.instance().getPowerUsageList().toJson(RTMProperties.parsePath("${RTMProperties.basePath}/check_power_usage_100.json").toString())
// ESMAlgorithm(state)
}
fun checkAlgorithm(path: String, algorithm: AlgorithmCheckCommand.Algorithm, limit: Double) {
fun checkAlgorithm(path: String, algorithm: Solver.Algorithm?, limit: Double) {
log.info("Algorithm Check!")
val state = {
val s = loadJsonFile<CurrentState>(Paths.get(path), CurrentState::class.java)
?: throw NullPointerException("State not found")
s.currentPowerOverLimit = s.powerUsage - limit
s.eval.resetPowerBudget(s.currentPowerOverLimit)
s
}
ServerInitializer.check()
val state = loadJsonFile<CurrentState>(Paths.get(path), CurrentState::class.java)
?: throw NullPointerException("State not found")
PCMAlgorithm(state)
ESMAlgorithm(state)
if (algorithm != null) {
var res = PCMAlgorithm(state(), algorithm).next()
res.toJson(RTMProperties.parsePath("${RTMProperties.basePath}/pcm_$algorithm.out").toAbsolutePath().toString(), true)
res = ESMAlgorithm(state(), algorithm).next()
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)
res = ESMAlgorithm(state(), algorithm).next()
res.toJson(RTMProperties.parsePath("${RTMProperties.basePath}/esm_$algorithm.out").toAbsolutePath().toString(), true)
}
}
}
......
......@@ -11,6 +11,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import psnc.m2dc.rtm.ICommandLine;
import psnc.m2dc.rtm.RTMApi;
import psnc.m2dc.rtm.pcm.algorithm.Solver;
/**
......@@ -27,12 +28,12 @@ public class AlgorithmCheckCommand extends ICommandLine {
@Parameter(names = {"--limit"}, description = " power limit")
private Double limit = null;
public enum Algorithm{
greedy,milp,random,simple,proportional
}
@Override
public void execute() {
RTMApi.Companion.instance().checkAlgorithm(path,Algorithm.valueOf(algo),limit);
if (algo == null) {
RTMApi.Companion.instance().checkAlgorithm(path, null, limit);
} else RTMApi.Companion.instance().checkAlgorithm(path, Solver.Algorithm.valueOf(algo), limit);
}
}
package psnc.m2dc.rtm.commands.java
val APP_VERSION = "1.0.529_67561"
\ No newline at end of file
val APP_VERSION = "1.0.529_73222"
\ No newline at end of file
package psnc.m2dc.rtm.client
const val APP_VERSION = "1.1.529_67561"
\ No newline at end of file
const val APP_VERSION = "1.1.529_73223"
\ No newline at end of file
......@@ -9,6 +9,7 @@ class ESM {
override fun toString(): String {
return description
}
val algorithm = RTMProperty(ESM + "algorithm","milp")
//val auto_perform_actions = ESM + "auto_perform_actions"
val scan_timeout_ms = RTMProperty(ESM + "scan_timeout_ms", 300000L)
......
......@@ -13,6 +13,7 @@ class PCM {
return description
}
val algorithm = RTMProperty(PCM + "algorithm", "greedy")
//val auto_perform_actions = RTMProperty(PCM + "auto_perform_actions", true)
val fire_null_limit_restore = RTMProperty(PCM + "fire_null_limit_restore ",
true)
......@@ -28,7 +29,7 @@ class PCM {
val default_node_priority = RTMProperty(PCM + "default_node_priority",
null, NodePriority::class.java, true,defaultKey = "\$[file]\$[basePath]/conf/default_priority.json")
null, NodePriority::class.java, true, defaultKey = "\$[file]\$[basePath]/conf/default_priority.json")
val default_node_priority_map = RTMMapProperty(
PCM + "default_node_priority_map",
GenericTypeMapWrapper.get<NodePriority>(psnc.m2dc.rtm.utils.NodePriorityMapWrapper()),
......
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