JIMC
JIMC
Explore posts from servers
MModular
Created by JIMC on 12/4/2023 in #questions
Trying to do compile time checking with 'const' type arguments.
struct ExposedSecret[T: AnyRegType]:
var borrowed_value: T

fn __init__(inout self, borrowed borrowed_value: T):
self.borrowed_value = borrowed_value

struct Secret[T: AnyRegType, MEC: Int, EC: Int]:
var inner: T

fn __init__[EC: Int=EC](inout self, owned value: T):
constrained[EC == 0, "`Secret[T, MEC, EC]` can only be constructed iff `EC == 0`"]()
self.inner = value

@staticmethod
fn ec_add_one(owned other: Self) -> Secret[T, MEC, EC + 1]:
return other^

fn expose_secret[ReturnedType: AnyRegType](owned self, owned closure:
fn(exposed_secret: ExposedSecret[T]) capturing -> ReturnedType)
-> ListLiteral[ReturnedType, Secret[T, MEC, EC + 1]]:
constrained[EC < MEC, "`expose_secret` can only be called if `EC < MEC`"]()
let returned_value = closure(ExposedSecret[T])
let new_self = Secret.ec_add_one(self^)
return [returned_value, new_self]

fn main():
let my_secret = Secret[Int, 3, 2](69)

@parameter
fn capturing_closure_but_actually_never_capture(borrowed exposed_secret: ExposedSecret[Int]) -> Int:
return exposed_secret.borrowed_value

let my_69_secret_tuple = my_secret^.expose_secret[Int](capturing_closure_but_actually_never_capture)
let returned_69_secret = my_69_secret_tuple.get[0, Int]()
let my_new_secret = my_69_secret_tuple^.get[1, Secret[Int, 3, 3]]()
struct ExposedSecret[T: AnyRegType]:
var borrowed_value: T

fn __init__(inout self, borrowed borrowed_value: T):
self.borrowed_value = borrowed_value

struct Secret[T: AnyRegType, MEC: Int, EC: Int]:
var inner: T

fn __init__[EC: Int=EC](inout self, owned value: T):
constrained[EC == 0, "`Secret[T, MEC, EC]` can only be constructed iff `EC == 0`"]()
self.inner = value

@staticmethod
fn ec_add_one(owned other: Self) -> Secret[T, MEC, EC + 1]:
return other^

fn expose_secret[ReturnedType: AnyRegType](owned self, owned closure:
fn(exposed_secret: ExposedSecret[T]) capturing -> ReturnedType)
-> ListLiteral[ReturnedType, Secret[T, MEC, EC + 1]]:
constrained[EC < MEC, "`expose_secret` can only be called if `EC < MEC`"]()
let returned_value = closure(ExposedSecret[T])
let new_self = Secret.ec_add_one(self^)
return [returned_value, new_self]

fn main():
let my_secret = Secret[Int, 3, 2](69)

@parameter
fn capturing_closure_but_actually_never_capture(borrowed exposed_secret: ExposedSecret[Int]) -> Int:
return exposed_secret.borrowed_value

let my_69_secret_tuple = my_secret^.expose_secret[Int](capturing_closure_but_actually_never_capture)
let returned_69_secret = my_69_secret_tuple.get[0, Int]()
let my_new_secret = my_69_secret_tuple^.get[1, Secret[Int, 3, 3]]()
The error:
/root/mojo_projs/sosecrets-mojo/src/secret.mojo:42:70: error: invalid call to 'get': result cannot bind AnyRegType type to memory-only type 'Secret[Int, 3, 3]'
let my_new_secret = my_69_secret_tuple^.get[1, Secret[Int, 3, 3]]()
~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
/root/mojo_projs/sosecrets-mojo/src/secret.mojo:1:1: note: function declared here

^
mojo: error: failed to parse the provided Mojo
/root/mojo_projs/sosecrets-mojo/src/secret.mojo:42:70: error: invalid call to 'get': result cannot bind AnyRegType type to memory-only type 'Secret[Int, 3, 3]'
let my_new_secret = my_69_secret_tuple^.get[1, Secret[Int, 3, 3]]()
~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
/root/mojo_projs/sosecrets-mojo/src/secret.mojo:1:1: note: function declared here

^
mojo: error: failed to parse the provided Mojo
11 replies
MModular
Created by JIMC on 10/15/2023 in #questions
`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
6 replies
MModular
Created by JIMC on 9/20/2023 in #questions
Cross-directory Imports
No description
4 replies
MModular
Created by JIMC on 9/11/2023 in #questions
Compile time `U8`
@Modular Staff I'm writing to write a struct U8 that kind of models after Int. Here is my impl:
struct U8:
var value: __mlir_type.ui8

fn __init__(inout self, value: Int):
let value_as_index = value.__mlir_index__()
let _255 = __mlir_op.`index.castu`[_type : __mlir_type.index](__mlir_attr.`255`)
let greater_than_255 = __mlir_op.`index.cmp`[pred : __mlir_attr.`#index<cmp_predicate ugt>`](value_as_index, _255)
let _0 = __mlir_op.`index.castu`[_type : __mlir_type.index](__mlir_attr.`0`)
let lesser_than_0 = __mlir_op.`index.cmp`[pred : __mlir_attr.`#index<cmp_predicate ult>`](value_as_index, _0)
self.value = __mlir_op.`index.castu`[_type: __mlir_type.ui8](value_as_index)
struct U8:
var value: __mlir_type.ui8

fn __init__(inout self, value: Int):
let value_as_index = value.__mlir_index__()
let _255 = __mlir_op.`index.castu`[_type : __mlir_type.index](__mlir_attr.`255`)
let greater_than_255 = __mlir_op.`index.cmp`[pred : __mlir_attr.`#index<cmp_predicate ugt>`](value_as_index, _255)
let _0 = __mlir_op.`index.castu`[_type : __mlir_type.index](__mlir_attr.`0`)
let lesser_than_0 = __mlir_op.`index.cmp`[pred : __mlir_attr.`#index<cmp_predicate ult>`](value_as_index, _0)
self.value = __mlir_op.`index.castu`[_type: __mlir_type.ui8](value_as_index)
It does check for the range (0-255) but not shown because the code snippet is sufficient to showcase the error I faced which is:
root@DESKTOP-N84UN90:~/mojo_projs/marray# mojo array3.mojo
/__w/modular/modular/Kernels/mojo/builtin/_startup.mojo:70:1: error: no viable expansions found
/__w/modular/modular/Kernels/mojo/builtin/_startup.mojo:70:1: note: call expansion failed - no concrete specializations
/__w/modular/modular/Kernels/mojo/builtin/_startup.mojo:11:1: note: no viable expansions found
/__w/modular/modular/Kernels/mojo/builtin/_startup.mojo:23:14: note: call expansion failed - no concrete specializations
array3.mojo:31:1: note: no viable expansions found
fn main():
^
array3.mojo:32:4: note: failed to evaluate 'apply'
alias a: U8 = 4
^
array3.mojo:5:4: note: failed to interpret function @$array3::U8::__init__($array3::U8=&,$builtin::$int::Int)_concrete
fn __init__(inout self, value: Int):
^
array3.mojo:13:67: note: failed to fold operation index.castu(4 : index)
self.value = __mlir_op.`index.castu`[_type: __mlir_type.ui8](value_as_index)
^
mojo: error: failed to run the pass manager
root@DESKTOP-N84UN90:~/mojo_projs/marray# mojo array3.mojo
/__w/modular/modular/Kernels/mojo/builtin/_startup.mojo:70:1: error: no viable expansions found
/__w/modular/modular/Kernels/mojo/builtin/_startup.mojo:70:1: note: call expansion failed - no concrete specializations
/__w/modular/modular/Kernels/mojo/builtin/_startup.mojo:11:1: note: no viable expansions found
/__w/modular/modular/Kernels/mojo/builtin/_startup.mojo:23:14: note: call expansion failed - no concrete specializations
array3.mojo:31:1: note: no viable expansions found
fn main():
^
array3.mojo:32:4: note: failed to evaluate 'apply'
alias a: U8 = 4
^
array3.mojo:5:4: note: failed to interpret function @$array3::U8::__init__($array3::U8=&,$builtin::$int::Int)_concrete
fn __init__(inout self, value: Int):
^
array3.mojo:13:67: note: failed to fold operation index.castu(4 : index)
self.value = __mlir_op.`index.castu`[_type: __mlir_type.ui8](value_as_index)
^
mojo: error: failed to run the pass manager
21 replies
MModular
Created by JIMC on 9/10/2023 in #questions
Compile time addition of numbers
I am trying to do compile time addition of numbers via generic types, e.g.
from memory import stack_allocation

struct IntType[num: Int]:
alias value: Int = num

fn comptime_add[Num1: IntType[num1: Int], Num2: IntType[num2: Int]]() -> IntType[num1 + num2]:
return Num1.value + Num2.value
from memory import stack_allocation

struct IntType[num: Int]:
alias value: Int = num

fn comptime_add[Num1: IntType[num1: Int], Num2: IntType[num2: Int]]() -> IntType[num1 + num2]:
return Num1.value + Num2.value
The errors are:
array2.mojo:6:31: error: use of unknown declaration 'num1'
fn comptime_add[Num1: IntType[num1: Int], Num2: IntType[num2: Int]]() -> IntType[num1 + num2]:
^~~~
array2.mojo:6:57: error: use of unknown declaration 'num2'
fn comptime_add[Num1: IntType[num1: Int], Num2: IntType[num2: Int]]() -> IntType[num1 + num2]:
^~~~
array2.mojo:6:82: error: use of unknown declaration 'num1'
fn comptime_add[Num1: IntType[num1: Int], Num2: IntType[num2: Int]]() -> IntType[num1 + num2]:
^~~~
array2.mojo:6:89: error: use of unknown declaration 'num2'
fn comptime_add[Num1: IntType[num1: Int], Num2: IntType[num2: Int]]() -> IntType[num1 + num2]:
array2.mojo:6:31: error: use of unknown declaration 'num1'
fn comptime_add[Num1: IntType[num1: Int], Num2: IntType[num2: Int]]() -> IntType[num1 + num2]:
^~~~
array2.mojo:6:57: error: use of unknown declaration 'num2'
fn comptime_add[Num1: IntType[num1: Int], Num2: IntType[num2: Int]]() -> IntType[num1 + num2]:
^~~~
array2.mojo:6:82: error: use of unknown declaration 'num1'
fn comptime_add[Num1: IntType[num1: Int], Num2: IntType[num2: Int]]() -> IntType[num1 + num2]:
^~~~
array2.mojo:6:89: error: use of unknown declaration 'num2'
fn comptime_add[Num1: IntType[num1: Int], Num2: IntType[num2: Int]]() -> IntType[num1 + num2]:
How should I approach this?
2 replies
MModular
Created by JIMC on 9/10/2023 in #questions
Error:cannot construct 'Array' from 'ListLiteral[Int, Int, Int, Int, Int]' value in 'var' initialize
I'm trying to create a Array[T: AnyType, N: Int] struct but encountered this error when trying to run it:
from memory import stack_allocation

struct Array[T: AnyType, N: Int]:
constrained[N <= 32, "`size` of N cannot be larger than 1024"]()
alias size: Int = N
alias type: AnyType = T

var capacity: Int
var length: Int
var storage: Pointer[T]

fn __init__[*Ts: AnyType](inout self, owned iterable: ListLiteral[Ts]) raises:
if N != len(iterable):
raise Error("`size` of `iterable` is not equal to the `size` of array")
self.capacity = self.size * 2
self.storage = stack_allocation[N*2, T]()
let src: Pointer[T] = Pointer.address_of(iterable).bitcast[T]()
for i in range(len(iterable)):
self.storage.store(i, src.load(i))


fn main():
var myarray: Array[Int, 5] = Array([1, 2, 3, 4, 5])
from memory import stack_allocation

struct Array[T: AnyType, N: Int]:
constrained[N <= 32, "`size` of N cannot be larger than 1024"]()
alias size: Int = N
alias type: AnyType = T

var capacity: Int
var length: Int
var storage: Pointer[T]

fn __init__[*Ts: AnyType](inout self, owned iterable: ListLiteral[Ts]) raises:
if N != len(iterable):
raise Error("`size` of `iterable` is not equal to the `size` of array")
self.capacity = self.size * 2
self.storage = stack_allocation[N*2, T]()
let src: Pointer[T] = Pointer.address_of(iterable).bitcast[T]()
for i in range(len(iterable)):
self.storage.store(i, src.load(i))


fn main():
var myarray: Array[Int, 5] = Array([1, 2, 3, 4, 5])
Please help.
41 replies