コード例 #1
0
def add_action_node(A: AGraph, G: nx.DiGraph, lambdas, n):
    """ Add an action node to the CAG. """
    output, = A.successors(n)

    # Only allow LoopVariableNodes in the DBN
    if output.attr["node_type"] == "LoopVariableNode":
        oname = output.attr["cag_label"]
        onode = G.nodes[oname]

        # Check if it is an initialization function
        if len(A.predecessors(n)) == 0:
            onode["init_fn"] = getattr(lambdas, n.attr["lambda_fn"])

        # Otherwise append the predecessor function list
        elif n.attr["label"] == "__decision__":
            preds = A.predecessors(n)
            if_var, = [
                n for n in preds
                if list(A.predecessors(n))[0].attr["label"] == "__condition__"
            ]
            condition_fn, = A.predecessors(if_var)
            condition_fn = condition_fn[:condition_fn.rfind("__")]
            condition_lambda = condition_fn.replace("condition", "lambda")
            onode["condition_fn"] = getattr(lambdas, condition_lambda)
        else:
            onode["pred_fns"].append(getattr(lambdas, n.attr["lambda_fn"]))

        # If the type of the function is assign, then add an edge in the CAG
        if n.attr["label"] == "__assign__":
            for i in A.predecessors(n):
                iname = i.attr["cag_label"]
                G.add_edge(iname, oname)
コード例 #2
0
def gen_op_insts(rf_allocs: List[RFallocation], dfg: AGraph, fu: AGraph,
                 input_map: Dict[str, int]) -> List[ATAI]:
    assembly = []
    instructions: List[Instruction] = []

    for instruction in fu.nodes():
        instructions.append(parse_instruction(instruction))

    for instruction in instructions:
        n = dfg.get_node(instruction.name)
        nodes = dfg.predecessors(n)

        input_type0 = inst_input_type(rf_allocs, fu, nodes[0])
        if len(nodes) > 1:
            input_type1 = inst_input_type(rf_allocs, fu, nodes[1])
        else:
            input_type1 = input_type0

        # This should never occur but we check for it anyways
        if input_type0 == OpInput and input_type1 == OpInput:
            if nodes[0] != nodes[1]:
                raise DoubleUnidenticalOPInputException

        # TODO: find scheduling for fetch ops might need to be swapped to fit?
        if input_type0 == RFInput:
            # If the data is in the RF we need to generate fetch instructions
            assembly.append(
                generate_fetch(rf_allocs, instruction, nodes[0],
                               ATAFetch.REG.REG0))
            input0 = RFInput()
        elif input_type0 == OpInput:
            input0 = OpInput()
        else:
            n = input_map[nodes[0].get_name()]
            if n is None:
                raise FUinputException(
                    'Cannot find FU from which predecessing node originates in map'
                )

            input0 = FUinput(n)

        if input_type1 == RFInput:
            assembly.append(
                generate_fetch(rf_allocs, instruction, nodes[1],
                               ATAFetch.REG.REG1))
            input1 = RFInput()
        elif input_type1 == OpInput:
            input1 = OpInput()
        else:
            n = input_map[nodes[1].get_name()]
            if n is None:
                raise FUinputException(
                    'Cannot find FU from which predecessing node originates in map'
                )

            input1 = FUinput(n)

        assembly.append(ATAOp(input0, input1, instruction.cycle))

    return assembly
コード例 #3
0
ファイル: tb_gen.py プロジェクト: FelixBrakel/uGenie-codegen
def gen_add_input2(
        dfg: AGraph, fu: AGraph,
        input_map: Dict[str, int]) -> Tuple[List[Input], List[Output]]:
    outputs: List[Output] = []
    inputs: List[Input] = []
    nodes: List[Instruction] = []
    for node in fu.nodes():
        nodes.append(parse_instruction(node))

    nodes.sort()
    prev_o = 0
    for node in nodes:
        preds = dfg.predecessors(node.name)
        parent0 = parse_instruction(preds[0])
        parent1 = parse_instruction(preds[1])

        if parent0.name in input_map:
            label = dfg.get_node(parent0.name).attr['label']
            if 'mul' in label:
                latency = 2
            else:
                latency = 1

            i0 = prev_o + 1
            inputs.append(
                Input(i0, input_map[parent0.name], parent0.cycle + latency))
        else:
            for output in outputs:
                if output.cycle == parent0.cycle + 1:
                    i0 = output.val
                    break

        if parent1.name in input_map:
            label = dfg.get_node(parent1.name).attr['label']
            if 'mul' in label:
                latency = 2
            else:
                latency = 1

            i1 = prev_o + 1
            inputs.append(
                Input(i1, input_map[parent1.name], parent1.cycle + latency))
        else:
            for output in outputs:
                if output.cycle == parent1.cycle + 1:
                    i1 = output.val
                    break

        expected = i0 + i1
        prev_o = expected
        outputs.append(Output(expected, node.cycle + 1))

    inputs.sort()
    return inputs, outputs
コード例 #4
0
    def from_agraph(cls, A: AGraph, lambdas):
        G = nx.DiGraph()
        variable_nodes = [
            n for n in A.nodes() if n.attr["node_type"] != "ActionNode"
        ]

        for n in variable_nodes:
            name = n.attr["cag_label"]
            G.add_node(name, value=None, pred_fns=[], agraph_name=n)
            if n.attr["is_index"] == "True":
                G.nodes[name]["init_fn"] = lambda: 1
                G.nodes[name]["update_fn"] = (lambda **kwargs: int(
                    kwargs.pop(list(kwargs.keys())[0])) + 1)
                G.add_edge(name, name)

        function_nodes = [n for n in A.nodes() if n not in variable_nodes]

        for f in function_nodes:
            output, = A.successors(f)
            oname = output.attr["cag_label"]

            # Check if it is an initialization function
            if len(A.predecessors(f)) == 0:
                G.nodes[oname]["init_fn"] = getattr(lambdas,
                                                    f.attr["lambda_fn"])
            # Otherwise append the predecessor function list
            elif f.attr["label"] == "__decision__":
                preds = A.predecessors(f)
                if_var, = [
                    n for n in preds if list(A.predecessors(n))
                    [0].attr["label"] == "__condition__"
                ]
                condition_fn, = A.predecessors(if_var)
                cut = condition_fn.rfind("__")
                condition_fn = condition_fn[:cut]
                condition_lambda = condition_fn.replace("condition", "lambda")
                G.nodes[oname]["condition_fn"] = getattr(
                    lambdas, condition_lambda)
            else:
                G.nodes[oname]["pred_fns"].append(
                    getattr(lambdas, f.attr["lambda_fn"]))

            # If the type of the function is assign, then add an edge in the CAG
            if f.attr["label"] == "__assign__":
                for i in A.predecessors(f):
                    iname = i.attr["cag_label"]
                    G.add_edge(iname, oname)

        for n in G.nodes(data=True):
            n_preds = len(n[1]["pred_fns"])
            if n_preds == 0:
                del n[1]["pred_fns"]
            elif n_preds == 1:
                n[1]["update_fn"], = n[1].pop("pred_fns")
            else:
                n[1]["choice_fns"] = n[1].pop("pred_fns")

                def update_fn(n, **kwargs):
                    cond_fn = n[1]["condition_fn"]
                    sig = signature(cond_fn)
                    if cond_fn(**kwargs):
                        return n[1]["choice_fns"][0](**kwargs)
                    else:
                        return n[1]["choice_fns"][1](**kwargs)

                n[1]["update_fn"] = partial(update_fn, n)

        isolated_nodes = [
            n for n in G.nodes()
            if len(list(G.predecessors(n))) == len(list(G.successors(n))) == 0
        ]
        for n in isolated_nodes:
            G.remove_node(n)
        return cls(G)
コード例 #5
0
ファイル: tb_gen.py プロジェクト: FelixBrakel/uGenie-codegen
def gen_mul_inputs(
        dfg: AGraph, fu: AGraph,
        input_map: Dict[str, int]) -> Tuple[List[Input], List[Output]]:
    outputs: List[Output] = []
    inputs: List[Input] = []
    nodes: List[Instruction] = []

    for node in fu.nodes():
        nodes.append(parse_instruction(node))

    nodes.sort()
    prime_idx = 0
    for node in nodes:
        preds = dfg.predecessors(node.name)
        parent0 = parse_instruction(preds[0])
        parent1 = parse_instruction(preds[1])

        label0 = dfg.get_node(parent0.name).attr['label']
        label1 = dfg.get_node(parent1.name).attr['label']

        i0, edge_case0, prime_idx = gen_mul_input(node, parent0, input_map,
                                                  inputs, outputs, prime_idx,
                                                  label0)
        i1, edge_case1, prime_idx = gen_mul_input(node, parent1, input_map,
                                                  inputs, outputs, prime_idx,
                                                  label1)

        if edge_case0 or edge_case1:
            expected = None
        else:
            expected = i0 * i1

        # if parent0.name in input_map:
        #     label = dfg.get_node(parent0.name).attr['label']
        #     if 'mul' in label:
        #         latency = 2
        #     else:
        #         latency = 1
        #
        #     i0 = PRIMES[prime_idx]
        #     prime_idx += 1
        #     inputs.append(Input(i0, input_map[parent0.name], parent0.cycle + latency))
        # else:
        #     for output in outputs:
        #         if output.cycle == parent0.cycle + 2:
        #             i0 = output.val
        #             break
        #
        # if parent1.name in input_map:
        #     label = dfg.get_node(parent1.name).attr['label']
        #     if 'mul' in label:
        #         latency = 2
        #     else:
        #         latency = 1
        #
        #     i1 = PRIMES[prime_idx]
        #     prime_idx += 1
        #     inputs.append(Input(i1, input_map[parent1.name], parent1.cycle + latency))
        # else:
        #     for output in outputs:
        #         if output.cycle == parent1.cycle + 2:
        #             i1 = output.val
        #             break

        # expected = i0 * i1
        outputs.append(Output(expected, node.cycle + 1))

    inputs.sort()
    return inputs, outputs