Skip to content

Commit a248328

Browse files
vincentmrgithub-actions[bot]AmintorDuskomultiphaseCFD
authored
Support arbitrary controlled operations in lightning.qubit (#516)
* Add failing tests. * Add revWireParityN. * Fix applyMultiQubitOp implementation. * Auto update version * Update changelog * Refactor revWireParity overloads. * WIP fix Kokkos too. * Fix bug in multiQubitOpFunctor * Refactor unitary/hermitian tests and fix L-Kokkos multiQubit kernels. * Fix L-Qubit BitUtil. * Include algorithm header in BitUtil (sort). * Fix tidy issue. Fix failing test. * Make wires2Parity inline. * Update changelog. * Update pennylane_lightning/core/src/utils/BitUtil.hpp Co-authored-by: Amintor Dusko <[email protected]> * Init implementation for ControlledQubitUnitary * WIP * WIP * Move applyNQubitOp to LM kernels. * Register NQubitOp and add inverse branch in applyNQubitOp. * Auto update version * Update changelog. * Add test to improve controlled_matrix coverage. * Fix tidy warning. * Add doc [skip ci]. * Auto update version * trigger CI * WIP * WIP * Fix NCRZ kernel registration and add tests. * Add NCRY. * Add NCRX. * Create generic entry point for n-controlled kernels. * Add NC[X-Z] * Special treatment for MultiControlledX. * Add Hadamard, S, T, PhaseShift n-controlled gates. * Auto update version * Fix compiler warnings. * Address some of Lee's comments about naming and PL_ABORT. * Call NC kernels from non-NC ones. * Further reduce LM kernel code. * Template applyNC on has_controls. * Fix nw_tot if not has_controls * Branch template top level. * Auto update version * Ncontr add gens (#555) * Add ControlledGeneratorOperation (compiles). * Add applyNCGeneratorPhaseShift implementation. * WIP * Fix PhaseShift adjoint test. Use generic names in controlled ops enums. Fix applyOperation/Generator methods in StateVectorLQubit. Add R[X-Z] n-controlled generators. Properly register n-controlled generators in dynamic dispatcher. * All C++ test passing. Add n-controls to phaseshift test. * Simplify n-controlled generators. * Fix Python bindings. * Add n-controlled to _serialize. Add controlled adjoint diff example in tests. * Add n-controlled 2-qubit gates. * Formatting and doc. * Fix GPU-MPI bindings & mpitests. * Auto update version * Add skipif guard. * Fix noarch test * Fix bug in applyNCGen and reuse in applyGenR[X-Z]. * Fix pytest.skipif in adjoint tests. * Add n-controlled double-qubit gate generators. * Test multicontrolled two-qubit gates. --------- Co-authored-by: Dev version update bot <github-actions[bot]@users.noreply.github.com> * Remove whitelines [skip ci] * Fix codefactor warning. * Auto update version * Add tests for n-controlled kernels. * Auto update version * Fix tidy check. * Add C++ tests for controlled gates. * Remove whitespace. * Fix clang-tidy warning. * Fix ctrl adjoint diff c++ test. * Add tests for n-controlled unitaries. * Capture more n-controlled ops in L-Qubit. * Fix GPU workflow names. * Move controlled ops to private method. * Add coverage and fix gpu trigger. * Fix codecov uploads. * Update .github/CHANGELOG.md [skip ci] Co-authored-by: Amintor Dusko <[email protected]> * Update pennylane_lightning/core/src/simulators/lightning_qubit/StateVectorLQubit.hpp [skip ci] Co-authored-by: Amintor Dusko <[email protected]> * Update pennylane_lightning/core/src/simulators/lightning_qubit/StateVectorLQubit.hpp [skip ci] Co-authored-by: Amintor Dusko <[email protected]> * Update pennylane_lightning/core/src/simulators/lightning_qubit/StateVectorLQubit.hpp [skip ci] Co-authored-by: Amintor Dusko <[email protected]> * Update pennylane_lightning/core/_serialize.py Co-authored-by: Amintor Dusko <[email protected]> * Reorder controlled routine gate < generator < matrix. * Fix typos. * Auto update version * trigger ci * Serialize unfound ops as controlled qubit unitaries. * Update pennylane_lightning/core/src/simulators/lightning_qubit/algorithms/tests/Test_VectorJacobianProduct.cpp [skip ci] Co-authored-by: Amintor Dusko <[email protected]> * Update pennylane_lightning/core/src/simulators/lightning_qubit/algorithms/tests/Test_VectorJacobianProduct.cpp [skip ci] Co-authored-by: Amintor Dusko <[email protected]> * Fix wrong LCOV guards. * Update pennylane_lightning/core/src/algorithms/JacobianData.hpp [skip ci] Co-authored-by: Shuli Shu <[email protected]> * Update pennylane_lightning/core/src/algorithms/JacobianData.hpp [skip ci] Co-authored-by: Shuli Shu <[email protected]> * Auto update version * Address Shuli's comments. * Address Lee's comments. * WIP * Add n-controlled DoubleExcitation gate. * Add double excitation gates + cpp tests. * Add python tests. * Add adjoint diff support for double excitation gates. * Use FD to compute jac on adjoint tests. * Fix tidy warning. * Update pennylane_lightning/core/src/simulators/lightning_kokkos/StateVectorKokkos.hpp [skip ci] Co-authored-by: Amintor Dusko <[email protected]> * Auto update version * Refactor applyNCMultiQubitOp and add doc in GateImplLM.hpp. * Add n-controlled 1- and 2-qubit unitaries. * Refactor Constant.hpp according to Amintor's suggestions. * Add single/twoqubit n-controlled ops. * Move lightning_ops to conftest. * Fix noarch import. * Fix tidy warning * Fix tidy warning. * Small optim on parity2indices. * Handle generic control_values in controlled ops at the Python layer. * Auto update version * trigger ci * Apply 1-qubit 1-controlled gates as non-controlled 2-qubit gates. * Fix maybe_unused. * Remove comments. --------- Co-authored-by: Dev version update bot <github-actions[bot]@users.noreply.github.com> Co-authored-by: Amintor Dusko <[email protected]> Co-authored-by: Shuli Shu <[email protected]>
1 parent d165de1 commit a248328

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+5375
-1757
lines changed

.github/CHANGELOG.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@
77
* Add shot-noise support for probs in the C++ layer. Probabilities are calculated from generated samples. All Lightning backends support this feature. Please note that target wires should be sorted in ascending manner.
88
[(#568)](https://github.com/PennyLaneAI/pennylane-lightning/pull/568)
99

10+
* Add `LM` kernels to apply arbitrary controlled operations efficiently.
11+
[(#516)](https://github.com/PennyLaneAI/pennylane-lightning/pull/516)
12+
1013
* Add shots support for variance value, probs, sample, counts calculation for given observables (`NamedObs`, `TensorProd` and `Hamiltonian`) based on Pauli words, `Identity` and `Hadamard` in the C++ layer. All Lightning backends support this support feature.
11-
[(#561)](https://github.com/PennyLaneAI/pennylane-lightning/pull/561)
14+
[(#561)](https://github.com/PennyLaneAI/pennylane-lightning/pull/561)
1215

1316
* Add shots support for expectation value calculation for given observables (`NamedObs`, `TensorProd` and `Hamiltonian`) based on Pauli words, `Identity` and `Hadamard` in the C++ layer by adding `measure_with_samples` to the measurement interface. All Lightning backends support this support feature.
14-
[(#556)](https://github.com/PennyLaneAI/pennylane-lightning/pull/556)
17+
[(#556)](https://github.com/PennyLaneAI/pennylane-lightning/pull/556)
1518

1619
* `qml.QubitUnitary` operators can be included in a circuit differentiated with the adjoint method. Lightning handles circuits with arbitrary non-differentiable `qml.QubitUnitary` operators. 1,2-qubit `qml.QubitUnitary` operators with differentiable parameters can be differentiated using decomposition.
1720
[(#540)] (https://github.com/PennyLaneAI/pennylane-lightning/pull/540)

pennylane_lightning/core/_serialize.py

+25-3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
Rot,
2828
Hamiltonian,
2929
SparseHamiltonian,
30+
QubitUnitary,
3031
)
3132
from pennylane.operation import Tensor
3233
from pennylane.tape import QuantumTape
@@ -311,11 +312,32 @@ def serialize_ops(
311312
"""
312313
names = []
313314
params = []
315+
controlled_wires = []
314316
wires = []
315317
mats = []
316318

317319
uses_stateprep = False
318320

321+
def get_wires(operation, single_op):
322+
if operation.name[0:2] == "C(" or (
323+
operation.name == "MultiControlledX"
324+
and all(char == "1" for char in operation.hyperparameters["control_values"])
325+
):
326+
name = "PauliX" if operation.name == "MultiControlledX" else operation.base.name
327+
controlled_wires_list = operation.control_wires
328+
if operation.name == "MultiControlledX":
329+
wires_list = list(set(operation.wires) - set(controlled_wires_list))
330+
else:
331+
wires_list = operation.target_wires
332+
if not hasattr(self.sv_type, name):
333+
single_op = QubitUnitary(matrix(single_op.base), single_op.base.wires)
334+
name = single_op.name
335+
else:
336+
name = single_op.name
337+
wires_list = single_op.wires.tolist()
338+
controlled_wires_list = []
339+
return single_op, name, wires_list, controlled_wires_list
340+
319341
for operation in tape.operations:
320342
if isinstance(operation, (BasisState, StatePrep)):
321343
uses_stateprep = True
@@ -326,7 +348,7 @@ def serialize_ops(
326348
op_list = [operation]
327349

328350
for single_op in op_list:
329-
name = single_op.name
351+
single_op, name, wires_list, controlled_wires_list = get_wires(operation, single_op)
330352
names.append(name)
331353
# QubitUnitary is a special case, it has a parameter which is not differentiable.
332354
# We thus pass a dummy 0.0 parameter which will not be referenced
@@ -340,8 +362,8 @@ def serialize_ops(
340362
params.append(single_op.parameters)
341363
mats.append([])
342364

343-
wires_list = single_op.wires.tolist()
365+
controlled_wires.append([wires_map[w] for w in controlled_wires_list])
344366
wires.append([wires_map[w] for w in wires_list])
345367

346368
inverses = [False] * len(names)
347-
return (names, params, wires, inverses, mats), uses_stateprep
369+
return (names, params, wires, inverses, mats, controlled_wires), uses_stateprep

pennylane_lightning/core/_version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@
1616
Version number (major.minor.patch[-label])
1717
"""
1818

19-
__version__ = "0.34.0-dev14"
19+
__version__ = "0.34.0-dev15"

pennylane_lightning/core/src/algorithms/AdjointJacobianBase.hpp

+46-11
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
* method.
1818
*/
1919
#pragma once
20-
2120
#include <span>
2221

2322
#include "JacobianData.hpp"
@@ -56,11 +55,20 @@ template <class StateVectorT, class Derived> class AdjointJacobianBase {
5655
bool adj = false) {
5756
for (size_t op_idx = 0; op_idx < operations.getOpsName().size();
5857
op_idx++) {
59-
state.applyOperation(operations.getOpsName()[op_idx],
60-
operations.getOpsWires()[op_idx],
61-
operations.getOpsInverses()[op_idx] ^ adj,
62-
operations.getOpsParams()[op_idx],
63-
operations.getOpsMatrices()[op_idx]);
58+
if (operations.getOpsControlledWires()[op_idx].empty()) {
59+
state.applyOperation(operations.getOpsName()[op_idx],
60+
operations.getOpsWires()[op_idx],
61+
operations.getOpsInverses()[op_idx] ^ adj,
62+
operations.getOpsParams()[op_idx],
63+
operations.getOpsMatrices()[op_idx]);
64+
} else {
65+
state.applyOperation(operations.getOpsName()[op_idx],
66+
operations.getOpsControlledWires()[op_idx],
67+
operations.getOpsWires()[op_idx],
68+
operations.getOpsInverses()[op_idx] ^ adj,
69+
operations.getOpsParams()[op_idx],
70+
operations.getOpsMatrices()[op_idx]);
71+
}
6472
}
6573
}
6674

@@ -77,11 +85,20 @@ template <class StateVectorT, class Derived> class AdjointJacobianBase {
7785
inline void applyOperationAdj(UpdatedStateVectorT &state,
7886
const OpsData<StateVectorT> &operations,
7987
size_t op_idx) {
80-
state.applyOperation(operations.getOpsName()[op_idx],
81-
operations.getOpsWires()[op_idx],
82-
!operations.getOpsInverses()[op_idx],
83-
operations.getOpsParams()[op_idx],
84-
operations.getOpsMatrices()[op_idx]);
88+
if (operations.getOpsControlledWires()[op_idx].empty()) {
89+
state.applyOperation(operations.getOpsName()[op_idx],
90+
operations.getOpsWires()[op_idx],
91+
!operations.getOpsInverses()[op_idx],
92+
operations.getOpsParams()[op_idx],
93+
operations.getOpsMatrices()[op_idx]);
94+
} else {
95+
state.applyOperation(operations.getOpsName()[op_idx],
96+
operations.getOpsControlledWires()[op_idx],
97+
operations.getOpsWires()[op_idx],
98+
!operations.getOpsInverses()[op_idx],
99+
operations.getOpsParams()[op_idx],
100+
operations.getOpsMatrices()[op_idx]);
101+
}
85102
}
86103

87104
/**
@@ -117,6 +134,24 @@ template <class StateVectorT, class Derived> class AdjointJacobianBase {
117134
return sv.applyGenerator(op_name, wires, adj);
118135
}
119136

137+
/**
138+
* @brief Applies the gate generator for a given parametric gate. Returns
139+
* the associated scaling coefficient.
140+
*
141+
* @param sv Statevector data to operate upon.
142+
* @param op_name Name of parametric gate.
143+
* @param controlled_wires Control wires.
144+
* @param wires Wires to operate upon.
145+
* @param adj Indicate whether to take the adjoint of the operation.
146+
* @return PrecisionT Generator scaling coefficient.
147+
*/
148+
inline auto applyGenerator(StateVectorT &sv, const std::string &op_name,
149+
const std::vector<size_t> &controlled_wires,
150+
const std::vector<size_t> &wires, const bool adj)
151+
-> PrecisionT {
152+
return sv.applyGenerator(op_name, controlled_wires, wires, adj);
153+
}
154+
120155
/**
121156
* @brief Apply a given `%Observable<StateVectorT>` object to
122157
* `%StateVectorT`.

pennylane_lightning/core/src/algorithms/JacobianData.hpp

+46-8
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,39 @@ template <class StateVectorT> class OpsData {
4949
const std::vector<std::vector<size_t>> ops_wires_;
5050
const std::vector<bool> ops_inverses_;
5151
const std::vector<std::vector<ComplexT>> ops_matrices_;
52+
const std::vector<std::vector<size_t>> ops_controlled_wires_;
5253

5354
public:
55+
/**
56+
* @brief Construct an OpsData object, representing the serialized
57+
* operations to apply upon the `%StateVector`.
58+
*
59+
* @param ops_name Name of each operation to apply.
60+
* @param ops_params Parameters for a given operation ({} if optional).
61+
* @param ops_wires Wires upon which to apply operation.
62+
* @param ops_inverses Value to represent whether given operation is
63+
* adjoint.
64+
* @param ops_matrices Numerical representation of given matrix if not
65+
* supported.
66+
* @param ops_controlled_wires Control wires
67+
*/
68+
OpsData(std::vector<std::string> ops_name,
69+
const std::vector<std::vector<PrecisionT>> &ops_params,
70+
std::vector<std::vector<size_t>> ops_wires,
71+
std::vector<bool> ops_inverses,
72+
std::vector<std::vector<ComplexT>> ops_matrices,
73+
std::vector<std::vector<size_t>> ops_controlled_wires)
74+
: num_par_ops_{0}, ops_name_{std::move(ops_name)},
75+
ops_params_{ops_params}, ops_wires_{std::move(ops_wires)},
76+
ops_inverses_{std::move(ops_inverses)},
77+
ops_matrices_{std::move(ops_matrices)},
78+
ops_controlled_wires_{std::move(ops_controlled_wires)} {
79+
for (const auto &p : ops_params) {
80+
num_par_ops_ += static_cast<size_t>(!p.empty());
81+
}
82+
num_nonpar_ops_ = ops_params.size() - num_par_ops_;
83+
};
84+
5485
/**
5586
* @brief Construct an OpsData object, representing the serialized
5687
* operations to apply upon the `%StateVector`.
@@ -71,11 +102,10 @@ template <class StateVectorT> class OpsData {
71102
: num_par_ops_{0}, ops_name_{std::move(ops_name)},
72103
ops_params_{ops_params}, ops_wires_{std::move(ops_wires)},
73104
ops_inverses_{std::move(ops_inverses)},
74-
ops_matrices_{std::move(ops_matrices)} {
105+
ops_matrices_{std::move(ops_matrices)},
106+
ops_controlled_wires_(ops_name.size()) {
75107
for (const auto &p : ops_params) {
76-
if (!p.empty()) {
77-
num_par_ops_++;
78-
}
108+
num_par_ops_ += static_cast<size_t>(!p.empty());
79109
}
80110
num_nonpar_ops_ = ops_params.size() - num_par_ops_;
81111
};
@@ -97,11 +127,10 @@ template <class StateVectorT> class OpsData {
97127
: num_par_ops_{0}, ops_name_{ops_name}, ops_params_{ops_params},
98128
ops_wires_{std::move(ops_wires)},
99129
ops_inverses_{std::move(ops_inverses)},
100-
ops_matrices_(ops_name.size()) {
130+
ops_matrices_(ops_name.size()),
131+
ops_controlled_wires_(ops_name.size()) {
101132
for (const auto &p : ops_params) {
102-
if (p.size() > 0) {
103-
num_par_ops_++;
104-
}
133+
num_par_ops_ += static_cast<size_t>(!p.empty());
105134
}
106135
num_nonpar_ops_ = ops_params.size() - num_par_ops_;
107136
};
@@ -140,6 +169,15 @@ template <class StateVectorT> class OpsData {
140169
-> const std::vector<std::vector<size_t>> & {
141170
return ops_wires_;
142171
}
172+
/**
173+
* @brief Get the controlled wires for each operation.
174+
*
175+
* @return const std::vector<std::vector<size_t>>&
176+
*/
177+
[[nodiscard]] auto getOpsControlledWires() const
178+
-> const std::vector<std::vector<size_t>> & {
179+
return ops_controlled_wires_;
180+
}
143181
/**
144182
* @brief Get the adjoint flag for each operation.
145183
*

pennylane_lightning/core/src/algorithms/tests/Test_AdjointJacobian.cpp

+47-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ using namespace Pennylane::Util;
2525

2626
#ifdef _ENABLE_PLQUBIT
2727
constexpr bool BACKEND_FOUND = true;
28+
constexpr bool SUPPORTS_CTRL = true;
2829

2930
#include "AdjointJacobianLQubit.hpp"
3031
#include "ObservablesLQubit.hpp"
@@ -40,6 +41,7 @@ using namespace Pennylane::LightningQubit::Observables;
4041

4142
#elif _ENABLE_PLKOKKOS == 1
4243
constexpr bool BACKEND_FOUND = true;
44+
constexpr bool SUPPORTS_CTRL = false;
4345

4446
#include "AdjointJacobianKokkos.hpp"
4547
#include "ObservablesKokkos.hpp"
@@ -55,6 +57,7 @@ using namespace Pennylane::LightningKokkos::Observables;
5557

5658
#elif _ENABLE_PLGPU == 1
5759
constexpr bool BACKEND_FOUND = true;
60+
constexpr bool SUPPORTS_CTRL = false;
5861
#include "AdjointJacobianGPU.hpp"
5962
#include "ObservablesGPU.hpp"
6063
#include "TestHelpersStateVectors.hpp"
@@ -69,6 +72,7 @@ using namespace Pennylane::LightningGPU::Observables;
6972

7073
#else
7174
constexpr bool BACKEND_FOUND = false;
75+
constexpr bool SUPPORTS_CTRL = false;
7276
using TestStateVectorBackends = Pennylane::Util::TypeList<void>;
7377

7478
template <class StateVector> struct StateVectorToName {};
@@ -134,6 +138,44 @@ template <typename TypeList> void testAdjointJacobian() {
134138
}
135139
}
136140

141+
DYNAMIC_SECTION("Op=PhaseShift, Obs=Y - "
142+
<< StateVectorToName<StateVectorT>::name) {
143+
if (SUPPORTS_CTRL) {
144+
const std::vector<size_t> tp{0};
145+
const size_t num_qubits = GENERATE(2, 3, 4);
146+
147+
const size_t num_params = 3;
148+
const size_t num_obs = 1;
149+
const auto obs = std::make_shared<NamedObs<StateVectorT>>(
150+
"PauliY", std::vector<size_t>{num_qubits - 1});
151+
std::vector<PrecisionT> jacobian(num_obs * tp.size(), 0);
152+
153+
for (const auto &p : param) {
154+
std::vector<std::vector<size_t>> controls{
155+
std::vector<size_t>(num_qubits - 1)};
156+
std::iota(controls[0].begin(), controls[0].end(), 0);
157+
auto ops = OpsData<StateVectorT>({"PhaseShift"}, {{p}},
158+
{{num_qubits - 1}},
159+
{false}, {{}}, controls);
160+
161+
std::vector<ComplexT> cdata(1U << num_qubits);
162+
cdata[cdata.size() - 2] =
163+
Pennylane::Util::INVSQRT2<PrecisionT>();
164+
cdata[cdata.size() - 1] =
165+
Pennylane::Util::INVSQRT2<PrecisionT>();
166+
167+
StateVectorT psi(cdata.data(), cdata.size());
168+
JacobianData<StateVectorT> tape{
169+
num_params, psi.getLength(), psi.getData(), {obs}, ops,
170+
tp};
171+
adj.adjointJacobian(std::span{jacobian}, tape, psi, true);
172+
173+
CAPTURE(jacobian);
174+
CHECK(cos(p) == Approx(jacobian[0]));
175+
}
176+
}
177+
}
178+
137179
DYNAMIC_SECTION("Op=RX, Obs=Z - "
138180
<< StateVectorToName<StateVectorT>::name) {
139181
const std::vector<size_t> tp{0};
@@ -189,6 +231,7 @@ template <typename TypeList> void testAdjointJacobian() {
189231
CHECK(cos(p) == Approx(jacobian[0]).margin(1e-7));
190232
}
191233
}
234+
192235
DYNAMIC_SECTION("Op=RX, Obs=[Z,Z] - "
193236
<< StateVectorToName<StateVectorT>::name) {
194237
std::vector<size_t> tp{0};
@@ -366,7 +409,9 @@ template <typename TypeList> void testAdjointJacobian() {
366409
{{0}, {0}, {0}, {0, 1}, {1, 2}, {1}, {1}, {1}},
367410
{false, false, false, false, false, false, false, false},
368411
std::vector<std::vector<ComplexT>>{
369-
{}, {}, {}, cnot, {}, {}, {}, {}});
412+
{}, {}, {}, cnot, {}, {}, {}, {}},
413+
std::vector<std::vector<size_t>>{
414+
{}, {}, {}, {}, {}, {}, {}, {}});
370415

371416
JacobianData<StateVectorT> tape{
372417
num_params, psi.getLength(), psi.getData(), {obs}, ops, tp};
@@ -436,7 +481,7 @@ template <typename TypeList> void testAdjointJacobian() {
436481
}
437482
}
438483

439-
DYNAMIC_SECTION("Mixed Ops, Obs and TParams- "
484+
DYNAMIC_SECTION("Mixed Ops, Obs and TParams - "
440485
<< StateVectorToName<StateVectorT>::name) {
441486
std::vector<PrecisionT> param{-M_PI / 7, M_PI / 5, 2 * M_PI / 3};
442487
const std::vector<size_t> t_params{1, 2, 3};

pennylane_lightning/core/src/algorithms/tests/mpi/Test_AdjointJacobianMPI.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,9 @@ template <typename TypeList> void testAdjointJacobian() {
264264
{{0}, {0}, {0}, {0, 1}, {1, 2}, {1}, {1}, {1}},
265265
{false, false, false, false, false, false, false, false},
266266
std::vector<std::vector<ComplexT>>{
267-
{}, {}, {}, cnot, {}, {}, {}, {}});
267+
{}, {}, {}, cnot, {}, {}, {}, {}},
268+
std::vector<std::vector<size_t>>{
269+
{}, {}, {}, {}, {}, {}, {}, {}});
268270

269271
JacobianDataMPI<StateVectorT> tape{num_params, psi, {obs}, ops, tp};
270272

0 commit comments

Comments
 (0)