Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Implemented ASR checks for function dependencies #2167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

arteevraina
Copy link
Collaborator

@arteevraina arteevraina commented Jul 17, 2023

Towards: #2006

LFortran: lfortran/lfortran#2327

@@ -440,6 +440,20 @@ class VerifyVisitor : public BaseWalkVisitor<VerifyVisitor>
verify_unique_dependencies(x.m_dependencies, x.n_dependencies,
x.m_name, x.base.base.loc);

// Dependencies of the function should be from same symbol table.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@certik Do you think this logic is on the right track for checking the that dependencies & function should be from same symbol table ?

@arteevraina arteevraina force-pushed the checks-for-same-symtab-dependencies branch from bead745 to 8d8bbc7 Compare July 19, 2023 17:28
@arteevraina arteevraina marked this pull request as ready for review July 19, 2023 17:55

require(dep_sym != nullptr,
"Dependency " + found_dep + " does not belong to same parent symbol table of " + std::string(x.m_name));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am trying to understand the logic here.

Are we ensuring that all dependencies are from the same parent symbol table?

It seems this logic is testing that all the symbols (except ExternalSymbol) are NOT from the parent symbol table. Tests pass, so I guess this is the correct logic, but I don't understand it. Once I understand it, let's document this as a comment.

@arteevraina
Copy link
Collaborator Author

arteevraina commented Jul 23, 2023

ASR verify fails in nested_vars pass when trying to generate the LLVM. But, run perfectly fine when trying to generate only ASR using --show-asr flag.

Here is the stacktrace:

ASR Pass starts: 'nested_vars'
ASR verify pass error: ASR verify: Dependency _lpython_floordiv@__lpython_overloaded_6___lpython_floordiv was not found in the parent symbol table main
Internal Compiler Error: Unhandled exception
Traceback (most recent call last):
  File "/Users/arteevraina/GSI/lpython/src/bin/lpython.cpp", line 1872
    err = compile_python_to_object_file(arg_file, tmp_o, runtime_library_dir,
  File "/Users/arteevraina/GSI/lpython/src/bin/lpython.cpp", line 827
    res = fe.get_llvm3(*asr, pass_manager, diagnostics, infile);
  File "/Users/arteevraina/GSI/lpython/src/lpython/python_evaluator.cpp", line 58
    run_fn, infile);
  File "/Users/arteevraina/GSI/lpython/src/libasr/codegen/asr_to_llvm.cpp", line 8227
    pass_manager.apply_passes(al, &asr, pass_options, diagnostics);
  File "/Users/arteevraina/GSI/lpython/src/libasr/pass/pass_manager.h", line 285
    apply_passes(al, asr, _passes, pass_options, diagnostics);
  File "/Users/arteevraina/GSI/lpython/src/libasr/pass/pass_manager.h", line 156
    throw LCompilersException("Verify failed in the pass: "
LCompilersException: Verify failed in the pass: nested_vars

cc: @certik @czgdp1807

Copy link
Collaborator

@czgdp1807 czgdp1807 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these changes should be simultaneously applied to LFortran as well. And then both the PRs should be merged together.

@arteevraina
Copy link
Collaborator Author

arteevraina commented Jul 28, 2023

I think these changes should be simultaneously applied to LFortran as well. And then both the PRs should be merged together.

Sure. I would be happy to do that.

I think there are still some things left to correct in this PR.

As, few tests like https://github.com/lcompilers/lpython/blob/v0.19.0/integration_tests/callback_01.py are still having dependencies that are not from same parent symbol table. As, in this one, g depends on func which is not in the same parent symtab as of g.

Can this be due to some of the checks that I implemented in this PR actually fail or am I missing some places to implement the same checks ? @czgdp1807

(lp) arteevraina@Arteevs-MacBook-Air lpython % src/bin/lpython ./integration_tests/callback_01.py --show-asr
(TranslationUnit
    (SymbolTable
        1
        {
            __main__:
                (Module
                    (SymbolTable
                        2
                        {
                            __main____global_statements:
                                (Function
                                    (SymbolTable
                                        9
                                        {
                                            
                                        })
                                    __main____global_statements
                                    (FunctionType
                                        []
                                        ()
                                        Source
                                        Implementation
                                        ()
                                        .false.
                                        .false.
                                        .false.
                                        .false.
                                        .false.
                                        []
                                        []
                                        .false.
                                    )
                                    [check]
                                    []
                                    [(SubroutineCall
                                        2 check
                                        ()
                                        []
                                        ()
                                    )]
                                    ()
                                    Public
                                    .false.
                                    .false.
                                    ()
                                ),
                            check:
                                (Function
                                    (SymbolTable
                                        8
                                        {
                                            
                                        })
                                    check
                                    (FunctionType
                                        []
                                        ()
                                        Source
                                        Implementation
                                        ()
                                        .false.
                                        .false.
                                        .false.
                                        .false.
                                        .false.
                                        []
                                        []
                                        .false.
                                    )
                                    [g]
                                    []
                                    [(Assert
                                        (IntegerCompare
                                            (FunctionCall
                                                2 g
                                                ()
                                                [((Var 2 f))
                                                ((IntegerConstant 10 (Integer 4)))]
                                                (Integer 4)
                                                ()
                                                ()
                                            )
                                            Eq
                                            (IntegerConstant 11 (Integer 4))
                                            (Logical 4)
                                            ()
                                        )
                                        ()
                                    )
                                    (Assert
                                        (IntegerCompare
                                            (FunctionCall
                                                2 g
                                                ()
                                                [((Var 2 f2))
                                                ((IntegerConstant 20 (Integer 4)))]
                                                (Integer 4)
                                                ()
                                                ()
                                            )
                                            Eq
                                            (IntegerConstant 30 (Integer 4))
                                            (Logical 4)
                                            ()
                                        )
                                        ()
                                    )
                                    (Assert
                                        (IntegerCompare
                                            (FunctionCall
                                                2 g
                                                ()
                                                [((Var 2 f3))
                                                ((IntegerConstant 5 (Integer 4)))]
                                                (Integer 4)
                                                ()
                                                ()
                                            )
                                            Eq
                                            (IntegerConstant 21 (Integer 4))
                                            (Logical 4)
                                            ()
                                        )
                                        ()
                                    )]
                                    ()
                                    Public
                                    .false.
                                    .false.
                                    ()
                                ),
                            f:
                                (Function
                                    (SymbolTable
                                        3
                                        {
                                            _lpython_return_variable:
                                                (Variable
                                                    3
                                                    _lpython_return_variable
                                                    []
                                                    ReturnVar
                                                    ()
                                                    ()
                                                    Default
                                                    (Integer 4)
                                                    ()
                                                    Source
                                                    Public
                                                    Required
                                                    .false.
                                                ),
                                            x:
                                                (Variable
                                                    3
                                                    x
                                                    []
                                                    In
                                                    ()
                                                    ()
                                                    Default
                                                    (Integer 4)
                                                    ()
                                                    Source
                                                    Public
                                                    Required
                                                    .false.
                                                )
                                        })
                                    f
                                    (FunctionType
                                        [(Integer 4)]
                                        (Integer 4)
                                        Source
                                        Implementation
                                        ()
                                        .false.
                                        .false.
                                        .false.
                                        .false.
                                        .false.
                                        []
                                        []
                                        .false.
                                    )
                                    []
                                    [(Var 3 x)]
                                    [(=
                                        (Var 3 _lpython_return_variable)
                                        (IntegerBinOp
                                            (Var 3 x)
                                            Add
                                            (IntegerConstant 1 (Integer 4))
                                            (Integer 4)
                                            ()
                                        )
                                        ()
                                    )
                                    (Return)]
                                    (Var 3 _lpython_return_variable)
                                    Public
                                    .false.
                                    .false.
                                    ()
                                ),
                            f2:
                                (Function
                                    (SymbolTable
                                        4
                                        {
                                            _lpython_return_variable:
                                                (Variable
                                                    4
                                                    _lpython_return_variable
                                                    []
                                                    ReturnVar
                                                    ()
                                                    ()
                                                    Default
                                                    (Integer 4)
                                                    ()
                                                    Source
                                                    Public
                                                    Required
                                                    .false.
                                                ),
                                            x:
                                                (Variable
                                                    4
                                                    x
                                                    []
                                                    In
                                                    ()
                                                    ()
                                                    Default
                                                    (Integer 4)
                                                    ()
                                                    Source
                                                    Public
                                                    Required
                                                    .false.
                                                )
                                        })
                                    f2
                                    (FunctionType
                                        [(Integer 4)]
                                        (Integer 4)
                                        Source
                                        Implementation
                                        ()
                                        .false.
                                        .false.
                                        .false.
                                        .false.
                                        .false.
                                        []
                                        []
                                        .false.
                                    )
                                    []
                                    [(Var 4 x)]
                                    [(=
                                        (Var 4 _lpython_return_variable)
                                        (IntegerBinOp
                                            (Var 4 x)
                                            Add
                                            (IntegerConstant 10 (Integer 4))
                                            (Integer 4)
                                            ()
                                        )
                                        ()
                                    )
                                    (Return)]
                                    (Var 4 _lpython_return_variable)
                                    Public
                                    .false.
                                    .false.
                                    ()
                                ),
                            f3:
                                (Function
                                    (SymbolTable
                                        5
                                        {
                                            _lpython_return_variable:
                                                (Variable
                                                    5
                                                    _lpython_return_variable
                                                    []
                                                    ReturnVar
                                                    ()
                                                    ()
                                                    Default
                                                    (Integer 4)
                                                    ()
                                                    Source
                                                    Public
                                                    Required
                                                    .false.
                                                ),
                                            x:
                                                (Variable
                                                    5
                                                    x
                                                    []
                                                    In
                                                    ()
                                                    ()
                                                    Default
                                                    (Integer 4)
                                                    ()
                                                    Source
                                                    Public
                                                    Required
                                                    .false.
                                                )
                                        })
                                    f3
                                    (FunctionType
                                        [(Integer 4)]
                                        (Integer 4)
                                        Source
                                        Implementation
                                        ()
                                        .false.
                                        .false.
                                        .false.
                                        .false.
                                        .false.
                                        []
                                        []
                                        .false.
                                    )
                                    [f
                                    f2]
                                    [(Var 5 x)]
                                    [(=
                                        (Var 5 _lpython_return_variable)
                                        (IntegerBinOp
                                            (FunctionCall
                                                2 f
                                                ()
                                                [((Var 5 x))]
                                                (Integer 4)
                                                ()
                                                ()
                                            )
                                            Add
                                            (FunctionCall
                                                2 f2
                                                ()
                                                [((Var 5 x))]
                                                (Integer 4)
                                                ()
                                                ()
                                            )
                                            (Integer 4)
                                            ()
                                        )
                                        ()
                                    )
                                    (Return)]
                                    (Var 5 _lpython_return_variable)
                                    Public
                                    .false.
                                    .false.
                                    ()
                                ),
                            g:
                                (Function
                                    (SymbolTable
                                        6
                                        {
                                            _lpython_return_variable:
                                                (Variable
                                                    6
                                                    _lpython_return_variable
                                                    []
                                                    ReturnVar
                                                    ()
                                                    ()
                                                    Default
                                                    (Integer 4)
                                                    ()
                                                    Source
                                                    Public
                                                    Required
                                                    .false.
                                                ),
                                            arg:
                                                (Variable
                                                    6
                                                    arg
                                                    []
                                                    In
                                                    ()
                                                    ()
                                                    Default
                                                    (Integer 4)
                                                    ()
                                                    Source
                                                    Public
                                                    Required
                                                    .false.
                                                ),
                                            func:
                                                (Function
                                                    (SymbolTable
                                                        7
                                                        {
                                                            func_arg_0:
                                                                (Variable
                                                                    7
                                                                    func_arg_0
                                                                    []
                                                                    Unspecified
                                                                    ()
                                                                    ()
                                                                    Default
                                                                    (Integer 4)
                                                                    ()
                                                                    Source
                                                                    Public
                                                                    Required
                                                                    .false.
                                                                ),
                                                            func_return_var_name:
                                                                (Variable
                                                                    7
                                                                    func_return_var_name
                                                                    []
                                                                    ReturnVar
                                                                    ()
                                                                    ()
                                                                    Default
                                                                    (Integer 4)
                                                                    ()
                                                                    Source
                                                                    Public
                                                                    Required
                                                                    .false.
                                                                )
                                                        })
                                                    func
                                                    (FunctionType
                                                        [(Integer 4)]
                                                        (Integer 4)
                                                        BindC
                                                        Interface
                                                        ()
                                                        .false.
                                                        .false.
                                                        .false.
                                                        .false.
                                                        .false.
                                                        []
                                                        []
                                                        .false.
                                                    )
                                                    []
                                                    [(Var 7 func_arg_0)]
                                                    []
                                                    (Var 7 func_return_var_name)
                                                    Public
                                                    .false.
                                                    .false.
                                                    ()
                                                ),
                                            ret:
                                                (Variable
                                                    6
                                                    ret
                                                    []
                                                    Local
                                                    ()
                                                    ()
                                                    Default
                                                    (Integer 4)
                                                    ()
                                                    Source
                                                    Public
                                                    Required
                                                    .false.
                                                )
                                        })
                                    g
                                    (FunctionType
                                        [(FunctionType
                                            [(Integer 4)]
                                            (Integer 4)
                                            BindC
                                            Interface
                                            ()
                                            .false.
                                            .false.
                                            .false.
                                            .false.
                                            .false.
                                            []
                                            []
                                            .false.
                                        )
                                        (Integer 4)]
                                        (Integer 4)
                                        Source
                                        Implementation
                                        ()
                                        .false.
                                        .false.
                                        .false.
                                        .false.
                                        .false.
                                        []
                                        []
                                        .false.
                                    )
                                    [func]
                                    [(Var 6 func)
                                    (Var 6 arg)]
                                    [(=
                                        (Var 6 ret)
                                        (FunctionCall
                                            6 func
                                            ()
                                            [((Var 6 arg))]
                                            (Integer 4)
                                            ()
                                            ()
                                        )
                                        ()
                                    )
                                    (=
                                        (Var 6 _lpython_return_variable)
                                        (Var 6 ret)
                                        ()
                                    )
                                    (Return)]
                                    (Var 6 _lpython_return_variable)
                                    Public
                                    .false.
                                    .false.
                                    ()
                                )
                        })
                    __main__
                    []
                    .false.
                    .false.
                ),
            main_program:
                (Program
                    (SymbolTable
                        10
                        {
                            __main____global_statements:
                                (ExternalSymbol
                                    10
                                    __main____global_statements
                                    2 __main____global_statements
                                    __main__
                                    []
                                    __main____global_statements
                                    Public
                                )
                        })
                    main_program
                    [__main__]
                    [(SubroutineCall
                        10 __main____global_statements
                        2 __main____global_statements
                        []
                        ()
                    )]
                )
        })
    []
)

@czgdp1807
Copy link
Collaborator

Now there are two things that can be done,

  1. func shouldn't be present inside the dependency list of g.
  2. Define func outside the symbol table of g.

Second option makes more sense to me. Defining func inside g doesn't make sense because the actual function callbacks which are passed to g calls are defined outside g. So placement of func inside g's symbol table is problematic to me. Also, in the backends, for defining g, first func should be declared, and that is not possible if you put it inside g's symbol table.

@czgdp1807
Copy link
Collaborator

@arteevraina Will you be working on this? Please let us know the status. I am marking it as draft for now. However whenever you are done, please mark it ready for review. Thanks for your work.

@czgdp1807 czgdp1807 marked this pull request as draft August 3, 2023 04:56
@arteevraina
Copy link
Collaborator Author

@arteevraina Will you be working on this? Please let us know the status. I am marking it as draft for now. However whenever you are done, please mark it ready for review. Thanks for your work.

Yes, I will be continuing my work on this. I was away for few days due to some work but now I will continue working on this.

@certik
Copy link
Contributor

certik commented Aug 30, 2023

I am still reviewing this. Before we can merge, can you please also send exactly the same PR against LFortran? We have to see that it passes all the tests there as well. @czgdp1807 do you see any issues with this PR?

@arteevraina
Copy link
Collaborator Author

I am still reviewing this. Before we can merge, can you please also send exactly the same PR against LFortran? We have to see that it passes all the tests there as well. @czgdp1807 do you see any issues with this PR?

Sure @certik , I will do that meanwhile.

@arteevraina
Copy link
Collaborator Author

@czgdp1807 I have resolved all of the comments on this PR.

@certik certik requested a review from czgdp1807 September 2, 2023 13:51
@certik
Copy link
Contributor

certik commented Sep 2, 2023

@arteevraina can you please submit a PR against LFortran as well? Let's see if things work there.

@arteevraina
Copy link
Collaborator Author

@arteevraina can you please submit a PR against LFortran as well? Let's see if things work there.

Sure @certik , I am on it.

@arteevraina
Copy link
Collaborator Author

Regarding the lfortran PR, I replicated the changes in the lfortran for libasr folder as it is and there were some dependency checks required in ast_common_visitor class as it is unique to lfortran.

After applying changes, I got some failures in integration tests, need to debug that. Will create the PR after fixing the tests locally.

@certik
Copy link
Contributor

certik commented Sep 2, 2023

Perfect! You can submit a PR to LFortran even if it doesn't work yet. I expected there would be some fixes needed, so we can just work on it iteratively.

@arteevraina
Copy link
Collaborator Author

PR -> lfortran/lfortran#2327

A total of 15 test cases are failing in lfortran in this PR. I am working to resolve the issues with them one by one. @certik

@certik
Copy link
Contributor

certik commented Oct 24, 2023

@czgdp1807 can you please review this?

@certik certik merged commit 800c657 into lcompilers:main Oct 24, 2023
Comment on lines +1 to +6
warning: The module 'numpy' located in $DIR/src/bin/../runtime/lpython_intrinsic_numpy.py cannot be loaded
--> tests/../integration_tests/array_01_decl.py:2:1
|
2 | from numpy import empty, int16, int32, int64, float32, float64, complex64, complex128
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ imported here

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems there are several errors like above that got committed in this PR. Are these reference errors expected or is it a bug?

ASR::symbol_t* dep_sym = x_symtab->resolve_symbol(found_dep);

require(dep_sym != nullptr,
"Dependency " + found_dep + " is inside symbol table " + std::string(x.m_name));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be "Dependency " + found_dep + " is not* inside symbol table "

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct, "not inside".

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you both are right.

I assumed the resolve_symbol checks in parent scope only and not in the current_scope. Now that i checked it's documentation, it checks both in current & parent scopes.

The check should will be updated like this :
SymbolTable *x_parent_symtab = x.m_symtab->parent; instead of SymbolTable* x_symtab = x.m_symtab;
and then "inside" phrase will make sense here.

certik added a commit to certik/lpython that referenced this pull request Oct 24, 2023
This was committed by a mistake in
lcompilers#2167.
Agent-Hellboy pushed a commit to Agent-Hellboy/lpython that referenced this pull request Mar 5, 2024
Agent-Hellboy pushed a commit to Agent-Hellboy/lpython that referenced this pull request Mar 5, 2024
This was committed by a mistake in
lcompilers#2167.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants