-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
symbolic codegen and exec #1552
Conversation
Changes made in
|
.github/workflows/test.yml
Outdated
@@ -263,10 +265,10 @@ jobs: | |||
run: python -c "from tinygrad.lazy import Device; assert Device.DEFAULT in ['LLVM','CLANG','CUDA','GPU'], Device.DEFAULT" | |||
- name: Run pytest (not cuda) | |||
if: matrix.backend!='cuda' | |||
run: python -m pytest -n=auto test/ -k '${{matrix.backend=='llvm'&&'not (test_nn.py and test_conv_transpose2d)'||'test'}}' -m 'not exclude_${{matrix.backend}}' | |||
run: CI=1 python -m pytest -n=auto test/ -k '${{matrix.backend=='llvm'&&'not (test_nn.py and test_conv_transpose2d)'||'test'}}' -m 'not exclude_${{matrix.backend}}' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You shouldn't need this, CI should be set automatically by CI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got it - removed
test/test_helpers.py
Outdated
@@ -106,5 +106,17 @@ def test_context_exit_reverts_updated_values(self): | |||
... | |||
assert D.value == 2, f"Expected D to be 2, but was {D.value}. Indicates that Context.__exit__ did not restore to the correct value." | |||
|
|||
class TestMergeDcits(unittest.TestCase): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
tinygrad/helpers.py
Outdated
@@ -22,6 +22,10 @@ def make_pair(x:Union[int, Tuple[int, ...]], cnt=2) -> Tuple[int, ...]: return ( | |||
def flatten(l:Iterator): return [item for sublist in l for item in sublist] | |||
def mnum(i) -> str: return str(i) if i >= 0 else f"m{-i}" | |||
def fromimport(mod, frm): return getattr(__import__(mod, fromlist=[frm]), frm) | |||
def merge_dicts(ds): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason you can't use dict1.update(dict2)
to merge dicts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
update
does not check if value conflicts, added a test case that (3, vi) @ (vi, 5)
should fail if they hold different values for vi
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a type signature to this function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Why is it |
I took this from tracing how PyFR implemented it for metal. My understanding from the metal spec section 4 is that kernel argument needs an address space attribute, and it only accepts pointer or reference |
So this isn't true for OpenCL...but maybe it's fine. PyOpenCL has |
tinygrad/shape/shapetracker.py
Outdated
@@ -162,7 +162,7 @@ def real_strides(self, ignore_valid=False) -> Tuple[Optional[Union[Node, int]], | |||
idx, valid = self.expr_idxs(idxs) | |||
ret: List[Optional[Union[Node, int]]] = [None] * len(self.views[-1].shape) | |||
for this_dim in (idx.nodes if isinstance(idx, SumNode) else [idx]): | |||
if isinstance(this_dim, MulNode) and isinstance(this_dim.a, Variable): | |||
if isinstance(this_dim, MulNode) and isinstance(this_dim.a, Variable) and str(this_dim.a.expr).startswith("idx"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks sketchy using a string compare. Is there a better way to write this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good call - updated
tinygrad/renderer/cstyle.py
Outdated
return f"for (int {expr} = {_min}; {expr} <= {_max}; ++{expr}) {{" | ||
|
||
def render_conditional(self, cond: str, x:str, y:str) -> str: | ||
return f"({cond})?({x}):{y}" | ||
|
||
def render_kernel(self, function_name:str, kernel:List[str], bufs:List[Tuple[str,DType]], global_size:List[int], local_size:List[int], prekernel:List[str]) -> Tuple[str,List[int],List[int]]: | ||
tmp = "const sampler_t smp = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" if any(isinstance(dtype, ImageDType) for _,dtype in bufs) else "" | ||
buftypes = [(name,f"{'read_only' if i > 0 else 'write_only'} image2d_t" if dtype.name.startswith('image') else | ||
buftypes = [(name[8:], self.arg_int_prefix) if name.startswith("ARG_INT_") else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
String stuff is always sketchy, is there a better way to do this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added an internal dtype for int argument and used that instead
It's close, but I don't like the string compare stuff, particularly the one in shapetracker. |
re: PyOpenCL and |
Cool, merged! |
part of #1353 , codegen and exec to implement
realize
for symbolic inputs.The combined
var_vals
are passed into kernel function directly. I have implemented the backend for CLANG, GPU, METAL.global_size
,local_size
andop_estimate
are computed to int during exec. In addition to CI, I also tested withDEBUG=4 python -m pytest -rA test/test_symbolic_ops.py
to make sure all debugging info renders with symbols.Most of the hand coded optimization works, and I need to disable the upcast ones because we cannot upcast a symbolic axis.
Also added some test cases for 2 variables. Want to make it as general as possible.
These two examples show that we need to support symbolic for loop max and symbolic offset
kernel for matmul
(3, vi) @ (vi, 5)
kernel for
(3, vi).cat((3, vj), dim=1)