> ## Documentation Index
> Fetch the complete documentation index at: https://dynex.mintlify.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Compute Backends

> Run on Dynex neuromorphic GPU chips or test locally

# Compute Backends

`DynexConfig` selects which hardware handles your computation. The primary backend for all production workloads is **GPU** — Dynex's own neuromorphic computing chips operated across a distributed GPU network worldwide.

## Overview

| Backend | Hardware                         | Use case                                   |
| ------- | -------------------------------- | ------------------------------------------ |
| `GPU`   | **Dynex neuromorphic GPU chips** | **Production — the primary Dynex backend** |
| `QPU`   | Specific QPU hardware models     | Targeted QPU hardware runs                 |
| `CPU`   | CPU workers on the network       | Lightweight testing on the network         |
| `LOCAL` | Local binary (offline)           | Unit tests, CI/CD, offline development     |

## GPU — Dynex Neuromorphic Chips

<Note>
  **This is the primary compute backend.** Dynex operates thousands of neuromorphic GPU chips distributed globally. When you submit a job with `ComputeBackend.GPU`, it runs directly on this hardware.
</Note>

The GPU network is Dynex's core infrastructure — the Digital Twin of a neuromorphic quantum computing machine, running on GPUs at scale. This backend delivers:

* **Neuromorphic parallelism** — thousands of chips work on your problem simultaneously
* **No qubit limits** — problems of arbitrary size are supported
* **Always available** — distributed, no single point of failure
* **Linear scaling** — tested up to 64 × 10⁶ variables with linear resource growth

```python theme={null}
from dynex import DynexConfig, ComputeBackend

config = DynexConfig(compute_backend=ComputeBackend.GPU)
```

That's it. Credentials are loaded from `DYNEX_SDK_KEY` and `DYNEX_GRPC_ENDPOINT` environment variables, or from a `.env` file.

### Full production example

```python theme={null}
import dynex
import dimod
from dynex import DynexConfig, ComputeBackend

config = DynexConfig(
    compute_backend=ComputeBackend.GPU,
    default_description="Portfolio optimization — production run",
    default_timeout=600.0,
)

bqm = dimod.BinaryQuadraticModel.from_qubo(Q)
model = dynex.BQM(bqm)
sampler = dynex.DynexSampler(model, config=config)
sampleset = sampler.sample(
    num_reads=10000,
    annealing_time=1000,
    shots=5,
)
print(f"Best energy: {sampleset.first.energy:.4f}")
```

***

## QPU — Quantum Processing Unit

For specialized QPU hardware models built on top of the Dynex GPU infrastructure. Requires specifying a QPU model.

```python theme={null}
from dynex import DynexConfig, ComputeBackend, QPUModel

config = DynexConfig(
    compute_backend=ComputeBackend.QPU,
    qpu_model=QPUModel.APOLLO_RC1
)
```

### Available QPU models

| Model          | Constant                | Description                |
| -------------- | ----------------------- | -------------------------- |
| `apollo_rc1`   | `QPUModel.APOLLO_RC1`   | Apollo RC1                 |
| `apollo_10000` | `QPUModel.APOLLO_10000` | Apollo 10000 — large-scale |

<Warning>
  `qpu_model` is required when `compute_backend=QPU`. Omitting it raises `ValueError`.
</Warning>

<Note>
  QPU hardware has tighter constraints than GPU. Use `num_reads` in the range 1–100, `annealing_time` in 10–1000, and `shots` up to 5.
</Note>

### Coefficient bounds: `qpu_max_coeff`

The Apollo QPU hardware requires BQM coefficients (linear and quadratic) to stay within a bounded range. The sampler automatically checks and scales your model if needed:

```python theme={null}
sampleset = sampler.sample(
    num_reads=50,
    annealing_time=200,
    qpu_max_coeff=9.0,  # Default. Coefficients above this are auto-scaled.
)
```

If any coefficient exceeds `qpu_max_coeff`, the entire BQM is scaled down proportionally so the maximum absolute coefficient equals the threshold. The scaling is transparent — solutions are returned in the original variable space.

| Scenario                           | Behaviour                                        |
| ---------------------------------- | ------------------------------------------------ |
| All coefficients ≤ `qpu_max_coeff` | No scaling, BQM used as-is                       |
| Any coefficient > `qpu_max_coeff`  | BQM auto-scaled, scaling factor logged           |
| Circuit BQM (QASM)                 | Scaling handled by Apollo API, parameter ignored |

<Tip>
  If your QUBO has large coefficients (e.g. penalty terms in CQM conversion), lower `qpu_max_coeff` to bring them into hardware range without manually rescaling the model.
</Tip>

### QPU sampling example

```python theme={null}
from dynex import DynexConfig, ComputeBackend, QPUModel
import dynex, dimod

config = DynexConfig(
    compute_backend=ComputeBackend.QPU,
    qpu_model=QPUModel.APOLLO_RC1
)
model = dynex.BQM(bqm)
sampler = dynex.DynexSampler(model, config=config)
sampleset = sampler.sample(
    num_reads=50,         # QPU: 1–100
    annealing_time=200,   # QPU: 10–1000
    shots=1,              # QPU: up to 5
    qpu_max_coeff=9.0,    # Auto-scale coefficients to hardware range
    preprocess=True
)
print(f"Best energy: {sampleset.first.energy:.4f}")
```

***

## CPU

CPU workers on the Dynex network. Useful for testing network connectivity and lightweight jobs before moving to GPU.

```python theme={null}
config = DynexConfig(compute_backend=ComputeBackend.CPU)
```

***

## LOCAL

Runs the `dynexcore` binary locally without any network connection. No SDK key required. Intended for offline development and CI/CD pipelines.

```python theme={null}
config = DynexConfig(compute_backend=ComputeBackend.LOCAL)
```

Requires the `dynexcore` binary in a `testnet/` directory. Download from [GitHub releases](https://github.com/Dynex-Development/py-sdk/releases).

<Note>
  LOCAL mode is for development only. Performance does not reflect the Dynex GPU network.
</Note>

***

## Configuration via environment variables

```bash theme={null}
# .env
DYNEX_SDK_KEY=your_sdk_key
DYNEX_GRPC_ENDPOINT=quantum-router-engine-grpc.hz.dynex.co:3000
DYNEX_COMPUTE_BACKEND=gpu
```

All `DynexConfig` parameters can be set via `DYNEX_*` environment variables. Constructor arguments always take priority.

## Full DynexConfig reference

```python theme={null}
from dynex import DynexConfig, ComputeBackend, QPUModel

config = DynexConfig(
    sdk_key=None,                          # SDK key (or DYNEX_SDK_KEY)
    grpc_endpoint=None,                    # gRPC endpoint (or DYNEX_GRPC_ENDPOINT)
    compute_backend=ComputeBackend.GPU,    # Primary production backend
    qpu_model=None,                        # Required for QPU only
    use_notebook_output=True,              # Jupyter-friendly output
    default_timeout=300.0,                 # Timeout in seconds
    default_description="Dynex SDK Job",   # Job label in dashboard
    retry_count=5,                         # Retries on transient failures
    dotenv_path=None,
)
```

## Backend selection by environment

```python theme={null}
import os
from dynex import DynexConfig, ComputeBackend, QPUModel

def get_config() -> DynexConfig:
    env = os.getenv("ENV", "development")
    if env == "production":
        return DynexConfig(compute_backend=ComputeBackend.GPU)
    elif env == "qpu":
        return DynexConfig(
            compute_backend=ComputeBackend.QPU,
            qpu_model=QPUModel.APOLLO_RC1
        )
    else:
        return DynexConfig(compute_backend=ComputeBackend.LOCAL)
```
