import phylanx
from phylanx.ast import *
from phylanx.ast.utils import printout
import numpy as np
et = phylanx.execution_tree
# Step 1: Write PhySL code in PhySL
# but execute it with Python
result = et.eval("""
block(
define(fib,n,
if(n<2,n,
fib(n-1)+fib(n-2))),
fib)""",et.var(10))
print(result)
# Step 2: Write Python code that
# gets magically turned into PhySL code.
@Phylanx() # biuld with phylanx!
def foo():
print("hello") # normal code
return 1 # At the moment, it needs a valid return type
foo() # This worked, but the output looks obscure
foo()[0] # Extract the Python value
printout(foo()) # This also works.
import numpy as np
f = np.linspace(0,10,11) # create a simple numpy array
@Phylanx
def pr(a):
print(a) # This prints to the console, so we don't see it.
return a[1:5] # Slicing works
print("output")
print(f) # print the numpy array, we can pass it to phylanx
#print(pr(f)) # phy_print should know how to print arrays
# About the console issue... the problem is stdout doesn't go to the notebook.
import os
os.write(1,b'Hello, Console')
# You can access the source code like this.
# We have $ in the symbol names to identify line and column number.
print(foo.__physl_src__)
# Using regexes, we can make it more human readable
import re
print(re.sub(r'\$\d+','',foo.__physl_src__))
@Phylanx()
def fib(n):
if n < 2:
return n
f1 = fib(n-1)
f2 = fib(n-2)
return f1+f2 # Doesn't work, the underlying PhySL only supports a single return
@Phylanx()
def fib(n):
if n < 2:
return n
else:
return fib(n-1)+fib(n-2) # OK, if every switch in an if/elif/else block
# does a return, that counts as a single return
fib(8)[0]
@Phylanx()
def sw(s):
# if / elif /else works
if s == "hello":
return "hi"
elif s == "goodbye":
return "bye"
else:
return "?"
print(sw("goodbye"))
print(re.sub(r'\$\d+','',sw.__physl_src__))
@Phylanx()
def floop():
sum = 0
n = -1
for i in range(10,1,n): # Basic for loops work
sum += i
return sum
print(re.sub(r'\$\d+','',floop.__physl_src__))
print(floop())
@Phylanx()
def wloop():
sum = 0
i = 0
while i < 10: # basic while loops work
sum += i
i += 1
return sum
print(wloop())
import numpy as np
@Phylanx()
def ar():
return constant(0,10) # creation of phylanx arrays
print(ar())
assert ar() == np.zeros(10) # compare with numpy
@Phylanx()
def ar2(a):
return a[3:8]
print(ar2(np.linspace(0,10,11))) # you can pass numpy arrays
# %load ./examples/algorithms/lra_csv_phyfun.py
# Copyright (c) 2018 Steven R. Brandt
# Copyright (c) 2018 R. Tohid
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import phylanx
from phylanx.ast import *
from phylanx.ast.utils import printout
@Phylanx("PhySL")
def lra(file_name, xlo1, xhi1, ylo1, yhi1, xlo2, xhi2, ylo2, yhi2, alpha,
iterations, enable_output):
data = file_read_csv(file_name)
x = data[xlo1:xhi1, ylo1:yhi1]
y = data[xlo2:xhi2, ylo2:yhi2]
weights = constant(0.0, shape(x, 1))
transx = transpose(x)
pred = constant(0.0, shape(x, 0))
error = constant(0.0, shape(x, 0))
gradient = constant(0.0, shape(x, 1))
step = 0
while step < iterations:
if enable_output:
print("step: ", step, ", ", weights)
pred = 1.0 / (1.0 + exp(-dot(x, weights)))
error = pred - y
gradient = dot(transx, error)
weights = weights - (alpha * gradient)
step += 1
return weights
res = lra("breast_cancer.csv", 0, 569, 0, 30, 0, 569, 30, 31, 1e-5, 750, 0)
printout(res)
# %load ./examples/algorithms/lra_csv_phyfun_np.py
# Copyright (c) 2018 Steven R. Brandt
# Copyright (c) 2018 R. Tohid
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import phylanx
import numpy as np
from phylanx.ast import *
from phylanx.ast.utils import printout
@Phylanx("PhySL")
def lra(x, y, alpha, iterations, enable_output):
weights = constant(0.0, shape(x, 1))
transx = transpose(x)
pred = constant(0.0, shape(x, 0))
error = constant(0.0, shape(x, 0))
gradient = constant(0.0, shape(x, 1))
step = 0
while step < iterations:
if (enable_output):
print("step: ", step, ", ", weights)
pred = 1.0 / (1.0 + exp(-dot(x, weights)))
error = pred - y
gradient = dot(transx, error)
weights = weights - (alpha * gradient)
step += 1
return weights
file_name = "breast_cancer.csv"
data = np.genfromtxt(file_name, skip_header=1, delimiter=",")
x = data[:, :-1]
y = data[:, -1:]
y = y.reshape((y.shape[0], ))
res = lra(x, y, 1e-5, 750, 0)
printout(res)
Partial list of things that don't work yet.
</pre>
%%phylanx_cell
print("No function!")
for i in range(10):
print("i=",i+1)
# %load /home/sbrandt/.ipython/profile_default/startup/magics.py
from __future__ import print_function
from IPython.core.magic import (Magics, magics_class, line_magic,
cell_magic, line_cell_magic)
import ast,re,os
from threading import Thread
from phylanx.ast import *
def readfds(fd):
while True:
result=os.read(fd,1000)
print(result.decode('utf-8'),end='')
class IORedirecter:
def __init__(self):
self.fds = os.pipe()
self.threadReadFDs = Thread(target=readfds,args=(self.fds[0],))
self.threadReadFDs.start()
self.saveStdout = os.dup(1)
def __enter__(self):
os.close(1)
os.dup(self.fds[1])
def __exit__(self,type,value,traceback):
os.close(1)
os.dup(self.saveStdout)
iod = IORedirecter()
# The class MUST call this class decorator at creation time
@magics_class
class MyMagics(Magics):
@cell_magic
def phylanx_cell(self,line,cell=None):
tcell = 'def _cell_():\n '+re.sub('\n','\n ',cell)+'\n return 1'
tree = ast.parse(tcell)
physl = PhySL()
assert len(tree.body) == 1
self.__physl_src__ = '%s(%s)\n' % (
full_node_name(tree.body[0], 'block'), physl.recompile(tree))
with iod:
et.eval(self.__physl_src__)
ip = get_ipython()
ip.register_magics(MyMagics)