pennylane-qrack 0.18.8__py3-none-macosx_14_0_arm64.whl → 0.20.0__py3-none-macosx_14_0_arm64.whl

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.

Potentially problematic release.


This version of pennylane-qrack might be problematic. Click here for more details.

@@ -247,7 +247,7 @@ CMAKE_CACHE_MAJOR_VERSION:INTERNAL=4
247
247
  //Minor version of cmake used to create the current loaded cache
248
248
  CMAKE_CACHE_MINOR_VERSION:INTERNAL=0
249
249
  //Patch version of cmake used to create the current loaded cache
250
- CMAKE_CACHE_PATCH_VERSION:INTERNAL=2
250
+ CMAKE_CACHE_PATCH_VERSION:INTERNAL=3
251
251
  //ADVANCED property for variable: CMAKE_COLOR_MAKEFILE
252
252
  CMAKE_COLOR_MAKEFILE-ADVANCED:INTERNAL=1
253
253
  //Path to CMake executable.
@@ -0,0 +1,117 @@
1
+ schema = 3
2
+
3
+ # The set of all gate types supported at the runtime execution interface of the
4
+ # device, i.e., what is supported by the `execute` method. The gate definitions
5
+ # should have the following format:
6
+ #
7
+ # GATE = { properties = [ PROPS ], conditions = [ CONDS ] }
8
+ #
9
+ # where PROPS and CONS are zero or more comma separated quoted strings.
10
+ #
11
+ # PROPS: additional support provided for each gate.
12
+ # - "controllable": if a controlled version of this gate is supported.
13
+ # - "invertible": if the adjoint of this operation is supported.
14
+ # - "differentiable": if device gradient is supported for this gate.
15
+ # CONDS: constraints on the support for each gate.
16
+ # - "analytic" or "finiteshots": if this operation is only supported in
17
+ # either analytic execution or with shots, respectively.
18
+ #
19
+ [operators.gates]
20
+
21
+ PauliX = { properties = [ "controllable", "invertible" ] }
22
+ PauliY = { properties = [ "controllable", "invertible" ] }
23
+ PauliZ = { properties = [ "controllable", "invertible" ] }
24
+ SX = { properties = [ "controllable", "invertible" ] }
25
+ MultiRZ = { properties = [ "controllable", "invertible" ] }
26
+ Hadamard = { properties = [ "controllable", "invertible" ] }
27
+ S = { properties = [ "controllable", "invertible" ] }
28
+ T = { properties = [ "controllable", "invertible" ] }
29
+ CNOT = { properties = [ "controllable", "invertible" ] }
30
+ SWAP = { properties = [ "controllable", "invertible" ] }
31
+ CSWAP = { properties = [ "controllable", "invertible" ] }
32
+ ISWAP = { properties = [ "controllable", "invertible" ] }
33
+ PSWAP = { properties = [ "controllable", "invertible" ] }
34
+ Toffoli = { properties = [ "controllable", "invertible" ] }
35
+ CY = { properties = [ "controllable", "invertible" ] }
36
+ CZ = { properties = [ "controllable", "invertible" ] }
37
+ PhaseShift = { properties = [ "controllable", "invertible" ] }
38
+ ControlledPhaseShift = { properties = [ "controllable", "invertible" ] }
39
+ CPhase = { properties = [ "controllable", "invertible" ] }
40
+ RX = { properties = [ "controllable", "invertible" ] }
41
+ RY = { properties = [ "controllable", "invertible" ] }
42
+ RZ = { properties = [ "controllable", "invertible" ] }
43
+ Rot = { properties = [ "controllable", "invertible" ] }
44
+ CRX = { properties = [ "controllable", "invertible" ] }
45
+ CRY = { properties = [ "controllable", "invertible" ] }
46
+ CRZ = { properties = [ "controllable", "invertible" ] }
47
+ CRot = { properties = [ "controllable", "invertible" ] }
48
+ U3 = { properties = [ "controllable", "invertible" ] }
49
+ MultiControlledX = { properties = [ "controllable", "invertible" ] }
50
+ Identity = { properties = [ "controllable", "invertible" ] }
51
+
52
+ # Observables supported by the device for measurements. The observables defined
53
+ # in this section should have the following format:
54
+ #
55
+ # OBSERVABLE = { conditions = [ CONDS ] }
56
+ #
57
+ # where CONDS is zero or more comma separated quoted strings, same as above.
58
+ #
59
+ # CONDS: constraints on the support for each observable.
60
+ # - "analytic" or "finiteshots": if this observable is only supported in
61
+ # either analytic execution or with shots, respectively.
62
+ # - "terms-commute": if a composite operator is only supported under the
63
+ # condition that its terms commute.
64
+ #
65
+ [operators.observables]
66
+
67
+ PauliX = {}
68
+ PauliY = {}
69
+ PauliZ = {}
70
+ Identity = {}
71
+ Prod = {}
72
+ # Hadamard = {}
73
+ # Hermitian = {}
74
+ # Projector = {}
75
+ # SparseHamiltonian = {}
76
+ # Hamiltonian = {}
77
+ # Sum = {}
78
+ # SProd = {}
79
+ # Exp = {}
80
+
81
+ # Types of measurement processes supported on the device. The measurements in
82
+ # this section should have the following format:
83
+ #
84
+ # MEASUREMENT_PROCESS = { conditions = [ CONDS ] }
85
+ #
86
+ # where CONDS is zero or more comma separated quoted strings, same as above.
87
+ #
88
+ # CONDS: constraints on the support for each measurement process.
89
+ # - "analytic" or "finiteshots": if this measurement is only supported
90
+ # in either analytic execution or with shots, respectively.
91
+ #
92
+ [measurement_processes]
93
+
94
+ ExpectationMP = { conditions = [ "finiteshots" ] }
95
+ VarianceMP = { conditions = [ "finiteshots" ] }
96
+ ProbabilityMP = { conditions = [ "finiteshots" ] }
97
+ StateMP = { conditions = [ "finiteshots" ] }
98
+ SampleMP = { conditions = [ "finiteshots" ] }
99
+ CountsMP = { conditions = [ "finiteshots" ] }
100
+
101
+ # Additional support that the device may provide that informs the compilation
102
+ # process. All accepted fields and their default values are listed below.
103
+ [compilation]
104
+
105
+ # Whether the device is compatible with qjit.
106
+ qjit_compatible = false
107
+
108
+ # Whether the device requires run time generation of the quantum circuit.
109
+ runtime_code_generation = false
110
+
111
+ # Whether the device supports allocating and releasing qubits during execution.
112
+ dynamic_qubit_management = false
113
+
114
+ # The methods of handling mid-circuit measurements that the device supports,
115
+ # e.g., "one-shot", "tree-traversal", "device", etc. An empty list indicates
116
+ # that the device does not support mid-circuit measurements.
117
+ supported_mcm_methods = [ "device", "one-shot" ]
@@ -21,32 +21,23 @@ schema = 3
21
21
  PauliX = { properties = [ "controllable", "invertible" ] }
22
22
  PauliY = { properties = [ "controllable", "invertible" ] }
23
23
  PauliZ = { properties = [ "controllable", "invertible" ] }
24
- SX = { properties = [ "controllable", "invertible" ] }
25
- MultiRZ = { properties = [ "controllable", "invertible" ] }
26
- Hadamard = { properties = [ "controllable", "invertible" ] }
27
- S = { properties = [ "controllable", "invertible" ] }
28
- T = { properties = [ "controllable", "invertible" ] }
29
- CNOT = { properties = [ "controllable", "invertible" ] }
30
- SWAP = { properties = [ "controllable", "invertible" ] }
31
- CSWAP = { properties = [ "controllable", "invertible" ] }
32
- ISWAP = { properties = [ "controllable", "invertible" ] }
33
- PSWAP = { properties = [ "controllable", "invertible" ] }
34
- Toffoli = { properties = [ "controllable", "invertible" ] }
35
- CY = { properties = [ "controllable", "invertible" ] }
36
- CZ = { properties = [ "controllable", "invertible" ] }
37
- PhaseShift = { properties = [ "controllable", "invertible" ] }
38
- ControlledPhaseShift = { properties = [ "controllable", "invertible" ] }
39
- CPhase = { properties = [ "controllable", "invertible" ] }
40
- RX = { properties = [ "controllable", "invertible" ] }
41
- RY = { properties = [ "controllable", "invertible" ] }
42
- RZ = { properties = [ "controllable", "invertible" ] }
43
- Rot = { properties = [ "controllable", "invertible" ] }
44
- CRX = { properties = [ "controllable", "invertible" ] }
45
- CRY = { properties = [ "controllable", "invertible" ] }
46
- CRZ = { properties = [ "controllable", "invertible" ] }
47
- CRot = { properties = [ "controllable", "invertible" ] }
48
- U3 = { properties = [ "controllable", "invertible" ] }
49
- MultiControlledX = { properties = [ "controllable", "invertible" ] }
24
+ SX = { properties = [ "invertible" ] }
25
+ MultiRZ = { properties = [ "invertible" ] }
26
+ Hadamard = { properties = [ "invertible" ] }
27
+ S = { properties = [ "invertible" ] }
28
+ T = { properties = [ "invertible" ] }
29
+ CNOT = { properties = [ "invertible" ] }
30
+ SWAP = { properties = [ "invertible" ] }
31
+ ISWAP = { properties = [ "invertible" ] }
32
+ PSWAP = { properties = [ "invertible" ] }
33
+ CY = { properties = [ "invertible" ] }
34
+ CZ = { properties = [ "invertible" ] }
35
+ PhaseShift = { properties = [ "invertible" ] }
36
+ RX = { properties = [ "invertible" ] }
37
+ RY = { properties = [ "invertible" ] }
38
+ RZ = { properties = [ "invertible" ] }
39
+ Rot = { properties = [ "invertible" ] }
40
+ U3 = { properties = [ "invertible" ] }
50
41
  Identity = { properties = [ "controllable", "invertible" ] }
51
42
 
52
43
  # Observables supported by the device for measurements. The observables defined
@@ -13,7 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """Version information.
16
- Version number (major.minor.patch[-label])
16
+ Version number (major.minor.patch[-label])
17
17
  """
18
18
 
19
- __version__ = "0.18.8"
19
+ __version__ = "0.20.0"
@@ -0,0 +1,449 @@
1
+ # Copyright 2020 Xanadu Quantum Technologies Inc.
2
+
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """
15
+ Base device class for PennyLane-Qrack.
16
+ """
17
+ from functools import reduce
18
+ import cmath, math
19
+ import os
20
+ import pathlib
21
+ import sys
22
+ import itertools as it
23
+
24
+ import numpy as np
25
+
26
+ # PennyLane v0.42 introduced the `exceptions` module and will raise
27
+ # deprecation warnings if they are imported from the top-level module.
28
+
29
+ # This ensures backwards compatibility with older versions of PennyLane.
30
+ try:
31
+ from pennylane.exceptions import DeviceError, QuantumFunctionError
32
+ except (ModuleNotFoundError, ImportError) as import_error:
33
+ from pennylane import DeviceError, QuantumFunctionError
34
+
35
+ from pennylane.devices import QubitDevice
36
+ from pennylane.ops import (
37
+ BasisState,
38
+ Adjoint,
39
+ )
40
+ from pennylane.wires import Wires
41
+
42
+ from pyqrack import QrackAceBackend, Pauli
43
+
44
+ from ._version import __version__
45
+ from sys import platform as _platform
46
+
47
+ # tolerance for numerical errors
48
+ tolerance = 1e-10
49
+
50
+
51
+ class QrackAceDevice(QubitDevice):
52
+ """Qrack Ace device"""
53
+
54
+ name = "Qrack device"
55
+ short_name = "qrack.simulator"
56
+ pennylane_requires = ">=0.11.0"
57
+ version = __version__
58
+ author = "Daniel Strano, adapted from Steven Oud and Xanadu"
59
+
60
+ _capabilities = {
61
+ "model": "qubit",
62
+ "tensor_observables": True,
63
+ "inverse_operations": True,
64
+ "returns_state": False,
65
+ }
66
+
67
+ _observable_map = {
68
+ "PauliX": Pauli.PauliX,
69
+ "PauliY": Pauli.PauliY,
70
+ "PauliZ": Pauli.PauliZ,
71
+ "Identity": Pauli.PauliI,
72
+ "Hadamard": None,
73
+ "Hermitian": None,
74
+ "Prod": None,
75
+ # "Sum": None,
76
+ # "SProd": None,
77
+ # "Exp": None,
78
+ # "Projector": None,
79
+ # "Hamiltonian": None,
80
+ # "SparseHamiltonian": None
81
+ }
82
+
83
+ observables = _observable_map.keys()
84
+ operations = {
85
+ "Identity",
86
+ "C(Identity)",
87
+ "MultiRZ",
88
+ "C(MultiRZ)",
89
+ "CRX",
90
+ "CRY",
91
+ "CRZ",
92
+ "CRot",
93
+ "SWAP",
94
+ "ISWAP",
95
+ "PSWAP",
96
+ "CNOT",
97
+ "CY",
98
+ "CZ",
99
+ "S",
100
+ "T",
101
+ "RX",
102
+ "RY",
103
+ "RZ",
104
+ "PauliX",
105
+ "C(PauliX)",
106
+ "PauliY",
107
+ "C(PauliY)",
108
+ "PauliZ",
109
+ "C(PauliZ)",
110
+ "Hadamard",
111
+ "SX",
112
+ "PhaseShift",
113
+ "C(PhaseShift)",
114
+ "U3",
115
+ "Rot",
116
+ "ControlledPhaseShift",
117
+ "CPhase",
118
+ }
119
+
120
+ config_filepath = pathlib.Path(
121
+ os.path.dirname(sys.modules[__name__].__file__) + "/QrackDeviceConfig.toml"
122
+ )
123
+
124
+ # Use "hybrid" stabilizer optimization? (Default is "true"; non-Clifford circuits will fall back to near-Clifford or universal simulation)
125
+ isStabilizerHybrid = False
126
+ # Use "tensor network" optimization? (Default is "true"; prevents dynamic qubit de-allocation; might function sub-optimally with "hybrid" stabilizer enabled)
127
+ isTensorNetwork = False
128
+ # Use Schmidt decomposition optimizations? (Default is "true")
129
+ isSchmidtDecompose = True
130
+ # Distribute Schmidt-decomposed qubit subsystems to multiple GPUs or accelerators, if available? (Default is "true"; mismatched device capacities might hurt overall performance)
131
+ isSchmidtDecomposeMulti = True
132
+ # Use "quantum binary decision diagram" ("QBDD") methods? (Default is "false"; note that QBDD is CPU-only)
133
+ isBinaryDecisionTree = False
134
+ # Use GPU acceleration? (Default is "true")
135
+ isOpenCL = True
136
+ # Use multi-GPU (or "multi-page") acceleration? (Default is "false")
137
+ isPaged = True
138
+ # Use CPU/GPU method hybridization? (Default is "false")
139
+ isCpuGpuHybrid = True
140
+ # Allocate GPU buffer from general host heap? (Default is "false"; "true" might improve performance or reliability in certain cases, like if using an Intel HD as accelerator)
141
+ isHostPointer = True if os.environ.get("PYQRACK_HOST_POINTER_DEFAULT_ON") else False
142
+ # Noise parameter. (Default is "0"; depolarizing noise intensity can also be controlled by "QRACK_GATE_DEPOLARIZATION" environment variable)
143
+ noise = 0
144
+ # How many full simulation columns, between border columns
145
+ long_range_columns=4
146
+ # How many full simulation rows, between border rows
147
+ long_range_rows=4
148
+ # Whether to transpose rows and columns
149
+ is_transpose=False
150
+
151
+ def __init__(self, wires=0, shots=None, **kwargs):
152
+ options = dict(kwargs)
153
+ if "isStabilizerHybrid" in options:
154
+ self.isStabilizerHybrid = options["isStabilizerHybrid"]
155
+ if "isTensorNetwork" in options:
156
+ self.isTensorNetwork = options["isTensorNetwork"]
157
+ if "isSchmidtDecompose" in options:
158
+ self.isSchmidtDecompose = options["isSchmidtDecompose"]
159
+ if "isBinaryDecisionTree" in options:
160
+ self.isBinaryDecisionTree = options["isBinaryDecisionTree"]
161
+ if "isOpenCL" in options:
162
+ self.isOpenCL = options["isOpenCL"]
163
+ if "isPaged" in options:
164
+ self.isPaged = options["isPaged"]
165
+ if "isCpuGpuHybrid" in options:
166
+ self.isCpuGpuHybrid = options["isCpuGpuHybrid"]
167
+ if "isHostPointer" in options:
168
+ self.isHostPointer = options["isHostPointer"]
169
+ if "noise" in options:
170
+ self.noise = options["noise"]
171
+ if (self.noise != 0) and (shots is None):
172
+ raise ValueError("Shots must be finite for noisy simulation (not analytical mode).")
173
+ if "long_range_columns" in options:
174
+ self.long_range_columns = options["long_range_columns"]
175
+ if "long_range_rows" in options:
176
+ self.long_range_rows = options["long_range_rows"]
177
+ if "is_transpose" in options:
178
+ self.is_transpose = options["is_transpose"]
179
+
180
+ super().__init__(wires=wires, shots=shots)
181
+ self.shots = shots
182
+ self._state = QrackAceBackend(
183
+ self.num_wires,
184
+ long_range_columns=self.long_range_columns,
185
+ long_range_rows=self.long_range_rows,
186
+ is_transpose=self.is_transpose,
187
+ isStabilizerHybrid=self.isStabilizerHybrid,
188
+ isTensorNetwork=self.isTensorNetwork,
189
+ isSchmidtDecompose=self.isSchmidtDecompose,
190
+ isBinaryDecisionTree=self.isBinaryDecisionTree,
191
+ isOpenCL=self.isOpenCL,
192
+ isCpuGpuHybrid=self.isCpuGpuHybrid,
193
+ isHostPointer=self.isHostPointer,
194
+ noise=self.noise,
195
+ )
196
+ self.device_kwargs = {
197
+ "long_range_columns": self.long_range_columns,
198
+ "long_range_rows": self.long_range_rows,
199
+ "is_transpose": self.is_transpose,
200
+ "is_hybrid_stabilizer": self.isStabilizerHybrid,
201
+ "is_tensor_network": self.isTensorNetwork,
202
+ "is_schmidt_decompose": self.isSchmidtDecompose,
203
+ "is_schmidt_decompose_parallel": self.isSchmidtDecomposeMulti,
204
+ "is_qpdd": self.isBinaryDecisionTree,
205
+ "is_gpu": self.isOpenCL,
206
+ "is_paged": self.isPaged,
207
+ "is_hybrid_cpu_gpu": self.isCpuGpuHybrid,
208
+ "is_host_pointer": self.isHostPointer,
209
+ "noise": self.noise,
210
+ }
211
+ self._circuit = []
212
+
213
+ def _reverse_state(self):
214
+ end = self.num_wires - 1
215
+ mid = self.num_wires >> 1
216
+ for i in range(mid):
217
+ self._state.swap(i, end - i)
218
+
219
+ def apply(self, operations, **kwargs):
220
+ """Apply the circuit operations to the state.
221
+
222
+ This method serves as an auxiliary method to :meth:`~.QrackDevice.apply`.
223
+
224
+ Args:
225
+ operations (List[pennylane.Operation]): operations to be applied
226
+ """
227
+
228
+ self._circuit = self._circuit + operations
229
+ if self.noise == 0:
230
+ self._apply()
231
+ self._circuit = []
232
+ # else: Defer application until shots or expectation values are requested
233
+
234
+ def _apply(self):
235
+ for op in self._circuit:
236
+ if isinstance(op, BasisState):
237
+ self._apply_basis_state(op)
238
+ else:
239
+ self._apply_gate(op)
240
+
241
+ def _apply_basis_state(self, op):
242
+ """Initialize a basis state"""
243
+ wires = self.map_wires(Wires(op.wires))
244
+ par = op.parameters[0]
245
+ wire_count = len(wires)
246
+ n_basis_state = len(par)
247
+
248
+ if not set(par).issubset({0, 1}):
249
+ raise ValueError("BasisState parameter must consist of 0 or 1 integers.")
250
+ if n_basis_state != wire_count:
251
+ raise ValueError("BasisState parameter and wires must be of equal length.")
252
+
253
+ for i in range(wire_count):
254
+ index = wires.labels[i]
255
+ if par[i] != self._state.m(index):
256
+ self._state.x(index)
257
+
258
+ def _apply_gate(self, op):
259
+ """Apply native qrack gate"""
260
+
261
+ opname = op.name
262
+ if isinstance(op, Adjoint):
263
+ op = op.base
264
+ opname = op.name + ".inv"
265
+
266
+ par = op.parameters
267
+
268
+ if opname == "MultiRZ":
269
+ device_wires = self.map_wires(op.wires)
270
+ for q in device_wires:
271
+ self._state.r(Pauli.PauliZ, par[0], q)
272
+ return
273
+
274
+ # translate op wire labels to consecutive wire labels used by the device
275
+ device_wires = self.map_wires(
276
+ (op.control_wires + op.wires) if op.control_wires else op.wires
277
+ )
278
+
279
+ if opname in [
280
+ "".join(p)
281
+ for p in it.product(
282
+ [
283
+ "CNOT",
284
+ "C(PauliX)",
285
+ ],
286
+ ["", ".inv"],
287
+ )
288
+ ]:
289
+ self._state.mcx(device_wires.labels[:-1], device_wires.labels[-1])
290
+ elif opname in ["C(PauliY)", "C(PauliY).inv"]:
291
+ self._state.mcy(device_wires.labels[:-1], device_wires.labels[-1])
292
+ elif opname in ["C(PauliZ)", "C(PauliZ).inv"]:
293
+ self._state.mcz(device_wires.labels[:-1], device_wires.labels[-1])
294
+ elif opname in ["SWAP", "SWAP.inv"]:
295
+ self._state.swap(device_wires.labels[0], device_wires.labels[1])
296
+ elif opname == "ISWAP":
297
+ self._state.iswap(device_wires.labels[0], device_wires.labels[1])
298
+ elif opname == "ISWAP.inv":
299
+ self._state.adjiswap(device_wires.labels[0], device_wires.labels[1])
300
+ elif opname in ["CY", "CY.inv", "C(CY)", "C(CY).inv"]:
301
+ self._state.mcy(device_wires.labels[:-1], device_wires.labels[-1])
302
+ elif opname in ["CZ", "CZ.inv", "C(CZ)", "C(CZ).inv"]:
303
+ self._state.mcz(device_wires.labels[:-1], device_wires.labels[-1])
304
+ elif opname == "S":
305
+ for label in device_wires.labels:
306
+ self._state.s(label)
307
+ elif opname == "S.inv":
308
+ for label in device_wires.labels:
309
+ self._state.adjs(label)
310
+ elif opname == "T":
311
+ for label in device_wires.labels:
312
+ self._state.t(label)
313
+ elif opname == "T.inv":
314
+ for label in device_wires.labels:
315
+ self._state.adjt(label)
316
+ elif opname == "RX":
317
+ for label in device_wires.labels:
318
+ self._state.r(Pauli.PauliX, par[0], label)
319
+ elif opname == "RX.inv":
320
+ for label in device_wires.labels:
321
+ self._state.r(Pauli.PauliX, -par[0], label)
322
+ elif opname == "RY":
323
+ for label in device_wires.labels:
324
+ self._state.r(Pauli.PauliY, par[0], label)
325
+ elif opname == "RY.inv":
326
+ for label in device_wires.labels:
327
+ self._state.r(Pauli.PauliY, -par[0], label)
328
+ elif opname == "RZ":
329
+ for label in device_wires.labels:
330
+ self._state.r(Pauli.PauliZ, par[0], label)
331
+ elif opname == "RZ.inv":
332
+ for label in device_wires.labels:
333
+ self._state.r(Pauli.PauliZ, -par[0], label)
334
+ elif opname in ["PauliX", "PauliX.inv"]:
335
+ for label in device_wires.labels:
336
+ self._state.x(label)
337
+ elif opname in ["PauliY", "PauliY.inv"]:
338
+ for label in device_wires.labels:
339
+ self._state.y(label)
340
+ elif opname in ["PauliZ", "PauliZ.inv"]:
341
+ for label in device_wires.labels:
342
+ self._state.z(label)
343
+ elif opname in ["Hadamard", "Hadamard.inv"]:
344
+ for label in device_wires.labels:
345
+ self._state.h(label)
346
+ elif opname == "SX":
347
+ half_pi = math.pi / 2
348
+ for label in device_wires.labels:
349
+ self._state.u(label, half_pi, -half_pi, half.pi)
350
+ elif opname == "SX.inv":
351
+ half_pi = math.pi / 2
352
+ for label in device_wires.labels:
353
+ self._state.u(label, -half_pi, -half.pi, half_pi)
354
+ elif opname == "PhaseShift":
355
+ half_par = par[0] / 2
356
+ for label in device_wires.labels:
357
+ self._state.u(label, 0, half_par, half_par)
358
+ elif opname == "PhaseShift.inv":
359
+ half_par = par[0] / 2
360
+ for label in device_wires.labels:
361
+ self._state.u(label, 0, -half_par, -half_par)
362
+ elif opname == "U3":
363
+ for label in device_wires.labels:
364
+ self._state.u(label, par[0], par[1], par[2])
365
+ elif opname == "U3.inv":
366
+ for label in device_wires.labels:
367
+ self._state.u(label, -par[0], -par[2], -par[1])
368
+ elif opname == "Rot":
369
+ for label in device_wires.labels:
370
+ self._state.r(Pauli.PauliZ, par[0], label)
371
+ self._state.r(Pauli.PauliY, par[1], label)
372
+ self._state.r(Pauli.PauliZ, par[2], label)
373
+ elif opname == "Rot.inv":
374
+ for label in device_wires.labels:
375
+ self._state.r(Pauli.PauliZ, -par[2], label)
376
+ self._state.r(Pauli.PauliY, -par[1], label)
377
+ self._state.r(Pauli.PauliZ, -par[0], label)
378
+ elif opname not in [
379
+ "Identity",
380
+ "Identity.inv",
381
+ "C(Identity)",
382
+ "C(Identity).inv",
383
+ ]:
384
+ raise DeviceError(f"Operation {opname} is not supported on a {self.short_name} device.")
385
+
386
+ def expval(self, observable, **kwargs):
387
+ if self.shots is None:
388
+ if isinstance(observable.name, list):
389
+ b = [self._observable_map[obs] for obs in observable.name]
390
+ elif observable.name == "Prod":
391
+ b = [self._observable_map[obs.name] for obs in observable.operands]
392
+ else:
393
+ b = [self._observable_map[observable.name]]
394
+
395
+ # exact expectation value
396
+ if callable(observable.eigvals):
397
+ eigvals = self._asarray(observable.eigvals(), dtype=self.R_DTYPE)
398
+ else: # older version of pennylane
399
+ eigvals = self._asarray(observable.eigvals, dtype=self.R_DTYPE)
400
+ prob = self.probability(wires=observable.wires)
401
+ return self._dot(eigvals, prob)
402
+
403
+ # estimate the ev
404
+ return np.mean(self.sample(observable))
405
+
406
+ def _generate_sample(self):
407
+ rev_sample = self._state.m_all()
408
+ sample = 0
409
+ for i in range(self.num_wires):
410
+ if (rev_sample & (1 << i)) > 0:
411
+ sample |= 1 << (self.num_wires - (i + 1))
412
+ return sample
413
+
414
+ def generate_samples(self):
415
+ if self.shots is None:
416
+ raise QuantumFunctionError(
417
+ "The number of shots has to be explicitly set on the device "
418
+ "when using sample-based measurements."
419
+ )
420
+
421
+ if self.noise != 0:
422
+ samples = []
423
+ for _ in range(self.shots):
424
+ self._state.reset_all()
425
+ self._apply()
426
+ samples.append(self._generate_sample())
427
+ self._samples = QubitDevice.states_to_binary(np.array(samples), self.num_wires)
428
+ self._circuit = []
429
+
430
+ return self._samples
431
+
432
+ if self.shots == 1:
433
+ self._samples = QubitDevice.states_to_binary(
434
+ np.array([self._generate_sample()]), self.num_wires
435
+ )
436
+
437
+ return self._samples
438
+
439
+ samples = np.array(
440
+ self._state.measure_shots(list(range(self.num_wires - 1, -1, -1)), self.shots)
441
+ )
442
+ self._samples = QubitDevice.states_to_binary(samples, self.num_wires)
443
+
444
+ return self._samples
445
+
446
+ def reset(self):
447
+ for i in range(self.num_wires):
448
+ if self._state.m(i):
449
+ self._state.x(i)
@@ -23,7 +23,15 @@ import itertools as it
23
23
 
24
24
  import numpy as np
25
25
 
26
- from pennylane import DeviceError, QuantumFunctionError
26
+ # PennyLane v0.42 introduced the `exceptions` module and will raise
27
+ # deprecation warnings if they are imported from the top-level module.
28
+
29
+ # This ensures backwards compatibility with older versions of PennyLane.
30
+ try:
31
+ from pennylane.exceptions import DeviceError, QuantumFunctionError
32
+ except (ModuleNotFoundError, ImportError) as import_error:
33
+ from pennylane import DeviceError, QuantumFunctionError
34
+
27
35
  from pennylane.devices import QubitDevice
28
36
  from pennylane.ops import (
29
37
  StatePrep,
@@ -159,7 +167,7 @@ class QrackDevice(QubitDevice):
159
167
  # Use CPU/GPU method hybridization? (Default is "false")
160
168
  isCpuGpuHybrid = True
161
169
  # Allocate GPU buffer from general host heap? (Default is "false"; "true" might improve performance or reliability in certain cases, like if using an Intel HD as accelerator)
162
- isHostPointer = True if os.environ.get('PYQRACK_HOST_POINTER_DEFAULT_ON') else False
170
+ isHostPointer = True if os.environ.get("PYQRACK_HOST_POINTER_DEFAULT_ON") else False
163
171
  # Noise parameter. (Default is "0"; depolarizing noise intensity can also be controlled by "QRACK_GATE_DEPOLARIZATION" environment variable)
164
172
  noise = 0
165
173
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pennylane-qrack
3
- Version: 0.18.8
3
+ Version: 0.20.0
4
4
  Summary: PennyLane plugin for Qrack.
5
5
  Home-page: http://github.com/vm6502q
6
6
  Maintainer: vm6502q
@@ -48,7 +48,7 @@ PennyLane-Qrack Plugin
48
48
 
49
49
  The PennyLane-Qrack plugin integrates the Qrack quantum computing framework with PennyLane's quantum machine learning capabilities.
50
50
 
51
- **Performance can benefit greatly from following the [Qrack repository "Quick Start" and "Power user considerations."](https://github.com/unitaryfund/qrack/blob/main/README.md#quick-start)**
51
+ Performance can benefit greatly from following the `Qrack repository "Quick Start" and "Power user considerations." <https://github.com/unitaryfund/qrack/blob/main/README.md#quick-start>`__
52
52
 
53
53
  This plugin is addapted from the `PennyLane-Qulacs plugin, <https://github.com/PennyLaneAI/pennylane-qulacs>`__ under the Apache License 2.0, with many thanks to the original developers!
54
54
 
@@ -0,0 +1,17 @@
1
+ pennylane_qrack/CMakeCache.txt,sha256=3aPN0Pdw_wCTy1lpTx_patJBKP59h9wpPi5YHzX3p04,15285
2
+ pennylane_qrack/Makefile,sha256=HMf2JV8WoMeW-rN8dAbzA3ssXMIzvgCPyJO-NvdJwPw,7618
3
+ pennylane_qrack/QrackAceDeviceConfig.toml,sha256=26At_9dsy_5bNe-rdW24BgQfWq8H5r8kf88oKLIma-c,5473
4
+ pennylane_qrack/QrackDeviceConfig.toml,sha256=qLzlakUAXGwz0ijRrsMZ9R0YLH7c43tjWAaoKzyALEY,4503
5
+ pennylane_qrack/__init__.py,sha256=_g4NKu07_pXqxvQaxjdAPe769S5tWwYjqyHi3z7YKHc,673
6
+ pennylane_qrack/_version.py,sha256=Ve10a6bX4Wzod0cprKE2Y8oJgYTpUJTknN_3Q1cTiuI,689
7
+ pennylane_qrack/cmake_install.cmake,sha256=ZhG9tI7bh8oZnfUnP0eAVtodPUizqINLahqbb_TXwxY,3108
8
+ pennylane_qrack/libqrack_device.dylib,sha256=JrpMKBDmu8fXuEhQno7B24IbCajM7fRDy32qIEjksTg,3299064
9
+ pennylane_qrack/qrack_ace_device.py,sha256=PpwloyAW7z0jyYBQH3FX8Z6ZtXKEajV0QJtiZ6ai228,16906
10
+ pennylane_qrack/qrack_device.cpp,sha256=0Dbey1g3DQeWYrzS9622Y7QDhizISuII49XLuv9xFIY,38115
11
+ pennylane_qrack/qrack_device.py,sha256=kefy76z8z9EQ6Z4gkNUxZXzOXNaQKUBetKPUO2RGsig,28236
12
+ pennylane_qrack-0.20.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
13
+ pennylane_qrack-0.20.0.dist-info/METADATA,sha256=ZLuJA81dxMjUuiaV7L5nZSFQKhtTh_93YSRqRrgKRv4,5955
14
+ pennylane_qrack-0.20.0.dist-info/WHEEL,sha256=97pmOSfusofyzGlW1jJA8mX_ciF6NJq3BQs-Zshjrk4,105
15
+ pennylane_qrack-0.20.0.dist-info/entry_points.txt,sha256=OrkJ6JVk-yndlQjqc-8dm8PxE-jNoNQRFXFeUBxVuCg,139
16
+ pennylane_qrack-0.20.0.dist-info/top_level.txt,sha256=5NFMNHqCHtVLwNkLg66xz846uUJAlnOJ5VGa6ulW1ow,16
17
+ pennylane_qrack-0.20.0.dist-info/RECORD,,
@@ -1,2 +1,3 @@
1
1
  [pennylane.plugins]
2
+ qrack.ace = pennylane_qrack.qrack_ace_device:QrackAceDevice
2
3
  qrack.simulator = pennylane_qrack.qrack_device:QrackDevice
@@ -1,15 +0,0 @@
1
- pennylane_qrack/CMakeCache.txt,sha256=3xpwB-OnOUg2Qneuo0p5nGMzhZWITCLvFQWeF4G_0x4,15285
2
- pennylane_qrack/Makefile,sha256=HMf2JV8WoMeW-rN8dAbzA3ssXMIzvgCPyJO-NvdJwPw,7618
3
- pennylane_qrack/QrackDeviceConfig.toml,sha256=oR9-dIAP6BzP3e2QSLroacaloHZsx7iJiKE6w7LGxUo,5459
4
- pennylane_qrack/__init__.py,sha256=_g4NKu07_pXqxvQaxjdAPe769S5tWwYjqyHi3z7YKHc,673
5
- pennylane_qrack/_version.py,sha256=CUwWqG7uJfyKzx_FpP5E0nFtiqwUh8Xm2K9mXegjgBE,692
6
- pennylane_qrack/cmake_install.cmake,sha256=ZhG9tI7bh8oZnfUnP0eAVtodPUizqINLahqbb_TXwxY,3108
7
- pennylane_qrack/libqrack_device.dylib,sha256=JrpMKBDmu8fXuEhQno7B24IbCajM7fRDy32qIEjksTg,3299064
8
- pennylane_qrack/qrack_device.cpp,sha256=0Dbey1g3DQeWYrzS9622Y7QDhizISuII49XLuv9xFIY,38115
9
- pennylane_qrack/qrack_device.py,sha256=DEiYy1eJQumWRIiNgxRWqc4YOYS1f85O2Jio7lWPuV8,27883
10
- pennylane_qrack-0.18.8.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
11
- pennylane_qrack-0.18.8.dist-info/METADATA,sha256=LaUqtyudUn67o3MWqvNLOfXlsz9F6oKADnZqNj2vO6s,5956
12
- pennylane_qrack-0.18.8.dist-info/WHEEL,sha256=97pmOSfusofyzGlW1jJA8mX_ciF6NJq3BQs-Zshjrk4,105
13
- pennylane_qrack-0.18.8.dist-info/entry_points.txt,sha256=V6f1sN6IZZZaEvxrI47A3K_kksp8fDUWjLWD0Met7Ww,79
14
- pennylane_qrack-0.18.8.dist-info/top_level.txt,sha256=5NFMNHqCHtVLwNkLg66xz846uUJAlnOJ5VGa6ulW1ow,16
15
- pennylane_qrack-0.18.8.dist-info/RECORD,,