stencil_code is based on ctree for more information on ctree see ctree on github.
pip install stencil_code
Check out the benchmarks folders for some performance tests you can run on our own machine. Here are the results on a MacBookPro 10,1 with the following specs.
- Processor 2.7 GHz Intel Core i7
- Memory 16 GB 1600 MHz DDR3
- Graphics NVIDIA GeForce GT 650M 1024 MB
Numpy convolve avg: 0.0370276
Specialized C with compile time avg: 0.1326465
Specialized C time avg without compile 0.0130333
Specialized OpenMP with compile time avg: 0.1278614
Specialized OpenMP time avg without compile 0.0125139
Specialized OpenCL with compile time avg: 0.0293867
Specialized OpenCL time avg without compile 0.0084686
class SimpleKernel(StencilKernel): @property def dim(self): return 2
@property
def ghost_depth(self):
return 1
def neighbors(self, pt, defn=0):
if defn == 0:
for x in range(-radius, radius+1):
for y in range(-radius, radius+1):
yield (pt[0] - x, pt[1] - y)
def kernel(self, in_grid, out_grid):
for x in self.interior_points(out_grid):
for y in self.neighbors(x, 0):
out_grid[x] += in_grid[y]
kernel = SimpleKernel() width = 1024 in_grid = numpy.rand(width).astype(numpy.float32) * 1000
out_grid = kernel(in_grid)
<a name='bilateralfilter'/>
### A bilateral filter
```python
import numpy
from stencil_code.stencil_kernel import StencilKernel
width = int(sys.argv[2])
height = int(sys.argv[3])
image_in = open(sys.argv[1], 'rb')
stdev_d = 3
stdev_s = 70
radius = stdev_d * 3
class BilatKernel(StencilKernel):
@property
def dim(self):
return 2
@property
def ghost_depth(self):
return radius
def neighbors(self, pt, defn=0):
if defn == 1:
for x in range(-radius, radius+1):
for y in range(-radius, radius+1):
yield (pt[0] - x, pt[1] - y)
def kernel(self, in_img, filter_d, filter_s, out_img):
for x in self.interior_points(out_img):
for y in self.neighbors(x, 1):
out_img[x] += in_img[y] * filter_d[
int(distance(x, y))] * \
filter_s[abs(int(in_img[x] - in_img[y]))]
def gaussian(stdev, length):
result = StencilGrid([length])
scale = 1.0/(stdev*math.sqrt(2.0*math.pi))
divisor = -1.0 / (2.0 * stdev * stdev)
for x in range(length):
result[x] = scale * math.exp(float(x) * float(x) * divisor)
return result
# Instantiate a kernel
kernel = BilatKernel()
# Get some input data
in_grid = numpy.random(width, height).astype(numpy.float32) * 255
# Create our filters
gaussian1 = gaussian(stdev_d, radius*2)
gaussian2 = gaussian(stdev_s, 256)
out_grid = kernel(in_grid, gaussian1, gaussian2)