{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Numba 0.54.0 Release Demo\n", "\n", "This notebook contains a demonstration of new features present in the 0.54.0 release of Numba. Whilst release notes are produced as part of the [CHANGE_LOG](https://github.com/numba/numba/blob/release0.54/CHANGE_LOG), there's nothing like seeing code in action!\n", "\n", "This release contains a lot of things including new features, updated library support and large scale internal changes/enhancements to permit extending Numba to new targets. In this notebook, the new CPU target features are demonstrated. The [CUDA target](https://numba.pydata.org/numba-doc/latest/cuda/index.html) also gained a lot of new features in 0.54.0 and [@gmarkall](https://github.com/gmarkall) has created a [demo notebook](https://mybinder.org/v2/gh/numba/numba-examples/master?filepath=notebooks%2FNumba_054_CUDA_Release_Demo.ipynb) especially for these!\n", "\n", "Key internal/support changes in this release are:\n", "\n", "- NumPy support is restricted to (1.17 <= x < 1.21).\n", "- Python 3.7 is the new minimum version of Python accepted.\n", "- Intel TBB 2021 is now supported and the new minimum version of TBB.\n", "- The LLVM backend has been upgraded to version 11.\n", "- Numba has directly vendored cloudpickle into its code base for use with caching and object mode.\n", "\n", "Intel also kindly sponsored research and development that lead to three new features:\n", "\n", "- Target extension support.\n", "- Custom NumPy array subclass support.\n", "- Context managed retargeting of the dispatcher." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Python support enhancements" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from numba import njit\n", "import numba\n", "assert numba.version_info.short >= (0, 54)\n", "from numba.core import types\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Numba 0.54 gains some basic `f-string` support ([@ehsantn](https://github.com/ehsantn)) and support for dictionary comprehensions ([@stuartarchibald](https://github.com/stuartarchibald))." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "@njit\n", "def demo_fstring_dict_comp():\n", " return {x: f'string_{x * 10}' for x in range(5)}\n", "\n", "demo_fstring_dict_comp()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It also gains support for the ``sum`` builtin ([@stuartarchibald](https://github.com/stuartarchibald))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "@njit\n", "def demo_sum():\n", " return sum([1, 2, 3]), sum((4, 5, 6)), sum((1j, 3, np.float64(7)))\n", " \n", "demo_sum()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and the ability to `hash()` `IntEnum`s ([@HPLegion](https://github.com/HPLegion))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from enum import IntEnum\n", "\n", "class Scale(IntEnum):\n", " C4 = 261\n", " D4 = 293\n", " E4 = 329\n", " F4 = 349\n", " G4 = 391\n", " A4 = 440\n", "\n", "@njit\n", "def demo_intenum_hash():\n", " return hash(Scale.D4), {Scale.C4: 'Middle C'}[Scale.C4]\n", "\n", "demo_intenum_hash()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## NumPy support enhancements\n", "\n", "Numba 0.54 contains support for some more NumPy functions:\n", "\n", "* ``np.clip`` ([@arvoelke](https://github.com/arvoelke), [@gmarkall](https://github.com/gmarkall))\n", "* ``np.rot90`` ([@braniii](https://github.com/braniii))\n", "* ``np.swapaxes`` ([@braniii](https://github.com/braniii))\n", "* ``np.random.dirichlet`` ([@rishi-kulkarni](https://github.com/rishi-kulkarni))\n", "* ``np.isreal`` ([@guilhermeleobas](https://github.com/guilhermeleobas))\n", "* ``np.iscomplex`` ([@guilhermeleobas](https://github.com/guilhermeleobas))\n", "* ``np.isrealobj`` ([@guilhermeleobas](https://github.com/guilhermeleobas))\n", "* ``np.iscomplexobj`` ([@guilhermeleobas](https://github.com/guilhermeleobas))\n", "* ``np.isscalar`` ([@guilhermeleobas](https://github.com/guilhermeleobas))\n", "* ``np.isneginf`` ([@guilhermeleobas](https://github.com/guilhermeleobas))\n", "* ``np.isposinf`` ([@guilhermeleobas](https://github.com/guilhermeleobas))\n", "\n", "and also enhances the support for:\n", "\n", "* ``np.argmax()`` now supports the `axis` kwarg ([@itamarst](https://github.com/itamarst))\n", "* ``__setitem__`` using ``0d`` arrays ([@guilhermeleobas](https://github.com/guilhermeleobas))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from numba import literal_unroll\n", "\n", "@njit\n", "def demo_numpy_new_features():\n", " x = np.linspace(0, 10, 20)\n", " print(\"np.clip\\n\", np.clip(x, 2., 5.))\n", " print(\"np.rot90\\n\", np.rot90(np.arange(4).reshape((2, 2))))\n", " print(\"np.swapaxes\\n\", np.swapaxes(np.arange(8).reshape((2, 2, 2)), 0, 2))\n", "\n", " np.random.seed(0)\n", " print(\"np.random.dirichlet\\n\", np.random.dirichlet((2, 3, 4), 2))\n", "\n", " for x in literal_unroll((1, 1j, np.array([1, 2j, 3]))):\n", " print(\"x is \", x)\n", " print(\" np.iscomplexobj(x)\", np.iscomplexobj(x))\n", " print(\" np.isreal(x)\", np.isreal(x))\n", " print(\" np.isrealobj(x)\", np.isrealobj(x))\n", " print(\" np.isscalar(x)\", np.isscalar(x))\n", " for x in literal_unroll((1, np.inf, -np.inf, np.nan)):\n", " print(\"x is \", x)\n", " print(\" np.isneginf(x)\", np.isneginf(x))\n", " print(\" np.isposinf(x)\", np.isposinf(x))\n", " print(\" np.iscomplex(x)\", np.iscomplex(x))\n", " \n", "demo_numpy_new_features()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Enhancements:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "@njit\n", "def demo_numpy_enhancements():\n", " # Axis support in np.argmax\n", " x = np.arange(12).reshape((3, 2, 2))\n", " x[:, 1, :] = 100\n", " print(\"np.argmax(x, axis=2)\\n\", np.argmax(x, axis=2))\n", " \n", " # Setitem using 0d arrays\n", " idx = np.array(1)\n", " x = np.arange(10)\n", " x[idx] = 100\n", " print(\"Setitem of x[idx]\\n\", x, \", idx =\", idx, \", idx.ndim =\", idx.ndim)\n", " \n", "demo_numpy_enhancements()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "----\n", "\n", "## See Also\n", "\n", "- [0.54 CUDA Demo](https://mybinder.org/v2/gh/numba/numba-examples/master?filepath=notebooks%2FNumba_054_CUDA_Release_Demo.ipynb)\n", "- [0.54 `overload_classmethod` and Array Subclass Demo](https://mybinder.org/v2/gh/numba/numba-examples/master?filepath=notebooks%2FNumba_054_overload_classmethod_array_subclass.ipynb)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.5" } }, "nbformat": 4, "nbformat_minor": 4 }