dpnp
dpnp copied to clipboard
Issue with performance using dpnp
The code on the dpnp using gpu or cpu devices is slower that using numpy library. But should be faster. dpnp - Device(level_zero:gpu:0) 540 ms ± 32.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) dpnp - Device(opencl:gpu:0) 731 ms ± 77.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) dpnp - Device(opencl:cpu:0) 660 ms ± 36.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) numpy 290 ms ± 16.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) The code on the dpnp:
DISPLAY_W, DISPLAY_H = 800, 600
OFFSET_X = 1.4*DISPLAY_W//2
OFFSET_Y = DISPLAY_H//2
ZOOM = 2.5/DISPLAY_H
MAX_ITER = 30
import os
os.environ["SYCL_DEVICE_FILTER"] = "level_zero:gpu"
#os.environ["SYCL_DEVICE_FILTER"] = "opencl:gpu"
#os.environ["SYCL_DEVICE_FILTER"] = "cpu"
import dpnp as np
def color_by_intensity(intensity):
c1 = np.asarray([0.0, 0.0, 0.2])
c2 = np.asarray([1.0, 0.7, 0.9])
c3 = np.asarray([0.6, 1.0, 0.2])
intensity = np.broadcast_to(intensity[:, :, np.newaxis], intensity.shape + (3,))
return np.where(intensity < 0.5, c3*intensity + c2*(1.0-intensity), c1*intensity + c2*(1.0-intensity))
def mandelbrot(x, y, zoom):
xx = (x - OFFSET_X) * zoom
yy = (y - OFFSET_Y) * zoom
c = xx + 1j * yy[:, np.newaxis]
n_iter = np.full(c.shape, 0, dtype=np.int32) # 2d array
z = np.zeros(c.shape, dtype=np.complex64) # 2d array too
mask = (n_iter < MAX_ITER) # Initialize with True
for i in range(MAX_ITER):
z[mask] = z[mask]**2 + c[mask]
mask = mask & (np.abs(z) <= 2.0)
n_iter[mask] = i
intensity = n_iter.T / MAX_ITER
values = (color_by_intensity(intensity)*255).astype(np.int32)
return values
import matplotlib.pyplot as plt
%matplotlib inline
class Fractal:
def __init__(self, zoom):
self.values = np.full((DISPLAY_W, DISPLAY_H, 3), 0, dtype=np.int32)
self.zoom = zoom
self.x = np.linspace(0, DISPLAY_W, num=DISPLAY_W, dtype=np.float32)
self.y = np.linspace(0, DISPLAY_H, num=DISPLAY_H, dtype=np.float32)
print (self.x.device)
def calculate(self):
self.values = mandelbrot(self.x, self.y, self.zoom)
def draw(self):
cpu_values = np.asnumpy(self.values)
plt.imshow(cpu_values)
def main():
fractal = Fractal(ZOOM)
%timeit fractal.calculate()
fractal.draw()
if __name__ == "__main__":
main()
The same code using numpy:
DISPLAY_W, DISPLAY_H = 800, 600
OFFSET_X = 1.4*DISPLAY_W//2
OFFSET_Y = DISPLAY_H//2
ZOOM = 2.5/DISPLAY_H
MAX_ITER = 30
import numpy as np
def color_by_intensity(intensity):
c1 = np.asarray([0.0, 0.0, 0.2])
c2 = np.asarray([1.0, 0.7, 0.9])
c3 = np.asarray([0.6, 1.0, 0.2])
intensity = np.broadcast_to(intensity[:, :, np.newaxis], intensity.shape + (3,))
return np.where(intensity < 0.5, c3*intensity + c2*(1.0-intensity), c1*intensity + c2*(1.0-intensity))
def mandelbrot(x, y, zoom):
xx = (x - OFFSET_X) * zoom
yy = (y - OFFSET_Y) * zoom
c = xx + 1j * yy[:, np.newaxis]
n_iter = np.full(c.shape, 0) # 2d array
z = np.empty(c.shape, np.csingle) # 2d array too
mask = (n_iter < MAX_ITER) # Initialize with True
for i in range(MAX_ITER):
z[mask] = z[mask]**2 + c[mask]
mask = mask & (np.abs(z) <= 2.0)
n_iter[mask] = i
intensity = n_iter.T / MAX_ITER
values = (color_by_intensity(intensity)*255).astype(np.int32)
return values
import matplotlib.pyplot as plt
%matplotlib inline
class Fractal:
def __init__(self, zoom):
self.values = np.full((DISPLAY_W, DISPLAY_H, 3), 0, dtype=np.int32)
self.zoom = zoom
#self.need_recalculate = True
self.x = np.linspace(0, DISPLAY_W, num=DISPLAY_W, dtype=np.float32)
self.y = np.linspace(0, DISPLAY_H, num=DISPLAY_H, dtype=np.float32)
def calculate(self):
self.values = mandelbrot(self.x, self.y, self.zoom)
def draw(self):
plt.imshow(self.values)
def main():
fractal = Fractal(ZOOM)
%timeit fractal.calculate()
fractal.draw()
if __name__ == "__main__":
main()