# coding: utf-8 # # Symbolic Image Filtering # In[1]: import pymbolic.primitives as p u_var = p.Variable("u") # Want to define an image filter. # # ---- # # To that end, define a new formula 'thing': A neighbor-average. # In[2]: class NeighborAverage(p.Expression): def __init__(self, child): self.child = child def __getinitargs__(self): return (self.child,) mapper_method = "map_neighbor_average" img_filter = NeighborAverage(u_var) #img_filter = u_var + u_var - NeighborAverage(u_var) img_filter # Let's define some indexing variables: # In[3]: from pymbolic.mapper import IdentityMapper i = p.Variable("i") j = p.Variable("j") ii = i+1 jj = j+1 # In[4]: class IndexMapper(IdentityMapper): def map_variable(self, expr): return expr[ii, jj] def map_neighbor_average(self, expr): var = expr.child return (2*var[ii,jj] + var[ii+1,jj] + var[ii-1,jj] + var[ii,jj+1] + var[ii,jj-1])/6 # Now apply this to our filter: # In[5]: idx_mapper = IndexMapper() print(idx_mapper(img_filter)) # ---- # # Now let's generate some code for this, using `loopy`: # In[6]: import loopy as lp result_var = p.Variable("result") # Observe the two parts of the `loopy` kernel description: # # * Polyhedral loop domain # * Instructions `[lp.ExpressionInstruction()]` # In[7]: knl = lp.make_kernel( "{[i,j]: 0<=i,j