/ 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()