qhyper 0.3.4__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {qhyper-0.3.4 → qhyper-0.4.0}/LICENSE.txt +1 -1
- qhyper-0.4.0/PKG-INFO +53 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/constraint.py +10 -5
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/converter.py +2 -2
- qhyper-0.4.0/QHyper/devices/__init__.py +32 -0
- qhyper-0.4.0/QHyper/devices/base.py +7 -0
- qhyper-0.4.0/QHyper/devices/dwave/__init__.py +1 -0
- qhyper-0.4.0/QHyper/devices/dwave/base.py +127 -0
- qhyper-0.4.0/QHyper/devices/iqm/__init__.py +13 -0
- qhyper-0.4.0/QHyper/devices/iqm/base.py +99 -0
- qhyper-0.4.0/QHyper/devices/iqm/fake_vlq.py +223 -0
- qhyper-0.4.0/QHyper/devices/iqm/resonance.py +103 -0
- qhyper-0.4.0/QHyper/devices/iqm/vlq.py +81 -0
- qhyper-0.4.0/QHyper/devices/pennylane/__init__.py +1 -0
- qhyper-0.4.0/QHyper/devices/pennylane/base.py +82 -0
- qhyper-0.4.0/QHyper/devices/qiskit_aer/__init__.py +4 -0
- qhyper-0.4.0/QHyper/devices/qiskit_aer/base.py +50 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/optimizers/__init__.py +12 -11
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/optimizers/cem.py +1 -1
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/optimizers/grid_search.py +1 -1
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/optimizers/qml_gradient_descent.py +2 -2
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/optimizers/random.py +1 -1
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/optimizers/scipy_minimizer.py +9 -4
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/problems/__init__.py +14 -13
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/problems/base.py +2 -2
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/problems/tsp.py +1 -1
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/solvers/__init__.py +65 -90
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/solvers/classical/gurobi/gurobi.py +1 -1
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/solvers/gate_based/pennylane/h_qaoa.py +8 -7
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/solvers/gate_based/pennylane/qaoa.py +20 -11
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/solvers/gate_based/pennylane/qml_qaoa.py +6 -5
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/solvers/gate_based/pennylane/wf_qaoa.py +8 -7
- qhyper-0.4.0/QHyper/solvers/gate_based/qiskit/__init__.py +4 -0
- qhyper-0.4.0/QHyper/solvers/gate_based/qiskit/qaoa.py +293 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/solvers/hyper_optimizer.py +3 -2
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/solvers/quantum_annealing/dwave/advantage.py +26 -34
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/solvers/quantum_annealing/dwave/cqm.py +16 -8
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/solvers/quantum_annealing/dwave/dqm.py +17 -9
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/util.py +12 -1
- qhyper-0.4.0/qhyper.egg-info/PKG-INFO +53 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/qhyper.egg-info/SOURCES.txt +15 -0
- qhyper-0.4.0/qhyper.egg-info/requires.txt +22 -0
- qhyper-0.4.0/setup.py +57 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/tests/test_optimizers_full.py +6 -1
- {qhyper-0.3.4 → qhyper-0.4.0}/tests/test_vqa.py +3 -2
- qhyper-0.3.4/PKG-INFO +0 -36
- qhyper-0.3.4/qhyper.egg-info/PKG-INFO +0 -36
- qhyper-0.3.4/qhyper.egg-info/requires.txt +0 -8
- qhyper-0.3.4/setup.py +0 -29
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/__init__.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/optimizers/base.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/optimizers/basinhopping.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/optimizers/dummy.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/optimizers/util.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/parser.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/polynomial.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/problems/community_detection.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/problems/knapsack.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/problems/maxcut.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/problems/workflow_scheduling.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/solvers/base.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/solvers/classical/__init__.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/solvers/classical/gurobi/__init__.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/solvers/gate_based/__init__.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/solvers/gate_based/pennylane/__init__.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/solvers/quantum_annealing/__init__.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/QHyper/solvers/quantum_annealing/dwave/__init__.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/README.md +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/qhyper.egg-info/dependency_links.txt +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/qhyper.egg-info/top_level.txt +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/setup.cfg +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/tests/test_converter.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/tests/test_optimizers.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/tests/test_problems.py +0 -0
- {qhyper-0.3.4 → qhyper-0.4.0}/tests/test_util.py +0 -0
qhyper-0.4.0/PKG-INFO
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: qhyper
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Quantum and classical combinatorial optimization problem solvers
|
|
5
|
+
Author: ACC Cyfronet AGH
|
|
6
|
+
Author-email: jzawalska@agh.edu.pl
|
|
7
|
+
License: MIT
|
|
8
|
+
Keywords: python,qhyper,quantum,solver,experiment
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Operating System :: Unix
|
|
15
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
16
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
17
|
+
Requires-Python: >=3.12
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE.txt
|
|
20
|
+
Requires-Dist: numpy~=2.2.6
|
|
21
|
+
Requires-Dist: PennyLane~=0.41.1
|
|
22
|
+
Requires-Dist: pennylane-lightning~=0.41.1
|
|
23
|
+
Requires-Dist: autoray~=0.7.2
|
|
24
|
+
Requires-Dist: tqdm~=4.67.3
|
|
25
|
+
Requires-Dist: sympy~=1.13.0
|
|
26
|
+
Requires-Dist: dwave-system~=1.36.0
|
|
27
|
+
Requires-Dist: dwave-cloud-client~=0.14.8
|
|
28
|
+
Requires-Dist: gurobipy~=12.0.0
|
|
29
|
+
Requires-Dist: pandas~=2.2.3
|
|
30
|
+
Requires-Dist: qiskit~=2.1.2
|
|
31
|
+
Requires-Dist: qiskit-aer~=0.17.2
|
|
32
|
+
Requires-Dist: iqm-client~=34.0.4
|
|
33
|
+
Requires-Dist: wfcommons~=0.8
|
|
34
|
+
Provides-Extra: vlq
|
|
35
|
+
Requires-Dist: py4lexis~=7.1; extra == "vlq"
|
|
36
|
+
Requires-Dist: qaas~=0.5.3; extra == "vlq"
|
|
37
|
+
Provides-Extra: dev
|
|
38
|
+
Requires-Dist: types-tqdm~=4.67.3.20260205; extra == "dev"
|
|
39
|
+
Requires-Dist: ipywidgets~=8.1; extra == "dev"
|
|
40
|
+
Dynamic: author
|
|
41
|
+
Dynamic: author-email
|
|
42
|
+
Dynamic: classifier
|
|
43
|
+
Dynamic: description
|
|
44
|
+
Dynamic: description-content-type
|
|
45
|
+
Dynamic: keywords
|
|
46
|
+
Dynamic: license
|
|
47
|
+
Dynamic: license-file
|
|
48
|
+
Dynamic: provides-extra
|
|
49
|
+
Dynamic: requires-dist
|
|
50
|
+
Dynamic: requires-python
|
|
51
|
+
Dynamic: summary
|
|
52
|
+
|
|
53
|
+
A package that allows to build and solve quantum and classical problems using predefined solvers and problems.
|
|
@@ -30,12 +30,17 @@ class MethodsForInequalities(Enum):
|
|
|
30
30
|
"""Enum class with different methods for handling inequalities.
|
|
31
31
|
|
|
32
32
|
There are two available methods for handling inequalities:
|
|
33
|
+
|
|
33
34
|
.. list-table::
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
* -
|
|
38
|
-
-
|
|
35
|
+
:header-rows: 1
|
|
36
|
+
:widths: 30 70
|
|
37
|
+
|
|
38
|
+
* - Method
|
|
39
|
+
- Description
|
|
40
|
+
* - ``SLACKS_LOG_2``
|
|
41
|
+
- Uses slack variables, log2(n) in number.
|
|
42
|
+
* - ``UNBALANCED_PENALIZATION``
|
|
43
|
+
- Uses unbalanced penalization.
|
|
39
44
|
"""
|
|
40
45
|
SLACKS_LOG_2 = 0
|
|
41
46
|
UNBALANCED_PENALIZATION = 1
|
|
@@ -176,7 +176,7 @@ class Converter:
|
|
|
176
176
|
Attributes
|
|
177
177
|
----------
|
|
178
178
|
problem : Problem
|
|
179
|
-
The problem to be solved. Objective
|
|
179
|
+
The problem to be solved. Objective function variables
|
|
180
180
|
should be written in the format <str><int> (e.g. x10, yz1).
|
|
181
181
|
cases: int, default 1
|
|
182
182
|
Number of variable cases (values)
|
|
@@ -214,7 +214,7 @@ class Converter:
|
|
|
214
214
|
for variable in problem.objective_function.get_variables():
|
|
215
215
|
if not pattern.match(variable):
|
|
216
216
|
raise ValueError(
|
|
217
|
-
f"Objective
|
|
217
|
+
f"Objective function variable '{variable}'"
|
|
218
218
|
"should be written in the format <str><int> (e.g. x10, yz1)."
|
|
219
219
|
)
|
|
220
220
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains device configurations, classes that describe where a
|
|
3
|
+
solver is run and know how to create the backend, sampler or simulator used
|
|
4
|
+
by the given platform.
|
|
5
|
+
Devices are kept separate from solvers, so the same solver can be run on a
|
|
6
|
+
local simulator or on real hardware just by changing the device.
|
|
7
|
+
|
|
8
|
+
.. code-block:: python
|
|
9
|
+
|
|
10
|
+
from QHyper.devices.pennylane import PennyLaneDevice
|
|
11
|
+
|
|
12
|
+
.. rubric:: Interface
|
|
13
|
+
|
|
14
|
+
.. autosummary::
|
|
15
|
+
:toctree: generated
|
|
16
|
+
|
|
17
|
+
Device -- Base class for devices.
|
|
18
|
+
|
|
19
|
+
.. rubric:: Available devices
|
|
20
|
+
|
|
21
|
+
.. autosummary::
|
|
22
|
+
:toctree: generated
|
|
23
|
+
|
|
24
|
+
pennylane.PennyLaneDevice -- PennyLane device configuration.
|
|
25
|
+
iqm.ResonanceDevice -- IQM Resonance device configuration.
|
|
26
|
+
iqm.VLQDevice -- VLQ device configuration.
|
|
27
|
+
qiskit_aer.AerDevice -- Qiskit Aer simulator device.
|
|
28
|
+
dwave.DWaveDevice -- D-Wave device configuration.
|
|
29
|
+
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
from QHyper.devices.base import Device
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from QHyper.devices.dwave.base import DWaveDevice
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from dwave.cloud import Client
|
|
8
|
+
from dwave.cloud.regions import get_regions
|
|
9
|
+
from dwave.system import (
|
|
10
|
+
DWaveSampler,
|
|
11
|
+
LeapHybridCQMSampler,
|
|
12
|
+
LeapHybridDQMSampler,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
from QHyper.util import normalize_key, remap_keys
|
|
16
|
+
from QHyper.devices.base import Device
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
DEVICE_NAME = 'DWaveSampler'
|
|
20
|
+
|
|
21
|
+
SAMPLERS = {
|
|
22
|
+
'advantage': (DWaveSampler,
|
|
23
|
+
lambda s: s.qpu),
|
|
24
|
+
'cqm': (LeapHybridCQMSampler,
|
|
25
|
+
lambda s: 'cqm' in s.supported_problem_types),
|
|
26
|
+
'dqm': (LeapHybridDQMSampler,
|
|
27
|
+
lambda s: 'dqm' in s.supported_problem_types),
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass
|
|
32
|
+
class DWaveDevice(Device):
|
|
33
|
+
"""
|
|
34
|
+
Device configuration for the D-Wave solvers.
|
|
35
|
+
|
|
36
|
+
Attributes
|
|
37
|
+
----------
|
|
38
|
+
type : str, default 'qpu'
|
|
39
|
+
Type of the device the problem is solved on.
|
|
40
|
+
Only 'qpu' is accepted, every D-Wave solver (Advantage, CQM, DQM)
|
|
41
|
+
runs on a remote machine.
|
|
42
|
+
name : str, default 'DWaveSampler'
|
|
43
|
+
Name of the device. Only 'DWaveSampler' is accepted.
|
|
44
|
+
backend : str | None, default None
|
|
45
|
+
Name of the backend, e.g. 'Advantage_system5.4'. If not provided,
|
|
46
|
+
the default backend available for the token is used.
|
|
47
|
+
region : str | None, default None
|
|
48
|
+
Region the backend is looked up in, e.g. 'eu-central-1'. If not
|
|
49
|
+
provided, the default region is used.
|
|
50
|
+
token : str | None, default None
|
|
51
|
+
D-Wave Leap API token. If not provided, the DWAVE_API_TOKEN
|
|
52
|
+
environment variable is used.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
type: str = 'qpu'
|
|
56
|
+
name: str = DEVICE_NAME
|
|
57
|
+
backend: str | None = None
|
|
58
|
+
region: str | None = None
|
|
59
|
+
token: str | None = None
|
|
60
|
+
|
|
61
|
+
def __post_init__(self) -> None:
|
|
62
|
+
self.type = str(self.type).lower()
|
|
63
|
+
if self.type != 'qpu':
|
|
64
|
+
raise ValueError(
|
|
65
|
+
"'device.type' must be 'qpu', every D-Wave solver "
|
|
66
|
+
"(advantage, cqm, dqm) runs on a remote machine"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
if normalize_key(self.name) != normalize_key(DEVICE_NAME):
|
|
70
|
+
raise ValueError(
|
|
71
|
+
f"'device.name' must be '{DEVICE_NAME}', got '{self.name}'"
|
|
72
|
+
)
|
|
73
|
+
self.name = DEVICE_NAME
|
|
74
|
+
|
|
75
|
+
if self.region is not None:
|
|
76
|
+
regions = [region.code for region in get_regions()]
|
|
77
|
+
if self.region not in regions:
|
|
78
|
+
raise ValueError(
|
|
79
|
+
f"Unknown D-Wave region '{self.region}'. "
|
|
80
|
+
f"Available regions: {sorted(regions)}"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
@classmethod
|
|
84
|
+
def from_config(cls, config: Any) -> "DWaveDevice":
|
|
85
|
+
if isinstance(config, cls):
|
|
86
|
+
return config
|
|
87
|
+
if not isinstance(config, dict):
|
|
88
|
+
raise ValueError("'device' must be a mapping")
|
|
89
|
+
return cls(**remap_keys(
|
|
90
|
+
config, ['type', 'name', 'backend', 'region', 'token']))
|
|
91
|
+
|
|
92
|
+
def make_sampler(self, solver_name: str) -> Any:
|
|
93
|
+
if solver_name not in SAMPLERS:
|
|
94
|
+
raise ValueError(
|
|
95
|
+
f"Unknown solver '{solver_name}', "
|
|
96
|
+
f"expected one of {sorted(SAMPLERS)}"
|
|
97
|
+
)
|
|
98
|
+
sampler, runs_on = SAMPLERS[solver_name]
|
|
99
|
+
|
|
100
|
+
kwargs: dict[str, Any] = {}
|
|
101
|
+
token = self.token or os.environ.get('DWAVE_API_TOKEN')
|
|
102
|
+
if token is not None:
|
|
103
|
+
kwargs['token'] = token
|
|
104
|
+
if self.region is not None:
|
|
105
|
+
kwargs['region'] = self.region
|
|
106
|
+
|
|
107
|
+
with Client.from_config(**kwargs) as client:
|
|
108
|
+
machines = sorted(
|
|
109
|
+
s.name for s in client.get_solvers() if runs_on(s))
|
|
110
|
+
|
|
111
|
+
where = (f"region '{self.region}'" if self.region
|
|
112
|
+
else 'the default region')
|
|
113
|
+
if not machines:
|
|
114
|
+
raise ValueError(
|
|
115
|
+
f"No machine for the '{solver_name}' solver is available "
|
|
116
|
+
f"in {where} with this token"
|
|
117
|
+
)
|
|
118
|
+
if self.backend is not None and self.backend not in machines:
|
|
119
|
+
raise ValueError(
|
|
120
|
+
f"'{self.backend}' is not a valid machine for the "
|
|
121
|
+
f"'{solver_name}' solver in {where}. "
|
|
122
|
+
f"Available machines: {machines}"
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
if self.backend is not None:
|
|
126
|
+
kwargs['solver'] = self.backend
|
|
127
|
+
return sampler(**kwargs)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# This project has received funding from the European High Performance Computing Joint Undertaking (EuroHPC JU)
|
|
2
|
+
# under grant agreement No 101159808 (EuroQHPC-Integration).
|
|
3
|
+
|
|
4
|
+
from QHyper.devices.iqm.base import IQMDevice
|
|
5
|
+
from QHyper.devices.iqm.resonance import ResonanceDevice, IQM_FAKE_BACKENDS, IQM_BACKEND_URL, IQMBackend
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def __getattr__(name):
|
|
9
|
+
# VLQDevice needs the optional 'vlq' extra (py4lexis, qaas)
|
|
10
|
+
if name == "VLQDevice":
|
|
11
|
+
from QHyper.devices.iqm.vlq import VLQDevice
|
|
12
|
+
return VLQDevice
|
|
13
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# This project has received funding from the European High Performance Computing Joint Undertaking (EuroHPC JU)
|
|
2
|
+
# under grant agreement No 101159808 (EuroQHPC-Integration).
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
from abc import ABC, abstractmethod
|
|
7
|
+
from dataclasses import fields
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from qiskit import QuantumCircuit
|
|
11
|
+
|
|
12
|
+
from QHyper.util import remap_keys
|
|
13
|
+
from QHyper.devices.base import Device
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class IQMDevice(Device, ABC):
|
|
17
|
+
"""Abstract base class for IQM device configurations."""
|
|
18
|
+
|
|
19
|
+
@abstractmethod
|
|
20
|
+
def make_backend(self) -> Any:
|
|
21
|
+
"""
|
|
22
|
+
Create the backend the circuits are run on.
|
|
23
|
+
|
|
24
|
+
Returns
|
|
25
|
+
-------
|
|
26
|
+
Any
|
|
27
|
+
Qiskit backend instance.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
@abstractmethod
|
|
33
|
+
def transpile(self, qc: QuantumCircuit, backend: Any) -> QuantumCircuit:
|
|
34
|
+
"""
|
|
35
|
+
Transpile the circuit to the gate set of the given backend.
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
qc : QuantumCircuit
|
|
40
|
+
Circuit to transpile.
|
|
41
|
+
backend : Any
|
|
42
|
+
Backend created by make_backend.
|
|
43
|
+
|
|
44
|
+
Returns
|
|
45
|
+
-------
|
|
46
|
+
QuantumCircuit
|
|
47
|
+
Circuit that can be run on the backend.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
...
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def from_config(cls, config: Any) -> "IQMDevice":
|
|
54
|
+
from QHyper.devices.iqm.resonance import ResonanceDevice
|
|
55
|
+
|
|
56
|
+
if isinstance(config, IQMDevice):
|
|
57
|
+
return config
|
|
58
|
+
if not isinstance(config, dict):
|
|
59
|
+
raise ValueError("'solver.device' must be a mapping")
|
|
60
|
+
|
|
61
|
+
cfg = remap_keys(
|
|
62
|
+
config,
|
|
63
|
+
['type', 'name', 'backend', 'project', 'resource_name', 'token'],
|
|
64
|
+
)
|
|
65
|
+
device_type = str(cfg.get('type', '')).lower()
|
|
66
|
+
device_name = str(cfg.get('name', '')).lower()
|
|
67
|
+
|
|
68
|
+
if device_type == 'simulator':
|
|
69
|
+
if device_name in ('it4i', 'lexis', 'vlq'):
|
|
70
|
+
from QHyper.devices.iqm.vlq import VLQDevice
|
|
71
|
+
return _build(VLQDevice, cfg)
|
|
72
|
+
return _build(ResonanceDevice, cfg)
|
|
73
|
+
if device_type == 'qpu':
|
|
74
|
+
if device_name in ('iqm.resonance', 'iqm', 'resonance'):
|
|
75
|
+
return _build(ResonanceDevice, cfg)
|
|
76
|
+
if device_name in ('it4i', 'lexis', 'vlq'):
|
|
77
|
+
from QHyper.devices.iqm.vlq import VLQDevice
|
|
78
|
+
return _build(VLQDevice, cfg)
|
|
79
|
+
if not device_name:
|
|
80
|
+
raise ValueError(
|
|
81
|
+
"'solver.device.name' must be a non-empty string"
|
|
82
|
+
)
|
|
83
|
+
raise ValueError(
|
|
84
|
+
f"Unsupported IQM qpu device name '{device_name}'. "
|
|
85
|
+
"Use 'iqm.resonance' for IQM or 'it4i'/'lexis' for LEXIS"
|
|
86
|
+
)
|
|
87
|
+
raise ValueError(
|
|
88
|
+
"'solver.device.type' must be either 'simulator' or 'qpu'"
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _build(target: type, cfg: dict[str, Any]) -> "IQMDevice":
|
|
93
|
+
names = {f.name for f in fields(target)}
|
|
94
|
+
unknown = [k for k in cfg if k not in names and k != 'name']
|
|
95
|
+
if unknown:
|
|
96
|
+
raise ValueError(
|
|
97
|
+
f"{target.__name__} does not accept config keys: {sorted(unknown)}"
|
|
98
|
+
)
|
|
99
|
+
return target(**{k: v for k, v in cfg.items() if k in names})
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# March 17, 2026 calibration data from VLQ
|
|
2
|
+
#
|
|
3
|
+
# Copyright 2022-2025 Qiskit on IQM developers
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
"""Fake backend for IQM's 24-qubit VLQ architecture."""
|
|
17
|
+
|
|
18
|
+
from iqm.iqm_client import StaticQuantumArchitecture
|
|
19
|
+
from iqm.qiskit_iqm.fake_backends.iqm_fake_backend import IQMErrorProfile, IQMFakeBackend
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def FakeVLQ() -> IQMFakeBackend:
|
|
23
|
+
"""Return IQMFakeBackend instance representing IQM's VLQ architecture."""
|
|
24
|
+
architecture = StaticQuantumArchitecture(
|
|
25
|
+
dut_label="FakeVLQ",
|
|
26
|
+
qubits=["QB1", "QB2", "QB3", "QB4", "QB5", "QB6", "QB7", "QB8", "QB9", "QB10", "QB11", "QB12", "QB13", "QB14", "QB15", "QB16", "QB17", "QB18", "QB19", "QB20", "QB21", "QB22", "QB23", "QB24"],
|
|
27
|
+
computational_resonators=["CR1"],
|
|
28
|
+
connectivity=[
|
|
29
|
+
("CR1", "QB1"),
|
|
30
|
+
("CR1", "QB2"),
|
|
31
|
+
("CR1", "QB3"),
|
|
32
|
+
("CR1", "QB4"),
|
|
33
|
+
("CR1", "QB5"),
|
|
34
|
+
("CR1", "QB6"),
|
|
35
|
+
("CR1", "QB7"),
|
|
36
|
+
("CR1", "QB8"),
|
|
37
|
+
("CR1", "QB9"),
|
|
38
|
+
("CR1", "QB10"),
|
|
39
|
+
("CR1", "QB11"),
|
|
40
|
+
("CR1", "QB12"),
|
|
41
|
+
("CR1", "QB13"),
|
|
42
|
+
("CR1", "QB14"),
|
|
43
|
+
("CR1", "QB15"),
|
|
44
|
+
("CR1", "QB16"),
|
|
45
|
+
("CR1", "QB17"),
|
|
46
|
+
("CR1", "QB18"),
|
|
47
|
+
("CR1", "QB19"),
|
|
48
|
+
("CR1", "QB20"),
|
|
49
|
+
("CR1", "QB21"),
|
|
50
|
+
("CR1", "QB22"),
|
|
51
|
+
("CR1", "QB23"),
|
|
52
|
+
("CR1", "QB24"),
|
|
53
|
+
],
|
|
54
|
+
)
|
|
55
|
+
error_profile = IQMErrorProfile(
|
|
56
|
+
t1s={
|
|
57
|
+
"CR1": 29814.7,
|
|
58
|
+
"QB1": 56045.2,
|
|
59
|
+
"QB2": 28729.9,
|
|
60
|
+
"QB3": 14851.5,
|
|
61
|
+
"QB4": 46265.7,
|
|
62
|
+
"QB5": 57696.6,
|
|
63
|
+
"QB6": 40583.2,
|
|
64
|
+
"QB7": 29192.0,
|
|
65
|
+
"QB8": 38211.8,
|
|
66
|
+
"QB9": 46878.0,
|
|
67
|
+
"QB10": 13875.1,
|
|
68
|
+
"QB11": 51104.7,
|
|
69
|
+
"QB12": 38616.3,
|
|
70
|
+
"QB13": 26429.5,
|
|
71
|
+
"QB14": 40202.9,
|
|
72
|
+
"QB15": 24569.9,
|
|
73
|
+
"QB16": 33320.0,
|
|
74
|
+
"QB17": 44884.3,
|
|
75
|
+
"QB18": 23783.5,
|
|
76
|
+
"QB19": 37904.1,
|
|
77
|
+
"QB20": 43738.6,
|
|
78
|
+
"QB21": 32227.6,
|
|
79
|
+
"QB22": 41627.0,
|
|
80
|
+
"QB23": 30612.1,
|
|
81
|
+
"QB24": 32437.0,
|
|
82
|
+
},
|
|
83
|
+
t2s={
|
|
84
|
+
"CR1": 29814.7,
|
|
85
|
+
"QB1": 11239.2,
|
|
86
|
+
"QB2": 15242.3,
|
|
87
|
+
"QB3": 6077.3,
|
|
88
|
+
"QB4": 11035.0,
|
|
89
|
+
"QB5": 14255.0,
|
|
90
|
+
"QB6": 12630.0,
|
|
91
|
+
"QB7": 13889.0,
|
|
92
|
+
"QB8": 9170.8,
|
|
93
|
+
"QB9": 9473.1,
|
|
94
|
+
"QB10": 10501.1,
|
|
95
|
+
"QB11": 10618.5,
|
|
96
|
+
"QB12": 13293.6,
|
|
97
|
+
"QB13": 6709.4,
|
|
98
|
+
"QB14": 12630.0,
|
|
99
|
+
"QB15": 12633.8,
|
|
100
|
+
"QB16": 13851.6,
|
|
101
|
+
"QB17": 14455.5,
|
|
102
|
+
"QB18": 9903.4,
|
|
103
|
+
"QB19": 10948.8,
|
|
104
|
+
"QB20": 17564.0,
|
|
105
|
+
"QB21": 13208.1,
|
|
106
|
+
"QB22": 15476.7,
|
|
107
|
+
"QB23": 17537.6,
|
|
108
|
+
"QB24": 12227.4,
|
|
109
|
+
},
|
|
110
|
+
single_qubit_gate_depolarizing_error_parameters={
|
|
111
|
+
"prx": {
|
|
112
|
+
"QB1": 0.01004,
|
|
113
|
+
"QB2": 0.01586,
|
|
114
|
+
"QB3": 0.00121,
|
|
115
|
+
"QB4": 0.00218,
|
|
116
|
+
"QB5": 0.00172,
|
|
117
|
+
"QB6": 0.00232,
|
|
118
|
+
"QB7": 0.00096,
|
|
119
|
+
"QB8": 0.00222,
|
|
120
|
+
"QB9": 0.00098,
|
|
121
|
+
"QB10": 0.00121,
|
|
122
|
+
"QB11": 0.00102,
|
|
123
|
+
"QB12": 0.00157,
|
|
124
|
+
"QB13": 0.0011,
|
|
125
|
+
"QB14": 0.03532,
|
|
126
|
+
"QB15": 0.00085,
|
|
127
|
+
"QB16": 0.00128,
|
|
128
|
+
"QB17": 0.00124,
|
|
129
|
+
"QB18": 0.00058,
|
|
130
|
+
"QB19": 0.00125,
|
|
131
|
+
"QB20": 0.00058,
|
|
132
|
+
"QB21": 0.0013,
|
|
133
|
+
"QB22": 0.0008,
|
|
134
|
+
"QB23": 0.00192,
|
|
135
|
+
"QB24": 0.0027,
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
two_qubit_gate_depolarizing_error_parameters={
|
|
139
|
+
"cz": {
|
|
140
|
+
("QB1", "CR1"): 0.005743,
|
|
141
|
+
("QB2", "CR1"): 0.060690,
|
|
142
|
+
("QB3", "CR1"): 0.012595,
|
|
143
|
+
("QB4", "CR1"): 0.007504,
|
|
144
|
+
("QB5", "CR1"): 0.005700,
|
|
145
|
+
("QB6", "CR1"): 0.044717,
|
|
146
|
+
("QB7", "CR1"): 0.005157,
|
|
147
|
+
("QB8", "CR1"): 0.007602,
|
|
148
|
+
("QB9", "CR1"): 0.007248,
|
|
149
|
+
("QB10", "CR1"): 0.011908,
|
|
150
|
+
("QB11", "CR1"): 0.007327,
|
|
151
|
+
("QB12", "CR1"): 0.005934,
|
|
152
|
+
("QB13", "CR1"): 0.005665,
|
|
153
|
+
("QB14", "CR1"): 0.111660,
|
|
154
|
+
("QB15", "CR1"): 0.004772,
|
|
155
|
+
("QB16", "CR1"): 0.021655,
|
|
156
|
+
("QB17", "CR1"): 0.006845,
|
|
157
|
+
("QB18", "CR1"): 0.026027,
|
|
158
|
+
("QB19", "CR1"): 0.005808,
|
|
159
|
+
("QB20", "CR1"): 0.358012,
|
|
160
|
+
("QB21", "CR1"): 0.015436,
|
|
161
|
+
("QB22", "CR1"): 0.006003,
|
|
162
|
+
("QB23", "CR1"): 0.004907,
|
|
163
|
+
("QB24", "CR1"): 0.006182,
|
|
164
|
+
},
|
|
165
|
+
"move": {
|
|
166
|
+
("QB1", "CR1"): 0.000659,
|
|
167
|
+
("QB2", "CR1"): 0.001453,
|
|
168
|
+
("QB3", "CR1"): 0.020023,
|
|
169
|
+
("QB4", "CR1"): 0.001523,
|
|
170
|
+
("QB5", "CR1"): 0.001287,
|
|
171
|
+
("QB6", "CR1"): 0.000998,
|
|
172
|
+
("QB7", "CR1"): 0.099595,
|
|
173
|
+
("QB8", "CR1"): 0.003081,
|
|
174
|
+
("QB9", "CR1"): 0.001481,
|
|
175
|
+
("QB10", "CR1"): 0.002812,
|
|
176
|
+
("QB11", "CR1"): 0.000970,
|
|
177
|
+
("QB12", "CR1"): 0.004332,
|
|
178
|
+
("QB13", "CR1"): 0.001165,
|
|
179
|
+
("QB14", "CR1"): 0.007962,
|
|
180
|
+
("QB15", "CR1"): 0.004231,
|
|
181
|
+
("QB16", "CR1"): 0.002013,
|
|
182
|
+
("QB17", "CR1"): 0.001451,
|
|
183
|
+
("QB18", "CR1"): 0.001123,
|
|
184
|
+
("QB19", "CR1"): 0.001912,
|
|
185
|
+
("QB20", "CR1"): 0.001385,
|
|
186
|
+
("QB21", "CR1"): 0.003157,
|
|
187
|
+
("QB22", "CR1"): 0.001503,
|
|
188
|
+
("QB23", "CR1"): 0.001453,
|
|
189
|
+
("QB24", "CR1"): 0.002493,
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
single_qubit_gate_durations={"prx": 32.0},
|
|
193
|
+
two_qubit_gate_durations={"cz": 88.0, "move": 64.0},
|
|
194
|
+
readout_errors={
|
|
195
|
+
"QB1": {"0": 0.016, "1": 0.0665},
|
|
196
|
+
"QB2": {"0": 0.0305, "1": 0.058},
|
|
197
|
+
"QB3": {"0": 0.0095, "1": 0.022},
|
|
198
|
+
"QB4": {"0": 0.0255, "1": 0.0225},
|
|
199
|
+
"QB5": {"0": 0.0285, "1": 0.037},
|
|
200
|
+
"QB6": {"0": 0.0195, "1": 0.061},
|
|
201
|
+
"QB7": {"0": 0.032, "1": 0.0275},
|
|
202
|
+
"QB8": {"0": 0.041, "1": 0.038},
|
|
203
|
+
"QB9": {"0": 0.043, "1": 0.0365},
|
|
204
|
+
"QB10": {"0": 0.019, "1": 0.033},
|
|
205
|
+
"QB11": {"0": 0.0095, "1": 0.0155},
|
|
206
|
+
"QB12": {"0": 0.009, "1": 0.0135},
|
|
207
|
+
"QB13": {"0": 0.0155, "1": 0.011},
|
|
208
|
+
"QB14": {"0": 0.016, "1": 0.205},
|
|
209
|
+
"QB15": {"0": 0.004, "1": 0.016},
|
|
210
|
+
"QB16": {"0": 0.0225, "1": 0.024},
|
|
211
|
+
"QB17": {"0": 0.0215, "1": 0.026},
|
|
212
|
+
"QB18": {"0": 0.0165, "1": 0.019},
|
|
213
|
+
"QB19": {"0": 0.0075, "1": 0.024},
|
|
214
|
+
"QB20": {"0": 0.014, "1": 0.0205},
|
|
215
|
+
"QB21": {"0": 0.0075, "1": 0.0195},
|
|
216
|
+
"QB22": {"0": 0.0225, "1": 0.033},
|
|
217
|
+
"QB23": {"0": 0.0055, "1": 0.0135},
|
|
218
|
+
"QB24": {"0": 0.017, "1": 0.0255},
|
|
219
|
+
},
|
|
220
|
+
name="VLQ",
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
return IQMFakeBackend(architecture, error_profile, name="FakeVLQBackend")
|