Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[new opmath 1] Toggle __use_new_opmath #5269

Merged
merged 67 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
fc0eb52
toggle __use_new_opmath
Qottmann Feb 27, 2024
6406a46
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
Qottmann Mar 4, 2024
b178ee3
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
Qottmann Mar 5, 2024
4900f54
update pauli arithmetic tests to pass
Qottmann Mar 5, 2024
2bc5936
black formatting
Qottmann Mar 5, 2024
9008e4c
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
Qottmann Mar 7, 2024
efb065f
[ci skip]
Qottmann Mar 7, 2024
b7e4278
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
Qottmann Mar 8, 2024
d58da38
[ci skip]
Qottmann Mar 8, 2024
6b499fb
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
Qottmann Mar 8, 2024
4c03020
[ci skip]
Qottmann Mar 8, 2024
a6af70b
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
Qottmann Mar 11, 2024
8554984
[ci skip]
Qottmann Mar 11, 2024
10a57da
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
Qottmann Mar 12, 2024
d604f8c
[ci skip]
Qottmann Mar 12, 2024
81fefca
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
Qottmann Mar 13, 2024
9e4bfb7
[ci skip]
Qottmann Mar 13, 2024
f4ee9fa
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
Qottmann Mar 14, 2024
4eefc86
[ci skip]
Qottmann Mar 14, 2024
5b25192
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
Qottmann Mar 15, 2024
d93a835
[ci skip]
Qottmann Mar 15, 2024
e8064eb
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
Qottmann Mar 15, 2024
e4435ce
[ci skip]
Qottmann Mar 15, 2024
f2b4555
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
Qottmann Mar 15, 2024
12a42f4
[ci skip]
Qottmann Mar 15, 2024
24e576a
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
Qottmann Mar 18, 2024
9422bad
[ci skip]
Qottmann Mar 18, 2024
79321c5
Merge branch 'master' into enable_new_opmath
Qottmann Mar 20, 2024
6238f1e
[ci skip]
Qottmann Mar 20, 2024
329cae4
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
Qottmann Mar 21, 2024
43434f6
[ci skip]
Qottmann Mar 21, 2024
393aa10
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
Qottmann Mar 22, 2024
4baebde
[ci skip]
Qottmann Mar 22, 2024
0131ec0
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane int…
Qottmann Mar 23, 2024
aaa07da
[ci skip]
Qottmann Mar 23, 2024
7343038
[new opmath 2] New `LinearCombination` class to succeed `qml.Hamilton…
Qottmann Mar 25, 2024
230acb5
pauli/conversion coverage
Qottmann Mar 25, 2024
dab69ed
legacy DQ coverage with Hamiltonians
Qottmann Mar 25, 2024
fdbbd30
linear combination coverage
Qottmann Mar 25, 2024
c0045a7
linear combination coverage
Qottmann Mar 25, 2024
ac269e0
black formatting
Qottmann Mar 25, 2024
bcd1d0c
Merge branch 'master' into enable_new_opmath
Qottmann Mar 25, 2024
84516ee
Merge branch 'master' into enable_new_opmath
Qottmann Mar 25, 2024
a1fbbb6
operation coverage
Qottmann Mar 25, 2024
e3ceca5
tests for coverage
Qottmann Mar 25, 2024
76a1fd6
black formatting
Qottmann Mar 25, 2024
287c9d8
Merge branch 'enable_new_opmath' of https://github.com/PennyLaneAI/pe…
Qottmann Mar 25, 2024
30ed7f7
pylint
Qottmann Mar 25, 2024
be79409
make pylint happy
astralcai Mar 25, 2024
f96a73c
parameter shift coverage
Qottmann Mar 25, 2024
f2518df
parameter shift coverage
Qottmann Mar 25, 2024
3fc66ac
black formatting
Qottmann Mar 25, 2024
9b49a7f
adjoint matrix hamiltonian
Qottmann Mar 25, 2024
c2659c9
black formatting
Qottmann Mar 25, 2024
57c75af
merge
Qottmann Mar 25, 2024
3ee65af
add coverage to symbolic op matrix with legacy H as base
astralcai Mar 25, 2024
bbd565c
Merge branch 'master' into enable_new_opmath
astralcai Mar 25, 2024
875dcf8
trigger-ci
astralcai Mar 25, 2024
da40e05
trigger
Qottmann Mar 25, 2024
631a1e5
adding coverage for grouping module
albi3ro Mar 25, 2024
ffe44cc
parameter shift coverage
astralcai Mar 25, 2024
38032a7
adding more test coverage
albi3ro Mar 25, 2024
36e855b
coverage for exp and default qubit legacy
astralcai Mar 25, 2024
8898cc7
trigger ci
albi3ro Mar 25, 2024
3cf8ad5
remove duplicate code
albi3ro Mar 25, 2024
6f47d72
coverage for conversion and default qubit legacy
astralcai Mar 25, 2024
0596287
Fix test case
astralcai Mar 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions doc/development/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,20 @@ Pending deprecations

- Added and deprecated for ``Sum`` and ``Prod`` instances in v0.35

* Accessing ``qml.ops.Hamiltonian`` with new operator arithmetic enabled is deprecated. Using ``qml.Hamiltonian``
with new operator arithmetic enabled now returns a ``LinearCombination`` instance. Some functionality
may not work as expected, and use of the Hamiltonian class with the new operator arithmetic will not
be supported in future releases of PennyLane.

You can update your code to the new operator arithmetic by using ``qml.Hamiltonian`` instead of importing
the Hamiltonian class directly or via ``qml.ops.Hamiltonian``. When the new operator arithmetic is enabled,
``qml.Hamiltonian`` will access the new corresponding implementation.

Alternatively, to continue accessing the legacy functionality, you can use
``qml.operation.disable_new_opmath()``.

- Deprecated in v0.36

Completed deprecation cycles
----------------------------

Expand Down
33 changes: 31 additions & 2 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@
* Added new function `qml.operation.convert_to_legacy_H` to convert `Sum`, `SProd`, and `Prod` to `Hamiltonian` instances.
[(#5309)](https://github.com/PennyLaneAI/pennylane/pull/5309)

<h3>Improvements 🛠</h3>

* The `qml.is_commuting` function now accepts `Sum`, `SProd`, and `Prod` instances.
[(#5351)](https://github.com/PennyLaneAI/pennylane/pull/5351)

* Operators can now be left multiplied `x * op` by numpy arrays.
[(#5361)](https://github.com/PennyLaneAI/pennylane/pull/5361)

* Create the `qml.Reflection` operator, useful for amplitude amplification and its variants.
[(#5159)](https://github.com/PennyLaneAI/pennylane/pull/5159)

Expand Down Expand Up @@ -123,6 +131,10 @@

```

* A new class `qml.ops.LinearCombination` is introduced. In essence, this class is an updated equivalent of `qml.ops.Hamiltonian`
but for usage with new operator arithmetic.
[(#5216)](https://github.com/PennyLaneAI/pennylane/pull/5216)

* The `qml.TrotterProduct` operator now supports error estimation functionality.
[(#5384)](https://github.com/PennyLaneAI/pennylane/pull/5384)

Expand All @@ -147,9 +159,14 @@
* The `molecular_hamiltonian` function calls `PySCF` directly when `method='pyscf'` is selected.
[(#5118)](https://github.com/PennyLaneAI/pennylane/pull/5118)

* All generators in the source code (except those in the `qchem` module) no longer return
`Hamiltonian` or `Tensor` instances. Wherever possible, these return `Sum`, `SProd`, and `Prod` instances.
* The generators in the source code return operators consistent with the global setting for
`qml.operator.active_new_opmath()` wherever possible. `Sum`, `SProd` and `Prod` instances
will be returned even after disabling the new operator arithmetic in cases where they offer
additional functionality not available using legacy operators.
[(#5253)](https://github.com/PennyLaneAI/pennylane/pull/5253)
[(#5410)](https://github.com/PennyLaneAI/pennylane/pull/5410)
[(#5411)](https://github.com/PennyLaneAI/pennylane/pull/5411)
[(#5421)](https://github.com/PennyLaneAI/pennylane/pull/5421)

* Upgraded `null.qubit` to the new device API. Also, added support for all measurements and various modes of differentiation.
[(#5211)](https://github.com/PennyLaneAI/pennylane/pull/5211)
Expand All @@ -160,6 +177,9 @@
* `Hamiltonian.pauli_rep` is now defined if the hamiltonian is a linear combination of paulis.
[(#5377)](https://github.com/PennyLaneAI/pennylane/pull/5377)

* `Prod.eigvals()` is now compatible with Qudit operators.
[(#5400)](https://github.com/PennyLaneAI/pennylane/pull/5400)

* Obtaining classical shadows using the `default.clifford` device is now compatible with
[stim](https://github.com/quantumlib/Stim) `v1.13.0`.
[(#5409)](https://github.com/PennyLaneAI/pennylane/pull/5409)
Expand Down Expand Up @@ -230,6 +250,10 @@
* Attempting to multiply `PauliWord` and `PauliSentence` with `*` will raise an error. Instead, use `@` to conform with the PennyLane convention.
[(#5341)](https://github.com/PennyLaneAI/pennylane/pull/5341)

* When new operator arithmetic is enabled, `qml.Hamiltonian` is now an alias for `qml.ops.LinearCombination`.
`Hamiltonian` will still be accessible as `qml.ops.Hamiltonian`.
[(#5393)](https://github.com/PennyLaneAI/pennylane/pull/5393)

* Since `default.mixed` does not support snapshots with measurements, attempting to do so will result in a `DeviceError` instead of getting the density matrix.
[(#5416)](https://github.com/PennyLaneAI/pennylane/pull/5416)

Expand All @@ -249,6 +273,11 @@
... circuit = qml.from_qasm(f.read())
```

* Accessing `qml.ops.Hamiltonian` with new operator arithmetic is deprecated. Using `qml.Hamiltonian` with new operator arithmetic enabled now
returns a `LinearCombination` instance. Some functionality may not work as expected. To continue using the `Hamiltonian` class, you can use
`qml.operation.disable_new_opmath()` to disable the new operator arithmetic.
[(#5393)](https://github.com/PennyLaneAI/pennylane/pull/5393)

<h3>Documentation 📝</h3>

* Removed some redundant documentation for the `evolve` function.
Expand Down
12 changes: 12 additions & 0 deletions pennylane/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,18 @@ class PennyLaneDeprecationWarning(UserWarning):
"""Warning raised when a PennyLane feature is being deprecated."""


del globals()["Hamiltonian"]


def __getattr__(name):
if name == "Hamiltonian":
if pennylane.operation.active_new_opmath():
return pennylane.ops.LinearCombination
return pennylane.ops.Hamiltonian

raise AttributeError(f"module 'pennylane' has no attribute '{name}'")


def _get_device_entrypoints():
"""Returns a dictionary mapping the device short name to the
loadable entrypoint"""
Expand Down
12 changes: 7 additions & 5 deletions pennylane/_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
)

from pennylane.operation import Observable, Operation, Tensor, Operator, StatePrepBase
from pennylane.ops import Hamiltonian, Sum
from pennylane.ops import Hamiltonian, Sum, LinearCombination
from pennylane.tape import QuantumScript, QuantumTape, expand_tape_state_prep
from pennylane.wires import WireError, Wires
from pennylane.queuing import QueuingManager
Expand Down Expand Up @@ -678,9 +678,8 @@ def default_expand_fn(self, circuit, max_expansion=10):
)
obs_on_same_wire = len(circuit._obs_sharing_wires) > 0 or comp_basis_sampled_multi_measure
obs_on_same_wire &= not any(
isinstance(o, qml.Hamiltonian) for o in circuit._obs_sharing_wires
isinstance(o, (Hamiltonian, LinearCombination)) for o in circuit._obs_sharing_wires
)

ops_not_supported = not all(self.stopping_condition(op) for op in circuit.operations)

if obs_on_same_wire:
Expand Down Expand Up @@ -745,17 +744,20 @@ def batch_transform(self, circuit: QuantumTape):
to be applied to the list of evaluated circuit results.
"""
supports_hamiltonian = self.supports_observable("Hamiltonian")

supports_sum = self.supports_observable("Sum")
finite_shots = self.shots is not None
grouping_known = all(
obs.grouping_indices is not None
for obs in circuit.observables
if isinstance(obs, Hamiltonian)
if isinstance(obs, (Hamiltonian, LinearCombination))
)
# device property present in braket plugin
use_grouping = getattr(self, "use_grouping", True)

hamiltonian_in_obs = any(isinstance(obs, Hamiltonian) for obs in circuit.observables)
hamiltonian_in_obs = any(
isinstance(obs, (Hamiltonian, LinearCombination)) for obs in circuit.observables
)
expval_sum_in_obs = any(
isinstance(m.obs, Sum) and isinstance(m, ExpectationMP) for m in circuit.measurements
)
Expand Down
2 changes: 1 addition & 1 deletion pennylane/_qubit_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -1631,7 +1631,7 @@ def adjoint_jacobian(
f" measurement {m.__class__.__name__}"
)

if m.obs.name == "Hamiltonian":
if not m.obs.has_matrix:
raise qml.QuantumFunctionError(
"Adjoint differentiation method does not support Hamiltonian observables."
)
Expand Down
32 changes: 28 additions & 4 deletions pennylane/data/attributes/operator/operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,13 @@ def consumes_types(cls) -> FrozenSet[Type[Operator]]:
qml.QubitCarry,
qml.QubitSum,
# pennylane/ops/qubit/hamiltonian.py
qml.Hamiltonian,
qml.ops.Hamiltonian,
# pennylane/ops/op_math/linear_combination.py
qml.ops.LinearCombination,
# pennylane/ops/op_math - prod.py, s_prod.py, sum.py
qml.ops.Prod,
qml.ops.SProd,
qml.ops.Sum,
# pennylane/ops/qubit/matrix_qml.py
qml.QubitUnitary,
qml.DiagonalQubitUnitary,
Expand Down Expand Up @@ -206,6 +212,8 @@ def _ops_to_hdf5(
op_class_names = []
for i, op in enumerate(value):
op_key = f"op_{i}"
if isinstance(op, (qml.ops.Prod, qml.ops.SProd, qml.ops.Sum)):
op = op.simplify()
if type(op) not in self.consumes_types():
raise TypeError(
f"Serialization of operator type '{type(op).__name__}' is not supported."
Expand All @@ -214,11 +222,19 @@ def _ops_to_hdf5(
if isinstance(op, Tensor):
self._ops_to_hdf5(bind, op_key, op.obs)
op_wire_labels.append("null")
elif isinstance(op, qml.Hamiltonian):
elif isinstance(op, (qml.ops.Hamiltonian, qml.ops.LinearCombination)):
coeffs, ops = op.terms()
ham_grp = self._ops_to_hdf5(bind, op_key, ops)
ham_grp["hamiltonian_coeffs"] = coeffs
op_wire_labels.append("null")
elif isinstance(op, (qml.ops.Prod, qml.ops.Sum)):
self._ops_to_hdf5(bind, op_key, op.operands)
op_wire_labels.append("null")
elif isinstance(op, qml.ops.SProd):
coeffs, ops = op.terms()
sprod_grp = self._ops_to_hdf5(bind, op_key, ops)
sprod_grp["sprod_scalar"] = coeffs
op_wire_labels.append("null")
else:
bind[op_key] = op.data if len(op.data) else h5py.Empty("f")
op_wire_labels.append(wires_to_json(op.wires))
Expand All @@ -238,21 +254,29 @@ def _hdf5_to_ops(self, bind: HDF5Group) -> List[Operator]:
wires_bind = bind["op_wire_labels"]
op_class_names = [] if names_bind.shape == (0,) else names_bind.asstr()
op_wire_labels = [] if wires_bind.shape == (0,) else wires_bind.asstr()

with qml.QueuingManager.stop_recording():
for i, op_class_name in enumerate(op_class_names):
op_key = f"op_{i}"

op_cls = self._supported_ops_dict()[op_class_name]
if op_cls is Tensor:
ops.append(Tensor(*self._hdf5_to_ops(bind[op_key])))
elif op_cls is qml.Hamiltonian:
elif op_cls in (qml.ops.Hamiltonian, qml.ops.LinearCombination):
ops.append(
qml.Hamiltonian(
coeffs=list(bind[op_key]["hamiltonian_coeffs"]),
observables=self._hdf5_to_ops(bind[op_key]),
)
)
elif op_cls in (qml.ops.Prod, qml.ops.Sum):
ops.append(op_cls(*self._hdf5_to_ops(bind[op_key])))
elif op_cls is qml.ops.SProd:
ops.append(
qml.ops.s_prod(
scalar=bind[op_key]["sprod_scalar"][0],
operator=self._hdf5_to_ops(bind[op_key])[0],
)
)
else:
wire_labels = json.loads(op_wire_labels[i])
op_data = bind[op_key]
Expand Down
7 changes: 4 additions & 3 deletions pennylane/devices/default_clifford.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"Identity",
"Projector",
"Hamiltonian",
"LinearCombination",
"Sum",
"SProd",
"Prod",
Expand Down Expand Up @@ -1017,9 +1018,9 @@ def _measure_single_sample(stim_ct, meas_ops, meas_idx, meas_wire):
"""Sample a single qubit Pauli measurement from a stim circuit"""
stim_sm = stim.TableauSimulator()
stim_sm.do_circuit(stim_ct)
return stim_sm.measure_observable(
stim.PauliString([0] * meas_idx + meas_ops + [0] * (meas_wire - meas_idx - 1))
)
res = [0] * meas_idx + meas_ops + [0] * (meas_wire - meas_idx - 1)
res = [int(r) for r in res]
return stim_sm.measure_observable(stim.PauliString(res))

def _sample_classical_shadow(self, meas, stim_circuit, shots, seed):
"""Measures classical shadows from the state of simulator device"""
Expand Down
1 change: 1 addition & 0 deletions pennylane/devices/default_qubit.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"Projector",
"SparseHamiltonian",
"Hamiltonian",
"LinearCombination",
"Sum",
"SProd",
"Prod",
Expand Down
19 changes: 11 additions & 8 deletions pennylane/devices/default_qubit_legacy.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ class DefaultQubitLegacy(QubitDevice):
"Projector",
"SparseHamiltonian",
"Hamiltonian",
"LinearCombination",
"Sum",
"SProd",
"Prod",
Expand Down Expand Up @@ -428,10 +429,11 @@ def _apply_sx(self, state, axes, inverse=False):
Returns:
array[complex]: output state
"""
if inverse:
return 0.5 * ((1 - 1j) * state + (1 + 1j) * self._apply_x(state, axes))

return 0.5 * ((1 + 1j) * state + (1 - 1j) * self._apply_x(state, axes))
return (
0.5 * ((1 - 1j) * state + (1 + 1j) * self._apply_x(state, axes))
if inverse
else 0.5 * ((1 + 1j) * state + (1 - 1j) * self._apply_x(state, axes))
)

def _apply_cnot(self, state, axes, **kwargs):
"""Applies a CNOT gate by slicing along the first axis specified in ``axes`` and then
Expand Down Expand Up @@ -597,7 +599,7 @@ def expval(self, observable, shot_range=None, bin_size=None):
# intercept other Hamiltonians
# TODO: Ideally, this logic should not live in the Device, but be moved
# to a component that can be re-used by devices as needed.
if observable.name not in ("Hamiltonian", "SparseHamiltonian"):
if observable.name not in ("Hamiltonian", "SparseHamiltonian", "LinearCombination"):
return super().expval(observable, shot_range=shot_range, bin_size=bin_size)

assert self.shots is None, f"{observable.name} must be used with shots=None"
Expand All @@ -606,7 +608,7 @@ def expval(self, observable, shot_range=None, bin_size=None):
backprop_mode = (
not isinstance(self.state, np.ndarray)
or any(not isinstance(d, (float, np.ndarray)) for d in observable.data)
) and observable.name == "Hamiltonian"
) and observable.name in ["Hamiltonian", "LinearCombination"]

if backprop_mode:
# TODO[dwierichs]: This branch is not adapted to broadcasting yet
Expand Down Expand Up @@ -666,7 +668,7 @@ def expval(self, observable, shot_range=None, bin_size=None):
csr_matrix.dot(Hmat, csr_matrix(state[..., None])),
).toarray()[0]

if observable.name == "Hamiltonian":
if observable.name in ["Hamiltonian", "LinearCombination"]:
res = qml.math.squeeze(res)

return self._real(res)
Expand Down Expand Up @@ -1086,6 +1088,7 @@ def _get_diagonalizing_gates(self, circuit: qml.tape.QuantumTape) -> List[Operat
meas_filtered = [
m
for m in circuit.measurements
if m.obs is None or not isinstance(m.obs, qml.Hamiltonian)
if m.obs is None
or not isinstance(m.obs, (qml.ops.Hamiltonian, qml.ops.LinearCombination))
]
return super()._get_diagonalizing_gates(qml.tape.QuantumScript(measurements=meas_filtered))
7 changes: 2 additions & 5 deletions pennylane/devices/default_qutrit.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
OMEGA = qml.math.exp(2 * np.pi * 1j / 3)


# pylint: disable=too-many-arguments
class DefaultQutrit(QutritDevice):
"""Default qutrit device for PennyLane.

Expand Down Expand Up @@ -87,11 +88,7 @@ class DefaultQutrit(QutritDevice):

# Identity is supported as an observable for qml.state() to work correctly. However, any
# measurement types that rely on eigenvalue decomposition will not work with qml.Identity
observables = {
"THermitian",
"GellMann",
"Identity",
}
observables = {"THermitian", "GellMann", "Identity", "Prod"}

# Static methods to use qml.math to allow for backprop differentiation
_reshape = staticmethod(qml.math.reshape)
Expand Down
4 changes: 2 additions & 2 deletions pennylane/devices/qubit/measure.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from scipy.sparse import csr_matrix

from pennylane import math
from pennylane.ops import Sum, Hamiltonian
from pennylane.ops import Sum, Hamiltonian, LinearCombination
from pennylane.measurements import (
StateMeasurement,
MeasurementProcess,
Expand Down Expand Up @@ -194,7 +194,7 @@ def get_measurement_function(
return full_dot_products

backprop_mode = math.get_interface(state, *measurementprocess.obs.data) != "numpy"
if isinstance(measurementprocess.obs, Hamiltonian):
if isinstance(measurementprocess.obs, (Hamiltonian, LinearCombination)):
# need to work out thresholds for when its faster to use "backprop mode" measurements
return sum_of_terms_method if backprop_mode else csr_dot_products

Expand Down
Loading
Loading