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

Fix unsigned integer bitnot #2061

Merged
merged 4 commits into from
Jun 30, 2023
Merged

Fix unsigned integer bitnot #2061

merged 4 commits into from
Jun 30, 2023

Conversation

Shaikh-Ubaid
Copy link
Collaborator

fixes #2054

@Shaikh-Ubaid
Copy link
Collaborator Author

In the commit lpython.py: Use numpy functions, I replaced custom functions with numpy functions. This way we need not implement every operator for custom Unsigned Integer class. A drawback here seems to be that everytime lpython is imported, it loads numpy (and thus could affect performance of CPython).

Please share if it is fine.

@Shaikh-Ubaid Shaikh-Ubaid requested a review from certik June 29, 2023 22:46
@Shaikh-Ubaid
Copy link
Collaborator Author

Ready.

@certik
Copy link
Contributor

certik commented Jun 30, 2023

I would only depend on CPython for now by default. Of course if you use NumPy then you need NumPy, but I would not require it if you don't use NumPy.

@certik
Copy link
Contributor

certik commented Jun 30, 2023

I think this looks great. Do you mind splitting the assert improvement into a separate PR? It will be much easier to review.

@Shaikh-Ubaid
Copy link
Collaborator Author

Ready.

pass

@pythoncall(module = "bindpy_01_module")
def multiply_ints(a: i32, b: i64, c: u32, d: u64) -> i64:
def multiply_ints(a: u32, b: u32, c: u32, d: u32) -> u64:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the signed integers tested somewhere? It seems we are now only testing unsigned integers, but we need to test both signed and unsigned.

@certik
Copy link
Contributor

certik commented Jun 30, 2023

I think this PR is great now, except that it seems the signed integer tests were removed --- if you can test both signed and unsigned, then we can merge it.

@@ -1,11 +1,19 @@
from lpython import i32, i64, u32, u64, f32, f64, pythoncall

@pythoncall(module = "bindpy_01_module")
def add_ints(a: i32, b: i64, c: u32, d: u64) -> i64:
def add_ints(a: i32, b: i32, c: i32, d: i32) -> i64:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is i64 not tested now?

pass

@pythoncall(module = "bindpy_01_module")
def add_unsigned_ints(a: u32, b: u32, c: u32, d: u32) -> u64:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's test u64 too.

@certik
Copy link
Contributor

certik commented Jun 30, 2023

I would say in this PR make sure all previous tests are left, and just add some unsigned tests.

Then in the next PR, let's test rigorously i8, i16, i32, i64 and u8, u16, u32, u64 to make sure they all work.

@Shaikh-Ubaid
Copy link
Collaborator Author

Shaikh-Ubaid commented Jun 30, 2023

Is i64 not tested now?
Let's test u64 too.
I would say in this PR make sure all previous tests are left, and just add some unsigned tests.

Yes, i64 is not tested as a direct parameter. It might be tested as an array of i64 (in some other test).

These tests were added to test initial support of cpython interop. I would not make the test big. I would add it as a separate-test / new-test-file (if needed). I think simple and smaller tests are much simpler to debug and figure the failure. Testing all the types into one file could lead to tricky debugging, I think.

These types will be tested thoroughly as we add more support for CPython-Interop (For example the pass at #2050). When I added this test initially, I kept the test case slightly less robust (and even slightly odd, for example multiplying/adding variables of different types together) so that we can have some freedom (or thinking/discussion opportunities) in the design/structure of CPython Interop.

We are needing to update this test bindpy_01.py since the UnsignedInteger class defined in lpython.py (for CPython) supports operations only its own instances. This was needed because after any operation we need the unsigned integer value to be in its valid range (as per its kind).

Currently, the updated test tests integers (only i32) and unsigned integers (only u32) which seems good. We can add more tests in a separate file, I think.

Please share what we should do. Any approach works for me.

@Shaikh-Ubaid
Copy link
Collaborator Author

Shaikh-Ubaid commented Jun 30, 2023

Then in the next PR, let's test rigorously i8, i16, i32, i64 and u8, u16, u32, u64 to make sure they all work.

Sure we can do this.

PS: Or shall we add more tests once we have the pass?

@Shaikh-Ubaid Shaikh-Ubaid requested a review from certik June 30, 2023 15:30
@certik certik merged commit b2a3520 into lcompilers:main Jun 30, 2023
8 checks passed
@certik
Copy link
Contributor

certik commented Jun 30, 2023

I think this is fine. We should now make sure all combinations are tested.

@Shaikh-Ubaid Shaikh-Ubaid deleted the fix_not branch June 30, 2023 18:40
@certik
Copy link
Contributor

certik commented Jul 17, 2023

We made a mistake here. The UnsignedIntegerBitNot wraps around, and thus does NOT correspond do the CPython's ~ operator, which does not wrap around. A solution is here:

#2173

We need to create a new intrinsic function bitnot(u) that maps to UnsignedIntegerBitNot, and then we must forbid ~u applied to unsigned integers. Then we remove the UnsignedInteger class in emulation mode. That brings us back to be compatible with CPython.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

C backend bug: ~ (not) operation
2 participants