Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with performance using dpnp #1363

Open
mvyasank opened this issue Apr 3, 2023 · 0 comments
Open

Issue with performance using dpnp #1363

mvyasank opened this issue Apr 3, 2023 · 0 comments

Comments

@mvyasank
Copy link

mvyasank commented Apr 3, 2023

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()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant