Skip to content
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

Assign integer expression to struct type scalar #143

Open
jcasas00 opened this issue Sep 9, 2022 · 15 comments
Open

Assign integer expression to struct type scalar #143

jcasas00 opened this issue Sep 9, 2022 · 15 comments
Assignees
Labels
enhancement New feature or request

Comments

@jcasas00
Copy link
Collaborator

jcasas00 commented Sep 9, 2022

def test_struct_scalar_twice():
    hcl.init()

    dt8='int8'
    dt32=hcl.Int(32)
    def kernel():
        stype = hcl.Struct({"x": dt8, "y": dt8})
        xy = hcl.scalar(0x12, "foo", dtype=stype).v

        # this also generates the same error test_struct_sideeffect
        stype2 = hcl.Struct({"a": dt8, "b": dt8})
        ab = hcl.scalar(xy.x, "ab", dtype=stype2).v     # <-- replace xy.x with a constant and it builds                                            

        r = hcl.compute((2,), lambda i: 0, dtype=dt32)
        r[0] = xy.y
        r[1] = ab.a
        return r
    s = hcl.create_schedule([], kernel)
    hcl_res = hcl.asarray(np.zeros((2,), dtype=np.int32), dtype=dt32)
    f = hcl.build(s)

The code above generates an LLVM segfault:

Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var LLVM_SYMBOLIZER_PATH to point to it):
/home/jcasas/dprive/heterocl_mlir/hcl-dialect-prototype/build/tools/hcl/python_packages/hcl_core/hcl_mlir/_mlir_libs/libHCLMLIRAggregateCAPI.so.15(+0x11b2584)[0x149f604d4584]
/home/jcasas/dprive/heterocl_mlir/hcl-dialect-prototype/build/tools/hcl/python_packages/hcl_core/hcl_mlir/_mlir_libs/libHCLMLIRAggregateCAPI.so.15(+0x11afce4)[0x149f604d1ce4]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x143c0)[0x149f6c78e3c0]
/home/jcasas/dprive/heterocl_mlir/hcl-dialect-prototype/build/tools/hcl/python_packages/hcl_core/hcl_mlir/_mlir_libs/libHCLMLIRAggregateCAPI.so.15(+0xf0b776)[0x149f6022d776]
/home/jcasas/dprive/heterocl_mlir/hcl-dialect-prototype/build/tools/hcl/python_packages/hcl_core/hcl_mlir/_mlir_libs/libHCLMLIRAggregateCAPI.so.15(+0xf53ae0)[0x149f60275ae0]
...

Not sure but this may be related to the comment about 'single expr' initialization not supported yet (#133 (comment))

@zzzDavid zzzDavid self-assigned this Sep 12, 2022
@zzzDavid zzzDavid added the enhancement New feature or request label Sep 12, 2022
@zzzDavid
Copy link
Collaborator

Yes it's related to #133 , general expr to initialize scalar with struct type is WIP

@zzzDavid zzzDavid added the urgent Fix ASAP label Sep 23, 2022
@zzzDavid
Copy link
Collaborator

zzzDavid commented Sep 24, 2022

Segmentation fault is caused by an unrealized_conversion_cast operation from i8 to !hcl.struct<i8, i8>.

  1. We should support initializing struct with general expression. However, I think we should restrict the bitwidth of the expression to be the same as the struct type. Otherwise there's ambiguity of how the struct fields should be initialized.
  2. We should throw error instead of warning for unrealized_conversion_cast, since it's not supported in execution engine anyway.

@zzzDavid
Copy link
Collaborator

@jcasas00 What is the expected behavior when we cast i8 to !hcl.struct<i8, i8>? Should we split i8 to i4 i4 first and extend them to i8 or extend i8 to i16 first then split?

@zhangzhiru
Copy link

What is the expected behavior when we cast i8 to !hcl.struct<i8, i8>

I suggest we generate an error (not warning) instead.

@jcasas00
Copy link
Collaborator Author

I think the most reasonable behavior would be the latter one -- extend the source data to the target type's size and then assign.

@jcasas00
Copy link
Collaborator Author

Rethinking this ... as long as an explicit cast works (i.e., hcl.scalar(hcl.cast("int16", ), ...)), then generating an error is fine. This way the cast is forced to be explicit.

@zzzDavid
Copy link
Collaborator

zzzDavid commented Sep 26, 2022

This issue should be fixed by ddcb3d4.

I agree that the cast should be explicit. The current integer to struct checks two things:

  • The integer bitwidth is the same as the bitwidth sum from the struct type
  • All fields of struct are integers, i.e. no automatic bitcast.

I've tested it with this test case:

def test_struct_scalar_twice():
    hcl.init()

    dt4='int4'
    dt8='int8'
    dt32=hcl.Int(32)
    def kernel():
        stype = hcl.Struct({"x": dt8, "y": dt8})
        xy = hcl.scalar(0x12, "foo", dtype=stype).v

        stype2 = hcl.Struct({"a": dt4, "b": dt4})
        ab = hcl.scalar(xy.x, "ab", dtype=stype2).v                               

        r = hcl.compute((2,), lambda i: 0, dtype=dt32)
        r[0] = xy.y
        r[1] = ab.a
        return r
    s = hcl.create_schedule([], kernel)
    hcl_res = hcl.asarray(np.zeros((2,), dtype=np.int32), dtype=dt32)
    f = hcl.build(s)
    f(hcl_res)
    assert hcl_res.asnumpy()[0] == 0
    assert hcl_res.asnumpy()[1] == 2

More test cases will be added.

@jcasas00
Copy link
Collaborator Author

jcasas00 commented Sep 26, 2022

Regarding "All fields of struct are integers, i.e. no automatic bitcast." , I think this may be too restrictive.
I'm interpreting this as saying we can't assign to a struct that has a field that is also a struct. For example:

    t1 = hcl.Struct({"x": hcl.UInt(8), "y": hcl.UInt(8)})
    t2 = hcl.Struct({"z": hcl.UInt(8), "t": t1})

I think as long as the value being assigned has the right bit width (e.g., 24 for a scalar assignment to type t2), the system should be able to assign the fields even if they are non-integers since the bit widths should match.

That said -- I recall we discussed with Sean before about supporting structs in structs but I don't think it was fully implemented. It would be a good enhancement to have to make data abstractions simpler to manage.

@jcasas00
Copy link
Collaborator Author

Misclicked ... didn't mean to close

@jcasas00 jcasas00 reopened this Sep 26, 2022
@zzzDavid
Copy link
Collaborator

I agree, I think we should support nested structs. What I meant by "no automatic bitcast" is that we don't do integer slice -> float/fixed bitcast.

@jcasas00
Copy link
Collaborator Author

This change seems to have caused a segfault in some other areas that used to work ...

If the following code is added:

with hcl.if_(xy.y > 0):    # add this "if" condition to the test case above ...
     r[0] = xy.y
     r[1] = ab.a

I see the following error:

  warnings.warn(self.message, category=self.category)
error: 'affine.load' op operation destroyed but still has uses
LLVM ERROR: operation destroyed but still has uses

@zzzDavid
Copy link
Collaborator

zzzDavid commented Sep 27, 2022

The AST visitor removed the condition operation while it still has uses:
https://github.com/cornell-zhang/hcl-dialect-prototype/blob/ddcb3d42ba4e3dcb0153245d55ba86b2913c1981/include/hcl/Bindings/Python/hcl/build_ir.py#L2685-L2687

Actually I don't think the new changes broke it, this is the same issue as #141. We need to revamp the logical operations.

@zzzDavid
Copy link
Collaborator

This issue is caused by struct op visitors. When their operands are removed but struct ops stayed, MLIR raises an "operation destroyed but still has uses" error. I have added remove and profile mode for struct op visitor with this commit: 7906b26.

@jcasas00
Copy link
Collaborator Author

Thanks. Looks like this one works now.

@jcasas00 jcasas00 removed the urgent Fix ASAP label Oct 17, 2022
@jcasas00
Copy link
Collaborator Author

Removing the urgent tag on this as the primary issue has been resolved.

@zzzDavid zzzDavid changed the title Stack dump generated when initializing hcl.scalar with struct field. Assign integer expression to struct type scalar Feb 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants