예제 #1
0
def connect_invocation_indirect_writes(
        graph: GraphInstance, inst: SystemInstance,
        instances_by_set: Dict[Set, List[DeviceInstance]], gi: DeviceInstance,
        ctxt: InvocationContext):
    graph_type = graph.graph_type
    invocation = ctxt.stat.id

    write_recv_counts = collections.Counter()

    for s in ctxt.get_all_involved_sets():
        for di in instances_by_set[s]:
            write_recv_counts[
                di] += 1  # Everything has an execute, even those not on the iter set

    for (index, arg) in ctxt.indirect_writes:
        dst_type = graph_type.device_types["set_{}".format(arg.to_set.id)]
        dst_pin = dst_type.pins["{invocation}_arg{index}_write_recv".format(
            invocation=invocation, index=index)]
        src_type = graph_type.device_types["set_{}".format(arg.iter_set.id)]
        src_pin_name = "{invocation}_arg{index}_write_send".format(
            invocation=invocation, index=index)
        src_pin = src_type.pins[src_pin_name]

        iter_instances = instances_by_set[arg.iter_set]
        to_instances = instances_by_set[arg.to_set]
        mapping = inst.maps[arg.map]
        if arg.index >= 0:
            for (src_index, src_instance) in enumerate(iter_instances):
                dst_index = mapping[src_index][arg.index]
                dst_instance = to_instances[dst_index]
                write_recv_counts[dst_instance] += 1
                graph.create_edge_instance(dst_instance, dst_pin, src_instance,
                                           src_pin)
        else:
            for (src_index, src_instance) in enumerate(iter_instances):
                for ai in range(arg.map.arity):
                    dst_index = mapping[src_index][ai]
                    dst_instance = to_instances[dst_index]
                    write_recv_counts[dst_instance] += 1
                    graph.create_edge_instance(dst_instance, dst_pin,
                                               src_instance, src_pin,
                                               {"index": ai})

    write_recv_total_name = "{invocation}_write_recv_total".format(
        invocation=invocation)
    for (di, count) in write_recv_counts.items():
        di.set_property(write_recv_total_name, count)
예제 #2
0
def connect_invocation_indirect_reads(
        graph: GraphInstance, inst: SystemInstance,
        instances_by_set: Dict[Set, List[DeviceInstance]], gi: DeviceInstance,
        ctxt: InvocationContext):
    graph_type = graph.graph_type
    invocation = ctxt.stat.id

    for (index, arg) in ctxt.indirect_reads:
        dst_type = graph_type.device_types["set_{}".format(arg.iter_set.id)]
        dst_pin = dst_type.pins["{invocation}_arg{index}_read_recv".format(
            invocation=invocation, index=index)]
        src_type = graph_type.device_types["set_{}".format(arg.to_set.id)]
        src_pin_name = "{invocation}_dat_{dat}_read_send".format(
            invocation=invocation, dat=arg.dat.id)
        if src_pin_name not in src_type.pins:
            raise RuntimeError(
                "Couldn't find pin {} in {}. Pins are {}".format(
                    src_pin_name, src_type.id, ",".join(src_type.pins)))
        src_pin = src_type.pins[src_pin_name]

        iter_instances = instances_by_set[arg.iter_set]
        to_instances = instances_by_set[arg.to_set]
        mapping = inst.maps[arg.map]

        if arg.index >= 0:
            for (dst_index, dst_instance) in enumerate(iter_instances):
                src_index = mapping[dst_index][arg.index]
                src_instance = to_instances[src_index]
                graph.create_edge_instance(dst_instance, dst_pin, src_instance,
                                           src_pin)
        else:
            assert -arg.index == arg.map.arity
            for (dst_index, dst_instance) in enumerate(iter_instances):
                for index in range(arg.map.arity):
                    src_index = mapping[dst_index][index]
                    src_instance = to_instances[src_index]
                    graph.create_edge_instance(dst_instance, dst_pin,
                                               src_instance, src_pin,
                                               {"index": index})
예제 #3
0
def build_graph(globalDeviceType: str, spec: SystemSpecification,
                inst: SystemInstance, code: Statement):
    graphTypeBuilder = sync_compiler(spec, code)
    graphType = graphTypeBuilder.build()

    graph = GraphInstance("op2", graphType)

    for g in spec.globals.values():
        if isinstance(g, MutableGlobal):
            graph.set_property("init_global_{}".format(g.id),
                               inst.globals[g].tolist())
        elif isinstance(g, ConstGlobal):
            graph.set_property("global_{}".format(g.id),
                               inst.globals[g].tolist())
        else:
            assert "Unknown global type"

    gi = graph.create_device_instance("global", globalDeviceType)

    instancesBySet = {}  # type: Dict[Set,List[DeviceInstance]]
    instancesByName = {}  # type: Dict[str,DeviceInstance]
    for set in spec.sets.values():
        instances = instancesBySet.setdefault(set, [])
        dt = graphType.device_types["set_{}".format(set.id)]
        for i in range(inst.sets[set]):
            name = "{}_{}".format(set.id, i)
            di = graph.create_device_instance(name, dt)
            instances.append(di)
            instancesByName[name] = di

    for (dat, vals) in inst.dats.items():
        init_dat_name = "init_dat_{}".format(dat.id)
        for (index, di) in enumerate(instancesBySet[dat.set]):
            sys.stderr.write("{}, {}, {}\n".format(dat.set.id, dat.id, index))
            di.set_property(init_dat_name, vals[index].tolist())

    kernels = find_kernels_in_code(code)
    for (i, stat) in enumerate(kernels):
        ctxt = InvocationContext(spec, stat)
        connect_invocation(graph, inst, instancesBySet, gi, ctxt)

    return graph
예제 #4
0
def connect_invocation(graph: GraphInstance, inst: SystemInstance,
                       instances_by_set: Dict[Set, List[DeviceInstance]],
                       gi: DeviceInstance, ctxt: InvocationContext):
    graph_type = graph.graph_type

    invocation = ctxt.stat.id
    all_involved = ctxt.get_all_involved_sets()
    total_responding_devices = 0
    for s in all_involved:
        begin = "{}_begin".format(invocation)
        end = "{}_end".format(invocation)
        for di in instances_by_set[s]:
            graph.create_edge_instance(di, begin, gi, begin)
            graph.create_edge_instance(gi, end, di, end)
            total_responding_devices += 1

    graph.set_property(
        "{invocation}_total_responding_devices".format(invocation=invocation),
        total_responding_devices)

    connect_invocation_indirect_reads(graph, inst, instances_by_set, gi, ctxt)
    connect_invocation_indirect_writes(graph, inst, instances_by_set, gi, ctxt)
    def instantiate(self, res: GraphInstance, graphTypes, externalLibs):
        """
            externalLibs={
                "libname": {
                    "name": Cell1,
                    "name2": Cell2
                }
                
            }
        """
        # gates
        graphType = graphTypes["circuit_gates"]
        inputTerminalGate = graphType.device_types["input_terminal"]
        outputTerminalGate = graphType.device_types["output_terminal"]
        ioOracle = graphType.device_types["io_oracle"]
        # exit is controlled by global `max_ticks`
        exitNode = graphType.device_types["exit_node"]
        graphInstDict = {}
        # io terminals
        inTermInsts = []
        outTermInsts = []
        def get_gate_type(libRef, cellRef):
            cell = externalLibs[libRef][cellRef]
            return cell.orignal_name

        def find_gt_gate(gateType, device_types=graphType.device_types):
            return device_types[gateMappings[gateType]]
        
        def get_input_ports(cell):
            return [ p for (p, dirc) in cell.ports.items() if dirc == "INPUT" ]

        def get_output_ports(cell):
            return [ p for (p, dirc) in cell.ports.items() if dirc == "OUTPUT" ]
        
        def get_net_terminals(cell, direction: str, nets, eLibs, graphInstDict):
            """
                return terminal device(s) and its port
                    port must match port definition in graph schema
                INPUT for a Cell is drain, but it is src for a port
            """
            srcTerms = []
            for term in nets:
                if term.instanceRef:
                    inst = cell.instances[term.instanceRef]
                    # the base gate
                    gate = eLibs[inst.libRef][inst.cellRef]
                    if gate.ports[term.portRef] != direction:
                        srcTerms.append(
                            (graphInstDict[term.instanceRef],
                            term.portRef)
                        )
                else:
                    if cell.ports[term.portRef] == direction:
                        # input terminal has only one output pin
                        # output terminal has only one receive pin
                        pinName = "out" if direction == "INPUT" else "receive"
                        srcTerms.append(
                            (graphInstDict[term.portRef],
                            pinName)
                        )
            if direction == "INPUT":
                assert(len(srcTerms) == 1,
                    "There can only be one source terminal in the net", 
                    srcTerms)
                return srcTerms[0]
            else:
                return srcTerms


            


        # construct device instance
        for (instId, inst) in self.instances.items():
            gType = get_gate_type(inst.libRef, inst.cellRef)
            node = DeviceInstance(
                parent=res,
                id="{0}_{1}".format(gType, instId),
                device_type=find_gt_gate(gType),
                )
            res.add_device_instance(node)
            graphInstDict[instId] = node
        
        # construct input terminals
        inTerms = get_input_ports(self)
        inTermTid = 0
        for inPin in inTerms:
            gid = inPin
            node = DeviceInstance(
                parent=res,
                id="{0}_{1}_{2}".format(self.name, "it", gid),
                device_type=inputTerminalGate,
                properties={"tid": inTermTid}
            )
            inTermTid += 1
            res.add_device_instance(node)
            graphInstDict[gid] = node
            inTermInsts.append(node)
        
        # construct output terminals
        outTerms = get_output_ports(self)
        outTermTid = 0
        for outPin in outTerms:
            gid = outPin
            node = DeviceInstance(
                parent=res,
                id="{0}_{1}_{2}".format(self.name, "ot", gid),
                device_type=outputTerminalGate,
                properties={"tid": outTermTid}
            )
            outTermTid += 1
            res.add_device_instance(node)
            graphInstDict[gid] = node
            outTermInsts.append(node)

        # construct edge instances
        for (_, edges) in self.nets.items():
            # find the only source
            (srcDev, srcPin) = get_net_terminals(
                self,
                "INPUT", edges,
                externalLibs, graphInstDict)
            # find drains
            drains = get_net_terminals(
                self,
                "OUTPUT", edges,
                externalLibs, graphInstDict)
            
            for (dstDev, dstPin) in drains:
                # except KeyError:
                #     srcDev = None
                #     srcPin = None
                edgeInst = EdgeInstance(
                    parent=res,
                    dst_device=dstDev,
                    dst_pin=dstPin,
                    src_device=srcDev,
                    src_pin=srcPin)
                res.add_edge_instance(edgeInst)
        # construct io_oracle
        ioOracleInst = DeviceInstance(
            parent=res,
            id="{0}_io_oracle".format(self.name),
            device_type=ioOracle,
            properties={"no_inputs": len(inTermInsts),
                "no_outputs": len(outTermInsts),
                "combinations": pow(2, len(inTermInsts))-1,
                "full_ot_mask": pow(2, len(outTermInsts))-1 }
        )
        res.add_device_instance(ioOracleInst)
        for iTerm in inTermInsts:
            edgeInst = EdgeInstance(
                parent=res,
                dst_device=iTerm,
                dst_pin="io_oracle_receive",
                src_device=ioOracleInst,
                src_pin="it_feed"
            )
            res.add_edge_instance(edgeInst)
        for oTerm in outTermInsts:
            edgeInst = EdgeInstance(
                parent=res,
                dst_device=ioOracleInst,
                dst_pin="ot_receive",
                src_device=oTerm,
                src_pin="out"
            )
            res.add_edge_instance(edgeInst)
예제 #6
0
#     d=int(sys.argv[1])
# if len(sys.argv)>2:
#     b=int(sys.argv[2])
# if len(sys.argv)>3:
#     maxTicks=int(sys.argv[3])

graphType = graphTypes["circuit_gates"]
universal2Gate = graphType.device_types["universal2"]
inputTerminalGate = graphType.device_types["input_terminal"]
outputTerminalGate = graphType.device_types["output_terminal"]
exitNode = graphType.device_types["exit_node"]

instName = "full_adder_1bit"

properties = {"max_ticks": maxTicks}
res = GraphInstance(instName, graphType, None)

usingCircuit = {
    "name":
    "1-bit full adder Cin, A, B -> Sum, Cout",
    "in": [1, 2, 3],
    "out": [5, 11],
    "gates": [{
        "id": 4,
        "type": "XOR",
        "in": [2, 3]
    }, {
        "id": 5,
        "type": "XOR",
        "in": [1, 4]
    }, {
# if len(sys.argv)>1:
#     d=int(sys.argv[1])
# if len(sys.argv)>2:
#     b=int(sys.argv[2])
# if len(sys.argv)>3:
#     maxTicks=int(sys.argv[3])

graphType = graphTypes["circuit_gates"]

properties = {"max_ticks": maxTicks}

for d in designs_sexp:
    designName = get_sexp_name(d)
    designContents = get_sexp_list_contents(d)
    cellRefs = get_sexp_list(designContents, "cellRef")
    res = GraphInstance(designName, graphType, None)
    for cellRef in cellRefs:
        cellRefName = get_sexp_name(cellRef)
        libRef = get_sexp_list_content(cellRef)
        libRefName = get_sexp_name(libRef)
        cell = intLibs[libRefName][cellRefName]
        cell.instantiate(res=res, graphTypes=graphTypes, externalLibs=extLibs)

if args.output_file == "STDOUT":
    save_dst = sys.stdout
else:
    save_dst = args.output_file

save_graph(res, save_dst)
#print(extLibs)