Exemplo n.º 1
0
def test_extract_edge_mapping_multiple_start_nodes(substrate, triangle_request):
    triangle_request.node[i]["allowed_nodes"] = [u, v]
    scenario = datamodel.Scenario("test", substrate, [triangle_request])

    mc = commutativity_model.CommutativityModelCreator(scenario)
    mc.model = MockModel("mockmodel")
    mc.preprocess_input()
    mc._create_sub_lp_variables()

    ku_index = frozenset([(k, u)])
    ij_sub_lp = mc.edge_sub_lp[triangle_request][ij][ku_index]
    ij_sub_lp.var_node_flow_source[u].x = 0.3
    ij_sub_lp.var_node_flow_source[v].x = 0.7

    ij_sub_lp.var_edge_flow[uv].x = 0.3

    ij_sub_lp.var_node_flow_sink[v].x = 1.0

    partial_mapping = solutions.Mapping("test_mapping", triangle_request, substrate, True)
    partial_mapping.map_node(i, u)

    assert ij_sub_lp.extract_edge_mapping(partial_mapping) == ([uv], v, 0.3)

    partial_mapping = solutions.Mapping("test_mapping", triangle_request, substrate, True)
    partial_mapping.map_node(i, v)

    assert ij_sub_lp.extract_edge_mapping(partial_mapping) == ([], v, 0.7)
Exemplo n.º 2
0
    def recover_fractional_solution_from_variables(self):
        solution_name = modelcreator.construct_name(
            "solution_", req_name="", sub_name=self.substrate.name)
        self.solution = solutions.FractionalScenarioSolution(
            solution_name, self.scenario)
        for req in self.requests:
            # mapping_name = modelcreator.construct_name("fractual_mapping_", req_name=req.name,
            #                              sub_name=self.substrate.name)
            is_embedded = self.var_embedding_decision[req].x > 0.5
            # mapping = mp_pkg.Mapping(mapping_name, req, self.substrate, is_embedded=is_embedded)

            if is_embedded:
                maps = self.obtain_fractional_mappings_of_request(req)
                if not maps:
                    mapping_name = modelcreator.construct_name(
                        "empty_mapping_",
                        req_name=req.name,
                        sub_name=self.substrate.name)
                    self.solution.add_mapping(
                        req,
                        solutions.Mapping(mapping_name, req, self.substrate,
                                          False), {}, {})
                for m, flow, load in maps:
                    self.solution.add_mapping(req, m, flow, load)
                    # TODO: even if the request is not embedded, a mapping object should be created, indicating that the request was not embedded
        return self.solution
Exemplo n.º 3
0
    def recover_integral_solution_from_variables(self):
        solution_name = modelcreator.construct_name(
            "solution_", req_name="", sub_name=self.substrate.name)
        self.solution = solutions.IntegralScenarioSolution(
            solution_name, self.scenario)

        for req in self.requests:

            # create mapping for specific req and substrate
            mapping_name = modelcreator.construct_name(
                "mapping_", req_name=req.name, sub_name=self.substrate.name)

            is_embedded = self.var_embedding_decision[req].x > 0.5

            mapping = solutions.Mapping(mapping_name,
                                        req,
                                        self.substrate,
                                        is_embedded=is_embedded)

            if is_embedded:
                self.obtain_integral_mapping_of_request(req, mapping)

            self.solution.add_mapping(req, mapping)

        return self.solution
Exemplo n.º 4
0
def test_extract_edge_mapping_only_use_exit_with_remaining_node_sink_flow(substrate, triangle_request):
    triangle_request.node[j]["allowed_nodes"] = [v, w]
    scenario = datamodel.Scenario("test", substrate, [triangle_request])

    mc = commutativity_model.CommutativityModelCreator(scenario)
    mc.model = MockModel("mockmodel")
    mc.preprocess_input()
    mc._create_sub_lp_variables()

    ku_index = frozenset([(k, u)])
    ij_sub_lp = mc.edge_sub_lp[triangle_request][ij][ku_index]
    ij_sub_lp.var_node_flow_source[u].x = 1.0

    # This contains 3 mappings with values 0.5, 0.25 and 0.25
    ij_sub_lp.var_edge_flow[uw].x = 0.5
    ij_sub_lp.var_edge_flow[uv].x = 0.5
    ij_sub_lp.var_edge_flow[wv].x = 0.25

    ij_sub_lp.var_node_flow_sink[w].x = 0.25
    ij_sub_lp.var_node_flow_sink[v].x = 0.75

    partial_mapping = solutions.Mapping("test_mapping", triangle_request, substrate, True)
    partial_mapping.map_node(i, u)

    ij_sub_lp._used_flow_source[u] += 0.5
    ij_sub_lp._used_flow[uv] += 0.5
    ij_sub_lp._used_flow_sink[v] += 0.5
    assert ij_sub_lp.extract_edge_mapping(partial_mapping) == ([uw], w, 0.25)

    ij_sub_lp._used_flow_source[u] += 0.25
    ij_sub_lp._used_flow[uw] += 0.25
    ij_sub_lp._used_flow_sink[w] += 0.25
    assert ij_sub_lp.extract_edge_mapping(partial_mapping) == ([uw, wv], v, 0.25)
def test_extract_edge_mapping_reversed_edge(substrate, triangle_request):
    triangle_request.graph["root"] = j

    scenario = datamodel.Scenario("test", substrate, [triangle_request])

    mc = commutativity_model.CommutativityModelCreator(scenario)
    mc.model = MockModel("mockmodel")
    mc.preprocess_input()
    mc._create_sub_lp_variables()

    ku_index = frozenset([(k, u)])
    kv_index = frozenset([(k, v)])

    ji_sub_lp = list(mc.edge_sub_lp[triangle_request][("j", "i")].values())[0]
    ji_sub_lp.var_node_flow_source[v].x = 0.5
    ji_sub_lp.var_edge_flow[wu].x = 0.5
    ji_sub_lp.var_edge_flow[vw].x = 0.5
    ji_sub_lp.var_node_flow_sink[u].x = 0.5

    partial_mapping = solutions.Mapping("test_mapping", triangle_request,
                                        substrate, True)
    partial_mapping.map_node(j, v)

    assert ji_sub_lp.extract_edge_mapping(partial_mapping) == ([uw,
                                                                wv], u, 0.5)
def test_reduce_flow_in_modelcreator(substrate, triangle_request, import_gurobi_mock):
    MockModel = import_gurobi_mock.MockModel
    scenario = datamodel.Scenario("test", substrate, [triangle_request])
    mc = commutativity_model.CommutativityModelCreator(scenario)
    mc.model = MockModel("mock_model")
    mc.preprocess_input()
    mc.create_variables_embedding_decision()
    mc._create_node_mapping_variables()
    mc._create_sub_lp_variables()

    ku_index = frozenset([(k, u)])

    mapping = solutions.Mapping("foo", triangle_request, substrate, True)
    mapping.mapping_nodes = {i: u, j: v, k: u}
    mapping.mapping_edges = {ij: [uv], jk: [vw, wu], ik: []}

    mc.reduce_flow(mapping, 0.25)
    assert mc._used_flow_embedding_decision[triangle_request] == 0.25

    assert mc._used_flow_node_mapping[triangle_request][i][u][ku_index] == 0.25
    assert mc._used_flow_node_mapping[triangle_request][j][v][ku_index] == 0.25
    assert mc._used_flow_node_mapping[triangle_request][k][u][frozenset()] == 0.25
    for ij_, uv_list in list(mapping.mapping_edges.items()):
        i_, j_ = ij_
        sub_lp = mc.edge_sub_lp[triangle_request][ij_][ku_index]
        assert sub_lp._used_flow_source[mapping.mapping_nodes[i_]] == 0.25
        assert sub_lp._used_flow_sink[mapping.mapping_nodes[j_]] == 0.25
        for uv_ in uv_list:
            u_, v_ = uv_
            assert sub_lp._used_flow[uv_] == 0.25
Exemplo n.º 7
0
    def construct_results_object(self, result, feasible):
        """
        Constructs

        :param result:
        :param feasible:
        :return:
        """
        total_cost = 0.0
        if feasible:
            node_mapping, link_mapping = result
            total_cost = self.calculate_solution_cost(node_mapping,
                                                      link_mapping)
        solution_alib = solutions.IntegralScenarioSolution(
            name="GBA-solution", scenario=self.scenario)
        runtime = time.time() - self.start_time
        result_alib = GreedyBorderAllocationResult(self.scenario, feasible,
                                                   runtime, total_cost)
        for req in self.scenario.requests:
            mapping_alib = solutions.Mapping("GBA-mapping-{}".format(req.name),
                                             req,
                                             self.scenario.substrate,
                                             is_embedded=feasible)
            # TODO: properly fill Mapping object
            solution_alib.add_mapping(req, mapping_alib)
        result_alib.solutions[result_alib.alg_key].append(solution_alib)
        return result_alib
Exemplo n.º 8
0
 def setup(self):
     self.substrate = datamodel.Substrate("sub1")
     self.request = datamodel.Request("req1")
     self.scenario = datamodel.Scenario("Sen1", self.substrate,
                                        [self.request])
     self.mapping = solutions.Mapping("map1", self.request, self.substrate,
                                      True)
     self.scenariosolution = solutions.IntegralScenarioSolution(
         "Solution1", self.scenario)
Exemplo n.º 9
0
def test_extract_edge_mapping_colocated_nodes(substrate, triangle_request):
    scenario = datamodel.Scenario("test", substrate, [triangle_request])

    mc = commutativity_model.CommutativityModelCreator(scenario)
    mc.model = MockModel("mockmodel")
    mc.preprocess_input()
    mc._create_sub_lp_variables()

    ku_index = frozenset([(k, u)])
    ik_sub_lp = mc.edge_sub_lp[triangle_request][ik][ku_index]
    ik_sub_lp.var_node_flow_source[u].x = 0.5
    ik_sub_lp.var_node_flow_sink[u].x = 0.5

    partial_mapping = solutions.Mapping("test_mapping", triangle_request, substrate, True)
    partial_mapping.map_node(i, u)

    assert ik_sub_lp.extract_edge_mapping(partial_mapping) == ([], u, 0.5)
def test_reduce_flow_in_modelcreator_with_reversed_edges(
        substrate, triangle_request, import_gurobi_mock):
    MockModel = import_gurobi_mock.MockModel
    triangle_request.graph["root"] = j
    scenario = datamodel.Scenario("test", substrate, [triangle_request])
    mc = commutativity_model.CommutativityModelCreator(scenario)
    mc.model = MockModel("mock_model")
    mc.preprocess_input()
    mc.create_variables_embedding_decision()
    mc._create_node_mapping_variables()
    mc._create_sub_lp_variables()

    mapping = solutions.Mapping("foo", triangle_request, substrate, True)
    mapping.mapping_nodes = {i: u, j: v, k: u}
    mapping.mapping_edges = {ij: [uv], jk: [vw, wu], ik: []}

    mc.reduce_flow(mapping, 0.25)
    assert mc._used_flow_embedding_decision[triangle_request] == 0.25

    dag_request = mc.dag_requests[triangle_request]
    cycle_end = [
        i_ for i_ in triangle_request.nodes
        if len(dag_request.get_in_neighbors(i_)) == 2
    ][0]
    comm_index = frozenset([(cycle_end, mapping.mapping_nodes[cycle_end])])

    for i_, u_ in mapping.mapping_nodes.items():
        if i_ == cycle_end:
            assert mc._used_flow_node_mapping[triangle_request][i_][u_][
                frozenset()] == 0.25
        else:
            assert mc._used_flow_node_mapping[triangle_request][i_][u_][
                comm_index] == 0.25
    for ij_, uv_list in mapping.mapping_edges.items():
        # We only need ij_ in the orientation of the BFS request
        if ij_ not in dag_request.edges:
            ij_ = ij_[1], ij_[0]
        i_, j_ = ij_
        sub_lp = mc.edge_sub_lp[triangle_request][ij_][comm_index]
        assert sub_lp._used_flow_source[mapping.mapping_nodes[i_]] == 0.25
        assert sub_lp._used_flow_sink[mapping.mapping_nodes[j_]] == 0.25
        for uv_ in uv_list:
            u_, v_ = uv_
            if sub_lp.is_reversed_edge:
                uv_ = v_, u_
            assert sub_lp._used_flow[uv_] == 0.25
Exemplo n.º 11
0
 def _get_empty_mapping_of_correct_type(self):
     if self.edge_embedding_model == ViNEEdgeEmbeddingModel.UNSPLITTABLE:
         name = mc.construct_name(
             "shortest_path_mapping_", req_name=self._current_request.name, sub_name=self.original_substrate.name
         )
         return solutions.Mapping(
             name, self._current_request, self.original_substrate, is_embedded=True,
         )
     elif self.edge_embedding_model == ViNEEdgeEmbeddingModel.SPLITTABLE:
         name = mc.construct_name(
             "splittable_mapping_", req_name=self._current_request.name, sub_name=self.original_substrate.name
         )
         return SplittableMapping(
             name, self._current_request, self.original_substrate, is_embedded=True,
         )
     else:
         raise ValueError("Invalid edge mapping method: {}".format(self.edge_embedding_model))
Exemplo n.º 12
0
def test_sublp_inconsistency_causes_exception(substrate, triangle_request):
    scenario = datamodel.Scenario("test", substrate, [triangle_request])

    mc = commutativity_model.CommutativityModelCreator(scenario)
    mc.model = MockModel("mockmodel")
    mc.preprocess_input()
    mc._create_sub_lp_variables()

    ku_index = frozenset([(k, u)])

    ij_sub_lp = mc.edge_sub_lp[triangle_request][ij][ku_index]

    ij_sub_lp.var_node_flow_source[u].x = 1.0
    partial_mapping = solutions.Mapping("", triangle_request, substrate, True)
    partial_mapping.mapping_nodes[i] = "u"
    with pytest.raises(ValueError) as e:
        ij_sub_lp.extract_edge_mapping(partial_mapping)
    assert str(e.value) == "Did not find valid edge mapping for ('i', 'j')"
Exemplo n.º 13
0
    def _get_fractional_mapping_and_load_from_path(self, req, mapping_name,
                                                   ext_graph, eedge_path):
        last_used_edge = 0
        previous_vnode = None
        is_embedded = self.var_embedding_decision[req].x > 0.5
        mapping = solutions.Mapping(mapping_name,
                                    req,
                                    self.substrate,
                                    is_embedded=is_embedded)
        load = {x: 0.0 for x in self.substrate.substrate_resources}
        for index, eedge in enumerate(eedge_path):
            if index == 0:
                # map first node of service chain according to first edge
                ntype, snode, vnode = ext_graph.edge[eedge]["node_origin"]
                mapping.map_node(vnode, snode)
                load[(ntype, snode)] += req.get_node_demand(vnode)
                last_used_edge = 0
                previous_vnode = vnode
            else:
                if "node_origin" in ext_graph.edge[eedge]:
                    # this edge represents a node mapping
                    ntype, snode, vnode = ext_graph.edge[eedge]["node_origin"]
                    mapping.map_node(vnode, snode)
                    load[(ntype, snode)] += req.get_node_demand(vnode)
                    # map path between previous_vnode and vnode

                    eedge_path_connecting_previous_vnode_and_vnode = eedge_path[
                        last_used_edge + 1:index]

                    se_path = [
                        ext_graph.edge[eedge]["edge_origin"][0] for eedge in
                        eedge_path_connecting_previous_vnode_and_vnode
                    ]

                    new_edge = (previous_vnode, vnode)
                    mapping.map_edge(new_edge, se_path)
                    for u, v in se_path:
                        load[(u, v)] += req.get_edge_demand(new_edge)

                    last_used_edge = index
                    previous_vnode = vnode
        return mapping, load
Exemplo n.º 14
0
def test_sublp_reduce_flow(substrate, triangle_request):
    scenario = datamodel.Scenario("test", substrate, [triangle_request])

    mc = commutativity_model.CommutativityModelCreator(scenario)
    mc.model = MockModel("mockmodel")
    mc.preprocess_input()
    mc._create_sub_lp_variables()

    ku_index = frozenset([(k, u)])

    ij_sub_lp = mc.edge_sub_lp[triangle_request][ij][ku_index]

    partial_mapping = solutions.Mapping("test_mapping", triangle_request, substrate, True)
    partial_mapping.map_node(i, u)
    partial_mapping.map_node(j, v)
    partial_mapping.map_edge(ij, [uw, wv])

    ij_sub_lp.reduce_flow(partial_mapping, 0.75)

    assert ij_sub_lp._used_flow[uw] == 0.75
    assert ij_sub_lp._used_flow[wv] == 0.75
    assert ij_sub_lp._used_flow_source[u] == 0.75
    assert ij_sub_lp._used_flow_sink[v] == 0.75
    def test_model_fixing_simple_scenario(self):
        sub = datamodel.Substrate("fixing_sub")
        sub.add_node("u", {"t1"}, {"t1": 10}, {"t1": 100})
        sub.add_node("v", {"t1"}, {"t1": 10}, {"t1": 100})
        sub.add_node("w", {"t1"}, {"t1": 10}, {"t1": 100})
        sub.add_node("x", {"t1"}, {"t1": 10}, {"t1": 100})
        sub.add_edge("u", "v")
        sub.add_edge("v", "w")
        sub.add_edge("w", "x")
        sub.add_edge("x", "u")

        req = datamodel.Request("fixing_req")
        req.profit = 1000
        req.add_node("i", 5, "t1", {"u", "v", "w", "x"})
        req.add_node("j", 5, "t1", {"u", "v", "w", "x"})
        req.add_edge("i", "j", 0.5)

        mapping = solutions.Mapping("fixing_mapping", req, sub, True)
        mapping.map_node("i", "u")
        mapping.map_node("j", "x")
        mapping.map_edge(("i", "j"), [("u", "v"), ("v", "w"), ("w", "x")])

        scenario = datamodel.Scenario("fixing_scen", sub, [req],
                                      datamodel.Objective.MAX_PROFIT)
        sol = solutions.IntegralScenarioSolution("fixing_sol", scenario)
        sol.add_mapping(req, mapping)

        mc_ecg = modelcreator_ecg_decomposition.ModelCreatorCactusDecomposition(
            scenario)
        mc_ecg.init_model_creator()
        mc_ecg.fix_mapping_variables_according_to_integral_solution(sol)
        ecg_sol = mc_ecg.compute_integral_solution()

        new_mapping = ecg_sol.solution.request_mapping[req]
        assert new_mapping.mapping_nodes == mapping.mapping_nodes
        assert new_mapping.mapping_edges == mapping.mapping_edges
Exemplo n.º 16
0
    def extract_request_mapping(self, req, labels, mapping_count):
        """
        Extract a request mapping.

        This is called by :meth:`recover_fractional_solution_from_variables`
        as long as there is flow remaining. If there is remaining flow,
        this function should find a mapping.

        :param datamodel.Request req: the request
        :param CommutativityLabels labels: the labels of the request
        :param int mapping_count: the mapping count used for the mapping name
        :return: a mapping of the request and the corresponding flow
        :rtype: (solutions.Mapping, float)
        """
        mapping = solutions.Mapping(
            "mapping_{}_{}".format(req.name, mapping_count), req,
            self.substrate, True)  # TODO: Ask Matthias about is_embedded
        root = req.graph["root"]
        queue = deque([root])
        added_to_queue = {root}
        min_flow_for_mapping = self.var_embedding_decision[
            req].x - self._used_flow_embedding_decision[req]

        u_root_candidates = self.var_node_mapping[req][root].keys()
        for u in u_root_candidates:
            for comm_index, var in self.var_node_mapping[req][root][
                    u].iteritems():
                if var.x - self._used_flow_node_mapping[req][root][u][
                        comm_index] > self.decomposition_epsilon:
                    mapping.map_node(root, u)
                    break
            if root in mapping.mapping_nodes:
                break

        while queue:
            i = queue.popleft()
            u = mapping.mapping_nodes[i]
            for comm_index, var in self.var_node_mapping[req][i][u].iteritems(
            ):
                i_mapping_remaining_flow = var.x - self._used_flow_node_mapping[
                    req][i][u][comm_index]
                if i_mapping_remaining_flow <= self.decomposition_epsilon:
                    continue

                bag_key = {k for k, v in comm_index}
                mapped_nodes_index = self.get_commutativity_index_from_mapping(
                    bag_key, mapping)
                if not (mapped_nodes_index <= comm_index):
                    # index is incompatible with current mapping
                    continue

                # comm_index is a valid choice, extend mapping by it
                for k, w_k in comm_index:
                    if k not in mapping.mapping_nodes:
                        mapping.map_node(k, w_k)
                min_flow_for_mapping = min(min_flow_for_mapping,
                                           i_mapping_remaining_flow)

            for j in self.dag_requests[req].get_out_neighbors(i):
                # handle edge ij
                # pick a comm index consistent with mapping
                ij = i, j
                ij_labels = labels.get_edge_labels(ij)

                # labels of ij are already fixed because labels of i are fixed
                comm_index = self.get_commutativity_index_from_mapping(
                    ij_labels, mapping)

                ij_sub_lp = self.edge_sub_lp[req][ij][comm_index]
                uv_list, v_j, flow = ij_sub_lp.extract_edge_mapping(mapping)
                min_flow_for_mapping = min(min_flow_for_mapping, flow)

                if ij_sub_lp.is_reversed_edge:
                    ij_original_orientation = j, i
                else:
                    ij_original_orientation = ij

                if j not in mapping.mapping_nodes:
                    mapping.map_node(j, v_j)
                mapping.map_edge(ij_original_orientation, uv_list)

                if j not in added_to_queue:
                    queue.append(j)
                    added_to_queue.add(j)
        return mapping, min_flow_for_mapping