# `Tinkex.Types.TensorDtype`
[🔗](https://github.com/North-Shore-AI/tinkex/blob/v0.4.0/lib/tinkex/types/tensor_dtype.ex#L1)

Tensor data type.

Mirrors Python `tinker.types.TensorDtype`.
Wire format: `"int64"` | `"float32"`

## Backend Limitations

IMPORTANT: The Tinker backend only supports 2 dtypes:
- `int64` - 64-bit signed integers
- `float32` - 32-bit floating point

Other types (float64, int32, unsigned) are NOT directly supported.

## Automatic Type Conversion

When using `from_nx_type/1`, Nx tensor types are automatically converted
to the supported backend types. This may cause precision loss or overflow:

| Nx Type | Backend Type | Notes |
|---------|--------------|-------|
| `{:f, 32}` | float32 | Direct mapping |
| `{:f, 64}` | float32 | **WARNING: Precision loss** - float64 downcast to float32 |
| `{:s, 64}` | int64 | Direct mapping |
| `{:s, 32}` | int64 | Safe upcast |
| `{:u, N}` | int64 | Safe upcast for N <= 63, may overflow for large u64 values |

## Python SDK Parity

This behavior matches the Python SDK, which also only supports int64 and float32.

# `t`

```elixir
@type t() :: :int64 | :float32
```

# `check_precision_loss`

```elixir
@spec check_precision_loss(tuple()) :: :ok | {:downcast, String.t()}
```

Check if an Nx type requires conversion that may lose precision.

Returns `{:downcast, reason}` if precision loss may occur,
otherwise `:ok`.

## Examples

    iex> TensorDtype.check_precision_loss({:f, 32})
    :ok

    iex> TensorDtype.check_precision_loss({:f, 64})
    {:downcast, "float64 to float32 - precision loss may occur"}

# `from_nx_type`

```elixir
@spec from_nx_type(tuple()) :: t()
```

Convert Nx tensor type to TensorDtype.

Performs automatic type conversion to match backend-supported types.
Emits warnings when precision loss may occur (e.g., float64 -> float32).

## Supported Conversions

- `{:f, 32}` -> `:float32` (direct)
- `{:f, 64}` -> `:float32` (downcast, **WARNING** emitted)
- `{:s, 64}` -> `:int64` (direct)
- `{:s, 32}` -> `:int64` (upcast)
- `{:u, _}` -> `:int64` (upcast)

## Examples

    iex> TensorDtype.from_nx_type({:f, 32})
    :float32

    # Downcast with warning
    iex> TensorDtype.from_nx_type({:f, 64})
    :float32
    # WARNING: Downcasting float64 to float32 - precision loss may occur

# `from_nx_type_quiet`

```elixir
@spec from_nx_type_quiet(tuple()) :: t()
```

Convert Nx tensor type to TensorDtype without emitting warnings.

Use this when you want to check the conversion without side effects.

# `parse`

```elixir
@spec parse(String.t() | nil) :: t() | nil
```

Parse wire format string to atom.

# `to_nx_type`

```elixir
@spec to_nx_type(t()) :: tuple()
```

Convert TensorDtype to Nx tensor type.

# `to_string`

```elixir
@spec to_string(t()) :: String.t()
```

Convert atom to wire format string.

---

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