From ba94cc8da116c327a7b28049f86bd04fd15c75ed Mon Sep 17 00:00:00 2001 From: leobago Date: Tue, 14 Mar 2023 08:26:37 +0100 Subject: [PATCH 1/5] Update requirements --- DAS/requirements.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/DAS/requirements.txt b/DAS/requirements.txt index d0bb457..da7dcc7 100644 --- a/DAS/requirements.txt +++ b/DAS/requirements.txt @@ -1,3 +1,7 @@ bitarray==2.6.0 -DAS==0.28.7 +DAS==0.29.0 +dicttoxml==1.7.16 +matplotlib==3.6.2 networkx==3.0 +numpy==1.23.5 +seaborn==0.12.2 From 377072ef7951c1d0a064869a247871a767af1801 Mon Sep 17 00:00:00 2001 From: Leonardo Bautista-Gomez Date: Tue, 14 Mar 2023 11:07:59 +0100 Subject: [PATCH 2/5] Fix deterministic feature --- study.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/study.py b/study.py index 52433c5..67dac5f 100644 --- a/study.py +++ b/study.py @@ -33,8 +33,11 @@ def study(): start = time.time() for shape in config.nextShape(): - if not config.deterministic: - random.seed(datetime.now()) + if config.deterministic: + random.seed("DASsimulator") + else: + random.seed(random.randint(0, 100)) + sim.resetShape(shape) sim.initValidators() From 45bdcc3308dc41bf1b944788f4d8821a4e63929d Mon Sep 17 00:00:00 2001 From: Leonardo Bautista-Gomez Date: Tue, 14 Mar 2023 11:25:17 +0100 Subject: [PATCH 3/5] Seed by microseconds. Determinisme checked. --- study.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/study.py b/study.py index 67dac5f..e87b12f 100644 --- a/study.py +++ b/study.py @@ -27,17 +27,16 @@ def study(): simCnt = 0 now = datetime.now() + if config.deterministic: + random.seed("DASsimulator") + else: + random.seed(str(now).split(".")[1]) execID = now.strftime("%Y-%m-%d_%H-%M-%S_")+str(random.randint(100,999)) sim.logger.info("Starting simulations:", extra=sim.format) start = time.time() for shape in config.nextShape(): - if config.deterministic: - random.seed("DASsimulator") - else: - random.seed(random.randint(0, 100)) - sim.resetShape(shape) sim.initValidators() From 833ae76097f8bd2655124d28baab51bb14df86f7 Mon Sep 17 00:00:00 2001 From: Leonardo Bautista-Gomez Date: Wed, 15 Mar 2023 12:37:23 +0100 Subject: [PATCH 4/5] add shape repr --- DAS/shape.py | 11 ++++++++++- study.py | 35 +++++++++++++++++++++-------------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/DAS/shape.py b/DAS/shape.py index 2f99ebf..a27b6ca 100644 --- a/DAS/shape.py +++ b/DAS/shape.py @@ -12,6 +12,15 @@ class Shape: self.netDegree = netDegree self.chi = chi - + def __repr__(self): + """Returns a printable representation of the shape""" + shastr = "" + shastr += "bs-"+str(self.blockSize) + shastr += "-nbv-"+str(self.numberValidators) + shastr += "-fr-"+str(self.failureRate) + shastr += "-chi-"+str(self.chi) + shastr += "-nd-"+str(self.netDegree) + shastr += "-r-"+str(self.run) + return repr(shastr) diff --git a/study.py b/study.py index e87b12f..6d223b8 100644 --- a/study.py +++ b/study.py @@ -2,8 +2,27 @@ import time, sys, random, copy import importlib +from joblib import Parallel, delayed from DAS import * +# Parallel execution: +# The code currently uses 'joblib' to execute on multiple cores. For other options such as 'ray', see +# https://stackoverflow.com/questions/9786102/how-do-i-parallelize-a-simple-python-loop +# For fixing logging issues in parallel execution, see +# https://stackoverflow.com/questions/58026381/logging-nested-functions-using-joblib-parallel-and-delayed-calls +# and https://github.com/joblib/joblib/issues/1017 + +def runOnce(sim, config, shape): + if config.deterministic: + random.seed(repr(shape)) + + sim.initLogger() + sim.resetShape(shape) + sim.initValidators() + sim.initNetwork() + result = sim.run() + sim.logger.info("Shape: %s ... Block Available: %d in %d steps" % (str(sim.shape.__dict__), result.blockAvailable, len(result.missingVector)), extra=sim.format) + return result def study(): if len(sys.argv) < 2: @@ -24,30 +43,18 @@ def study(): sim = Simulator(shape, config) sim.initLogger() results = [] - simCnt = 0 now = datetime.now() - if config.deterministic: - random.seed("DASsimulator") - else: - random.seed(str(now).split(".")[1]) execID = now.strftime("%Y-%m-%d_%H-%M-%S_")+str(random.randint(100,999)) sim.logger.info("Starting simulations:", extra=sim.format) start = time.time() - for shape in config.nextShape(): + results = Parallel(config.numJobs)(delayed(runOnce)(sim, config, shape) for shape in config.nextShape()) - sim.resetShape(shape) - sim.initValidators() - sim.initNetwork() - result = sim.run() - sim.logger.info("Shape: %s ... Block Available: %d in %d steps" % (str(sim.shape.__dict__), result.blockAvailable, len(result.missingVector)), extra=sim.format) - results.append(copy.deepcopy(result)) - simCnt += 1 end = time.time() - sim.logger.info("A total of %d simulations ran in %d seconds" % (simCnt, end-start), extra=sim.format) + sim.logger.info("A total of %d simulations ran in %d seconds" % (len(results), end-start), extra=sim.format) if config.dumpXML: for res in results: From 0a92ef70713f6c7b7b97c3c1244308a2e7b76b09 Mon Sep 17 00:00:00 2001 From: Leonardo Bautista-Gomez Date: Wed, 15 Mar 2023 13:18:02 +0100 Subject: [PATCH 5/5] Adding and logging random seed in the shape for each simulation --- DAS/results.py | 7 +------ DAS/shape.py | 6 +++++- config_example.py | 6 +++++- study.py | 9 +++------ 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/DAS/results.py b/DAS/results.py index e20cdec..0efe26d 100644 --- a/DAS/results.py +++ b/DAS/results.py @@ -39,11 +39,6 @@ class Result: resXml = dicttoxml(resd1) xmlstr = minidom.parseString(resXml) xmlPretty = xmlstr.toprettyxml() - filePath = "results/"+execID+"/nbv-"+str(self.shape.numberValidators)+\ - "-bs-"+str(self.shape.blockSize)+\ - "-nd-"+str(self.shape.netDegree)+\ - "-fr-"+str(self.shape.failureRate)+\ - "-chi-"+str(self.shape.chi)+\ - "-r-"+str(self.shape.run)+".xml" + filePath = "results/"+execID+"/"+str(self.shape)+".xml" with open(filePath, "w") as f: f.write(xmlPretty) diff --git a/DAS/shape.py b/DAS/shape.py index a27b6ca..1dd19b2 100644 --- a/DAS/shape.py +++ b/DAS/shape.py @@ -11,6 +11,7 @@ class Shape: self.failureRate = failureRate self.netDegree = netDegree self.chi = chi + self.randomSeed = "" def __repr__(self): """Returns a printable representation of the shape""" @@ -21,6 +22,9 @@ class Shape: shastr += "-chi-"+str(self.chi) shastr += "-nd-"+str(self.netDegree) shastr += "-r-"+str(self.run) - return repr(shastr) + return shastr + def setSeed(self, seed): + """Adds the random seed to the shape""" + self.randomSeed = seed diff --git a/config_example.py b/config_example.py index 0ac65ad..1a4db01 100644 --- a/config_example.py +++ b/config_example.py @@ -35,11 +35,15 @@ blockSizes = range(32,65,16) # Per-topic mesh neighborhood size netDegrees = range(6, 9, 2) -# number of rows and columns a validator is interested in +# Number of rows and columns a validator is interested in chis = range(4, 9, 2) +# Set to True if you want your run to be deterministic, False if not deterministic = False +# If your run is deterministic you can decide the random seed. This is ignore otherwise. +randomSeed = "DAS" + def nextShape(): for run in runs: for fr in failureRates: diff --git a/study.py b/study.py index 6d223b8..e24fb46 100644 --- a/study.py +++ b/study.py @@ -14,7 +14,8 @@ from DAS import * def runOnce(sim, config, shape): if config.deterministic: - random.seed(repr(shape)) + shape.setSeed(config.randomSeed+"-"+str(shape)) + random.seed(shape.randomSeed) sim.initLogger() sim.resetShape(shape) @@ -49,10 +50,7 @@ def study(): sim.logger.info("Starting simulations:", extra=sim.format) start = time.time() - results = Parallel(config.numJobs)(delayed(runOnce)(sim, config, shape) for shape in config.nextShape()) - - end = time.time() sim.logger.info("A total of %d simulations ran in %d seconds" % (len(results), end-start), extra=sim.format) @@ -61,8 +59,7 @@ def study(): res.dump(execID) sim.logger.info("Results dumped into results/%s/" % (execID), extra=sim.format) - visualization = 1 - if visualization: + if config.visualization: vis = Visualizer(execID) vis.plotHeatmaps()