Week 10
For Week 10, I was working on the symbolic ASR pass. Reiterating the idea behing the pass, we want to introduce such an ASR->ASR pass to lift the symbolic support from the C backend and extend its functionality to all other backends like LLVM. The Pull Request for the same can be viewed here
So we would essentially want to treat Program 1 as Program 2 and make changes in the ASR from Program 1 accordingly.
# Program 1
from lpython import S
from sympy import pi
def main0():
x: S = pi
main0()
# Program 2
from lpython import ccall, CPtr, p_c_pointer, pointer, i64, empty_c_void_p
import os
@ccall(header="symengine/cwrapper.h", c_shared_lib="symengine", c_shared_lib_path=f"{os.environ['CONDA_PREFIX']}/lib")
def basic_new_stack(x: CPtr) -> None:
pass
@ccall(header="symengine/cwrapper.h", c_shared_lib="symengine", c_shared_lib_path=f"{os.environ['CONDA_PREFIX']}/lib")
def basic_const_pi(x: CPtr) -> None:
pass
def main0():
_x: i64 = i64(0)
x: CPtr = empty_c_void_p()
p_c_pointer(pointer(_x, i64), x)
basic_new_stack(x)
basic_const_pi(x)
main0()
To achieve the following there are few things which need to be addressed
- We need to replace the originally declared
x:S
variable by another variable of the formx:CPtr
either by completely creating a new variable or by editing the type of the first one. We also need a placeholder variable declared for all initially declared symbolic variables, something of the form_x:i64
. - Once the above change has been initiated, we know that we need the
basic_new_stack
for allocating memory to a SymEngine basic variable and hence we need to introduce thebasic_new_stack
function in the Symbol Table of theModule
node. - The next step here would be to change the function body of the
main0
function and introduce the statements responsible for declaring the basic variablex
and allot memory to it. - This should be followed by handling the assignment statement through a
visit_Assignment
function in thereplace_symbolic
pass . Once we identify the value and the symbolic intrinsic function being used likeSymbolicpi
orSymbolicAdd
, we need to introducebasic_const_pi
function or thebasic_add
function respectively.
I was able to achieve the first 3 points mentioned above and will be addressing the 4th point soon. Hence we currently have the following.
(lf) anutosh491@spbhat68:~/lpython/lpython$ cat examples/expr2.py
from lpython import S
from sympy import pi
def main0():
x: S = pi
main0()
(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --show-asr --pass=symbolic examples/expr2.py
(TranslationUnit
(SymbolTable
1
{
__main__:
(Module
(SymbolTable
2
{
.....
basic_new_stack:
(Function
(SymbolTable
6
{
x:
(Variable
6
x
[]
In
()
()
Default
(CPtr)
()
BindC
Public
Required
.true.
)
})
basic_new_stack
(FunctionType
[(CPtr)]
()
BindC
Interface
"basic_new_stack"
.false.
.false.
.false.
.false.
.false.
[]
.false.
)
[]
[(Var 6 x)]
[]
()
Public
.false.
.false.
"symengine/cwrapper.h"
),
main0:
(Function
(SymbolTable
3
{
_x:
(Variable
3
_x
[]
Local
()
()
Default
(Integer 8)
()
Source
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]
[]
[(=
(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 x)
(IntrinsicFunction
SymbolicPi
[]
0
(SymbolicExpression)
()
)
()
)]
()
Public
.false.
.false.
()
)
})
__main__
[]
.false.
.false.
)
As y’all can see, after addressing the 4th point, block 1 would be converted to block 2.
# block 1
(=
(Var 3 x)
(IntrinsicFunction
SymbolicPi
[]
0
(SymbolicExpression)
()
)
()
)
# block 2
(SubroutineCall
2 basic_const_pi
()
[((Var 12 x))]
()
)
Once, the above functionality has been added, the symbolic ASR pass should be in a good position and after some testing and refactoring the first Pull Request should be ready. I would like to thank Thirumalai Shaktivel, a fellow experienced contributor who has been helping me extensively with all my doubts and helping me out whenever I face any blocker.
Talking about my plans for the next week.
- Have a concrete implementation for the pass we discussed in this blog.
Thank You for going through the blog. I hope you like it. Stick around for what’s next to come. Moving into Week 11!