Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nrm
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
16
Issues
16
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
argo
nrm
Commits
c2f4dab0
Commit
c2f4dab0
authored
Dec 07, 2018
by
Valentin Reis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adding some of the power-expe code.
parent
e992a7f1
Pipeline
#4566
failed with stages
in 2 minutes and 18 seconds
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
61 additions
and
31 deletions
+61
-31
nrm/controller.py
nrm/controller.py
+46
-25
nrm/daemon.py
nrm/daemon.py
+6
-5
nrm/subprograms.py
nrm/subprograms.py
+9
-1
No files found.
nrm/controller.py
View file @
c2f4dab0
...
...
@@ -2,10 +2,12 @@ from __future__ import print_function
import
logging
import
time
import
math
logger
=
logging
.
getLogger
(
'nrm'
)
logger_power
=
logging
.
getLogger
(
'power'
)
class
Action
(
object
):
"""Information about a control action."""
...
...
@@ -15,6 +17,7 @@ class Action(object):
self
.
command
=
command
self
.
delta
=
delta
class
PowerActuator
(
object
):
"""Actuator in charge of power control."""
...
...
@@ -41,7 +44,41 @@ class PowerActuator(object):
action
.
command
,
action
.
delta
,
action
.
target
)
# sensor_manager is a SensorManager, which is not only about sensing
# 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
):
pass
...
...
@@ -51,34 +88,18 @@ class Controller(object):
"""Implements a control loop for resource management."""
def
__init__
(
self
,
actuators
):
def
__init__
(
self
,
actuators
,
strategy
):
self
.
actuators
=
actuators
def
planify
(
self
,
target
,
machineinfo
):
"""Plan the next action for the control loop."""
# current_e = float(machineinfo['energy']['energy']['cumulative']['package-0'])/(1000*1000) # in joules
current_p
=
float
(
machineinfo
[
'energy'
][
'power'
][
'p0'
])
/
(
1000
*
1000
)
# in joules
current_p
=
float
(
machineinfo
[
'energy'
][
'power'
][
'p1'
])
/
(
1000
*
1000
)
# in joules
logger_power
.
info
(
"%s %s %s"
%
(
time
.
time
(),
current_p
,
current_p
))
return
(
None
,
None
)
# direction = 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)
# current_e = float(machineinfo['energy']['energy']
# ['cumulative']['package-0'])/(1000*1000) # in joules
# In joules:
current_p
=
float
(
machineinfo
[
'energy'
][
'power'
][
'p0'
])
/
(
1000
*
1000
)
current_p
=
float
(
machineinfo
[
'energy'
][
'power'
][
'p1'
])
/
(
1000
*
1000
)
logger_power
.
info
(
"%s %s %s"
%
(
time
.
time
(),
current_p
,
current_p
))
return
(
None
,
None
)
def
execute
(
self
,
action
,
actuator
):
"""Build the action for the appropriate manager."""
...
...
nrm/daemon.py
View file @
c2f4dab0
...
...
@@ -2,7 +2,7 @@ from __future__ import print_function
from
applications
import
ApplicationManager
from
containers
import
ContainerManager
from
controller
import
Controller
,
PowerActuator
from
controller
import
Controller
,
PowerActuator
,
DiscretizedPowerActuator
from
powerpolicy
import
PowerPolicyManager
from
functools
import
partial
import
json
...
...
@@ -169,7 +169,9 @@ class Daemon(object):
logger
.
info
(
"sending sensor message: %r"
,
msg
)
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
)
logger
.
info
(
"Controller chose plan "
+
str
(
plan
))
action
,
actuator
=
plan
...
...
@@ -259,7 +261,6 @@ class Daemon(object):
def
do_shutdown
(
self
):
self
.
sensor_manager
.
stop
()
ioloop
.
IOLoop
.
current
().
stop
()
context
.
term
()
def
main
(
self
):
# Bind address for downstream clients
...
...
@@ -303,7 +304,8 @@ class Daemon(object):
self
.
container_manager
=
ContainerManager
(
self
.
resource_manager
)
self
.
application_manager
=
ApplicationManager
()
self
.
sensor_manager
=
SensorManager
()
pa
=
PowerActuator
(
self
.
sensor_manager
)
pa
=
PowerActuator
(
self
.
sensor_manager
,
strategy
=
self
.
config
[
'powerlevel'
])
self
.
controller
=
Controller
([
pa
])
self
.
sensor_manager
.
start
()
...
...
@@ -322,7 +324,6 @@ class Daemon(object):
signal
.
signal
(
signal
.
SIGCHLD
,
self
.
do_signal
)
ioloop
.
IOLoop
.
current
().
start
()
context
.
term
()
def
runner
(
config
):
...
...
nrm/subprograms.py
View file @
c2f4dab0
...
...
@@ -4,6 +4,7 @@ import logging
import
xml.etree.ElementTree
import
tornado.process
as
process
import
subprocess
import
os
logger
=
logging
.
getLogger
(
'nrm'
)
resources
=
collections
.
namedtuple
(
"Resources"
,
[
"cpus"
,
"mems"
])
...
...
@@ -42,7 +43,14 @@ class NodeOSClient(object):
def
__init__
(
self
):
"""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
):
"""Gather available resources."""
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment