Example #1
0
    def run(self):
        """
        Execute the BGP protocol. Must be called after init_partition.
        """
        converged = False
        log.debug("running BGP...")
        for r in self._active_in_partition:
            if r.is_external():
                r.local_bgp_step(self._igp_cost_provider)
        nof_rounds = 0
        while not converged:
            nof_rounds += 1
            if nof_rounds > 100:
                log.error("BGP did not converge after 100 rounds, is it diverging?")
                raise Exception("Bgp did not converge after 100 rounds")
            # log.debug("started next BGP round")
            converged = True
            for r in self._all_in_partition:    # need to do this also for passive nodes to clear their msg_in lists
                r.prepare_next_round()
                converged = converged and r.is_converged()
            if not converged:
                for r in self._active_in_partition:
                    r.local_bgp_step(self._igp_cost_provider)
        log.debug("BGP converged after %d rounds", nof_rounds)

        # select best announcement for all passive nodes as well
        for r in self._passive_in_partition:
            r.local_bgp_step(self._igp_cost_provider, send=False)
Example #2
0
    def _setup_partition_run_bgp(self, flow: Flow):
        self.problem.bgp.init_partition(flow, self._igp_provider)

        # run BGP to determine the selected next hops
        self.problem.bgp.run()
        self._igp_provider.update_bgp_next_hops(
            flow.dst, self.problem.bgp.get_next_hops_for_internal())
        log.debug("computed next hops: %s",
                  self._igp_provider._bgp_next_hop_data)
Example #3
0
    def _explore(self, state: list):
        log.debug("Exploring: {}".format(state))

        p_state = self.problem.failure_model.get_state_prob(state)

        self._igp_provider.recompute()

        fw_graphs = {}
        for flow in self.problem.property.flows:
            self._setup_partition_run_bgp(flow)
            fwg, _ = self._construct_fw_graph_decision_points(flow)
            fw_graphs[flow] = fwg

        self.solution.p_explored = self.solution.p_explored + p_state
        log.debug("checking property for fw graphs: %s", fw_graphs)
        if self.problem.property.check(fw_graphs):
            log.debug(" -> HOLDS")
            self.solution.p_property += p_state
        else:
            log.debug(" -> DOES NOT HOLD")
        self.solution.num_explored += 1

        if self._full_trace:
            fw_graphs[self.problem.property.flows[0]].normalize()
            data = {
                'state': state.copy(),
                'fw_graph': fw_graphs[self.problem.property.flows[0]].next
            }
            self._trace.append(data)
            log.data("explored_reference", data)
Example #4
0
    def compute_bn_event_prob(self, event: BnEvent):
        if len(event.data) == 0:
            return 1.0

        log.debug("started Bayes Net inference")

        # build up minimal network from scratch
        ppy_event = ppy.Event()
        for bnn in self.bn_nodes:
            bnn.clear()
        self.network = []
        for bnn, val in event.data:
            bnn.build_network(self.network)
            ppy_event.setValue(bnn.var, val)

        # perform inference
        res = self._compute_event_prob(ppy_event)
        log.debug("finished inference")
        return res
Example #5
0
    def _explore(self, state: list):
        """
        Explore a given state.
        """
        log.debug("exploring: {}".format(state))

        self._update_graph(state)

        # update shortest paths, partitions, etc.
        self._igp_provider.recompute()

        hot_edges = set()
        fw_graphs = {}
        for flow in self.problem.property.flows:
            self._setup_partition_run_bgp(flow)
            fwg, decision_points = self._construct_fw_graph_decision_points(
                flow)
            fw_graphs[flow] = fwg
            log.debug("computed forwarding graph: %s", fwg)
            self._add_hot_edges_bgp(flow, fwg, decision_points, hot_edges)

        for e in hot_edges:
            e_id = self.problem.link_id_for_edge[e]
            if state[e_id] == -1:
                state[e_id] = 0
                p_state = self.problem.failure_model.get_state_prob(state)
                self._add_to_explore_queue(state, p_state.val())
                state[e_id] = 1
        p_state = self.problem.failure_model.get_state_prob(
            state)  # probability that all hot edges are up
        self.solution.p_explored = self.solution.p_explored + p_state
        log.debug("checking property for fw graphs: %s", fw_graphs)
        if self.problem.property.check(fw_graphs):
            log.debug(" -> HOLDS")
            self.solution.p_property += p_state
        else:
            log.debug(" -> DOES NOT HOLD")
        self.solution.num_explored += 1

        log.debug("current precision: {}".format(
            self.solution.p_explored.invert().val()))

        if self._stat_prec:
            log.data("precision", self.solution.p_explored.invert().val())

        if self._stat_hot and self.solution.num_explored <= 10:
            log.data("fraction_hot", len(hot_edges) / float(len(state)))

        if self._full_trace:
            fw_graphs[self.problem.property.flows[0]].normalize()
            data = {
                'state': state,
                'fw_graph': fw_graphs[self.problem.property.flows[0]].next
            }
            self._trace.append(data)
            log.data("explored_smart", data)