Skip to main content

Hitachi

Hitachi has developed the CMOS annealing machine πŸ”—, a non-Neumann architecture computer utilizing the structure of SRAM, a storage device, to perform optimization processing with the Ising model.

Solvers​

ModelSolvers
Quadratic Unconstrained Binary Optimization (QUBO)hitachi.cmos_annealer

You can specify the machine type using the HitachiParameterModel to run the process using the following options:

  • 3 : GPU 32bit(int)
  • 4 : GPU 32bit(float)
  • 5 : ASIC 4bit
from strangeworks_optimization_models.parameter_models import HitachiParameterModel

options = HitachiParameterModel(solver_type=5)

Hitachi API Reference πŸ”—

Quadratic Unconstrained Binary Optimization (QUBO)​

import strangeworks as sw

from strangeworks_optimization import StrangeworksOptimizer
from strangeworks_optimization_models.parameter_models import HitachiParameterModel
from dimod import BinaryQuadraticModel

sw.authenticate(api_key)

linear = {1: -2, 2: -2, 3: -3, 4: -3, 5: -2}
quadratic = {(1, 2): 2, (1, 3): 2, (2, 4): 2, (3, 4): 2, (3, 5): 2, (4, 5): 2}
model = BinaryQuadraticModel(linear, quadratic, "BINARY")

options = HitachiParameterModel(solver_type=5)

solver = 'hitachi.cmos_annealer'

so = StrangeworksOptimizer(
model=model,
options=options,
solver=solver
)

sw_job = so.run()
print(f"Job slug: {sw_job.slug}")
print(f"Job status: {so.status(sw_job.slug)}")
results = so.results(sw_job.slug)
print(results.solution)

Ising Model​

The Ising model is a mathematical framework used to simulate magnetic materials. It aims to find the best arrangement of spins (up or down) on a grid, following specific rules.

In essence, Ising models are similar to QUBO models, but they use spin variables (up or down) instead of binary variables.

The model is defined by a list of integer arrays [x0, y0, x1, y1, p]. Each array has 5 elements that describe the points or interactions in the Ising model. The order of these elements doesn't affect the outcome.

  • x and y are coordinates on the grid (x-axis, y-axis).
  • p is the coefficient for the interaction.

To define a vertex (or magnetic field), use x0 == x1 and y0 == y1. To define an interaction between two vertices, ensure x0, y0 and x1, y1 are adjacent (up-down, left-right, or diagonal). If non-adjacent vertices are specified, an error will occur.

import strangeworks as sw

from strangeworks_optimization import StrangeworksOptimizer
from strangeworks_optimization_models.problem_models import HitachiModelList
from strangeworks_optimization_models.parameter_models import HitachiParameterModel

sw.authenticate(api_key)

model = HitachiModelList(
[
[0, 0, 0, 1, 117],
[0, 0, 1, 0, 104],
[0, 0, 1, 1, 65],
[0, 1, 1, 0, 72],
[0, 1, 1, 1, 45],
[1, 0, 1, 1, 40],
]
)

options = HitachiParameterModel(solver_type=5)

solver = 'hitachi.cmos_annealer'

so = StrangeworksOptimizer(
model=model,
options=options,
solver=solver
)

sw_job = so.run()
print(f"Job slug: {sw_job.slug}")
print(f"Job status: {so.status(sw_job.slug)}")
results = so.results(sw_job.slug)
print(results.solution)

Parameters​

from strangeworks_optimization_models.parameter_models import HitachiParameterModel

options = HitachiParameterModel(
.....
)

Solvers

  • hitachi.cmos_annealer
KeyDescriptionData TypeDefault ValueMinimum ValueMaximum Value
typeExecution machine typeinteger3--
num_executionsAnnealing execution countinteger1110
parametersExecution parameter control settingobject---
temperature_num_stepsTemperature change step numberinteger101100
temperature_step_lengthLength per temperature stepinteger10011000
temperature_initialInitial temperaturenumber10.00 or more3.402823e+38
temperature_targetFinal temperaturenumber0.010 or more3.402823e+38
outputsControl of values included in responseobject---
energiesOutput energy valuebooleantrue--
spinsOutput spin value arraybooleantrue--
execution_timeOutput execution time (nsec)booleanfalse--
num_outputsNumber of outputs of spin value and energy valueinteger00num_executions
averaged_spinsOutput average value per site of spinbooleanfalse--
averaged_energyOutput the average value of energybooleanfalse--

Embedding​

To use embedding with Hitachi solvers, pass the embedding_parameters parameter to the solver.

from strangeworks_optimization_models.parameter_models import HitachiParameterModel

options = HitachiParameterModel(embedding_parameters={
"chain_strength": 10,
"anneal_schedule": [[0, 0], [1, 1]],
"anneal_offsets": [0, 0],
"annealing_time": 1,
"auto_scale": True,
})

Solvers

  • DwaveSamplerParameterModel(embedding_parameters)
  • HitachiParameterModel(embedding_parameters)
ParameterTypeDefaultDescription
max_no_improvementintNoneMaximum number of failed iterations to improve the current solution. Each iteration attempts to find an embedding for each variable such that it is adjacent to all its neighbours.
random_seedintNoneSeed for the random number generator. If set to None, the seed is initialized using os.random().
timeoutintNoneMaximum time (in seconds) before the algorithm gives up.
max_betafloatNoneQubits are assigned weight based on a formula (beta^n) where n is the number of chains containing that qubit. This value should be greater than 1. If None, max_beta is effectively infinite.
triesintNoneNumber of restart attempts before the algorithm stops. A typical restart takes between 1 and 60 seconds.
inner_roundsintNoneMaximum number of iterations between restart attempts. If None, inner_rounds is effectively infinite.
chainlength_patienceintNoneMaximum number of failed iterations to improve chain lengths in the current solution.
max_fillintNoneRestricts the number of chains that can simultaneously incorporate the same qubit during the search. Values above 63 are treated as 63. If None, max_fill is effectively infinite.
threadsintNoneMaximum number of threads to use. Parallelization is only advantageous where the expected degree of variables is significantly greater than the number of threads.
return_overlapboolNoneDetermines the function’s return value. If True, a 2-tuple is returned with the embedding and a boolean representing the embedding validity. If False, only an embedding is returned.
skip_initializationboolNoneSkips the initialization pass if the chains passed through initial_chains and fixed_chains are semi-valid.
verboseintNoneLevel of output verbosity. Ranges from 0 (quiet) to 4 (detailed debugging).
interactiveboolNoneIf True, the verbose output will be printed to stdout/stderr and keyboard interrupts will stop the embedding process, returning the current state to the user.
initial_chainsdictNoneInitial chains to be inserted into an embedding before fixed_chains are placed.
fixed_chainsdictNoneFixed chains that are inserted into an embedding before the initialization pass and do not change during the algorithm.
restrict_chainsdictNoneEnsures that each chain is a subset of restrict_chains throughout the algorithm.
suspend_chainsdictNoneA metafeature implemented in the Python interface. Each entry is an iterable of iterables representing the target node labels.