Skip to content
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

Extending Functionality of the Symbolic ASR pass #2255

Merged
merged 23 commits into from
Aug 8, 2023

Conversation

anutosh491
Copy link
Collaborator

No description provided.

@anutosh491
Copy link
Collaborator Author

Hello @Thirumalai-Shaktivel
Through my latest commit I do the following . Let's consider the program

def main():
   x: S = pi + Symbol('y')

Eventually we would like to treat this as the following (basically change the ASR of program 1 to satisfy program 2)

def main():
   temp_var1 : S = pi
   temp_var2: S = Symbol('y')
   x: S = temp_var1 + temp_var2;

Through the latest commit

  1. I've introduced a symengine_queue framework which would generate those temporary variables for us.
  2. It would add those variables in the function symbol table, declare them using basic_new_stack, adds corresponding functions (basic_const_pi etc) in the module's symbol table and finally assign then with pi and Symbol('y').

So now if we apply the pass , we get (just pasting the function body)

                            main0:
                                (Function
                                    (SymbolTable
                                        3
                                        {
                                            _queue0:
                                                (Variable
                                                    3
                                                    _queue0
                                                    []
                                                    Local
                                                    ()
                                                    ()
                                                    Default
                                                    (Integer 8)
                                                    ()
                                                    BindC
                                                    Public
                                                    Required
                                                    .false.
                                                ),
                                            _queue1:
                                                (Variable
                                                    3
                                                    _queue1
                                                    []
                                                    Local
                                                    ()
                                                    ()
                                                    Default
                                                    (Integer 8)
                                                    ()
                                                    BindC
                                                    Public
                                                    Required
                                                    .false.
                                                ),
                                            _x:
                                                (Variable
                                                    3
                                                    _x
                                                    []
                                                    Local
                                                    ()
                                                    ()
                                                    Default
                                                    (Integer 8)
                                                    ()
                                                    Source
                                                    Public
                                                    Required
                                                    .false.
                                                ),
                                            queue0:
                                                (Variable
                                                    3
                                                    queue0
                                                    []
                                                    Local
                                                    ()
                                                    ()
                                                    Default
                                                    (CPtr)
                                                    ()
                                                    BindC
                                                    Public
                                                    Required
                                                    .false.
                                                ),
                                            queue1:
                                                (Variable
                                                    3
                                                    queue1
                                                    []
                                                    Local
                                                    ()
                                                    ()
                                                    Default
                                                    (CPtr)
                                                    ()
                                                    BindC
                                                    Public
                                                    Required
                                                    .false.
                                                ),
                                            x:
                                                (Variable
                                                    3
                                                    x
                                                    []
                                                    Local
                                                    ()
                                                    ()
                                                    Default
                                                    (CPtr)
                                                    ()
                                                    Source
                                                    Public
                                                    Required
                                                    .false.
                                                )
                                        })
                                    main0
                                    (FunctionType
                                        []
                                        ()
                                        Source
                                        Implementation
                                        ()
                                        .false.
                                        .false.
                                        .false.
                                        .false.
                                        .false.
                                        []
                                        .false.
                                    )
                                    [basic_new_stack
                                    basic_add
                                    basic_const_pi
                                    symbol_set]
                                    []
                                    [(=
                                        (Var 3 _x)
                                        (Cast
                                            (IntegerConstant 0 (Integer 4))
                                            IntegerToInteger
                                            (Integer 8)
                                            (IntegerConstant 0 (Integer 8))
                                        )
                                        ()
                                    )
                                    (=
                                        (Var 3 x)
                                        (PointerNullConstant
                                            (CPtr)
                                        )
                                        ()
                                    )
                                    (=
                                        (Var 3 x)
                                        (PointerToCPtr
                                            (GetPointer
                                                (Var 3 _x)
                                                (Pointer
                                                    (Integer 8)
                                                )
                                                ()
                                            )
                                            (CPtr)
                                            ()
                                        )
                                        ()
                                    )
                                    (SubroutineCall
                                        2 basic_new_stack
                                        2 basic_new_stack
                                        [((Var 3 x))]
                                        ()
                                    )
                                    (=
                                        (Var 3 _queue0)
                                        (Cast
                                            (IntegerConstant 0 (Integer 4))
                                            IntegerToInteger
                                            (Integer 8)
                                            (IntegerConstant 0 (Integer 8))
                                        )
                                        ()
                                    )
                                    (=
                                        (Var 3 queue0)
                                        (PointerNullConstant
                                            (CPtr)
                                        )
                                        ()
                                    )
                                    (=
                                        (Var 3 queue0)
                                        (PointerToCPtr
                                            (GetPointer
                                                (Var 3 _queue0)
                                                (Pointer
                                                    (Integer 8)
                                                )
                                                ()
                                            )
                                            (CPtr)
                                            ()
                                        )
                                        ()
                                    )
                                    (SubroutineCall
                                        2 basic_new_stack
                                        2 basic_new_stack
                                        [((Var 3 queue0))]
                                        ()
                                    )
                                    (SubroutineCall
                                        2 basic_const_pi
                                        2 basic_const_pi
                                        [((Var 3 queue0))]
                                        ()
                                    )
                                    (=
                                        (Var 3 _queue1)
                                        (Cast
                                            (IntegerConstant 0 (Integer 4))
                                            IntegerToInteger
                                            (Integer 8)
                                            (IntegerConstant 0 (Integer 8))
                                        )
                                        ()
                                    )
                                    (=
                                        (Var 3 queue1)
                                        (PointerNullConstant
                                            (CPtr)
                                        )
                                        ()
                                    )
                                    (=
                                        (Var 3 queue1)
                                        (PointerToCPtr
                                            (GetPointer
                                                (Var 3 _queue1)
                                                (Pointer
                                                    (Integer 8)
                                                )
                                                ()
                                            )
                                            (CPtr)
                                            ()
                                        )
                                        ()
                                    )
                                    (SubroutineCall
                                        2 basic_new_stack
                                        2 basic_new_stack
                                        [((Var 3 queue1))]
                                        ()
                                    )
                                    (SubroutineCall
                                        2 symbol_set
                                        2 symbol_set
                                        [((Var 3 queue1))
                                        ((StringConstant
                                            "x"
                                            (Character 1 1 ())
                                        ))]
                                        ()
                                    )
                                    (SubroutineCall
                                        2 basic_add
                                        2 basic_add
                                        [((Var 3 x))
                                        ((IntrinsicFunction
                                            SymbolicPi
                                            []
                                            0
                                            (SymbolicExpression)
                                            ()
                                        ))
                                        ((IntrinsicFunction
                                            SymbolicSymbol
                                            [(StringConstant
                                                "x"
                                                (Character 1 1 ())
                                            )]
                                            0
                                            (SymbolicExpression)
                                            ()
                                        ))]
                                        ()
                                    )]
                                    ()
                                    Public
                                    .false.
                                    .false.
                                    ()
                                )

@czgdp1807 czgdp1807 marked this pull request as draft August 5, 2023 09:46
@anutosh491
Copy link
Collaborator Author

anutosh491 commented Aug 7, 2023

Hello @certik and @Thirumalai-Shaktivel
After my latest commit where I've introduced the symengine_stack to handle operator chaining and other functionalities , I can see that all statements in the symbolic tests (symbolics_01 to symbolics_06) are executed as expected except the assert statement (will address this through the next commit) .

Hence now we can create any composite function from the elementary functions we have and play around with them using assignment and print statements . Let's check symbolics_04 here both through the C and the LLVM backend . I am commenting out the assert statements as of now.

from sympy import Symbol, pi, S
from lpython import S

def test_chained_operations():
    x: S = Symbol('x')
    y: S = Symbol('y')
    z: S = Symbol('z')
    a: S = Symbol('a')
    b: S = Symbol('b')
    
    # Chained Operations
    w: S = (x + y) * ((a - b) / (pi + z))
    result: S = (w ** S(2) - pi) + S(3)
    
    # Print Statements
    # assert(result == S(3) + (a -b)**S(2)*(x + y)**S(2)/(z + pi)**S(2) - pi)
    print(result)
    
    # Additional Variables
    c: S = Symbol('c')
    d: S = Symbol('d')
    e: S = Symbol('e')
    f: S = Symbol('f')
    
    # Chained Operations with Additional Variables
    x = (c * d + e) / f
    y = (x - S(10)) * (pi + S(5))
    z = y ** (S(2) / (f + d))
    result = (z + e) * (a - b)
    
    # Print Statements
    #assert(result == (a - b)*(e + ((S(5) + pi)*(S(-10) + (e + c*d)/f))**(S(2)/(d + f))))
    print(result)
    #assert(x == (e + c*d)/f)
    print(x)
    #assert(y == (S(5) + pi)*(S(-10) + (e + c*d)/f))
    print(y)
    #assert(z == ((S(5) + pi)*(S(-10) + (e + c*d)/f))**(S(2)/(d + f)))
    print(z)

test_chained_operations()
(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine integration_tests/symbolics_04.py
3 + (a - b)**2*(x + y)**2/(z + pi)**2 - pi
(a - b)*(e + ((5 + pi)*(-10 + (e + c*d)/f))**(2/(d + f)))
(e + c*d)/f
(5 + pi)*(-10 + (e + c*d)/f)
((5 + pi)*(-10 + (e + c*d)/f))**(2/(d + f))

(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine --backend=c integration_tests/symbolics_04.py
3 + (a - b)**2*(x + y)**2/(z + pi)**2 - pi
(a - b)*(e + ((5 + pi)*(-10 + (e + c*d)/f))**(2/(d + f)))
(e + c*d)/f
(5 + pi)*(-10 + (e + c*d)/f)
((5 + pi)*(-10 + (e + c*d)/f))**(2/(d + f))

As can be seen these match with the commented out assert statements hence I am quite confident of these results.

@anutosh491
Copy link
Collaborator Author

As of now I haven't refactored any amount of code . As you might see lot of repetetions but that's so that y'all can see all raw code which is being used while reviewing rather than seeing macros etc . I hope that works .

@anutosh491
Copy link
Collaborator Author

The latest commit implements visit_Assert and I think so now we should be good to go with all symbolic tests for C and LLVM backends . I'll paste the results below

(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine integration_tests/symbolics_01.py 
y + pi
(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine --backend=c integration_tests/symbolics_01.py 
y + pi
(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine integration_tests/symbolics_02.py 
x + y
x - y
x*y
x/y
x**y
0
(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine --backend=c integration_tests/symbolics_02.py 
x + y
x - y
x*y
x/y
x**y
0
(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine integration_tests/symbolics_03.py 
2*x
2*x + pi
(2*x + pi)/z
(2*x + pi)**2/z**2
(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine --backend=c integration_tests/symbolics_03.py 
2*x
2*x + pi
(2*x + pi)/z
(2*x + pi)**2/z**2
(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine integration_tests/symbolics_04.py 
3 + (a - b)**2*(x + y)**2/(z + pi)**2 - pi
(a - b)*(e + ((5 + pi)*(-10 + (e + c*d)/f))**(2/(d + f)))
(e + c*d)/f
(5 + pi)*(-10 + (e + c*d)/f)
((5 + pi)*(-10 + (e + c*d)/f))**(2/(d + f))
(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine --backend=c integration_tests/symbolics_04.py 
3 + (a - b)**2*(x + y)**2/(z + pi)**2 - pi
(a - b)*(e + ((5 + pi)*(-10 + (e + c*d)/f))**(2/(d + f)))
(e + c*d)/f
(5 + pi)*(-10 + (e + c*d)/f)
((5 + pi)*(-10 + (e + c*d)/f))**(2/(d + f))
(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine integration_tests/symbolics_05.py 
2*x*y + x**2 + y**2
3*x*y**2 + 3*x*z**2 + 3*x**2*y + 3*x**2*z + 3*y*z**2 + 3*y**2*z + 6*x*y*z + x**3 + y**3 + z**3
2*(x + y)
3*(x + y + z)**2
(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine --backend=c integration_tests/symbolics_05.py 
2*x*y + x**2 + y**2
3*x*y**2 + 3*x*z**2 + 3*x**2*y + 3*x**2*z + 3*y*z**2 + 3*y**2*z + 6*x*y*z + x**3 + y**3 + z**3
2*(x + y)
3*(x + y + z)**2
(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine integration_tests/symbolics_06.py 
abs(log(cos(sin(exp(x)))))
(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine --backend=c integration_tests/symbolics_06.py 
abs(log(cos(sin(exp(x)))))

All results are expected . All asserts pass correctly !

@anutosh491
Copy link
Collaborator Author

anutosh491 commented Aug 7, 2023

In the latest commit I've uncommented all symbolic tests and added the llvm_sym label for all too . All of them pass for me locally , hope the CI also passes.

EDIT1 : All tests pass through the c_sym , cpython_sym and llvm_sym backends and the c_sym backend with the FAST label.
The tests are failing through the llvm_sym backend with the FAST label.
Not sure if this should be addressed.

@certik
Copy link
Contributor

certik commented Aug 7, 2023

@anutosh491 great job!! I think you almost have it. Add the NOFAST and see if things pass. If so, we'll then do a final review and merge it.

Yes, it doesn't matter that there is repetition. That can be refactored later.

@anutosh491 anutosh491 marked this pull request as ready for review August 8, 2023 06:51
@anutosh491
Copy link
Collaborator Author

Ready @certik @Thirumalai-Shaktivel

@certik certik merged commit 320841b into lcompilers:main Aug 8, 2023
9 checks passed
@certik
Copy link
Contributor

certik commented Aug 8, 2023

Great job @anutosh491 !

I can see two avenues how to improve this:

@anutosh491 anutosh491 deleted the GSoC_PR_11 branch August 9, 2023 04:27
@anutosh491
Copy link
Collaborator Author

Thanks for the reviews @certik . Yes now that we have the pass in place , I'll remove the symbolic support from the C backend and then proceed onto refactoring the pass.

Another thing I can see is there are quite some issues related to my project that are open and I think now could be closed like
#1987 , #1907 etc . We could maybe assign a label named "symbolic" or something to these and close them eventually.

@certik
Copy link
Contributor

certik commented Aug 9, 2023

Perfect!

Go ahead and assign the label "symbolic", I added it to the above two issues you mentioned.

@certik certik mentioned this pull request Aug 9, 2023
9 tasks
@anutosh491 anutosh491 mentioned this pull request Aug 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants