lcompilers / lpython

Python compiler
https://lpython.org/
Other
1.5k stars 157 forks source link

Unhandled exception with array parameter / argument #2497

Closed rebcabin closed 7 months ago

rebcabin commented 7 months ago

I imitated some code in integration_tests/array_expr02.py. Here is a snippet:

def modify(array_a: f32[:], n: i32) -> f32[n]:
    return sqrt(array_a)

In my context, this pattern generated an unhandled exception.

import numpy
from numpy import array, empty, int16
from lpython import (i16, i32, ccallback, c_p_pointer, Pointer, u64, CPtr, i64,
                     ccall, sizeof, Array, Allocatable, TypeVar, Const)

@ccall
def _lfortran_malloc(size : i32) -> CPtr:
    """Borrow from bindc_07.py in integration_tests."""
    pass

rows = TypeVar("rows")
cols = TypeVar("cols")

def load_lpython_array_from_c_fortran_array(b: CPtr, rows: i32, cols: i32) -> i16[rows, cols]:
    """Load an LPython array from a C / Fortran array."""
    B: Pointer[i16[:]] = c_p_pointer(b, i16[:], array([rows * cols]))
    D: i16[rows, cols] = empty((rows, cols), dtype=int16)
    i: i32
    j: i32
    for i in range(rows):
        for j in range(cols):
            D[i, j] = B[(i * cols) + j]
    return D

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ATTENTION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def spot_print_lpython_array(a: i16[:], rows: i32, cols: i32) -> None:
    pass

def main() -> i32:

    # "Const" lets these appear in type declarations such as i16[n, m]
    n  : Const[i32] = 15
    m  : Const[i32] = 3

    Anm_l4 : CPtr = _lfortran_malloc((n * m) * i32(sizeof(i16)))

    Anm: i16[n, m] = load_lpython_array_from_c_fortran_array(Anm_l4, n, m)
    spot_print_lpython_array(Anm, n, m)

    return 0

if __name__ == "__main__":
    main()
(lp) ┌─(~/Documents/GitHub/lpython/integration_tests)──────────────────────────────────────────────────────────────────────────────(brian@MacBook-Pro:s001)─┐
└─(19:42:08 on vector-backend ✹ ✭)──> PYTHONPATH=".:../src/runtime/lpython:.." LPYTHON_PY_MOD_NAME="" LPYTHON_PY_MOD_PATH="_lpython-tmp-test-cpython" python ../ISSUES/UNHANDLED-EXCEPTIONS/Issue2497.py
(lp) ┌─(~/Documents/GitHub/lpython/integration_tests)──────────────────────────────────────────────────────────────────────────────(brian@MacBook-Pro:s001)─┐
└─(19:43:02 on vector-backend ✹ ✭)──> lpython ../ISSUES/UNHANDLED-EXCEPTIONS/Issue2497.py                                                ──(Tue,Feb06)─┘
Internal Compiler Error: Unhandled exception
Traceback (most recent call last):
  File "/Users/brian/Dropbox/Mac/Documents/GitHub/lpython/src/bin/lpython.cpp", line 1872
    err = compile_python_to_object_file(arg_file, tmp_o, runtime_library_dir,
  File "/Users/brian/Dropbox/Mac/Documents/GitHub/lpython/src/bin/lpython.cpp", line 824
    res = fe.get_llvm3(*asr, pass_manager, diagnostics, infile);
  File "/Users/brian/Dropbox/Mac/Documents/GitHub/lpython/src/lpython/python_evaluator.cpp", line 71
    run_fn, infile);
  File "/Users/brian/Dropbox/Mac/Documents/GitHub/lpython/src/libasr/codegen/asr_to_llvm.cpp", line 9276
    pass_manager.apply_passes(al, &asr, co.po, diagnostics);
  File "/Users/brian/Documents/GitHub/lpython/src/libasr/pass/pass_manager.h", line 299
    apply_passes(al, asr, _passes, pass_options, diagnostics);
  File "/Users/brian/Documents/GitHub/lpython/src/libasr/pass/pass_manager.h", line 160
    _passes_db[passes[i]](al, *asr, pass_options);
  File "/Users/brian/Dropbox/Mac/Documents/GitHub/lpython/src/libasr/pass/pass_array_by_data.cpp", line 651
    u.visit_TranslationUnit(unit);
  File "../libasr/asr.h", line 39627
  File "../libasr/asr.h", line 5060
  File "../libasr/asr.h", line 4774
  File "../libasr/asr.h", line 39645
  File "../libasr/asr.h", line 5060
  File "../libasr/asr.h", line 4775
  File "../libasr/asr.h", line 39661
  File "../libasr/asr.h", line 39621
  File "../libasr/asr.h", line 5077
  File "../libasr/asr.h", line 4825
  File "/Users/brian/Dropbox/Mac/Documents/GitHub/lpython/src/libasr/pass/pass_array_by_data.cpp", line 573
    visit_Call(x);
  File "/Users/brian/Dropbox/Mac/Documents/GitHub/lpython/src/libasr/pass/pass_array_by_data.cpp", line 540
    throw LCompilersException("Number of arguments in the new "
LCompilersException: Number of arguments in the new function call doesn't satisfy min_args <= new_args.size() <= max_args, 5 <= 7 <= 5
rebcabin commented 7 months ago

Also fails with double colon:

def spot_print_lpython_array(a: i16[:, :], rows: i32, cols: i32) -> None:
    pass
def spot_print_lpython_array(a: i16[::], rows: i32, cols: i32) -> None:
    pass
rebcabin commented 7 months ago

Also fails with one-dimensional array:

    foo: i16[n] = empty((15,), dtype=i16)
    spot_print_lpython_array(foo, n, m)
rebcabin commented 7 months ago

Marking this Issue severe because without advice or a fix, I cannot pass arrays as parameters to functions, I must manually inline all code, and that's very nasty.

rebcabin commented 7 months ago

Here is another example of where it's needed to stand in for missing broadcast of constant:

def clear_row(a: i16[:], row: i32, cols: i32) -> None:
    j: i32
    for j in range(cols):
        a[row, j] = i16(0)
    VR_SIZE: i32 = 32_768
    k: i32
    A_ik: i16
    jj: i32
    ii: i32
    i: i32
    for jj in range(0, l, VR_SIZE):  # each VR-col chunk in B and C
        for ii in range(0, n, M2):  # each M2 block in A cols and B rows
            for i in range(0, M2):  # zero-out rows of C
                # Due to Issue 2496, I cannot pass an array to a function
                clear_row(Cnl, i + ii, l)  # ~~~~~~~~~~~~~~~~~~ ATTENTION ~~~~~~
                # Cnl[i + ii, :] = 0
                pass
certik commented 7 months ago

There are several issues:

Now it works.