Commit c2f4dab0 authored by Valentin Reis's avatar Valentin Reis

Adding some of the power-expe code.

parent e992a7f1
Pipeline #4566 failed with stages
in 2 minutes and 18 seconds
...@@ -2,10 +2,12 @@ from __future__ import print_function ...@@ -2,10 +2,12 @@ from __future__ import print_function
import logging import logging
import time import time
import math
logger = logging.getLogger('nrm') logger = logging.getLogger('nrm')
logger_power = logging.getLogger('power') logger_power = logging.getLogger('power')
class Action(object): class Action(object):
"""Information about a control action.""" """Information about a control action."""
...@@ -15,6 +17,7 @@ class Action(object): ...@@ -15,6 +17,7 @@ class Action(object):
self.command = command self.command = command
self.delta = delta self.delta = delta
class PowerActuator(object): class PowerActuator(object):
"""Actuator in charge of power control.""" """Actuator in charge of power control."""
...@@ -41,7 +44,41 @@ class PowerActuator(object): ...@@ -41,7 +44,41 @@ class PowerActuator(object):
action.command, action.delta, action.target) action.command, action.delta, action.target)
# sensor_manager is a SensorManager, which is not only about sensing # sensor_manager is a SensorManager, which is not only about sensing
# but also about setting power limits. # but also about setting power limits.
# self.sensor_manager.set_powerlimit(action.target, action.command) self.sensor_manager.set_powerlimit(action.target, action.command)
def update(self, action):
pass
class DiscretizedPowerActuator(object):
"""Actuator in charge of power control via discretization."""
def __init__(self, sm, lowerboundwatts, k):
self.sensor_manager = sm
self.lowerboundwatts = lowerboundwatts # the minimal cpu wattage
self.k = k # the number of arms
def available_actions(self):
actions = []
pl = self.sensor_manager.get_powerlimits()
logger.info("BanditPowerActuator: power limits %r", pl)
maxW = int(pl[[k for k, i in pl.items()][0]]['maxW'])
if maxW < self.lowerboundwatts:
logger.error("BanditPowerActuator: The provided power lowerbound\
is higher than the available maximum CPU wattage.")
rangeW = maxW - self.lowerboundwatts
arms = [self.lowerboundwatts + (float(a)*rangeW/float(self.k))
for a in range(1, self.k+1)]
logger.info("BanditPowerActuator: discretized power limits: %r:", arms)
actions = [Action([k for k, i in pl.items()][0], int(math.floor(a)), 0)
for a in arms]
return(actions)
def execute(self, action):
logger.info("changing power limit: %r, %r",
action.command, action.delta)
self.sensor_manager.set_powerlimit(action.target, action.command)
def update(self, action): def update(self, action):
pass pass
...@@ -51,34 +88,18 @@ class Controller(object): ...@@ -51,34 +88,18 @@ class Controller(object):
"""Implements a control loop for resource management.""" """Implements a control loop for resource management."""
def __init__(self, actuators): def __init__(self, actuators, strategy):
self.actuators = actuators self.actuators = actuators
def planify(self, target, machineinfo): def planify(self, target, machineinfo):
"""Plan the next action for the control loop.""" """Plan the next action for the control loop."""
# current_e = float(machineinfo['energy']['energy']['cumulative']['package-0'])/(1000*1000) # in joules # current_e = float(machineinfo['energy']['energy']
current_p = float(machineinfo['energy']['power']['p0'])/(1000*1000) # in joules # ['cumulative']['package-0'])/(1000*1000) # in joules
current_p = float(machineinfo['energy']['power']['p1'])/(1000*1000) # in joules # In joules:
logger_power.info("%s %s %s" % (time.time(),current_p,current_p)) current_p = float(machineinfo['energy']['power']['p0'])/(1000*1000)
return (None,None) current_p = float(machineinfo['energy']['power']['p1'])/(1000*1000)
logger_power.info("%s %s %s" % (time.time(), current_p, current_p))
# direction = None return (None, None)
# if total_power < target:
# direction = 'i'
# elif total_power > target:
# direction = 'd'
# if direction:
# actions = []
# for act in self.actuators:
# newactions = act.available_actions(direction)
# actions.extend([(a, act) for a in newactions])
# if actions:
# # TODO: better choice
# actions.sort(key=lambda x: x[0].delta)
# return actions.pop(0)
# else:
# return (None, None)
def execute(self, action, actuator): def execute(self, action, actuator):
"""Build the action for the appropriate manager.""" """Build the action for the appropriate manager."""
......
...@@ -2,7 +2,7 @@ from __future__ import print_function ...@@ -2,7 +2,7 @@ from __future__ import print_function
from applications import ApplicationManager from applications import ApplicationManager
from containers import ContainerManager from containers import ContainerManager
from controller import Controller, PowerActuator from controller import Controller, PowerActuator, DiscretizedPowerActuator
from powerpolicy import PowerPolicyManager from powerpolicy import PowerPolicyManager
from functools import partial from functools import partial
import json import json
...@@ -169,7 +169,9 @@ class Daemon(object): ...@@ -169,7 +169,9 @@ class Daemon(object):
logger.info("sending sensor message: %r", msg) logger.info("sending sensor message: %r", msg)
def do_control(self): def do_control(self):
logger.info("Asking controller to plan for target %s using machine info %s" % (self.target, self.machine_info)) logger.info(
"Asking controller to plan for target %s using machine info %s"
% (self.target, self.machine_info))
plan = self.controller.planify(self.target, self.machine_info) plan = self.controller.planify(self.target, self.machine_info)
logger.info("Controller chose plan " + str(plan)) logger.info("Controller chose plan " + str(plan))
action, actuator = plan action, actuator = plan
...@@ -259,7 +261,6 @@ class Daemon(object): ...@@ -259,7 +261,6 @@ class Daemon(object):
def do_shutdown(self): def do_shutdown(self):
self.sensor_manager.stop() self.sensor_manager.stop()
ioloop.IOLoop.current().stop() ioloop.IOLoop.current().stop()
context.term()
def main(self): def main(self):
# Bind address for downstream clients # Bind address for downstream clients
...@@ -303,7 +304,8 @@ class Daemon(object): ...@@ -303,7 +304,8 @@ class Daemon(object):
self.container_manager = ContainerManager(self.resource_manager) self.container_manager = ContainerManager(self.resource_manager)
self.application_manager = ApplicationManager() self.application_manager = ApplicationManager()
self.sensor_manager = SensorManager() self.sensor_manager = SensorManager()
pa = PowerActuator(self.sensor_manager) pa = PowerActuator(self.sensor_manager,
strategy=self.config['powerlevel'])
self.controller = Controller([pa]) self.controller = Controller([pa])
self.sensor_manager.start() self.sensor_manager.start()
...@@ -322,7 +324,6 @@ class Daemon(object): ...@@ -322,7 +324,6 @@ class Daemon(object):
signal.signal(signal.SIGCHLD, self.do_signal) signal.signal(signal.SIGCHLD, self.do_signal)
ioloop.IOLoop.current().start() ioloop.IOLoop.current().start()
context.term()
def runner(config): def runner(config):
......
...@@ -4,6 +4,7 @@ import logging ...@@ -4,6 +4,7 @@ import logging
import xml.etree.ElementTree import xml.etree.ElementTree
import tornado.process as process import tornado.process as process
import subprocess import subprocess
import os
logger = logging.getLogger('nrm') logger = logging.getLogger('nrm')
resources = collections.namedtuple("Resources", ["cpus", "mems"]) resources = collections.namedtuple("Resources", ["cpus", "mems"])
...@@ -42,7 +43,14 @@ class NodeOSClient(object): ...@@ -42,7 +43,14 @@ class NodeOSClient(object):
def __init__(self): def __init__(self):
"""Load client configuration.""" """Load client configuration."""
self.prefix = "argo_nodeos_config" if 'ARGO_NODEOS_CONFIG' in os.environ:
logger.info("NodeOSClient: bypassing argo_nodeos_config with %s\n"
% os.environ['ARGO_NODEOS_CONFIG'])
self.prefix = os.environ['ARGO_NODEOS_CONFIG']
else:
logger.info("NodeOSClient: using argo_nodeos_config from path")
self.prefix = "argo_nodeos_config"
def getavailable(self): def getavailable(self):
"""Gather available resources.""" """Gather available resources."""
......
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 to comment