How to get this function type right?

In my test.mojo:

from layout.tensor_builder import LayoutTensorBuild as tensor_builder                         
from layout.layout_tensor import (                                                            
    Layout,                                                                                   
    LayoutTensor,                                                                             
)                                                                                                                                                                                           
fn example_tensor[rows: Int, columns: Int]() -> LayoutTensor[DType.int32, Layout.row_major(rows, columns), MutableAnyOrigin]:
    var t = tensor_builder[DType.int32]().row_major[rows, columns]().alloc()                  
    @parameter                                                                                
    for r in range(rows):                                                                     
        @parameter                                                                                  
        for c in range(columns):                                                              
            t[r, c] = (r + 1) * 100 + c                                                       
    return t                                                                                  
                                                                                              
fn main():                                                                                    
    C = example_tensor[8, 16]

when I run it:

$ mojo test.mojo 
test.mojo:14:12: error: cannot implicitly convert 'LayoutTensor[int32, row_major[::Origin[::Bool(_to_int_tuple[::VariadicList[::Int]]()), MutableAnyOrigin]' value to 'LayoutTensor[int32, row_major(rows, columns), MutableAnyOrigin]'
    return t

Any help to get this right?

Summoning @lukas who knows how this is supposed to work..

I suspect this is a case where the Mojo compiler can’t prove that the return type of the builder.row_major() is the same as the type of the return value, but the types are the same. This is something that we’d need to fix either in the compiler, or in the definition of the builder struct.

As a workaround, I think you can use a rebind. The following works for me:

fn example_tensor[rows: Int, columns: Int]() -> LayoutTensor[DType.int32, Layout.row_major(rows, columns), MutableAnyOrigin]:
    …
    return rebind[LayoutTensor[DType.int32, Layout.row_major(rows, columns), MutableAnyOrigin]](t)


fn main():
    var C = example_tensor[8, 16]()
    print(C)
1 Like

Thanks for your help here.

It fixes compiler complaints, but when I call the function:

print(example_tensor[8, 4, 10]())

I get the following error:

open-source/max/mojo/stdlib/stdlib/builtin/rebind.mojo:42:5: note: error: rebind input type '!kgen.struct<(pointer<none>, struct<(array<2, scalar<si64>>, array<2, scalar<si64>>)>, struct<(array<1, scalar<si32>>, array<1, scalar<si64>>)>)>' does not match result type '!kgen.struct<(pointer<none>, struct<(array<2, scalar<si32>>, array<2, scalar<si32>>)>, struct<(array<1, scalar<si32>>, array<1, scalar<si32>>)>)>'
error: Expression [13]:1:31: call expansion failed
print(example_tensor[8, 4, 10]())
                              ^
Expression [12]:4:4: function instantiation failed
fn example_tensor[rows: Int, columns: Int, base: Int =100]() -> LayoutTensor[
   ^

Expression [12]:13:96: call expansion failed
    return rebind[LayoutTensor[DType.int32, Layout.row_major(rows, columns), MutableAnyOrigin]](t)
                                                                                               ^

expression failed to parse (no further compiler diagnostics)

Here is the complete example, it compiles and runs fine using Mojo nightly.

from layout.tensor_builder import LayoutTensorBuild as tensor_builder
from layout.layout_tensor import (
    Layout,
    LayoutTensor,
)
fn example_tensor[rows: Int, columns: Int]() -> LayoutTensor[DType.int32, Layout.row_major(rows, columns), MutableAnyOrigin]:
    var t = tensor_builder[DType.int32]().row_major[rows, columns]().alloc()
    @parameter
    for r in range(rows):
        @parameter
        for c in range(columns):
            t[r, c] = (r + 1) * 100 + c
    return rebind[LayoutTensor[DType.int32, Layout.row_major(rows, columns), MutableAnyOrigin]](t)

fn main():
    var C = example_tensor[8, 16]()
    print(C)

Can you post your example (all lines) so that we can figure out what is different?

After upgrading Mojo, it can run. But the code does not generate the expected matrix.

Now I have found a way to get correct results, but not through type rebinding.

Here is the full code:

from layout.tensor_builder import LayoutTensorBuild as tensor_builder, static                 
from layout.layout_tensor import (                                                            
    Layout,                                                                                   
    LayoutTensor,                                                                             
)                                                                                             
fn example_tensor_incorrect[rows: Int, columns: Int]() -> LayoutTensor[DType.int32, Layout.row_major(rows, columns), MutableAnyOrigin]:                                                     
    var t = tensor_builder[DType.int32]().row_major[rows, columns]().alloc()                  
    @parameter                                                                                
    for r in range(rows):                                                                     
        @parameter                                                                            
        for c in range(columns):                                                              
            t[r, c] = (r + 1) * 100 + c                                                       
    return rebind[LayoutTensor[DType.int32, Layout.row_major(rows, columns), MutableAnyOrigin]](t)                                                                                          
                                                                                              
fn example_tensor_correct[rows: Int, columns: Int]() -> LayoutTensor[                         
    DType.int32,                                                                              
    Layout.row_major(rows, columns),                                                          
    MutableAnyOrigin,                                                                         
]:                                                                                            
    var t = tensor_builder[DType.int32]().row_major(                                                          static[rows](), static[columns]()                                             
            ).alloc()                                                                         
    for r in range(rows):                                                                     
        for c in range(columns):                                                                          t[r, c] = (r + 1) * 100 + c                                                       
    return t                                                                                  
                                                                                              
fn main():                                                                                    
    C = example_tensor_incorrect[4, 5]()                                                      
    print(C)                                                                                  
    print('-' * 30)                                                                           
    C = example_tensor_correct[4, 5]()                                                        
    print(C)
mojo --version
Mojo 0.25.6.0 (06be5aab)

mojo test.mojo
1029040880 32765 1029041328 32765 1 
0 -1235150896 22031 -1257761984 22031 
-1257761984 22031 1029040728 32765 0 
4 1537 0 4 0 
------------------------------
100 101 102 103 104 
200 201 202 203 204 
300 301 302 303 304 
400 401 402 403 404 

Any idea why the first function is incorrect? thanks @denis!

Just found that it is not the issue of rebind()/static(). It is wrong result because of using @parameter . I am wondering what could be the reason…

Please create an issue here

done: [BUG] compile-time result differs from run-time one. · Issue #5357 · modular/modular · GitHub

2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.