[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("ser", parlist.map({_ => Thread.sleep(10); 2}))
|
||||
|
||||
//startSimulation()
|
||||
}
|
||||
|
||||
def startSimulation(): Unit = {
|
||||
@@ -42,6 +42,7 @@ object Main {
|
||||
outputThread.start()
|
||||
simulator.start()
|
||||
outputThread.join()
|
||||
sharedMemory.outputReset()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
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 {
|
||||
def run(): Unit = {
|
||||
val output = sharedMemory.output
|
||||
(0 until output.size, output).zipped.foreach((time, result) => outputData(time, result.watch()))
|
||||
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))
|
||||
}
|
||||
|
||||
def outputData(time: Int, output: Map[Cell, Map[Group, Vector[SensorResult]]]): Unit = {
|
||||
Vector.tabulate(sharedMemory.config.duration)(t => Time(t, duration)).foreach(outputHelper)
|
||||
}
|
||||
|
||||
def outputData(time: Time, sensors: Map[Cell, Map[Group, Vector[SensorResult]]], groundTruths: Map[Cell, Map[Group, Truth]]): Unit = {
|
||||
println("TICK: " + time)
|
||||
println(output)
|
||||
println(sensors)
|
||||
println(groundTruths)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class Simulation(config: Configuration) {
|
||||
cells.foreach(simCell)
|
||||
}
|
||||
// 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 = {
|
||||
|
||||
@@ -2,6 +2,7 @@ package scim.datastruct
|
||||
|
||||
import scim.lib.ConcurrentBroadcast.BroadcastObject
|
||||
import scim.lib.simulation._
|
||||
|
||||
import scala.collection.parallel.ForkJoinTaskSupport
|
||||
|
||||
// configuration
|
||||
@@ -21,23 +22,30 @@ case class Time(time: Int, duration: Int){
|
||||
case class SharedMemory(sensor: Map[Time, Map[Cell, Map[Group, Vector[SensorResult]]]],
|
||||
groundTruth: Map[Time, Map[Cell, Map[Group, Truth]]],
|
||||
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
|
||||
// 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
|
||||
// through the configuration. it can however be deleted once it is no longer required, tho this seems
|
||||
// to be rather unbeneficial, as the space was already preallocated. Sensors however could be replaced
|
||||
// or deleted, depending if a buffer or list is used.
|
||||
|
||||
// through the configuration throughout the entire simulation. it can however be deleted once it is no longer
|
||||
// required, tho this seems to be rather unbeneficial, as the space was already preallocated.
|
||||
// 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 = {
|
||||
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] = {
|
||||
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)
|
||||
}
|
||||
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]) {
|
||||
@@ -50,6 +58,9 @@ abstract class BroadcastHandler[A](broadcastObject: BroadcastObject[A]) {
|
||||
def exists: Boolean = {
|
||||
!broadcastObject.peak().isEmpty
|
||||
}
|
||||
def reset(): Unit = {
|
||||
broadcastObject.broadcastReset()
|
||||
}
|
||||
}
|
||||
case class SimulationBehaviours(functions: Map[String, SimulationBehaviour]) {
|
||||
def get(name: String): Option[SimulationBehaviour] = {
|
||||
|
||||
@@ -63,6 +63,8 @@ object ScalaLocks {
|
||||
|
||||
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) {
|
||||
|
||||
import ScalaLocks._
|
||||
|
||||
Reference in New Issue
Block a user