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

[stdlib] FloatLiteral missing operators to conform Python float types #2558

Closed

Conversation

msaelices
Copy link

@msaelices msaelices commented May 6, 2024

There are some missing operators in the FloatLiteral struct that we would need to implement to conform the Python float type:

  • __round__(ndigits)
  • __mod__(rhs)
  • __divmod__(rhs)

This PR implements them and adds some tests to check the methods.

Signed-off-by: Manuel Saelices <msaelices@gmail.com>
…od and associated tests

Signed-off-by: Manuel Saelices <msaelices@gmail.com>
Signed-off-by: Manuel Saelices <msaelices@gmail.com>
Signed-off-by: Manuel Saelices <msaelices@gmail.com>
@msaelices msaelices force-pushed the floatliteral-missing-operators-v2 branch from 4d94eb4 to 13d8ed9 Compare May 7, 2024 07:38
…hing related with the compiler (function unpacking) or the tuple type

Signed-off-by: Manuel Saelices <msaelices@gmail.com>
…r is at compile time

Signed-off-by: Manuel Saelices <msaelices@gmail.com>
@JoeLoser JoeLoser added the imported-internally Signals that a given pull request has been imported internally. label May 10, 2024
Copy link
Contributor

@laszlokindrat laszlokindrat left a comment

Choose a reason for hiding this comment

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

This is awesome, thank you for pushing on this! I have a couple of questions and mostly small quibbles and suggestions, but we highly appreciate this improvement!

stdlib/src/builtin/float_literal.mojo Show resolved Hide resolved
@@ -239,7 +239,38 @@ struct FloatLiteral(
return truncated
return truncated + 1

# TODO: implement __round__
@always_inline("nodebug")
fn __round__(self, ndigits: IntLiteral = 0) -> Self:
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you please add the Roundable trait explicitly to FloatLiteral? That will probably require you to split this into two signatures. After that, would you be interested in changing the __round__ signature in Roundable to expect ndigits as well?

Copy link
Author

Choose a reason for hiding this comment

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

Implemented Roundable trait here: msaelices@26906ca

I'm not sure if adding a ndigits function to Roundable would break integers, and that parameter on those types has no meaning, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

It has the same meaning as for floating point numbers, it's just that for non-negative ndigits values, the round function acts like identity on integers:

round(5232323,-2) == 5232300

If you are interested, I would love to see a followup patch with improving the Roundable trait and the implementation for other types!

Copy link
Author

Choose a reason for hiding this comment

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

Sure. I will create a separated PR with the improvement.

Copy link
Contributor

Choose a reason for hiding this comment

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

Amazing, thanks, please ping me when that's done!

Copy link
Author

Choose a reason for hiding this comment

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

@laszlokindrat It's here: #2656

stdlib/src/builtin/float_literal.mojo Outdated Show resolved Hide resolved
stdlib/src/builtin/float_literal.mojo Show resolved Hide resolved
stdlib/src/builtin/float_literal.mojo Outdated Show resolved Hide resolved
stdlib/src/builtin/float_literal.mojo Show resolved Hide resolved
stdlib/src/builtin/float_literal.mojo Outdated Show resolved Hide resolved
Comment on lines 119 to 123
# TODO: I think this is failing because of a bug in the compiler or int the tuple type:
# The test runner is returning the following error when executin `a, b = FloatLiteral(4.5).__divmod__(2.0)`:
# invalid call to '__refitem__': callee expects 4 parameters, but 2 were specified
# var a: FloatLiteral
# var b: FloatLiteral
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe there is a compiler bug, but this can't work for a different reason: FloatLiteral is nonmaterializable, so you cannot have a runtime variable with that type. This would be one possible way to work around this:

alias PairType = Tuple[FloatLiteral, FloatLiteral]
alias t: PairType = FloatLiteral(4.5).__divmod__(2.0)
assert_equal(t[0], 2.0)  # not sure if direct indexing works on `Tuple` yet, but you get the point
assert_equal(t[1], 0.5)

Copy link
Author

Choose a reason for hiding this comment

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

It does not work:

    alias Pair = Tuple[FloatLiteral, FloatLiteral]
    alias t: Pair = (4.5).__divmod__(2.0)
    assert_equal(t[0], 2.0)
    assert_equal(t[1], 0.5)

Gives me the following error:

RUN: at line 13: mojo /home/msaelices/src/mojo/stdlib/test/builtin/test_float_literal.mojo
+ mojo /home/msaelices/src/mojo/stdlib/test/builtin/test_float_literal.mojo
/home/msaelices/src/mojo/stdlib/test/builtin/test_float_literal.mojo:124:18: error: invalid call to '__init__': argument #1 cannot be converted from 'Pair' to 'Reference['Tuple[FloatLiteral, FloatLiteral]', ...]
    assert_equal(t[0], 2.0)
                 ^
/home/msaelices/src/mojo/stdlib/test/builtin/test_float_literal.mojo:124:18: note: cannot bind an RValue to a reference
    assert_equal(t[0], 2.0)
                 ^
/home/msaelices/src/mojo/stdlib/src/memory/reference.mojo:222:8: note: function declared here
    fn __init__(inout self, value: Self._mlir_type):
       ^
/home/msaelices/src/mojo/stdlib/test/builtin/test_float_literal.mojo:125:18: error: invalid call to '__init__': argument #1 cannot be converted from 'Pair' to 'Reference['Tuple[FloatLiteral, FloatLiteral]', ...]
    assert_equal(t[1], 0.5)
                 ^
/home/msaelices/src/mojo/stdlib/test/builtin/test_float_literal.mojo:125:18: note: cannot bind an RValue to a reference
    assert_equal(t[1], 0.5)
                 ^
/home/msaelices/src/mojo/stdlib/src/memory/reference.mojo:222:8: note: function declared here
    fn __init__(inout self, value: Self._mlir_type):

And, trying to avoid the usage of indexing on Tuples I did this:

    alias Pair = Tuple[FloatLiteral, FloatLiteral]
    alias t: Pair = (4.5).__divmod__(2.0)
    assert_equal(t, (2.0, 0.5))

Getting this error:

RUN: at line 13: mojo /home/msaelices/src/mojo/stdlib/test/builtin/test_float_literal.mojo
+ mojo /home/msaelices/src/mojo/stdlib/test/builtin/test_float_literal.mojo
/home/msaelices/src/mojo/stdlib/test/builtin/test_float_literal.mojo:124:17: error: no matching function in call to 'assert_equal'
    assert_equal(t, (2.0, 0.5))
    ~~~~~~~~~~~~^~~~~~~~~~~~~~~
/home/msaelices/src/mojo/stdlib/src/testing/testing.mojo:118:4: note: candidate not viable: callee expects 1 parameter, but 0 were specified
fn assert_equal[T: Testable](lhs: T, rhs: T, msg: String = "") raises:
   ^
/home/msaelices/src/mojo/stdlib/test/builtin/test_float_literal.mojo:124:18: note: failed to infer parameter 'T', argument type 'Tuple[FloatLiteral, FloatLiteral]' does not conform to trait 'Testable'
    assert_equal(t, (2.0, 0.5))
                 ^
/home/msaelices/src/mojo/stdlib/src/testing/testing.mojo:139:4: note: candidate not viable: argument #0 cannot be converted from 'Pair' to 'String'
fn assert_equal(lhs: String, rhs: String, msg: String = "") raises:
   ^
/home/msaelices/src/mojo/stdlib/src/testing/testing.mojo:156:4: note: candidate not viable: callee expects 2 parameters, but 0 were specified
fn assert_equal[
   ^
/home/msaelices/src/mojo/stdlib/test/builtin/test_float_literal.mojo:124:17: note: failed to infer parameter 'type', parameter isn't used in any argument
    assert_equal(t, (2.0, 0.5))
    ~~~~~~~~~~~~^~~~~~~~~~~~~~~
mojo: error: failed to parse the provided Mojo source module

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm gonna take a look at why this is happening.

Copy link
Author

Choose a reason for hiding this comment

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

I've figured it out. There was a minor typo in your suggestions. When I saw it again I've found that the second alias was actually a var declaration, so it's fixed here: msaelices@5914b4c

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for the alias Pair trick, it worked like a charm

Copy link
Contributor

Choose a reason for hiding this comment

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

great, thank you!

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm actually suprised this worked for you: var t: Pair = (4.5).__divmod__(2.0) shouldn't compile since FloatLiteral is non-materializable. On a related note, I'm running into issues with this in our internal CI. I'll continue to investigate.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, something is wrong with Tuple in parameter expressions. I will land your patch with slightly modified tests, and we can circle back later if needed.

stdlib/test/builtin/test_float_literal.mojo Show resolved Hide resolved
stdlib/test/builtin/test_float_literal.mojo Show resolved Hide resolved
Copy link
Contributor

@laszlokindrat laszlokindrat left a comment

Choose a reason for hiding this comment

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

This is awesome, thank you for pushing on this! I have a couple questions and quibbles, but we really appreciate this contribution!

Signed-off-by: Manuel Saelices <msaelices@gmail.com>
Signed-off-by: Manuel Saelices <msaelices@gmail.com>
…he float literals

Signed-off-by: Manuel Saelices <msaelices@gmail.com>
…en IntLiteral.__pow__ was implemented

Signed-off-by: Manuel Saelices <msaelices@gmail.com>
Signed-off-by: Manuel Saelices <msaelices@gmail.com>
Signed-off-by: Manuel Saelices <msaelices@gmail.com>
Signed-off-by: Manuel Saelices <msaelices@gmail.com>
Signed-off-by: Manuel Saelices <msaelices@gmail.com>
Signed-off-by: Manuel Saelices <msaelices@gmail.com>
Dan13llljws and others added 16 commits May 15, 2024 19:10
The safe version of `take/get` aborts if type checking fails.

MODULAR_ORIG_COMMIT_REV_ID: 240b627f31860a674e5878a1467e3c39feadce1b
[External] [docs] Correct typo in types.ipynb

Correcting typo.

Co-authored-by: N <47500890+avi-cenna@users.noreply.github.com>
Closes modularml#2646
MODULAR_ORIG_COMMIT_REV_ID: aef3bb9dca96efdc6badc7b9369f14583ea2c71a
This is done by introducing a `Truncable` trait. Implementations of
`__trunc__` are added for the core numeric types.

MODULAR_ORIG_COMMIT_REV_ID: 0b70cb6eaf05651ceb676eda40db6d364b0c9995
…9904)

This changes `Tuple` to take its input pack as 'owned' and then
move from the pack into it storage.

This unearthed some bugs handling owned packs which were causing
multiple destructions, as a consequence of VariadicPack's ctor
moving off of `-> Self`.  Fix these bugs, make the variadics.mojo
more thorough, and make the IR pattern matching more "fail fast"
for when the IR changes again next time.

MODULAR_ORIG_COMMIT_REV_ID: b11da619445ce8330e7fef7b98e20860421ce1e6
Also, some general corrections and rewrites. (And one very trivial typo
fix in another file.)

MODULAR_ORIG_COMMIT_REV_ID: 70f8469144f5e17c9836fbd748a8b440707d53df
[stdlib] Added `Variant.replace`

BEGING_PUBLIC
[stdlib] Added `Variant.replace`

The `replace` method serve the same purpose as `take` before, but
enforces placement of a new element immediately.

This also fix the problem where `Optional.take` does not actually
take out the value.

Test cases were updated accordingly
END_PUBLIC

---------

Co-authored-by: Connor Gray <code@connorgray.com>
MODULAR_ORIG_COMMIT_REV_ID: 0a35284f47a9a8fcf58c2a25e3288725ac426e37
The abs function was evaluating both branches even if we can prove the
value is positive. Switch the conditions to avoid that.y

Co-authored-by: Abdul Dakkak <adakkak@m3.local>
MODULAR_ORIG_COMMIT_REV_ID: ee080ab8be7b8838d918734ee032fec34d12860b
…ike functions in simd.mojo (#39872)

Fixes modularml#2237 for `reduce`-like functions in simd.mojo:
- Adds documentation for constraint on value of `size_out` not exceeding
width of input vector in `reduce_add`, `reduce_mul`, `reduce_max` and
`reduce_min`.

Signed-off-by: Brian-M-J <brianmj02@gmail.com>

Co-authored-by: Brian M Johnson <1DT21AI037@dsatm.edu.in>
Closes modularml#2461
MODULAR_ORIG_COMMIT_REV_ID: b151847dcc2e89c9b87fec873941bf8b20a534c7
…ions (#39931)

Add unit tests for the `__add__()`, `__radd__()`, and `__iadd__()`
methods.

Co-authored-by: Peyman Barazandeh <peymanb@gmail.com>
Closes modularml#2611
MODULAR_ORIG_COMMIT_REV_ID: b1616eedeb11b99a9e8f62df6f58cd708c587d78
These were accidentally disabled when the original patch landed.

MODULAR_ORIG_COMMIT_REV_ID: 0debdbd812763b50aefedc3aed34b51593fdd8c7
* Add String.as_bytes_slice() -> Span[Int8, _, _]
* Add StringLiteral.as_bytes_slice() -> Span[Int8, 0, ImmStaticLifetime]
* Add new ImmStaticLifetime and MutStaticLifetime helpers
* Add _byte_length() methods to String and StringLiteral
* Change Span.__getitem__() to return a Reference, making the doc
comment accurate
* Add Span.unsafe_ptr()
* Fix missing declaration of utils/span in CMakeLists.txt

MODULAR_ORIG_COMMIT_REV_ID: e7c7f512b0d968f1cbb1e2098f824b621046659a
With the recent change to `Bool` to use an `i1` as its
representation, many of the errors holding up moving
`Reference.is_mutable` to `Bool` were resolved.

Co-authored-by: Chris Lattner <clattner@nondot.org>
MODULAR_ORIG_COMMIT_REV_ID: 980a32f9b676905284a58b454c3f5e25a7280b21
Signed-off-by: Manuel Saelices <msaelices@gmail.com>
Signed-off-by: Manuel Saelices <msaelices@gmail.com>
Signed-off-by: Manuel Saelices <msaelices@gmail.com>
@msaelices msaelices requested a review from a team as a code owner May 15, 2024 17:15
Copy link
Contributor

@laszlokindrat laszlokindrat left a comment

Choose a reason for hiding this comment

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

Thanks again, it's great to have this fixed!

@modularbot
Copy link
Collaborator

✅🟣 This contribution has been merged 🟣✅

Your pull request has been merged to the internal upstream Mojo sources. It will be reflected here in the Mojo repository on the nightly branch during the next Mojo nightly release, typically within the next 24-48 hours.

We use Copybara to merge external contributions, click here to learn more.

@modularbot modularbot added merged-internally Indicates that this pull request has been merged internally merged-externally Merged externally in public mojo repo labels May 16, 2024
modularbot pushed a commit that referenced this pull request May 16, 2024
…float types (#39733)

[External] [stdlib] FloatLiteral missing operators to conform Python
float types

There are some missing operators in the `FloatLiteral` struct that we
would need to implement to conform the Python `float` type:

* `__round__(ndigits)`
* `__mod__(rhs)`
* `__divmod__(rhs)`

This PR implements them and adds some tests to check the methods.

---------

Co-authored-by: Manuel Saelices <msaelices@gmail.com>
Closes #2558
MODULAR_ORIG_COMMIT_REV_ID: ce34e9e2ad55590ccad85563098ab88146c198a2
@modularbot
Copy link
Collaborator

Landed in 5f22b5f! Thank you for your contribution 🎉

@modularbot modularbot closed this May 16, 2024
lsh pushed a commit to lsh/mojo that referenced this pull request May 17, 2024
…float types (#39733)

[External] [stdlib] FloatLiteral missing operators to conform Python
float types

There are some missing operators in the `FloatLiteral` struct that we
would need to implement to conform the Python `float` type:

* `__round__(ndigits)`
* `__mod__(rhs)`
* `__divmod__(rhs)`

This PR implements them and adds some tests to check the methods.

---------

Co-authored-by: Manuel Saelices <msaelices@gmail.com>
Closes modularml#2558
MODULAR_ORIG_COMMIT_REV_ID: ce34e9e2ad55590ccad85563098ab88146c198a2

Signed-off-by: Lukas Hermann <lukashermann28@gmail.com>
msaelices added a commit to msaelices/mojo that referenced this pull request May 18, 2024
…float types (#39733)

[External] [stdlib] FloatLiteral missing operators to conform Python
float types

There are some missing operators in the `FloatLiteral` struct that we
would need to implement to conform the Python `float` type:

* `__round__(ndigits)`
* `__mod__(rhs)`
* `__divmod__(rhs)`

This PR implements them and adds some tests to check the methods.

---------

Co-authored-by: Manuel Saelices <msaelices@gmail.com>
Closes modularml#2558
MODULAR_ORIG_COMMIT_REV_ID: ce34e9e2ad55590ccad85563098ab88146c198a2
martinvuyk pushed a commit to martinvuyk/mojo that referenced this pull request May 24, 2024
…float types (#39733)

[External] [stdlib] FloatLiteral missing operators to conform Python
float types

There are some missing operators in the `FloatLiteral` struct that we
would need to implement to conform the Python `float` type:

* `__round__(ndigits)`
* `__mod__(rhs)`
* `__divmod__(rhs)`

This PR implements them and adds some tests to check the methods.

---------

Co-authored-by: Manuel Saelices <msaelices@gmail.com>
Closes modularml#2558
MODULAR_ORIG_COMMIT_REV_ID: ce34e9e2ad55590ccad85563098ab88146c198a2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
imported-internally Signals that a given pull request has been imported internally. merged-externally Merged externally in public mojo repo merged-internally Indicates that this pull request has been merged internally
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet