This notebook contains a demonstration of new features present in the 0.46.0 release of Numba. Whilst release notes are produced as part of the CHANGE_LOG
, there's nothing like seeing code in action! It should be noted that this release does not contain a huge amount of changes to user facing support. A lot of the changes to the code base this time around were to continue to enhance Numba's use as a compiler toolkit and add features for advanced users/developers.
Some exciting news... The Numba team finally started working on, the colloquially named, "scumba" project, to add SciPy support in Numba, the project is called numba-scipy
(it's expected that there may be other numba-XYZ
projects). This project also demonstrates a new feature added in this release, that Numba now has a formal way to register a project with Numba itself via an auto-discovery mechanism. Read more about this mechanism here. A demonstration of numba-scipy
appears later in this notebook.
For users of Numba, demonstrations of new features include:
In addition, predominantly for library developers/compiler engineers, new features include:
'inline'
kwarg to both the @numba.jit
family of decorators and @numba.extending.overload
.jit
application.These are demonstrated in a separate notebook here.
First, import the necessary from Numba and NumPy...
from numba import jit, njit, config, __version__, errors
from numba.extending import overload
import numba
import numpy as np
assert tuple(int(x) for x in __version__.split('.')[:2]) >= (0, 46)
As noted above, the 0.46 release cycle saw the Numba core developers start work on a new community driven project called numba-scipy
. This project adds support for using SciPy functions in Numba JIT'd code, at present it's in its very infancy but, with thanks to external contributors, some functionality is already present (docs are here). Below is an example of using scipy.special.*
functions in JIT code.
from scipy import special
@njit
def call_scipy_in_jitted_code():
print("special.beta(1.2, 3.4)", special.beta(1.2, 3.4))
print("special.j0(5.6) ", special.j0(5.6))
call_scipy_in_jitted_code()
The above also nicely highlights the automatic extension registration working (docs are here), note how numba-scipy
did not need to be imported to make use of the scipy.special
functions, all that was needed was to install numba-scipy
package in the current Python environment.
It should be noted that contributions to numba-scipy
are welcomed, a good place to start is the contributing guide to get set up and then the guide to @overload
ing.
This release contains a number of newly supported NumPy functions, all written by contributors from the Numba community:
np.cross
is added along with the extension numba.numpy_extensions.cross2d
for cases where both inputs have shape[-1] == 2
.np.array_equal
is now supported.np.count_nonzero
np.append
np.triu_indices
np.tril_indices
np.triu_indices_from
np.tril_indices_from
A quick demo of the above:
from numba import numpy_extensions
@njit
def numpy_new():
arr = np.array([[0, 2], [3 ,0]])
# np.count_nonzero
print("np.count_nonzero:\n", np.count_nonzero(arr))
# np.append
print("np.append:\n", np.append(arr, arr))
# np.array_equal
print("np.array_equal:\n", np.array_equal(arr, arr))
# np.tri{u,l}_indices
print("np.triu_indices:\n",np.triu_indices(4, k=2))
print("np.tril_indices:\n",np.tril_indices(3, k=2))
# np.tri{u,l}_indices_from
print("np.triu_indices_from:\n",np.triu_indices_from(arr, k=0))
print("np.tril_indices_from:\n",np.tril_indices_from(arr, k=2))
# np.cross
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([[4, 5, 6], [1, 2, 3]])
print("np.cross", np.cross(a, b))
# np.cross, works fine unless `shape[-1] == 2` for both inputs
# where it becomes impossible to statically determine the shape
# of the return type, in this case replace `np.cross` with the
# `numba.numpy_extensions.cross2d` function. e.g.
c = np.array([[1, 2], [4, 5]])
d = np.array([[4, 5], [1, 2]])
print("numpy_extensions.cross2d", numpy_extensions.cross2d(c, d))
numpy_new()
dtype
support in np.sum
¶Numba 0.46 has support added for the dtype
kwarg in np.sum
and np.ndarray.sum
, this has been repeatedly requested and was kindly implemented by a member of the Numba community. A quick demo:
@njit
def np_sum_demo():
x = np.arange(10)
x_sum = x.sum(dtype=np.complex128)
y = np.arange(24).reshape((4, 6)).astype(np.uint8)
y_sum = np.sum(y, axis=1, dtype=np.uint16)
return (x_sum, y_sum)
print(np_sum_demo())
With thanks to another contributor from the Numba community, Numba can now consume and operate on NumPy arrays with a unicode dtype.
from numba.typed import List
@njit
def unicode_array_demo(arr):
acc = List()
for i in (13, 20, 12, 1, 0, 28, 8, 18, 28, 27, 26):
acc.append(str(arr[i]))
return ''.join(acc)
arr = np.array([chr(x) for x in range(ord('a'), ord('a') + 26)] + ['⚡', '🐍', chr(32)])
unicode_array_demo(arr)
Some new features were added that don't fit anywhere in particular but are still very useful...
Just one in this section for 0.46, .count()
is supported on Unicode strings (also contributed by a Numba community member!).
@njit
def demo_misc():
print("n🐍u🐍m🐍b🐍a⚡".count("🐍")) # count the snakes
demo_misc()