/ study.py
study.py
 1  #! /bin/python3
 2  
 3  import time, sys, random, copy
 4  import importlib
 5  import subprocess
 6  from joblib import Parallel, delayed
 7  from DAS import *
 8  
 9  # Parallel execution:
10  # The code currently uses 'joblib' to execute on multiple cores. For other options such as 'ray', see
11  # https://stackoverflow.com/questions/9786102/how-do-i-parallelize-a-simple-python-loop
12  # For fixing logging issues in parallel execution, see
13  # https://stackoverflow.com/questions/58026381/logging-nested-functions-using-joblib-parallel-and-delayed-calls
14  # and https://github.com/joblib/joblib/issues/1017
15  
16  def initLogger(config):
17      """It initializes the logger."""
18      logger = logging.getLogger("Study")
19      logger.setLevel(config.logLevel)
20      ch = logging.StreamHandler()
21      ch.setLevel(config.logLevel)
22      ch.setFormatter(CustomFormatter())
23      logger.addHandler(ch)
24      return logger
25  
26  def runOnce(config, shape, execID):
27  
28      if config.deterministic:
29          shape.setSeed(config.randomSeed+"-"+str(shape))
30          random.seed(shape.randomSeed)
31  
32      sim = Simulator(shape, config, execID)
33      sim.initLogger()
34      sim.initValidators()
35      sim.initNetwork()
36      result = sim.run()
37      sim.logger.info("Shape: %s ... Block Available: %d in %d steps" % (str(sim.shape.__dict__), result.blockAvailable, len(result.missingVector)), extra=sim.format)
38  
39      if config.dumpXML:
40          result.dump()
41  
42      if config.visualization:
43          visual = Visualizor(execID, config, [result])
44          visual.plotAll()
45  
46      return result
47  
48  def study():
49      if len(sys.argv) < 2:
50          print("You need to pass a configuration file in parameter")
51          exit(1)
52  
53      try:
54          config = importlib.import_module(sys.argv[1])
55      except ModuleNotFoundError as e:
56          try:
57              config = importlib.import_module(str(sys.argv[1]).replace(".py", ""))
58          except ModuleNotFoundError as e:
59              print(e)
60              print("You need to pass a configuration file in parameter")
61              exit(1)
62  
63      logger = initLogger(config)
64      format = {"entity": "Study"}
65  
66      results = []
67  
68      now = datetime.now()
69      execID = now.strftime("%Y-%m-%d_%H-%M-%S_")+str(random.randint(100,999))
70  
71      # save config and code state for reproducibility
72      if not os.path.exists("results"):
73          os.makedirs("results")
74      dir = "results/"+execID
75      if not os.path.exists(dir):
76          os.makedirs(dir)
77      if config.saveGit:
78         with open(dir+"/git.diff", 'w') as f:
79             subprocess.run(["git", "diff"], stdout=f)
80         with open(dir+"/git.describe", 'w') as f:
81             subprocess.run(["git", "describe", "--always"], stdout=f)
82      subprocess.run(["cp", sys.argv[1], dir+"/"])
83  
84      logger.info("Starting simulations:", extra=format)
85      start = time.time()
86      results = Parallel(config.numJobs)(delayed(runOnce)(config, shape ,execID) for shape in config.nextShape())
87      end = time.time()
88      logger.info("A total of %d simulations ran in %d seconds" % (len(results), end-start), extra=format)
89  
90      if config.visualization:
91          vis = Visualizer(execID, config)
92          vis.plotHeatmaps()
93  
94          visual = Visualizor(execID, config, results)
95          visual.plotHeatmaps("nn", "fr")
96  
97  if __name__ == "__main__":
98      study()