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β
Model | Solvers |
---|---|
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)
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
andy
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
Key | Description | Data Type | Default Value | Minimum Value | Maximum Value |
---|---|---|---|---|---|
type | Execution machine type | integer | 3 | - | - |
num_executions | Annealing execution count | integer | 1 | 1 | 10 |
parameters | Execution parameter control setting | object | - | - | - |
temperature_num_steps | Temperature change step number | integer | 10 | 1 | 100 |
temperature_step_length | Length per temperature step | integer | 100 | 1 | 1000 |
temperature_initial | Initial temperature | number | 10.0 | 0 or more | 3.402823e+38 |
temperature_target | Final temperature | number | 0.01 | 0 or more | 3.402823e+38 |
outputs | Control of values included in response | object | - | - | - |
energies | Output energy value | boolean | true | - | - |
spins | Output spin value array | boolean | true | - | - |
execution_time | Output execution time (nsec) | boolean | false | - | - |
num_outputs | Number of outputs of spin value and energy value | integer | 0 | 0 | num_executions |
averaged_spins | Output average value per site of spin | boolean | false | - | - |
averaged_energy | Output the average value of energy | boolean | false | - | - |
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)
Parameter | Type | Default | Description |
---|---|---|---|
max_no_improvement | int | None | Maximum 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_seed | int | None | Seed for the random number generator. If set to None, the seed is initialized using os.random(). |
timeout | int | None | Maximum time (in seconds) before the algorithm gives up. |
max_beta | float | None | Qubits 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. |
tries | int | None | Number of restart attempts before the algorithm stops. A typical restart takes between 1 and 60 seconds. |
inner_rounds | int | None | Maximum number of iterations between restart attempts. If None, inner_rounds is effectively infinite. |
chainlength_patience | int | None | Maximum number of failed iterations to improve chain lengths in the current solution. |
max_fill | int | None | Restricts 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. |
threads | int | None | Maximum number of threads to use. Parallelization is only advantageous where the expected degree of variables is significantly greater than the number of threads. |
return_overlap | bool | None | Determines 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_initialization | bool | None | Skips the initialization pass if the chains passed through initial_chains and fixed_chains are semi-valid. |
verbose | int | None | Level of output verbosity. Ranges from 0 (quiet) to 4 (detailed debugging). |
interactive | bool | None | If 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_chains | dict | None | Initial chains to be inserted into an embedding before fixed_chains are placed. |
fixed_chains | dict | None | Fixed chains that are inserted into an embedding before the initialization pass and do not change during the algorithm. |
restrict_chains | dict | None | Ensures that each chain is a subset of restrict_chains throughout the algorithm. |
suspend_chains | dict | None | A metafeature implemented in the Python interface. Each entry is an iterable of iterables representing the target node labels. |