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