# Notes on Target Extensions

Warning

All features and APIs described in this page are in-development and may change at any time without deprecation notices being issued.

## Inheriting compiler flags from the caller

Compiler flags, i.e. options such as `fastmath`, `nrt` in `@jit(nrt=True, fastmath=True))` are specified per-function but their effects are not well-defined—some flags affect the entire callgraph, some flags affect only the current function. Sometimes it is necessary for callees to inherit flags from the caller; for example the `fastmath` flag should be infectious.

To address the problem, the following are needed:

1. Better definitions for the semantics of compiler flags. Preferably, all flags should limit their effect to the current function. (TODO)

2. Allow compiler flags to be inherited from the caller. (Done)

3. Consider compiler flags in function resolution. (TODO)

`numba.core.targetconfig.ConfigStack` is used to propagate the compiler flags throughout the compiler. At the start of the compilation, the flags are pushed into the `ConfigStack`, which maintains a thread-local stack for the compilation. Thus, callees can check the flags in the caller.

class numba.core.targetconfig.ConfigStack

  A stack for tracking target configurations in the compiler.

  It stores the stack in a thread-local class attribute. All instances in the same thread will see the same stack.

  enter(flags)

    Returns a contextmanager that performs `push(flags)` on enter and `pop()` on exit.

  classmethod top_or_none()

    Get the TOS or return None if no config is set.

### Compiler flags

Compiler flags are defined as a subclass of `TargetConfig`:

class numba.core.targetconfig.TargetConfig(copy_from=None)

  Base class for `TargetConfig`.

  Subclass should fill class members with `Option`. For example:

      >>> class MyTargetConfig(TargetConfig):
      >>>     a_bool_option = Option(type=bool, default=False, doc="a bool")
      >>>     an_int_option = Option(type=int, default=0, doc="an int")

  The metaclass will insert properties for each `Option`. For example:

      >>> tc = MyTargetConfig()
      >>> tc.a_bool_option = True  # invokes the setter
      >>> print(tc.an_int_option)  # print the default

  copy()

    Clone this instance.

  classmethod demangle(mangled: str) → str

    Returns the demangled result from `.get_mangle_string()`

  discard(name)

    Remove the option by name if it is defined.

    After this, the value for the option will be set to its default value.

  get_mangle_string() → str

    Return a string suitable for symbol mangling.

  inherit_if_not_set(name, default=<NotSet>)

    Inherit flag from `ConfigStack`.

    Parameters:
      name str

        Option name.

      default optional

        When given, it overrides the default value. It is only used when the flag is not defined locally and there is no entry in the `ConfigStack`.

  is_set(name)

    Is the option set?

  summary() → str

    Returns a `str` that summarizes this instance.

    In contrast to `__repr__`, only options that are explicitly set will be shown.

  values()

    Returns a dict of all the values

These are internal compiler flags and they are different from the user-facing options used in the jit decorators.

Internally, the user-facing options are mapped to the internal compiler flags by `numba.core.options.TargetOptions`. Each target can override the default compiler flags and control the flag inheritance in `TargetOptions.finalize`. The CPU target overrides it.

class numba.core.options.TargetOptions

  Target options maps user options from decorators to the `numba.core.compiler.Flags` used by lowering and target context.

  finalize(flags, options)

    Subclasses can override this method to make target specific customizations of default flags.

    Parameters:
      flags Flags
      options dict

In `numba.core.options.TargetOptions.finalize()`, use `numba.core.targetconfig.TargetConfig.inherit_if_not_set()` to request a compiler flag from the caller if it is not set for the current function.