Open Pranavchiku opened 1 year ago
subroutine find_fit(x, expr)
real :: x
interface
function expr(x) result(y)
real, intent(in) :: x
real :: y
end function
end interface
end subroutine
Should ASR node of find_fit
subroutine have expr
as dependency? if yes, it is not having the provision for same which we need to implement to get minpack/examples/example_primes
working.
I think expr
shouldn't be in dependencies list, since it is not an external function, but rather a call back, or "function type". See https://github.com/lfortran/lfortran/issues/1162 for more details on this.
subroutine find_fit(x, expr)
real :: x
interface
function expr(x) result(y)
real, intent(in) :: x
real :: y
end function
end interface
end subroutine
program main
real :: x
call find_fit(x, f)
contains
function f(x) result(y)
real, intent(in) :: x
real :: y
end function
end program
With the latest idea in https://github.com/lfortran/lfortran/issues/1162#issuecomment-1372487399, the expr
above becomes a Variable
called expr
of type FunctionType
(no name).
And f
becomes a Var
that points to a Function
f
.
Regarding:
subroutine find_fit(x, expr_arg)
real :: x
interface
function expr(x) result(y)
real, intent(in) :: x
real :: y
end function
end interface
procedure(expr) :: expr_arg
end subroutine
Here expr_arg
is a Variable of type FunctionType (no name). And expr
is a NamedFunctionType symbol. Both expr_arg
and expr
point to the same FunctionType. But otherwise there is no link between them, which might not be ideal, but it should work.
All this refactor can be done later.
For now, we already have the callbacks working in some way, see integration_tests/callback_*.f90
. Let's create a minimal reproducible example of a bug that you are hitting, and then let's see if there is a way to fix it within the current design, which would unblock us. And we can do the full redesign later.
module find_fit_module
implicit none
public
contains
subroutine find_fit(expr)
interface
function expr(x) result(y)
implicit none
real, intent(in) :: x(:)
real :: y(size(x))
end function
end interface
end subroutine
end module
program main
use find_fit_module, only: find_fit
implicit none
call find_fit(expression)
contains
function expression(x) result(y)
real, intent(in) :: x(:)
real :: y(size(x))
y = x
end function
end program
Throws
$ lfortran a.f90
ASR verify pass error: ASR verify: Var::m_v `x` cannot point outside of its symbol table
Internal Compiler Error: Unhandled exception
Traceback (most recent call last):
Binary file "/home/pranavchiku/lfortran/src/bin/lfortran", in _start()
File "./csu/../csu/libc-start.c", line 392, in __libc_start_main_impl()
File "./csu/../sysdeps/nptl/libc_start_call_main.h", line 58, in __libc_start_call_main()
File "/home/pranavchiku/lfortran/src/bin/lfortran.cpp", line 1938, in ??
err = compile_to_object_file(arg_file, tmp_o, false,
File "/home/pranavchiku/lfortran/src/bin/lfortran.cpp", line 865, in ??
res = fe.get_llvm3(*asr, lpm, diagnostics, infile);
File "/home/pranavchiku/lfortran/src/lfortran/fortran_evaluator.cpp", line 342, in LCompilers::FortranEvaluator::get_llvm3(LCompilers::ASR::TranslationUnit_t&, LCompilers::PassManager&, LCompilers::diag::Diagnostics&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
compiler_options, run_fn, infile);
File "/home/pranavchiku/lfortran/src/libasr/codegen/asr_to_llvm.cpp", line 6794, in LCompilers::asr_to_llvm(LCompilers::ASR::TranslationUnit_t&, LCompilers::diag::Diagnostics&, llvm::LLVMContext&, Allocator&, LCompilers::PassManager&, LCompilers::CompilerOptions&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
pass_manager.apply_passes(al, &asr, pass_options, diagnostics);
File "/home/pranavchiku/lfortran/src/libasr/pass/pass_manager.h", line 209, in LCompilers::PassManager::apply_passes(Allocator&, LCompilers::ASR::TranslationUnit_t*, LCompilers::PassOptions&, LCompilers::diag::Diagnostics&)
_apply_passes(al, asr, _passes, pass_options, diagnostics);
LCompilersException: Verify failed
With the latest main, this is the error:
(lf) harshita@harshita-linux:~/Desktop/lfortran$ lfortran a.f90
; ModuleID = 'LFortran'
source_filename = "LFortran"
%array = type { float*, i32, %dimension_descriptor*, i1, i32 }
%dimension_descriptor = type { i32, i32, i32 }
define void @__module_find_fit_module_find_fit(void (%array*, float*)* %expr) {
.entry:
br label %return
return: ; preds = %.entry
ret void
}
declare void @expr(%array*, float*)
define void @expression_x(float* %x, i32* %__1x, i32* %__2x, float* %y) {
.entry:
%__1_t = alloca i32, align 4
%__1_v = alloca i32, align 4
%0 = load i32, i32* %__1x, align 4
store i32 %0, i32* %__1_v, align 4
store i32 0, i32* %__1_t, align 4
br label %loop.head
loop.head: ; preds = %loop.body, %.entry
%1 = load i32, i32* %__1_t, align 4
%2 = add i32 %1, 1
%3 = load i32, i32* %__2x, align 4
%4 = mul i32 1, %3
%5 = add i32 %4, 1
%6 = sub i32 %5, 1
%7 = icmp sle i32 %2, %6
br i1 %7, label %loop.body, label %loop.end
loop.body: ; preds = %loop.head
%8 = load i32, i32* %__1_t, align 4
%9 = add i32 %8, 1
store i32 %9, i32* %__1_t, align 4
%10 = load i32, i32* %__1_t, align 4
%11 = load i32, i32* %__2x, align 4
%12 = mul i32 1, %11
%13 = sub i32 %10, 1
%14 = mul i32 1, %13
%15 = add i32 0, %14
%16 = mul i32 1, %12
%17 = getelementptr inbounds float, float* %y, i32 %15
%18 = load i32, i32* %__1_v, align 4
%19 = load i32, i32* %__1x, align 4
%20 = load i32, i32* %__2x, align 4
%21 = sub i32 %18, %19
%22 = mul i32 1, %21
%23 = add i32 0, %22
%24 = mul i32 1, %20
%25 = getelementptr inbounds float, float* %x, i32 %23
%26 = load float, float* %25, align 4
store float %26, float* %17, align 4
%27 = load i32, i32* %__1_v, align 4
%28 = add i32 %27, 1
store i32 %28, i32* %__1_v, align 4
br label %loop.head
loop.end: ; preds = %loop.head
br label %return
return: ; preds = %loop.end
ret void
}
define i32 @main(i32 %0, i8** %1) {
.entry:
call void @_lpython_set_argv(i32 %0, i8** %1)
call void @__module_find_fit_module_find_fit(void (float*, i32*, i32*, float*)* @expression_x)
ret i32 0
}
declare void @_lpython_set_argv(i32, i8**)
code generation error: asr_to_llvm: module failed verification. Error:
Call parameter type does not match function signature!
void (float*, i32*, i32*, float*)* @expression_x
void (%array*, float*)* call void @__module_find_fit_module_find_fit(void (float*, i32*, i32*, float*)* @expression_x)
I am trying to have a minimal reproducible error, so that it can be easy to debug.