Jupyter Notebook 2: Falling back to NumPy

Data Parallel Extensions for Python are still in active development and have not yet reached production quality. This in particular means that some functional and performance gaps may exist in certain dpnp functions that require workarounds. The functional gaps include:

  • Certain NumPy APIs are not supported. For complete reference please see the comparison table for Data Parallel Extension for NumPy.

  • Limited support of dtypes. At present the Data Parallel Extension for NumPy supports float32, float64, int32, and int64 types.

  • Certain keyword arguments are supported for default settings only. Please refer to the Data Parallel Extension for NumPy API Reference for details.

Since NumPy API is versatily there are typically some workaround options exist. Please refer to Data Parallel Extension for NumPy API Reference and NumPy documentation for hints for possible alternatives.

Another possible workaround is to fall back to the host and execute the script via NumPy. This is a discouraged use because it typically results in significant performance penalties associated with copying data from the device to the host and back. However, for debugging purposes you may still want to enable this behavior.

To do so you must set the DPNP_RAISE_EXCEPION_ON_NUMPY_FALLBACK environment variable to 0.

Let’s take the following example:

[3]:
import dpnp
import numpy

N = 200*100

# Create an two dimencial array with singular element and array like option
a_np = numpy.full((N, N), 3., like = numpy.zeros((N, 0)))
print(a_np)
a_dp = dpnp.full((N, N), 3., like = dpnp.zeros((N, 0)))
print(a_dp)
[[3. 3. 3. ... 3. 3. 3.]
 [3. 3. 3. ... 3. 3. 3.]
 [3. 3. 3. ... 3. 3. 3.]
 ...
 [3. 3. 3. ... 3. 3. 3.]
 [3. 3. 3. ... 3. 3. 3.]
 [3. 3. 3. ... 3. 3. 3.]]
---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
Cell In[3], line 9
      7 a_np = numpy.full((N, N), 3., like = numpy.zeros((N, 0)))
      8 print(a_np)
----> 9 a_dp = dpnp.full((N, N), 3., like = dpnp.zeros((N, 0)))
     10 print(a_dp)

File ~\AppData\Local\Continuum\miniconda3\envs\ndpex-examples\lib\site-packages\dpnp\dpnp_iface_arraycreation.py:747, in full(shape, fill_value, dtype, order, like, device, usm_type, sycl_queue)
    738 else:
    739     return dpnp_container.full(shape,
    740                                fill_value,
    741                                dtype=dtype,
   (...)
    744                                usm_type=usm_type,
    745                                sycl_queue=sycl_queue)
--> 747 return call_origin(numpy.full, shape, fill_value, dtype, order, like=like)

File dpnp\dpnp_utils\dpnp_algo_utils.pyx:132, in dpnp.dpnp_utils.dpnp_algo_utils.call_origin()

NotImplementedError: Requested funtion=full with args=((20000, 20000), 3.0, None, 'C') and kwargs={'like': array([])} isn't currently supported and would fall back on NumPy implementation. Define enviroment variable `DPNP_RAISE_EXCEPION_ON_NUMPY_FALLBACK` to `0` if the fall back is required to be supported without rasing an exception.

We are attempting to call dpnp.full() function with the keyword argument like set to another dpnp array, which is currently unsupported. A possible alternative would be to use dpnp.full_like function:

[4]:
from time import time

t = time()
a = dpnp.full_like(dpnp.zeros((N, 0)), 3., shape=(N, N))
print(f"Elapsed {(time()-t)*1000:.2f} ms")
print(a)
print("Array a is located on the device:", a.device)
Elapsed 1494.33 ms
[[3. 3. 3. ... 3. 3. 3.]
 [3. 3. 3. ... 3. 3. 3.]
 [3. 3. 3. ... 3. 3. 3.]
 ...
 [3. 3. 3. ... 3. 3. 3.]
 [3. 3. 3. ... 3. 3. 3.]
 [3. 3. 3. ... 3. 3. 3.]]
Array a is located on the device: Device(level_zero:gpu:0)

Now we enable DPNP_RAISE_EXCEPION_ON_NUMPY_FALLBACK to fall back to NumPy in case of NotImplementedError.

Note: Restart Jupyter Notebook kernel before running the following code

[1]:
import os
os.environ["DPNP_RAISE_EXCEPION_ON_NUMPY_FALLBACK"] = "0"

import dpnp as np
print ("DPNP_RAISE_EXCEPION_ON_NUMPY_FALLBACK =", np.config.__DPNP_RAISE_EXCEPION_ON_NUMPY_FALLBACK__)  # Expect 0

from time import time

N = 200*100

t = time()
a = np.full((N, N), 3., like = np.zeros((N, 0)))
print(f"Elapsed {(time()-t)*1000:.2f} ms")
print(a)
print("Array a is located on the device:", a.device)
DPNP_RAISE_EXCEPION_ON_NUMPY_FALLBACK = 0
Elapsed 2231.62 ms
[[3. 3. 3. ... 3. 3. 3.]
 [3. 3. 3. ... 3. 3. 3.]
 [3. 3. 3. ... 3. 3. 3.]
 ...
 [3. 3. 3. ... 3. 3. 3.]
 [3. 3. 3. ... 3. 3. 3.]
 [3. 3. 3. ... 3. 3. 3.]]
Array a is located on the device: Device(level_zero:gpu:0)