loopy
loopy copied to clipboard
[Usability] Callables that are (unintentional) entrypoints cause type errors
Consider this code (from @xywei):
import pyopencl as cl
import numpy as np
import loopy as lp
inline = False
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
n = 4
x = np.random.rand(n, n, n, n, n)
y = np.random.rand(n, n, n, n, n)
grandchild_knl = lp.make_kernel(
"{[i, j]:0<= i, j< 4}",
"""
c[i, j] = 2*a[i, j] + 3*b[i, j]
""", name="linear_combo1")
child_knl = lp.make_kernel(
"{[i, j]:0<=i, j < 4}",
"""
[i, j]: g[i, j] = linear_combo1([i, j]: e[i, j], [i, j]: f[i, j])
""", name="linear_combo2")
parent_knl = lp.make_kernel(
"{[i, j, k, l, m]: 0<=i, j, k, l, m<4}",
"""
[j, l]: z[i, j, k, l, m] = linear_combo2([j, l]: x[i, j, k, l, m],
[j, l]: y[i, j, k, l, m])
""",
kernel_data=[
lp.GlobalArg(
name="x, y",
dtype=np.float64,
shape=(n, n, n, n, n)),
...],
name="mmmmain"
)
knl = lp.merge([grandchild_knl, child_knl, parent_knl])
if inline:
knl = lp.inline_callable_kernel(knl, "linear_combo2")
knl = lp.inline_callable_kernel(knl, "linear_combo1")
evt, (out, ) = knl(queue, x=x, y=y, entrypoint="mmmmain")
print(knl)
assert (np.linalg.norm(2*x+3*y-out)/(
np.linalg.norm(2*x+3*y))) < 1e-15
It crashes with
Traceback (most recent call last):
File "/home/andreas/tmp/xiaoyu-type-bug/type-bug.py", line 48, in <module>
evt, (out, ) = knl(queue, x=x, y=y, entrypoint="mmmmain")
File "/home/andreas/src/loopy/loopy/translation_unit.py", line 347, in __call__
return pex(*args, **kwargs)
File "/home/andreas/src/loopy/loopy/target/pyopencl_execution.py", line 368, in __call__
translation_unit_info = self.translation_unit_info(entrypoint,
File "/home/andreas/src/pytools/pytools/__init__.py", line 706, in wrapper
result = function(obj, *args, **kwargs)
File "/home/andreas/src/loopy/loopy/target/pyopencl_execution.py", line 292, in translation_unit_info
codegen_result = generate_code_v2(program)
File "/home/andreas/src/loopy/loopy/codegen/__init__.py", line 751, in generate_code_v2
program = infer_unknown_types(program, expect_completion=True)
File "/home/andreas/src/loopy/loopy/type_inference.py", line 1051, in infer_unknown_types
raise LoopyError("could not determine type of"
loopy.diagnostic.LoopyError: could not determine type of 'b' of kernel 'linear_combo1'.
If child_knl and grandchild_knl weren't marked as entrypoints (because make_kernel, not make_function), the type inference failure would be avoided. On the one hand, that's correct: We've still got the entrypoint versions of those callables hanging around, untyped, preventing codegen. OTOH, the fix isn't very discoverable. It'd be nice if the message said, "Hey, this error is for entrypoint you're not currently trying to call. Did you mean for this callable to be an entrypoint?"