-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
[MLIR][Python] IntegerAttribute doesn't accept unsigned values greater than 63 bits #128072
Comments
@llvm/issue-subscribers-mlir-python Author: John Demme (teqdruid)
```python
# This works
ir.IntegerAttr.get(ir.IntegerType.get_signless(64), 0x7fffffffffffffff)
This doesn'tir.IntegerAttr.get(ir.IntegerType.get_signless(64), 0xffffffffffffffff)
TypeError: get(): incompatible function arguments. The following argument types are supported: Invoked with types: pycde.circt._mlir_libs._mlir.ir.IntegerType, int
|
I have been told by @stellaraccident that |
It's probably hopeless to try to standardize on the internal representation of an arbitrary precision int like what python uses. With that said, what you need is a c struct that lets you get in/out of both APInt and the procedure python has for accessing large ints. APInt itself is pretty simple in this regard: it has a numbits field and a union that either holds a single uint64 or a pointer to an array of uint64 that is heap allocated if more than one word. This isn't a great design for dealing with a lot of large values... Will result in a lot of heap allocations. What I'd do: define an apint_interop_t struct that has a number of bits and a pointer to uint64 words that is at least of size numbits / 64. For APIs that need to take an APInt, the caller just populates that as needed. For those that return, have the caller pass in a pointer to the struct with numbits set to the max that is allocated. Then if too small, have the read function return a failure and populate the actual numbits needed. It's annoying, but you can build reasonably efficient interop with such a mechanism, even for the array cases, if a bit careful about it. |
Yeah, that sounds like the response I expected. I had hoped that someone would point me to a C APInt interop which LLVM has already using somewhere. I'll keep this in mind for the future. I'm in sprint/hack to a demo mode right now. Or if anyone else wants to do it. Strikes me as a pretty good first project. |
Hi! This issue may be a good introductory issue for people new to working on LLVM. If you would like to work on this issue, your first steps are:
If you have any further questions about this issue, don't hesitate to ask via a comment in the thread below. |
@llvm/issue-subscribers-good-first-issue Author: John Demme (teqdruid)
```python
# This works
ir.IntegerAttr.get(ir.IntegerType.get_signless(64), 0x7fffffffffffffff)
This doesn'tir.IntegerAttr.get(ir.IntegerType.get_signless(64), 0xffffffffffffffff)
TypeError: get(): incompatible function arguments. The following argument types are supported: Invoked with types: pycde.circt._mlir_libs._mlir.ir.IntegerType, int
|
This seems pretty hacky since we'd have to add a C++ API somewhere which supports the CAPI attributes and APInt. Possible, but ugly as it doesn't solve the problem for non-C++ users. |
@teqdruid @stellaraccident It doesn't seem like anyone has started work on this, could I give it a go? |
Sure - tag me explicitly if you'd like my help on reviews... I'm not otherwise watching super closely. |
Same here |
llvm/llvm-project#128072 To mitigate this, if a constant over 63-bits is specified, create it by concatenating 32-bit constants.
Apolgies for the slow movement on this. My understanding is that the interfaces involved are:
CAPI:
For Python, my understanding is that way in and out for large integers in python is via use of py::byte. I just want to make sure I'm understanding correctly what was meant by the following:
From this, my understanding is that the CAPI should be updated with functions like the following:
The Python interface would call these new functions to receive an I also wanted to understand better how your proposed design helps with heap accesses, it's unclear to me where we could save on allocations. Thanks! |
Fixes issue llvm#128072. Allows for arbitrarily sized integers to be requested via Python.
Fixes issue llvm#128072. Allows for arbitrarily sized integers to be requested via Python.
Fixes issue llvm#128072. Allows for arbitrarily sized integers to be requested via Python.
The problem is that the nanobind (and CAPI) calls use
int64_t
(signed) which 0xffffffffffffffff overflows. (This doesn't produce the nicest error message, but that's a problem with nanobind.) Generally speaking, we need a way to pass >= 64-bit values into nanobind (easy enough by using the python int type) and through the CAPI (the real issue). The 64-bit case is pretty easy to solve (usinguint64_t
), but we need a more generic way. In C++ world, we have APInt. Is there a C equivalent we could use? Is there some standard way we could support this?The text was updated successfully, but these errors were encountered: