Week 11

For Week 11, I was working on finishing the first part of the symbolic ASR pass. The first part involved being able to support assignment and print statements for symbolic functions and operations. I was able to do this successfully. If y’all remember I had worked on around 6 to 7 Pull Requests before my midterm evaluations where I was working on supporting symbolic functionality through the C backend. In our case, we want to replicate the functionality that was added but through the symbolic pass this time and not the C backend.

As of now functionality for the following PRs have been replciated : #1846, #1964, #2077, #2094. Demonstrating these results through an example.

# Through the main branch (results through the C backend)
(lf) anutosh491@spbhat68:~/lpython/lpython$ cat examples/expr2.py 
from lpython import S
from sympy import Symbol, sin, diff

def main0():
    x: S = Symbol('x')
    y: S = sin(x)
    z: S = diff(y, x)
    print(y)
    print(z)

(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --show-asr examples/expr2.py 

    [(=
        (Var 3 x)
        (IntrinsicFunction
            SymbolicSymbol
            [(StringConstant
                "x"
                (Character 1 1 ())
            )]
            0
            (SymbolicExpression)
            ()
        )
        ()
    )
    (=
        (Var 3 y)
        (IntrinsicFunction
            SymbolicSin
            [(Var 3 x)]
            0
            (SymbolicExpression)
            ()
        )
        ()
    )
    (=
        (Var 3 z)
        (IntrinsicFunction
            SymbolicDiff
            [(Var 3 y)
            (Var 3 x)]
            0
            (SymbolicExpression)
            ()
        )
        ()
    )
    (Print
        ()
        [(Var 3 y)]
        ()
        ()
    )
    (Print
        ()
        [(Var 3 z)]
        ()
        ()
    )]

(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --show-c examples/expr2.py 

// Implementations
char * __name__ = "__main__";
void main0()
{
    basic x;
    basic_new_stack(x);
    basic y;
    basic_new_stack(y);
    basic z;
    basic_new_stack(z);
    symbol_set(x, "x");
    basic_sin(y, x);
    basic_diff(z, y, x);
    printf("%s\n", basic_str(y));
    printf("%s\n", basic_str(z));
    basic_free_stack(z);
    basic_free_stack(y);
    basic_free_stack(x);
}

(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine --backend=c examples/expr2.py 
sin(x)
cos(x)

Generating the same results through the symbolic pass.

(lf) anutosh491@spbhat68:~/lpython/lpython$ cat examples/expr2.py 
from lpython import S
from sympy import Symbol, sin, diff

def main0():
    x: S = Symbol('x')
    y: S = sin(x)
    z: S = diff(y, x)
    print(y)
    print(z)

(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --show-asr --pass=symbolic examples/expr2.py 

    [(=
        (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 _y)
        (Cast
            (IntegerConstant 0 (Integer 4))
            IntegerToInteger
            (Integer 8)
            (IntegerConstant 0 (Integer 8))
        )
        ()
    )
    (=
        (Var 3 y)
        (PointerNullConstant
            (CPtr)
        )
        ()
    )
    (=
        (Var 3 y)
        (PointerToCPtr
            (GetPointer
                (Var 3 _y)
                (Pointer
                    (Integer 8)
                )
                ()
            )
            (CPtr)
            ()
        )
        ()
    )
    (SubroutineCall
        2 basic_new_stack
        2 basic_new_stack
        [((Var 3 y))]
        ()
    )
    (=
        (Var 3 _z)
        (Cast
            (IntegerConstant 0 (Integer 4))
            IntegerToInteger
            (Integer 8)
            (IntegerConstant 0 (Integer 8))
        )
        ()
    )
    (=
        (Var 3 z)
        (PointerNullConstant
            (CPtr)
        )
        ()
    )
    (=
        (Var 3 z)
        (PointerToCPtr
            (GetPointer
                (Var 3 _z)
                (Pointer
                    (Integer 8)
                )
                ()
            )
            (CPtr)
            ()
        )
        ()
    )
    (SubroutineCall
        2 basic_new_stack
        2 basic_new_stack
        [((Var 3 z))]
        ()
    )
    (SubroutineCall
        2 symbol_set
        2 symbol_set
        [((Var 3 x))
        ((StringConstant
            "x"
            (Character 1 1 ())
        ))]
        ()
    )
    (SubroutineCall
        2 basic_sin
        2 basic_sin
        [((Var 3 y))
        ((Var 3 x))]
        ()
    )
    (SubroutineCall
        2 basic_diff
        2 basic_diff
        [((Var 3 z))
        ((Var 3 y))
        ((Var 3 x))]
        ()
    )
    (Print
        ()
        [(FunctionCall
            2 basic_str
            2 basic_str
            [((Var 3 y))]
            (Character 1 -2 ())
            ()
            ()
        )]
        ()
        ()
    )
    (Print
        ()
        [(FunctionCall
            2 basic_str
            2 basic_str
            [((Var 3 z))]
            (Character 1 -2 ())
            ()
            ()
        )]
        ()
        ()
    )]
(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --show-c examples/expr2.py 

// Implementations
char * __name__ = "__main__";
void main0()
{
    int64_t _x;
    int64_t _y;
    int64_t _z;
    void* x;
    void* y;
    void* z;
    _x = 0;
    x = NULL;
    x = (void*) &_x;
    basic_new_stack(x);
    _y = 0;
    y = NULL;
    y = (void*) &_y;
    basic_new_stack(y);
    _z = 0;
    z = NULL;
    z = (void*) &_z;
    basic_new_stack(z);
    symbol_set(x, "x");
    basic_sin(y, x);
    basic_diff(z, y, x);
    printf("%s\n", basic_str(y));
    printf("%s\n", basic_str(z));
}

(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --enable-symengine --backend=c examples/expr2.py 
sin(x)
cos(x)

So in our weekly meeting, I got my work on #2239 reviewed by Ondřej and Thirumalai who gave me some suggestions and approved my pull request after I addressed those changes. As y’all can see above simple assignment and print statements are working without any issues as of now. Hence I’ve started working on the second part of the symbolic ASR pass through #2255.The goal of this PR is to work on the following.

  • Support print statements without assigning the symbolic functions/operations to any prior variables. For eg
    def main0():
    print(sin(Symbol("x")))
    print(diff(sin(Symbol("x")), x))
    
  • Support chaining of operators. For eg
    def main0():
    x: S = Symbol('x')
    y: S = Symbol('y')
    a: S = Symbol('a')
    b: S = Symbol('b')
        
    # Chained Operations
    w: S = (x + y) * ((a - b) / (pi + z))
    
  • Support assert statements. For eg
    def main0():
    x: S = pi
    y: S = Symbol('y')
    z: S = x + y
    assert(z == pi + y)
    

Once these functionalities have been addressed, our symbolic pass would be good to go and we can essentially nullify the changes in the C backend responsible for supporting symbolic operations as we would no longer be needing them. So as I move to the final week of my GSoC project, I have to look after the following.

  • Finish my work on #2255 and address the above written cases.
  • Make sure that all symbolic tests pass through the symbolic pass.
  • Remove relevant changes made in the C backend.

Thank You for going through the blog. I hope you like it. Stick around for what’s next to come. Moving into the final week!

Address

Mumbai, Maharashtra, India