M
Modular•14mo ago
JIMC

`if` Statement doesn't work??? :astonished:

Consider this:
@register_passable("trivial")
struct U69:
var value: __mlir_type.ui69

alias MAX: Int = 590295810358705651711
alias ZERO: Int = 0

alias greater_than_255_err_msg: StringLiteral = "Unable to parameterize a value of type `U69` with an integer value greater than 590295810358705651711"
alias lesser_than_0_err_msg: StringLiteral = "Unable to parameterize a value of type `U69` with a negative integer value"

@always_inline("nodebug")
fn __init__(N: Int) raises -> Self:
print("In `__init__`, `N` is: ", N)
if N > Self.MAX:
raise Error(Self.greater_than_255_err_msg)
if N < Self.ZERO:
raise Error(Self.lesser_than_0_err_msg)
return Self {
value: __mlir_op.`index.castu`[_type = __mlir_type.ui69](N.__mlir_index__())
}

@always_inline("nodebug")
fn __into_int__(owned self) -> Int:
return __mlir_op.`index.castu`[_type = __mlir_type.index](self.value)

@always_inline("nodebug")
fn __into_mlir_u69__(self) -> __mlir_type.ui69:
return self.value

@always_inline("nodebug")
fn __add__(self: Self, other: Self) raises -> Self:
let lhs = __mlir_op.`index.castu`[_type = __mlir_type.index](self.__into_mlir_u69__())
let rhs = __mlir_op.`index.castu`[_type = __mlir_type.index](other.__into_mlir_u69__())
let result = __mlir_op.`index.add`[](lhs, rhs)
return U69(Int(result))


fn main() raises:
let c: U69 = 2
print(c.__into_int__())
@register_passable("trivial")
struct U69:
var value: __mlir_type.ui69

alias MAX: Int = 590295810358705651711
alias ZERO: Int = 0

alias greater_than_255_err_msg: StringLiteral = "Unable to parameterize a value of type `U69` with an integer value greater than 590295810358705651711"
alias lesser_than_0_err_msg: StringLiteral = "Unable to parameterize a value of type `U69` with a negative integer value"

@always_inline("nodebug")
fn __init__(N: Int) raises -> Self:
print("In `__init__`, `N` is: ", N)
if N > Self.MAX:
raise Error(Self.greater_than_255_err_msg)
if N < Self.ZERO:
raise Error(Self.lesser_than_0_err_msg)
return Self {
value: __mlir_op.`index.castu`[_type = __mlir_type.ui69](N.__mlir_index__())
}

@always_inline("nodebug")
fn __into_int__(owned self) -> Int:
return __mlir_op.`index.castu`[_type = __mlir_type.index](self.value)

@always_inline("nodebug")
fn __into_mlir_u69__(self) -> __mlir_type.ui69:
return self.value

@always_inline("nodebug")
fn __add__(self: Self, other: Self) raises -> Self:
let lhs = __mlir_op.`index.castu`[_type = __mlir_type.index](self.__into_mlir_u69__())
let rhs = __mlir_op.`index.castu`[_type = __mlir_type.index](other.__into_mlir_u69__())
let result = __mlir_op.`index.add`[](lhs, rhs)
return U69(Int(result))


fn main() raises:
let c: U69 = 2
print(c.__into_int__())
Then run mojo, I got this:
mojo src/u69.mojo
In `__init__`, `N` is: 2
Unhandled exception caught during execution: Unable to parameterize a value of type `U69` with an integer value greater than 590295810358705651711
mojo: error: execution exited with a non-zero result: 1
mojo src/u69.mojo
In `__init__`, `N` is: 2
Unhandled exception caught during execution: Unable to parameterize a value of type `U69` with an integer value greater than 590295810358705651711
mojo: error: execution exited with a non-zero result: 1
Hmmm, 2 is definitely lesser than Self.MAX=590295810358705651711, what happened? @ModularStaff
5 Replies
Alex Kirchhoff
Alex Kirchhoff•14mo ago
Int is backed by the MLIR index type, which is pointer-sized. The current Mojo release is 64-bit, so Int can only store up to 64 bits. Hence, alias MAX: Int = 590295810358705651711 gets truncated to be equivalent to alias MAX: Int = -1. Then, 2 is not lesser than -1, which causes the code path you are experiencing to be followed.
Cogs
Cogs•14mo ago
Will there eventually be support for i128 and u128 integer types?
jmky
jmky•14mo ago
Thank you for your reply, that is an excellent explanation! I wonder how can one make use of IntLiteral to cast it into u69 at compile time then uses it at runtime with @nonmaterializable decorator.
Alex Kirchhoff
Alex Kirchhoff•14mo ago
I don't think we have a user-accessible way to do this right now (there is an undocumented MLIR op that does it, but I'm hearing that it can be buggy in some cases at the moment). I talked to another member of the Modular staff who is working in this area and they mentioned that they are likely to add a cast method to IntLiteral in the future that should be officially supported, so keep an eye on the changelog.
jmky
jmky•14mo ago
Good day to you sir, thank you for checking in with your colleagues on this - I think it's pretty groundbreaking with how Mojo allows for direct interfacing with MLIR and allows developers to go wild with more compile time programming 🚀
Want results from more Discord servers?
Add your server