Skip to content

Issue with performance using dpnp #1363

Open

Description

@mvyasank

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()

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions