Exemple #1
0
def main():
    if not len(sys.argv) > 1:
        print("Expected at least one module filename", file=sys.stderr)
        exit(1)

    def process_diagnostic(diag):
        print("\n".join(diag.render()), file=sys.stderr)
        if diag.level in ("fatal", "error"):
            exit(1)

    engine = diagnostic.Engine()
    engine.process = process_diagnostic

    modules = []
    for filename in sys.argv[1:]:
        modules.append(Module(Source.from_filename(filename, engine=engine)))

    llobj = RV32GTarget().compile_and_link(modules)

    basename, ext = os.path.splitext(sys.argv[-1])
    with open(basename + ".so", "wb") as f:
        f.write(llobj)
Exemple #2
0
def main():
    def process_diagnostic(diag):
        print("\n".join(diag.render()))
        if diag.level in ("fatal", "error"):
            exit(1)

    engine = diagnostic.Engine()
    engine.process = process_diagnostic

    mod = Module(Source.from_string("".join(fileinput.input()).expandtabs(), engine=engine))

    target = NativeTarget()
    llmod = mod.build_llvm_ir(target=target)

    # Add main so that the result can be executed with lli
    llmain = ll.Function(llmod, ll.FunctionType(ll.VoidType(), []), "main")
    llbuilder = ll.IRBuilder(llmain.append_basic_block("entry"))
    llbuilder.call(llmod.get_global(llmod.name + ".__modinit__"), [
                    ll.Constant(ll.IntType(8).as_pointer(), None)])
    llbuilder.ret_void()

    print(llmod)
Exemple #3
0
def main():
    if not len(sys.argv) == 2:
        print("Expected exactly one module filename", file=sys.stderr)
        exit(1)

    def process_diagnostic(diag):
        print("\n".join(diag.render()), file=sys.stderr)
        if diag.level in ("fatal", "error"):
            exit(1)

    engine = diagnostic.Engine()
    engine.process = process_diagnostic

    with open(sys.argv[1]) as f:
        testcase_code = compile(f.read(), f.name, "exec")
        testcase_vars = {'__name__': 'testbench'}
        exec(testcase_code, testcase_vars)

    ddb_path = os.path.join(os.path.dirname(sys.argv[1]), "device_db.pyon")
    dmgr = DeviceManager(DeviceDB(ddb_path))

    def embed():
        experiment = testcase_vars["Benchmark"](dmgr)

        stitcher = Stitcher(core=experiment.core, dmgr=dmgr)
        stitcher.stitch_call(experiment.run, (experiment, ), {})
        stitcher.finalize()
        return stitcher

    stitcher = embed()
    module = Module(stitcher)

    benchmark(lambda: embed(), "ARTIQ embedding")

    benchmark(lambda: Module(stitcher), "ARTIQ transforms and validators")

    benchmark(lambda: OR1KTarget().compile_and_link([module]),
              "LLVM optimization and linking")
Exemple #4
0
    def __init__(self, core, dmgr, engine=None):
        self.core = core
        self.dmgr = dmgr
        if engine is None:
            self.engine = diagnostic.Engine(all_errors_are_fatal=True)
        else:
            self.engine = engine

        self.name = ""
        self.typedtree = []
        self.inject_at = 0
        self.globals = {}

        # We don't want some things from the prelude as they are provided in
        # the host Python namespace and gain special meaning when quoted.
        self.prelude = prelude.globals()
        self.prelude.pop("print")
        self.prelude.pop("array")

        self.functions = {}

        self.embedding_map = EmbeddingMap()
        self.value_map = defaultdict(lambda: [])
Exemple #5
0
def main():
    if len(sys.argv) > 1 and sys.argv[1] == "+diag":
        del sys.argv[1]
        diag = True
        def process_diagnostic(diag):
            print("\n".join(diag.render(only_line=True)))
            if diag.level == "fatal":
                exit()
    else:
        diag = False
        def process_diagnostic(diag):
            print("\n".join(diag.render(colored=False)))
            if diag.level in ("fatal", "error"):
                exit(1)

    if len(sys.argv) > 1 and sys.argv[1] == "+delay":
        del sys.argv[1]
        force_delays = True
    else:
        force_delays = False

    engine = diagnostic.Engine()
    engine.process = process_diagnostic

    try:
        mod = Module(Source.from_string("".join(fileinput.input()).expandtabs(), engine=engine))

        if force_delays:
            for var in mod.globals:
                typ = mod.globals[var].find()
                if types.is_function(typ) and types.is_indeterminate_delay(typ.delay):
                    process_diagnostic(typ.delay.find().cause)

        print(repr(mod))
    except:
        if not diag: raise
Exemple #6
0
    def _compute_value_type(self, object_value, object_type, object_loc,
                            attr_name, loc):
        if not hasattr(object_value, attr_name):
            if attr_name.startswith('_'):
                names = set(
                    filter(lambda name: not name.startswith('_'),
                           dir(object_value)))
            else:
                names = set(dir(object_value))
            suggestion = suggest_identifier(attr_name, names)

            note = diagnostic.Diagnostic("note", "attribute accessed here", {},
                                         loc)
            if suggestion is not None:
                diag = diagnostic.Diagnostic(
                    "error",
                    "host object does not have an attribute '{attr}'; "
                    "did you mean '{suggestion}'?", {
                        "attr": attr_name,
                        "suggestion": suggestion
                    },
                    object_loc,
                    notes=[note])
            else:
                diag = diagnostic.Diagnostic(
                    "error",
                    "host object does not have an attribute '{attr}'",
                    {"attr": attr_name},
                    object_loc,
                    notes=[note])
            self.engine.process(diag)
            return

        # Figure out what ARTIQ type does the value of the attribute have.
        # We do this by quoting it, as if to serialize. This has some
        # overhead (i.e. synthesizing a source buffer), but has the advantage
        # of having the host-to-ARTIQ mapping code in only one place and
        # also immediately getting proper diagnostics on type errors.
        attr_value = getattr(object_value, attr_name)
        if inspect.ismethod(attr_value) and types.is_instance(object_type):
            # In cases like:
            #     class c:
            #         @kernel
            #         def f(self): pass
            # we want f to be defined on the class, not on the instance.
            attributes = object_type.constructor.attributes
            attr_value = SpecializedFunction(object_type, attr_value.__func__)
        else:
            attributes = object_type.attributes

        attr_value_type = None

        if isinstance(attr_value, list):
            # Fast path for lists of scalars.
            IS_FLOAT = 1
            IS_INT32 = 2
            IS_INT64 = 4

            state = 0
            for elt in attr_value:
                if elt.__class__ == float:
                    state |= IS_FLOAT
                elif elt.__class__ == int:
                    if -2**31 < elt < 2**31 - 1:
                        state |= IS_INT32
                    elif -2**63 < elt < 2**63 - 1:
                        state |= IS_INT64
                    else:
                        state = -1
                        break
                else:
                    state = -1

            if state == IS_FLOAT:
                attr_value_type = builtins.TList(builtins.TFloat())
            elif state == IS_INT32:
                attr_value_type = builtins.TList(builtins.TInt32())
            elif state == IS_INT64:
                attr_value_type = builtins.TList(builtins.TInt64())

        if attr_value_type is None:
            # Slow path. We don't know what exactly is the attribute value,
            # so we quote it only for the error message that may possibly result.
            ast = self.quote(attr_value, object_loc.expanded_from)

            def proxy_diagnostic(diag):
                note = diagnostic.Diagnostic(
                    "note",
                    "while inferring a type for an attribute '{attr}' of a host object",
                    {"attr": attr_name}, loc)
                diag.notes.append(note)

                self.engine.process(diag)

            proxy_engine = diagnostic.Engine()
            proxy_engine.process = proxy_diagnostic
            Inferencer(engine=proxy_engine).visit(ast)
            IntMonomorphizer(engine=proxy_engine).visit(ast)
            attr_value_type = ast.type

        return attributes, attr_value_type