Commit 1fb0017a authored by dugupeiwen's avatar dugupeiwen
Browse files

init 0.58

parents
.. _deprecation:
===================
Deprecation Notices
===================
This section contains information about deprecation of behaviours, features and
APIs that have become undesirable/obsolete. Any information about the schedule
for their deprecation and reasoning behind the changes, along with examples, is
provided. However, first is a small section on how to suppress deprecation
warnings that may be raised from Numba so as to prevent warnings propagating
into code that is consuming Numba.
.. _suppress_deprecation_warnings:
Suppressing Deprecation warnings
================================
All Numba deprecations are issued via ``NumbaDeprecationWarning`` or
``NumbaPendingDeprecationWarning`` s, to suppress the reporting of
these the following code snippet can be used::
from numba.core.errors import NumbaDeprecationWarning, NumbaPendingDeprecationWarning
import warnings
warnings.simplefilter('ignore', category=NumbaDeprecationWarning)
warnings.simplefilter('ignore', category=NumbaPendingDeprecationWarning)
The ``action`` used above is ``'ignore'``, other actions are available, see
`The Warnings Filter <https://docs.python.org/3/library/warnings.html#the-warnings-filter>`_
documentation for more information.
.. note:: It is **strongly recommended** that applications and libraries which
choose to suppress these warnings should pin their Numba dependency
to a suitable version because their users will no longer be aware of
the coming incompatibility.
Deprecation of reflection for List and Set types
================================================
Reflection (:term:`reflection`) is the jargon used in Numba to describe the
process of ensuring that changes made by compiled code to arguments that are
mutable Python container data types are visible in the Python interpreter when
the compiled function returns. Numba has for some time supported reflection of
``list`` and ``set`` data types and it is support for this reflection that
is scheduled for deprecation with view to replace with a better implementation.
Reason for deprecation
----------------------
First recall that for Numba to be able to compile a function in ``nopython``
mode all the variables must have a concrete type ascertained through type
inference. In simple cases, it is clear how to reflect changes to containers
inside ``nopython`` mode back to the original Python containers. However,
reflecting changes to complex data structures with nested container types (for
example, lists of lists of integers) quickly becomes impossible to do
efficiently and consistently. After a number of years of experience with this
problem, it is clear that providing this behaviour is both fraught with
difficulty and often leads to code which does not have good performance (all
reflected data has to go through special APIs to convert the data to native
formats at call time and then back to CPython formats at return time). As a
result of this, the sheer number of reported problems in the issue tracker, and
how well a new approach that was taken with ``typed.Dict`` (typed dictionaries)
has gone, the core developers have decided to deprecate the noted ``reflection``
behaviour.
Example(s) of the impact
------------------------
At present only a warning of the upcoming change is issued. In future code such
as::
from numba import njit
@njit
def foo(x):
x.append(10)
a = [1, 2, 3]
foo(a)
will require adjustment to use a ``typed.List`` instance, this typed container
is synonymous to the :ref:`feature-typed-dict`. An example of translating the
above is::
from numba import njit
from numba.typed import List
@njit
def foo(x):
x.append(10)
a = [1, 2, 3]
typed_a = List()
[typed_a.append(x) for x in a]
foo(typed_a)
For more information about ``typed.List`` see :ref:`feature-typed-list`. Further
usability enhancements for this feature were made in the 0.47.0 release
cycle.
Schedule
--------
This feature will be removed with respect to this schedule:
* Pending-deprecation warnings will be issued in version 0.44.0
* Prominent notice will be given for a minimum of two releases prior to full
removal.
Recommendations
---------------
Projects that need/rely on the deprecated behaviour should pin their dependency
on Numba to a version prior to removal of this behaviour, or consider following
replacement instructions that will be issued outlining how to adjust to the
change.
Expected Replacement
--------------------
As noted above ``typed.List`` will be used to permit similar functionality to
reflection in the case of ``list`` s, a ``typed.Set`` will provide the
equivalent for ``set`` (not implemented yet!). The advantages to this approach
are:
* That the containers are typed means type inference has to work less hard.
* Nested containers (containers of containers of ...) are more easily
supported.
* Performance penalties currently incurred translating data to/from native
formats are largely avoided.
* Numba's ``typed.Dict`` will be able to use these containers as values.
Deprecation of :term:`object mode` `fall-back` behaviour when using ``@jit``
============================================================================
The ``numba.jit`` decorator has for a long time followed the behaviour of first
attempting to compile the decorated function in :term:`nopython mode` and should
this compilation fail it will `fall-back` and try again to compile but this time
in :term:`object mode`. It is this `fall-back` behaviour which is being
deprecated, the result of which will be that ``numba.jit`` will by default
compile in :term:`nopython mode` and :term:`object mode` compilation will
become `opt-in` only.
.. note::
It is relatively common for the ``numba.jit`` decorator to be used within
other decorators to provide an easy path to compilation. Due to this change,
deprecation warnings may be raised from such call sites. To avoid these
warnings, it's recommended to either
:ref:`suppress them <suppress_deprecation_warnings>` if the application does
not rely on :term:`object mode` `fall-back` or to check the documentation
for the decorator to see how to pass application appropriate options through
to the wrapped ``numba.jit`` decorator. An example of this within the Numba
API would be ``numba.vectorize``. This decorator simply forwards keyword
arguments to the internal ``numba.jit`` decorator call site such that e.g.
``@vectorize(nopython=True)`` would be an appropriate declaration for a
``nopython=True`` mode use of ``@vectorize``.
Reason for deprecation
----------------------
The `fall-back` has repeatedly caused confusion for users as seemingly innocuous
changes in user code can lead to drastic performance changes as code which may
have once compiled in :term:`nopython mode` mode may silently switch to
compiling in :term:`object mode` e.g::
from numba import jit
@jit
def foo():
l = []
for x in range(10):
l.append(x)
return l
foo()
assert foo.nopython_signatures # this was compiled in nopython mode
@jit
def bar():
l = []
for x in range(10):
l.append(x)
return reversed(l) # innocuous change, but no reversed support in nopython mode
bar()
assert not bar.nopython_signatures # this was not compiled in nopython mode
Another reason to remove the `fall-back` is that it is confusing for the
compiler engineers developing Numba as it causes internal state problems that
are really hard to debug and it makes manipulating the compiler pipelines
incredibly challenging.
Further, it has long been considered best practice that the
:term:`nopython mode` keyword argument in the ``numba.jit`` decorator is set to
``True`` and that any user effort spent should go into making code work in this
mode as there's very little gain if it does not. The result is that, as Numba
has evolved, the amount of use :term:`object mode` gets in practice and its
general utility has decreased. It can be noted that there are some minor
improvements available through the notion of :term:`loop-lifting`, the cases of
this being used in practice are, however, rare and often a legacy from use of
less-recent Numba whereby such behaviour was better accommodated/the use of
``@jit`` with `fall-back` was recommended.
Example(s) of the impact
------------------------
At present a warning of the upcoming change is issued if ``@jit`` decorated code
uses the `fall-back` compilation path. In future code such as::
@jit
def bar():
l = []
for x in range(10):
l.append(x)
return reversed(l)
bar()
will simply not compile, a ``TypingError`` would be raised.
A further consequence of this change is that the ``nopython`` keyword argument
will become redundant as :term:`nopython mode` will be the default. As a result,
following this change, supplying the keyword argument as ``nopython=False`` will
trigger a warning stating that the implicit default has changed to ``True``.
Essentially this keyword will have no effect following removal of this feature.
Schedule
--------
This feature will be removed with respect to this schedule:
* Deprecation warnings will be issued in version 0.44.0.
* Prominent notice is given in 0.57.0.
* Removal will take place in version 0.59.0.
Recommendations
---------------
Projects that need/rely on the deprecated behaviour should pin their dependency
on Numba to a version prior to removal of this behaviour.
General advice to accommodate the scheduled deprecation:
Users with code compiled at present with ``@jit`` can supply the
``nopython=True`` keyword argument, if the code continues to compile then the
code is already ready for this change. If the code does not compile, continue
using the ``@jit`` decorator without ``nopython=True`` and profile the
performance of the function. Then remove the decorator and again check the
performance of the function. If there is no benefit to having the ``@jit``
decorator present consider removing it! If there is benefit to having the
``@jit`` decorator present, then to be future proof supply the keyword argument
``forceobj=True`` to ensure the function is always compiled in
:term:`object mode`.
Advice for users of the "loop-lifting" feature:
If object mode compilation with loop-lifting is needed it should be
explicitly declared through supplying the keyword arguments ``forceobj=True``
and ``looplift=True`` to the ``@jit`` decorator.
Advice for users setting ``nopython=False``:
This is essentially specifying the implicit default prior to removal of this
feature, either remove the keyword argument or change the value to ``True``.
.. _deprecation-of-generated-jit:
Deprecation of ``generated_jit``
================================
The top level API function ``numba.generated_jit`` provides functionality that
allows users to write JIT compilable functions that have different
implementations based on the types of the arguments to the function. This is a
hugely useful concept and is also key to Numba's internal implementation.
Reason for deprecation
----------------------
There are a number of reasons for this deprecation.
First, ``generated_jit`` breaks the concept of "JIT transparency" in that if the
JIT compiler is disabled, the source code does not execute the same way as it
would were the JIT compiler present.
Second, internally Numba uses the ``numba.extending.overload`` family of
decorators to access an equivalent functionality to ``generated_jit``. The
``overload`` family of decorators are more powerful than ``generated_jit`` as
they support far more options and both the CPU and CUDA targets. Essentially a
replacement for ``generated_jit`` already exists and has been recommended and
preferred for a long while.
Third, the public extension API decorators are far better maintained than
``generated_jit``. This is an important consideration due to Numba's limited
resources, fewer duplicated pieces of functionality to maintain will reduce
pressure on these resources.
For more information on the ``overload`` family of decorators see the
:ref:`high level extension API documentation <high-level-extending>`.
Example(s) of the impact
------------------------
Any source code using ``generated_jit`` would fail to work once the
functionality has been removed.
Schedule
--------
This feature will be removed with respect to this schedule:
* Deprecation warnings will be issued in version 0.57.0.
* Removal will take place in version 0.59.0.
Recommendations
---------------
Projects that need/rely on the deprecated behaviour should pin their dependency
on Numba to a version prior to removal of this behaviour, or consider following
replacement instructions below that outline how to adjust to the change.
Replacement
-----------
The ``overload`` decorator offers a replacement for the functionality available
through ``generated_jit``. An example follows of translating from one to the
other. First define a type specialised function dispatch with the
``generated_jit`` decorator::
from numba import njit, generated_jit, types
@generated_jit
def select(x):
if isinstance(x, types.Float):
def impl(x):
return x + 1
return impl
elif isinstance(x, types.UnicodeType):
def impl(x):
return x + " the number one"
return impl
else:
raise TypeError("Unsupported Type")
@njit
def foo(x):
return select(x)
print(foo(1.))
print(foo("a string"))
Conceptually, ``generated_jit`` is like ``overload``, but with ``generated_jit``
the overloaded function is the decorated function. Taking the example above and
adjusting it to use the ``overload`` API::
from numba import njit, types
from numba.extending import overload
# A pure python implementation that will run if the JIT compiler is disabled.
def select(x):
if isinstance(x, float):
return x + 1
elif isinstance(x, str):
return x + " the number one"
else:
raise TypeError("Unsupported Type")
# An overload for the `select` function cf. generated_jit
@overload(select)
def ol_select(x):
if isinstance(x, types.Float):
def impl(x):
return x + 1
return impl
elif isinstance(x, types.UnicodeType):
def impl(x):
return x + " the number one"
return impl
else:
raise TypeError("Unsupported Type")
@njit
def foo(x):
return select(x)
print(foo(1.))
print(foo("a string"))
Further, users that are using ``generated_jit`` to dispatch on some of the more
primitive types may find that Numba's support for ``isinstance`` is sufficient,
for example::
@njit # NOTE: standard @njit decorator.
def select(x):
if isinstance(x, float):
return x + 1
elif isinstance(x, str):
return x + " the number one"
else:
raise TypeError("Unsupported Type")
@njit
def foo(x):
return select(x)
print(foo(1.))
print(foo("a string"))
.. _deprecation-numba-pycc:
Deprecation of the ``numba.pycc`` module
========================================
Numba has supported some degree of Ahead-of-Time (AOT) compilation through the
use of the tools in the ``numba.pycc`` module. This capability is very important
to the Numba project and following an assessment of the viability of the current
approach, it was decided to deprecate it in favour of developing new technology
to better meet current needs.
Reason for deprecation
----------------------
There are a number of reasons for this deprecation.
* ``numba.pycc`` tools create C-Extensions that have symbols that are only
usable from the Python interpreter, they are not compatible with calls made
from within code compiled using Numba's JIT compiler. This drastically reduces
the utility of AOT compiled functions.
* ``numba.pycc`` has some reliance on ``setuptools`` (and ``distutils``) which
is something Numba is trying to reduce, particularly due to the upcoming
removal of ``distutils`` in Python 3.12.
* The ``numba.pycc`` compilation chain is very limited in terms of its feature
set in comparison to Numba's JIT compiler, it also has numerous technical
issues to do with declaring and linking both internal and external libraries.
* The number of users of ``numba.pycc`` is assumed to be quite small, this was
indicated through discussions at a Numba public meeting on 2022-10-04 and
issue #8509.
* The Numba project is working on new innovations in the AOT compiler space and
the maintainers consider it a better use of resources to develop these than
maintain and develop ``numba.pycc``.
Example(s) of the impact
------------------------
Any source code using ``numba.pycc`` would fail to work once the functionality
has been removed.
Schedule
--------
This feature will be removed with respect to this schedule:
* Pending-deprecation warnings will be issued in version 0.57.0.
* Deprecation warnings will be issued once a replacement is developed.
* Deprecation warnings will be given for a minimum of two releases prior to full
removal.
Recommendations
---------------
Projects that need/rely on the deprecated behaviour should pin their dependency
on Numba to a version prior to removal of this behaviour, or consider following
replacement instructions below that outline how to adjust to the change.
Replacement
-----------
A replacement for this functionality is being developed as part of the Numba
2023 development focus. The ``numba.pycc`` module will not be removed until this
replacement functionality is able to provide similar utility and offer an
upgrade path. At the point of the new technology being deemed suitable,
replacement instructions will be issued.
Deprecation and removal of CUDA Toolkits < 11.2 and devices with CC < 5.0
=========================================================================
- Support for CUDA toolkits less than 11.2 has been removed.
- Support for devices with Compute Capability < 5.0 is deprecated and will be
removed in the future.
Recommendations
---------------
- For devices of Compute Capability 3.0 and 3.2, Numba 0.55.1 or earlier will
be required.
- CUDA toolkit 11.2 or later should be installed.
Schedule
--------
- In Numba 0.55.1: support for CC < 5.0 and CUDA toolkits < 10.2 was deprecated.
- In Numba 0.56: support for CC < 3.5 and CUDA toolkits < 10.2 was removed.
- In Numba 0.57: Support for CUDA toolkit 10.2 was removed.
- In Numba 0.58: Support CUDA toolkits 11.0 and 11.1 was removed.
- In a future release: Support for CC < 5.0 will be removed.
Deprecation of old-style ``NUMBA_CAPTURED_ERRORS``
==================================================
The use of ``NUMBA_CAPTURED_ERRORS=old_style`` environment variable is being
deprecated in Numba.
Reason for deprecation
----------------------
Previously, this variable allowed controlling how Numba handles exceptions
during compilation that do not inherit from ``numba.core.errors.NumbaError``.
The default "old_style" behavior was to capture and wrap these errors, often
obscuring the original exception.
The new "new_style" option treats non-``NumbaError`` exceptions as hard errors,
propagating them without capturing. This differentiates compilation errors from
unintended exceptions during compilation.
The old style will eventually be removed in favor of the new behavior. Users
should migrate to setting ``NUMBA_CAPTURED_ERRORS='new_style'`` to opt-in to the
new exception handling. This will become the default in the future.
Impact
------
The impact of this deprecation will only affect those who are extending Numba
functionality.
Recommendations
---------------
- Projects that extends Numba should set
``NUMBA_CAPTURED_ERRORS='new_style'`` for testing to find all places where
non-``NumbaError`` exceptions are raised during compilation.
- Modify any code that raises a non-``NumbaError`` to indicate a compilation
error to raise a subclass of ``NumbaError`` instead. For example, instead of
raising a ``TypeError``, raise a ``numba.core.errors.NumbaTypeError``.
Schedule
--------
- In Numba 0.58: ``NUMBA_CAPTURED_ERRORS=old_style`` is deprecated. Warnings
will be raised when `old_style` error capturing is used.
- In Numba 0.59: explicitly setting ``NUMBA_CAPTURED_ERRORS=old_style`` will
raise deprecation warnings.
- In Numba 0.60: ``NUMBA_CAPTURED_ERRORS=new_style`` becomes the default.
- In Numba 0.61: support for ``NUMBA_CAPTURED_ERRORS=old_style`` will be
removed.
.. _numba-envvars:
Environment variables
=====================
.. note:: This section relates to environment variables that impact Numba's
runtime, for compile time environment variables see
:ref:`numba-source-install-env_vars`.
Numba allows its behaviour to be changed through the use of environment
variables. Unless otherwise mentioned, those variables have integer values and
default to zero.
For convenience, Numba also supports the use of a configuration file to persist
configuration settings. Note: To use this feature ``pyyaml`` must be installed.
The configuration file must be named ``.numba_config.yaml`` and be present in
the directory from which the Python interpreter is invoked. The configuration
file, if present, is read for configuration settings before the environment
variables are searched. This means that the environment variable settings will
override the settings obtained from a configuration file (the configuration file
is for setting permanent preferences whereas the environment variables are for
ephemeral preferences).
The format of the configuration file is a dictionary in ``YAML`` format that
maps the environment variables below (without the ``NUMBA_`` prefix) to a
desired value. For example, to permanently switch on developer mode
(``NUMBA_DEVELOPER_MODE`` environment variable) and control flow graph printing
(``NUMBA_DUMP_CFG`` environment variable), create a configuration file with the
contents::
developer_mode: 1
dump_cfg: 1
This can be especially useful in the case of wanting to use a set color scheme
based on terminal background color. For example, if the terminal background
color is black, the ``dark_bg`` color scheme would be well suited and can be set
for permanent use by adding::
color_scheme: dark_bg
Jit flags
---------
These variables globally override flags to the :func:`~numba.jit` decorator.
.. envvar:: NUMBA_BOUNDSCHECK
If set to 0 or 1, globally disable or enable bounds checking, respectively.
The default if the variable is not set or set to an empty string is to use
the ``boundscheck`` flag passed to the :func:`~numba.jit` decorator for a
given function. See the documentation of :ref:`@jit
<jit-decorator-boundscheck>` for more information.
Note, due to limitations in numba, the bounds checking currently produces
exception messages that do not match those from NumPy. If you set
``NUMBA_FULL_TRACEBACKS=1``, the full exception message with the axis,
index, and shape information will be printed to the terminal.
Debugging
---------
These variables influence what is printed out during compilation of
:term:`JIT functions <JIT function>`.
.. envvar:: NUMBA_DEVELOPER_MODE
If set to non-zero, developer mode produces full tracebacks and disables
help instructions. Default is zero.
.. envvar:: NUMBA_FULL_TRACEBACKS
If set to non-zero, enable full tracebacks when an exception occurs.
Defaults to the value set by `NUMBA_DEVELOPER_MODE`.
.. envvar:: NUMBA_SHOW_HELP
If set to non-zero, show resources for getting help. Default is zero.
.. envvar:: NUMBA_CAPTURED_ERRORS
Alters the way in which Numba captures and handles exceptions that do not
inherit from ``numba.core.errors.NumbaError`` during compilation (e.g.
standard Python exceptions). This does not impact runtime exception
handling. Valid values are:
- ``"old_style"`` (default): this is the exception handling behaviour that
is present in Numba versions <= 0.54.x. Numba will capture and wrap all
errors occurring in compilation and depending on the compilation phase they
will likely materialize as part of the message in a ``TypingError`` or a
``LoweringError``.
- ``"new_style"`` this will treat any exception that does not inherit from
``numba.core.errors.NumbaError`` **and** is raised during compilation as a
"hard error", i.e. the exception will propagate and compilation will halt.
The purpose of this new style is to differentiate between intentionally
raised exceptions and those which occur due to mistakes. For example, if
an ``AttributeError`` occurs in the typing of an ``@overload`` function,
under this new behaviour it is assumed that this a mistake in the
implementation and compilation will halt due to this exception. This
behaviour will eventually become the default.
.. envvar:: NUMBA_DISABLE_ERROR_MESSAGE_HIGHLIGHTING
If set to non-zero error message highlighting is disabled. This is useful
for running the test suite on CI systems.
.. envvar:: NUMBA_COLOR_SCHEME
Alters the color scheme used in error reporting (requires the ``colorama``
package to be installed to work). Valid values are:
- ``no_color`` No color added, just bold font weighting.
- ``dark_bg`` Suitable for terminals with a dark background.
- ``light_bg`` Suitable for terminals with a light background.
- ``blue_bg`` Suitable for terminals with a blue background.
- ``jupyter_nb`` Suitable for use in Jupyter Notebooks.
*Default value:* ``no_color``. The type of the value is ``string``.
.. envvar:: NUMBA_HIGHLIGHT_DUMPS
If set to non-zero and ``pygments`` is installed, syntax highlighting is
applied to Numba IR, LLVM IR and assembly dumps. Default is zero.
.. envvar:: NUMBA_DISABLE_PERFORMANCE_WARNINGS
If set to non-zero the issuing of performance warnings is disabled. Default
is zero.
.. envvar:: NUMBA_DEBUG
If set to non-zero, print out all possible debugging information during
function compilation. Finer-grained control can be obtained using other
variables below.
.. envvar:: NUMBA_DEBUG_FRONTEND
If set to non-zero, print out debugging information during operation
of the compiler frontend, up to and including generation of the Numba
Intermediate Representation.
.. envvar:: NUMBA_DEBUG_NRT
If set to non-zero, print out debugging information at runtime about the use
of :ref:`Numba run time (NRT) <arch-numba-runtime>` reference count
operations. If set to non-zero, this also switches on the filling of all NRT
allocated regions with an identifiable "marker" byte pattern, ``0xCB`` on
allocation and ``0xDE`` on deallocation, both to help with debugging memory
leaks.
.. envvar:: NUMBA_NRT_STATS
If set to non-zero, enable the
:ref:`Numba run time (NRT) <arch-numba-runtime>` statistics counters. These
counters are enabled process wide on import of Numba and are atomic.
.. envvar:: NUMBA_DEBUGINFO
If set to non-zero, enable debug for the full application by setting
the default value of the ``debug`` option in ``jit``. Beware that
enabling debug info significantly increases the memory consumption
for each compiled function.
Default value equals to the value of `NUMBA_ENABLE_PROFILING`.
.. envvar:: NUMBA_EXTEND_VARIABLE_LIFETIMES
If set to non-zero, extend the lifetime of variables to the end of the block
in which their lifetime ends. This is particularly useful in conjunction
with :envvar:`NUMBA_DEBUGINFO` as it helps with introspection of values.
Default is zero.
.. envvar:: NUMBA_GDB_BINARY
Set the ``gdb`` binary for use in Numba's ``gdb`` support. This takes one of
two forms: 1) a path and full name of the binary to explicitly express
which binary to use 2) just the name of the binary and the current path will
be searched using the standard path resolution rules. For example:
``/path/from/root/to/binary/name_of_gdb_binary`` or
``custom_gdb_binary_name``. This is to permit the use of a ``gdb`` from a
non-default location with a non-default name. The default value is ``gdb``.
.. envvar:: NUMBA_DEBUG_TYPEINFER
If set to non-zero, print out debugging information about type inference.
.. envvar:: NUMBA_ENABLE_PROFILING
Enables JIT events of LLVM in order to support profiling of jitted functions.
This option is automatically enabled under certain profilers.
.. envvar:: NUMBA_TRACE
If set to non-zero, trace certain function calls (function entry and exit
events, including arguments and return values).
.. envvar:: NUMBA_CHROME_TRACE
If defined, chrome tracing is enabled and this variable specifies the filepath
of the chrome tracing json file output. The emitted file can be opened by
a Chromium-based browser using the profile viewer at `chrome://tracing/`.
.. warning:: This feature is not supported in multi-process applications.
.. envvar:: NUMBA_DUMP_BYTECODE
If set to non-zero, print out the Python :py:term:`bytecode` of
compiled functions.
.. envvar:: NUMBA_DUMP_CFG
If set to non-zero, print out information about the Control Flow Graph
of compiled functions.
.. envvar:: NUMBA_DUMP_IR
If set to non-zero, print out the Numba Intermediate Representation
of compiled functions.
.. envvar:: NUMBA_DUMP_SSA
If set to non-zero, print out the Numba Intermediate Representation of
compiled functions after conversion to Static Single Assignment (SSA) form.
.. envvar:: NUMBA_DEBUG_PRINT_AFTER
Dump the Numba IR after declared pass(es). This is useful for debugging IR
changes made by given passes. Accepted values are:
* Any pass name (as given by the ``.name()`` method on the class)
* Multiple pass names as a comma separated list, i.e. ``"foo_pass,bar_pass"``
* The token ``"all"``, which will print after all passes.
The default value is ``"none"`` so as to prevent output.
.. envvar:: NUMBA_DUMP_ANNOTATION
If set to non-zero, print out types annotations for compiled functions.
.. envvar:: NUMBA_DUMP_LLVM
Dump the unoptimized LLVM assembly source of compiled functions.
Unoptimized code is usually very verbose; therefore,
:envvar:`NUMBA_DUMP_OPTIMIZED` is recommended instead.
.. envvar:: NUMBA_DUMP_FUNC_OPT
Dump the LLVM assembly source after the LLVM "function optimization"
pass, but before the "module optimization" pass. This is useful mostly
when developing Numba itself, otherwise use :envvar:`NUMBA_DUMP_OPTIMIZED`.
.. envvar:: NUMBA_DUMP_OPTIMIZED
Dump the LLVM assembly source of compiled functions after all
optimization passes. The output includes the raw function as well as
its CPython-compatible wrapper (whose name begins with ``wrapper.``).
Note that the function is often inlined inside the wrapper, as well.
.. envvar:: NUMBA_DEBUG_ARRAY_OPT
Dump debugging information related to the processing associated with
the ``parallel=True`` jit decorator option.
.. envvar:: NUMBA_DEBUG_ARRAY_OPT_RUNTIME
Dump debugging information related to the runtime scheduler associated
with the ``parallel=True`` jit decorator option.
.. envvar:: NUMBA_DEBUG_ARRAY_OPT_STATS
Dump statistics about how many operators/calls are converted to
parallel for-loops and how many are fused together, which are associated
with the ``parallel=True`` jit decorator option.
.. envvar:: NUMBA_PARALLEL_DIAGNOSTICS
If set to an integer value between 1 and 4 (inclusive) diagnostic information
about parallel transforms undertaken by Numba will be written to STDOUT. The
higher the value set the more detailed the information produced.
.. envvar:: NUMBA_DUMP_ASSEMBLY
Dump the native assembly code of compiled functions.
.. envvar:: NUMBA_LLVM_PASS_TIMINGS
Set to ``1`` to enable recording of pass timings in LLVM;
e.g. ``NUMBA_LLVM_PASS_TIMINGS=1``.
See :ref:`developer-llvm-timings`.
*Default value*: ``0`` (Off)
.. seealso::
:ref:`numba-troubleshooting` and :ref:`architecture`.
Compilation options
-------------------
.. envvar:: NUMBA_OPT
The optimization level; typically this option is passed straight to LLVM. It
may take one of the values ``0``, ``1``, ``2`` or ``3`` which correspond
approximately to the ``-O{value}`` flag found in many command line
compilation tools. The value ``max`` is also supported, this is Numba
specific, it has the effect of running with the optimization level set at
``3`` both before and after a pass which in which reference count operation
pruning takes place. In some cases this may increase performance, in other
cases it may impede performance, the same can be said for compilation time.
This option is present to give users the opportunity to choose a value
suitable for their application.
*Default value:* 3
.. envvar:: NUMBA_LOOP_VECTORIZE
If set to non-zero, enable LLVM loop vectorization.
*Default value:* 1
.. envvar:: NUMBA_SLP_VECTORIZE
If set to non-zero, enable LLVM superword-level parallelism vectorization.
Note that use of this feature has occasionally resulted in LLVM producing
miscompilations, hence it is off by default.
*Default value:* 0
.. envvar:: NUMBA_ENABLE_AVX
If set to non-zero, enable AVX optimizations in LLVM. This is disabled
by default on Sandy Bridge and Ivy Bridge architectures as it can sometimes
result in slower code on those platforms.
.. envvar:: NUMBA_DISABLE_INTEL_SVML
If set to non-zero and Intel SVML is available, the use of SVML will be
disabled.
.. envvar:: NUMBA_DISABLE_JIT
Disable JIT compilation entirely. The :func:`~numba.jit` decorator acts
as if it performs no operation, and the invocation of decorated functions
calls the original Python function instead of a compiled version. This
can be useful if you want to run the Python debugger over your code.
.. envvar:: NUMBA_CPU_NAME
.. envvar:: NUMBA_CPU_FEATURES
Override CPU and CPU features detection.
By setting ``NUMBA_CPU_NAME=generic``, a generic CPU model is picked
for the CPU architecture and the feature list (``NUMBA_CPU_FEATURES``)
defaults to empty. CPU features must be listed with the format
``+feature1,-feature2`` where ``+`` indicates enable and ``-`` indicates
disable. For example, ``+sse,+sse2,-avx,-avx2`` enables SSE and SSE2, and
disables AVX and AVX2.
These settings are passed to LLVM for configuring the compilation target.
To get a list of available options, use the ``llc`` commandline tool
from LLVM, for example::
llc -march=x86 -mattr=help
.. tip:: To force all caching functions (``@jit(cache=True)``) to emit
portable code (portable within the same architecture and OS),
simply set ``NUMBA_CPU_NAME=generic``.
.. envvar:: NUMBA_FUNCTION_CACHE_SIZE
Override the size of the function cache for retaining recently
deserialized functions in memory. In systems like
`Dask <http://dask.pydata.org>`_, it is common for functions to be deserialized
multiple times. Numba will cache functions as long as there is a
reference somewhere in the interpreter. This cache size variable controls
how many functions that are no longer referenced will also be retained,
just in case they show up in the future. The implementation of this is
not a true LRU, but the large size of the cache should be sufficient for
most situations.
Note: this is unrelated to the compilation cache.
*Default value:* 128
.. envvar:: NUMBA_LLVM_REFPRUNE_PASS
Turns on the LLVM pass level reference-count pruning pass and disables the
regex based implementation in Numba.
*Default value:* 1 (On)
.. envvar:: NUMBA_LLVM_REFPRUNE_FLAGS
When ``NUMBA_LLVM_REFPRUNE_PASS`` is on, this allows configuration
of subpasses in the reference-count pruning LLVM pass.
Valid values are any combinations of the below separated by `,`
(case-insensitive):
- ``all``: enable all subpasses.
- ``per_bb``: enable per-basic-block level pruning, which is same as the
old regex based implementation.
- ``diamond``: enable inter-basic-block pruning that is a diamond shape
pattern, i.e. a single-entry single-exit CFG subgraph where has an incref
in the entry and a corresponding decref in the exit.
- ``fanout``: enable inter-basic-block pruning that has a fanout pattern,
i.e. a single-entry multiple-exit CFG subgraph where the entry has an
incref and every exit has a corresponding decref.
- ``fanout_raise``: same as ``fanout`` but allow subgraph exit nodes to be
raising an exception and not have a corresponding decref.
For example, ``all`` is the same as
``per_bb, diamond, fanout, fanout_raise``
*Default value:* "all"
.. envvar:: NUMBA_USE_RVSDG_FRONTEND
Turns on the experimental RVSDG frontend. It depends on the ``numba-rvsdg``
package and only supports Python 3.11 partially.
This option will be removed when the RVSDG frontend fully replaces the
old frontend.
*Default value:* 0 (Off)
.. _numba-envvars-caching:
Caching options
---------------
Options for the compilation cache.
.. envvar:: NUMBA_DEBUG_CACHE
If set to non-zero, print out information about operation of the
:ref:`JIT compilation cache <jit-cache>`.
.. envvar:: NUMBA_CACHE_DIR
Override the location of the cache directory. If defined, this should be
a valid directory path.
If not defined, Numba picks the cache directory in the following order:
1. In-tree cache. Put the cache next to the corresponding source file under
a ``__pycache__`` directory following how ``.pyc`` files are stored.
2. User-wide cache. Put the cache in the user's application directory using
``appdirs.user_cache_dir`` from the
`Appdirs package <https://github.com/ActiveState/appdirs>`_.
3. IPython cache. Put the cache in an IPython specific application
directory.
Stores are made under the ``numba_cache`` in the directory returned by
``IPython.paths.get_ipython_cache_dir()``.
Also see :ref:`docs on cache sharing <cache-sharing>` and
:ref:`docs on cache clearing <cache-clearing>`
.. _numba-envvars-gpu-support:
GPU support
-----------
.. envvar:: NUMBA_DISABLE_CUDA
If set to non-zero, disable CUDA support.
.. envvar:: NUMBA_FORCE_CUDA_CC
If set, force the CUDA compute capability to the given version (a
string of the type ``major.minor``), regardless of attached devices.
.. envvar:: NUMBA_CUDA_DEFAULT_PTX_CC
The default compute capability (a string of the type ``major.minor``) to
target when compiling to PTX using ``cuda.compile_ptx``. The default is
5.2, which is the lowest non-deprecated compute capability in the most
recent version of the CUDA toolkit supported (11.0 at present).
.. envvar:: NUMBA_ENABLE_CUDASIM
If set, don't compile and execute code for the GPU, but use the CUDA
Simulator instead. For debugging purposes.
.. envvar:: NUMBA_CUDA_ARRAY_INTERFACE_SYNC
Whether to synchronize on streams provided by objects imported using the CUDA
Array Interface. This defaults to 1. If set to 0, then no synchronization
takes place, and the user of Numba (and other CUDA libraries) is responsible
for ensuring correctness with respect to synchronization on streams.
.. envvar:: NUMBA_CUDA_LOG_LEVEL
For debugging purposes. If no other logging is configured, the value of this
variable is the logging level for CUDA API calls. The default value is
``CRITICAL`` - to trace all API calls on standard error, set this to
``DEBUG``.
.. envvar:: NUMBA_CUDA_LOG_API_ARGS
By default the CUDA API call logs only give the names of functions called.
Setting this variable to 1 also includes the values of arguments to Driver
API calls in the logs.
.. envvar:: NUMBA_CUDA_DRIVER
Path of the directory in which the CUDA driver libraries are to be found.
Normally this should not need to be set as Numba can locate the driver in
standard locations. However, this variable can be used if the driver is in a
non-standard location.
.. envvar:: NUMBA_CUDA_LOG_SIZE
Buffer size for logs produced by CUDA driver API operations. This defaults
to 1024 and should not normally need to be modified - however, if an error
in an API call produces a large amount of output that appears to be
truncated (perhaps due to multiple long function names, for example) then
this variable can be used to increase the buffer size and view the full
error message.
.. envvar:: NUMBA_CUDA_VERBOSE_JIT_LOG
Whether the CUDA driver should produce verbose log messages. Defaults to 1,
indicating that verbose messaging is enabled. This should not need to be
modified under normal circumstances.
.. envvar:: NUMBA_CUDA_PER_THREAD_DEFAULT_STREAM
When set to 1, the default stream is the per-thread default stream. When set
to 0, the default stream is the legacy default stream. This defaults to 0,
for the legacy default stream. See `Stream Synchronization Behavior
<https://docs.nvidia.com/cuda/cuda-runtime-api/stream-sync-behavior.html>`_
for an explanation of the legacy and per-thread default streams.
This variable only takes effect when using Numba's internal CUDA bindings;
when using the NVIDIA bindings, use the environment variable
``CUDA_PYTHON_CUDA_PER_THREAD_DEFAULT_STREAM`` instead.
.. seealso::
The `Default Stream section
<https://nvidia.github.io/cuda-python/release/11.6.0-notes.html#default-stream>`_
in the NVIDIA Bindings documentation.
.. envvar:: NUMBA_CUDA_LOW_OCCUPANCY_WARNINGS
Enable warnings if the grid size is too small relative to the number of
streaming multiprocessors (SM). This option is on by default (default value is 1).
The heuristic checked is whether ``gridsize < 2 * (number of SMs)``. NOTE: The absence of
a warning does not imply a good gridsize relative to the number of SMs. Disabling
this warning will reduce the number of CUDA API calls (during JIT compilation), as the
heuristic needs to check the number of SMs available on the device in the
current context.
.. envvar:: NUMBA_CUDA_WARN_ON_IMPLICIT_COPY
Enable warnings if a kernel is launched with host memory which forces a copy to and
from the device. This option is on by default (default value is 1).
.. envvar:: NUMBA_CUDA_USE_NVIDIA_BINDING
When set to 1, Numba will attempt to use the `NVIDIA CUDA Python binding
<https://nvidia.github.io/cuda-python/>`_ to make calls to the driver API
instead of using its own ctypes binding. This defaults to 0 (off), as the
NVIDIA binding is currently missing support for Per-Thread Default
Streams and the profiler APIs.
.. envvar:: NUMBA_CUDA_INCLUDE_PATH
The location of the CUDA include files. This is used when linking CUDA C/C++
sources to Python kernels, and needs to be correctly set for CUDA includes to
be available to linked C/C++ sources. On Linux, it defaults to
``/usr/local/cuda/include``. On Windows, the default is
``$env:CUDA_PATH\include``.
Threading Control
-----------------
.. envvar:: NUMBA_NUM_THREADS
If set, the number of threads in the thread pool for the parallel CPU target
will take this value. Must be greater than zero. This value is independent
of ``OMP_NUM_THREADS`` and ``MKL_NUM_THREADS``.
*Default value:* The number of CPU cores on the system as determined at run
time. This can be accessed via :obj:`numba.config.NUMBA_DEFAULT_NUM_THREADS`.
See also the section on :ref:`setting_the_number_of_threads` for
information on how to set the number of threads at runtime.
.. envvar:: NUMBA_THREADING_LAYER
This environment variable controls the library used for concurrent execution
for the CPU parallel targets (``@vectorize(target='parallel')``,
``@guvectorize(target='parallel')`` and ``@njit(parallel=True)``). The
variable type is string and by default is ``default`` which will select a
threading layer based on what is available in the runtime. The valid values
are (for more information about these see
:ref:`the threading layer documentation <numba-threading-layer>`):
* ``default`` - select a threading layer based on what is available in the
current runtime.
* ``safe`` - select a threading layer that is both fork and thread safe
(requires the TBB package).
* ``forksafe`` - select a threading layer that is fork safe.
* ``threadsafe`` - select a threading layer that is thread safe.
* ``tbb`` - A threading layer backed by Intel TBB.
* ``omp`` - A threading layer backed by OpenMP.
* ``workqueue`` - A simple built-in work-sharing task scheduler.
.. envvar:: NUMBA_THREADING_LAYER_PRIORITY
This environment variable controls the order in which the libraries used for
concurrent execution, for the CPU parallel targets
(``@vectorize(target='parallel')``, ``@guvectorize(target='parallel')``
and ``@njit(parallel=True)``), are prioritized for use. The variable type is
string and by default is ``tbb omp workqueue``, with the priority taken based
on position from the left of the string, left most being the highest. Valid
values are any permutation of the three choices (for more information about
these see :ref:`the threading layer documentation <numba-threading-layer>`.)
Floating-point pitfalls
=======================
Precision and accuracy
----------------------
For some operations, Numba may use a different algorithm than Python or
Numpy. The results may not be bit-by-bit compatible. The difference
should generally be small and within reasonable expectations. However,
small accumulated differences might produce large differences at the end,
especially if a divergent function is involved.
Math library implementations
''''''''''''''''''''''''''''
Numba supports a variety of platforms and operating systems, each of which
has its own math library implementation (referred to as ``libm`` from here
in). The majority of math functions included in ``libm`` have specific
requirements as set out by the IEEE 754 standard (like ``sin()``, ``exp()``
etc.), but each implementation may have bugs. Thus, on some platforms
Numba has to exercise special care in order to workaround known ``libm``
issues.
Another typical problem is when an operating system's ``libm`` function
set is incomplete and needs to be supplemented by additional functions.
These are provided with reference to the IEEE 754 and C99 standards
and are often implemented in Numba in a manner similar to equivalent
CPython functions.
Linear algebra
''''''''''''''
Numpy forces some linear algebra operations to run in double-precision mode
even when a ``float32`` input is given. Numba will always observe
the input's precision, and invoke single-precision linear algebra routines
when all inputs are ``float32`` or ``complex64``.
The implementations of the ``numpy.linalg`` routines in Numba only support the
floating point types that are used in the LAPACK functions that provide
the underlying core functionality. As a result only ``float32``, ``float64``,
``complex64`` and ``complex128`` types are supported. If a user has e.g. an
``int32`` type, an appropriate type conversion must be performed to a
floating point type prior to its use in these routines. The reason for this
decision is to essentially avoid having to replicate type conversion choices
made in Numpy and to also encourage the user to choose the optimal floating
point type for the operation they are undertaking.
Mixed-types operations
''''''''''''''''''''''
Numpy will most often return a ``float64`` as a result of a computation
with mixed integer and floating-point operands (a typical example is the
power operator ``**``). Numba by contrast will select the highest precision
amongst the floating-point operands, so for example ``float32 ** int32``
will return a ``float32``, regardless of the input values. This makes
performance characteristics easier to predict, but you should explicitly
cast the input to ``float64`` if you need the extra precision.
.. _ufunc-fpu-errors:
Warnings and errors
-------------------
When calling a :term:`ufunc` created with :func:`~numba.vectorize`,
Numpy will determine whether an error occurred by examining the FPU
error word. It may then print out a warning or raise an exception
(such as ``RuntimeWarning: divide by zero encountered``),
depending on the current error handling settings.
Depending on how LLVM optimized the ufunc's code, however, some spurious
warnings or errors may appear. If you get caught by this issue, we
recommend you call :func:`numpy.seterr` to change Numpy's error handling
settings, or the :class:`numpy.errstate` context manager to switch them
temporarily::
with np.errstate(all='ignore'):
x = my_ufunc(y)
Reference Manual
================
.. toctree::
types.rst
jit-compilation.rst
aot-compilation.rst
utils.rst
envvars.rst
pysupported.rst
numpysupported.rst
pysemantics.rst
fpsemantics.rst
deprecation.rst
Just-in-Time compilation
========================
.. _jit-decorator:
JIT functions
-------------
.. decorator:: numba.jit(signature=None, nopython=False, nogil=False, cache=False, forceobj=False, parallel=False, error_model='python', fastmath=False, locals={}, boundscheck=False)
Compile the decorated function on-the-fly to produce efficient machine
code. All parameters are optional.
If present, the *signature* is either a single signature or a list of
signatures representing the expected :ref:`numba-types` of function
arguments and return values. Each signature can be given in several
forms:
* A tuple of :ref:`numba-types` arguments (for example
``(numba.int32, numba.double)``) representing the types of the
function's arguments; Numba will then infer an appropriate return
type from the arguments.
* A call signature using :ref:`numba-types`, specifying both return
type and argument types. This can be given in intuitive form
(for example ``numba.void(numba.int32, numba.double)``).
* A string representation of one of the above, for example
``"void(int32, double)"``. All type names used in the string are assumed
to be defined in the ``numba.types`` module.
*nopython* and *nogil* are boolean flags. *locals* is a mapping of
local variable names to :ref:`numba-types`.
This decorator has several modes of operation:
* If one or more signatures are given in *signature*, a specialization is
compiled for each of them. Calling the decorated function will then try
to choose the best matching signature, and raise a :class:`TypeError` if
no appropriate conversion is available for the function arguments. If
converting succeeds, the compiled machine code is executed with the
converted arguments and the return value is converted back according to
the signature.
* If no *signature* is given, the decorated function implements
lazy compilation. Each call to the decorated function will try to
re-use an existing specialization if it exists (for example, a call
with two integer arguments may re-use a specialization for argument
types ``(numba.int64, numba.int64)``). If no suitable specialization
exists, a new specialization is compiled on-the-fly, stored for later
use, and executed with the converted arguments.
If true, *nopython* forces the function to be compiled in :term:`nopython
mode`. If not possible, compilation will raise an error.
If true, *forceobj* forces the function to be compiled in :term:`object
mode`. Since object mode is slower than nopython mode, this is mostly
useful for testing purposes.
If true, *nogil* tries to release the :py:term:`global interpreter lock`
inside the compiled function. The GIL will only be released if Numba can
compile the function in :term:`nopython mode`, otherwise a compilation
warning will be printed.
.. _jit-decorator-cache:
If true, *cache* enables a file-based cache to shorten compilation times
when the function was already compiled in a previous invocation.
The cache is maintained in the ``__pycache__`` subdirectory of
the directory containing the source file; if the current user is not
allowed to write to it, though, it falls back to a platform-specific
user-wide cache directory (such as ``$HOME/.cache/numba`` on Unix
platforms).
.. _jit-decorator-parallel:
If true, *parallel* enables the automatic parallelization of a number of
common NumPy constructs as well as the fusion of adjacent parallel
operations to maximize cache locality.
The *error_model* option controls the divide-by-zero behavior.
Setting it to 'python' causes divide-by-zero to raise exception like CPython.
Setting it to 'numpy' causes divide-by-zero to set the result to *+/-inf* or
*nan*.
Not all functions can be cached, since some functionality cannot be
always persisted to disk. When a function cannot be cached, a
warning is emitted.
.. _jit-decorator-fastmath:
If true, *fastmath* enables the use of otherwise unsafe floating point
transforms as described in the
`LLVM documentation <https://llvm.org/docs/LangRef.html#fast-math-flags>`_.
Further, if :ref:`Intel SVML <intel-svml>` is installed faster but less
accurate versions of some math intrinsics are used (answers to within
``4 ULP``).
.. _jit-decorator-boundscheck:
If true, *boundscheck* enables bounds checking for array indices. Out of
bounds accesses will raise IndexError. The default is to not do bounds
checking. If bounds checking is disabled, out of bounds accesses can
produce garbage results or segfaults. However, enabling bounds checking
will slow down typical functions, so it is recommended to only use this
flag for debugging. You can also set the `NUMBA_BOUNDSCHECK` environment
variable to 0 or 1 to globally override this flag.
The *locals* dictionary may be used to force the :ref:`numba-types`
of particular local variables, for example if you want to force the
use of single precision floats at some point. In general, we recommend
you let Numba's compiler infer the types of local variables by itself.
Here is an example with two signatures::
@jit(["int32(int32)", "float32(float32)"], nopython=True)
def f(x): ...
Not putting any parentheses after the decorator is equivalent to calling
the decorator without any arguments, i.e.::
@jit
def f(x): ...
is equivalent to::
@jit()
def f(x): ...
The decorator returns a :class:`Dispatcher` object.
.. note::
If no *signature* is given, compilation errors will be raised when
the actual compilation occurs, i.e. when the function is first called
with some given argument types.
.. note::
Compilation can be influenced by some dedicated :ref:`numba-envvars`.
Generated JIT functions
-----------------------
.. decorator:: numba.generated_jit(nopython=False, nogil=False, cache=False, forceobj=False, locals={})
Like the :func:`~numba.jit` decorator, but calls the decorated function at
compile-time, passing the *types* of the function's arguments.
The decorated function must return a callable which will be compiled as
the function's implementation for those types, allowing flexible kinds of
specialization.
The :func:`~numba.generated_jit` decorator returns a :class:`Dispatcher` object.
Dispatcher objects
------------------
.. class:: Dispatcher
The class of objects created by calling :func:`~numba.jit` or
:func:`~numba.generated_jit`. You shouldn't try to create such an object
in any other way. Calling a Dispatcher object calls the compiled
specialization for the arguments with which it is called, letting it
act as an accelerated replacement for the Python function which was compiled.
In addition, Dispatcher objects have the following methods and attributes:
.. attribute:: py_func
The pure Python function which was compiled.
.. method:: inspect_types(file=None, pretty=False)
Print out a listing of the function source code annotated line-by-line
with the corresponding Numba IR, and the inferred types of the various
variables. If *file* is specified, printing is done to that file
object, otherwise to sys.stdout. If *pretty* is set to True then colored
ANSI will be produced in a terminal and HTML in a notebook.
.. seealso:: :ref:`architecture`
.. method:: inspect_llvm(signature=None)
Return a dictionary keying compiled function signatures to the human
readable LLVM IR generated for the function. If the signature
keyword is specified a string corresponding to that individual
signature is returned.
.. method:: inspect_asm(signature=None)
Return a dictionary keying compiled function signatures to the
human-readable native assembly code for the function. If the
signature keyword is specified a string corresponding to that
individual signature is returned.
.. method:: inspect_cfg(signature=None, show_wrapped)
Return a dictionary keying compiled function signatures to the
control-flow graph objects for the function. If the signature keyword is
specified a string corresponding to that individual signature is returned.
The control-flow graph objects can be stringified (``str`` or ``repr``)
to get the textual representation of the graph in DOT format. Or, use
its ``.display(filename=None, view=False)`` method to plot the graph.
The *filename* option can be set to a specific path for the rendered
output to write to. If *view* option is True, the plot is opened by
the system default application for the image format (PDF). In IPython
notebook, the returned object can be plot inlined.
Usage::
@jit
def foo():
...
# opens the CFG in system default application
foo.inspect_cfg(foo.signatures[0]).display(view=True)
.. method:: inspect_disasm_cfg(signature=None)
Return a dictionary keying compiled function signatures to the
control-flow graph of the disassembly of the underlying compiled ``ELF``
object. If the signature keyword is specified a control-flow graph
corresponding to that individual signature is returned. This function is
execution environment aware and will produce SVG output in Jupyter
notebooks and ASCII in terminals.
Example::
@njit
def foo(x):
if x < 3:
return x + 1
return x + 2
foo(10)
print(foo.inspect_disasm_cfg(signature=foo.signatures[0]))
Gives::
[0x08000040]> # method.__main__.foo_241_long_long (int64_t arg1, int64_t arg3);
─────────────────────────────────────────────────────────────────────┐
│ 0x8000040 │
│ ; arg3 ; [02] -r-x section size 279 named .text │
│ ;-- section..text: │
│ ;-- .text: │
│ ;-- __main__::foo$241(long long): │
│ ;-- rip: │
│ 25: method.__main__.foo_241_long_long (int64_t arg1, int64_t arg3); │
│ ; arg int64_t arg1 @ rdi │
│ ; arg int64_t arg3 @ rdx │
│ ; 2 │
│ cmp rdx, 2 │
│ jg 0x800004f │
└─────────────────────────────────────────────────────────────────────┘
f t
│ │
│ └──────────────────────────────┐
└──┐ │
│ │
┌─────────────────────────┐ ┌─────────────────────────┐
│ 0x8000046 │ │ 0x800004f │
│ ; arg3 │ │ ; arg3 │
│ inc rdx │ │ add rdx, 2 │
│ ; arg3 │ │ ; arg3 │
│ mov qword [rdi], rdx │ │ mov qword [rdi], rdx │
│ xor eax, eax │ │ xor eax, eax │
│ ret │ │ ret │
└─────────────────────────┘ └─────────────────────────┘
.. method:: recompile()
Recompile all existing signatures. This can be useful for example if
a global or closure variable was frozen by your function and its value
in Python has changed. Since compiling isn't cheap, this is mainly
for testing and interactive use.
.. method:: parallel_diagnostics(signature=None, level=1)
Print parallel diagnostic information for the given signature. If no
signature is present it is printed for all known signatures. ``level`` is
used to adjust the verbosity, ``level=1`` (default) is minimum verbosity,
levels 2, 3, and 4 provide increasing levels of verbosity.
.. method:: get_metadata(signature=None)
Obtain the compilation metadata for a given signature. This is useful for
developers of Numba and Numba extensions.
Vectorized functions (ufuncs and DUFuncs)
-----------------------------------------
.. decorator:: numba.vectorize(*, signatures=[], identity=None, nopython=True, target='cpu', forceobj=False, cache=False, locals={})
Compile the decorated function and wrap it either as a `NumPy
ufunc`_ or a Numba :class:`~numba.DUFunc`. The optional
*nopython*, *forceobj* and *locals* arguments have the same meaning
as in :func:`numba.jit`.
*signatures* is an optional list of signatures expressed in the
same form as in the :func:`numba.jit` *signature* argument. If
*signatures* is non-empty, then the decorator will compile the user
Python function into a NumPy ufunc. If no *signatures* are given,
then the decorator will wrap the user Python function in a
:class:`~numba.DUFunc` instance, which will compile the user
function at call time whenever NumPy can not find a matching loop
for the input arguments. *signatures* is required if *target* is
``"parallel"``.
*identity* is the identity (or unit) value of the function being
implemented. Possible values are 0, 1, None, and the string
``"reorderable"``. The default is None. Both None and
``"reorderable"`` mean the function has no identity value;
``"reorderable"`` additionally specifies that reductions along multiple
axes can be reordered.
If there are several *signatures*, they must be ordered from the more
specific to the least specific. Otherwise, NumPy's type-based
dispatching may not work as expected. For example, the following is
wrong::
@vectorize(["float64(float64)", "float32(float32)"])
def f(x): ...
as running it over a single-precision array will choose the ``float64``
version of the compiled function, leading to much less efficient
execution. The correct invocation is::
@vectorize(["float32(float32)", "float64(float64)"])
def f(x): ...
*target* is a string for backend target; Available values are "cpu",
"parallel", and "cuda". To use a multithreaded version, change the
target to "parallel" (which requires signatures to be specified)::
@vectorize(["float64(float64)", "float32(float32)"], target='parallel')
def f(x): ...
For the CUDA target, use "cuda"::
@vectorize(["float64(float64)", "float32(float32)"], target='cuda')
def f(x): ...
The compiled function can be cached to reduce future compilation time.
It is enabled by setting *cache* to True. Only the "cpu" and "parallel"
targets support caching.
The ufuncs created by this function respect `NEP-13 <https://numpy.org/neps/nep-0013-ufunc-overrides.html>`_,
NumPy's mechanism for overriding ufuncs. If any of the arguments of the
ufunc's ``__call__`` have a ``__array_ufunc__`` method, that method will
be called (in Python, not the compiled context), which may pre-process
and/or post-process the arguments and return value of the compiled ufunc
(or might not even call it).
.. decorator:: numba.guvectorize(signatures, layout, *, identity=None, nopython=True, target='cpu', forceobj=False, cache=False, locals={})
Generalized version of :func:`numba.vectorize`. While
:func:`numba.vectorize` will produce a simple ufunc whose core
functionality (the function you are decorating) operates on scalar
operands and returns a scalar value, :func:`numba.guvectorize`
allows you to create a `NumPy ufunc`_ whose core function takes array
arguments of various dimensions.
The additional argument *layout* is a string specifying, in symbolic
form, the dimensionality and size relationship of the argument types
and return types. For example, a matrix multiplication will have
a layout string of ``"(m,n),(n,p)->(m,p)"``. Its definition might
be (function body omitted)::
@guvectorize(["void(float64[:,:], float64[:,:], float64[:,:])"],
"(m,n),(n,p)->(m,p)")
def f(a, b, result):
"""Fill-in *result* matrix such as result := a * b"""
...
If one of the arguments should be a scalar, the corresponding layout
specification is ``()`` and the argument will really be given to
you as a zero-dimension array (you have to dereference it to get the
scalar value). For example, a :ref:`one-dimension moving average <example-movemean>`
with a parameterable window width may have a layout string of ``"(n),()->(n)"``.
Note that any output will be given to you preallocated as an additional
function argument: your code has to fill it with the appropriate values
for the function you are implementing.
If your function doesn't take an output array, you should omit the "arrow"
in the layout string (e.g. ``"(n),(n)"``). When doing this, it is important
to be aware that changes to the input arrays cannot always be relied on to be
visible outside the execution of the ufunc, as NumPy may pass in temporary
arrays as inputs (for example, if a cast is required).
.. seealso::
Specification of the `layout string <https://numpy.org/doc/stable/reference/c-api/generalized-ufuncs.html#details-of-signature>`_
as supported by NumPy. Note that NumPy uses the term "signature",
which we unfortunately use for something else.
The compiled function can be cached to reduce future compilation time.
It is enabled by setting *cache* to True. Only the "cpu" and "parallel"
targets support caching.
.. _NumPy ufunc: http://docs.scipy.org/doc/numpy/reference/ufuncs.html
.. class:: numba.DUFunc
The class of objects created by calling :func:`numba.vectorize`
with no signatures.
DUFunc instances should behave similarly to NumPy
:class:`~numpy.ufunc` objects with one important difference:
call-time loop generation. When calling a ufunc, NumPy looks at
the existing loops registered for that ufunc, and will raise a
:class:`~python.TypeError` if it cannot find a loop that it cannot
safely cast the inputs to suit. When calling a DUFunc, Numba
delegates the call to NumPy. If the NumPy ufunc call fails, then
Numba attempts to build a new loop for the given input types, and
calls the ufunc again. If this second call attempt fails or a
compilation error occurs, then DUFunc passes along the exception to
the caller.
.. seealso::
The ":ref:`dynamic-universal-functions`" section in the user's
guide demonstrates the call-time behavior of
:class:`~numba.DUFunc`, and discusses the impact of call order
on how Numba generates the underlying :class:`~numpy.ufunc`.
.. attribute:: ufunc
The actual NumPy :class:`~numpy.ufunc` object being built by the
:class:`~numba.DUFunc` instance. Note that the
:class:`~numba.DUFunc` object maintains several important data
structures required for proper ufunc functionality (specifically
the dynamically compiled loops). Users should not pass the
:class:`~numpy.ufunc` value around without ensuring the
underlying :class:`~numba.DUFunc` will not be garbage collected.
.. attribute:: nin
The number of DUFunc (ufunc) inputs. See `ufunc.nin`_.
.. attribute:: nout
The number of DUFunc outputs. See `ufunc.nout`_.
.. attribute:: nargs
The total number of possible DUFunc arguments (should be
:attr:`~numba.DUFunc.nin` + :attr:`~numba.DUFunc.nout`).
See `ufunc.nargs`_.
.. attribute:: ntypes
The number of input types supported by the DUFunc. See
`ufunc.ntypes`_.
.. attribute:: types
A list of the supported types given as strings. See
`ufunc.types`_.
.. attribute:: identity
The identity value when using the ufunc as a reduction. See
`ufunc.identity`_.
.. method:: reduce(A, *, axis, dtype, out, keepdims)
Reduces *A*\'s dimension by one by applying the DUFunc along one
axis. See `ufunc.reduce`_.
.. method:: accumulate(A, *, axis, dtype, out)
Accumulate the result of applying the operator to all elements.
See `ufunc.accumulate`_.
.. method:: reduceat(A, indices, *, axis, dtype, out)
Performs a (local) reduce with specified slices over a single
axis. See `ufunc.reduceat`_.
.. method:: outer(A, B)
Apply the ufunc to all pairs (*a*, *b*) with *a* in *A*, and *b*
in *B*. See `ufunc.outer`_.
.. method:: at(A, indices, *, B)
Performs unbuffered in place operation on operand *A* for
elements specified by *indices*. If you are using NumPy 1.7 or
earlier, this method will not be present. See `ufunc.at`_.
.. note::
Vectorized functions can, in rare circumstances, show
:ref:`unexpected warnings or errors <ufunc-fpu-errors>`.
.. _`ufunc.nin`: http://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.nin.html#numpy.ufunc.nin
.. _`ufunc.nout`: http://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.nout.html#numpy.ufunc.nout
.. _`ufunc.nargs`: http://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.nargs.html#numpy.ufunc.nargs
.. _`ufunc.ntypes`: http://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.ntypes.html#numpy.ufunc.ntypes
.. _`ufunc.types`: http://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.types.html#numpy.ufunc.types
.. _`ufunc.identity`: http://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.identity.html#numpy.ufunc.identity
.. _`ufunc.reduce`: http://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.reduce.html#numpy.ufunc.reduce
.. _`ufunc.accumulate`: http://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.accumulate.html#numpy.ufunc.accumulate
.. _`ufunc.reduceat`: http://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.reduceat.html#numpy.ufunc.reduceat
.. _`ufunc.outer`: http://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.outer.html#numpy.ufunc.outer
.. _`ufunc.at`: http://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.at.html#numpy.ufunc.at
C callbacks
-----------
.. decorator:: numba.cfunc(signature, nopython=False, cache=False, locals={})
Compile the decorated function on-the-fly to produce efficient machine
code. The compiled code is wrapped in a thin C callback that makes it
callable using the natural C ABI.
The *signature* is a single signature representing the signature of the
C callback. It must have the same form as in :func:`~numba.jit`.
The decorator does not check that the types in the signature have
a well-defined representation in C.
*nopython* and *cache* are boolean flags. *locals* is a mapping of
local variable names to :ref:`numba-types`. They all have the same
meaning as in :func:`~numba.jit`.
The decorator returns a :class:`CFunc` object.
.. note::
C callbacks currently do not support :term:`object mode`.
.. class:: CFunc
The class of objects created by :func:`~numba.cfunc`. :class:`CFunc`
objects expose the following attributes and methods:
.. attribute:: address
The address of the compiled C callback, as an integer.
.. attribute:: cffi
A `cffi`_ function pointer instance, to be passed as an argument to
`cffi`_-wrapped functions. The pointer's type is ``void *``, so
only minimal type checking will happen when passing it to `cffi`_.
.. attribute:: ctypes
A :mod:`ctypes` callback instance, as if it were created using
:func:`ctypes.CFUNCTYPE`.
.. attribute:: native_name
The name of the compiled C callback.
.. method:: inspect_llvm()
Return the human-readable LLVM IR generated for the C callback.
:attr:`native_name` is the name under which this callback is defined
in the IR.
.. _cffi: https://cffi.readthedocs.org/
.. _numpy-support:
========================
Supported NumPy features
========================
One objective of Numba is having a seamless integration with `NumPy`_.
NumPy arrays provide an efficient storage method for homogeneous sets of
data. NumPy dtypes provide type information useful when compiling, and
the regular, structured storage of potentially large amounts of data
in memory provides an ideal memory layout for code generation. Numba
excels at generating code that executes on top of NumPy arrays.
NumPy support in Numba comes in many forms:
* Numba understands calls to NumPy `ufuncs`_ and is able to generate
equivalent native code for many of them.
* NumPy arrays are directly supported in Numba. Access to NumPy arrays
is very efficient, as indexing is lowered to direct memory accesses
when possible.
* Numba is able to generate `ufuncs`_ and `gufuncs`_. This means that it
is possible to implement ufuncs and gufuncs within Python, getting
speeds comparable to that of ufuncs/gufuncs implemented in C extension
modules using the NumPy C API.
.. _NumPy: http://www.numpy.org/
.. _ufuncs: http://docs.scipy.org/doc/numpy/reference/ufuncs.html
.. _gufuncs: http://docs.scipy.org/doc/numpy/reference/c-api.generalized-ufuncs.html
The following sections focus on the NumPy features supported in
:term:`nopython mode`, unless otherwise stated.
Scalar types
============
Numba supports the following NumPy scalar types:
* **Integers**: all integers of either signedness, and any width up to 64 bits
* **Booleans**
* **Real numbers:** single-precision (32-bit) and double-precision (64-bit) reals
* **Complex numbers:** single-precision (2x32-bit) and double-precision (2x64-bit) complex numbers
* **Datetimes and timestamps:** of any unit
* **Character sequences** (but no operations are available on them)
* **Structured scalars:** structured scalars made of any of the types above and arrays of the types above
The following scalar types and features are not supported:
* **Arbitrary Python objects**
* **Half-precision and extended-precision** real and complex numbers
* **Nested structured scalars** the fields of structured scalars may not contain other structured scalars
The operations supported on NumPy scalars are almost the same as on the
equivalent built-in types such as ``int`` or ``float``. You can use a type's
constructor to convert from a different type or width. In addition you can use
the ``view(np.<dtype>)`` method to bitcast all ``int`` and ``float`` types
within the same width. However, you must define the scalar using a NumPy
constructor within a jitted function. For example, the following will work:
.. code:: pycon
>>> import numpy as np
>>> from numba import njit
>>> @njit
... def bitcast():
... i = np.int64(-1)
... print(i.view(np.uint64))
...
>>> bitcast()
18446744073709551615
Whereas the following will not work:
.. code:: pycon
>>> import numpy as np
>>> from numba import njit
>>> @njit
... def bitcast(i):
... print(i.view(np.uint64))
...
>>> bitcast(np.int64(-1))
---------------------------------------------------------------------------
TypingError Traceback (most recent call last)
...
TypingError: Failed in nopython mode pipeline (step: ensure IR is legal prior to lowering)
'view' can only be called on NumPy dtypes, try wrapping the variable with 'np.<dtype>()'
File "<ipython-input-3-fc40aaab84c4>", line 3:
def bitcast(i):
print(i.view(np.uint64))
Structured scalars support attribute getting and setting, as well as
member lookup using constant strings. Strings stored in a local or global tuple
are considered constant strings and can be used for member lookup.
.. literalinclude:: ../../../numba/tests/doc_examples/test_rec_array.py
:language: python
:start-after: magictoken.ex_rec_arr_const_index.begin
:end-before: magictoken.ex_rec_arr_const_index.end
:dedent: 8
It is also possible to use local or global tuples together with ``literal_unroll``:
.. literalinclude:: ../../../numba/tests/doc_examples/test_rec_array.py
:language: python
:start-after: magictoken.ex_rec_arr_lit_unroll_index.begin
:end-before: magictoken.ex_rec_arr_lit_unroll_index.end
:dedent: 8
Record subtyping
----------------
.. warning::
This is an experimental feature.
Numba allows `width subtyping <https://en.wikipedia.org/wiki/Subtyping#Record_types>`_ of structured scalars.
For example, ``dtype([('a', 'f8'), ('b', 'i8')])`` will be considered a subtype of ``dtype([('a', 'f8')]``, because
the second is a strict subset of the first, i.e. field ``a`` is of the same type and is in the same position in both
types. The subtyping relationship will matter in cases where compilation for a certain input is not allowed, but the
input is a subtype of another, allowed type.
.. code-block:: python
import numpy as np
from numba import njit, typeof
from numba.core import types
record1 = np.array([1], dtype=[('a', 'f8')])[0]
record2 = np.array([(2,3)], dtype=[('a', 'f8'), ('b', 'f8')])[0]
@njit(types.float64(typeof(record1)))
def foo(rec):
return rec['a']
foo(record1)
foo(record2)
Without subtyping the last line would fail. With subtyping, no new compilation will be triggered, but the
compiled function for ``record1`` will be used for ``record2``.
.. seealso::
`NumPy scalars <http://docs.scipy.org/doc/numpy/reference/arrays.scalars.html>`_
reference.
Array types
===========
`NumPy arrays <http://docs.scipy.org/doc/numpy/reference/arrays.ndarray.html>`_
of any of the scalar types above are supported, regardless of the shape
or layout.
.. note::
`NumPy MaskedArrays <https://numpy.org/doc/stable/reference/maskedarray.html>`_
are not supported.
Array access
------------
Arrays support normal iteration. Full basic indexing and slicing is
supported along with passing ``None`` / ``np.newaxis`` as indices for
additional resulting dimensions. A subset of advanced indexing is also
supported: only one advanced index is allowed, and it has to be a
one-dimensional array (it can be combined with an arbitrary number
of basic indices as well).
.. seealso::
`NumPy indexing <http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html>`_
reference.
.. _structured-array-access:
Structured array access
-----------------------
Numba presently supports accessing fields of individual elements in structured
arrays by attribute as well as by getting and setting. This goes slightly
beyond the NumPy API, which only allows accessing fields by getting and
setting. For example:
.. code:: python
from numba import njit
import numpy as np
record_type = np.dtype([("ival", np.int32), ("fval", np.float64)], align=True)
def f(rec):
value = 2.5
rec[0].ival = int(value)
rec[0].fval = value
return rec
arr = np.ones(1, dtype=record_type)
cfunc = njit(f)
# Works
print(cfunc(arr))
# Does not work
print(f(arr))
The above code results in the output:
.. code:: none
[(2, 2.5)]
Traceback (most recent call last):
File "repro.py", line 22, in <module>
print(f(arr))
File "repro.py", line 9, in f
rec[0].ival = int(value)
AttributeError: 'numpy.void' object has no attribute 'ival'
The Numba-compiled version of the function executes, but the pure Python
version raises an error because of the unsupported use of attribute access.
.. note::
This behavior will eventually be deprecated and removed.
Attributes
----------
The following attributes of NumPy arrays are supported:
* :attr:`~numpy.ndarray.dtype`
* :attr:`~numpy.ndarray.flags`
* :attr:`~numpy.ndarray.flat`
* :attr:`~numpy.ndarray.itemsize`
* :attr:`~numpy.ndarray.nbytes`
* :attr:`~numpy.ndarray.ndim`
* :attr:`~numpy.ndarray.shape`
* :attr:`~numpy.ndarray.size`
* :attr:`~numpy.ndarray.strides`
* :attr:`~numpy.ndarray.T`
* :attr:`~numpy.ndarray.real`
* :attr:`~numpy.ndarray.imag`
The ``flags`` object
''''''''''''''''''''
The object returned by the :attr:`~numpy.ndarray.flags` attribute supports
the ``contiguous``, ``c_contiguous`` and ``f_contiguous`` attributes.
The ``flat`` object
'''''''''''''''''''
The object returned by the :attr:`~numpy.ndarray.flat` attribute supports
iteration and indexing, but be careful: indexing is very slow on
non-C-contiguous arrays.
The ``real`` and ``imag`` attributes
''''''''''''''''''''''''''''''''''''
NumPy supports these attributes regardless of the dtype but Numba chooses to
limit their support to avoid potential user error. For numeric dtypes,
Numba follows NumPy's behavior. The :attr:`~numpy.ndarray.real` attribute
returns a view of the real part of the complex array and it behaves as an identity
function for other numeric dtypes. The :attr:`~numpy.ndarray.imag` attribute
returns a view of the imaginary part of the complex array and it returns a zero
array with the same shape and dtype for other numeric dtypes. For non-numeric
dtypes, including all structured/record dtypes, using these attributes will
result in a compile-time (`TypingError`) error. This behavior differs from
NumPy's but it is chosen to avoid the potential confusion with field names that
overlap these attributes.
Calculation
-----------
The following methods of NumPy arrays are supported in their basic form
(without any optional arguments):
* :meth:`~numpy.ndarray.all`
* :meth:`~numpy.ndarray.any`
* :meth:`~numpy.ndarray.clip`
* :meth:`~numpy.ndarray.conj`
* :meth:`~numpy.ndarray.conjugate`
* :meth:`~numpy.ndarray.cumprod`
* :meth:`~numpy.ndarray.cumsum`
* :meth:`~numpy.ndarray.max`
* :meth:`~numpy.ndarray.mean`
* :meth:`~numpy.ndarray.min`
* :meth:`~numpy.ndarray.nonzero`
* :meth:`~numpy.ndarray.prod`
* :meth:`~numpy.ndarray.std`
* :meth:`~numpy.ndarray.take`
* :meth:`~numpy.ndarray.var`
The corresponding top-level NumPy functions (such as :func:`numpy.prod`)
are similarly supported.
Other methods
-------------
The following methods of NumPy arrays are supported:
* :meth:`~numpy.ndarray.argmax` (``axis`` keyword argument supported).
* :meth:`~numpy.ndarray.argmin` (``axis`` keyword argument supported).
* :func:`numpy.argpartition` (only the 2 first arguments)
* :meth:`~numpy.ndarray.argsort` (``kind`` key word argument supported for
values ``'quicksort'`` and ``'mergesort'``)
* :meth:`~numpy.ndarray.astype` (only the 1-argument form)
* :meth:`~numpy.ndarray.copy` (without arguments)
* :meth:`~numpy.ndarray.dot` (only the 1-argument form)
* :meth:`~numpy.ndarray.flatten` (no order argument; 'C' order only)
* :meth:`~numpy.ndarray.item` (without arguments)
* :meth:`~numpy.ndarray.itemset` (only the 1-argument form)
* :meth:`~numpy.ndarray.ptp` (without arguments)
* :meth:`~numpy.ndarray.ravel` (no order argument; 'C' order only)
* :meth:`~numpy.ndarray.repeat` (no axis argument)
* :meth:`~numpy.ndarray.reshape` (only the 1-argument form)
* :meth:`~numpy.ndarray.sort` (without arguments)
* :meth:`~numpy.ndarray.sum` (with or without the ``axis`` and/or ``dtype``
arguments.)
* ``axis`` only supports ``integer`` values.
* If the ``axis`` argument is a compile-time constant, all valid values
are supported.
An out-of-range value will result in a ``LoweringError`` at compile-time.
* If the ``axis`` argument is not a compile-time constant, only values
from 0 to 3 are supported.
An out-of-range value will result in a runtime exception.
* All numeric ``dtypes`` are supported in the ``dtype`` parameter.
``timedelta`` arrays can be used as input arrays but ``timedelta`` is not
supported as ``dtype`` parameter.
* When a ``dtype`` is given, it determines the type of the internal
accumulator. When it is not, the selection is made automatically based on
the input array's ``dtype``, mostly following the same rules as NumPy.
However, on 64-bit Windows, Numba uses a 64-bit accumulator for integer
inputs (``int64`` for ``int32`` inputs and ``uint64`` for ``uint32``
inputs), while NumPy would use a 32-bit accumulator in those cases.
* :meth:`~numpy.ndarray.transpose`
* :meth:`~numpy.ndarray.view` (only the 1-argument form)
* :meth:`~numpy.ndarray.__contains__`
Where applicable, the corresponding top-level NumPy functions (such as
:func:`numpy.argmax`) are similarly supported.
.. warning::
Sorting may be slightly slower than NumPy's implementation.
Functions
=========
Linear algebra
--------------
Basic linear algebra is supported on 1-D and 2-D contiguous arrays of
floating-point and complex numbers:
* :func:`numpy.dot`
* :func:`numpy.kron` ('C' and 'F' order only)
* :func:`numpy.outer`
* :func:`numpy.trace` (only the first argument).
* :func:`numpy.vdot`
* On Python 3.5 and above, the matrix multiplication operator from
:pep:`465` (i.e. ``a @ b`` where ``a`` and ``b`` are 1-D or 2-D arrays).
* :func:`numpy.linalg.cholesky`
* :func:`numpy.linalg.cond` (only non string values in ``p``).
* :func:`numpy.linalg.det`
* :func:`numpy.linalg.eig` (only running with data that does not cause a domain
change is supported e.g. real input -> real
output, complex input -> complex output).
* :func:`numpy.linalg.eigh` (only the first argument).
* :func:`numpy.linalg.eigvals` (only running with data that does not cause a
domain change is supported e.g. real input -> real output,
complex input -> complex output).
* :func:`numpy.linalg.eigvalsh` (only the first argument).
* :func:`numpy.linalg.inv`
* :func:`numpy.linalg.lstsq`
* :func:`numpy.linalg.matrix_power`
* :func:`numpy.linalg.matrix_rank`
* :func:`numpy.linalg.norm` (only the 2 first arguments and only non string
values in ``ord``).
* :func:`numpy.linalg.pinv`
* :func:`numpy.linalg.qr` (only the first argument).
* :func:`numpy.linalg.slogdet`
* :func:`numpy.linalg.solve`
* :func:`numpy.linalg.svd` (only the 2 first arguments).
.. note::
The implementation of these functions needs SciPy to be installed.
Reductions
----------
The following reduction functions are supported:
* :func:`numpy.diff` (only the 2 first arguments)
* :func:`numpy.amin` (only the first argument, also aliased as np.min)
* :func:`numpy.amax` (only the first argument, also aliased as np.max)
* :func:`numpy.median` (only the first argument)
* :func:`numpy.nancumprod` (only the first argument)
* :func:`numpy.nancumsum` (only the first argument)
* :func:`numpy.nanmax` (only the first argument)
* :func:`numpy.nanmean` (only the first argument)
* :func:`numpy.nanmedian` (only the first argument)
* :func:`numpy.nanmin` (only the first argument)
* :func:`numpy.nanpercentile` (only the 2 first arguments, complex dtypes
unsupported)
* :func:`numpy.nanquantile` (only the 2 first arguments, complex dtypes
unsupported)
* :func:`numpy.nanprod` (only the first argument)
* :func:`numpy.nanstd` (only the first argument)
* :func:`numpy.nansum` (only the first argument)
* :func:`numpy.nanvar` (only the first argument)
* :func:`numpy.percentile` (only the 2 first arguments, complex dtypes
unsupported)
* :func:`numpy.quantile` (only the 2 first arguments, complex dtypes
unsupported)
Polynomials
-----------
The following polynomial functions are supported:
* :func:`numpy.polynomial.polynomial.polyadd()`
* :func:`numpy.polynomial.polynomial.polymul()`
* :func:`numpy.polynomial.polynomial.polysub()`
* :func:`numpy.polynomial.polyutils.trimseq()`
Other functions
---------------
The following top-level functions are supported:
* :func:`numpy.allclose`
* :func:`numpy.append`
* :func:`numpy.arange`
* :func:`numpy.argsort` (``kind`` key word argument supported for values
``'quicksort'`` and ``'mergesort'``)
* :func:`numpy.argwhere`
* :func:`numpy.around`
* :func:`numpy.array` (only the 2 first arguments)
* :func:`numpy.array_equal`
* :func:`numpy.array_split`
* :func:`numpy.asarray` (only the 2 first arguments)
* :func:`numpy.asarray_chkfinite` (only the 2 first arguments)
* :func:`numpy.ascontiguousarray` (only the first argument)
* :func:`numpy.asfarray`
* :func:`numpy.asfortranarray` (only the first argument)
* :func:`numpy.atleast_1d`
* :func:`numpy.atleast_2d`
* :func:`numpy.atleast_3d`
* :func:`numpy.bartlett`
* :func:`numpy.bincount`
* :func:`numpy.blackman`
* :func:`numpy.broadcast_to` (only the 2 first arguments)
* :func:`numpy.broadcast_arrays` (only the first argument)
* :func:`numpy.broadcast_shapes`
* :func:`numpy.column_stack`
* :func:`numpy.concatenate` (only supports tuple arguments)
* :func:`numpy.convolve` (all arguments)
* :func:`numpy.copy` (only the first argument)
* :func:`numpy.corrcoef` (only the 3 first arguments, requires SciPy)
* :func:`numpy.correlate` (all arguments)
* :func:`numpy.count_nonzero` (axis only supports scalar values)
* :func:`numpy.cov` (only the 5 first arguments)
* :func:`numpy.cross` (only the 2 first arguments; at least one of the input
arrays should have ``shape[-1] == 3``)
* If ``shape[-1] == 2`` for both inputs, please replace your
:func:`numpy.cross` call with :func:`numba.np.extensions.cross2d`.
* :func:`numpy.delete` (only the 2 first arguments)
* :func:`numpy.diag`
* :func:`numpy.diagflat`
* :func:`numpy.digitize`
* :func:`numpy.dsplit`
* :func:`numpy.dstack`
* :func:`numpy.dtype` (only the first argument)
* :func:`numpy.ediff1d`
* :func:`numpy.empty` (only the 2 first arguments)
* :func:`numpy.empty_like` (only the 2 first arguments)
* :func:`numpy.expand_dims`
* :func:`numpy.extract`
* :func:`numpy.eye`
* :func:`numpy.fill_diagonal`
* :func:`numpy.flatten` (no order argument; 'C' order only)
* :func:`numpy.flatnonzero`
* :func:`numpy.flip` (no axis argument)
* :func:`numpy.fliplr`
* :func:`numpy.flipud`
* :func:`numpy.frombuffer` (only the 2 first arguments)
* :func:`numpy.full` (only the 3 first arguments)
* :func:`numpy.full_like` (only the 3 first arguments)
* :func:`numpy.geomspace` (only the 3 first arguments)
* :func:`numpy.hamming`
* :func:`numpy.hanning`
* :func:`numpy.histogram` (only the 3 first arguments)
* :func:`numpy.hsplit`
* :func:`numpy.hstack`
* :func:`numpy.identity`
* :func:`numpy.isclose`
* :func:`numpy.kaiser`
* :func:`numpy.iscomplex`
* :func:`numpy.iscomplexobj`
* :func:`numpy.isneginf`
* :func:`numpy.isposinf`
* :func:`numpy.isreal`
* :func:`numpy.isrealobj`
* :func:`numpy.isscalar`
* :func:`numpy.interp` (only the 3 first arguments)
* :func:`numpy.intersect1d` (only first 2 arguments, ar1 and ar2)
* :func:`numpy.linspace` (only the 3-argument form)
* :func:`numpy.logspace` (only the 3 first arguments)
* :func:`numpy.nan_to_num` (only the 3 first arguments)
* :class:`numpy.ndenumerate`
* :class:`numpy.ndindex`
* :class:`numpy.nditer` (only the first argument)
* :func:`numpy.ones` (only the 2 first arguments)
* :func:`numpy.ones_like` (only the 2 first arguments)
* :func:`numpy.partition` (only the 2 first arguments)
* :func:`numpy.ptp` (only the first argument)
* :func:`numpy.ravel` (no order argument; 'C' order only)
* :func:`numpy.repeat` (no axis argument)
* :func:`numpy.reshape` (no order argument; 'C' order only)
* :func:`numpy.resize`
* :func:`numpy.roll` (only the 2 first arguments; second argument ``shift``
must be an integer)
* :func:`numpy.roots`
* :func:`numpy.rot90` (only the 2 first arguments)
* :func:`numpy.round_`
* :func:`numpy.row_stack`
* :func:`numpy.searchsorted` (only the 3 first arguments)
* :func:`numpy.select` (only using homogeneous lists or tuples for the first
two arguments, condlist and choicelist). Additionally, these two arguments
can only contain arrays (unlike NumPy that also accepts tuples).
* :func:`numpy.shape`
* :func:`numpy.sinc`
* :func:`numpy.sort` (no optional arguments, quicksort accepts
multi-dimensional array and sorts its last axis).
* :func:`numpy.split`
* :func:`numpy.stack` (only the first two arguments are supported)
* :func:`numpy.swapaxes`
* :func:`numpy.take` (only the 2 first arguments)
* :func:`numpy.take_along_axis` (the axis argument must be a literal value)
* :func:`numpy.transpose`
* :func:`numpy.trapz` (only the 3 first arguments)
* :func:`numpy.tri` (only the 3 first arguments; third argument ``k`` must be an integer)
* :func:`numpy.tril` (second argument ``k`` must be an integer)
* :func:`numpy.tril_indices` (all arguments must be integer)
* :func:`numpy.tril_indices_from` (second argument ``k`` must be an integer)
* :func:`numpy.trim_zeros` (for NumPy array arguments only)
* :func:`numpy.triu` (second argument ``k`` must be an integer)
* :func:`numpy.triu_indices` (all arguments must be integer)
* :func:`numpy.triu_indices_from` (second argument ``k`` must be an integer)
* :func:`numpy.union1d` (For unicode arrays, only supports arrays of the same dtype)
* :func:`numpy.unique` (only the first argument)
* :func:`numpy.vander`
* :func:`numpy.vsplit`
* :func:`numpy.vstack`
* :func:`numpy.where`
* :func:`numpy.zeros` (only the 2 first arguments)
* :func:`numpy.zeros_like` (only the 2 first arguments)
The following constructors are supported, both with a numeric input (to
construct a scalar) or a sequence (to construct an array):
* :class:`numpy.bool_`
* :class:`numpy.complex64`
* :class:`numpy.complex128`
* :class:`numpy.float32`
* :class:`numpy.float64`
* :class:`numpy.int8`
* :class:`numpy.int16`
* :class:`numpy.int32`
* :class:`numpy.int64`
* :class:`numpy.intc`
* :class:`numpy.intp`
* :class:`numpy.uint8`
* :class:`numpy.uint16`
* :class:`numpy.uint32`
* :class:`numpy.uint64`
* :class:`numpy.uintc`
* :class:`numpy.uintp`
The following machine parameter classes are supported, with all purely numerical
attributes:
* :class:`numpy.iinfo`
* :class:`numpy.finfo` (``machar`` attribute not supported)
* :class:`numpy.MachAr` (with no arguments to the constructor)
Literal arrays
--------------
.. XXX should this part of the user's guide?
Neither Python nor Numba has actual array literals, but you can construct
arbitrary arrays by calling :func:`numpy.array` on a nested tuple::
a = numpy.array(((a, b, c), (d, e, f)))
(nested lists are not yet supported by Numba)
Modules
=======
.. _numpy-random:
``random``
----------
Generator Objects
'''''''''''''''''
Numba supports :py:class:`numpy.random.Generator()` objects. As of version 0.56, users can pass
individual NumPy :py:class:`Generator` objects into Numba functions and use their
methods inside the functions. The same algorithms are used as NumPy for
random number generation hence maintaining parity between the random
number generated using NumPy and Numba under identical arguments
(also the same documentation notes as NumPy :py:class:`Generator` methods apply).
The current Numba support for :py:class:`Generator` is not thread-safe, hence we
do not recommend using :py:class:`Generator` methods in methods with parallel
execution logic.
.. note::
NumPy's :py:class:`Generator` objects rely on :py:class:`BitGenerator` to manage state
and generate the random bits, which are then transformed into random
values from useful distributions. Numba will ``unbox`` the :py:class:`Generator` objects
and will maintain a reference to the underlying :py:class:`BitGenerator` objects using NumPy's
``ctypes`` interface bindings. Hence :py:class:`Generator` objects can cross the JIT boundary
and their functions be used within Numba-Jit code. Note that since only references
to :py:class:`BitGenerator` objects are maintained, any change to the state of a particular
:py:class:`Generator` object outside Numba code would affect the state of :py:class:`Generator`
inside the Numba code.
.. literalinclude:: ../../../numba/tests/doc_examples/test_numpy_generators.py
:language: python
:start-after: magictoken.npgen_usage.begin
:end-before: magictoken.npgen_usage.end
:dedent: 8
The following :py:class:`Generator` methods are supported:
* :func:`numpy.random.Generator().beta()`
* :func:`numpy.random.Generator().chisquare()`
* :func:`numpy.random.Generator().exponential()`
* :func:`numpy.random.Generator().f()`
* :func:`numpy.random.Generator().gamma()`
* :func:`numpy.random.Generator().geometric()`
* :func:`numpy.random.Generator().integers()` (Both `low` and `high` are required
arguments. Array values for low and high are currently not supported.)
* :func:`numpy.random.Generator().laplace()`
* :func:`numpy.random.Generator().logistic()`
* :func:`numpy.random.Generator().lognormal()`
* :func:`numpy.random.Generator().logseries()` (Accepts float values as well as
data types that cast to floats. Array values for ``p`` are currently not
supported.)
* :func:`numpy.random.Generator().negative_binomial()`
* :func:`numpy.random.Generator().noncentral_chisquare()` (Accepts float values
as well as data types that cast to floats. Array values for ``dfnum`` and
``nonc`` are currently not supported.)
* :func:`numpy.random.Generator().noncentral_f()` (Accepts float values as well
as data types that cast to floats. Array values for ``dfnum``, ``dfden`` and
``nonc`` are currently not supported.)
* :func:`numpy.random.Generator().normal()`
* :func:`numpy.random.Generator().pareto()`
* :func:`numpy.random.Generator().permutation()` (Only accepts NumPy ndarrays and integers.)
* :func:`numpy.random.Generator().poisson()`
* :func:`numpy.random.Generator().power()`
* :func:`numpy.random.Generator().random()`
* :func:`numpy.random.Generator().rayleigh()`
* :func:`numpy.random.Generator().shuffle()` (Only accepts NumPy ndarrays.)
* :func:`numpy.random.Generator().standard_cauchy()`
* :func:`numpy.random.Generator().standard_exponential()`
* :func:`numpy.random.Generator().standard_gamma()`
* :func:`numpy.random.Generator().standard_normal()`
* :func:`numpy.random.Generator().standard_t()`
* :func:`numpy.random.Generator().triangular()`
* :func:`numpy.random.Generator().uniform()`
* :func:`numpy.random.Generator().wald()`
* :func:`numpy.random.Generator().weibull()`
* :func:`numpy.random.Generator().zipf()`
.. note::
Due to instruction selection differences across compilers, there
may be discrepancies, when compared to NumPy, in the order of 1000s
of ULPs on 32-bit architectures as well as linux-aarch64 and linux-
ppc64le platforms. For Linux-x86_64, Windows-x86_64 and macOS these
discrepancies are less pronounced (order of 10s of ULPs) but are not
guaranteed to follow the exception pattern and may increase in some
cases.
The differences are unlikely to impact the "quality" of the random
number generation as they occur through changes in rounding that
happen when fused-multiply-add is used instead of multiplication
followed by addition.
RandomState and legacy Random number generation
'''''''''''''''''''''''''''''''''''''''''''''''
Numba supports top-level functions from the
`numpy.random <http://docs.scipy.org/doc/numpy/reference/routines.random.html>`_
module, but does not allow you to create individual RandomState instances.
The same algorithms are used as for :ref:`the standard
random module <pysupported-random>` (and therefore the same notes apply),
but with an independent internal state: seeding or drawing numbers from
one generator won't affect the other.
The following functions are supported.
Initialization
''''''''''''''
* :func:`numpy.random.seed`: with an integer argument only
.. warning::
Calling :func:`numpy.random.seed` from interpreted code (including from :term:`object mode`
code) will seed the NumPy random generator, not the Numba random generator.
To seed the Numba random generator, see the example below.
.. code-block:: python
from numba import njit
import numpy as np
@njit
def seed(a):
np.random.seed(a)
@njit
def rand():
return np.random.rand()
# Incorrect seeding
np.random.seed(1234)
print(rand())
np.random.seed(1234)
print(rand())
# Correct seeding
seed(1234)
print(rand())
seed(1234)
print(rand())
Simple random data
''''''''''''''''''
* :func:`numpy.random.rand`
* :func:`numpy.random.randint` (only the first two arguments)
* :func:`numpy.random.randn`
* :func:`numpy.random.random`
* :func:`numpy.random.random_sample`
* :func:`numpy.random.ranf`
* :func:`numpy.random.sample`
Permutations
''''''''''''
* :func:`numpy.random.choice`: the optional *p* argument (probabilities
array) is not supported
* :func:`numpy.random.permutation`
* :func:`numpy.random.shuffle`: the sequence argument must be a one-dimension
NumPy array or buffer-providing object (such as a :class:`bytearray`
or :class:`array.array`)
Distributions
'''''''''''''
The following functions support all arguments.
* :func:`numpy.random.beta`
* :func:`numpy.random.binomial`
* :func:`numpy.random.chisquare`
* :func:`numpy.random.dirichlet`
* :func:`numpy.random.exponential`
* :func:`numpy.random.f`
* :func:`numpy.random.gamma`
* :func:`numpy.random.geometric`
* :func:`numpy.random.gumbel`
* :func:`numpy.random.hypergeometric`
* :func:`numpy.random.laplace`
* :func:`numpy.random.logistic`
* :func:`numpy.random.lognormal`
* :func:`numpy.random.logseries`
* :func:`numpy.random.multinomial`
* :func:`numpy.random.negative_binomial`
* :func:`numpy.random.noncentral_chisquare`
* :func:`numpy.random.normal`
* :func:`numpy.random.pareto`
* :func:`numpy.random.poisson`
* :func:`numpy.random.power`
* :func:`numpy.random.rayleigh`
* :func:`numpy.random.standard_cauchy`
* :func:`numpy.random.standard_exponential`
* :func:`numpy.random.standard_gamma`
* :func:`numpy.random.standard_normal`
* :func:`numpy.random.standard_t`
* :func:`numpy.random.triangular`
* :func:`numpy.random.uniform`
* :func:`numpy.random.vonmises`
* :func:`numpy.random.wald`
* :func:`numpy.random.weibull`
* :func:`numpy.random.zipf`
.. note::
Calling :func:`numpy.random.seed` from non-Numba code (or from
:term:`object mode` code) will seed the NumPy random generator, not the
Numba random generator.
.. note::
Since version 0.28.0, the generator is thread-safe and fork-safe. Each
thread and each process will produce independent streams of random numbers.
``stride_tricks``
-----------------
The following functions from the :mod:`numpy.lib.stride_tricks` module
are supported:
* :func:`~numpy.lib.stride_tricks.as_strided` (the *strides* argument
is mandatory, the *subok* argument is not supported)
* :func:`~numpy.lib.stride_tricks.sliding_window_view` (the *subok* argument is
not supported, the *writeable* argument is not supported with the returned
view always being writeable)
.. _supported_ufuncs:
Standard ufuncs
===============
One objective of Numba is having all the
`standard ufuncs in NumPy <http://docs.scipy.org/doc/numpy/reference/ufuncs.html#available-ufuncs>`_
understood by Numba. When a supported ufunc is found when compiling a
function, Numba maps the ufunc to equivalent native code. This allows the
use of those ufuncs in Numba code that gets compiled in :term:`nopython mode`.
Limitations
-----------
Right now, only a selection of the standard ufuncs work in :term:`nopython mode`.
Following is a list of the different standard ufuncs that Numba is aware of,
sorted in the same way as in the NumPy documentation.
Math operations
---------------
============== ============= ===============
UFUNC MODE
-------------- ------------------------------
name object mode nopython mode
============== ============= ===============
add Yes Yes
subtract Yes Yes
multiply Yes Yes
divide Yes Yes
logaddexp Yes Yes
logaddexp2 Yes Yes
true_divide Yes Yes
floor_divide Yes Yes
negative Yes Yes
power Yes Yes
float_power Yes Yes
remainder Yes Yes
mod Yes Yes
fmod Yes Yes
divmod (*) Yes Yes
abs Yes Yes
absolute Yes Yes
fabs Yes Yes
rint Yes Yes
sign Yes Yes
conj Yes Yes
exp Yes Yes
exp2 Yes Yes
log Yes Yes
log2 Yes Yes
log10 Yes Yes
expm1 Yes Yes
log1p Yes Yes
sqrt Yes Yes
square Yes Yes
cbrt Yes Yes
reciprocal Yes Yes
conjugate Yes Yes
gcd Yes Yes
lcm Yes Yes
============== ============= ===============
(\*) not supported on timedelta types
Trigonometric functions
-----------------------
============== ============= ===============
UFUNC MODE
-------------- ------------------------------
name object mode nopython mode
============== ============= ===============
sin Yes Yes
cos Yes Yes
tan Yes Yes
arcsin Yes Yes
arccos Yes Yes
arctan Yes Yes
arctan2 Yes Yes
hypot Yes Yes
sinh Yes Yes
cosh Yes Yes
tanh Yes Yes
arcsinh Yes Yes
arccosh Yes Yes
arctanh Yes Yes
deg2rad Yes Yes
rad2deg Yes Yes
degrees Yes Yes
radians Yes Yes
============== ============= ===============
Bit-twiddling functions
-----------------------
============== ============= ===============
UFUNC MODE
-------------- ------------------------------
name object mode nopython mode
============== ============= ===============
bitwise_and Yes Yes
bitwise_or Yes Yes
bitwise_xor Yes Yes
bitwise_not Yes Yes
invert Yes Yes
left_shift Yes Yes
right_shift Yes Yes
============== ============= ===============
Comparison functions
--------------------
============== ============= ===============
UFUNC MODE
-------------- ------------------------------
name object mode nopython mode
============== ============= ===============
greater Yes Yes
greater_equal Yes Yes
less Yes Yes
less_equal Yes Yes
not_equal Yes Yes
equal Yes Yes
logical_and Yes Yes
logical_or Yes Yes
logical_xor Yes Yes
logical_not Yes Yes
maximum Yes Yes
minimum Yes Yes
fmax Yes Yes
fmin Yes Yes
============== ============= ===============
Floating functions
------------------
============== ============= ===============
UFUNC MODE
-------------- ------------------------------
name object mode nopython mode
============== ============= ===============
isfinite Yes Yes
isinf Yes Yes
isnan Yes Yes
signbit Yes Yes
copysign Yes Yes
nextafter Yes Yes
modf Yes No
ldexp Yes Yes
frexp Yes No
floor Yes Yes
ceil Yes Yes
trunc Yes Yes
spacing Yes Yes
============== ============= ===============
Datetime functions
------------------
============== ============= ===============
UFUNC MODE
-------------- ------------------------------
name object mode nopython mode
============== ============= ===============
isnat Yes Yes
============== ============= ===============
.. _pysemantics:
Deviations from Python Semantics
================================
Bounds Checking
---------------
By default, instead of causing an :class:`IndexError`, accessing an
out-of-bound index of an array in a Numba-compiled function will return
invalid values or lead to an access violation error (it's reading from
invalid memory locations). Bounds checking can be enabled on a specific
function via the :ref:`boundscheck <jit-decorator-boundscheck>`
option of the jit decorator. Additionally, the :envvar:`NUMBA_BOUNDSCHECK`
can be set to 0 or 1 to globally override this flag.
.. note::
Bounds checking will slow down typical functions so it is recommended to only
use this flag for debugging purposes.
Exceptions and Memory Allocation
--------------------------------
Due to limitations in the current compiler when handling exceptions, memory
allocated (almost always NumPy arrays) within a function that raises an
exception will **leak**. This is a known issue that will be fixed, but in the
meantime, it is best to do memory allocation outside of functions that can
also raise exceptions.
Integer width
-------------
While Python has arbitrary-sized integers, integers in Numba-compiled
functions get a fixed size through :term:`type inference` (usually,
the size of a machine integer). This means that arithmetic
operations can wrapround or produce undefined results or overflow.
Type inference can be overridden by an explicit type specification,
if fine-grained control of integer width is desired.
.. seealso::
:ref:`Enhancement proposal 1: Changes in integer typing <nbep-1>`
Boolean inversion
-----------------
Calling the bitwise complement operator (the ``~`` operator) on a Python
boolean returns an integer, while the same operator on a Numpy boolean
returns another boolean::
>>> ~True
-2
>>> ~np.bool_(True)
False
Numba follows the Numpy semantics.
Global and closure variables
----------------------------
In :term:`nopython mode`, global and closure variables are *frozen* by
Numba: a Numba-compiled function sees the value of those variables at the
time the function was compiled. Also, it is not possible to change their
values from the function.
Numba **may or may not** copy global variables referenced inside a compiled
function. Small global arrays are copied for potential compiler optimization
with immutability assumption. However, large global arrays are not copied to
conserve memory. The definition of "small" and "large" may change.
Zero initialization of variables
--------------------------------
Numba does not track variable liveness at runtime. For simplicity of
implementation, all variables are zero-initialized. Example::
from numba import njit
@njit
def foo():
for i in range(0):
pass
print(i) # will print 0 and not raise UnboundLocalError
foo()
.. _pysupported:
=========================
Supported Python features
=========================
Apart from the :ref:`pysupported-language` part below, which applies to both
:term:`object mode` and :term:`nopython mode`, this page only lists the
features supported in :term:`nopython mode`.
.. warning::
Numba behavior differs from Python semantics in some situations. We
strongly advise reviewing :ref:`pysemantics` to become familiar with these
differences.
.. _pysupported-language:
Language
========
Constructs
----------
Numba strives to support as much of the Python language as possible, but
some language features are not available inside Numba-compiled functions.
Below is a quick reference for the support level of Python constructs.
**Supported** constructs:
- conditional branch: ``if .. elif .. else``
- loops: ``while``, ``for .. in``, ``break``, ``continue``
- basic generator: ``yield``
- assertion: ``assert``
**Partially supported** constructs:
- exceptions: ``try .. except``, ``raise``, ``else`` and ``finally``
(See details in this :ref:`section <pysupported-exception-handling>`)
- context manager:
``with`` (only support :ref:`numba.objmode() <with_objmode>`)
- list comprehension (see details in this
:ref:`section <pysupported-comprehension>`)
**Unsupported** constructs:
- async features: ``async with``, ``async for`` and ``async def``
- class definition: ``class`` (except for :ref:`@jitclass <jitclass>`)
- set, dict and generator comprehensions
- generator delegation: ``yield from``
Functions
---------
Function calls
''''''''''''''
Numba supports function calls using positional and named arguments, as well
as arguments with default values and ``*args`` (note the argument for
``*args`` can only be a tuple, not a list). Explicit ``**kwargs`` are
not supported.
Function calls to locally defined inner functions are supported as long as
they can be fully inlined.
Functions as arguments
''''''''''''''''''''''
Functions can be passed as argument into another function. But, they cannot
be returned. For example:
.. code-block:: python
from numba import jit
@jit
def add1(x):
return x + 1
@jit
def bar(fn, x):
return fn(x)
@jit
def foo(x):
return bar(add1, x)
# Passing add1 within numba compiled code.
print(foo(1))
# Passing add1 into bar from interpreted code
print(bar(add1, 1))
.. note:: Numba does not handle function objects as real objects. Once a
function is assigned to a variable, the variable cannot be
re-assigned to a different function.
Inner function and closure
'''''''''''''''''''''''''''
Numba now supports inner functions as long as they are non-recursive
and only called locally, but not passed as argument or returned as
result. The use of closure variables (variables defined in outer scopes)
within an inner function is also supported.
Recursive calls
'''''''''''''''
Most recursive call patterns are supported. The only restriction is that the
recursive callee must have a control-flow path that returns without recursing.
Numba is able to type-infer recursive functions without specifying the function
type signature (which is required in numba 0.28 and earlier).
Recursive calls can even call into a different overload of the function.
.. XXX add reference to NBEP
Generators
----------
Numba supports generator functions and is able to compile them in
:term:`object mode` and :term:`nopython mode`. The returned generator
can be used both from Numba-compiled code and from regular Python code.
Coroutine features of generators are not supported (i.e. the
:meth:`generator.send`, :meth:`generator.throw`, :meth:`generator.close`
methods).
.. _pysupported-exception-handling:
Exception handling
------------------
``raise`` statement
'''''''''''''''''''
The ``raise`` statement is only supported in the following forms:
* ``raise SomeException``
* ``raise SomeException(<arguments>)``
It is currently unsupported to re-raise an exception created in compiled code.
``try .. except``
'''''''''''''''''
The ``try .. except`` construct is partially supported. The following forms
of are supported:
* the *bare* except that captures all exceptions:
.. code-block:: python
try:
...
except:
...
* using exactly the ``Exception`` class in the ``except`` clause:
.. code-block:: python
try:
...
except Exception:
...
This will match any exception that is a subclass of ``Exception`` as
expected. Currently, instances of ``Exception`` and it's subclasses are the
only kind of exception that can be raised in compiled code.
.. warning:: Numba currently masks signals like ``KeyboardInterrupt`` and
``SystemExit``. These signaling exceptions are ignored during the execution of
Numba compiled code. The Python interpreter will handle them as soon as
the control is returned to it.
Currently, exception objects are not materialized inside compiled functions.
As a result, it is not possible to store an exception object into a user
variable or to re-raise an exception. With this limitation, the only realistic
use-case would look like:
.. code-block:: python
try:
do_work()
except Exception:
handle_error_case()
return error_code
``try .. except .. else .. finally``
''''''''''''''''''''''''''''''''''''
The ``else`` block and the ``finally`` block of a ``try .. except`` are
supported:
.. code-block:: python
>>> @jit(nopython=True)
... def foo():
... try:
... print('main block')
... except Exception:
... print('handler block')
... else:
... print('else block')
... finally:
... print('final block')
...
>>> foo()
main block
else block
final block
The ``try .. finally`` construct without the ``except`` clause is also
supported.
.. _pysupported-builtin-types:
Built-in types
==============
int, bool
---------
Arithmetic operations as well as truth values are supported.
The following attributes and methods are supported:
* ``.conjugate()``
* ``.real``
* ``.imag``
float, complex
--------------
Arithmetic operations as well as truth values are supported.
The following attributes and methods are supported:
* ``.conjugate()``
* ``.real``
* ``.imag``
str
---
Numba supports (Unicode) strings in Python 3. Strings can be passed into
:term:`nopython mode` as arguments, as well as constructed and returned from
:term:`nopython mode`. As in Python, slices (even of length 1) return a new,
reference counted string. Optimized code paths for efficiently accessing
single characters may be introduced in the future.
The in-memory representation is the same as was introduced in Python 3.4, with
each string having a tag to indicate whether the string is using a 1, 2, or 4
byte character width in memory. When strings of different encodings are
combined (as in concatenation), the resulting string automatically uses the
larger character width of the two input strings. String slices also use the
same character width as the original string, even if the slice could be
represented with a narrower character width. (These details are invisible to
the user, of course.)
The following constructors, functions, attributes and methods are currently
supported:
* ``str(int)``
* ``len()``
* ``+`` (concatenation of strings)
* ``*`` (repetition of strings)
* ``in``, ``.contains()``
* ``==``, ``<``, ``<=``, ``>``, ``>=`` (comparison)
* ``.capitalize()``
* ``.casefold()``
* ``.center()``
* ``.count()``
* ``.endswith()``
* ``.endswith()``
* ``.expandtabs()``
* ``.find()``
* ``.index()``
* ``.isalnum()``
* ``.isalpha()``
* ``.isdecimal()``
* ``.isdigit()``
* ``.isidentifier()``
* ``.islower()``
* ``.isnumeric()``
* ``.isprintable()``
* ``.isspace()``
* ``.istitle()``
* ``.isupper()``
* ``.join()``
* ``.ljust()``
* ``.lower()``
* ``.lstrip()``
* ``.partition()``
* ``.replace()``
* ``.rfind()``
* ``.rindex()``
* ``.rjust()``
* ``.rpartition()``
* ``.rsplit()``
* ``.rstrip()``
* ``.split()``
* ``.splitlines()``
* ``.startswith()``
* ``.strip()``
* ``.swapcase()``
* ``.title()``
* ``.upper()``
* ``.zfill()``
Regular string literals (e.g. ``"ABC"``) as well as f-strings without format specs
(e.g. ``"ABC_{a+1}"``)
that only use string and integer variables (types with ``str()`` overload)
are supported in :term:`nopython mode`.
Additional operations as well as support for Python 2 strings / Python 3 bytes
will be added in a future version of Numba. Python 2 Unicode objects will
likely never be supported.
.. warning::
The performance of some operations is known to be slower than the CPython
implementation. These include substring search (``in``, ``.contains()``
and ``find()``) and string creation (like ``.split()``). Improving the
string performance is an ongoing task, but the speed of CPython is
unlikely to be surpassed for basic string operation in isolation.
Numba is most successfully used for larger algorithms that happen to
involve strings, where basic string operations are not the bottleneck.
tuple
-----
Tuple support is categorised into two categories based on the contents of a
tuple. The first category is homogeneous tuples, these are tuples where the type
of all the values in the tuple are the same, the second is heterogeneous tuples,
these are tuples where the types of the values are different.
.. note::
The ``tuple()`` constructor itself is NOT supported.
homogeneous tuples
------------------
An example of a homogeneous tuple:
.. code-block:: python
homogeneous_tuple = (1, 2, 3, 4)
The following operations are supported on homogeneous tuples:
* Tuple construction.
* Tuple unpacking.
* Comparison between tuples.
* Iteration and indexing.
* Addition (concatenation) between tuples.
* Slicing tuples with a constant slice.
* The index method on tuples.
heterogeneous tuples
--------------------
An example of a heterogeneous tuple:
.. code-block:: python
heterogeneous_tuple = (1, 2j, 3.0, "a")
The following operations are supported on heterogeneous tuples:
* Comparison between tuples.
* Indexing using an index value that is a compile time constant
e.g. ``mytuple[7]``, where ``7`` is evidently a constant.
* Iteration over a tuple (requires experimental :func:`literal_unroll` feature,
see below).
.. warning::
The following feature (:func:`literal_unroll`) is experimental and was added
in version 0.47.
To permit iteration over a heterogeneous tuple the special function
:func:`numba.literal_unroll` must be used. This function has no effect other
than to act as a token to permit the use of this feature. Example use:
.. code-block:: python
from numba import njit, literal_unroll
@njit
def foo():
heterogeneous_tuple = (1, 2j, 3.0, "a")
for i in literal_unroll(heterogeneous_tuple):
print(i)
.. warning::
The following restrictions apply to the use of :func:`literal_unroll`:
* :func:`literal_unroll` can only be used on tuples and constant lists of
compile time constants, e.g. ``[1, 2j, 3, "a"]`` and the list not being
mutated.
* The only supported use pattern for :func:`literal_unroll` is loop
iteration.
* Only one :func:`literal_unroll` call is permitted per loop nest (i.e.
nested heterogeneous tuple iteration loops are forbidden).
* The usual type inference/stability rules still apply.
A more involved use of :func:`literal_unroll` might be type specific dispatch,
recall that string and integer literal values are considered their own type,
for example:
.. code-block:: python
from numba import njit, types, literal_unroll
from numba.extending import overload
def dt(x):
# dummy function to overload
pass
@overload(dt, inline='always')
def ol_dt(li):
if isinstance(li, types.StringLiteral):
value = li.literal_value
if value == "apple":
def impl(li):
return 1
elif value == "orange":
def impl(li):
return 2
elif value == "banana":
def impl(li):
return 3
return impl
elif isinstance(li, types.IntegerLiteral):
value = li.literal_value
if value == 0xca11ab1e:
def impl(li):
# capture the dispatcher literal value
return 0x5ca1ab1e + value
return impl
@njit
def foo():
acc = 0
for t in literal_unroll(('apple', 'orange', 'banana', 3390155550)):
acc += dt(t)
return acc
print(foo())
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
the types are compatible (for example, ``[1, 2.5]`` is rejected as it
contains a :class:`int` and a :class:`float`).
For example, to create a list of arrays::
In [1]: from numba import njit
In [2]: import numpy as np
In [3]: @njit
...: def foo(x):
...: lst = []
...: for i in range(x):
...: lst.append(np.arange(i))
...: return lst
...:
In [4]: foo(4)
Out[4]: [array([], dtype=int64), array([0]), array([0, 1]), array([0, 1, 2])]
.. _feature-reflected-list:
List Reflection
'''''''''''''''
In nopython mode, Numba does not operate on Python objects. ``list`` are
compiled into an internal representation. Any ``list`` arguments must be
converted into this representation on the way in to nopython mode and their
contained elements must be restored in the original Python objects via a
process called :term:`reflection`. Reflection is required to maintain the same
semantics as found in regular Python code. However, the reflection process
can be expensive for large lists and it is not supported for lists that contain
reflected data types. Users cannot use list-of-list as an argument because
of this limitation.
.. note::
When passing a list into a JIT-compiled function, any modifications
made to the list will not be visible to the Python interpreter until
the function returns. (A limitation of the reflection process.)
.. warning::
List sorting currently uses a quicksort algorithm, which has different
performance characterics than the algorithm used by Python.
.. _feature-list-initial-value:
Initial Values
''''''''''''''
.. warning::
This is an experimental feature!
Lists that:
* Are constructed using the square braces syntax
* Have values of a literal type
will have their initial value stored in the ``.initial_value`` property on the
type so as to permit inspection of these values at compile time. If required,
to force value based dispatch the :ref:`literally <developer-literally>`
function will accept such a list.
Example:
.. literalinclude:: ../../../numba/tests/doc_examples/test_literal_container_usage.py
:language: python
:caption: from ``test_ex_initial_value_list_compile_time_consts`` of ``numba/tests/doc_examples/test_literal_container_usage.py``
:start-after: magictoken.test_ex_initial_value_list_compile_time_consts.begin
:end-before: magictoken.test_ex_initial_value_list_compile_time_consts.end
:dedent: 12
:linenos:
.. _feature-typed-list:
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:: ../../../numba/tests/doc_examples/test_typed_list_usage.py
:language: python
:caption: from ``ex_inferred_list_jit`` of ``numba/tests/doc_examples/test_typed_list_usage.py``
:start-after: magictoken.ex_inferred_list_jit.begin
:end-before: magictoken.ex_inferred_list_jit.end
:dedent: 12
: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:: ../../../numba/tests/doc_examples/test_typed_list_usage.py
:language: python
:caption: from ``ex_inferred_list`` of ``numba/tests/doc_examples/test_typed_list_usage.py``
:start-after: magictoken.ex_inferred_list.begin
:end-before: magictoken.ex_inferred_list.end
:dedent: 12
:linenos:
Finally, here's an example of using a nested `List()`:
.. literalinclude:: ../../../numba/tests/doc_examples/test_typed_list_usage.py
:language: python
:caption: from ``ex_nested_list`` of ``numba/tests/doc_examples/test_typed_list_usage.py``
:start-after: magictoken.ex_nested_list.begin
:end-before: magictoken.ex_nested_list.end
:dedent: 12
:linenos:
.. _feature-literal-list:
Literal List
''''''''''''
.. warning::
This is an experimental feature!
Numba supports the use of literal lists containing any values, for example::
l = ['a', 1, 2j, np.zeros(5,)]
the predominant use of these lists is for use as a configuration object.
The lists appear as a ``LiteralList`` type which inherits from ``Literal``, as a
result the literal values of the list items are available at compile time.
For example:
.. literalinclude:: ../../../numba/tests/doc_examples/test_literal_container_usage.py
:language: python
:caption: from ``test_ex_literal_list`` of ``numba/tests/doc_examples/test_literal_container_usage.py``
:start-after: magictoken.test_ex_literal_list.begin
:end-before: magictoken.test_ex_literal_list.end
:dedent: 12
:linenos:
Important things to note about these kinds of lists:
#. They are immutable, use of mutating methods e.g. ``.pop()`` will result in
compilation failure. Read-only static access and read only methods are
supported e.g. ``len()``.
#. Dynamic access of items is not possible, e.g. ``some_list[x]``, for a
value ``x`` which is not a compile time constant. This is because it's
impossible to statically determine the type of the item being accessed.
#. Inside the compiler, these lists are actually just tuples with some extra
things added to make them look like they are lists.
#. They cannot be returned to the interpreter from a compiled function.
.. _pysupported-comprehension:
List comprehension
''''''''''''''''''
Numba supports list comprehension. For example::
In [1]: from numba import njit
In [2]: @njit
...: def foo(x):
...: return [[i for i in range(n)] for n in range(x)]
...:
In [3]: foo(3)
Out[3]: [[], [0], [0, 1]]
.. note::
Prior to version 0.39.0, Numba did not support the creation of nested lists.
Numba also supports "array comprehension" that is a list comprehension
followed immediately by a call to :func:`numpy.array`. The following
is an example that produces a 2D Numpy array::
from numba import jit
import numpy as np
@jit(nopython=True)
def f(n):
return np.array([ [ x * y for x in range(n) ] for y in range(n) ])
In this case, Numba is able to optimize the program to allocate and
initialize the result array directly without allocating intermediate
list objects. Therefore, the nesting of list comprehension here is
not a problem since a multi-dimensional array is being created here
instead of a nested list.
Additionally, Numba supports parallel array comprehension when combined
with the :ref:`parallel_jit_option` option on CPUs.
set
---
All methods and operations on sets are supported in JIT-compiled functions.
Sets must be strictly homogeneous: Numba will reject any set containing
objects of different types, even if the types are compatible (for example,
``{1, 2.5}`` is rejected as it contains a :class:`int` and a :class:`float`).
The use of reference counted types, e.g. strings, in sets is unsupported.
.. note::
When passing a set into a JIT-compiled function, any modifications
made to the set will not be visible to the Python interpreter until
the function returns.
.. _feature-typed-dict:
Typed Dict
----------
.. warning::
``numba.typed.Dict`` is an experimental feature. The API may change
in the future releases.
.. note::
``dict()`` was not supported in versions prior to 0.44. Currently, calling
``dict()`` translates to calling ``numba.typed.Dict()``.
Numba supports the use of ``dict()``. Such use is semantically equivalent to
``{}`` and ``numba.typed.Dict()``. It will create an instance of
``numba.typed.Dict`` where the key-value types will be later inferred by usage.
Numba also supports, explicitly, the ``dict(iterable)`` constructor.
Numba does not fully support the Python ``dict`` because it is an untyped
container that can have any Python types as members. To generate efficient
machine code, Numba needs the keys and the values of the dictionary to have
fixed types, declared in advance. To achieve this, Numba has a typed dictionary,
``numba.typed.Dict``, for which the type-inference mechanism must be able to
infer the key-value types by use, or the user must explicitly declare the
key-value type using the ``Dict.empty()`` constructor method.
This typed dictionary has the same API as the Python ``dict``, it implements
the ``collections.MutableMapping`` interface and is usable in both interpreted
Python code and JIT-compiled Numba functions.
Because the typed dictionary stores keys and values in Numba's native,
unboxed data layout, passing a Numba dictionary into nopython mode has very low
overhead. However, this means that using a typed dictionary from the Python
interpreter is slower than a regular dictionary because Numba has to box and
unbox key and value objects when getting or setting items.
An important difference of the typed dictionary in comparison to Python's
``dict`` is that **implicit casting** occurs when a key or value is stored.
As a result the *setitem* operation may fail should the type-casting fail.
It should be noted that the Numba typed dictionary is implemented using the same
algorithm as the CPython 3.7 dictionary. As a consequence, the typed dictionary
is ordered and has the same collision resolution as the CPython implementation.
Further to the above in relation to type specification, there are limitations
placed on the types that can be used as keys and/or values in the typed
dictionary, most notably the Numba ``Set`` and ``List`` types are currently
unsupported. Acceptable key/value types include but are not limited to: unicode
strings, arrays (value only), scalars, tuples. It is expected that these
limitations will be relaxed as Numba continues to improve.
Here's an example of using ``dict()`` and ``{}`` to create ``numba.typed.Dict``
instances and letting the compiler infer the key-value types:
.. literalinclude:: ../../../numba/tests/doc_examples/test_typed_dict_usage.py
:language: python
:caption: from ``test_ex_inferred_dict_njit`` of ``numba/tests/doc_examples/test_typed_dict_usage.py``
:start-after: magictoken.ex_inferred_dict_njit.begin
:end-before: magictoken.ex_inferred_dict_njit.end
:dedent: 12
:linenos:
Here's an example of creating a ``numba.typed.Dict`` instance from interpreted
code and using the dictionary in jit code:
.. literalinclude:: ../../../numba/tests/doc_examples/test_typed_dict_usage.py
:language: python
:caption: from ``test_ex_typed_dict_from_cpython`` of ``numba/tests/doc_examples/test_typed_dict_usage.py``
:start-after: magictoken.ex_typed_dict_from_cpython.begin
:end-before: magictoken.ex_typed_dict_from_cpython.end
:dedent: 12
:linenos:
Here's an example of creating a ``numba.typed.Dict`` instance from jit code and
using the dictionary in interpreted code:
.. literalinclude:: ../../../numba/tests/doc_examples/test_typed_dict_usage.py
:language: python
:caption: from ``test_ex_typed_dict_njit`` of ``numba/tests/doc_examples/test_typed_dict_usage.py``
:start-after: magictoken.ex_typed_dict_njit.begin
:end-before: magictoken.ex_typed_dict_njit.end
:dedent: 12
:linenos:
It should be noted that ``numba.typed.Dict`` is not thread-safe.
Specifically, functions which modify a dictionary from multiple
threads will potentially corrupt memory, causing a
range of possible failures. However, the dictionary can be safely read from
multiple threads as long as the contents of the dictionary do not
change during the parallel access.
Dictionary comprehension
''''''''''''''''''''''''
Numba supports dictionary comprehension under the assumption that a
``numba.typed.Dict`` instance can be created from the comprehension. For
example::
In [1]: from numba import njit
In [2]: @njit
...: def foo(n):
...: return {i: i**2 for i in range(n)}
...:
In [3]: foo(3)
Out[3]: DictType[int64,int64]<iv=None>({0: 0, 1: 1, 2: 4})
.. _feature-dict-initial-value:
Initial Values
''''''''''''''
.. warning::
This is an experimental feature!
Typed dictionaries that:
* Are constructed using the curly braces syntax
* Have literal string keys
* Have values of a literal type
will have their initial value stored in the ``.initial_value`` property on the
type so as to permit inspection of these values at compile time. If required,
to force value based dispatch the :ref:`literally <developer-literally>`
function will accept a typed dictionary.
Example:
.. literalinclude:: ../../../numba/tests/doc_examples/test_literal_container_usage.py
:language: python
:caption: from ``test_ex_initial_value_dict_compile_time_consts`` of ``numba/tests/doc_examples/test_literal_container_usage.py``
:start-after: magictoken.test_ex_initial_value_dict_compile_time_consts.begin
:end-before: magictoken.test_ex_initial_value_dict_compile_time_consts.end
:dedent: 12
:linenos:
.. _feature-literal-str-key-dict:
Heterogeneous Literal String Key Dictionary
-------------------------------------------
.. warning::
This is an experimental feature!
Numba supports the use of statically declared string key to any value
dictionaries, for example::
d = {'a': 1, 'b': 'data', 'c': 2j}
the predominant use of these dictionaries is to orchestrate advanced compilation
dispatch or as a container for use as a configuration object. The dictionaries
appear as a ``LiteralStrKeyDict`` type which inherits from ``Literal``, as a
result the literal values of the keys and the types of the items are available
at compile time. For example:
.. literalinclude:: ../../../numba/tests/doc_examples/test_literal_container_usage.py
:language: python
:caption: from ``test_ex_literal_dict_compile_time_consts`` of ``numba/tests/doc_examples/test_literal_container_usage.py``
:start-after: magictoken.test_ex_literal_dict_compile_time_consts.begin
:end-before: magictoken.test_ex_literal_dict_compile_time_consts.end
:dedent: 12
:linenos:
Important things to note about these kinds of dictionaries:
#. They are immutable, use of mutating methods e.g. ``.pop()`` will result in
compilation failure. Read-only static access and read only methods are
supported e.g. ``len()``.
#. Dynamic access of items is not possible, e.g. ``some_dictionary[x]``, for a
value ``x`` which is not a compile time constant. This is because it's
impossible statically determine the type of the item being accessed.
#. Inside the compiler, these dictionaries are actually just named tuples with
some extra things added to make them look like they are dictionaries.
#. They cannot be returned to the interpreter from a compiled function.
#. The ``.keys()``, ``.values()`` and ``.items()`` methods all functionally
operate but return tuples opposed to iterables.
None
----
The None value is supported for identity testing (when using an
:class:`~numba.optional` type).
bytes, bytearray, memoryview
----------------------------
The :class:`bytearray` type and, on Python 3, the :class:`bytes` type
support indexing, iteration and retrieving the len().
The :class:`memoryview` type supports indexing, slicing, iteration,
retrieving the len(), and also the following attributes:
* :attr:`~memoryview.contiguous`
* :attr:`~memoryview.c_contiguous`
* :attr:`~memoryview.f_contiguous`
* :attr:`~memoryview.itemsize`
* :attr:`~memoryview.nbytes`
* :attr:`~memoryview.ndim`
* :attr:`~memoryview.readonly`
* :attr:`~memoryview.shape`
* :attr:`~memoryview.strides`
Built-in functions
==================
The following built-in functions are supported:
* :func:`abs`
* :class:`bool`
* :func:`chr`
* :class:`complex`
* :func:`divmod`
* :func:`enumerate`
* :func:`filter`
* :class:`float`
* :func:`getattr`: the attribute must be a string literal and the return type
cannot be a function type (e.g. ``getattr(numpy, 'cos')`` is not supported as
it returns a function type).
* :func:`hasattr`
* :func:`hash` (see :ref:`pysupported-hashing` below)
* :class:`int`: only the one-argument form
* :func:`iter`: only the one-argument form
* :func:`isinstance`
* :func:`len`
* :func:`min`
* :func:`map`
* :func:`max`
* :func:`next`: only the one-argument form
* :func:`ord`
* :func:`print`: only numbers and strings; no ``file`` or ``sep`` argument
* :class:`range`: The only permitted use of range is as a callable function
(cannot pass range as an argument to a jitted function or return a range from
a jitted function).
* :func:`repr`
* :func:`round`
* :func:`sorted`: the ``key`` argument is not supported
* :func:`sum`
* :func:`str`
* :func:`type`: only the one-argument form, and only on some types
(e.g. numbers and named tuples)
* :func:`zip`
.. _pysupported-hashing:
Hashing
-------
The :func:`hash` built-in is supported and produces hash values for all
supported hashable types with the following Python version specific behavior:
Under Python 3, hash values computed by Numba will exactly match those computed
in CPython under the condition that the :attr:`sys.hash_info.algorithm` is
``siphash24`` (default).
The ``PYTHONHASHSEED`` environment variable influences the hashing behavior in
precisely the manner described in the CPython documentation.
Standard library modules
========================
``array``
---------
Limited support for the :class:`array.array` type is provided through
the buffer protocol. Indexing, iteration and taking the len() is supported.
All type codes are supported except for ``"u"``.
``cmath``
---------
The following functions from the :mod:`cmath` module are supported:
* :func:`cmath.acos`
* :func:`cmath.acosh`
* :func:`cmath.asin`
* :func:`cmath.asinh`
* :func:`cmath.atan`
* :func:`cmath.atanh`
* :func:`cmath.cos`
* :func:`cmath.cosh`
* :func:`cmath.exp`
* :func:`cmath.isfinite`
* :func:`cmath.isinf`
* :func:`cmath.isnan`
* :func:`cmath.log`
* :func:`cmath.log10`
* :func:`cmath.phase`
* :func:`cmath.polar`
* :func:`cmath.rect`
* :func:`cmath.sin`
* :func:`cmath.sinh`
* :func:`cmath.sqrt`
* :func:`cmath.tan`
* :func:`cmath.tanh`
``collections``
---------------
Named tuple classes, as returned by :func:`collections.namedtuple`, are
supported in the same way regular tuples are supported. Attribute access
and named parameters in the constructor are also supported.
Creating a named tuple class inside Numba code is *not* supported; the class
must be created at the global level.
.. _ctypes-support:
``ctypes``
----------
Numba is able to call ctypes-declared functions with the following argument
and return types:
* :class:`ctypes.c_int8`
* :class:`ctypes.c_int16`
* :class:`ctypes.c_int32`
* :class:`ctypes.c_int64`
* :class:`ctypes.c_uint8`
* :class:`ctypes.c_uint16`
* :class:`ctypes.c_uint32`
* :class:`ctypes.c_uint64`
* :class:`ctypes.c_float`
* :class:`ctypes.c_double`
* :class:`ctypes.c_void_p`
``enum``
--------
Both :class:`enum.Enum` and :class:`enum.IntEnum` subclasses are supported.
``math``
--------
The following functions from the :mod:`math` module are supported:
* :func:`math.acos`
* :func:`math.acosh`
* :func:`math.asin`
* :func:`math.asinh`
* :func:`math.atan`
* :func:`math.atan2`
* :func:`math.atanh`
* :func:`math.ceil`
* :func:`math.copysign`
* :func:`math.cos`
* :func:`math.cosh`
* :func:`math.degrees`
* :func:`math.erf`
* :func:`math.erfc`
* :func:`math.exp`
* :func:`math.expm1`
* :func:`math.fabs`
* :func:`math.floor`
* :func:`math.frexp`
* :func:`math.gamma`
* :func:`math.gcd`
* :func:`math.hypot`
* :func:`math.isfinite`
* :func:`math.isinf`
* :func:`math.isnan`
* :func:`math.ldexp`
* :func:`math.lgamma`
* :func:`math.log`
* :func:`math.log10`
* :func:`math.log1p`
* :func:`math.pow`
* :func:`math.radians`
* :func:`math.sin`
* :func:`math.sinh`
* :func:`math.sqrt`
* :func:`math.tan`
* :func:`math.tanh`
* :func:`math.trunc`
``operator``
------------
The following functions from the :mod:`operator` module are supported:
* :func:`operator.add`
* :func:`operator.and_`
* :func:`operator.eq`
* :func:`operator.floordiv`
* :func:`operator.ge`
* :func:`operator.gt`
* :func:`operator.iadd`
* :func:`operator.iand`
* :func:`operator.ifloordiv`
* :func:`operator.ilshift`
* :func:`operator.imatmul` (Python 3.5 and above)
* :func:`operator.imod`
* :func:`operator.imul`
* :func:`operator.invert`
* :func:`operator.ior`
* :func:`operator.ipow`
* :func:`operator.irshift`
* :func:`operator.isub`
* :func:`operator.itruediv`
* :func:`operator.ixor`
* :func:`operator.le`
* :func:`operator.lshift`
* :func:`operator.lt`
* :func:`operator.matmul` (Python 3.5 and above)
* :func:`operator.mod`
* :func:`operator.mul`
* :func:`operator.ne`
* :func:`operator.neg`
* :func:`operator.not_`
* :func:`operator.or_`
* :func:`operator.pos`
* :func:`operator.pow`
* :func:`operator.rshift`
* :func:`operator.sub`
* :func:`operator.truediv`
* :func:`operator.xor`
``functools``
-------------
The :func:`functools.reduce` function is supported but the `initializer`
argument is required.
.. _pysupported-random:
``random``
----------
Numba supports top-level functions from the :mod:`random` module, but does
not allow you to create individual Random instances. A Mersenne-Twister
generator is used, with a dedicated internal state. It is initialized at
startup with entropy drawn from the operating system.
* :func:`random.betavariate`
* :func:`random.expovariate`
* :func:`random.gammavariate`
* :func:`random.gauss`
* :func:`random.getrandbits`: number of bits must not be greater than 64
* :func:`random.lognormvariate`
* :func:`random.normalvariate`
* :func:`random.paretovariate`
* :func:`random.randint`
* :func:`random.random`
* :func:`random.randrange`
* :func:`random.seed`: with an integer argument only
* :func:`random.shuffle`: the sequence argument must be a one-dimension
Numpy array or buffer-providing object (such as a :class:`bytearray`
or :class:`array.array`); the second (optional) argument is not supported
* :func:`random.uniform`
* :func:`random.triangular`
* :func:`random.vonmisesvariate`
* :func:`random.weibullvariate`
.. warning::
Calling :func:`random.seed` from non-Numba code (or from :term:`object mode`
code) will seed the Python random generator, not the Numba random generator.
To seed the Numba random generator, see the example below.
.. code-block:: python
from numba import njit
import random
@njit
def seed(a):
random.seed(a)
@njit
def rand():
return random.random()
# Incorrect seeding
random.seed(1234)
print(rand())
random.seed(1234)
print(rand())
# Correct seeding
seed(1234)
print(rand())
seed(1234)
print(rand())
.. note::
Since version 0.28.0, the generator is thread-safe and fork-safe. Each
thread and each process will produce independent streams of random numbers.
.. seealso::
Numba also supports most additional distributions from the :ref:`Numpy
random module <numpy-random>`.
``heapq``
---------
The following functions from the :mod:`heapq` module are supported:
* :func:`heapq.heapify`
* :func:`heapq.heappop`
* :func:`heapq.heappush`
* :func:`heapq.heappushpop`
* :func:`heapq.heapreplace`
* :func:`heapq.nlargest` : first two arguments only
* :func:`heapq.nsmallest` : first two arguments only
Note: the heap must be seeded with at least one value to allow its type to be
inferred; heap items are assumed to be homogeneous in type.
Third-party modules
===================
.. I put this here as there's only one module (apart from Numpy), otherwise
it should be a separate page.
.. _cffi-support:
``cffi``
--------
Similarly to ctypes, Numba is able to call into `cffi`_-declared external
functions, using the following C types and any derived pointer types:
* :c:expr:`char`
* :c:expr:`short`
* :c:expr:`int`
* :c:expr:`long`
* :c:expr:`long long`
* :c:expr:`unsigned char`
* :c:expr:`unsigned short`
* :c:expr:`unsigned int`
* :c:expr:`unsigned long`
* :c:expr:`unsigned long long`
* :c:expr:`int8_t`
* :c:expr:`uint8_t`
* :c:expr:`int16_t`
* :c:expr:`uint16_t`
* :c:expr:`int32_t`
* :c:expr:`uint32_t`
* :c:expr:`int64_t`
* :c:expr:`uint64_t`
* :c:expr:`float`
* :c:expr:`double`
* :c:expr:`ssize_t`
* :c:expr:`size_t`
* :c:expr:`void`
The ``from_buffer()`` method of ``cffi.FFI`` and ``CompiledFFI`` objects is
supported for passing Numpy arrays and other buffer-like objects. Only
*contiguous* arguments are accepted. The argument to ``from_buffer()``
is converted to a raw pointer of the appropriate C type (for example a
``double *`` for a ``float64`` array).
Additional type mappings for the conversion from a buffer to the appropriate C
type may be registered with Numba. This may include struct types, though it is
only permitted to call functions that accept pointers to structs - passing a
struct by value is unsupported. For registering a mapping, use:
.. function:: numba.core.typing.cffi_utils.register_type(cffi_type, numba_type)
Out-of-line cffi modules must be registered with Numba prior to the use of any
of their functions from within Numba-compiled functions:
.. function:: numba.core.typing.cffi_utils.register_module(mod)
Register the cffi out-of-line module ``mod`` with Numba.
Inline cffi modules require no registration.
.. _cffi: https://cffi.readthedocs.org/
.. _numba-types:
====================
Types and signatures
====================
Rationale
=========
As an optimizing compiler, Numba needs to decide on the type of each
variable to generate efficient machine code. Python's standard types
are not precise enough for that, so we had to develop our own fine-grained
type system.
You will encounter Numba types mainly when trying to inspect the results
of Numba's type inference, for :ref:`debugging <numba-envvars>` or
:ref:`educational <architecture>` purposes. However, you need to use
types explicitly if compiling code :ref:`ahead-of-time <pycc>`.
Signatures
==========
A signature specifies the type of a function. Exactly which kind
of signature is allowed depends on the context (:term:`AOT` or :term:`JIT`
compilation), but signatures always involve some representation of Numba
types to specify the concrete types for the function's arguments and,
if required, the function's return type.
An example function signature would be the string ``"f8(i4, i4)"``
(or the equivalent ``"float64(int32, int32)"``) which specifies a
function taking two 32-bit integers and returning a double-precision float.
Basic types
===========
The most basic types can be expressed through simple expressions. The
symbols below refer to attributes of the main ``numba`` module (so if
you read "boolean", it means that symbol can be accessed as ``numba.boolean``).
Many types are available both as a canonical name and a shorthand alias,
following NumPy's conventions.
Numbers
-------
The following table contains the elementary numeric types currently defined
by Numba and their aliases.
=================== ========= ===================================
Type name(s) Shorthand Comments
=================== ========= ===================================
boolean b1 represented as a byte
uint8, byte u1 8-bit unsigned byte
uint16 u2 16-bit unsigned integer
uint32 u4 32-bit unsigned integer
uint64 u8 64-bit unsigned integer
int8, char i1 8-bit signed byte
int16 i2 16-bit signed integer
int32 i4 32-bit signed integer
int64 i8 64-bit signed integer
intc -- C int-sized integer
uintc -- C int-sized unsigned integer
intp -- pointer-sized integer
uintp -- pointer-sized unsigned integer
ssize_t -- C ssize_t
size_t -- C size_t
float32 f4 single-precision floating-point number
float64, double f8 double-precision floating-point number
complex64 c8 single-precision complex number
complex128 c16 double-precision complex number
=================== ========= ===================================
Arrays
------
The easy way to declare :class:`~numba.types.Array` types is to subscript an
elementary type according to the number of dimensions. For example a
1-dimension single-precision array::
>>> numba.float32[:]
array(float32, 1d, A)
or a 3-dimension array of the same underlying type::
>>> numba.float32[:, :, :]
array(float32, 3d, A)
This syntax defines array types with no particular layout (producing code
that accepts both non-contiguous and contiguous arrays), but you can
specify a particular contiguity by using the ``::1`` index either at
the beginning or the end of the index specification::
>>> numba.float32[::1]
array(float32, 1d, C)
>>> numba.float32[:, :, ::1]
array(float32, 3d, C)
>>> numba.float32[::1, :, :]
array(float32, 3d, F)
This style of type declaration is supported within Numba compiled-functions,
e.g. declaring the type of a :ref:`typed.List <feature-typed-list>`.::
from numba import njit, types, typed
@njit
def example():
return typed.List.empty_list(types.float64[:, ::1])
Note that this feature is only supported for simple numerical types. Application
to compound types, e.g. record types, is not supported.
Functions
---------
.. warning::
The feature of considering functions as first-class type objects is
under development.
Functions are often considered as certain transformations of
input arguments to output values. Within Numba :term:`JIT` compiled
functions, the functions can also be considered as objects, that is,
functions can be passed around as arguments or return values, or used
as items in sequences, in addition to being callable.
First-class function support is enabled for all Numba :term:`JIT`
compiled functions and Numba ``cfunc`` compiled functions except when:
- using a non-CPU compiler,
- the compiled function is a Python generator,
- the compiled function has Omitted arguments,
- or the compiled function returns Optional value.
To disable first-class function support, use ``no_cfunc_wrapper=True``
decorator option.
For instance, consider an example where the Numba :term:`JIT` compiled
function applies user-specified functions as a composition to an input
argument::
>>> @numba.njit
... def composition(funcs, x):
... r = x
... for f in funcs[::-1]:
... r = f(r)
... return r
...
>>> @numba.cfunc("double(double)")
... def a(x):
... return x + 1.0
...
>>> @numba.njit
... def b(x):
... return x * x
...
>>> composition((a, b), 0.5), 0.5 ** 2 + 1
(1.25, 1.25)
>>> composition((b, a, b, b, a), 0.5), b(a(b(b(a(0.5)))))
(36.75390625, 36.75390625)
Here, ``cfunc`` compiled functions ``a`` and ``b`` are considered as
first-class function objects because these are passed in to the Numba
:term:`JIT` compiled function ``composition`` as arguments, that is, the
``composition`` is :term:`JIT` compiled independently from its argument function
objects (that are collected in the input argument ``funcs``).
Currently, first-class function objects can be Numba ``cfunc`` compiled
functions, :term:`JIT` compiled functions, and objects that implement the
Wrapper Address Protocol (WAP, see below) with the following restrictions:
======================== ============ ============== ===========
Context JIT compiled cfunc compiled WAP objects
======================== ============ ============== ===========
Can be used as arguments yes yes yes
Can be called yes yes yes
Can be used as items yes\* yes yes
Can be returned yes yes yes
Namespace scoping yes yes yes
Automatic overload yes no no
======================== ============ ============== ===========
\* at least one of the items in a sequence of first-class function objects must
have a precise type.
Wrapper Address Protocol - WAP
++++++++++++++++++++++++++++++
Wrapper Address Protocol provides an API for making any Python object
a first-class function for Numba :term:`JIT` compiled functions. This assumes
that the Python object represents a compiled function that can be
called via its memory address (function pointer value) from Numba :term:`JIT`
compiled functions. The so-called WAP objects must define the
following two methods:
.. method:: __wrapper_address__(self) -> int
Return the memory address of a first-class function. This
method is used when a Numba :term:`JIT` compiled function tries to
call the given WAP instance.
.. method:: signature(self) -> numba.typing.Signature
Return the signature of the given first-class
function. This method is used when passing in the given
WAP instance to a Numba :term:`JIT` compiled function.
In addition, the WAP object may implement the ``__call__``
method. This is necessary when calling WAP objects from Numba
:term:`JIT` compiled functions in :term:`object mode`.
As an example, let us call the standard math library function ``cos``
within a Numba :term:`JIT` compiled function. The memory address of ``cos`` can
be established after loading the math library and using the ``ctypes``
package::
>>> import numba, ctypes, ctypes.util, math
>>> libm = ctypes.cdll.LoadLibrary(ctypes.util.find_library('m'))
>>> class LibMCos(numba.types.WrapperAddressProtocol):
... def __wrapper_address__(self):
... return ctypes.cast(libm.cos, ctypes.c_voidp).value
... def signature(self):
... return numba.float64(numba.float64)
...
>>> @numba.njit
... def foo(f, x):
... return f(x)
...
>>> foo(LibMCos(), 0.0)
1.0
>>> foo(LibMCos(), 0.5), math.cos(0.5)
(0.8775825618903728, 0.8775825618903728)
Miscellaneous Types
-------------------
There are some non-numerical types that do not fit into the other categories.
=================== =================================================
Type name(s) Comments
=================== =================================================
pyobject generic Python object
voidptr raw pointer, no operations can be performed on it
=================== =================================================
Advanced types
==============
For more advanced declarations, you have to explicitly call helper
functions or classes provided by Numba.
.. warning::
The APIs documented here are not guaranteed to be stable. Unless
necessary, it is recommended to let Numba infer argument types by using
the :ref:`signature-less variant of @jit <jit-lazy>`.
.. A word of note: I only documented those types that can be genuinely
useful to users, i.e. types that can be passed as parameters to a JIT
function. Other types such as tuple are only usable in type inference.
Inference
---------
.. function:: numba.typeof(value)
Create a Numba type accurately describing the given Python *value*.
``ValueError`` is raised if the value isn't supported in
:term:`nopython mode`.
::
>>> numba.typeof(np.empty(3))
array(float64, 1d, C)
>>> numba.typeof((1, 2.0))
(int64, float64)
>>> numba.typeof([0])
reflected list(int64)
NumPy scalars
-------------
Instead of using :func:`~numba.typeof`, non-trivial scalars such as
structured types can also be constructed programmatically.
.. function:: numba.from_dtype(dtype)
Create a Numba type corresponding to the given NumPy *dtype*::
>>> struct_dtype = np.dtype([('row', np.float64), ('col', np.float64)])
>>> ty = numba.from_dtype(struct_dtype)
>>> ty
Record([('row', '<f8'), ('col', '<f8')])
>>> ty[:, :]
unaligned array(Record([('row', '<f8'), ('col', '<f8')]), 2d, A)
.. class:: numba.types.NPDatetime(unit)
Create a Numba type for NumPy datetimes of the given *unit*. *unit*
should be a string amongst the codes recognized by NumPy (e.g.
``Y``, ``M``, ``D``, etc.).
.. class:: numba.types.NPTimedelta(unit)
Create a Numba type for NumPy timedeltas of the given *unit*. *unit*
should be a string amongst the codes recognized by NumPy (e.g.
``Y``, ``M``, ``D``, etc.).
.. seealso::
NumPy `datetime units <http://docs.scipy.org/doc/numpy/reference/arrays.datetime.html#datetime-units>`_.
Arrays
------
.. class:: numba.types.Array(dtype, ndim, layout)
Create an array type. *dtype* should be a Numba type. *ndim* is the
number of dimensions of the array (a positive integer). *layout*
is a string giving the layout of the array: ``A`` means any layout, ``C``
means C-contiguous and ``F`` means Fortran-contiguous.
Optional types
--------------
.. class:: numba.optional(typ)
Create an optional type based on the underlying Numba type *typ*.
The optional type will allow any value of either *typ* or :const:`None`.
::
>>> @jit((optional(intp),))
... def f(x):
... return x is not None
...
>>> f(0)
True
>>> f(None)
False
Type annotations
-----------------
.. function:: numba.extending.as_numba_type(py_type)
Create a Numba type corresponding to the given Python *type annotation*.
``TypingError`` is raised if the type annotation can't be mapped to a Numba
type. This function is meant to be used at statically compile time to
evaluate Python type annotations. For runtime checking of Python objects
see ``typeof`` above.
For any numba type, ``as_numba_type(nb_type) == nb_type``.
>>> numba.extending.as_numba_type(int)
int64
>>> import typing # the Python library, not the Numba one
>>> numba.extending.as_numba_type(typing.List[float])
ListType[float64]
>>> numba.extending.as_numba_type(numba.int32)
int32
``as_numba_type`` is automatically updated to include any ``@jitclass``.
>>> @jitclass
... class Counter:
... x: int
...
... def __init__(self):
... self.x = 0
...
... def inc(self):
... old_val = self.x
... self.x += 1
... return old_val
...
>>> numba.extending.as_numba_type(Counter)
instance.jitclass.Counter#11bad4278<x:int64>
Currently ``as_numba_type`` is only used to infer fields for ``@jitclass``.
=========
Utilities
=========
Dealing with pointers
=====================
These functions can be called from pure Python as well as in
:term:`nopython mode`.
.. function:: numba.carray(ptr, shape, dtype=None)
Return a Numpy array view over the data pointed to by *ptr* with the
given *shape*, in C order. If *dtype* is given, it is used as the array's
dtype, otherwise the array's dtype is inferred from *ptr*'s type.
As the returned array is a view, not a copy, writing to it will modify
the original data.
*ptr* should be a ctypes pointer object (either a typed pointer
as created using :func:`~ctypes.POINTER`, or a :class:`~ctypes.c_void_p`).
*shape* should be an integer or a tuple of integers.
*dtype* should be a Numpy dtype or scalar class (i.e. both
``np.dtype('int8')`` and ``np.int8`` are accepted).
.. function:: numba.farray(ptr, shape, dtype=None)
Same as :func:`~numba.carray`, but the data is assumed to be laid out
in Fortran order, and the array view is constructed accordingly.
======================
Release Notes
======================
Towncrier generated notes:
--------------------------
.. toctree::
:maxdepth: 1
:glob:
:reversed:
release/*
Non-Towncrier generated notes:
------------------------------
.. toctree::
:maxdepth: 1
release-notes.rst
This source diff could not be displayed because it is too large. You can view the blob instead.
Version 0.58.0 (20 September 2023)
----------------------------------
.. contents:: Table of Contents
:depth: 2
This is a major Numba release. Numba now uses towncrier to create the release
notes, so please find a summary of all noteworthy items below.
Highlights
~~~~~~~~~~
Added towncrier
"""""""""""""""
This PR adds towncrier as a GitHub workflow for checking release notes.
From this PR onwards every PR made in Numba will require a appropriate
release note associated with it. The reviewer may decide to skip adding
release notes in smaller PRs with minimal impact by addition of a
``skip_release_notes`` label to the PR.
(`PR-#8792 <https://github.com/numba/numba/pull/8792>`__)
The minimum supported NumPy version is 1.22.
""""""""""""""""""""""""""""""""""""""""""""
Following NEP-0029, the minimum supported NumPy version is now 1.22.
(`PR-#9093 <https://github.com/numba/numba/pull/9093>`__)
Add support for NumPy 1.25
""""""""""""""""""""""""""
Extend Numba to support new and changed features released in NumPy 1.25.
(`PR-#9011 <https://github.com/numba/numba/pull/9011>`__)
Remove NVVM 3.4 and CTK 11.0 / 11.1 support
"""""""""""""""""""""""""""""""""""""""""""
Support for CUDA toolkits < 11.2 is removed.
(`PR-#9040 <https://github.com/numba/numba/pull/9040>`__)
Removal of Windows 32-bit Support
"""""""""""""""""""""""""""""""""
This release onwards, Numba has discontinued support for Windows 32-bit
operating systems.
(`PR-#9083 <https://github.com/numba/numba/pull/9083>`__)
The minimum llvmlite version is now 0.41.0.
"""""""""""""""""""""""""""""""""""""""""""
The minimum required version of llvmlite is now version 0.41.0.
(`PR-#8916 <https://github.com/numba/numba/pull/8916>`__)
Added RVSDG-frontend
""""""""""""""""""""
This PR is a preliminary work on adding a RVSDG-frontend for processing
bytecode. RVSDG (Regionalized Value-State Dependence Graph) allows us to
have a dataflow-centric view instead of a traditional SSA-CFG view. This
allows us to simplify the compiler in the future.
(`PR-#9012 <https://github.com/numba/numba/pull/9012>`__)
New Features
~~~~~~~~~~~~
``numba.experimental.jitclass`` gains support for ``__*matmul__`` methods.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
``numba.experimental.jitclass`` now has support for the following methods:
* ``__matmul__``
* ``__imatmul__``
* ``__rmatmul__``
(`PR-#8892 <https://github.com/numba/numba/pull/8892>`__)
``numba.experimental.jitclass`` gains support for reflected "dunder" methods.
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
``numba.experimental.jitclass`` now has support for the following methods:
* ``__radd__``
* ``__rand_``
* ``__rfloordiv__``
* ``__rlshift__``
* ``__ror_``
* ``__rmod_``
* ``__rmul_``
* ``__rpow_``
* ``__rrshift_``
* ``__rsub_``
* ``__rtruediv_``
* ``__rxor_``
(`PR-#8906 <https://github.com/numba/numba/pull/8906>`__)
Add support for value ``max`` to ``NUMBA_OPT``.
"""""""""""""""""""""""""""""""""""""""""""""""
The optimisation level that Numba applies when compiling can be set through the
environment variable ``NUMBA_OPT``. This has historically been a value between
0 and 3 (inclusive). Support for the value ``max`` has now been added, this is a
Numba-specific optimisation level which indicates that the user would like Numba
to try running the most optimisation possible, potentially trading a longer
compilation time for better run-time performance. In practice, use of the ``max``
level of optimisation may or may not benefit the run-time or compile-time
performance of user code, but it has been added to present an easy to access
option for users to try if they so wish.
(`PR-#9094 <https://github.com/numba/numba/pull/9094>`__)
Improvements
~~~~~~~~~~~~
Updates to ``numba.core.pythonapi``.
""""""""""""""""""""""""""""""""""""
Support for Python C-API functions ``PyBytes_AsString`` and
``PyBytes_AsStringAndSize`` is added to ``numba.core.pythonapi.PythonAPI`` as
``bytes_as_string`` and ``bytes_as_string_and_size`` methods respectively.
(`PR-#8462 <https://github.com/numba/numba/pull/8462>`__)
Support for ``isinstance`` is now non-experimental.
"""""""""""""""""""""""""""""""""""""""""""""""""""
Support for the ``isinstance`` built-in function has moved from being considered
an experimental feature to a fully supported feature.
(`PR-#8911 <https://github.com/numba/numba/pull/8911>`__)
NumPy Support
~~~~~~~~~~~~~
All modes are supported in ``numpy.correlate`` and ``numpy.convolve``.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
All values for the ``mode`` argument to ``numpy.correlate`` and
``numpy.convolve`` are now supported.
(`PR-#7543 <https://github.com/numba/numba/pull/7543>`__)
``@vectorize`` accommodates arguments implementing ``__array_ufunc__``.
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Universal functions (``ufunc``\ s) created with ``numba.vectorize`` will now
respect arguments implementing ``__array_ufunc__`` (NEP-13) to allow pre- and
post-processing of arguments and return values when the ufunc is called from the
interpreter.
(`PR-#8995 <https://github.com/numba/numba/pull/8995>`__)
Added support for ``np.geomspace`` function.
""""""""""""""""""""""""""""""""""""""""""""
This PR improves on `#4074 <https://github.com/numba/numba/issues/4074>`__ by
adding support for ``np.geomspace``. The current implementation only supports
scalar ``start`` and ``stop`` parameters.
(`PR-#9068 <https://github.com/numba/numba/pull/9068>`__)
Added support for ``np.vsplit``, ``np.hsplit``, ``np.dsplit``.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
This PR improves on `#4074 <https://github.com/numba/numba/issues/4074>`__ by adding support for ``np.vsplit``, ``np.hsplit``, ``and np.dsplit``.
(`PR-#9082 <https://github.com/numba/numba/pull/9082>`__)
Added support for ``np.row_stack`` function.
""""""""""""""""""""""""""""""""""""""""""""
Support is added for ``numpy.row_stack``.
(`PR-#9085 <https://github.com/numba/numba/pull/9085>`__)
Added support for functions ``np.polynomial.polyutils.trimseq``, as well as functions ``polyadd``, ``polysub``, ``polymul`` from ``np.polynomial.polynomial``.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Support is added for ``np.polynomial.polyutils.trimseq``, ``np.polynomial.polynomial.polyadd``, ``np.polynomial.polynomial.polysub``, ``np.polynomial.polynomial.polymul``.
(`PR-#9087 <https://github.com/numba/numba/pull/9087>`__)
Added support for ``np.diagflat`` function.
"""""""""""""""""""""""""""""""""""""""""""
Support is added for ``numpy.diagflat``.
(`PR-#9113 <https://github.com/numba/numba/pull/9113>`__)
Added support for ``np.resize`` function.
"""""""""""""""""""""""""""""""""""""""""
Support is added for ``numpy.resize``.
(`PR-#9118 <https://github.com/numba/numba/pull/9118>`__)
Add np.trim_zeros
"""""""""""""""""
Support for ``np.trim_zeros()`` is added.
(`PR-#9074 <https://github.com/numba/numba/pull/9074>`__)
CUDA Changes
~~~~~~~~~~~~
Bitwise operation ``ufunc`` support for the CUDA target.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Support is added for some ``ufunc``\ s associated with bitwise operation on the
CUDA target. Namely:
* ``numpy.bitwise_and``
* ``numpy.bitwise_or``
* ``numpy.bitwise_not``
* ``numpy.bitwise_xor``
* ``numpy.invert``
* ``numpy.left_shift``
* ``numpy.right_shift``
(`PR-#8974 <https://github.com/numba/numba/pull/8974>`__)
Add support for the latest CUDA driver codes.
"""""""""""""""""""""""""""""""""""""""""""""
Support is added for the latest set of CUDA driver codes.
(`PR-#8988 <https://github.com/numba/numba/pull/8988>`__)
Add NumPy comparison ufunc in CUDA
""""""""""""""""""""""""""""""""""
this PR adds support for comparison ufuncs for the CUDA target
(eg. ``numpy.greater``, ``numpy.greater_equal``, ``numpy.less_equal``, etc.).
(`PR-#9007 <https://github.com/numba/numba/pull/9007>`__)
Report absolute path of ``libcuda.so`` on Linux
"""""""""""""""""""""""""""""""""""""""""""""""
``numba -s`` now reports the absolute path to ``libcuda.so`` on Linux, to aid
troubleshooting driver issues, particularly on WSL2 where a Linux driver can
incorrectly be installed in the environment.
(`PR-#9034 <https://github.com/numba/numba/pull/9034>`__)
Add debuginfo support to ``nvdisasm`` output.
"""""""""""""""""""""""""""""""""""""""""""""
Support is added for debuginfo (source line and inlining information) in
functions that make calls through ``nvdisasm``. For example the CUDA dispatcher
``.inspect_sass`` method output is now augmented with this information.
(`PR-#9035 <https://github.com/numba/numba/pull/9035>`__)
Add CUDA SASS CFG Support
"""""""""""""""""""""""""
This PR adds support for getting the SASS CFG in dot language format.
It adds an ``inspect_sass_cfg()`` method to CUDADispatcher and the ``-cfg``
flag to the nvdisasm command line tool.
(`PR-#9051 <https://github.com/numba/numba/pull/9051>`__)
Support NVRTC using the ctypes binding
""""""""""""""""""""""""""""""""""""""
NVRTC can now be used when the ctypes binding is in use, enabling float16, and
linking CUDA C / C++ sources without needing the NVIDIA CUDA Python bindings.
(`PR-#9086 <https://github.com/numba/numba/pull/9086>`__)
Fix CUDA atomics tests with toolkit 12.2
""""""""""""""""""""""""""""""""""""""""
CUDA 12.2 generates slightly different PTX for some atomics, so the relevant
tests are updated to look for the correct instructions when 12.2 is used.
(`PR-#9088 <https://github.com/numba/numba/pull/9088>`__)
Bug Fixes
~~~~~~~~~
Handling of different sized unsigned integer indexes are fixed in ``numba.typed.List``.
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
An issue with the order of truncation/extension and casting of unsigned integer
indexes in ``numba.typed.List`` has been fixed.
(`PR-#7262 <https://github.com/numba/numba/pull/7262>`__)
Prevent invalid fusion
""""""""""""""""""""""
This PR fixes an issue in which an array first read in a parfor and later
written in the same parfor would only be classified as used in the parfor.
When a subsequent parfor also used the same array then fusion of the
parfors was happening which should have been forbidden given that that the
first parfor was also writing to the array. This PR treats such arrays
in a parfor as being both used and defined so that fusion will be prevented.
(`PR-#7582 <https://github.com/numba/numba/pull/7582>`__)
The ``numpy.allclose`` implementation now correctly handles default arguments.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
The implementation of ``numpy.allclose`` is corrected to use ``TypingError`` to
report typing errors.
(`PR-#8885 <https://github.com/numba/numba/pull/8885>`__)
Add type validation to ``numpy.isclose``.
"""""""""""""""""""""""""""""""""""""""""
Type validation is added to the implementation of ``numpy.isclose``.
(`PR-#8944 <https://github.com/numba/numba/pull/8944>`__)
Fix support for overloading dispatcher with non-compatible first-class functions
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Fixes an error caused by not handling compilation error during casting of
``Dispatcher`` objects into first-class functions. With the fix, users can now
overload a dispatcher with non-compatible first-class functions. Refer to
https://github.com/numba/numba/issues/9071 for details.
(`PR-#9072 <https://github.com/numba/numba/pull/9072>`__)
Support ``dtype`` keyword argument in ``numpy.arange`` with ``parallel=True``
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Fixes parfors transformation to support the use of ``dtype`` keyword argument in
``numpy.arange(..., dtype=dtype)``.
(`PR-#9095 <https://github.com/numba/numba/pull/9095>`__)
Fix all ``@overload``\ s to use parameter names that match public APIs.
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Some of the Numba ``@overload``\ s for functions in NumPy and Python's built-ins
were written using parameter names that did not match those used in API they
were overloading. The result of this being that calling a function with such a
mismatch using the parameter names as key-word arguments at the call site would
result in a compilation error. This has now been universally fixed throughout
the code base and a unit test is running with a best-effort attempt to prevent
reintroduction of similar mistakes in the future. Fixed functions include:
From Python built-ins:
* ``complex``
From the Python ``random`` module:
* ``random.seed``
* ``random.gauss``
* ``random.normalvariate``
* ``random.randrange``
* ``random.randint``
* ``random.uniform``
* ``random.shuffle``
From the ``numpy`` module:
* ``numpy.argmin``
* ``numpy.argmax``
* ``numpy.array_equal``
* ``numpy.average``
* ``numpy.count_nonzero``
* ``numpy.flip``
* ``numpy.fliplr``
* ``numpy.flipud``
* ``numpy.iinfo``
* ``numpy.isscalar``
* ``numpy.imag``
* ``numpy.real``
* ``numpy.reshape``
* ``numpy.rot90``
* ``numpy.swapaxes``
* ``numpy.union1d``
* ``numpy.unique``
From the ``numpy.linalg`` module:
* ``numpy.linalg.norm``
* ``numpy.linalg.cond``
* ``numpy.linalg.matrix_rank``
From the ``numpy.random`` module:
* ``numpy.random.beta``
* ``numpy.random.chisquare``
* ``numpy.random.f``
* ``numpy.random.gamma``
* ``numpy.random.hypergeometric``
* ``numpy.random.lognormal``
* ``numpy.random.pareto``
* ``numpy.random.randint``
* ``numpy.random.random_sample``
* ``numpy.random.ranf``
* ``numpy.random.rayleigh``
* ``numpy.random.sample``
* ``numpy.random.shuffle``
* ``numpy.random.standard_gamma``
* ``numpy.random.triangular``
* ``numpy.random.weibull``
(`PR-#9099 <https://github.com/numba/numba/pull/9099>`__)
Changes
~~~~~~~
Support for ``@numba.extending.intrinsic(prefer_literal=True)``
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
In the high level extension API, the ``prefer_literal`` option is added to the
``numba.extending.intrinsic`` decorator to prioritize the use of literal types
when available. This has the same behavior as in the ``prefer_literal``
option in the ``numba.extending.overload`` decorator.
(`PR-#6647 <https://github.com/numba/numba/pull/6647>`__)
Deprecations
~~~~~~~~~~~~
Deprecation of old-style ``NUMBA_CAPTURED_ERRORS``
""""""""""""""""""""""""""""""""""""""""""""""""""
Added deprecation schedule of ``NUMBA_CAPTURED_ERRORS=old_style``.
``NUMBA_CAPTURED_ERRORS=new_style`` will become the default in future releases.
Details are documented at
https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-old-style-numba-captured-errors
(`PR-#9090 <https://github.com/numba/numba/pull/9090>`__)
Pull-Requests
~~~~~~~~~~~~~
* PR `#6647 <https://github.com/numba/numba/pull/6647>`_: Support prefer_literal option for intrinsic decorator (`ashutoshvarma <https://github.com/ashutoshvarma>`_ `sklam <https://github.com/sklam>`_)
* PR `#7262 <https://github.com/numba/numba/pull/7262>`_: fix order of handling and casting (`esc <https://github.com/esc>`_)
* PR `#7543 <https://github.com/numba/numba/pull/7543>`_: Support for all modes in np.correlate and np.convolve (`jeertmans <https://github.com/jeertmans>`_)
* PR `#7582 <https://github.com/numba/numba/pull/7582>`_: Use get_parfor_writes to detect illegal array access that prevents fusion. (`DrTodd13 <https://github.com/DrTodd13>`_)
* PR `#8371 <https://github.com/numba/numba/pull/8371>`_: Added binomial distribution (`esc <https://github.com/esc>`_ `kc611 <https://github.com/kc611>`_)
* PR `#8462 <https://github.com/numba/numba/pull/8462>`_: Add PyBytes_AsString and PyBytes_AsStringAndSize (`ianna <https://github.com/ianna>`_)
* PR `#8633 <https://github.com/numba/numba/pull/8633>`_: DOC: Convert vectorize and guvectorize examples to doctests (`Matt711 <https://github.com/Matt711>`_)
* PR `#8730 <https://github.com/numba/numba/pull/8730>`_: Update dev-docs (`sgbaird <https://github.com/sgbaird>`_ `esc <https://github.com/esc>`_)
* PR `#8792 <https://github.com/numba/numba/pull/8792>`_: Added towncrier as a github workflow (`kc611 <https://github.com/kc611>`_)
* PR `#8854 <https://github.com/numba/numba/pull/8854>`_: Updated mk_alloc to support Numba-Dpex compute follows data. (`mingjie-intel <https://github.com/mingjie-intel>`_)
* PR `#8861 <https://github.com/numba/numba/pull/8861>`_: CUDA: Don't add device kwarg for jit registry (`gmarkall <https://github.com/gmarkall>`_)
* PR `#8871 <https://github.com/numba/numba/pull/8871>`_: Don't return the function in CallConv.decorate_function() (`gmarkall <https://github.com/gmarkall>`_)
* PR `#8885 <https://github.com/numba/numba/pull/8885>`_: Fix np.allclose not handling default args (`guilhermeleobas <https://github.com/guilhermeleobas>`_)
* PR `#8892 <https://github.com/numba/numba/pull/8892>`_: Add support for __*matmul__ methods in jitclass (`louisamand <https://github.com/louisamand>`_)
* PR `#8895 <https://github.com/numba/numba/pull/8895>`_: CUDA: Enable caching functions that use CG (`gmarkall <https://github.com/gmarkall>`_)
* PR `#8906 <https://github.com/numba/numba/pull/8906>`_: Add support for reflected dunder methods in jitclass (`louisamand <https://github.com/louisamand>`_)
* PR `#8911 <https://github.com/numba/numba/pull/8911>`_: Remove isinstance experimental feature warning (`guilhermeleobas <https://github.com/guilhermeleobas>`_)
* PR `#8916 <https://github.com/numba/numba/pull/8916>`_: Bump llvmlite requirement to 0.41.0dev0 (`sklam <https://github.com/sklam>`_)
* PR `#8925 <https://github.com/numba/numba/pull/8925>`_: Update release checklist template (`sklam <https://github.com/sklam>`_)
* PR `#8937 <https://github.com/numba/numba/pull/8937>`_: Remove old Website development documentation (`esc <https://github.com/esc>`_ `gmarkall <https://github.com/gmarkall>`_)
* PR `#8944 <https://github.com/numba/numba/pull/8944>`_: Add exceptions to np.isclose (`guilhermeleobas <https://github.com/guilhermeleobas>`_)
* PR `#8974 <https://github.com/numba/numba/pull/8974>`_: CUDA: Add binary ufunc support (`Matt711 <https://github.com/Matt711>`_)
* PR `#8976 <https://github.com/numba/numba/pull/8976>`_: Fix index URL for ptxcompiler/cubinlinker packages. (`bdice <https://github.com/bdice>`_)
* PR `#8978 <https://github.com/numba/numba/pull/8978>`_: Import MVC packages when using MVCLinker. (`bdice <https://github.com/bdice>`_)
* PR `#8983 <https://github.com/numba/numba/pull/8983>`_: Fix typo in deprecation.rst (`dsgibbons <https://github.com/dsgibbons>`_)
* PR `#8988 <https://github.com/numba/numba/pull/8988>`_: support for latest CUDA driver codes #8363 (`s1Sharp <https://github.com/s1Sharp>`_)
* PR `#8995 <https://github.com/numba/numba/pull/8995>`_: Allow libraries that implement __array_ufunc__ to override DUFunc.__c… (`jpivarski <https://github.com/jpivarski>`_)
* PR `#9007 <https://github.com/numba/numba/pull/9007>`_: CUDA: Add comparison ufunc support (`Matt711 <https://github.com/Matt711>`_)
* PR `#9012 <https://github.com/numba/numba/pull/9012>`_: RVSDG-frontend (`sklam <https://github.com/sklam>`_)
* PR `#9021 <https://github.com/numba/numba/pull/9021>`_: update the release checklist following 0.57.1rc1 (`esc <https://github.com/esc>`_)
* PR `#9022 <https://github.com/numba/numba/pull/9022>`_: fix: update the C++ ABI repo reference (`emmanuel-ferdman <https://github.com/emmanuel-ferdman>`_)
* PR `#9028 <https://github.com/numba/numba/pull/9028>`_: Replace use of imp module removed in 3.12 (`hauntsaninja <https://github.com/hauntsaninja>`_)
* PR `#9034 <https://github.com/numba/numba/pull/9034>`_: CUDA libs test: Report the absolute path of the loaded libcuda.so on Linux, + other improvements (`gmarkall <https://github.com/gmarkall>`_)
* PR `#9035 <https://github.com/numba/numba/pull/9035>`_: CUDA: Allow for debuginfo in nvdisasm output (`Matt711 <https://github.com/Matt711>`_)
* PR `#9037 <https://github.com/numba/numba/pull/9037>`_: Recognize additional functions as being pure or not having side effects. (`DrTodd13 <https://github.com/DrTodd13>`_)
* PR `#9039 <https://github.com/numba/numba/pull/9039>`_: Correct git clone link in installation instructions. (`ellifteria <https://github.com/ellifteria>`_)
* PR `#9040 <https://github.com/numba/numba/pull/9040>`_: Remove NVVM 3.4 and CTK 11.0 / 11.1 support (`gmarkall <https://github.com/gmarkall>`_)
* PR `#9046 <https://github.com/numba/numba/pull/9046>`_: copy the change log changes for 0.57.1 to main (`esc <https://github.com/esc>`_)
* PR `#9050 <https://github.com/numba/numba/pull/9050>`_: Update CODEOWNERS (`sklam <https://github.com/sklam>`_)
* PR `#9051 <https://github.com/numba/numba/pull/9051>`_: Add CUDA CFG support (`Matt711 <https://github.com/Matt711>`_)
* PR `#9056 <https://github.com/numba/numba/pull/9056>`_: adding weekly meeting notes script (`esc <https://github.com/esc>`_)
* PR `#9068 <https://github.com/numba/numba/pull/9068>`_: Adding np.geomspace (`KrisMinchev <https://github.com/KrisMinchev>`_)
* PR `#9069 <https://github.com/numba/numba/pull/9069>`_: Fix towncrier error due to importlib_resources upgrade (`sklam <https://github.com/sklam>`_)
* PR `#9072 <https://github.com/numba/numba/pull/9072>`_: Fix support for overloading dispatcher with non-compatible first-class functions (`gmarkall <https://github.com/gmarkall>`_ `sklam <https://github.com/sklam>`_)
* PR `#9074 <https://github.com/numba/numba/pull/9074>`_: Add np.trim_zeros (`sungraek <https://github.com/sungraek>`_ `guilhermeleobas <https://github.com/guilhermeleobas>`_)
* PR `#9082 <https://github.com/numba/numba/pull/9082>`_: Add np.vsplit, np.hsplit, and np.dsplit (`KrisMinchev <https://github.com/KrisMinchev>`_)
* PR `#9083 <https://github.com/numba/numba/pull/9083>`_: Removed windows 32 references from code and documentation (`kc611 <https://github.com/kc611>`_)
* PR `#9085 <https://github.com/numba/numba/pull/9085>`_: Add tests for np.row_stack (`KrisMinchev <https://github.com/KrisMinchev>`_)
* PR `#9086 <https://github.com/numba/numba/pull/9086>`_: Support NVRTC using ctypes binding (`testhound <https://github.com/testhound>`_ `gmarkall <https://github.com/gmarkall>`_)
* PR `#9087 <https://github.com/numba/numba/pull/9087>`_: Add trimseq from np.polynomial.polyutils and polyadd, polysub, polymul from np.polynomial.polynomial (`KrisMinchev <https://github.com/KrisMinchev>`_)
* PR `#9088 <https://github.com/numba/numba/pull/9088>`_: Fix: Issue 9063 - CUDA atomics tests failing with CUDA 12.2 (`gmarkall <https://github.com/gmarkall>`_)
* PR `#9090 <https://github.com/numba/numba/pull/9090>`_: Add deprecation notice for old_style error capturing. (`esc <https://github.com/esc>`_ `sklam <https://github.com/sklam>`_)
* PR `#9094 <https://github.com/numba/numba/pull/9094>`_: Add support for a 'max' level to NUMBA_OPT environment variable. (`stuartarchibald <https://github.com/stuartarchibald>`_)
* PR `#9095 <https://github.com/numba/numba/pull/9095>`_: Support dtype keyword in arange_parallel_impl (`DrTodd13 <https://github.com/DrTodd13>`_ `sklam <https://github.com/sklam>`_)
* PR `#9105 <https://github.com/numba/numba/pull/9105>`_: NumPy 1.25 support (PR #9011) continued (`gmarkall <https://github.com/gmarkall>`_ `apmasell <https://github.com/apmasell>`_)
* PR `#9111 <https://github.com/numba/numba/pull/9111>`_: Fixes ReST syntax error in PR#9099 (`stuartarchibald <https://github.com/stuartarchibald>`_ `gmarkall <https://github.com/gmarkall>`_ `sklam <https://github.com/sklam>`_ `apmasell <https://github.com/apmasell>`_)
* PR `#9112 <https://github.com/numba/numba/pull/9112>`_: Fixups for PR#9100 (`stuartarchibald <https://github.com/stuartarchibald>`_ `sklam <https://github.com/sklam>`_)
* PR `#9113 <https://github.com/numba/numba/pull/9113>`_: Add support for np.diagflat (`KrisMinchev <https://github.com/KrisMinchev>`_)
* PR `#9114 <https://github.com/numba/numba/pull/9114>`_: update np min to 122 (`stuartarchibald <https://github.com/stuartarchibald>`_ `esc <https://github.com/esc>`_)
* PR `#9117 <https://github.com/numba/numba/pull/9117>`_: Fixed towncrier template rendering (`kc611 <https://github.com/kc611>`_)
* PR `#9118 <https://github.com/numba/numba/pull/9118>`_: Add support for np.resize() (`KrisMinchev <https://github.com/KrisMinchev>`_)
* PR `#9120 <https://github.com/numba/numba/pull/9120>`_: Update conda-recipe for numba-rvsdg (`sklam <https://github.com/sklam>`_)
* PR `#9127 <https://github.com/numba/numba/pull/9127>`_: Fix accidental cffi test deps, refactor cffi skipping (`gmarkall <https://github.com/gmarkall>`_)
* PR `#9128 <https://github.com/numba/numba/pull/9128>`_: Merge rvsdg_frontend branch to main (`esc <https://github.com/esc>`_ `sklam <https://github.com/sklam>`_)
* PR `#9152 <https://github.com/numba/numba/pull/9152>`_: Fix old_style error capturing deprecation warnings (`sklam <https://github.com/sklam>`_)
* PR `#9159 <https://github.com/numba/numba/pull/9159>`_: Fix uncaught exception in find_file() (`gmarkall <https://github.com/gmarkall>`_)
* PR `#9173 <https://github.com/numba/numba/pull/9173>`_: Towncrier fixups (Continue #9158 and retarget to main branch) (`sklam <https://github.com/sklam>`_)
* PR `#9181 <https://github.com/numba/numba/pull/9181>`_: Remove extra decrefs in RNG (`sklam <https://github.com/sklam>`_)
* PR `#9190 <https://github.com/numba/numba/pull/9190>`_: Fix issue with incompatible multiprocessing context in test. (`stuartarchibald <https://github.com/stuartarchibald>`_)
Authors
~~~~~~~
* `apmasell <https://github.com/apmasell>`_
* `ashutoshvarma <https://github.com/ashutoshvarma>`_
* `bdice <https://github.com/bdice>`_
* `DrTodd13 <https://github.com/DrTodd13>`_
* `dsgibbons <https://github.com/dsgibbons>`_
* `ellifteria <https://github.com/ellifteria>`_
* `emmanuel-ferdman <https://github.com/emmanuel-ferdman>`_
* `esc <https://github.com/esc>`_
* `gmarkall <https://github.com/gmarkall>`_
* `guilhermeleobas <https://github.com/guilhermeleobas>`_
* `hauntsaninja <https://github.com/hauntsaninja>`_
* `ianna <https://github.com/ianna>`_
* `jeertmans <https://github.com/jeertmans>`_
* `jpivarski <https://github.com/jpivarski>`_
* `jtilly <https://github.com/jtilly>`_
* `kc611 <https://github.com/kc611>`_
* `KrisMinchev <https://github.com/KrisMinchev>`_
* `louisamand <https://github.com/louisamand>`_
* `Matt711 <https://github.com/Matt711>`_
* `mingjie-intel <https://github.com/mingjie-intel>`_
* `s1Sharp <https://github.com/s1Sharp>`_
* `sgbaird <https://github.com/sgbaird>`_
* `sklam <https://github.com/sklam>`_
* `stuartarchibald <https://github.com/stuartarchibald>`_
* `sungraek <https://github.com/sungraek>`_
* `testhound <https://github.com/testhound>`_
Version 0.58.1 (17 October 2023)
--------------------------------
This is a maintenance release that adds support for NumPy 1.26 and fixes a bug.
NumPy Support
~~~~~~~~~~~~~
Support NumPy 1.26
==================
Support for NumPy 1.26 is added.
(`PR-#9227 <https://github.com/numba/numba/pull/9227>`__)
Bug Fixes
~~~~~~~~~
Fixed handling of float default arguments in inline closures
============================================================
Float default arguments in inline closures would produce incorrect results since
updates for Python 3.11 - these are now handled correctly again.
(`PR-#9222 <https://github.com/numba/numba/pull/9222>`__)
Pull-Requests
~~~~~~~~~~~~~
* PR `#9220 <https://github.com/numba/numba/pull/9220>`_: Support passing arbitrary flags to NVVM (`gmarkall <https://github.com/gmarkall>`_)
* PR `#9227 <https://github.com/numba/numba/pull/9227>`_: Support NumPy 1.26 (PR aimed at review / merge) (`Tialo <https://github.com/Tialo>`_ `gmarkall <https://github.com/gmarkall>`_)
* PR `#9228 <https://github.com/numba/numba/pull/9228>`_: Fix #9222 - Don't replace `.` with `_` in func arg names in inline closures (`gmarkall <https://github.com/gmarkall>`_)
Authors
~~~~~~~
* `gmarkall <https://github.com/gmarkall>`_
* `Tialo <https://github.com/Tialo>`_
.. _numba-5_mins:
A ~5 minute guide to Numba
==========================
Numba is a just-in-time compiler for Python that works best on code that uses
NumPy arrays and functions, and loops. The most common way to use Numba is
through its collection of decorators that can be applied to your functions to
instruct Numba to compile them. When a call is made to a Numba-decorated
function it is compiled to machine code "just-in-time" for execution and all or
part of your code can subsequently run at native machine code speed!
Out of the box Numba works with the following:
* OS: Windows (64 bit), OSX, Linux (64 bit). Unofficial support on
\*BSD.
* Architecture: x86, x86_64, ppc64le, armv8l (aarch64), M1/Arm64.
* GPUs: Nvidia CUDA.
* CPython
* NumPy 1.22 - 1.26
How do I get it?
----------------
Numba is available as a `conda <https://conda.io/docs/>`_ package for the
`Anaconda Python distribution <https://www.anaconda.com/>`_::
$ conda install numba
Numba also has wheels available::
$ pip install numba
Numba can also be
:ref:`compiled from source <numba-source-install-instructions>`, although we do
not recommend it for first-time Numba users.
Numba is often used as a core package so its dependencies are kept to an
absolute minimum, however, extra packages can be installed as follows to provide
additional functionality:
* ``scipy`` - enables support for compiling ``numpy.linalg`` functions.
* ``colorama`` - enables support for color highlighting in backtraces/error
messages.
* ``pyyaml`` - enables configuration of Numba via a YAML config file.
* ``intel-cmplr-lib-rt`` - allows the use of the Intel SVML (high performance
short vector math library, x86_64 only). Installation instructions are in the
:ref:`performance tips <intel-svml>`.
Will Numba work for my code?
----------------------------
This depends on what your code looks like, if your code is numerically
orientated (does a lot of math), uses NumPy a lot and/or has a lot of loops,
then Numba is often a good choice. In these examples we'll apply the most
fundamental of Numba's JIT decorators, ``@jit``, to try and speed up some
functions to demonstrate what works well and what does not.
Numba works well on code that looks like this::
from numba import jit
import numpy as np
x = np.arange(100).reshape(10, 10)
@jit(nopython=True) # Set "nopython" mode for best performance, equivalent to @njit
def go_fast(a): # Function is compiled to machine code when called the first time
trace = 0.0
for i in range(a.shape[0]): # Numba likes loops
trace += np.tanh(a[i, i]) # Numba likes NumPy functions
return a + trace # Numba likes NumPy broadcasting
print(go_fast(x))
It won't work very well, if at all, on code that looks like this::
from numba import jit
import pandas as pd
x = {'a': [1, 2, 3], 'b': [20, 30, 40]}
@jit
def use_pandas(a): # Function will not benefit from Numba jit
df = pd.DataFrame.from_dict(a) # Numba doesn't know about pd.DataFrame
df += 1 # Numba doesn't understand what this is
return df.cov() # or this!
print(use_pandas(x))
Note that Pandas is not understood by Numba and as a result Numba would simply
run this code via the interpreter but with the added cost of the Numba internal
overheads!
What is ``nopython`` mode?
--------------------------
The Numba ``@jit`` decorator fundamentally operates in two compilation modes,
``nopython`` mode and ``object`` mode. In the ``go_fast`` example above,
``nopython=True`` is set in the ``@jit`` decorator; this is instructing Numba to
operate in ``nopython`` mode. The behaviour of the ``nopython`` compilation mode
is to essentially compile the decorated function so that it will run entirely
without the involvement of the Python interpreter. This is the recommended and
best-practice way to use the Numba ``jit`` decorator as it leads to the best
performance.
Should the compilation in ``nopython`` mode fail, Numba can compile using
``object mode``. This is a fall back mode for the ``@jit`` decorator if
``nopython=True`` is not set (as seen in the ``use_pandas`` example above). In
this mode Numba will identify loops that it can compile and compile those into
functions that run in machine code, and it will run the rest of the code in the
interpreter. For best performance avoid using this mode!
How to measure the performance of Numba?
----------------------------------------
First, recall that Numba has to compile your function for the argument types
given before it executes the machine code version of your function. This takes
time. However, once the compilation has taken place Numba caches the machine
code version of your function for the particular types of arguments presented.
If it is called again with the same types, it can reuse the cached version
instead of having to compile again.
A really common mistake when measuring performance is to not account for the
above behaviour and to time code once with a simple timer that includes the
time taken to compile your function in the execution time.
For example::
from numba import jit
import numpy as np
import time
x = np.arange(100).reshape(10, 10)
@jit(nopython=True)
def go_fast(a): # Function is compiled and runs in machine code
trace = 0.0
for i in range(a.shape[0]):
trace += np.tanh(a[i, i])
return a + trace
# DO NOT REPORT THIS... COMPILATION TIME IS INCLUDED IN THE EXECUTION TIME!
start = time.perf_counter()
go_fast(x)
end = time.perf_counter()
print("Elapsed (with compilation) = {}s".format((end - start)))
# NOW THE FUNCTION IS COMPILED, RE-TIME IT EXECUTING FROM CACHE
start = time.perf_counter()
go_fast(x)
end = time.perf_counter()
print("Elapsed (after compilation) = {}s".format((end - start)))
This, for example prints:
.. code-block:: pycon
Elapsed (with compilation) = 0.33030009269714355s
Elapsed (after compilation) = 6.67572021484375e-06s
A good way to measure the impact Numba JIT has on your code is to time execution
using the `timeit <https://docs.python.org/3/library/timeit.html>`_ module
functions; these measure multiple iterations of execution and, as a result,
can be made to accommodate for the compilation time in the first execution.
As a side note, if compilation time is an issue, Numba JIT supports
:ref:`on-disk caching <jit-decorator-cache>` of compiled functions and also has
an :ref:`Ahead-Of-Time <aot-compilation>` compilation mode.
How fast is it?
---------------
Assuming Numba can operate in ``nopython`` mode, or at least compile some loops,
it will target compilation to your specific CPU. Speed up varies depending on
application but can be one to two orders of magnitude. Numba has a
:ref:`performance guide <performance-tips>` that covers common options for
gaining extra performance.
How does Numba work?
--------------------
Numba reads the Python bytecode for a decorated function and combines this with
information about the types of the input arguments to the function. It analyzes
and optimizes your code, and finally uses the LLVM compiler library to generate
a machine code version of your function, tailored to your CPU capabilities. This
compiled version is then used every time your function is called.
Other things of interest:
-------------------------
Numba has quite a few decorators, we've seen ``@jit``, but there's
also:
* ``@njit`` - this is an alias for ``@jit(nopython=True)`` as it is so commonly
used!
* ``@vectorize`` - produces NumPy ``ufunc`` s (with all the ``ufunc`` methods
supported). :ref:`Docs are here <vectorize>`.
* ``@guvectorize`` - produces NumPy generalized ``ufunc`` s.
:ref:`Docs are here <guvectorize>`.
* ``@stencil`` - declare a function as a kernel for a stencil like operation.
:ref:`Docs are here <numba-stencil>`.
* ``@jitclass`` - for jit aware classes. :ref:`Docs are here <jitclass>`.
* ``@cfunc`` - declare a function for use as a native call back (to be called
from C/C++ etc). :ref:`Docs are here <cfunc>`.
* ``@overload`` - register your own implementation of a function for use in
nopython mode, e.g. ``@overload(scipy.special.j0)``.
:ref:`Docs are here <high-level-extending>`.
Extra options available in some decorators:
* ``parallel = True`` - :ref:`enable <jit-decorator-parallel>` the
:ref:`automatic parallelization <numba-parallel>` of the function.
* ``fastmath = True`` - enable :ref:`fast-math <jit-decorator-fastmath>`
behaviour for the function.
ctypes/cffi/cython interoperability:
* ``cffi`` - The calling of :ref:`CFFI <cffi-support>` functions is supported
in ``nopython`` mode.
* ``ctypes`` - The calling of :ref:`ctypes <ctypes-support>` wrapped
functions is supported in ``nopython`` mode.
* Cython exported functions :ref:`are callable <cython-support>`.
GPU targets:
~~~~~~~~~~~~
Numba can target `Nvidia CUDA <https://developer.nvidia.com/cuda-zone>`_ GPUs.
You can write a kernel in pure Python and have Numba handle the computation and
data movement (or do this explicitly). Click for Numba documentation on
:ref:`CUDA <cuda-index>`.
.. _cfunc:
====================================
Creating C callbacks with ``@cfunc``
====================================
Interfacing with some native libraries (for example written in C or C++)
can necessitate writing native callbacks to provide business logic to the
library. The :func:`numba.cfunc` decorator creates a compiled function
callable from foreign C code, using the signature of your choice.
Basic usage
===========
The ``@cfunc`` decorator has a similar usage to ``@jit``, but with an
important difference: passing a single signature is mandatory.
It determines the visible signature of the C callback::
from numba import cfunc
@cfunc("float64(float64, float64)")
def add(x, y):
return x + y
The C function object exposes the address of the compiled C callback as
the :attr:`~CFunc.address` attribute, so that you can pass it to any
foreign C or C++ library. It also exposes a :mod:`ctypes` callback
object pointing to that callback; that object is also callable from
Python, making it easy to check the compiled code::
@cfunc("float64(float64, float64)")
def add(x, y):
return x + y
print(add.ctypes(4.0, 5.0)) # prints "9.0"
Example
=======
In this example, we are going to be using the ``scipy.integrate.quad``
function. That function accepts either a regular Python callback or
a C callback wrapped in a :mod:`ctypes` callback object.
Let's define a pure Python integrand and compile it as a
C callback::
>>> import numpy as np
>>> from numba import cfunc
>>> def integrand(t):
return np.exp(-t) / t**2
...:
>>> nb_integrand = cfunc("float64(float64)")(integrand)
We can pass the ``nb_integrand`` object's :mod:`ctypes` callback to
``scipy.integrate.quad`` and check that the results are the same as with
the pure Python function::
>>> import scipy.integrate as si
>>> def do_integrate(func):
"""
Integrate the given function from 1.0 to +inf.
"""
return si.quad(func, 1, np.inf)
...:
>>> do_integrate(integrand)
(0.14849550677592208, 3.8736750296130505e-10)
>>> do_integrate(nb_integrand.ctypes)
(0.14849550677592208, 3.8736750296130505e-10)
Using the compiled callback, the integration function does not invoke the
Python interpreter each time it evaluates the integrand. In our case, the
integration is made 18 times faster::
>>> %timeit do_integrate(integrand)
1000 loops, best of 3: 242 µs per loop
>>> %timeit do_integrate(nb_integrand.ctypes)
100000 loops, best of 3: 13.5 µs per loop
Dealing with pointers and array memory
======================================
A less trivial use case of C callbacks involves doing operation on some
array of data passed by the caller. As C doesn't have a high-level
abstraction similar to Numpy arrays, the C callback's signature will pass
low-level pointer and size arguments. Nevertheless, the Python code for
the callback will expect to exploit the power and expressiveness of Numpy
arrays.
In the following example, the C callback is expected to operate on 2-d arrays,
with the signature ``void(double *input, double *output, int m, int n)``.
You can implement such a callback thusly::
from numba import cfunc, types, carray
c_sig = types.void(types.CPointer(types.double),
types.CPointer(types.double),
types.intc, types.intc)
@cfunc(c_sig)
def my_callback(in_, out, m, n):
in_array = carray(in_, (m, n))
out_array = carray(out, (m, n))
for i in range(m):
for j in range(n):
out_array[i, j] = 2 * in_array[i, j]
The :func:`numba.carray` function takes as input a data pointer and a shape
and returns an array view of the given shape over that data. The data is
assumed to be laid out in C order. If the data is laid out in Fortran order,
:func:`numba.farray` should be used instead.
Handling C structures
=====================
With CFFI
---------
For applications that have a lot of state, it is useful to pass data in C
structures. To simplify the interoperability with C code, numba can convert
a ``cffi`` type into a numba ``Record`` type using
``numba.core.typing.cffi_utils.map_type``::
from numba.core.typing import cffi_utils
nbtype = cffi_utils.map_type(cffi_type, use_record_dtype=True)
.. note:: **use_record_dtype=True** is needed otherwise pointers to C
structures are returned as void pointers.
.. note:: From v0.49 the ``numba.cffi_support`` module has been phased out
in favour of ``numba.core.typing.cffi_utils``
For example::
from cffi import FFI
src = """
/* Define the C struct */
typedef struct my_struct {
int i1;
float f2;
double d3;
float af4[7]; // arrays are supported
} my_struct;
/* Define a callback function */
typedef double (*my_func)(my_struct*, size_t);
"""
ffi = FFI()
ffi.cdef(src)
# Get the function signature from *my_func*
sig = cffi_utils.map_type(ffi.typeof('my_func'), use_record_dtype=True)
# Make the cfunc
from numba import cfunc, carray
@cfunc(sig)
def foo(ptr, n):
base = carray(ptr, n) # view pointer as an array of my_struct
tmp = 0
for i in range(n):
tmp += base[i].i1 * base[i].f2 / base[i].d3
tmp += base[i].af4.sum() # nested arrays are like normal NumPy arrays
return tmp
With ``numba.types.Record.make_c_struct``
-----------------------------------------
The ``numba.types.Record`` type can be created manually to follow a
C-structure's layout. To do that, use ``Record.make_c_struct``, for example::
my_struct = types.Record.make_c_struct([
# Provides a sequence of 2-tuples i.e. (name:str, type:Type)
('i1', types.int32),
('f2', types.float32),
('d3', types.float64),
('af4', types.NestedArray(dtype=types.float32, shape=(7,))),
])
Due to ABI limitations, structures should be passed as pointers
using ``types.CPointer(my_struct)`` as the argument type. Inside the ``cfunc``
body, the ``my_struct*`` can be accessed with ``carray``.
Full example
------------
See full example in ``examples/notebooks/Accessing C Struct Data.ipynb``.
Signature specification
=======================
The explicit ``@cfunc`` signature can use any :ref:`Numba types <numba-types>`,
but only a subset of them make sense for a C callback. You should
generally limit yourself to scalar types (such as ``int8`` or ``float64``)
,pointers to them (for example ``types.CPointer(types.int8)``), or pointers
to ``Record`` type.
Compilation options
===================
A number of keyword-only arguments can be passed to the ``@cfunc``
decorator: ``nopython`` and ``cache``. Their meaning is similar to those
in the ``@jit`` decorator.
Calling C code from Numba
=========================
It is also possible to call C code from Numba ``@jit`` functions. In this
example, we are going to be compiling a simple function ``sum`` that adds two
integers and calling it within Numba ``@jit`` code.
.. note::
The example below was tested on Linux and will likely work on Unix-like
operating systems.
.. code-block:: C
#include <stdint.h>
int64_t sum(int64_t a, int64_t b){
return a + b;
}
Compile the code with ``gcc lib.c -fPIC -shared -o shared_library.so`` to
generate a shared library.
.. code-block:: python
from numba import njit
from numba.core import types, typing
from llvmlite import binding
import os
# load the library into LLVM
path = os.path.abspath('./shared_library.so')
binding.load_library_permanently(path)
# Adds typing information
c_func_name = 'sum'
return_type = types.int64
argty = types.int64
c_sig = typing.signature(return_type, argty, argty)
c_func = types.ExternalFunction(c_func_name, c_sig)
@njit
def example(x, y):
return c_func(x, y)
print(example(3, 4)) # 7
It is also possible to use ``ctypes`` as well to call C functions. The advantage
of using ``ctypes`` is that it is invariant to the usage of JIT decorators.
.. code-block:: python
from numba import njit
import ctypes
DSO = ctypes.CDLL('./shared_library.so')
# Add typing information
c_func = DSO.sum
c_func.restype = ctypes.c_int
c_func.argtypes = [ctypes.c_int, ctypes.c_int]
@njit
def example(x, y):
return c_func(x, y)
print(example(3, 4)) # 7
print(example.py_func(3, 4)) # 7
.. _cli:
Command line interface
======================
Numba is a Python package, usually you ``import numba`` from Python and use the
Python application programming interface (API). However, Numba also ships with a
command line interface (CLI), i.e. a tool ``numba`` that is installed when you
install Numba.
Currently, the only purpose of the CLI is to allow you to quickly show some
information about your system and installation, or to quickly get some debugging
information for a Python script using Numba.
.. _cli_usage:
Usage
-----
To use the Numba CLI from the terminal, use ``numba`` followed by the options
and arguments like ``--help`` or ``-s``, as explained below.
Sometimes it can happen that you get a "command not found" error when you type
``numba``, because your ``PATH`` isn't configured properly. In that case you can
use the equivalent command ``python -m numba``. If that still gives "command
not found", try to ``import numba`` as suggested here:
:ref:`numba-source-install-check`.
The two versions ``numba`` and ``python -m numba`` are the same. The first is
shorter to type, but if you get a "command not found" error because your
``PATH`` doesn't contain the location where ``numba`` is installed, having the
``python -m numba`` variant is useful.
To use the Numba CLI from IPython or Jupyter, use ``!numba``, i.e. prefix the
command with an exclamation mark. This is a general IPython/Jupyter feature to
execute shell commands, it is not available in the regular ``python`` terminal.
.. _cli_help:
Help
----
To see all available options, use ``numba --help``::
$ numba --help
usage: numba [-h] [--annotate] [--dump-llvm] [--dump-optimized]
[--dump-assembly] [--annotate-html ANNOTATE_HTML] [-s]
[--sys-json SYS_JSON]
[filename]
positional arguments:
filename Python source filename
optional arguments:
-h, --help show this help message and exit
--annotate Annotate source
--dump-llvm Print generated llvm assembly
--dump-optimized Dump the optimized llvm assembly
--dump-assembly Dump the LLVM generated assembly
--annotate-html ANNOTATE_HTML
Output source annotation as html
-s, --sysinfo Output system information for bug reporting
--sys-json SYS_JSON Saves the system info dict as a json file
.. _cli_sysinfo:
System information
------------------
The ``numba -s`` (or the equivalent ``numba --sysinfo``) command prints a lot of
information about your system and your Numba installation and relevant
dependencies.
Remember: you can use ``!numba -s`` with an exclamation mark to see this
information from IPython or Jupyter.
Example output::
$ numba -s
System info:
--------------------------------------------------------------------------------
__Time Stamp__
Report started (local time) : 2022-11-30 15:40:42.368114
UTC start time : 2022-11-30 15:40:42.368129
Running time (s) : 2.563586
__Hardware Information__
Machine : x86_64
CPU Name : ivybridge
CPU Count : 3
Number of accessible CPUs : ?
List of accessible CPUs cores : ?
CFS Restrictions (CPUs worth of runtime) : None
CPU Features : 64bit aes avx cmov cx16 cx8 f16c
fsgsbase fxsr mmx pclmul popcnt
rdrnd sahf sse sse2 sse3 sse4.1
sse4.2 ssse3 xsave
Memory Total (MB) : 14336
Memory Available (MB) : 11540
__OS Information__
Platform Name : macOS-10.16-x86_64-i386-64bit
Platform Release : 20.6.0
OS Name : Darwin
OS Version : Darwin Kernel Version 20.6.0: Thu Sep 29 20:15:11 PDT 2022; root:xnu-7195.141.42~1/RELEASE_X86_64
OS Specific Version : 10.16 x86_64
Libc Version : ?
__Python Information__
Python Compiler : Clang 14.0.6
Python Implementation : CPython
Python Version : 3.10.8
Python Locale : en_US.UTF-8
__Numba Toolchain Versions__
Numba Version : 0+untagged.gb91eec710
llvmlite Version : 0.40.0dev0+43.g7783803
__LLVM Information__
LLVM Version : 11.1.0
__CUDA Information__
CUDA Device Initialized : False
CUDA Driver Version : ?
CUDA Runtime Version : ?
CUDA NVIDIA Bindings Available : ?
CUDA NVIDIA Bindings In Use : ?
CUDA Detect Output:
None
CUDA Libraries Test Output:
None
__NumPy Information__
NumPy Version : 1.23.4
NumPy Supported SIMD features : ('MMX', 'SSE', 'SSE2', 'SSE3', 'SSSE3', 'SSE41', 'POPCNT', 'SSE42', 'AVX', 'F16C')
NumPy Supported SIMD dispatch : ('SSSE3', 'SSE41', 'POPCNT', 'SSE42', 'AVX', 'F16C', 'FMA3', 'AVX2', 'AVX512F', 'AVX512CD', 'AVX512_KNL', 'AVX512_SKX', 'AVX512_CLX', 'AVX512_CNL', 'AVX512_ICL')
NumPy Supported SIMD baseline : ('SSE', 'SSE2', 'SSE3')
NumPy AVX512_SKX support detected : False
__SVML Information__
SVML State, config.USING_SVML : False
SVML Library Loaded : False
llvmlite Using SVML Patched LLVM : True
SVML Operational : False
__Threading Layer Information__
TBB Threading Layer Available : True
+-->TBB imported successfully.
OpenMP Threading Layer Available : True
+-->Vendor: Intel
Workqueue Threading Layer Available : True
+-->Workqueue imported successfully.
__Numba Environment Variable Information__
None found.
__Conda Information__
Conda Build : not installed
Conda Env : 4.12.0
Conda Platform : osx-64
Conda Python Version : 3.9.12.final.0
Conda Root Writable : True
__Installed Packages__
(output truncated due to length)
.. _cli_debug:
Debugging
---------
As shown in the help output above, the ``numba`` command includes options that
can help you to debug Numba compiled code.
To try it out, create an example script called ``myscript.py``::
import numba
@numba.jit
def f(x):
return 2 * x
f(42)
and then execute one of the following commands::
$ numba myscript.py --annotate
$ numba myscript.py --annotate-html myscript.html
$ numba myscript.py --dump-llvm
$ numba myscript.py --dump-optimized
$ numba myscript.py --dump-assembly
========
Examples
========
Mandelbrot
----------
.. literalinclude:: ../../../numba/tests/doc_examples/test_examples.py
:language: python
:caption: from ``test_mandelbrot`` of ``numba/tests/doc_examples/test_examples.py``
:start-after: magictoken.ex_mandelbrot.begin
:end-before: magictoken.ex_mandelbrot.end
:dedent: 12
:linenos:
.. _example-movemean:
Moving average
--------------
.. literalinclude:: ../../../numba/tests/doc_examples/test_examples.py
:language: python
:caption: from ``test_moving_average`` of ``numba/tests/doc_examples/test_examples.py``
:start-after: magictoken.ex_moving_average.begin
:end-before: magictoken.ex_moving_average.end
:dedent: 12
:linenos:
Multi-threading
---------------
The code below showcases the potential performance improvement when
using the :ref:`nogil <jit-nogil>` feature. For example, on a 4-core machine,
the following results were printed::
numpy (1 thread) 145 ms
numba (1 thread) 128 ms
numba (4 threads) 35 ms
.. note::
If preferred it's possible to use the standard `concurrent.futures
<https://docs.python.org/3/library/concurrent.futures.html>`_ module
rather than spawn threads and dispatch tasks by hand.
.. literalinclude:: ../../../numba/tests/doc_examples/test_examples.py
:language: python
:caption: from ``test_no_gil`` of ``numba/tests/doc_examples/test_examples.py``
:start-after: magictoken.ex_no_gil.begin
:end-before: magictoken.ex_no_gil.end
:dedent: 12
:linenos:
==========================
Frequently Asked Questions
==========================
Installation
============
Numba could not be imported
---------------------------
If you are seeing an exception on importing Numba with an error message
that starts with::
ImportError: Numba could not be imported.
here are some common issues and things to try to fix it.
#. Your installation has more than one version of Numba a given environment.
Common ways this occurs include:
* Installing Numba with conda and then installing again with pip.
* Installing Numba with pip and then updating to a new version with pip (pip
re-installations don't seem to always clean up very well).
To fix this the best approach is to create an entirely new environment and
install a single version of Numba in that environment using a package manager
of your choice.
#. Your installation has Numba for Python version X but you are running with
Python version Y.
This occurs due to a variety of Python environment mix-up/mismatch problems.
The most common mismatch comes from installing Numba into the
site-packages/environment of one version of Python by using a base or
system installation of Python that is a different version, this typically
happens through the use of the "wrong" ``pip`` binary. This will obviously
cause problems as the C-Extensions on which Numba relies are bound to
specific Python versions. A way to check if this likely the problem is to
see if the path to the ``python`` binary at::
python -c 'import sys; print(sys.executable)'
matches the path to your installation tool and/or matches the reported
installation location and if the Python versions match up across all of
these. Note that Python version ``X.Y.A`` is compatible with ``X.Y.B``.
To fix this the best approach is to create an entirely new environment and
ensure that the installation tool used to install Numba is the one from that
environment/the Python versions at install and run time match.
#. Your core system libraries are too old.
This is a somewhat rare occurrence, but there are occasions when a very old
(typically out of support) version of Linux is in use it doesn't have a
``glibc`` library with sufficiently new versioned symbols for Numba's shared
libraries to resolve against. The fix for this is to update your OS system
libraries/update your OS.
#. You are using an IDE e.g. Spyder.
There are some unknown issues in relation to installing Numba via IDEs, but
it would appear that these are likely variations of 1. or 2. with the same
suggested fixes. Also, try installation from outside of the IDE with the
command line.
If you have an installation problem which is not one of the above problems,
please do ask on `numba.discourse.group <https://numba.discourse.group/>`_ and
if possible include the path where Numba is installed and also the output of::
python -c 'import sys; print(sys.executable)'
Programming
===========
Can I pass a function as an argument to a jitted function?
----------------------------------------------------------
As of Numba 0.39, you can, so long as the function argument has also been
JIT-compiled::
@jit(nopython=True)
def f(g, x):
return g(x) + g(-x)
result = f(jitted_g_function, 1)
However, dispatching with arguments that are functions has extra overhead.
If this matters for your application, you can also use a factory function to
capture the function argument in a closure::
def make_f(g):
# Note: a new f() is created each time make_f() is called!
@jit(nopython=True)
def f(x):
return g(x) + g(-x)
return f
f = make_f(jitted_g_function)
result = f(1)
Improving the dispatch performance of functions in Numba is an ongoing task.
Numba doesn't seem to care when I modify a global variable
----------------------------------------------------------
Numba considers global variables as compile-time constants. If you want
your jitted function to update itself when you have modified a global
variable's value, one solution is to recompile it using the
:meth:`~Dispatcher.recompile` method. This is a relatively slow operation,
though, so you may instead decide to rearchitect your code and turn the
global variable into a function argument.
Can I debug a jitted function?
------------------------------
Calling into :mod:`pdb` or other such high-level facilities is currently not
supported from Numba-compiled code. However, you can temporarily disable
compilation by setting the :envvar:`NUMBA_DISABLE_JIT` environment
variable.
How can I create a Fortran-ordered array?
-----------------------------------------
Numba currently doesn't support the ``order`` argument to most Numpy
functions such as :func:`numpy.empty` (because of limitations in the
:term:`type inference` algorithm). You can work around this issue by
creating a C-ordered array and then transposing it. For example::
a = np.empty((3, 5), order='F')
b = np.zeros(some_shape, order='F')
can be rewritten as::
a = np.empty((5, 3)).T
b = np.zeros(some_shape[::-1]).T
How can I increase integer width?
---------------------------------
By default, Numba will generally use machine integer width for integer
variables. On a 32-bit machine, you may sometimes need the magnitude of
64-bit integers instead. You can simply initialize relevant variables as
``np.int64`` (for example ``np.int64(0)`` instead of ``0``). It will
propagate to all computations involving those variables.
.. _parallel_faqs:
How can I tell if ``parallel=True`` worked?
-------------------------------------------
If the ``parallel=True`` transformations failed for a function
decorated as such, a warning will be displayed. See also
:ref:`numba-parallel-diagnostics` for information about parallel diagnostics.
Performance
===========
Does Numba inline functions?
----------------------------
Numba gives enough information to LLVM so that functions short enough
can be inlined. This only works in :term:`nopython mode`.
Does Numba vectorize array computations (SIMD)?
-----------------------------------------------
Numba doesn't implement such optimizations by itself, but it lets LLVM
apply them.
Why has my loop not vectorized?
-------------------------------
Numba enables the loop-vectorize optimization in LLVM by default.
While it is a powerful optimization, not all loops are applicable.
Sometimes, loop-vectorization may fail due to subtle details like memory access
pattern. To see additional diagnostic information from LLVM,
add the following lines:
.. code-block:: python
import llvmlite.binding as llvm
llvm.set_option('', '--debug-only=loop-vectorize')
This tells LLVM to print debug information from the **loop-vectorize**
pass to stderr. Each function entry looks like:
.. note::
Using ``--debug-only`` requires LLVM to be build with assertions enabled to
work. Use the build of llvmlite in the `Numba channel <https://anaconda.org/numba/llvmlite>`_
which is linked against LLVM with assertions enabled.
.. code-block:: text
LV: Checking a loop in "<low-level symbol name>" from <function name>
LV: Loop hints: force=? width=0 unroll=0
...
LV: Vectorization is possible but not beneficial.
LV: Interleaving is not beneficial.
Each function entry is separated by an empty line. The reason for rejecting
the vectorization is usually at the end of the entry. In the example above,
LLVM rejected the vectorization because doing so will not speedup the loop.
In this case, it can be due to memory access pattern. For instance, the
array being looped over may not be in contiguous layout.
When memory access pattern is non-trivial such that it cannot determine the
access memory region, LLVM may reject with the following message:
.. code-block:: text
LV: Can't vectorize due to memory conflicts
Another common reason is:
.. code-block:: text
LV: Not vectorizing: loop did not meet vectorization requirements.
In this case, vectorization is rejected because the vectorized code may behave
differently. This is a case to try turning on ``fastmath=True`` to allow
fastmath instructions.
Why are the ``typed`` containers slower when used from the interpreter?
-----------------------------------------------------------------------
The Numba ``typed`` containers found in ``numba.typed`` e.g.
``numba.typed.List`` store their data in an efficient form for access from JIT
compiled code. When these containers are used from the CPython interpreter, the
data involved has to be converted from/to the container format. This process is
relatively costly and as a result impacts performance. In JIT compiled code no
such penalty exists and so operations on the containers are much quicker and
often faster than the pure Python equivalent.
Does Numba automatically parallelize code?
------------------------------------------
It can, in some cases:
* Ufuncs and gufuncs with the ``target="parallel"`` option will run on multiple threads.
* The ``parallel=True`` option to ``@jit`` will attempt to optimize array
operations and run them in parallel. It also adds support for ``prange()`` to
explicitly parallelize a loop.
You can also manually run computations on multiple threads yourself and use
the ``nogil=True`` option (see :ref:`releasing the GIL <jit-nogil>`). Numba
can also target parallel execution on GPU architectures using its CUDA and HSA
backends.
Can Numba speed up short-running functions?
-------------------------------------------
Not significantly. New users sometimes expect to JIT-compile such
functions::
def f(x, y):
return x + y
and get a significant speedup over the Python interpreter. But there isn't
much Numba can improve here: most of the time is probably spent in CPython's
function call mechanism, rather than the function itself. As a rule of
thumb, if a function takes less than 10 µs to execute: leave it.
The exception is that you *should* JIT-compile that function if it is called
from another jitted function.
There is a delay when JIT-compiling a complicated function, how can I improve it?
---------------------------------------------------------------------------------
Try to pass ``cache=True`` to the ``@jit`` decorator. It will keep the
compiled version on disk for later use.
A more radical alternative is :ref:`ahead-of-time compilation <pycc>`.
GPU Programming
===============
How do I work around the ``CUDA initialized before forking`` error?
-------------------------------------------------------------------
On Linux, the ``multiprocessing`` module in the Python standard library
defaults to using the ``fork`` method for creating new processes. Because of
the way process forking duplicates state between the parent and child
processes, CUDA will not work correctly in the child process if the CUDA
runtime was initialized *prior* to the fork. Numba detects this and raises a
``CudaDriverError`` with the message ``CUDA initialized before forking``.
One approach to avoid this error is to make all calls to ``numba.cuda``
functions inside the child processes or after the process pool is created.
However, this is not always possible, as you might want to query the number of
available GPUs before starting the process pool. In Python 3, you can change
the process start method, as described in the `multiprocessing documentation
<https://docs.python.org/3.9/library/multiprocessing.html#contexts-and-start-methods>`_.
Switching from ``fork`` to ``spawn`` or ``forkserver`` will avoid the CUDA
initialization issue, although the child processes will not inherit any global
variables from their parent.
Integration with other utilities
================================
Can I "freeze" an application which uses Numba?
-----------------------------------------------
If you're using PyInstaller or a similar utility to freeze an application,
you may encounter issues with llvmlite. llvmlite needs a non-Python DLL
for its working, but it won't be automatically detected by freezing utilities.
You have to inform the freezing utility of the DLL's location: it will
usually be named ``llvmlite/binding/libllvmlite.so`` or
``llvmlite/binding/llvmlite.dll``, depending on your system.
I get errors when running a script twice under Spyder
-----------------------------------------------------
When you run a script in a console under Spyder, Spyder first tries to
reload existing modules. This doesn't work well with Numba, and can
produce errors like ``TypeError: No matching definition for argument type(s)``.
There is a fix in the Spyder preferences. Open the "Preferences" window,
select "Console", then "Advanced Settings", click the "Set UMR excluded
modules" button, and add ``numba`` inside the text box that pops up.
To see the setting take effect, be sure to restart the IPython console or
kernel.
.. _llvm-locale-bug:
Why does Numba complain about the current locale?
-------------------------------------------------
If you get an error message such as the following::
RuntimeError: Failed at nopython (nopython mode backend)
LLVM will produce incorrect floating-point code in the current locale
it means you have hit a LLVM bug which causes incorrect handling of
floating-point constants. This is known to happen with certain third-party
libraries such as the Qt backend to matplotlib.
To work around the bug, you need to force back the locale to its default
value, for example::
import locale
locale.setlocale(locale.LC_NUMERIC, 'C')
How do I get Numba development builds?
--------------------------------------
Pre-release versions of Numba can be installed with conda::
$ conda install -c numba/label/dev numba
Miscellaneous
=============
Where does the project name "Numba" come from?
----------------------------------------------
"Numba" is a combination of "NumPy" and "Mamba". Mambas are some of the fastest
snakes in the world, and Numba makes your Python code fast.
How do I reference/cite/acknowledge Numba in other work?
--------------------------------------------------------
For academic use, the best option is to cite our ACM Proceedings: `Numba: a
LLVM-based Python JIT compiler.
<http://dl.acm.org/citation.cfm?id=2833162&dl=ACM&coll=DL>`_ You can also find
`the sources on github <https://github.com/numba/Numba-SC15-Paper>`_, including
`a pre-print pdf
<https://github.com/numba/Numba-SC15-Paper/raw/master/numba_sc15.pdf>`_, in case
you don't have access to the ACM site but would like to read the paper.
Other related papers
~~~~~~~~~~~~~~~~~~~~
A paper describing ParallelAccelerator technology, that is activated when the
``parallel=True`` jit option is used, can be found `here
<http://drops.dagstuhl.de/opus/volltexte/2017/7269/pdf/LIPIcs-ECOOP-2017-4.pdf>`_.
How do I write a minimal working reproducer for a problem with Numba?
---------------------------------------------------------------------
A minimal working reproducer for Numba should include:
1. The source code of the function(s) that reproduce the problem.
2. Some example data and a demonstration of calling the reproducing code with
that data. As Numba compiles based on type information, unless your problem
is numerical, it's fine to just provide dummy data of the right type, e.g.
use ``numpy.ones`` of the correct ``dtype``/size/shape for arrays.
3. Ideally put 1. and 2. into a script with all the correct imports. Make sure
your script actually executes and reproduces the problem before submitting
it! The target is to make it so that the script can just be copied directly
from the `issue tracker <https://github.com/numba/numba/issues>`_ and run by
someone else such that they can see the same problem as you are having.
Having made a reproducer, now remove every part of the code that does not
contribute directly to reproducing the problem to create a "minimal" reproducer.
This means removing imports that aren't used, removing variables that aren't
used or have no effect, removing lines of code which have no effect, reducing
the complexity of expressions, and shrinking input data to the minimal amount
required to trigger the problem.
Doing the above really helps out the Numba issue triage process and will enable
a faster response to your problem!
`Suggested further reading
<http://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports>`_ on
writing minimal working reproducers.
.. _generated-jit:
================================================
Flexible specializations with ``@generated_jit``
================================================
While the :func:`~numba.jit` decorator is useful for many situations,
sometimes you want to write a function that has different implementations
depending on its input types. The :func:`~numba.generated_jit` decorator
allows the user to control the selection of a specialization at compile-time,
while fully retaining runtime execution speed of a JIT function.
Example
=======
Suppose you want to write a function which returns whether a given value
is a "missing" value according to certain conventions. For the sake of
the example, let's adopt the following definition:
- for floating-point arguments, a missing value is a ``NaN``
- for Numpy datetime64 and timedelta64 arguments, a missing value is a ``NaT``
- other types don't have the concept of a missing value.
That compile-time logic is easily implemented using the
:func:`~numba.generated_jit` decorator::
import numpy as np
from numba import generated_jit, types
@generated_jit(nopython=True)
def is_missing(x):
"""
Return True if the value is missing, False otherwise.
"""
if isinstance(x, types.Float):
return lambda x: np.isnan(x)
elif isinstance(x, (types.NPDatetime, types.NPTimedelta)):
# The corresponding Not-a-Time value
missing = x('NaT')
return lambda x: x == missing
else:
return lambda x: False
There are several things to note here:
* The decorated function is called with the :ref:`Numba types <numba-types>`
of the arguments, not their values.
* The decorated function doesn't actually compute a result, it returns
a callable implementing the actual definition of the function for the
given types.
* It is possible to pre-compute some data at compile-time (the ``missing``
variable above) to have them reused inside the compiled implementation.
* The function definitions use the same names for arguments as in the
decorated function, this is required to ensure passing arguments by
name works as expected.
Compilation options
===================
The :func:`~numba.generated_jit` decorator supports the same keyword-only
arguments as the :func:`~numba.jit` decorator, for example the ``nopython``
and ``cache`` options.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment