Skip to main content

Workflow: Formulation and Sampling

Every computation on Dynex follows the same pattern: define a model, configure a backend, sample, and analyze results.

Full Example

import dynex
import dimod
from dynex import DynexConfig, ComputeBackend

# Step 1: Build the problem model
bqm = dimod.BinaryQuadraticModel(
    {0: -1.0, 1: -1.0},
    {(0, 1): 2.0},
    0.0,
    'BINARY'
)

# Step 2: Configure the compute backend (GPU = Dynex neuromorphic chips)
config = DynexConfig(compute_backend=ComputeBackend.GPU)

# Step 3: Wrap model and create sampler
model = dynex.BQM(bqm)
sampler = dynex.DynexSampler(model, config=config, description="My optimization job")

# Step 4: Sample
sampleset = sampler.sample(
    num_reads=1000,
    annealing_time=200,
    shots=5,
)

# Step 5: Inspect results
best = sampleset.first
print(f"Best sample:  {best.sample}")
print(f"Best energy:  {best.energy}")

# Iterate over all samples
for sample, energy in sampleset.data(['sample', 'energy']):
    print(f"  {sample} → energy {energy:.4f}")

Step 1: Choose a Model Type

Select the model class that best fits your problem:
ModelClassUse when
Binary Quadratic Modeldynex.BQMNatural QUBO/Ising formulation
Constrained Quadratic Modeldynex.CQMConstraints are central to the problem
Discrete Quadratic Modeldynex.DQMVariables have more than 2 possible values
See Defining Models for detailed examples of each type.

Step 2: Choose a Compute Backend

from dynex import DynexConfig, ComputeBackend, QPUModel

# GPU — Dynex neuromorphic chips, primary production backend
config = DynexConfig(compute_backend=ComputeBackend.GPU)

# QPU — specific quantum hardware model
config = DynexConfig(
    compute_backend=ComputeBackend.QPU,
    qpu_model=QPUModel.APOLLO_RC1
)

# CPU — lightweight network jobs and connectivity testing
config = DynexConfig(compute_backend=ComputeBackend.CPU)

# LOCAL — offline testing, no credentials required
config = DynexConfig(compute_backend=ComputeBackend.LOCAL)
Use GPU for all production workloads — it runs on Dynex’s own neuromorphic chips distributed globally. Use LOCAL for offline development and unit tests.

Step 3: Build Sampler

sampler = dynex.DynexSampler(
    model,
    config=config,
    description="Optional job description",
    logging=True
)

Step 4: Run Sampling

sampleset = sampler.sample(
    num_reads=1000,       # Number of parallel reads
    annealing_time=200,   # Integration depth (ODE steps)
    shots=5,              # Minimum solutions from network
    preprocess=False,     # Enable preprocessing for QPU
)
Parameter guidance:
ParameterGPU (small/test)GPU (production)QPU
num_reads100–5001000–100001–100
annealing_time50–200200–100010–1000
shots11–51–5
QPU backends have tighter hardware constraints: num_reads must stay within 1–100, annealing_time within 10–1000, and shots up to 5.

Step 5: Analyze Results

The sampler returns a dimod SampleSet:
# Best solution
best = sampleset.first
print(best.sample)   # {0: 1, 1: 0, 2: 1, ...}
print(best.energy)   # -3.14159

# All samples sorted by energy
for sample in sampleset.samples():
    print(sample)

# As pandas DataFrame
df = sampleset.to_pandas_dataframe()
print(df.head())

# Number of occurrences
for sample, energy, num_occ in sampleset.data(['sample', 'energy', 'num_occurrences']):
    print(f"Energy {energy:.3f} occurred {num_occ} times")

Step 6: Iterate

Tune your model and parameters:
  • Better solutions → increase num_reads and annealing_time
  • Faster results → decrease annealing_time, use CPU instead of QPU
  • Constrained problems → switch from BQM to CQM
  • Large-scale → use QPU backend with preprocess=True

Migrating from legacy SDK

LegacyCurrent
sampler.sample(..., mainnet=True)DynexConfig(compute_backend=ComputeBackend.CPU)
sampler.sample(..., mainnet=False)DynexConfig(compute_backend=ComputeBackend.LOCAL)
sampler.sample(..., v2=True)Remove v2=True — no longer needed
REST-based communicationgRPC-based communication (automatic)