Implement dumb 'with parallel' (#265).

This commit is contained in:
whitequark 2016-02-22 13:51:08 +00:00
parent 51a5910002
commit bc81be1345
10 changed files with 52 additions and 2 deletions

View File

@ -144,6 +144,9 @@ def fn_print():
def fn_kernel(): def fn_kernel():
return types.TBuiltinFunction("kernel") return types.TBuiltinFunction("kernel")
def obj_parallel():
return types.TBuiltin("parallel")
def obj_interleave(): def obj_interleave():
return types.TBuiltin("interleave") return types.TBuiltin("interleave")

View File

@ -30,6 +30,7 @@ def globals():
"portable": builtins.fn_kernel(), "portable": builtins.fn_kernel(),
# ARTIQ context managers # ARTIQ context managers
"parallel": builtins.obj_parallel(),
"interleave": builtins.obj_interleave(), "interleave": builtins.obj_interleave(),
"sequential": builtins.obj_sequential(), "sequential": builtins.obj_sequential(),
"watchdog": builtins.fn_watchdog(), "watchdog": builtins.fn_watchdog(),

View File

@ -765,6 +765,28 @@ class ARTIQIRGenerator(algorithm.Visitor):
if not tail.is_terminated(): if not tail.is_terminated():
tail.append(ir.Branch(self.current_block)) tail.append(ir.Branch(self.current_block))
return return
elif types.is_builtin(context_expr_node.type, "parallel"):
start_mu = self.append(ir.Builtin("now_mu", [], builtins.TInt64()))
end_mu = start_mu
for stmt in node.body:
self.append(ir.Builtin("at_mu", [start_mu], builtins.TNone()))
block = self.add_block()
if self.current_block.is_terminated():
self.warn_unreachable(stmt[0])
else:
self.append(ir.Branch(block))
self.current_block = block
self.visit(stmt)
mid_mu = self.append(ir.Builtin("now_mu", [], builtins.TInt64()))
gt_mu = self.append(ir.Compare(ast.Gt(loc=None), mid_mu, end_mu))
end_mu = self.append(ir.Select(gt_mu, mid_mu, end_mu))
self.append(ir.Builtin("at_mu", [end_mu], builtins.TNone()))
return
cleanup = [] cleanup = []
for item_node in node.items: for item_node in node.items:

View File

@ -994,6 +994,7 @@ class Inferencer(algorithm.Visitor):
typ = node.context_expr.type typ = node.context_expr.type
if (types.is_builtin(typ, "interleave") or types.is_builtin(typ, "sequential") or if (types.is_builtin(typ, "interleave") or types.is_builtin(typ, "sequential") or
types.is_builtin(typ, "parallel") or
(isinstance(node.context_expr, asttyped.CallT) and (isinstance(node.context_expr, asttyped.CallT) and
types.is_builtin(node.context_expr.func.type, "watchdog"))): types.is_builtin(node.context_expr.func.type, "watchdog"))):
# builtin context managers # builtin context managers
@ -1092,8 +1093,8 @@ class Inferencer(algorithm.Visitor):
for item_node in node.items: for item_node in node.items:
typ = item_node.context_expr.type.find() typ = item_node.context_expr.type.find()
if (types.is_builtin(typ, "interleave") or types.is_builtin(typ, "sequential")) and \ if (types.is_builtin(typ, "parallel") or types.is_builtin(typ, "interleave") or
len(node.items) != 1: types.is_builtin(typ, "sequential")) and len(node.items) != 1:
diag = diagnostic.Diagnostic("error", diag = diagnostic.Diagnostic("error",
"the '{kind}' context manager must be the only one in a 'with' statement", "the '{kind}' context manager must be the only one in a 'with' statement",
{"kind": typ.name}, {"kind": typ.name},

View File

@ -34,3 +34,4 @@ if os.name == "posix":
config.environment["LIBARTIQ_SUPPORT"] = support_lib config.environment["LIBARTIQ_SUPPORT"] = support_lib
config.available_features.add("exceptions") config.available_features.add("exceptions")
config.available_features.add("time")

View File

@ -1,4 +1,5 @@
# RUN: %python -m artiq.compiler.testbench.jit %s # RUN: %python -m artiq.compiler.testbench.jit %s
# REQUIRES: time
assert now() == 0.0 assert now() == 0.0
delay(100.0) delay(100.0)

View File

@ -1,4 +1,5 @@
# RUN: %python -m artiq.compiler.testbench.jit %s # RUN: %python -m artiq.compiler.testbench.jit %s
# REQUIRES: time
assert now_mu() == 0 assert now_mu() == 0
delay_mu(100) delay_mu(100)

View File

@ -1,4 +1,5 @@
# RUN: %python -m artiq.compiler.testbench.jit %s # RUN: %python -m artiq.compiler.testbench.jit %s
# REQUIRES: time
assert seconds_to_mu(2.0) == 2000000 assert seconds_to_mu(2.0) == 2000000
assert mu_to_seconds(1500000) == 1.5 assert mu_to_seconds(1500000) == 1.5

View File

@ -0,0 +1,18 @@
# RUN: %python -m artiq.compiler.testbench.jit %s
# REQUIRES: time
with parallel:
with sequential:
assert now_mu() == 0
delay_mu(10)
assert now_mu() == 10
with sequential:
assert now_mu() == 0
delay_mu(20)
assert now_mu() == 20
with sequential:
assert now_mu() == 0
delay_mu(15)
assert now_mu() == 15
assert now_mu() == 0
assert now_mu() == 20

View File

@ -1,5 +1,6 @@
# RUN: %python -m artiq.compiler.testbench.jit %s >%t # RUN: %python -m artiq.compiler.testbench.jit %s >%t
# RUN: OutputCheck %s --file-to-check=%t # RUN: OutputCheck %s --file-to-check=%t
# REQUIRES: time
def f(): def f():
with watchdog(1.0): with watchdog(1.0):