lcompilers / lpython

Python compiler
https://lpython.org/
Other
1.51k stars 164 forks source link

Array assignment fails #1599

Open certik opened 1 year ago

certik commented 1 year ago
from numpy import empty, float32

def main():
    a: f32[10000] = empty(10000, dtype=float32)
    b: f32[10000]
    b[:] = a[:]

main()

gives:

$ lpython a.py
Internal Compiler Error: Unhandled exception
Traceback (most recent call last):
  File "/Users/ondrej/repos/lpython/src/bin/lpython.cpp", line 1685
    err = compile_python_to_object_file(arg_file, tmp_o, runtime_library_dir,
  File "/Users/ondrej/repos/lpython/src/bin/lpython.cpp", line 703
    res = fe.get_llvm3(*asr, pass_manager, diagnostics, infile);
  File "/Users/ondrej/repos/lpython/src/lpython/python_evaluator.cpp", line 58
    run_fn, infile);
  File "/Users/ondrej/repos/lpython/src/libasr/codegen/asr_to_llvm.cpp", line 7025
    pass_manager.apply_passes(al, &asr, pass_options, diagnostics);
  File "/Users/ondrej/repos/lpython/src/libasr/pass/pass_manager.h", line 213
    _apply_passes(al, asr, _passes, pass_options, diagnostics);
  File "/Users/ondrej/repos/lpython/src/libasr/pass/pass_manager.h", line 104
    _passes_db[passes[i]](al, *asr, pass_options);
  File "/Users/ondrej/repos/lpython/src/libasr/pass/arr_slice.cpp", line 220
    ArraySectionVisitor v(al);
  File "../libasr/asr.h", line 39209
  File "../libasr/asr.h", line 4480
  File "../libasr/asr.h", line 4219
  File "../libasr/asr.h", line 39227
  File "../libasr/asr.h", line 4480
  File "../libasr/asr.h", line 4220
  File "../libasr/asr.h", line 39247
  File "/Users/ondrej/repos/lpython/src/libasr/pass/arr_slice.cpp", line 195
    visit_stmt(*m_body[i]);
  File "../libasr/asr.h", line 4495
  File "../libasr/asr.h", line 4241
  File "/Users/ondrej/repos/lpython/src/libasr/pass/arr_slice.cpp", line 207
    current_expr = const_cast<ASR::expr_t**>(&(x.m_value));
  File "/Users/ondrej/repos/lpython/src/libasr/pass/arr_slice.cpp", line 187
    replacer.replace_expr(*current_expr);
  File "../libasr/asr.h", line 38554
  File "/Users/ondrej/repos/lpython/src/libasr/pass/arr_slice.cpp", line 159
    int a_kind = ASRUtils::extract_kind_from_ttype_t(ASRUtils::expr_type(idx_vars_target[0]));
  File "../libasr/asr_utils.h", line 108
  File "../libasr/asr.h", line 41878
Thirumalai-Shaktivel commented 1 year ago

The following seems to work:

from lpython import f32
from numpy import empty, float32

def main():
    a: f32[3] = empty(3, dtype=float32)
    b: f32[3] = empty(3, dtype=float32)
    a[0] = f32(1)
    a[1] = f32(2)
    a[2] = f32(3)
    b = a
    # b[:] = a[:]
    print(a, b)

main()

We need to support b[:] = a[:]

Thirumalai-Shaktivel commented 1 year ago

I checked this in LFortran:

program name
    implicit none
    integer:: x(2) = [1,2]
    integer:: y(2)
    y(:) = x(:)
    print *, x, y
end program name
$ lfortran examples/expr2.f90           
1 2 
0 0 
$ gfortran examples/expr2.f90 && ./a.out
           1           2           1           2

It seems both have the same issue .i.e., ArraySection is replaced to Associate in array_op pass:

(=
    (ArraySection
        (Var 2 y)
        [((ArrayBound
            (Var 2 y)
            (IntegerConstant 1 (Integer 4))
            (Integer 4)
            LBound
            (IntegerConstant 1 (Integer 4))
        )
        (ArrayBound
            (Var 2 y)
            (IntegerConstant 1 (Integer 4))
            (Integer 4)
            UBound
            (IntegerConstant 2 (Integer 4))
        )
        (IntegerConstant 1 (Integer 4)))]
        (Array
            (Integer 4)
            [(()
            ())]
            DescriptorArray
        )
        ()
    )
    (ArraySection
        (Var 2 x)
        [((ArrayBound
            (Var 2 x)
            (IntegerConstant 1 (Integer 4))
            (Integer 4)
            LBound
            (IntegerConstant 1 (Integer 4))
        )
        (ArrayBound
            (Var 2 x)
            (IntegerConstant 1 (Integer 4))
            (Integer 4)
            UBound
            (IntegerConstant 2 (Integer 4))
        )
        (IntegerConstant 1 (Integer 4)))]
        (Array
            (Integer 4)
            [(()
            ())]
            DescriptorArray
        )
        ()
    )
    ()
)

After arrayop pass

(=>
    (Var 2 __libasr__created__var__0__array_section_pointer_)
    (ArraySection
        (Var 2 x)
        [((ArrayBound
            (Var 2 x)
            (IntegerConstant 1 (Integer 4))
            (Integer 4)
            LBound
            (IntegerConstant 1 (Integer 4))
        )
        (ArrayBound
            (Var 2 x)
            (IntegerConstant 1 (Integer 4))
            (Integer 4)
            UBound
            (IntegerConstant 2 (Integer 4))
        )
        (IntegerConstant 1 (Integer 4)))]
        (Array
            (Integer 4)
            [(()
            ())]
            DescriptorArray
        )
        ()
    )
)
Thirumalai-Shaktivel commented 1 year ago
program name
    implicit none
    integer:: x(2) = [1,2]
    integer:: y(2)
    y = x(:)
    print *, x, y
end program name

LFortran

$ lfortran examples/expr2.f90 
1 2 
0 0

@czgdp1807, I came across this: https://github.com/lcompilers/lpython/issues/1599#issuecomment-1621157646 issue again in LFortran! Why do we replace the assignment statement to associate? Do I miss anything? Should this be handled in some other pass?