Commit 37029d12 authored by Valentin Reis's avatar Valentin Reis

daemon with log output

parent 56d89781
#!/usr/bin/env python2
"""NRM Daemon.
Usage:
daemon bandit
[-k <k> | --discretization=<k>] [-l <watts> | --lowerboundwatts=<watts>]
[-e <eps> | --epsilon=<eps>] [-o <k> | --log_power=<log>]
daemon enforce <policy>
[-k <k> | --discretization <k>] [-l <watts> | --lowerboundwatts <watts>]
[-o <k> | --log_power=<log>]
Arguments:
<policy> The powercontrol policy to enforce. [default: None]
Options:
-h --help Show this screen.
-k <k> --discretization=<k> The discretization count to use in powercontrol.
[default: 4]
-l <watts> --lowerboundwatts=<watts> The minimum cpu wattage allowed. [default: 100]
-e <eps> --epsilon=<eps> The exploration constant for bandit powercontrol.
[default: 0.1]
-o <log> --log_power=<log> The log file for power use.
Try: daemon bandit -k 4 -l 100 -e 0.1
daemon bandit -k 4 -l 100 -e 1 #random bandit
daemon enforce 0 -k 2 #enforce the lower bound
daemon enforce 1 -k 2 #enforce the maximum
"""
from docopt import docopt
import nrm
import nrm.daemon
if __name__ == "__main__":
nrm.daemon.runner()
arguments = docopt(__doc__, version='Naval Fate 2.0')
print(arguments)
if arguments["enforce"]:
arguments["<policy>"]=int(arguments["<policy>"])
nrm.daemon.runner(power_discretization=int(arguments["--discretization"]),
enforce_powerpolicy=arguments["<policy>"],
exploration_constant=float(arguments["--epsilon"]),
lowerboundwatts=int(arguments["--lowerboundwatts"]),
log_power=arguments["--log_power"])
......@@ -3,7 +3,7 @@
pythonPackages.buildPythonPackage {
name = "nrm";
src = ./.;
propagatedBuildInputs = with pythonPackages;[ six numpy tornado pyzmq hwloc ];
propagatedBuildInputs = with pythonPackages;[ six numpy tornado pyzmq hwloc docopt];
buildInputs = with pythonPackages;[ pytest];
testPhase = '' pytest '';
}
......@@ -57,7 +57,7 @@ class Application(object):
def update_progress(self, msg):
"""Update the progress tracking."""
payload = self.progress + float(msg['payload'])
self.progress = self.progress + float(msg['payload'])
def reset_progress(self, msg):
"""Update the progress tracking."""
......
......@@ -84,23 +84,18 @@ class DiscretizedPowerActuator(object):
def update(self, action):
pass
class BasicPowerLoss(object):
def __init__(self, a, b, power_min=100000000, power_max=0, progress_min=1000000000, progress_max=0):
self.a = a
self.b = b
self.power_min = power_min
def __init__(self, alpha, power_max=0, progress_max=0):
self.alpha = alpha
self.power_max = power_max
self.progress_min = progress_min
self.progress_max = progress_max
def loss(self,progress,power):
if power>self.power_max: self.power_max = power
if power<self.power_min: self.power_min = power
if progress>self.progress_max: self.progress_max = progress
if progress<self.progress_min: self.progress_min = progress
return((self.a*(power-self.power_min)/(max(0.001, self.power_max-self.power_min))) +
(self.b*(progress-self.progress_min)/(max(0.001,self.progress_max-self.progress_min))))
power_n=power/max(0.001, self.power_max)
progress_n=progress/max(0.001, self.progress_max)
return(self.alpha*power_n + (1-self.alpha)*progress_n)
class EpsGreedyBandit(object):
"""Epsilon greedy bandit. Actions in O,..,k-1."""
......@@ -120,12 +115,12 @@ class EpsGreedyBandit(object):
assert(loss >= 0)
# logging.info("NEXT0!! Arriving with self.n :%s" %str(self.n))
# logging.info("NEXT0!! Arriving with self.a :%s" %str(self.a))
if self.a!=None:
if self.a is not None:
self.losses[self.a]=self.losses[self.a]+loss
self.plays[self.a]=self.plays[self.a]+1
self.n=self.n+1
logging.info("Bandit: the total plays are:%s" %str(self.plays))
logging.info("Bandit: the estimated losses are:%s" %str([l/p for l,p in zip(self.losses,self.plays)]))
logging.info("Bandit: the estimated losses are:%s" %str([l/(max(1,p)) for l,p in zip(self.losses,self.plays)]))
if self.n <= self.k:
self.a = self.n-1
else:
......@@ -138,17 +133,21 @@ class EpsGreedyBandit(object):
class BanditController(object):
"""Implements a bandit control loop for resource management."""
def __init__(self, actuators, initialization_rounds=20, exploration=0.2, enforce=None):
def __init__(self, actuators, initialization_rounds=20,
exploration=0.2, enforce=None, log_power=None):
self.actuators = actuators
self.initialization_rounds = initialization_rounds
self.actions = [a for a in itertools.product(*[act.available_actions() for act in actuators])]
self.loss = BasicPowerLoss(1,-1)
self.loss = BasicPowerLoss(0.5)
self.bandit = EpsGreedyBandit(exploration,len(self.actions))
self.n=0
if enforce!=None:
if enforce is not None:
assert(enforce>=0)
assert(enforce<len(self.actions))
self.enforce=enforce
self.log_power=log_power
if self.log_power is not None:
self.log_power.write("progress power loss a desc")
def planify(self, target, machineinfo, applications):
"""Plan the next action for the control loop."""
......@@ -157,11 +156,12 @@ class BanditController(object):
self.n=self.n+1
total_progress = sum([a.progress for a in applications.values()])
total_power = float(machineinfo['energy']['power']['p0'])
logger.info("Controller:MACHINEINFO %s." %(str(machineinfo)))
logger.info("Controller: Reading progress %s and power %s." %(total_progress,total_power))
logger.info("Controller: Reading machineinfo %s." %(str(machineinfo)))
logger.info("Controller: Reading progress %s and power %s."
%(total_progress,total_power))
loss = self.loss.loss(progress=total_progress,power=total_power)
logger.info("Controller: Computing loss %s." %loss)
if self.enforce!=None:
logger.info("Controller: Incurring loss %s." %loss)
if self.enforce is not None:
logger.info("Controller: enforced action.")
a=self.enforce
if self.n>self.initialization_rounds:
......@@ -171,7 +171,12 @@ class BanditController(object):
logger.info("Controller: estimating max power/max progress ranges.")
a=self.n % len(self.actions)
action = self.actions[a]
logger.info("Controller: playing arm id %s (powercap '%s')." %(str(a),str([act.command for act in list(action)])))
logger.info("Controller: playing arm id %s (powercap '%s')."
%(str(a),str([act.command for act in list(action)])))
if self.log_power is not None:
self.log_power.write("%s %s %s %s %s\n"
%(str(total_progress),str(total_power),str(loss),
str(a),str([act.command for act in list(action)])))
return(list(action),self.actuators)
def execute(self, actions, actuators):
......
......@@ -18,8 +18,17 @@ logger = logging.getLogger('nrm')
class Daemon(object):
def __init__(self):
def __init__(self,power_discretization=4,
enforce_powerpolicy=False,
lowerboundwatts=100,
exploration_constant=0.1,
log_power=None):
self.target = 100.0
self.log_power = log_power
self.k = power_discretization
self.eps = exploration_constant
self.enforce = enforce_powerpolicy
self.lowerboundwatts = lowerboundwatts
def do_downstream_receive(self, parts):
logger.info("receiving downstream message: %r", parts)
......@@ -220,8 +229,9 @@ class Daemon(object):
self.application_manager = ApplicationManager()
self.sensor_manager = SensorManager()
# aa = ApplicationActuator(self.application_manager, self.downstream_pub)
pa = DiscretizedPowerActuator(self.sensor_manager,lowerboundwatts=100,k=4)
self.controller = BanditController([pa])
pa = DiscretizedPowerActuator(self.sensor_manager,lowerboundwatts=self.lowerboundwatts,k=self.k)
self.controller = BanditController([pa],enforce=self.enforce,
exploration=self.eps,log_power=self.log_power)
self.sensor_manager.start()
self.machine_info = self.sensor_manager.do_update()
......@@ -240,8 +250,23 @@ class Daemon(object):
ioloop.IOLoop.current().start()
def runner():
def runner(power_discretization=4,
enforce_powerpolicy=False,
lowerboundwatts=100,
exploration_constant=0.1,
log_power=None):
ioloop.install()
logging.basicConfig(level=logging.DEBUG)
daemon = Daemon()
daemon.main()
if log_power is not None: log_power=open(log_power,'r')
try:
daemon = Daemon(power_discretization=power_discretization,
enforce_powerpolicy=enforce_powerpolicy,
lowerboundwatts=lowerboundwatts,
exploration_constant=exploration_constant,
log_power=log_power)
daemon.main()
if log_power!=None:
close(log_power,'r')
except:
if log_power!=None:
close(log_power,'r')
......@@ -20,6 +20,6 @@ setup(
],
packages=find_packages(),
install_requires=['six', 'pyzmq', 'tornado', 'numpy'],
install_requires=['six', 'pyzmq', 'tornado', 'numpy', 'docopt'],
scripts=['bin/daemon', 'bin/app', 'bin/cmd', 'bin/argo-perf-wrapper']
)
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