# `Nx.Backend`
[🔗](https://github.com/elixir-nx/nx/blob/v0.11.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()
```

# `all_close`
*optional* 

```elixir
@callback all_close(out :: tensor(), 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()
```

# `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()
```

# `cholesky`
*optional* 

```elixir
@callback cholesky(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()
```

# `cumulative_max`
*optional* 

```elixir
@callback cumulative_max(out :: tensor(), t :: tensor(), keyword()) :: tensor()
```

# `cumulative_min`
*optional* 

```elixir
@callback cumulative_min(out :: tensor(), t :: tensor(), keyword()) :: tensor()
```

# `cumulative_product`
*optional* 

```elixir
@callback cumulative_product(out :: tensor(), t :: tensor(), keyword()) :: tensor()
```

# `cumulative_sum`
*optional* 

```elixir
@callback cumulative_sum(out :: tensor(), t :: tensor(), keyword()) :: tensor()
```

# `determinant`
*optional* 

```elixir
@callback determinant(out :: tensor(), t :: tensor()) :: tensor()
```

# `divide`

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

# `dot`

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

# `eigh`
*optional* 

```elixir
@callback eigh({eigenvals :: tensor(), eigenvecs :: tensor()}, tensor(), keyword()) ::
  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()
```

# `fft2`
*optional* 

```elixir
@callback fft2(out :: tensor(), tensor(), keyword()) :: 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()
```

# `ifft2`
*optional* 

```elixir
@callback ifft2(out :: tensor(), tensor(), keyword()) :: 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_not`
*optional* 

```elixir
@callback logical_not(out :: tensor(), t :: tensor()) :: tensor()
```

# `logical_or`

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

# `logical_xor`

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

# `lu`
*optional* 

```elixir
@callback lu({p :: tensor(), l :: tensor(), u :: tensor()}, tensor(), keyword()) ::
  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()
```

# `optional`
*optional* 

```elixir
@callback optional(atom(), [term()], fun()) :: tensor()
```

Invoked for execution of optional callbacks with a default implementation.

First we will attempt to call the optional callback itself
(one of the many callbacks defined below), then we attempt
to call this callback (which is also optional), then we
fallback to the default implementation.

# `pad`

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

# `phase`
*optional* 

```elixir
@callback phase(out :: tensor(), t :: tensor()) :: 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()
```

# `qr`
*optional* 

```elixir
@callback qr({q :: tensor(), r :: tensor()}, tensor(), keyword()) :: 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()
```

# `solve`
*optional* 

```elixir
@callback solve(out :: tensor(), a :: tensor(), b :: tensor()) :: 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()
```

# `svd`
*optional* 

```elixir
@callback svd({u :: tensor(), s :: tensor(), v :: tensor()}, tensor(), keyword()) ::
  tensor()
```

# `take`
*optional* 

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

# `take_along_axis`
*optional* 

```elixir
@callback take_along_axis(
  out :: tensor(),
  input :: tensor(),
  indices :: 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()
```

# `top_k`
*optional* 

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

# `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*
