# `Snakepit.Hardware.Selector`
[🔗](https://github.com/nshkrdotcom/snakepit/blob/v0.13.0/lib/snakepit/hardware/selector.ex#L1)

Device selection logic for hardware abstraction.

Provides intelligent device selection based on availability, preferences,
and fallback strategies.

# `device`

```elixir
@type device() ::
  :cpu
  | :cuda
  | :mps
  | :rocm
  | {:cuda, non_neg_integer()}
  | {:rocm, non_neg_integer()}
```

# `device_preference`

```elixir
@type device_preference() ::
  :auto | :cpu | :cuda | :mps | :rocm | {:cuda, non_neg_integer()}
```

# `device_info`

```elixir
@spec device_info(device()) :: map()
```

Returns information about a selected device.

Returns a map with device details useful for logging and telemetry.

# `select`

```elixir
@spec select(device_preference()) :: {:ok, device()} | {:error, :device_not_available}
```

Selects a device based on preference.

## Options

- `:auto` - Automatically select the best available accelerator
- `:cpu` - Select CPU (always available)
- `:cuda` - Select CUDA (fails if not available)
- `:mps` - Select MPS (fails if not available or not on macOS)
- `:rocm` - Select ROCm (fails if not available)
- `{:cuda, device_id}` - Select specific CUDA device

## Returns

- `{:ok, device}` on success
- `{:error, :device_not_available}` if requested device is unavailable

# `select_with_fallback`

```elixir
@spec select_with_fallback([device_preference()]) ::
  {:ok, device()} | {:error, :no_device}
```

Selects the first available device from a preference list.

Tries each device in order until one is available, returning that device.
If no devices are available, returns `{:error, :no_device}`.

## Examples

    iex> Hardware.Selector.select_with_fallback([:cuda, :mps, :cpu])
    {:ok, :cpu}  # if CUDA and MPS unavailable

---

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