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",
|
_dump(os.getenv("ARTIQ_DUMP_LLVM"), "LLVM IR (optimized)", ".ll",
|
||||||
lambda: str(llparsedmod))
|
lambda: str(llparsedmod))
|
||||||
|
|
||||||
|
return llparsedmod
|
||||||
|
|
||||||
|
def assemble(self, llmodule):
|
||||||
lltarget = llvm.Target.from_triple(self.triple)
|
lltarget = llvm.Target.from_triple(self.triple)
|
||||||
llmachine = lltarget.create_target_machine(
|
llmachine = lltarget.create_target_machine(
|
||||||
features=",".join(["+{}".format(f) for f in self.features]),
|
features=",".join(["+{}".format(f) for f in self.features]),
|
||||||
reloc="pic", codemodel="default")
|
reloc="pic", codemodel="default")
|
||||||
|
|
||||||
_dump(os.getenv("ARTIQ_DUMP_ASM"), "Assembly", ".s",
|
_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):
|
def link(self, objects, init_fn):
|
||||||
"""Link the relocatable objects into a shared library for this target."""
|
"""Link the relocatable objects into a shared library for this target."""
|
||||||
|
@ -139,7 +142,7 @@ class Target:
|
||||||
return library
|
return library
|
||||||
|
|
||||||
def compile_and_link(self, modules):
|
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())
|
init_fn=modules[0].entry_point())
|
||||||
|
|
||||||
def strip(self, library):
|
def strip(self, library):
|
||||||
|
|
|
@ -6,9 +6,12 @@ import argparse
|
||||||
import sys
|
import sys
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
import logging
|
import logging
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
import h5py
|
import h5py
|
||||||
|
|
||||||
|
from llvmlite_artiq import binding as llvm
|
||||||
|
|
||||||
from artiq.language.environment import EnvExperiment
|
from artiq.language.environment import EnvExperiment
|
||||||
from artiq.master.databases import DeviceDB, DatasetDB
|
from artiq.master.databases import DeviceDB, DatasetDB
|
||||||
from artiq.master.worker_db import DeviceManager, DatasetManager
|
from artiq.master.worker_db import DeviceManager, DatasetManager
|
||||||
|
@ -19,21 +22,58 @@ from artiq.tools import *
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
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):
|
def build(self):
|
||||||
self.setattr_device("core")
|
self.setattr_device("core")
|
||||||
self.setattr_argument("file")
|
self.setattr_argument("file")
|
||||||
|
self.target = OR1KTarget()
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
with open(self.file, "rb") as f:
|
kernel_library = self.compile()
|
||||||
kernel_library = f.read()
|
|
||||||
|
|
||||||
target = OR1KTarget()
|
|
||||||
self.core.comm.load(kernel_library)
|
self.core.comm.load(kernel_library)
|
||||||
self.core.comm.run()
|
self.core.comm.run()
|
||||||
self.core.comm.serve(ObjectMap(),
|
self.core.comm.serve(StubObjectMap(),
|
||||||
lambda addresses: target.symbolize(kernel_library, addresses))
|
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:
|
class DummyScheduler:
|
||||||
|
@ -91,13 +131,21 @@ def get_argparser(with_file=True):
|
||||||
|
|
||||||
def _build_experiment(device_mgr, dataset_mgr, args):
|
def _build_experiment(device_mgr, dataset_mgr, args):
|
||||||
if hasattr(args, "file"):
|
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:
|
if args.arguments:
|
||||||
raise ValueError("arguments not supported for ELF kernels")
|
raise ValueError("arguments not supported for precompiled kernels")
|
||||||
if args.experiment:
|
if args.experiment:
|
||||||
raise ValueError("experiment-by-name not supported "
|
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)
|
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:
|
else:
|
||||||
module = file_import(args.file, prefix="artiq_run_")
|
module = file_import(args.file, prefix="artiq_run_")
|
||||||
file = args.file
|
file = args.file
|
||||||
|
|
Loading…
Reference in New Issue