From cc75679b70c0c94633d3f97b06f7d8b8dd79fefc Mon Sep 17 00:00:00 2001 From: Csaba Kiraly Date: Tue, 21 Mar 2023 08:34:28 +0100 Subject: [PATCH] add generalized metrics collection Signed-off-by: Csaba Kiraly --- DAS/observer.py | 28 +++++++++++++++------------- DAS/results.py | 4 ++++ DAS/simulator.py | 9 ++++++--- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/DAS/observer.py b/DAS/observer.py index 6af4507..1bdf4d0 100644 --- a/DAS/observer.py +++ b/DAS/observer.py @@ -1,6 +1,6 @@ #!/bin/python3 -from statistics import mean +import numpy as np from DAS.block import * class Observer: @@ -68,16 +68,18 @@ class Observer: return missingSamples, sampleProgress, nodeProgress, validatorProgress def getTrafficStats(self, validators): - statsTxInSlot = [v.statsTxInSlot for v in validators] - statsRxInSlot = [v.statsRxInSlot for v in validators] - statsRxDupInSlot = [v.statsRxDupInSlot for v in validators] - TX_prod = statsTxInSlot[0] - RX_prod = statsRxInSlot[0] - TX_avg = mean(statsTxInSlot[1:]) - TX_max = max(statsTxInSlot[1:]) - Rx_avg = mean(statsRxInSlot[1:]) - Rx_max = max(statsRxInSlot[1:]) - RxDup_avg = mean(statsRxDupInSlot[1:]) - RxDup_max = max(statsRxDupInSlot[1:]) + def maxOrNan(l): + return np.max(l) if l else np.NaN - return (TX_prod, RX_prod, TX_avg, TX_max, Rx_avg, Rx_max, RxDup_avg, RxDup_max) + trafficStats = {} + for cl in range(0,3): + Tx = [v.statsTxInSlot for v in validators if v.nodeClass == cl] + Rx = [v.statsRxInSlot for v in validators if v.nodeClass == cl] + RxDup = [v.statsRxDupInSlot for v in validators if v.nodeClass == cl] + trafficStats[cl] = { + "Tx": {"mean": np.mean(Tx), "max": maxOrNan(Tx)}, + "Rx": {"mean": np.mean(Rx), "max": maxOrNan(Rx)}, + "RxDup": {"mean": np.mean(RxDup), "max": maxOrNan(RxDup)}, + } + + return trafficStats diff --git a/DAS/results.py b/DAS/results.py index 0efe26d..61f4f04 100644 --- a/DAS/results.py +++ b/DAS/results.py @@ -13,6 +13,7 @@ class Result: self.blockAvailable = -1 self.tta = -1 self.missingVector = [] + self.metrics = {} def populate(self, shape, missingVector): """It populates part of the result data inside a vector.""" @@ -26,6 +27,9 @@ class Result: self.blockAvailable = 0 self.tta = -1 + def addMetric(self, name, metric): + self.metrics[name] = metric + def dump(self, execID): """It dumps the results of the simulation in an XML file.""" if not os.path.exists("results"): diff --git a/DAS/simulator.py b/DAS/simulator.py index 9c8efcd..010082d 100644 --- a/DAS/simulator.py +++ b/DAS/simulator.py @@ -147,6 +147,7 @@ class Simulator: arrived, expected, ready, validated = self.glob.checkStatus(self.validators) missingSamples = expected - arrived missingVector = [] + trafficStatsVector = [] steps = 0 while(True): missingVector.append(missingSamples) @@ -167,11 +168,12 @@ class Simulator: self.validators[i].logColumns() # log TX and RX statistics - TX_prod, RX_prod, TX_avg, TX_max, Rx_avg, Rx_max, RxDup_avg, RxDup_max = self.glob.getTrafficStats(self.validators) - self.logger.info("step %d: TX_prod=%.1f, RX_prod=%.1f, TX_avg=%.1f, TX_max=%.1f, Rx_avg=%.1f, Rx_max=%.1f, RxDup_avg=%.1f, RxDup_max=%.1f" % - (steps, TX_prod, RX_prod, TX_avg, TX_max, Rx_avg, Rx_max ,RxDup_avg, RxDup_max), extra=self.format) + trafficStats = self.glob.getTrafficStats(self.validators) + self.logger.debug("step %d: %s" % + (steps, trafficStats), extra=self.format) for i in range(0,self.shape.numberNodes): self.validators[i].updateStats() + trafficStatsVector.append(trafficStats) missingSamples, sampleProgress, nodeProgress, validatorProgress = self.glob.getProgress(self.validators) self.logger.debug("step %d, arrived %0.02f %%, ready %0.02f %%, validated %0.02f %%" @@ -188,5 +190,6 @@ class Simulator: steps += 1 self.result.populate(self.shape, missingVector) + self.result.addMetric("trafficStats", trafficStatsVector) return self.result