diff --git a/docs/source/reference/deprecation.rst b/docs/source/reference/deprecation.rst index 84b3589af2f..4df3c489198 100644 --- a/docs/source/reference/deprecation.rst +++ b/docs/source/reference/deprecation.rst @@ -1,3 +1,5 @@ +.. _deprecation: + =================== Deprecation Notices =================== diff --git a/docs/source/reference/pysupported.rst b/docs/source/reference/pysupported.rst index 500bca2ded1..7aaef2a6682 100644 --- a/docs/source/reference/pysupported.rst +++ b/docs/source/reference/pysupported.rst @@ -214,6 +214,16 @@ The following operations are supported: list ---- + +.. warning:: + As of version 0.45.x the internal implementation for the list datatype in + Numba is changing. Until recently, only a single implementation of the list + datatype was available, the so-called *reflected-list* (see below). + However, it was scheduled for deprecation from version 0.44.0 onwards due + to its limitations. As of version 0.45.0 a new implementation, the + so-called *typed-list* (see below), is available as an experimental + feature. For more information, please see: :ref:`deprecation`. + Creating and returning lists from JIT-compiled functions is supported, as well as all methods and operations. Lists must be strictly homogeneous: Numba will reject any list containing objects of different types, even if @@ -260,6 +270,78 @@ of this limitation. List sorting currently uses a quicksort algorithm, which has different performance characterics than the algorithm used by Python. +Typed List +'''''''''' + +.. note:: + ``numba.typed.List`` is an experimental feature, if you encounter any bugs in + functionality or suffer from unexpectedly bad performance, please report + this, ideally by opening an issue on the Numba issue tracker. + +As of version 0.45.0 a new implementation of the list data type is available, +the so-called *typed-list*. This is compiled library backed, type-homogeneous +list data type that is an improvement over the *reflected-list* mentioned +above. Additionally, lists can now be arbitrarily nested. Since the +implementation is considered experimental, you will need to import it +explicitly from the `numba.typed` module:: + + In [1]: from numba.typed import List + + In [2]: from numba import njit + + In [3]: @njit + ...: def foo(l): + ...: l.append(23) + ...: return l + ...: + + In [4]: mylist = List() + + In [5]: mylist.append(1) + + In [6]: foo(mylist) + Out[6]: ListType[int64]([1, 23]) + + +.. note:: + As the typed-list stabilizes it will fully replace the reflected-list and the + constructors `[]` and `list()` will create a typed-list instead of a + reflected one. + + +Here's an example using ``List()`` to create ``numba.typed.List`` inside a +jit-compiled function and letting the compiler infer the item type: + +.. literalinclude:: ../../../examples/typed_list_usage.py + :language: python + :caption: from ``ex_inferred_list_jit`` of ``examples/typed_list_usage.py`` + :start-after: magictoken.ex_inferred_list_jit.begin + :end-before: magictoken.ex_inferred_list_jit.end + :dedent: 4 + :linenos: + +Here's an example of using ``List()`` to create a ``numba.typed.List`` outside of +a jit-compiled function and then using it as an argument to a jit-compiled +function: + +.. literalinclude:: ../../../examples/typed_list_usage.py + :language: python + :caption: from ``ex_inferred_list`` of ``examples/typed_list_usage.py`` + :start-after: magictoken.ex_inferred_list.begin + :end-before: magictoken.ex_inferred_list.end + :dedent: 4 + :linenos: + +Finally, here's an example of using a nested `List()`: + +.. literalinclude:: ../../../examples/typed_list_usage.py + :language: python + :caption: from ``ex_nested_list`` of ``examples/typed_list_usage.py`` + :start-after: magictoken.ex_nested_list.begin + :end-before: magictoken.ex_nested_list.end + :dedent: 4 + :linenos: + .. _pysupported-comprehension: List comprehension diff --git a/examples/typed_list_usage.py b/examples/typed_list_usage.py new file mode 100644 index 00000000000..88f37fa5374 --- /dev/null +++ b/examples/typed_list_usage.py @@ -0,0 +1,75 @@ +# Contents in this file are referenced from the sphinx-generated docs. +# "magictoken" is used for markers as beginning and ending of example text. + + +def ex_inferred_list_jit(): + # magictoken.ex_inferred_list_jit.begin + from numba import njit + from numba.typed import List + + @njit + def foo(): + # Instantiate a typed-list + l = List() + # Append a value to it, this will set the type to int32/int64 (depending on platform) + l.append(42) + # The usual list operations, getitem, pop and length are supported + print(l[0]) # 42 + l[0] = 23 + print(l[0]) # 23 + print(len(l)) # 1 + l.pop() + print(len(l)) # 0 + return l + + mylist = foo() + + # magictoken.ex_inferred_list_jit.end + + +def ex_inferred_list(): + # magictoken.ex_inferred_list.begin + from numba import njit + from numba.typed import List + + @njit + def foo(mylist): + for i in range(10, 20): + mylist.append() + return mylist + + # Instantiate a typed-list, outside of a jit context + l = List() + # Append a value to it, this will set the type to int32/int64 (depending on platform) + l.append(42) + # The usual list operations, getitem, pop and length are supported + print(l[0]) # 42 + l[0] = 23 + print(l[0]) # 23 + print(len(l)) # 1 + l.pop() + print(len(l)) # 0 + + # And you can use the typed-list as an argument for a jit compiled function + + l = foo(l) + print(len(l)) # 10 + + # magictoken.ex_inferred_list.end + + +def ex_nested_list(): + # magictoken.ex_nested_list.begin + from numba.typed import List + + # typed-lists can be nested in typed-lists + mylist = List() + for i in range(10): + l = List() + for i in range(10): + l.append(i) + mylist.append(l) + # mylist is now a list of 10 lists, each containing 10 integers + print(mylist) + + # magictoken.ex_nested_list.end