Skip to content
This repository was archived by the owner on Mar 11, 2019. It is now read-only.

Commit 25322e1

Browse files
committed
Merge pull request #73 from Spirals-Team/feature/g5k-sensor
feature(g5k-sensor): implement the external powermeter OmegaWatt (fro…
2 parents 6c7d295 + 888ab01 commit 25322e1

File tree

24 files changed

+492
-193
lines changed

24 files changed

+492
-193
lines changed

powerapi-cli/src/main/scala/org/powerapi/app/PowerAPI.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ import org.powerapi.core.power._
3131
import org.powerapi.module.cpu.dvfs.CpuDvfsModule
3232
import org.powerapi.module.cpu.simple.{SigarCpuSimpleModule, ProcFSCpuSimpleModule}
3333
import org.powerapi.module.libpfm.{LibpfmModule, LibpfmHelper, LibpfmCoreProcessModule, LibpfmCoreModule, LibpfmProcessModule}
34-
import org.powerapi.module.powerspy.PowerSpyModule
34+
import org.powerapi.module.extPMeter.powerspy.PowerSpyModule
35+
import org.powerapi.module.extPMeter.g5k.G5kOmegaWattModule
3536
import scala.concurrent.duration.DurationInt
3637
import scala.sys
3738
import scala.sys.process.stringSeqToProcess
@@ -43,7 +44,7 @@ import scala.sys.process.stringSeqToProcess
4344
* @author <a href="mailto:l.huertas.pro@gmail.com">Loïc Huertas</a>
4445
*/
4546
object PowerAPI extends App {
46-
val modulesR = """(procfs-cpu-simple|sigar-cpu-simple|cpu-dvfs|libpfm|libpfm-process|libpfm-core|libpfm-core-process|powerspy|rapl)(,(procfs-cpu-simple|sigar-cpu-simple|cpu-dvfs|libpfm|libpfm-process|libpfm-core|libpfm-core-process|powerspy|rapl))*""".r
47+
val modulesR = """(procfs-cpu-simple|sigar-cpu-simple|cpu-dvfs|libpfm|libpfm-process|libpfm-core|libpfm-core-process|powerspy|g5k-omegawatt|rapl)(,(procfs-cpu-simple|sigar-cpu-simple|cpu-dvfs|libpfm|libpfm-process|libpfm-core|libpfm-core-process|powerspy|g5k-omegawatt|rapl))*""".r
4748
val aggR = """max|min|geomean|logsum|mean|median|stdev|sum|variance""".r
4849
val durationR = """\d+""".r
4950
val pidR = """(\d+)""".r
@@ -113,7 +114,7 @@ object PowerAPI extends App {
113114
|You can use different settings per software-defined power meter for some modules by using the optional prefix option.
114115
|Please, refer to the documentation inside the GitHub wiki for further details.
115116
|
116-
|usage: ./powerapi modules [procfs-cpu-simple|sigar-cpu-simple|cpu-dvfs|libpfm|libpfm-process|libpfm-core|libpfm-core-proces|powerspy|rapl,...] *--prefix [name]* \
117+
|usage: ./powerapi modules [procfs-cpu-simple|sigar-cpu-simple|cpu-dvfs|libpfm|libpfm-process|libpfm-core|libpfm-core-proces|powerspy|g5k-omegawatt|rapl,...] *--prefix [name]* \
117118
| monitor --frequency [ms] --targets [pid, ..., app, ...|all] --agg [max|min|geomean|logsum|mean|median|stdev|sum|variance] --[console,file [filepath],chart] \
118119
| duration [s]
119120
|
@@ -180,7 +181,8 @@ object PowerAPI extends App {
180181
case "libpfm-process" => LibpfmProcessModule(powerMeterConf('prefix).asInstanceOf[Option[String]], libpfmHelper.get)
181182
case "libpfm-core" => LibpfmCoreModule(powerMeterConf('prefix).asInstanceOf[Option[String]], libpfmHelper.get)
182183
case "libpfm-core-process" => LibpfmCoreProcessModule(powerMeterConf('prefix).asInstanceOf[Option[String]], libpfmHelper.get)
183-
case "powerspy" => PowerSpyModule()
184+
case "powerspy" => PowerSpyModule(powerMeterConf('prefix).asInstanceOf[Option[String]])
185+
case "g5k-omegawatt" => G5kOmegaWattModule(powerMeterConf('prefix).asInstanceOf[Option[String]])
184186
case "rapl" => RAPLModule()
185187
}
186188
}).toSeq

powerapi-core/src/main/scala/org/powerapi/core/ExternalPMeter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ package org.powerapi.core
2828
* @author <a href="mailto:maxime.colmant@gmail.com">Maxime Colmant</a>
2929
*/
3030
trait ExternalPMeter {
31-
def init(): Unit
31+
def init(bus: MessageBus): Unit
3232
def start(): Unit
3333
def stop(): Unit
3434
}

powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyChannel.scala renamed to powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterChannel.scala

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,59 +20,60 @@
2020
*
2121
* If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
2222
*/
23-
package org.powerapi.module.powerspy
23+
package org.powerapi.module.extPMeter
2424

2525
import akka.actor.ActorRef
2626
import org.powerapi.core.{Channel, Message, MessageBus}
2727
import org.powerapi.core.power.Power
2828

2929
/**
30-
* PowerSpyChannel channel and messages.
30+
* ExtPMeterChannel channel and messages.
3131
*
3232
* @author <a href="mailto:maxime.colmant@gmail.com">Maxime Colmant</a>
33+
* @author <a href="mailto:l.huertas.pro@gmail.com">Loïc Huertas</a>
3334
*/
34-
object PowerSpyChannel extends Channel {
35+
object ExtPMeterChannel extends Channel {
3536

36-
type M = PowerSpyPower
37+
type M = ExtPMeterPower
3738

3839
/**
39-
* PowerSpyPower is represented as a dedicated type of message.
40+
* ExtPMeterPower is represented as a dedicated type of message.
4041
*
4142
* @param topic: subject used for routing the message.
4243
* @param power: power consumption got by an external device.
4344
*/
44-
case class PowerSpyPower(topic: String,
45-
power: Power) extends Message
45+
case class ExtPMeterPower(topic: String,
46+
power: Power) extends Message
4647

4748
/**
4849
* Topic for communicating with the Sensor actor.
4950
*/
50-
private val pMeterTopic = "powerspy:power"
51+
private val pMeterTopic = "extpmeter:power"
5152

5253
/**
5354
* Topic for communicating with the Formula actor.
5455
*/
55-
private val topic = "sensor:powerspy"
56+
private val topic = "sensor:extpmeter"
5657

5758
/**
58-
* Publish a PowerSpyPower in the event bus.
59+
* Publish a ExtPMeterPower in the event bus.
5960
*/
60-
def publishExternalPowerSpyPower(power: Power): MessageBus => Unit = {
61-
publish(PowerSpyPower(pMeterTopic, power))
61+
def publishExternalPMeterPower(power: Power): MessageBus => Unit = {
62+
publish(ExtPMeterPower(pMeterTopic, power))
6263
}
6364

64-
def publishPowerSpyPower(power: Power): MessageBus => Unit = {
65-
publish(PowerSpyPower(topic, power))
65+
def publishPMeterPower(power: Power): MessageBus => Unit = {
66+
publish(ExtPMeterPower(topic, power))
6667
}
6768

6869
/**
6970
* External methods used for interacting with the bus.
7071
*/
71-
def subscribeExternalPowerSpyPower: MessageBus => ActorRef => Unit = {
72+
def subscribeExternalPMeterPower: MessageBus => ActorRef => Unit = {
7273
subscribe(pMeterTopic)
7374
}
7475

75-
def subscribePowerSpyPower: MessageBus => ActorRef => Unit = {
76+
def subscribePMeterPower: MessageBus => ActorRef => Unit = {
7677
subscribe(topic)
7778
}
7879
}

powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyFormula.scala renamed to powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterFormula.scala

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*
2121
* If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
2222
*/
23-
package org.powerapi.module.powerspy
23+
package org.powerapi.module.extPMeter
2424

2525
import akka.event.LoggingReceive
2626
import org.powerapi.core.{OSHelper, APIComponent, MessageBus}
@@ -29,7 +29,7 @@ import org.powerapi.core.power._
2929
import org.powerapi.core.target.{Application, All, Process, TargetUsageRatio}
3030
import org.powerapi.module.{Cache, CacheKey}
3131
import org.powerapi.module.PowerChannel.publishRawPowerReport
32-
import org.powerapi.module.powerspy.PowerSpyChannel.{PowerSpyPower, subscribePowerSpyPower}
32+
import org.powerapi.module.extPMeter.ExtPMeterChannel.{ExtPMeterPower, subscribePMeterPower}
3333
import scala.reflect.ClassTag
3434

3535
/**
@@ -39,20 +39,21 @@ import scala.reflect.ClassTag
3939
* The simple CpuSensor is used for getting the Target cpu usage ratio (UsageReport).
4040
*
4141
* @author <a href="mailto:maxime.colmant@gmail.com">Maxime Colmant</a>
42+
* @author <a href="mailto:l.huertas.pro@gmail.com">Loïc Huertas</a>
4243
*/
43-
class PowerSpyFormula(eventBus: MessageBus, osHelper: OSHelper, idlePower: Power) extends APIComponent {
44+
class ExtPMeterFormula(eventBus: MessageBus, osHelper: OSHelper, idlePower: Power) extends APIComponent {
4445

4546
override def preStart(): Unit = {
46-
subscribePowerSpyPower(eventBus)(self)
47+
subscribePMeterPower(eventBus)(self)
4748
subscribeMonitorTick(eventBus)(self)
4849
super.preStart()
4950
}
5051

5152
def receive: PartialFunction[Any, Unit] = running(None)
5253

53-
def running(pspyPower: Option[PowerSpyPower]): PartialFunction[Any, Unit] = LoggingReceive {
54-
case msg: PowerSpyPower => context.become(running(Some(msg)))
55-
case msg: MonitorTick => compute(pspyPower, msg)
54+
def running(epmPower: Option[ExtPMeterPower]): PartialFunction[Any, Unit] = LoggingReceive {
55+
case msg: ExtPMeterPower => context.become(running(Some(msg)))
56+
case msg: MonitorTick => compute(epmPower, msg)
5657
} orElse default
5758

5859
// In order to compute the target's ratio
@@ -98,17 +99,17 @@ class PowerSpyFormula(eventBus: MessageBus, osHelper: OSHelper, idlePower: Power
9899
}
99100
}
100101

101-
def compute(pSpyPower: Option[PowerSpyPower], monitorTick: MonitorTick): Unit = {
102-
pSpyPower match {
102+
def compute(epmPower: Option[ExtPMeterPower], monitorTick: MonitorTick): Unit = {
103+
epmPower match {
103104
case Some(pPower) => {
104105
lazy val dynamicP = if(pPower.power.toMilliWatts - idlePower.toMilliWatts > 0) pPower.power - idlePower else 0.W
105106

106107
monitorTick.target match {
107-
case All => publishRawPowerReport(monitorTick.muid, monitorTick.target, pPower.power, "PowerSpy", monitorTick.tick)(eventBus)
108-
case _ => publishRawPowerReport(monitorTick.muid, monitorTick.target, dynamicP * targetCpuUsageRatio(monitorTick).ratio, "PowerSpy", monitorTick.tick)(eventBus)
108+
case All => publishRawPowerReport(monitorTick.muid, monitorTick.target, pPower.power, "ExtPMeter", monitorTick.tick)(eventBus)
109+
case _ => publishRawPowerReport(monitorTick.muid, monitorTick.target, dynamicP * targetCpuUsageRatio(monitorTick).ratio, "ExtPMeter", monitorTick.tick)(eventBus)
109110
}
110111
}
111-
case _ => log.debug("{}", "no PowerSpyPower message received")
112+
case _ => log.debug("{}", "no ExtPMeterPower message received")
112113
}
113114
}
114115
}

powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyFormulaConfiguration.scala renamed to powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterFormulaConfiguration.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*
2121
* If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
2222
*/
23-
package org.powerapi.module.powerspy
23+
package org.powerapi.module.extPMeter
2424

2525
import org.powerapi.core.{Configuration, ConfigValue}
2626
import org.powerapi.core.power._
@@ -29,8 +29,9 @@ import org.powerapi.core.power._
2929
* Main configuration.
3030
*
3131
* @author <a href="mailto:maxime.colmant@gmail.com">Maxime Colmant</a>
32+
* @author <a href="mailto:l.huertas.pro@gmail.com">Loïc Huertas</a>
3233
*/
33-
trait PowerSpyFormulaConfiguration extends Configuration {
34+
trait ExtPMeterFormulaConfiguration extends Configuration {
3435
lazy val idlePower = load { _.getDouble(s"powerapi.hardware.idle-power") } match {
3536
case ConfigValue(idle) => idle.W
3637
case _ => 0.W

powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyModule.scala renamed to powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterModule.scala

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,17 @@
2020
*
2121
* If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
2222
*/
23-
package org.powerapi.module.powerspy
23+
package org.powerapi.module.extPMeter
2424

2525
import org.powerapi.PowerModule
26-
import org.powerapi.core.{OSHelper, LinuxHelper}
26+
import org.powerapi.core.{ExternalPMeter, OSHelper}
2727
import org.powerapi.core.power.Power
2828
import scala.concurrent.duration.FiniteDuration
2929

30-
class PowerSpyModule(osHelper: OSHelper, mac: String, interval: FiniteDuration, idlePower: Power) extends PowerModule {
30+
class ExtPMeterModule(osHelper: OSHelper, extPMeter: ExternalPMeter, idlePower: Power) extends PowerModule {
3131
lazy val underlyingClasses = eventBus match {
3232
case Some(bus) => {
33-
(Seq((classOf[PowerSpySensor], Seq(new PowerSpyPMeter(bus, mac, interval)))), Seq((classOf[PowerSpyFormula], Seq(osHelper, idlePower))))
33+
(Seq((classOf[ExtPMeterSensor], Seq(extPMeter))), Seq((classOf[ExtPMeterFormula], Seq(osHelper, idlePower))))
3434
}
3535
case _ => (Seq(), Seq())
3636
}
@@ -39,10 +39,3 @@ class PowerSpyModule(osHelper: OSHelper, mac: String, interval: FiniteDuration,
3939
lazy val underlyingFormulaeClasses = underlyingClasses._2
4040
}
4141

42-
object PowerSpyModule extends PowerSpyFormulaConfiguration with PowerSpyPMeterConfiguration {
43-
def apply(): PowerSpyModule = {
44-
val linuxHelper = new LinuxHelper
45-
46-
new PowerSpyModule(linuxHelper, mac, interval, idlePower)
47-
}
48-
}

powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpySensor.scala renamed to powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterSensor.scala

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,23 @@
2020
*
2121
* If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
2222
*/
23-
package org.powerapi.module.powerspy
23+
package org.powerapi.module.extPMeter
2424

2525
import akka.event.LoggingReceive
2626
import org.powerapi.core.{ExternalPMeter, MessageBus, APIComponent}
27-
import org.powerapi.module.powerspy.PowerSpyChannel.{PowerSpyPower, publishPowerSpyPower, subscribeExternalPowerSpyPower}
27+
import org.powerapi.module.extPMeter.ExtPMeterChannel.{ExtPMeterPower, publishPMeterPower, subscribeExternalPMeterPower}
2828

2929
/**
30-
* PowerSpySensor's implementation by using an helper.
30+
* ExtPMeterSensor's implementation by using an helper.
3131
*
3232
* @author <a href="mailto:maxime.colmant@gmail.com">Maxime Colmant</a>
33+
* @author <a href="mailto:l.huertas.pro@gmail.com">Loïc Huertas</a>
3334
*/
34-
class PowerSpySensor(eventBus: MessageBus, pMeter: ExternalPMeter) extends APIComponent {
35+
class ExtPMeterSensor(eventBus: MessageBus, pMeter: ExternalPMeter) extends APIComponent {
3536

3637
override def preStart(): Unit = {
37-
subscribeExternalPowerSpyPower(eventBus)(self)
38-
pMeter.init()
38+
subscribeExternalPMeterPower(eventBus)(self)
39+
pMeter.init(eventBus)
3940
pMeter.start()
4041
super.preStart()
4142
}
@@ -46,10 +47,10 @@ class PowerSpySensor(eventBus: MessageBus, pMeter: ExternalPMeter) extends APICo
4647
}
4748

4849
def receive: PartialFunction[Any, Unit] = LoggingReceive {
49-
case msg: PowerSpyPower => sense(msg)
50+
case msg: ExtPMeterPower => sense(msg)
5051
} orElse default
5152

52-
def sense(pSpyPower: PowerSpyPower): Unit = {
53-
publishPowerSpyPower(pSpyPower.power)(eventBus)
53+
def sense(epmPower: ExtPMeterPower): Unit = {
54+
publishPMeterPower(epmPower.power)(eventBus)
5455
}
5556
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* This software is licensed under the GNU Affero General Public License, quoted below.
3+
*
4+
* This file is a part of PowerAPI.
5+
*
6+
* Copyright (C) 2011-2015 Inria, University of Lille 1.
7+
*
8+
* PowerAPI is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU Affero General Public License as
10+
* published by the Free Software Foundation, either version 3 of
11+
* the License, or (at your option) any later version.
12+
*
13+
* PowerAPI is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU Affero General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU Affero General Public License
19+
* along with PowerAPI.
20+
*
21+
* If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
22+
*/
23+
package org.powerapi.module.extPMeter.g5k
24+
25+
import org.powerapi.core.LinuxHelper
26+
import org.powerapi.module.extPMeter.{ExtPMeterFormulaConfiguration, ExtPMeterModule}
27+
28+
object G5kOmegaWattModule extends ExtPMeterFormulaConfiguration {
29+
def apply(prefixConfig: Option[String] = None): ExtPMeterModule = {
30+
val conf = new G5kPMeterConfiguration(prefixConfig)
31+
val linuxHelper = new LinuxHelper
32+
33+
new ExtPMeterModule(linuxHelper, new G5kPMeter(conf.probe, conf.interval), idlePower)
34+
}
35+
}

0 commit comments

Comments
 (0)