forked from M-Labs/artiq
artiq_run: allow running LLVM IR/bitcode files, even with trivial RPCs.
This commit is contained in:
parent
da31d29897
commit
914bc9f360
@ -113,15 +113,18 @@ class Target:
|
||||
_dump(os.getenv("ARTIQ_DUMP_LLVM"), "LLVM IR (optimized)", ".ll",
|
||||
lambda: str(llparsedmod))
|
||||
|
||||
return llparsedmod
|
||||
|
||||
def assemble(self, llmodule):
|
||||
lltarget = llvm.Target.from_triple(self.triple)
|
||||
llmachine = lltarget.create_target_machine(
|
||||
features=",".join(["+{}".format(f) for f in self.features]),
|
||||
reloc="pic", codemodel="default")
|
||||
|
||||
_dump(os.getenv("ARTIQ_DUMP_ASM"), "Assembly", ".s",
|
||||
lambda: llmachine.emit_assembly(llparsedmod))
|
||||
lambda: llmachine.emit_assembly(llmodule))
|
||||
|
||||
return llmachine.emit_object(llparsedmod)
|
||||
return llmachine.emit_object(llmodule)
|
||||
|
||||
def link(self, objects, init_fn):
|
||||
"""Link the relocatable objects into a shared library for this target."""
|
||||
@ -139,7 +142,7 @@ class Target:
|
||||
return library
|
||||
|
||||
def compile_and_link(self, modules):
|
||||
return self.link([self.compile(module) for module in modules],
|
||||
return self.link([self.assemble(self.compile(module)) for module in modules],
|
||||
init_fn=modules[0].entry_point())
|
||||
|
||||
def strip(self, library):
|
||||
|
@ -6,9 +6,12 @@ import argparse
|
||||
import sys
|
||||
from operator import itemgetter
|
||||
import logging
|
||||
from collections import defaultdict
|
||||
|
||||
import h5py
|
||||
|
||||
from llvmlite_artiq import binding as llvm
|
||||
|
||||
from artiq.language.environment import EnvExperiment
|
||||
from artiq.master.databases import DeviceDB, DatasetDB
|
||||
from artiq.master.worker_db import DeviceManager, DatasetManager
|
||||
@ -19,21 +22,58 @@ from artiq.tools import *
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class StubObject:
|
||||
def __setattr__(self, name, value):
|
||||
pass
|
||||
|
||||
class ELFRunner(EnvExperiment):
|
||||
class StubObjectMap:
|
||||
def __init__(self):
|
||||
stub_object = StubObject()
|
||||
self.forward_map = defaultdict(lambda: stub_object)
|
||||
self.forward_map[1] = lambda _: None # return RPC
|
||||
self.next_id = -1
|
||||
|
||||
def retrieve(self, object_id):
|
||||
return self.forward_map[object_id]
|
||||
|
||||
def store(self, value):
|
||||
self.forward_map[self.next_id] = value
|
||||
self.next_id -= 1
|
||||
|
||||
class FileRunner(EnvExperiment):
|
||||
def build(self):
|
||||
self.setattr_device("core")
|
||||
self.setattr_argument("file")
|
||||
self.target = OR1KTarget()
|
||||
|
||||
def run(self):
|
||||
with open(self.file, "rb") as f:
|
||||
kernel_library = f.read()
|
||||
kernel_library = self.compile()
|
||||
|
||||
target = OR1KTarget()
|
||||
self.core.comm.load(kernel_library)
|
||||
self.core.comm.run()
|
||||
self.core.comm.serve(ObjectMap(),
|
||||
lambda addresses: target.symbolize(kernel_library, addresses))
|
||||
self.core.comm.serve(StubObjectMap(),
|
||||
lambda addresses: self.target.symbolize(kernel_library, addresses))
|
||||
|
||||
class ELFRunner(FileRunner):
|
||||
def compile(self):
|
||||
with open(self.file, "rb") as f:
|
||||
return f.read()
|
||||
|
||||
class LLVMIRRunner(FileRunner):
|
||||
def compile(self):
|
||||
with open(self.file, "r") as f:
|
||||
llmodule = llvm.parse_assembly(f.read())
|
||||
llmodule.verify()
|
||||
return self.target.link([self.target.assemble(llmodule)],
|
||||
init_fn='__modinit__')
|
||||
|
||||
class LLVMBitcodeRunner(FileRunner):
|
||||
def compile(self):
|
||||
with open(self.file, "rb") as f:
|
||||
llmodule = llvm.parse_bitcode(f.read())
|
||||
llmodule.verify()
|
||||
return self.target.link([self.target.assemble(llmodule)],
|
||||
init_fn='__modinit__')
|
||||
|
||||
|
||||
class DummyScheduler:
|
||||
@ -91,13 +131,21 @@ def get_argparser(with_file=True):
|
||||
|
||||
def _build_experiment(device_mgr, dataset_mgr, args):
|
||||
if hasattr(args, "file"):
|
||||
if args.file.endswith(".elf"):
|
||||
is_elf = args.file.endswith(".elf")
|
||||
is_ll = args.file.endswith(".ll")
|
||||
is_bc = args.file.endswith(".bc")
|
||||
if is_elf or is_ll or is_bc:
|
||||
if args.arguments:
|
||||
raise ValueError("arguments not supported for ELF kernels")
|
||||
raise ValueError("arguments not supported for precompiled kernels")
|
||||
if args.experiment:
|
||||
raise ValueError("experiment-by-name not supported "
|
||||
"for ELF kernels")
|
||||
"for precompiled kernels")
|
||||
if is_elf:
|
||||
return ELFRunner(device_mgr, dataset_mgr, file=args.file)
|
||||
elif is_ll:
|
||||
return LLVMIRRunner(device_mgr, dataset_mgr, file=args.file)
|
||||
elif is_bc:
|
||||
return LLVMBitcodeRunner(device_mgr, dataset_mgr, file=args.file)
|
||||
else:
|
||||
module = file_import(args.file, prefix="artiq_run_")
|
||||
file = args.file
|
||||
|
Loading…
Reference in New Issue
Block a user