[ref] added Publisher and SimConfig trait

- Publisher trait allows simulation to publish and Output to subscribe
 - Simconfig trait wraps simulation config settings
This commit is contained in:
2020-01-29 01:19:11 -06:00
parent a5ced64f35
commit 0d651019c9
4 changed files with 47 additions and 15 deletions

View File

@@ -4,11 +4,10 @@ import scim.datastruct.{Cell, Group, SensorResult, SharedMemory, Time, Truth}
class Output(sharedMemory: SharedMemory, printOutput: Boolean = true) extends Runnable {
def run(): Unit = {
val outputBroadcast = sharedMemory.output
val duration = sharedMemory.config.duration
def outputHelper(time: Time): Unit = {
outputBroadcast(time.time).watch()
outputData(time, sharedMemory.getResult(time), sharedMemory.getTruth(time))
val simOutput = sharedMemory.subscribe(time)
outputData(time, simOutput._1, simOutput._2)
}
Vector.tabulate(sharedMemory.config.duration)(t => Time(t, duration)).foreach(outputHelper)

View File

@@ -6,13 +6,15 @@ import scim.lib.debugUtil.{DebugType, debug, debugf}
class Simulation(config: Configuration) {
private val sharedMemory = config.sharedMemory
private val sharedConfig = sharedMemory.config
//private val sharedConfig = sharedMemory.config
private val cells = config.cells
val output = sharedMemory.output
private val parallelizeCellMin = config.getCellThreadConfig._1
private val parallelizeCellThreadPool = config.getCellThreadConfig._2
private val parallelizeGroupMin = config.getGroupThreadConfig._1
private val parallelizeGroupThreadPool = config.getGroupThreadConfig._2
def start(): Unit = {
val duration = sharedConfig.duration
val duration = config.getDuration
val timeVector = Vector.tabulate(duration)(t => Time(t, duration))
def simTime(time: Time): Unit = {
// FIXME: really shouldn't have to .map(kv => kv._1 -> kv._2) to get an immutable map, in fact it shouldn't even be mutable in the first place...
@@ -36,15 +38,15 @@ class Simulation(config: Configuration) {
val configTruth = if(sharedMemory.groundTruthConfig.contains(time)) Some(sharedMemory.groundTruthConfig(time)) else None
simGroups(time, cell, groups, configTruth, prevTruths(cell), resultTruths(cell), sensorResults(cell))
}
if(sharedConfig.parCell != 0 && cells.size >= sharedConfig.parCell ) {
if(parallelizeCellMin != 0 && cells.size >= parallelizeCellMin ) {
val cellList = cells.par
cellList.tasksupport = sharedConfig.cellThreadPool
cellList.tasksupport = parallelizeCellThreadPool
cellList.foreach(simCell)
} else {
cells.foreach(simCell)
}
// broadcast the results
output(time.time).broadcast(true)
sharedMemory.publish(time)
}
private def simGroups(time: Time, cell: Cell, groups: Map[Group, List[(Group, Sensor, Option[GroundTruth])]], configTruths: Option[Map[Group, Truth]], PrevTruths: Map[Group, Truth], resultTruths: Map[Group, Truth], resultSensors: Map[Group, Vector[SensorResult]]): Unit = {
@@ -73,9 +75,9 @@ class Simulation(config: Configuration) {
simulate(time, cell, prevTruth, resTruth, restSens, element)
})
}
if(sharedConfig.parGroup != 0 && cells.size >= sharedConfig.parGroup ) {
if(parallelizeGroupMin != 0 && cells.size >= parallelizeGroupMin ) {
val groupList = groups.par
groupList.tasksupport = sharedConfig.groupThreadPool
groupList.tasksupport = parallelizeGroupThreadPool
groupList.foreach(simGroup)
} else {
groups.foreach(simGroup)

View File

@@ -29,7 +29,7 @@ case class SharedMemory(sensor: Map[Time, Map[Cell, Map[Group, Vector[SensorResu
groundTruthConfig: Map[Time, Map[Group, Truth]],
config: SimulationConfig,
groups: Map[String, Group],
output: Vector[BroadcastObject[Boolean]]) {
private val output: Vector[BroadcastObject[Boolean]]) extends Publisher {
// memory optimization: remove sensor and throw output into output
// only map Truths from config into groundtruth, do a if groundTruth.contains(time) groundTruth(time) else prevTruth in case of time.start Truth(None) (or better map it to time.start anyways in parser)
// can drop cell from ground truth
@@ -57,6 +57,14 @@ case class SharedMemory(sensor: Map[Time, Map[Cell, Map[Group, Vector[SensorResu
groundTruth.foreach(kv => kv._2.foreach(kv2 => kv2._2.foreach(kv3 => kv3._2.reset())))
output.foreach(e => e.broadcastReset())
}
def subscribe(time: Time): SimulationOutput = {
output(time.time).watch()
(getResult(time), getTruth(time))
}
def publish(time: Time): Unit = {
output(time.time).broadcast(true)
}
}
case class SimulationBehaviours(functions: Map[String, SimulationBehaviour]) {
@@ -177,5 +185,12 @@ case class SensorCount(count: Int) {
}
// NOTE: The Group is actually obsolete in the Tuple3 as Sensor and GroundTruth hold theirs (unless removed from their case class)
case class Configuration(cells: Map[Cell, Map[Group, List[(Group, Sensor, Option[GroundTruth])]]], sharedMemory: SharedMemory)
case class Configuration(cells: Map[Cell, Map[Group, List[(Group, Sensor, Option[GroundTruth])]]], sharedMemory: SharedMemory) extends SimConfig {
def getDuration: Int = sharedMemory.config.duration
def getRuns: Int = sharedMemory.config.runs
def getTickFactor: Int = sharedMemory.config.tickfactor
def getCellThreadConfig: (Int, ForkJoinTaskSupport) = (sharedMemory.config.parCell, sharedMemory.config.cellThreadPool)
def getGroupThreadConfig: (Int, ForkJoinTaskSupport) = (sharedMemory.config.parGroup, sharedMemory.config.groupThreadPool)
def getSensorThreadConfig: (Int, ForkJoinTaskSupport) = (sharedMemory.config.parSensor, sharedMemory.config.sensorThreadPool)
}

View File

@@ -1,6 +1,7 @@
package scim.lib
import scim.datastruct.{Behaviour, Cell, Group, SensorCount, SensorResult, Time, Truth}
import scim.lib.simInterfaces.SimulationOutput
import scala.collection.parallel.ForkJoinTaskSupport
@@ -8,11 +9,26 @@ package object simInterfaces {
import scim.datastruct._
// maybe change to by-name parameters? have to check performance gain
type SimulationBehaviour = (Cell, Time, Option[Double], Option[FunctionArgs]) => Option[Double]
type SimulationOutput = (Map[Cell, Map[Group, Vector[SensorResult]]], Map[Cell, Map[Group, Truth]])
}
package object configInterfaces {
trait Publisher {
def subscribe(time: Time): SimulationOutput
def publish(time: Time): Unit
def outputReset(): Unit
}
trait SimConfig {
def getDuration: Int
def getRuns: Int
def getTickFactor: Int
def getCellThreadConfig: (Int, ForkJoinTaskSupport)
def getGroupThreadConfig: (Int, ForkJoinTaskSupport)
def getSensorThreadConfig: (Int, ForkJoinTaskSupport)
}
trait Result[A] {
val result = new scim.lib.ConcurrentBroadcast.BroadcastObject[A]()
def get: A = {