---
name: torch_device_select
kind: function
lang: py
domain: ml
version: "1.0.0"
purity: impure
signature: "def torch_device_select(preference: str = 'auto') -> str"
description: "Selecciona el torch device optimo segun preferencia y disponibilidad real del hardware. 'auto' elige CUDA > MPS > CPU. Para preferencias explicitas valida disponibilidad y hace fallback a CPU con warnings.warn."
tags: [torch, pytorch, cuda, mps, device, hardware, probe, ml, apple-silicon]
uses_functions: [cuda_available_py_ml]
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: []
params:
  - name: preference
    desc: "'auto' detecta el mejor device disponible (CUDA > MPS > CPU). 'cuda' fuerza cuda:0. 'cuda:N' fuerza GPU N. 'mps' fuerza Apple Silicon. 'cpu' siempre retorna cpu."
output: "string de device listo para torch: 'cuda:0', 'cuda:N', 'mps' o 'cpu'. Nunca lanza excepcion — fallback a 'cpu' con warning si el device solicitado no esta disponible."
tested: true
tests:
  - "preference=cpu siempre retorna cpu"
  - "preference=auto sin cuda ni mps retorna cpu"
  - "preference=cuda sin cuda disponible retorna cpu con warning"
  - "preference=cuda:5 con solo 1 GPU retorna cpu con warning"
  - "preference desconocida retorna cpu con warning"
test_file_path: "python/functions/ml/tests/test_torch_device_select.py"
file_path: "python/functions/ml/torch_device_select.py"
---

## Ejemplo

```python
from ml.torch_device_select import torch_device_select

# Deteccion automatica (recomendado)
device = torch_device_select()         # "cuda:0" o "mps" o "cpu"

# Forzar CPU para reproducibilidad
device = torch_device_select("cpu")    # siempre "cpu"

# Preferencia explicita con fallback automatico
device = torch_device_select("cuda")   # "cuda:0" o "cpu" + warning

# Uso tipico al cargar un modelo
import torch
device_str = torch_device_select("auto")
model = MyModel().to(torch.device(device_str))
```

## Comparacion con gliner_load_model

`gliner_load_model` usa internamente `_resolve_device` con la misma logica
CUDA/CPU. `torch_device_select` extiende ese patron con:
- Soporte MPS (Apple Silicon M1/M2/M3).
- Seleccion de GPU especifica (`cuda:N`).
- Fallback con `warnings.warn` en vez de silencio.

## Notas

- No levanta excepcion si torch no esta instalado: todos los helpers internos
  capturan ImportError y tratan el device como no disponible.
- `warnings.warn` en vez de logging para no imponer dependencia de logging al caller.
- MPS requiere torch >= 1.12 y macOS 12.3+. En sistemas Linux/Windows
  `torch.backends.mps` puede no existir — el helper lo maneja con `hasattr`.
- impure: depende del estado del hardware y de las librerias instaladas.
