def __init__(self, cfr, module, solver, metrics_variables, metrics_objective_direction): self.cfr = cfr self.module = module self.solvers = replicateSolver(solver, Options.CORES) self.metrics_variables = metrics_variables self.metrics_objective_direction = metrics_objective_direction self.clock = Clock() self.consumerConstraints = self.splitter()
def __init__(self, task_queue, result_queue, cfr, timeQueue, index, outputFileParentName, num_consumers, s, consumerConstraints): multiprocessing.Process.__init__(self) self.task_queue = task_queue self.result_queue = result_queue self.timeQueue = timeQueue self.cfr = cfr self.solver = s self.consumerConstraints = consumerConstraints self.index = index self.num_consumers = num_consumers self.clock = Clock()
def __init__(self, fenetre, COMport): self.logger = logging.getLogger("socket") self.mode = 'remote' # on memorise la fenetre associée à ce compteur self.fenetre = fenetre # initialisation du port COM self.vtr = protocoleVTR(COMport) # initialisation de la machine à état self.state = StateMachine('stopped') # initialisation de l'horloge self.clock = Clock() self.clock.initCounterWithSeconds(0) self.logger.info( "interfaceVTR {ver}: Starting".format(ver=self.current_version))
def __init__(self, task_queue, result_queue, cfr, timeQueue, index, outputFileParentName, num_consumers, s, metrics_variables, metrics_objective_direction, consumerConstraints): multiprocessing.Process.__init__(self) self.task_queue = task_queue self.result_queue = result_queue self.timeQueue = timeQueue self.cfr = cfr self.solver = s self.consumerConstraints = consumerConstraints self.index = index self.num_consumers = num_consumers self.ParetoFront = [] self.clock = Clock() self.GIAOptions = GuidedImprovementAlgorithmOptions(verbosity=0, \ incrementallyWriteLog=False, \ writeTotalTimeFilename="timefile.csv", \ writeRandomSeedsFilename="randomseed.csv", useCallLogs=False) self.GIAAlgorithm = GuidedImprovementAlgorithm(self.cfr, self.solver, metrics_variables, \ metrics_objective_direction, [], options=self.GIAOptions)
def run(): ''' Runs the Z3-translator on each pair (file, numInstances) in tests, and ensures that the number of generated models equals numInstances. ''' clock = Clock() tests = getTestSet() num_passed = 0 exceptions = 0 exception_list = [] failed_list = [] temp_model_count = Options.NUM_INSTANCES for t in tests: (file, expected_model_count) = t try: if expected_model_count == Options.INFINITE and Options.NUM_INSTANCES < 0: #will change it back after the test runs Options.NUM_INSTANCES = 5 module = file.getModule() print_separate("Attempting: " + str(file.__name__)) clock.tick("Total Z3 Run Time") cfr = ClaferModel(module) actual_model_count = cfr.run() clock.tack("Total Z3 Run Time") clock = clock.combineClocks(cfr.clock) if(expected_model_count == actual_model_count or (expected_model_count == Options.INFINITE and actual_model_count == Options.NUM_INSTANCES)): print("PASSED: " + str(file.__name__)) num_passed = num_passed + 1 else: failed_list.append(str(file.__name__)) print("FAILED: " + str(file.__name__) + " " + str(expected_model_count) + " " + str(actual_model_count)) except: print("FAILED: " + str(file.__name__) + " " + "\nException raised.") traceback.print_exc() exception_list.append(str(file.__name__)) exceptions = exceptions + 1 Options.NUM_INSTANCES = temp_model_count print_separate("Results: " + str(num_passed) + "/" + str(len(tests)) + "\n| " + "Failed List: " + str(failed_list) + "\n| " + "Exceptions: " + str(exceptions) + "/" + str(len(tests)) + "\n| " + "Exception List: " + str(exception_list)) clock.printEvents()
class StandardConsumer(multiprocessing.Process): def __init__(self, task_queue, result_queue, cfr, timeQueue, index, outputFileParentName, num_consumers, s, consumerConstraints): multiprocessing.Process.__init__(self) self.task_queue = task_queue self.result_queue = result_queue self.timeQueue = timeQueue self.cfr = cfr self.solver = s self.consumerConstraints = consumerConstraints self.index = index self.num_consumers = num_consumers self.clock = Clock() def run(self): num_solutions = 0 self.clock.tick("Consumer " + str(self.index)) while True: next_task = self.task_queue.get() try: if next_task == "Poison" or (num_solutions == Options.NUM_INSTANCES): self.task_queue.task_done() break except: pass self.solver.push() self.solver.add(self.consumerConstraints[int(next_task)]) self.clock.tick("Task " + str(next_task)) while self.solver.check( ) == Common.SAT and num_solutions != Options.NUM_INSTANCES: model = self.solver.model() self.result_queue.put(model_to_string(self.cfr, model)) num_solutions = num_solutions + 1 preventSameModel(self.cfr, self.solver, model) self.task_queue.task_done() self.clock.tock("Task " + str(next_task)) self.solver.pop() self.clock.tock("Consumer " + str(self.index)) self.timeQueue.put(self.clock) return 0
class StandardConsumer(multiprocessing.Process): def __init__(self, task_queue, result_queue, cfr, timeQueue, index, outputFileParentName, num_consumers, s, consumerConstraints): multiprocessing.Process.__init__(self) self.task_queue = task_queue self.result_queue = result_queue self.timeQueue = timeQueue self.cfr = cfr self.solver = s self.consumerConstraints = consumerConstraints self.index = index self.num_consumers = num_consumers self.clock = Clock() def run(self): num_solutions = 0 self.clock.tick("Consumer " + str(self.index)) while True: next_task = self.task_queue.get() try: if next_task == "Poison" or (num_solutions == Options.NUM_INSTANCES): self.task_queue.task_done() break except: pass self.solver.push() self.solver.add(self.consumerConstraints[int(next_task)]) self.clock.tick("Task " + str(next_task)) while self.solver.check() == Common.SAT and num_solutions != Options.NUM_INSTANCES: model = self.solver.model() self.result_queue.put(model_to_string(self.cfr, model)) num_solutions = num_solutions + 1 preventSameModel(self.cfr, self.solver, model) self.task_queue.task_done() self.clock.tock("Task " + str(next_task)) self.solver.pop() self.clock.tock("Consumer " + str(self.index)) self.timeQueue.put(self.clock) return 0
class ParSolver(): def __init__(self, cfr, module, solver, metrics_variables, metrics_objective_direction): self.cfr = cfr self.module = module self.solvers = replicateSolver(solver, Options.CORES) self.metrics_variables = metrics_variables self.metrics_objective_direction = metrics_objective_direction self.clock = Clock() self.consumerConstraints = self.splitter() def run(self): if not self.consumerConstraints: self.cfr.metric = Common.BOUND return [] mgr = multiprocessing.Manager() taskQueue = mgr.Queue() solutions = mgr.Queue() timeQueue = mgr.Queue() # Enqueue initial tasks for i in range(Options.NUM_SPLIT): taskQueue.put(i) for i in range(Options.CORES): taskQueue.put("Poison") # Start consumers #case: objectives if self.metrics_variables: self.consumers = [ Consumer.GIAConsumer(taskQueue, solutions, self.cfr, timeQueue, i, "out", Options.CORES, j, self.metrics_variables, self.metrics_objective_direction, self.consumerConstraints) for i,j in zip(range(Options.CORES), self.solvers)] #case: no objectives else: self.consumers = [ Consumer.StandardConsumer(taskQueue, solutions, self.cfr, timeQueue, i, "out", Options.CORES, j, self.consumerConstraints) for i,j in zip(range(Options.CORES), self.solvers)] self.clock.tick("ParSolver") for w in self.consumers: w.start() TERMINATED = False for w in self.consumers: if Options.TIME_OUT != 0: w.join(Options.TIME_OUT) else: w.join() if w.is_alive(): TERMINATED = True w.terminate() if TERMINATED: GeneralHeuristics.safe_raise_heuristic_failure_exception("Heuristic Timed Out") results = [] while not solutions.empty(): result = solutions.get() results.append(result) while not timeQueue.empty(): clock = timeQueue.get() self.clock = self.clock.combineClocks(clock) self.clock.tick("Merge") merged_results = self.merge(results) self.clock.tock("Merge") self.clock.tock("ParSolver") self.clock.getParallelStats(self.cfr) return merged_results def merge(self, results): if self.metrics_variables: results = self.removeDominatedAndEqual(results) return [i for (i,_) in results] else: return list(set(results)) def checkDominated(self, l, r): worseInOne = False betterInOne = False for i in range(len(l)): ml = l[i] mr = r[i] if self.metrics_objective_direction[i] == METRICS_MAXIMIZE: if ml < mr: worseInOne = True elif ml > mr: betterInOne = True elif self.metrics_objective_direction[i] == METRICS_MINIMIZE: if ml > mr: worseInOne = True elif ml < mr: betterInOne = True if (worseInOne and not betterInOne): return True return False def removeDominatedAndEqual(self, results): count = len(results) removalList = [False for _ in range(count)] for i in range(count): for j in range(count): if i != j: if self.checkDominated(results[i][1], results[j][1]): removalList[i] = True elif i < j and (results[i][0] == results[j][0] or results[i][1] == results[j][1]): removalList[i] = True nonDominated = [] for i in range(len(removalList)): if not removalList[i]: nonDominated.append(results[i]) return nonDominated def splitter(self): heuristic = GeneralHeuristics.heuristics[Options.SPLIT] return heuristic(self.cfr, self.module, Options.NUM_SPLIT)
class interfaceVTR: # Les variables déclarées ici sont accessibles avant les instanciations current_version = "v1.0" # ------------------------------------------------------------------ # Constructeur # Parametre: handler sur le fichier de log # ------------------------------------------------------------------ def __init__(self, fenetre, COMport): self.logger = logging.getLogger("socket") self.mode = 'remote' # on memorise la fenetre associée à ce compteur self.fenetre = fenetre # initialisation du port COM self.vtr = protocoleVTR(COMport) # initialisation de la machine à état self.state = StateMachine('stopped') # initialisation de l'horloge self.clock = Clock() self.clock.initCounterWithSeconds(0) self.logger.info( "interfaceVTR {ver}: Starting".format(ver=self.current_version)) # ------------------------------------------------------------------ # Renvoie le numero de port utilisé # ------------------------------------------------------------------ def getCOMport(self): return self.vtr.getCOMport() # ------------------------------------------------------------------ # Passe en mode LOCAL # ------------------------------------------------------------------ def setStatusToLocal(self): self.mode = 'local' b = self.fenetre.nametowidget('boutonLocal') b.configure(state=tkinter.DISABLED, bg="gold") b = self.fenetre.nametowidget('boutonRemote') b.configure(state=tkinter.NORMAL, bg="lightgrey") if (self.state.getStatus() != 'ejected'): # On dégrise les boutons PLAY et STOP #print (self.fenetre.winfo_children()) b = self.fenetre.nametowidget('boutonPlay') b.configure(state=tkinter.NORMAL) b = self.fenetre.nametowidget('boutonStop') b.configure(state=tkinter.NORMAL) b = self.fenetre.nametowidget('boutonFF') b.configure(state=tkinter.NORMAL) b = self.fenetre.nametowidget('boutonRW') b.configure(state=tkinter.NORMAL) # ------------------------------------------------------------------ # Passe en mode REMOTE # ------------------------------------------------------------------ def setStatusToRemote(self): self.mode = 'remote' # On grise les boutons PLAY et STOP b = self.fenetre.nametowidget('boutonPlay') b.configure(state=tkinter.DISABLED) b = self.fenetre.nametowidget('boutonStop') b.configure(state=tkinter.DISABLED) b = self.fenetre.nametowidget('boutonFF') b.configure(state=tkinter.DISABLED) b = self.fenetre.nametowidget('boutonRW') b.configure(state=tkinter.DISABLED) b = self.fenetre.nametowidget('boutonLocal') b.configure(state=tkinter.NORMAL, bg="lightgrey") b = self.fenetre.nametowidget('boutonRemote') b.configure(state=tkinter.DISABLED, bg="gold") # ------------------------------------------------------------------ # Passe en PLAY (si local) # ------------------------------------------------------------------ def play(self): # le bouton est actif si on est en Local # la fonction est active si on est en Stopped ou Cued status = self.state.getStatus() if ((status == 'stopped') or (status == 'cued')): self.state.setStatus('playing') # on initialise le compteur avec la valeur à laquelle on l'avait arrêté current_counter = self.clock.getCounterValue() self.clock.initCounterWithSeconds(current_counter) self.clock.start() # On grise les boutons PLAY, FF et RW b = self.fenetre.nametowidget('boutonPlay') b.configure(state=tkinter.DISABLED, bg="lime") b = self.fenetre.nametowidget('boutonFF') b.configure(state=tkinter.DISABLED, bg="yellowgreen") b = self.fenetre.nametowidget('boutonRW') b.configure(state=tkinter.DISABLED, bg="yellowgreen") b = self.fenetre.nametowidget('boutonStop') b.configure(bg="yellowgreen") # ------------------------------------------------------------------ # Passe en Fast Forward # ------------------------------------------------------------------ def fastForward(self): # le bouton est grisé si on est en Local # la fonction est active si on est en Stopped ou Cued status = self.state.getStatus() if ((status == 'stopped') or (status == 'cued')): self.state.setStatus('>>') # on initialise le compteur avec la valeur à laquelle on l'avait arrêté current_counter = self.clock.getCounterValue() self.clock.initCounterWithSeconds(current_counter) self.clock.start(10) # Speed x10 # On grise les boutons PLAY, FF et RW b = self.fenetre.nametowidget('boutonPlay') b.configure(state=tkinter.DISABLED, bg="yellowgreen") b = self.fenetre.nametowidget('boutonFF') b.configure(state=tkinter.DISABLED, bg="lime") b = self.fenetre.nametowidget('boutonRW') b.configure(state=tkinter.DISABLED, bg="yellowgreen") b = self.fenetre.nametowidget('boutonStop') b.configure(bg="yellowgreen") # ------------------------------------------------------------------ # Passe en Fast Rewind # ------------------------------------------------------------------ def fastRewind(self): # le bouton est grisé si on est en Local # la fonction est active si on est en Stopped ou Cued status = self.state.getStatus() if ((status == 'stopped') or (status == 'cued')): self.state.setStatus('<<') # on initialise le compteur avec la valeur à laquelle on l'avait arrêté current_counter = self.clock.getCounterValue() self.clock.initCounterWithSeconds(current_counter) self.clock.start(-10) # Speed x10 # On grise les boutons PLAY, FF et RW b = self.fenetre.nametowidget('boutonPlay') b.configure(state=tkinter.DISABLED, bg="yellowgreen") b = self.fenetre.nametowidget('boutonFF') b.configure(state=tkinter.DISABLED, bg="yellowgreen") b = self.fenetre.nametowidget('boutonRW') b.configure(state=tkinter.DISABLED, bg="lime") b = self.fenetre.nametowidget('boutonStop') b.configure(bg="yellowgreen") # ------------------------------------------------------------------ # Passe en STOP # ------------------------------------------------------------------ def stop(self): self.state.setStatus('stopped') self.clock.stop() # On dégrise les boutons PLAY, FF et RW b = self.fenetre.nametowidget('boutonPlay') b.configure(state=tkinter.NORMAL, bg="yellowgreen") b = self.fenetre.nametowidget('boutonFF') b.configure(state=tkinter.NORMAL, bg="yellowgreen") b = self.fenetre.nametowidget('boutonRW') b.configure(state=tkinter.NORMAL, bg="yellowgreen") b = self.fenetre.nametowidget('boutonStop') b.configure(bg="lime") # ------------------------------------------------------------------ # Commande PAUSE reçue # ------------------------------------------------------------------ def pause(self): self.state.setStatus('cued') self.clock.stop() # ------------------------------------------------------------------ # Commande CUE reçue # parametre = TC cible au format FFSSMMHH # ------------------------------------------------------------------ def cue(self, new_tc): # On positionne le compteur à la valeur demandée self.clock.stop() self.clock.resetCounter() self.clock.initCounterWithFFSSMMHH(new_tc) # On positionne le status self.state.setStatus('cueing') self.state.setStatusIn('cued', delay=2) # ------------------------------------------------------------------ # Ejecte la cassette # ------------------------------------------------------------------ def eject(self): self.state.setStatus('ejecting') self.state.setStatusIn('ejected', delay=1) # après dela de 1 seconde self.clock.stop() self.clock.resetCounter() b = self.fenetre.nametowidget('boutonEject') b.configure(state=tkinter.DISABLED) b = self.fenetre.nametowidget('boutonInsert') b.configure(state=tkinter.NORMAL) b = self.fenetre.nametowidget('boutonPlay') b.configure(state=tkinter.DISABLED, bg="yellowgreen") b = self.fenetre.nametowidget('boutonFF') b.configure(state=tkinter.DISABLED, bg="yellowgreen") b = self.fenetre.nametowidget('boutonRW') b.configure(state=tkinter.DISABLED, bg="yellowgreen") b = self.fenetre.nametowidget('boutonStop') b.configure(state=tkinter.DISABLED, bg="yellowgreen") # ------------------------------------------------------------------ # Insertion d'une nouvelle cassette # par defaut, le TCin de la cassette insérée est 10:00:00 # ------------------------------------------------------------------ def insert(self, tcin=36000): self.state.setStatus('stopped') self.clock.stop() self.clock.resetCounter() self.clock.initCounterWithSeconds(tcin) b = self.fenetre.nametowidget('boutonEject') b.configure(state=tkinter.NORMAL) b = self.fenetre.nametowidget('boutonInsert') b.configure(state=tkinter.DISABLED) if (self.mode == 'local'): # On dégrise les boutons PLAY et STOP b = self.fenetre.nametowidget('boutonPlay') b.configure(state=tkinter.NORMAL, bg="yellowgreen") b = self.fenetre.nametowidget('boutonStop') b.configure(state=tkinter.NORMAL, bg="yellowgreen") b = self.fenetre.nametowidget('boutonFF') b.configure(state=tkinter.NORMAL, bg="yellowgreen") b = self.fenetre.nametowidget('boutonRW') b.configure(state=tkinter.NORMAL, bg="yellowgreen") # ------------------------------------------------------------------ # met à jour le status affiché # ------------------------------------------------------------------ def updateDisplay(self, mode_var, status_var, compteur_var): # Refresh de l'affichage du mode mode_var.set(self.mode) # Refresh de l'affichage du status status_var.set(self.state.getStatus()) # Refresh de l'affichage du compteur if (self.state.getStatus() == 'ejected'): compteur_var.set("--:--:--:--") elif (self.state.getStatus() == 'cueing'): compteur_var.set(">>:>>") else: h, m, s, i = self.clock.getCounterHMSI() compteur_var.set("{h:02}:{m:02}:{s:02}:{i:02}".format( h=h % 24, m=m, s=s, i=i)) # h modulo 24 # Lecture des octets reçus, et envoi de la réponse message = self.vtr.readCommand() if (message): self.buildResponse(message) self.vtr.sendResponse() # Appel périodique (il faut répondre en moins de 10 ms) self.fenetre.after(5, self.updateDisplay, mode_var, status_var, compteur_var) # ------------------------------------------------------------------ # Construit le message a renvoyer # ------------------------------------------------------------------ def buildResponse(self, code_reponse): if (code_reponse == None): pass elif (code_reponse == 'TIME_SENSE'): h, m, s, i = self.clock.getCounterHMSI() self.vtr.buildResponseTC(h, m, s, i) elif (code_reponse == 'STATUS_SENSE'): self.vtr.buildResponseSTATUS(self.mode, self.state.getStatus()) elif (code_reponse == 'NACK'): self.vtr.buildResponseNACK() elif (code_reponse == 'DEVICE_TYPE'): self.vtr.buildResponseDEV_TYPE() elif (code_reponse == 'REW'): self.fastRewind() elif (code_reponse == 'FFWD'): self.fastForward() elif (code_reponse == 'EJECT'): self.eject() elif (code_reponse == 'STOP'): self.stop() elif (code_reponse == 'REC'): pass # le recording par le VTR n'est pas géré. elif (code_reponse == 'PLAY'): self.play() elif (code_reponse == 'SHTL'): pass # SHUTTLE non géré elif (code_reponse == 'PAUSE'): self.pause() elif (code_reponse == 'CUE'): self.cue(self.vtr.getNewTC()) else: self.logger.info("Unknown Response: {r}".format(r=code_reponse))
class GIAConsumer(multiprocessing.Process): def __init__(self, task_queue, result_queue, cfr, timeQueue, index, outputFileParentName, num_consumers, s, metrics_variables, metrics_objective_direction, consumerConstraints): multiprocessing.Process.__init__(self) self.task_queue = task_queue self.result_queue = result_queue self.timeQueue = timeQueue self.cfr = cfr self.solver = s self.consumerConstraints = consumerConstraints self.index = index self.num_consumers = num_consumers self.ParetoFront = [] self.clock = Clock() self.GIAOptions = GuidedImprovementAlgorithmOptions(verbosity=0, \ incrementallyWriteLog=False, \ writeTotalTimeFilename="timefile.csv", \ writeRandomSeedsFilename="randomseed.csv", useCallLogs=False) self.GIAAlgorithm = GuidedImprovementAlgorithm(self.cfr, self.solver, metrics_variables, \ metrics_objective_direction, [], options=self.GIAOptions) def addParetoPoints(self, point): self.ParetoFront.append(point) def run(self): num_solutions = 0 self.clock.tick("Consumer " + str(self.index)) while True: next_task = self.task_queue.get() try: if next_task == "Poison" or (num_solutions == Options.NUM_INSTANCES): self.task_queue.task_done() break except: pass self.solver.push() self.solver.add(self.consumerConstraints[int(next_task)]) self.consumerConstraints[int(next_task)] self.clock.tick("Task " + str(next_task)) total_sat_calls = 0 total_unsat_time = 0 while True: if self.GIAAlgorithm.s.check( ) != Common.SAT or num_solutions == Options.NUM_INSTANCES: self.clock.tock("Task " + str(next_task)) self.task_queue.task_done() self.solver.pop() break else: prev_solution = self.GIAAlgorithm.s.model() self.GIAAlgorithm.s.push() NextParetoPoint, _local_count_unsat_calls, _local_count_unsat_calls = self.GIAAlgorithm.ranToParetoFront( prev_solution) self.addParetoPoints(NextParetoPoint) metric_values = self.GIAAlgorithm.get_metric_values( NextParetoPoint) self.result_queue.put( (model_to_string(self.cfr, NextParetoPoint), metric_values)) self.GIAAlgorithm.s.pop() tmpNotDominatedByNextParetoPoint = self.GIAAlgorithm.ConstraintNotDominatedByX( NextParetoPoint) self.GIAAlgorithm.s.add(tmpNotDominatedByNextParetoPoint) num_solutions = num_solutions + 1 self.clock.tock("Consumer " + str(self.index)) print("Total Sat Calls: " + total_sat_calls) print("Total Unsat Time: " + total_unsat_time) self.timeQueue.put(self.clock) return 0
class GIAConsumer(multiprocessing.Process): def __init__(self, task_queue, result_queue, cfr, timeQueue, index, outputFileParentName, num_consumers, s, metrics_variables, metrics_objective_direction, consumerConstraints): multiprocessing.Process.__init__(self) self.task_queue = task_queue self.result_queue = result_queue self.timeQueue = timeQueue self.cfr = cfr self.solver = s self.consumerConstraints = consumerConstraints self.index = index self.num_consumers = num_consumers self.ParetoFront = [] self.clock = Clock() self.GIAOptions = GuidedImprovementAlgorithmOptions(verbosity=0, \ incrementallyWriteLog=False, \ writeTotalTimeFilename="timefile.csv", \ writeRandomSeedsFilename="randomseed.csv", useCallLogs=False) self.GIAAlgorithm = GuidedImprovementAlgorithm(self.cfr, self.solver, metrics_variables, \ metrics_objective_direction, [], options=self.GIAOptions) def addParetoPoints(self, point): self.ParetoFront.append(point) def run(self): num_solutions = 0 self.clock.tick("Consumer " + str(self.index)) while True: next_task = self.task_queue.get() try: if next_task == "Poison" or (num_solutions == Options.NUM_INSTANCES): self.task_queue.task_done() break except: pass self.solver.push() self.solver.add(self.consumerConstraints[int(next_task)]) self.consumerConstraints[int(next_task)] self.clock.tick("Task " + str(next_task)) total_sat_calls = 0 total_unsat_time = 0 while True: if self.GIAAlgorithm.s.check() != Common.SAT or num_solutions == Options.NUM_INSTANCES: self.clock.tock("Task " + str(next_task)) self.task_queue.task_done() self.solver.pop() break else: prev_solution = self.GIAAlgorithm.s.model() self.GIAAlgorithm.s.push() NextParetoPoint, _local_count_unsat_calls, _local_count_unsat_calls = self.GIAAlgorithm.ranToParetoFront(prev_solution) self.addParetoPoints(NextParetoPoint) metric_values = self.GIAAlgorithm.get_metric_values(NextParetoPoint) self.result_queue.put((model_to_string(self.cfr, NextParetoPoint), metric_values)) self.GIAAlgorithm.s.pop() tmpNotDominatedByNextParetoPoint = self.GIAAlgorithm.ConstraintNotDominatedByX(NextParetoPoint) self.GIAAlgorithm.s.add(tmpNotDominatedByNextParetoPoint) num_solutions = num_solutions + 1 self.clock.tock("Consumer " + str(self.index)) print("Total Sat Calls: " + total_sat_calls) print("Total Unsat Time: " + total_unsat_time) self.timeQueue.put(self.clock) return 0
class ParSolver(): def __init__(self, cfr, module, solver, metrics_variables, metrics_objective_direction): self.cfr = cfr self.module = module self.solvers = replicateSolver(solver, Options.CORES) self.metrics_variables = metrics_variables self.metrics_objective_direction = metrics_objective_direction self.clock = Clock() self.consumerConstraints = self.splitter() def run(self): if not self.consumerConstraints: self.cfr.metric = Common.BOUND return [] mgr = multiprocessing.Manager() taskQueue = mgr.Queue() solutions = mgr.Queue() timeQueue = mgr.Queue() # Enqueue initial tasks for i in range(Options.NUM_SPLIT): taskQueue.put(i) for i in range(Options.CORES): taskQueue.put("Poison") # Start consumers #case: objectives if self.metrics_variables: self.consumers = [ Consumer.GIAConsumer(taskQueue, solutions, self.cfr, timeQueue, i, "out", Options.CORES, j, self.metrics_variables, self.metrics_objective_direction, self.consumerConstraints) for i, j in zip(range(Options.CORES), self.solvers) ] #case: no objectives else: self.consumers = [ Consumer.StandardConsumer(taskQueue, solutions, self.cfr, timeQueue, i, "out", Options.CORES, j, self.consumerConstraints) for i, j in zip(range(Options.CORES), self.solvers) ] self.clock.tick("ParSolver") for w in self.consumers: w.start() TERMINATED = False for w in self.consumers: if Options.TIME_OUT != 0: w.join(Options.TIME_OUT) else: w.join() if w.is_alive(): TERMINATED = True w.terminate() if TERMINATED: GeneralHeuristics.safe_raise_heuristic_failure_exception( "Heuristic Timed Out") results = [] while not solutions.empty(): result = solutions.get() results.append(result) while not timeQueue.empty(): clock = timeQueue.get() self.clock = self.clock.combineClocks(clock) self.clock.tick("Merge") merged_results = self.merge(results) self.clock.tock("Merge") self.clock.tock("ParSolver") self.clock.getParallelStats(self.cfr) return merged_results def merge(self, results): if self.metrics_variables: results = self.removeDominatedAndEqual(results) return [i for (i, _) in results] else: return list(set(results)) def checkDominated(self, l, r): worseInOne = False betterInOne = False for i in range(len(l)): ml = l[i] mr = r[i] if self.metrics_objective_direction[i] == METRICS_MAXIMIZE: if ml < mr: worseInOne = True elif ml > mr: betterInOne = True elif self.metrics_objective_direction[i] == METRICS_MINIMIZE: if ml > mr: worseInOne = True elif ml < mr: betterInOne = True if (worseInOne and not betterInOne): return True return False def removeDominatedAndEqual(self, results): count = len(results) removalList = [False for _ in range(count)] for i in range(count): for j in range(count): if i != j: if self.checkDominated(results[i][1], results[j][1]): removalList[i] = True elif i < j and (results[i][0] == results[j][0] or results[i][1] == results[j][1]): removalList[i] = True nonDominated = [] for i in range(len(removalList)): if not removalList[i]: nonDominated.append(results[i]) return nonDominated def splitter(self): heuristic = GeneralHeuristics.heuristics[Options.SPLIT] return heuristic(self.cfr, self.module, Options.NUM_SPLIT)