From 8221490196b3a844198aa5ee9c273a3863c1984a Mon Sep 17 00:00:00 2001 From: Leonardo Bautista-Gomez Date: Tue, 29 Nov 2022 18:12:02 +0100 Subject: [PATCH] Add logic for multi-simulation studies --- simulator/DAS.py | 105 +++++++++++++++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 35 deletions(-) diff --git a/simulator/DAS.py b/simulator/DAS.py index 762711b..856a10f 100644 --- a/simulator/DAS.py +++ b/simulator/DAS.py @@ -1,6 +1,6 @@ #! /bin/python3 -import random, logging +import random, logging, time from datetime import datetime class Block: @@ -94,20 +94,20 @@ class Validator: if self.proposer == 1: self.logger.warning("I am a block proposer."% self.ID) else: - self.logger.info("Selected rows: "+str(self.rowIDs), extra=self.format) - self.logger.info("Selected columns: "+str(self.columnIDs), extra=self.format) + self.logger.debug("Selected rows: "+str(self.rowIDs), extra=self.format) + self.logger.debug("Selected columns: "+str(self.columnIDs), extra=self.format) def initBlock(self): - self.logger.info("I am a block proposer.", extra=self.format) + self.logger.debug("I am a block proposer.", extra=self.format) self.block = Block(self.blockSize) self.block.fill() - self.block.print() + #self.block.print() def broadcastBlock(self, broadcasted): if self.proposer == 0: self.logger.error("I am NOT a block proposer", extra=self.format) else: - self.logger.info("Broadcasting my block...", extra=self.format) + self.logger.debug("Broadcasting my block...", extra=self.format) tempBlock = self.block order = [i for i in range(self.blockSize * self.blockSize)] random.shuffle(order) @@ -115,7 +115,7 @@ class Validator: i = order.pop() if (random.randint(0,99) > self.failureRate): broadcasted.data[i] = self.block.data[i] - broadcasted.print() + #broadcasted.print() def getColumn(self, columnID, broadcasted): column = [0] * self.blockSize @@ -191,9 +191,9 @@ class Validator: if success >= len(row)/2: for i in range(len(row)): self.rows[rid][i] = goldenData[(self.rowIDs[rid]*self.blockSize)+i] - self.logger.info("%d samples restored in row %d" % (failures, self.rowIDs[rid]), extra=self.format ) + self.logger.debug("%d samples restored in row %d" % (failures, self.rowIDs[rid]), extra=self.format ) else: - self.logger.warning("Row %d cannot be restored" % (self.rowIDs[rid]), extra=self.format) + self.logger.debug("Row %d cannot be restored" % (self.rowIDs[rid]), extra=self.format) def checkRestoreColumns(self, goldenData): for cid in range(len(self.columns)): @@ -212,9 +212,9 @@ class Validator: if success >= len(column)/2: for i in range(len(column)): self.columns[cid][i] = goldenData[(i*self.blockSize)+self.columnIDs[cid]] - self.logger.info("%d samples restored in column %d" % (failures, self.columnIDs[cid]), extra=self.format) + self.logger.debug("%d samples restored in column %d" % (failures, self.columnIDs[cid]), extra=self.format) else: - self.logger.info("Column %d cannot be restored" % (self.columnIDs[cid]), extra=self.format) + self.logger.debug("Column %d cannot be restored" % (self.columnIDs[cid]), extra=self.format) class Observer: @@ -230,11 +230,13 @@ class Observer: def __init__(self, blockSize, logger): self.format = {"entity": "Observer"} self.blockSize = blockSize + self.logger = logger + + def reset(self): self.block = [0] * self.blockSize * self.blockSize self.goldenData = [0] * self.blockSize * self.blockSize self.rows = [0] * self.blockSize self.columns = [0] * self.blockSize - self.logger = logger self.broadcasted = Block(self.blockSize) def checkRowsColumns(self, validators): @@ -246,9 +248,9 @@ class Observer: self.columns[c] += 1 for i in range(self.blockSize): - self.logger.info("Row/Column %d have %d and %d validators assigned." % (i, self.rows[i], self.columns[i]), extra=self.format) + self.logger.debug("Row/Column %d have %d and %d validators assigned." % (i, self.rows[i], self.columns[i]), extra=self.format) if self.rows[i] == 0 or self.columns[i] == 0: - logging.warning("There is a row/column that has not been assigned", extra=self.format) + self.logger.warning("There is a row/column that has not been assigned", extra=self.format) def setGoldenData(self, block): for i in range(self.blockSize*self.blockSize): @@ -260,16 +262,16 @@ class Observer: if self.broadcasted.data[i] == 0: zeros += 1 if zeros > 0: - self.logger.warning("There are %d missing samples in the network" % zeros, extra=self.format) + self.logger.debug("There are %d missing samples in the network" % zeros, extra=self.format) return zeros class Simulator: - chi = 4 - blockSize = 16 - numberValidators = 32 - failureRate = 66 + chi = 8 + blockSize = 256 + numberValidators = 8192 + failureRate = 0 proposerID = 0 logLevel = logging.INFO deterministic = 0 @@ -279,20 +281,17 @@ class Simulator: format = {} steps = 0 - def __init__(self): - logger = logging.getLogger("DAS") - logger.setLevel(self.logLevel) - ch = logging.StreamHandler() - ch.setLevel(self.logLevel) + def __init__(self, failureRate): + self.failureRate = failureRate self.format = {"entity": "Simulator"} - ch.setFormatter(CustomFormatter()) - logger.addHandler(ch) - self.logger = logger self.steps = 0 + def initValidators(self): if not self.deterministic: random.seed(datetime.now()) self.glob = Observer(self.blockSize, self.logger) + self.glob.reset() + self.validators = [] for i in range(self.numberValidators): val = Validator(i, self.chi, self.blockSize, int(not i!=0), self.failureRate, self.deterministic, self.logger) if i == self.proposerID: @@ -302,14 +301,26 @@ class Simulator: val.logIDs() self.validators.append(val) + def initLogger(self): + logger = logging.getLogger("DAS") + logger.setLevel(self.logLevel) + ch = logging.StreamHandler() + ch.setLevel(self.logLevel) + ch.setFormatter(CustomFormatter()) + logger.addHandler(ch) + self.logger = logger + + def resetFailureRate(self, failureRate): + self.failureRate = failureRate def run(self): self.glob.checkRowsColumns(self.validators) self.validators[self.proposerID].broadcastBlock(self.glob.broadcasted) missingSamples = self.glob.checkBroadcasted() + self.steps = 0 while(missingSamples > 0): oldMissingSamples = missingSamples - self.logger.info("Step %d:" % self.steps, extra=self.format) + self.logger.debug("Step %d:" % self.steps, extra=self.format) for i in range(1,self.numberValidators): self.validators[i].receiveRowsColumns(self.glob.broadcasted) #Rows @@ -332,14 +343,38 @@ class Simulator: self.steps += 1 if missingSamples == 0: - self.logger.info("The entire block is available at step %d!" % self.steps, extra=self.format) + self.logger.debug("The entire block is available at step %d, with failure rate %d !" % (self.steps, self.failureRate), extra=self.format) + return 0 else: - self.logger.warning("The block is CANNOT be recovered!", extra=self.format) - self.logger.info("End of simulation", extra=self.format) - - -sim = Simulator() -sim.run() + self.logger.debug("The block cannot be recovered, failure rate %d!" % self.failureRate, extra=self.format) + return 1 + +def study(): + sim = Simulator(0) + sim.initLogger() + maxTries = 5 + step = 25 + frRange = [] + resultRange = [] + simCnt = 0 + sim.logger.info("Starting %d simulations:" % (maxTries*100), extra=sim.format) + start = time.time() + for fr in range(0, 100, step): + if fr % 10 == 0: + sim.logger.info("Failure rate %d %% ..." % fr, extra=sim.format) + sim.resetFailureRate(fr) + result = 0 + for i in range(maxTries): + sim.initValidators() + result += sim.run() + simCnt += 1 + frRange.append(fr) + resultRange.append(100-result) + end = time.time() + sim.logger.info("A total of %d simulations ran in %d seconds" % (simCnt, end-start), extra=sim.format) + for i in range(len(frRange)): + sim.logger.info("For failure rate of %d we got %d %% success rate in DAS!" % (frRange[i], resultRange[i]), extra=sim.format) +study()