Skip to content

Commit

Permalink
update branch
Browse files Browse the repository at this point in the history
  • Loading branch information
LuisAlfredoNu committed Jan 2, 2025
1 parent a8b12b5 commit ec4f1f2
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 287 deletions.
5 changes: 1 addition & 4 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -465,9 +465,6 @@ Ali Asadi, Amintor Dusko, Diego Guala, Joseph Lee, Luis Alfredo Nuñez Meneses,
* Enable setting the PennyLane version when invoking, for example, `make docker-build version=master pl_version=master`.
[(#791)](https://github.com/PennyLaneAI/pennylane-lightning/pull/791)

* Add a Catalyst-specific wrapping class for Lightning Kokkos.
[(#770)](https://github.com/PennyLaneAI/pennylane-lightning/pull/770)

### Documentation

* The installation instructions for all lightning plugins have been improved.
Expand Down Expand Up @@ -614,7 +611,7 @@ Ali Asadi, Astral Cai, Ahmed Darwish, Amintor Dusko, Vincent Michaud-Rioux, Luis

* Changed the name of `lightning.tensor` to `default.tensor` with the `quimb` backend.
[(#719)](https://github.com/PennyLaneAI/pennylane-lightning/pull/719)

* `lightning.qubit` and `lightning.kokkos` adhere to user-specified mid-circuit measurement configuration options.
[(#736)](https://github.com/PennyLaneAI/pennylane-lightning/pull/736)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,6 @@ class GateImplementationsLM : public PauliGenerator<GateImplementationsLM> {
applyNCHadamard(arr, num_qubits, {}, {}, wires, inverse);
}


template <class PrecisionT>
static void
applyNCS(std::complex<PrecisionT> *arr, const std::size_t num_qubits,
Expand Down
294 changes: 13 additions & 281 deletions pennylane_lightning/lightning_qubit/lightning_qubit.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,287 +62,19 @@
from ._measurements import LightningMeasurements
from ._state_vector import LightningStateVector

try:
# pylint: disable=import-error, unused-import
from pennylane_lightning.lightning_qubit_ops import backend_info

LQ_CPP_BINARY_AVAILABLE = True
except ImportError:
LQ_CPP_BINARY_AVAILABLE = False

Result_or_ResultBatch = Union[Result, ResultBatch]
QuantumTapeBatch = Sequence[QuantumTape]
QuantumTape_or_Batch = Union[QuantumTape, QuantumTapeBatch]
PostprocessingFn = Callable[[ResultBatch], Result_or_ResultBatch]


def simulate(
circuit: QuantumScript,
state: LightningStateVector,
mcmc: dict = None,
postselect_mode: str = None,
) -> Result:
"""Simulate a single quantum script.
Args:
circuit (QuantumTape): The single circuit to simulate
state (LightningStateVector): handle to Lightning state vector
mcmc (dict): Dictionary containing the Markov Chain Monte Carlo
parameters: mcmc, kernel_name, num_burnin. Descriptions of
these fields are found in :class:`~.LightningQubit`.
postselect_mode (str): Configuration for handling shots with mid-circuit measurement
postselection. Use ``"hw-like"`` to discard invalid shots and ``"fill-shots"`` to
keep the same number of shots. Default is ``None``.
Returns:
Tuple[TensorLike]: The results of the simulation
Note that this function can return measurements for non-commuting observables simultaneously.
"""
if mcmc is None:
mcmc = {}
state.reset_state()
has_mcm = any(isinstance(op, MidMeasureMP) for op in circuit.operations)
if circuit.shots and has_mcm:
results = []
aux_circ = qml.tape.QuantumScript(
circuit.operations,
circuit.measurements,
shots=[1],
trainable_params=circuit.trainable_params,
)
for _ in range(circuit.shots.total_shots):
state.reset_state()
mid_measurements = {}
final_state = state.get_final_state(
aux_circ, mid_measurements=mid_measurements, postselect_mode=postselect_mode
)
results.append(
LightningMeasurements(final_state, **mcmc).measure_final_state(
aux_circ, mid_measurements=mid_measurements
)
)
return tuple(results)
final_state = state.get_final_state(circuit)
return LightningMeasurements(final_state, **mcmc).measure_final_state(circuit)


def jacobian(circuit: QuantumTape, state: LightningStateVector, batch_obs=False, wire_map=None):
"""Compute the Jacobian for a single quantum script.
Args:
circuit (QuantumTape): The single circuit to simulate
state (LightningStateVector): handle to Lightning state vector
batch_obs (bool): Determine whether we process observables in parallel when
computing the jacobian. This value is only relevant when the lightning
qubit is built with OpenMP. Default is False.
wire_map (Optional[dict]): a map from wire labels to simulation indices
Returns:
TensorLike: The Jacobian of the quantum script
"""
if wire_map is not None:
[circuit], _ = qml.map_wires(circuit, wire_map)
state.reset_state()
final_state = state.get_final_state(circuit)
return LightningAdjointJacobian(final_state, batch_obs=batch_obs).calculate_jacobian(circuit)


def simulate_and_jacobian(
circuit: QuantumTape, state: LightningStateVector, batch_obs=False, wire_map=None
):
"""Simulate a single quantum script and compute its Jacobian.
Args:
circuit (QuantumTape): The single circuit to simulate
state (LightningStateVector): handle to Lightning state vector
batch_obs (bool): Determine whether we process observables in parallel when
computing the jacobian. This value is only relevant when the lightning
qubit is built with OpenMP. Default is False.
wire_map (Optional[dict]): a map from wire labels to simulation indices
Returns:
Tuple[TensorLike]: The results of the simulation and the calculated Jacobian
Note that this function can return measurements for non-commuting observables simultaneously.
"""
if wire_map is not None:
[circuit], _ = qml.map_wires(circuit, wire_map)
res = simulate(circuit, state)
jac = LightningAdjointJacobian(state, batch_obs=batch_obs).calculate_jacobian(circuit)
return res, jac


def vjp(
circuit: QuantumTape,
cotangents: Tuple[Number],
state: LightningStateVector,
batch_obs=False,
wire_map=None,
):
"""Compute the Vector-Jacobian Product (VJP) for a single quantum script.
Args:
circuit (QuantumTape): The single circuit to simulate
cotangents (Tuple[Number, Tuple[Number]]): Gradient-output vector. Must
have shape matching the output shape of the corresponding circuit. If
the circuit has a single output, ``cotangents`` may be a single number,
not an iterable of numbers.
state (LightningStateVector): handle to Lightning state vector
batch_obs (bool): Determine whether we process observables in parallel when
computing the VJP. This value is only relevant when the lightning
qubit is built with OpenMP.
wire_map (Optional[dict]): a map from wire labels to simulation indices
Returns:
TensorLike: The VJP of the quantum script
"""
if wire_map is not None:
[circuit], _ = qml.map_wires(circuit, wire_map)
state.reset_state()
final_state = state.get_final_state(circuit)
return LightningAdjointJacobian(final_state, batch_obs=batch_obs).calculate_vjp(
circuit, cotangents
)


def simulate_and_vjp(
circuit: QuantumTape,
cotangents: Tuple[Number],
state: LightningStateVector,
batch_obs=False,
wire_map=None,
):
"""Simulate a single quantum script and compute its Vector-Jacobian Product (VJP).
Args:
circuit (QuantumTape): The single circuit to simulate
cotangents (Tuple[Number, Tuple[Number]]): Gradient-output vector. Must
have shape matching the output shape of the corresponding circuit. If
the circuit has a single output, ``cotangents`` may be a single number,
not an iterable of numbers.
state (LightningStateVector): handle to Lightning state vector
batch_obs (bool): Determine whether we process observables in parallel when
computing the jacobian. This value is only relevant when the lightning
qubit is built with OpenMP.
wire_map (Optional[dict]): a map from wire labels to simulation indices
Returns:
Tuple[TensorLike]: The results of the simulation and the calculated VJP
Note that this function can return measurements for non-commuting observables simultaneously.
"""
if wire_map is not None:
[circuit], _ = qml.map_wires(circuit, wire_map)
res = simulate(circuit, state)
_vjp = LightningAdjointJacobian(state, batch_obs=batch_obs).calculate_vjp(circuit, cotangents)
return res, _vjp


_operations = frozenset(
{
"Identity",
"QubitUnitary",
"MultiControlledX",
"DiagonalQubitUnitary",
"PauliX",
"PauliY",
"PauliZ",
"MultiRZ",
"GlobalPhase",
"Hadamard",
"S",
"Adjoint(S)",
"T",
"Adjoint(T)",
"SX",
"Adjoint(SX)",
"CNOT",
"SWAP",
"ISWAP",
"PSWAP",
"Adjoint(ISWAP)",
"SISWAP",
"Adjoint(SISWAP)",
"SQISW",
"CSWAP",
"Toffoli",
"CY",
"CZ",
"PhaseShift",
"ControlledPhaseShift",
"RX",
"RY",
"RZ",
"Rot",
"CRX",
"CRY",
"CRZ",
"C(PauliX)",
"C(PauliY)",
"C(PauliZ)",
"C(Hadamard)",
"C(S)",
"C(T)",
"C(SX)",
"C(PhaseShift)",
"C(RX)",
"C(RY)",
"C(RZ)",
"C(Rot)",
"C(SWAP)",
"C(IsingXX)",
"C(IsingXY)",
"C(IsingYY)",
"C(IsingZZ)",
"C(SingleExcitation)",
"C(SingleExcitationMinus)",
"C(SingleExcitationPlus)",
"C(DoubleExcitation)",
"C(DoubleExcitationMinus)",
"C(DoubleExcitationPlus)",
"C(MultiRZ)",
"C(GlobalPhase)",
"C(QubitUnitary)",
"CRot",
"IsingXX",
"IsingYY",
"IsingZZ",
"IsingXY",
"SingleExcitation",
"SingleExcitationPlus",
"SingleExcitationMinus",
"DoubleExcitation",
"DoubleExcitationPlus",
"DoubleExcitationMinus",
"QubitCarry",
"QubitSum",
"OrbitalRotation",
"QFT",
"ECR",
"BlockEncode",
"C(BlockEncode)",
}
)
# The set of supported operations.


_observables = frozenset(
{
"PauliX",
"PauliY",
"PauliZ",
"Hadamard",
"Hermitian",
"Identity",
"Projector",
"SparseHamiltonian",
"Hamiltonian",
"LinearCombination",
"Sum",
"SProd",
"Prod",
"Exp",
}
)
# The set of supported observables.
_to_matrix_ops = {
"BlockEncode": OperatorProperties(controllable=True),
"DiagonalQubitUnitary": OperatorProperties(),
"ECR": OperatorProperties(),
"ISWAP": OperatorProperties(),
"OrbitalRotation": OperatorProperties(),
"PSWAP": OperatorProperties(),
"QubitCarry": OperatorProperties(),
"QubitSum": OperatorProperties(),
"SISWAP": OperatorProperties(),
"SQISW": OperatorProperties(),
"SX": OperatorProperties(),
}


def stopping_condition(op: Operator) -> bool:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,9 +472,9 @@ def circuit():
qml.PauliY,
qml.PauliZ,
qml.Hadamard,
qml.SX,
qml.S,
qml.T,
qml.SX,
qml.PhaseShift,
qml.RX,
qml.RY,
Expand Down

0 comments on commit ec4f1f2

Please sign in to comment.