[mod] reduced memory footprint of output and reset everything after a run
- instead of copying the output, a vector indicates if a time is done - a full run has to be consumed by the output before the next
This commit is contained in:
@@ -28,7 +28,7 @@ object Main {
|
|||||||
|
|
||||||
//lib.evalUtil.time("par", parlist.par.map({_ => Thread.sleep(10); 2}))
|
//lib.evalUtil.time("par", parlist.par.map({_ => Thread.sleep(10); 2}))
|
||||||
//lib.evalUtil.time("ser", parlist.map({_ => Thread.sleep(10); 2}))
|
//lib.evalUtil.time("ser", parlist.map({_ => Thread.sleep(10); 2}))
|
||||||
|
//startSimulation()
|
||||||
}
|
}
|
||||||
|
|
||||||
def startSimulation(): Unit = {
|
def startSimulation(): Unit = {
|
||||||
@@ -42,6 +42,7 @@ object Main {
|
|||||||
outputThread.start()
|
outputThread.start()
|
||||||
simulator.start()
|
simulator.start()
|
||||||
outputThread.join()
|
outputThread.join()
|
||||||
|
sharedMemory.outputReset()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,22 @@
|
|||||||
package scim.components
|
package scim.components
|
||||||
|
|
||||||
import scim.datastruct.{Cell, Group, SensorResult, SharedMemory}
|
import scim.datastruct.{Cell, Group, SensorResult, SharedMemory, Time, Truth}
|
||||||
|
|
||||||
class Output(sharedMemory: SharedMemory) extends Runnable {
|
class Output(sharedMemory: SharedMemory) extends Runnable {
|
||||||
def run(): Unit = {
|
def run(): Unit = {
|
||||||
val output = sharedMemory.output
|
val outputBroadcast = sharedMemory.output
|
||||||
(0 until output.size, output).zipped.foreach((time, result) => outputData(time, result.watch()))
|
val duration = sharedMemory.config.duration
|
||||||
|
def outputHelper(time: Time): Unit = {
|
||||||
|
outputBroadcast(time.time).watch()
|
||||||
|
outputData(time, sharedMemory.getResult(time), sharedMemory.getTruth(time))
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector.tabulate(sharedMemory.config.duration)(t => Time(t, duration)).foreach(outputHelper)
|
||||||
}
|
}
|
||||||
|
|
||||||
def outputData(time: Int, output: Map[Cell, Map[Group, Vector[SensorResult]]]): Unit = {
|
def outputData(time: Time, sensors: Map[Cell, Map[Group, Vector[SensorResult]]], groundTruths: Map[Cell, Map[Group, Truth]]): Unit = {
|
||||||
println("TICK: " + time)
|
println("TICK: " + time)
|
||||||
println(output)
|
println(sensors)
|
||||||
|
println(groundTruths)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class Simulation(config: Configuration) {
|
|||||||
cells.foreach(simCell)
|
cells.foreach(simCell)
|
||||||
}
|
}
|
||||||
// broadcast the results
|
// broadcast the results
|
||||||
output(time.time).broadcast(sensorResults)
|
output(time.time).broadcast(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private def simGroups(time: Time, cell: Cell, groups: Map[Group, List[(Group, Sensor, Option[GroundTruth])]], prevTruths: Map[Group, Truth], resultTruths: Map[Group, Truth], resultSensors: Map[Group, Vector[SensorResult]]): Unit = {
|
private def simGroups(time: Time, cell: Cell, groups: Map[Group, List[(Group, Sensor, Option[GroundTruth])]], prevTruths: Map[Group, Truth], resultTruths: Map[Group, Truth], resultSensors: Map[Group, Vector[SensorResult]]): Unit = {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package scim.datastruct
|
|||||||
|
|
||||||
import scim.lib.ConcurrentBroadcast.BroadcastObject
|
import scim.lib.ConcurrentBroadcast.BroadcastObject
|
||||||
import scim.lib.simulation._
|
import scim.lib.simulation._
|
||||||
|
|
||||||
import scala.collection.parallel.ForkJoinTaskSupport
|
import scala.collection.parallel.ForkJoinTaskSupport
|
||||||
|
|
||||||
// configuration
|
// configuration
|
||||||
@@ -21,23 +22,30 @@ case class Time(time: Int, duration: Int){
|
|||||||
case class SharedMemory(sensor: Map[Time, Map[Cell, Map[Group, Vector[SensorResult]]]],
|
case class SharedMemory(sensor: Map[Time, Map[Cell, Map[Group, Vector[SensorResult]]]],
|
||||||
groundTruth: Map[Time, Map[Cell, Map[Group, Truth]]],
|
groundTruth: Map[Time, Map[Cell, Map[Group, Truth]]],
|
||||||
config: SimulationConfig,
|
config: SimulationConfig,
|
||||||
output: Vector[BroadcastObject[Map[Cell, Map[Group, Vector[SensorResult]]]]]) {
|
output: Vector[BroadcastObject[Boolean]]) {
|
||||||
// This could be spatially optimized to have a function to invoke a new simulation tick
|
// This could be spatially optimized to have a function to invoke a new simulation tick
|
||||||
// a template of Map[SensorID, SensorResult] would have to be kept and deep copied when
|
// a template of Map[Cell, Map[Group, Vector[SensorResult]]] would have to be kept and deep copied when
|
||||||
// another tick is simulated. this won't work for ground truth, as it may already be defined
|
// another tick is simulated. this won't work for ground truth, as it may already be defined
|
||||||
// through the configuration. it can however be deleted once it is no longer required, tho this seems
|
// through the configuration throughout the entire simulation. it can however be deleted once it is no longer
|
||||||
// to be rather unbeneficial, as the space was already preallocated. Sensors however could be replaced
|
// required, tho this seems to be rather unbeneficial, as the space was already preallocated.
|
||||||
// or deleted, depending if a buffer or list is used.
|
// Sensors however could be replaced or deleted, depending if a buffer or list is used. in a producer/consumer manner
|
||||||
|
|
||||||
def getTruth(time: Time, cell: Cell, group: Group): Truth = {
|
def getTruth(time: Time, cell: Cell, group: Group): Truth = {
|
||||||
groundTruth(time)(cell)(group)
|
groundTruth(time)(cell)(group)
|
||||||
}
|
}
|
||||||
|
def getTruth(time: Time): Map[Cell, Map[Group, Truth]] = {
|
||||||
|
groundTruth(time)
|
||||||
|
}
|
||||||
def getResult(time: Time, cell: Cell, group: Group): Vector[SensorResult] = {
|
def getResult(time: Time, cell: Cell, group: Group): Vector[SensorResult] = {
|
||||||
sensor(time)(cell)(group)
|
sensor(time)(cell)(group)
|
||||||
}
|
}
|
||||||
def getAllResults(time: Time): Map[Cell, Map[Group, Vector[SensorResult]]] = {
|
def getResult(time: Time): Map[Cell, Map[Group, Vector[SensorResult]]] = {
|
||||||
sensor(time)
|
sensor(time)
|
||||||
}
|
}
|
||||||
|
def outputReset(): Unit = {
|
||||||
|
sensor.foreach(kv => kv._2.foreach(kv2 => kv2._2.foreach(kv3 => kv3._2.foreach(res => res.reset()))))
|
||||||
|
groundTruth.foreach(kv => kv._2.foreach(kv2 => kv2._2.foreach(kv3 => kv3._2.reset())))
|
||||||
|
output.foreach(e => e.broadcastReset())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class BroadcastHandler[A](broadcastObject: BroadcastObject[A]) {
|
abstract class BroadcastHandler[A](broadcastObject: BroadcastObject[A]) {
|
||||||
@@ -50,6 +58,9 @@ abstract class BroadcastHandler[A](broadcastObject: BroadcastObject[A]) {
|
|||||||
def exists: Boolean = {
|
def exists: Boolean = {
|
||||||
!broadcastObject.peak().isEmpty
|
!broadcastObject.peak().isEmpty
|
||||||
}
|
}
|
||||||
|
def reset(): Unit = {
|
||||||
|
broadcastObject.broadcastReset()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case class SimulationBehaviours(functions: Map[String, SimulationBehaviour]) {
|
case class SimulationBehaviours(functions: Map[String, SimulationBehaviour]) {
|
||||||
def get(name: String): Option[SimulationBehaviour] = {
|
def get(name: String): Option[SimulationBehaviour] = {
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ object ScalaLocks {
|
|||||||
|
|
||||||
object ConcurrentBroadcast {
|
object ConcurrentBroadcast {
|
||||||
|
|
||||||
|
// WARNING: Type A should be immutable and not hold any mutable data
|
||||||
|
// could add a clone/copy when retrieving for AnyRef types
|
||||||
class BroadcastObject[A](default: Option[A] = None) {
|
class BroadcastObject[A](default: Option[A] = None) {
|
||||||
|
|
||||||
import ScalaLocks._
|
import ScalaLocks._
|
||||||
|
|||||||
Reference in New Issue
Block a user