# `Nx.Backend`
[🔗](https://github.com/elixir-nx/nx/blob/v0.12.0/nx/lib/nx/backend.ex#L1)

The behaviour for tensor backends.

Each backend is module that defines a struct and implements the callbacks
defined in this module. The callbacks are mostly implementations of the
functions in the `Nx` module with the tensor output shape given as first
argument.

`Nx` backends come in two flavors: opaque backends, of which you should
not access its data directly except through the functions in the `Nx`
module, and public ones, of which its data can be directly accessed and
traversed. The former typically have the `Backend` suffix.

`Nx` ships with the following backends:

  * `Nx.BinaryBackend` - an opaque backend written in pure Elixir
    that stores the data in Elixir's binaries. This is the default
    backend used by the `Nx` module. The backend itself (and its
    data) is private and must not be accessed directly.

  * `Nx.TemplateBackend` - an opaque backend written that works as
    a template in APIs to declare the type, shape, and names of
    tensors to be expected in the future.

  * `Nx.Defn.Expr` - a public backend used by `defn` to build
    expression trees that are traversed by custom compilers.

This module also includes functions that are meant to be shared
across backends.

# `axes`

```elixir
@type axes() :: Nx.Tensor.axes()
```

# `axis`

```elixir
@type axis() :: Nx.Tensor.axis()
```

# `backend_options`

```elixir
@type backend_options() :: term()
```

# `shape`

```elixir
@type shape() :: Nx.Tensor.shape()
```

# `t`

```elixir
@type t() :: %{__struct__: atom()}
```

# `tensor`

```elixir
@type tensor() :: Nx.Tensor.t()
```

# `abs`

```elixir
@callback abs(out :: tensor(), tensor()) :: tensor()
```

# `acos`

```elixir
@callback acos(out :: tensor(), tensor()) :: tensor()
```

# `acosh`

```elixir
@callback acosh(out :: tensor(), tensor()) :: tensor()
```

# `add`

```elixir
@callback add(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `all`

```elixir
@callback all(out :: tensor(), tensor(), keyword()) :: tensor()
```

# `any`

```elixir
@callback any(out :: tensor(), tensor(), keyword()) :: tensor()
```

# `argmax`

```elixir
@callback argmax(out :: tensor(), tensor(), keyword()) :: tensor()
```

# `argmin`

```elixir
@callback argmin(out :: tensor(), tensor(), keyword()) :: tensor()
```

# `argsort`

```elixir
@callback argsort(out :: tensor(), tensor(), keyword()) :: tensor()
```

# `as_type`

```elixir
@callback as_type(out :: tensor(), tensor()) :: tensor()
```

# `asin`

```elixir
@callback asin(out :: tensor(), tensor()) :: tensor()
```

# `asinh`

```elixir
@callback asinh(out :: tensor(), tensor()) :: tensor()
```

# `atan2`

```elixir
@callback atan2(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `atan`

```elixir
@callback atan(out :: tensor(), tensor()) :: tensor()
```

# `atanh`

```elixir
@callback atanh(out :: tensor(), tensor()) :: tensor()
```

# `backend_copy`

```elixir
@callback backend_copy(tensor(), module(), backend_options()) :: tensor()
```

# `backend_deallocate`

```elixir
@callback backend_deallocate(tensor()) :: :ok | :already_deallocated
```

# `backend_transfer`

```elixir
@callback backend_transfer(tensor(), module(), backend_options()) :: tensor()
```

# `bitcast`

```elixir
@callback bitcast(out :: tensor(), tensor()) :: tensor()
```

# `bitwise_and`

```elixir
@callback bitwise_and(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `bitwise_not`

```elixir
@callback bitwise_not(out :: tensor(), tensor()) :: tensor()
```

# `bitwise_or`

```elixir
@callback bitwise_or(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `bitwise_xor`

```elixir
@callback bitwise_xor(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `block`

```elixir
@callback block(struct(), output :: tensor() | tuple(), args :: [term()], fun()) ::
  tensor() | tuple()
```

Invoked for execution of `Nx.block/4`.

`output` is the result template (`Nx.Tensor` or tuple of tensors). `args` are
the tensor (and optional trailing keyword lists) passed to `Nx.block/4`.
Backends should dispatch on `struct` (see `Nx.Block.*`) and either run a
native implementation or invoke `fun` as `apply(fun, [struct | args])`.

# `broadcast`

```elixir
@callback broadcast(out :: tensor(), tensor(), shape(), axes()) :: tensor()
```

# `cbrt`

```elixir
@callback cbrt(out :: tensor(), tensor()) :: tensor()
```

# `ceil`

```elixir
@callback ceil(out :: tensor(), tensor()) :: tensor()
```

# `clip`

```elixir
@callback clip(out :: tensor(), tensor(), min :: tensor(), max :: tensor()) :: tensor()
```

# `concatenate`

```elixir
@callback concatenate(out :: tensor(), tensor(), axis()) :: tensor()
```

# `conjugate`

```elixir
@callback conjugate(out :: tensor(), tensor()) :: tensor()
```

# `constant`

```elixir
@callback constant(out :: tensor(), number() | Complex.t(), backend_options()) :: tensor()
```

# `conv`

```elixir
@callback conv(out :: tensor(), tensor(), kernel :: tensor(), keyword()) :: tensor()
```

# `cos`

```elixir
@callback cos(out :: tensor(), tensor()) :: tensor()
```

# `cosh`

```elixir
@callback cosh(out :: tensor(), tensor()) :: tensor()
```

# `count_leading_zeros`

```elixir
@callback count_leading_zeros(out :: tensor(), tensor()) :: tensor()
```

# `divide`

```elixir
@callback divide(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `dot`

```elixir
@callback dot(out :: tensor(), tensor(), axes(), axes(), tensor(), axes(), axes()) ::
  tensor()
```

# `equal`

```elixir
@callback equal(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `erf`

```elixir
@callback erf(out :: tensor(), tensor()) :: tensor()
```

# `erf_inv`

```elixir
@callback erf_inv(out :: tensor(), tensor()) :: tensor()
```

# `erfc`

```elixir
@callback erfc(out :: tensor(), tensor()) :: tensor()
```

# `exp`

```elixir
@callback exp(out :: tensor(), tensor()) :: tensor()
```

# `expm1`

```elixir
@callback expm1(out :: tensor(), tensor()) :: tensor()
```

# `eye`

```elixir
@callback eye(tensor(), backend_options()) :: tensor()
```

# `fft`

```elixir
@callback fft(out :: tensor(), tensor(), keyword()) :: tensor()
```

# `floor`

```elixir
@callback floor(out :: tensor(), tensor()) :: tensor()
```

# `from_binary`

```elixir
@callback from_binary(out :: tensor(), binary(), backend_options()) :: tensor()
```

# `from_pointer`

```elixir
@callback from_pointer(
  opaque_pointer :: term(),
  type :: tuple(),
  shape :: tuple(),
  backend_opts :: keyword(),
  opts :: keyword()
) :: tensor() | no_return()
```

# `gather`

```elixir
@callback gather(out :: tensor(), input :: tensor(), indices :: tensor(), keyword()) ::
  tensor()
```

# `greater`

```elixir
@callback greater(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `greater_equal`

```elixir
@callback greater_equal(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `ifft`

```elixir
@callback ifft(out :: tensor(), tensor(), keyword()) :: tensor()
```

# `imag`

```elixir
@callback imag(out :: tensor(), tensor()) :: tensor()
```

# `indexed_add`

```elixir
@callback indexed_add(
  out :: tensor(),
  tensor(),
  indices :: tensor(),
  updates :: tensor(),
  keyword()
) ::
  tensor()
```

# `indexed_put`

```elixir
@callback indexed_put(
  out :: tensor(),
  tensor(),
  indices :: tensor(),
  updates :: tensor(),
  keyword()
) ::
  tensor()
```

# `init`

```elixir
@callback init(keyword()) :: backend_options()
```

# `inspect`

```elixir
@callback inspect(tensor(), Inspect.Opts.t()) :: tensor()
```

# `iota`

```elixir
@callback iota(tensor(), axis() | nil, backend_options()) :: tensor()
```

# `is_infinity`

```elixir
@callback is_infinity(out :: tensor(), tensor()) :: tensor()
```

# `is_nan`

```elixir
@callback is_nan(out :: tensor(), tensor()) :: tensor()
```

# `left_shift`

```elixir
@callback left_shift(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `less`

```elixir
@callback less(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `less_equal`

```elixir
@callback less_equal(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `log1p`

```elixir
@callback log1p(out :: tensor(), tensor()) :: tensor()
```

# `log`

```elixir
@callback log(out :: tensor(), tensor()) :: tensor()
```

# `logical_and`

```elixir
@callback logical_and(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `logical_or`

```elixir
@callback logical_or(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `logical_xor`

```elixir
@callback logical_xor(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `max`

```elixir
@callback max(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `min`

```elixir
@callback min(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `multiply`

```elixir
@callback multiply(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `negate`

```elixir
@callback negate(out :: tensor(), tensor()) :: tensor()
```

# `not_equal`

```elixir
@callback not_equal(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `pad`

```elixir
@callback pad(out :: tensor(), tensor(), pad_value :: tensor(), padding_config :: list()) ::
  tensor()
```

# `population_count`

```elixir
@callback population_count(out :: tensor(), tensor()) :: tensor()
```

# `pow`

```elixir
@callback pow(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `product`

```elixir
@callback product(out :: tensor(), tensor(), keyword()) :: tensor()
```

# `put_slice`

```elixir
@callback put_slice(out :: tensor(), tensor(), tensor(), list()) :: tensor()
```

# `quotient`

```elixir
@callback quotient(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `real`

```elixir
@callback real(out :: tensor(), tensor()) :: tensor()
```

# `reduce`

```elixir
@callback reduce(out :: tensor(), tensor(), acc :: tensor(), keyword(), fun()) :: tensor()
```

# `reduce_max`

```elixir
@callback reduce_max(out :: tensor(), tensor(), keyword()) :: tensor()
```

# `reduce_min`

```elixir
@callback reduce_min(out :: tensor(), tensor(), keyword()) :: tensor()
```

# `remainder`

```elixir
@callback remainder(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `reshape`

```elixir
@callback reshape(out :: tensor(), tensor()) :: tensor()
```

# `reverse`

```elixir
@callback reverse(out :: tensor(), tensor(), axes()) :: tensor()
```

# `right_shift`

```elixir
@callback right_shift(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `round`

```elixir
@callback round(out :: tensor(), tensor()) :: tensor()
```

# `rsqrt`

```elixir
@callback rsqrt(out :: tensor(), tensor()) :: tensor()
```

# `select`

```elixir
@callback select(out :: tensor(), tensor(), tensor(), tensor()) :: tensor()
```

# `sigmoid`

```elixir
@callback sigmoid(out :: tensor(), tensor()) :: tensor()
```

# `sign`

```elixir
@callback sign(out :: tensor(), tensor()) :: tensor()
```

# `sin`

```elixir
@callback sin(out :: tensor(), tensor()) :: tensor()
```

# `sinh`

```elixir
@callback sinh(out :: tensor(), tensor()) :: tensor()
```

# `slice`

```elixir
@callback slice(out :: tensor(), tensor(), list(), list(), list()) :: tensor()
```

# `sort`

```elixir
@callback sort(out :: tensor(), tensor(), keyword()) :: tensor()
```

# `sqrt`

```elixir
@callback sqrt(out :: tensor(), tensor()) :: tensor()
```

# `squeeze`

```elixir
@callback squeeze(out :: tensor(), tensor(), axes()) :: tensor()
```

# `stack`

```elixir
@callback stack(out :: tensor(), tensor(), axis()) :: tensor()
```

# `subtract`

```elixir
@callback subtract(out :: tensor(), tensor(), tensor()) :: tensor()
```

# `sum`

```elixir
@callback sum(out :: tensor(), tensor(), keyword()) :: tensor()
```

# `tan`

```elixir
@callback tan(out :: tensor(), tensor()) :: tensor()
```

# `tanh`

```elixir
@callback tanh(out :: tensor(), tensor()) :: tensor()
```

# `to_batched`

```elixir
@callback to_batched(out :: tensor(), tensor(), keyword()) :: [tensor()]
```

# `to_binary`

```elixir
@callback to_binary(tensor(), limit :: non_neg_integer()) :: binary()
```

# `to_pointer`

```elixir
@callback to_pointer(tensor(), opts :: keyword()) :: term() | no_return()
```

# `transpose`

```elixir
@callback transpose(out :: tensor(), tensor(), axes()) :: tensor()
```

# `triangular_solve`

```elixir
@callback triangular_solve(out :: tensor(), a :: tensor(), b :: tensor(), keyword()) ::
  tensor()
```

# `window_max`

```elixir
@callback window_max(out :: tensor(), tensor(), shape(), keyword()) :: tensor()
```

# `window_min`

```elixir
@callback window_min(out :: tensor(), tensor(), shape(), keyword()) :: tensor()
```

# `window_product`

```elixir
@callback window_product(out :: tensor(), tensor(), shape(), keyword()) :: tensor()
```

# `window_reduce`

```elixir
@callback window_reduce(
  out :: tensor(),
  tensor(),
  acc :: tensor(),
  shape(),
  keyword(),
  fun()
) :: tensor()
```

# `window_scatter_max`

```elixir
@callback window_scatter_max(
  out :: tensor(),
  tensor(),
  tensor(),
  tensor(),
  shape(),
  keyword()
) :: tensor()
```

# `window_scatter_min`

```elixir
@callback window_scatter_min(
  out :: tensor(),
  tensor(),
  tensor(),
  tensor(),
  shape(),
  keyword()
) :: tensor()
```

# `window_sum`

```elixir
@callback window_sum(out :: tensor(), tensor(), shape(), keyword()) :: tensor()
```

# `inspect`

Inspects the given tensor given by `binary`.

Note the `binary` may have fewer elements than the
tensor size but, in such cases, it must strictly have
more elements than `inspect_opts.limit`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
