Esempio n. 1
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
Esempio n. 2
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
Esempio n. 3
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)
Esempio n. 4
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
Esempio n. 5
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
Esempio n. 6
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)