Skip to content

Commit

Permalink
V0.15.1 bugfix (#1268)
Browse files Browse the repository at this point in the history
* allow pyscf>=1.7.2 for QChem (#1254)

(cherry picked from commit 34ada2c)

* merge

* merge

* Fixes two bugs in the parameter-shift Hessian (#1260)

* Fixes two bugs in the parameter-shift Hessian

* fix

* added additional test

(cherry picked from commit beaf0a6)

* merge

* changelog

* Apply suggestions from code review

Co-authored-by: Maria Schuld <mariaschuld@gmail.com>

Co-authored-by: antalszava <antalszava@gmail.com>
Co-authored-by: Maria Schuld <mariaschuld@gmail.com>
  • Loading branch information
3 people authored May 3, 2021
1 parent 6252d3e commit 53b8d65
Show file tree
Hide file tree
Showing 44 changed files with 666 additions and 133 deletions.
37 changes: 36 additions & 1 deletion .github/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,38 @@
# Release 0.15.1 (current release)

<h3>Bug fixes</h3>

* Fixes two bugs in the parameter-shift Hessian.
[(#1260)](https://github.com/PennyLaneAI/pennylane/pull/1260)

- Fixes a bug where having an unused parameter in the Autograd interface
would result in an indexing error during backpropagation.

- The parameter-shift Hessian only supports the two-term parameter-shift
rule currently, so raises an error if asked to differentiate
any unsupported gates (such as the controlled rotation gates).

* A bug which resulted in `qml.adjoint()` and `qml.inv()` failing to work with
templates has been fixed.
[(#1243)](https://github.com/PennyLaneAI/pennylane/pull/1243)

* Deprecation warning instances in PennyLane have been changed to `UserWarning`,
to account for recent changes to how Python warnings are filtered in
[PEP565](https://www.python.org/dev/peps/pep-0565/).
[(#1211)](https://github.com/PennyLaneAI/pennylane/pull/1211)

<h3>Documentation</h3>

* Updated the order of the parameters to the `GaussianState` operation to match
the way that the PennyLane-SF plugin uses them.
[(#1255)](https://github.com/PennyLaneAI/pennylane/pull/1255)

<h3>Contributors</h3>

This release contains contributions from (in alphabetical order):

Josh Izaac, Maria Schuld, Antal Száva.

# Release 0.15.0 (current release)

<h3>New features since last release</h3>
Expand Down Expand Up @@ -622,7 +657,7 @@ fully differentiable.
of shots is set explicitly.

* If creating a QNode from a quantum function with an argument named `shots`,
a `DeprecationWarning` is raised, warning the user that this is a reserved
a `UserWarning` is raised, warning the user that this is a reserved
argument to change the number of shots on a per-call basis.
[(#1075)](https://github.com/PennyLaneAI/pennylane/pull/1075)

Expand Down
2 changes: 1 addition & 1 deletion pennylane/_qubit_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ def sample_basis_states(self, number_of_states, state_probability):
"The number of shots has to be explicitly set on the device "
"when using sample-based measurements. Since no shots are specified, "
"a default of 1000 shots is used.",
DeprecationWarning,
UserWarning,
)

shots = self.shots or 1000
Expand Down
2 changes: 1 addition & 1 deletion pennylane/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
Version number (major.minor.patch[-label])
"""

__version__ = "0.15.0"
__version__ = "0.15.1"
2 changes: 1 addition & 1 deletion pennylane/beta/devices/default_tensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class DefaultTensor(Device):
name = "PennyLane TensorNetwork simulator plugin"
short_name = "default.tensor"
pennylane_requires = "0.15"
version = "0.15.0"
version = "0.15.1"
author = "Xanadu Inc."

_operation_map = {
Expand Down
12 changes: 7 additions & 5 deletions pennylane/devices/default_gaussian.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ def thermal_state(nbar, hbar=2.0):
return state


def gaussian_state(mu, cov, hbar=2.0):
def gaussian_state(cov, mu, hbar=2.0):
r"""Returns a Gaussian state.
This is simply a bare wrapper function,
Expand All @@ -444,17 +444,19 @@ def gaussian_state(mu, cov, hbar=2.0):
ordering.
Args:
mu (array): vector means. Must be length-:math:`2N`,
where N is the number of modes
cov (array): covariance matrix. Must be dimension :math:`2N\times 2N`,
where N is the number of modes
mu (array): vector means. Must be length-:math:`2N`,
where N is the number of modes
hbar (float): (default 2) the value of :math:`\hbar` in the commutation
relation :math:`[\x,\p]=i\hbar`
Returns:
tuple: the mean and covariance matrix of the Gaussian state
tuple: the mean and the covariance matrix of the Gaussian state
"""
# pylint: disable=unused-argument

# Note: the internal order of mu and cov is different to the one used in Strawberry Fields
return mu, cov


Expand Down Expand Up @@ -648,7 +650,7 @@ class DefaultGaussian(Device):
name = "Default Gaussian PennyLane plugin"
short_name = "default.gaussian"
pennylane_requires = "0.15"
version = "0.15.0"
version = "0.15.1"
author = "Xanadu Inc."

_operation_map = {
Expand Down
2 changes: 1 addition & 1 deletion pennylane/devices/default_mixed.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class DefaultMixed(QubitDevice):
name = "Default mixed-state qubit PennyLane plugin"
short_name = "default.mixed"
pennylane_requires = "0.15"
version = "0.15.0"
version = "0.15.1"
author = "Xanadu Inc."

operations = {
Expand Down
2 changes: 1 addition & 1 deletion pennylane/devices/default_qubit.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class DefaultQubit(QubitDevice):
name = "Default qubit PennyLane plugin"
short_name = "default.qubit"
pennylane_requires = "0.15"
version = "0.15.0"
version = "0.15.1"
author = "Xanadu Inc."

operations = {
Expand Down
4 changes: 2 additions & 2 deletions pennylane/devices/default_qubit_jax.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,8 @@ def sample_basis_states(self, number_of_states, state_probability):
"The number of shots has to be explicitly set on the jax device "
"when using sample-based measurements. Since no shots are specified, "
"a default of 1000 shots is used.\n"
"This warning will replaced with an error in a future release.",
DeprecationWarning,
"This warning will be replaced with an error in a future release.",
UserWarning,
)

shots = self.shots or 1000
Expand Down
2 changes: 1 addition & 1 deletion pennylane/devices/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def skip_if():
"""Fixture to skip tests."""

def _skip_if(dev, capabilities):
""" Skip test if device has any of the given capabilities. """
"""Skip test if device has any of the given capabilities."""

dev_capabilities = dev.capabilities()
for capability, value in capabilities.items():
Expand Down
2 changes: 1 addition & 1 deletion pennylane/devices/tests/test_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@


def qfunc_no_input():
"""Model agnostic quantum function """
"""Model agnostic quantum function"""
return qml.expval(qml.Identity(wires=0))


Expand Down
3 changes: 2 additions & 1 deletion pennylane/interfaces/autograd.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,8 @@ def hessian_product(ddy):
if dy.size > 1:
vhp = dy @ ddy @ hessian @ dy.T
else:
vhp = np.squeeze(ddy @ hessian)
vhp = ddy @ hessian
vhp = vhp.flatten()

return vhp

Expand Down
4 changes: 2 additions & 2 deletions pennylane/ops/cv.py
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ class ThermalState(CVOperation):


class GaussianState(CVOperation):
r"""pennylane.GaussianState(r, V, wires)
r"""pennylane.GaussianState(V, r, wires)
Prepare subsystems in a given Gaussian state.
**Details:**
Expand All @@ -720,9 +720,9 @@ class GaussianState(CVOperation):
* Gradient recipe: None
Args:
V (array): the :math:`2N\times 2N` (real and positive definite) covariance matrix
r (array): a length :math:`2N` vector of means, of the
form :math:`(\x_0,\dots,\x_{N-1},\p_0,\dots,\p_{N-1})`
V (array): the :math:`2N\times 2N` (real and positive definite) covariance matrix
"""
num_wires = AnyWires
num_params = 2
Expand Down
2 changes: 1 addition & 1 deletion pennylane/qnode.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def __init__(
"Detected 'shots' as an argument to the given quantum function. "
"The 'shots' argument name is reserved for overriding the number of shots "
"taken by the device. Its use outside of this context should be avoided.",
DeprecationWarning,
UserWarning,
)
self._qfunc_uses_shots_arg = True
else:
Expand Down
30 changes: 30 additions & 0 deletions pennylane/tape/jacobian_tape.py
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,36 @@ def hessian(self, device, params=None, **options):
# parameters. Simply return an empty Hessian.
return np.zeros((len(params), len(params)), dtype=float)

# The parameter-shift Hessian implementation currently only supports
# the two-term parameter-shift rule. Raise an error for unsupported operations.
supported_ops = (
"RX",
"RY",
"RZ",
"Rot",
"PhaseShift",
"ControlledPhaseShift",
"MultiRZ",
"PauliRot",
"U1",
"U2",
"U3",
"SingleExcitationMinus",
"SingleExcitationPlus",
"DoubleExcitationMinus",
"DoubleExcitationPlus",
)

for idx, info in self._par_info.items():
op = info["op"]

if idx in self.trainable_params and op.name not in supported_ops:
raise ValueError(
f"The operation {op.name} is currently not supported for the "
f"parameter-shift Hessian.\nPlease decompose the operation in your "
f"QNode by replacing it with '{op.__str__().replace('(', '.decomposition(')}'"
)

# some gradient methods need the device or the device wires
options["device"] = device
options["dev_wires"] = device.wires
Expand Down
33 changes: 31 additions & 2 deletions pennylane/tape/tape.py
Original file line number Diff line number Diff line change
Expand Up @@ -648,11 +648,40 @@ def inv(self):
self.trainable_params = {parameter_mapping[i] for i in self.trainable_params}
self._par_info = {parameter_mapping[k]: v for k, v in self._par_info.items()}

for op in self._ops:
op.inverse = not op.inverse
for idx, op in enumerate(self._ops):
try:
self._ops[idx] = op.adjoint()
except NotImplementedError:
op.inverse = not op.inverse

self._ops = list(reversed(self._ops))

def adjoint(self):
"""Create a tape that is the adjoint of this one.
Adjointed tapes are the conjugated and transposed version of the
original tapes. Adjointed ops are equivalent to the inverted operation for unitary
gates.
Returns:
~.QuantumTape: the adjointed tape
"""
new_tape = self.copy(copy_operations=True)
qml.transforms.invisible(new_tape.inv)()

# the current implementation of the adjoint
# transform requires that the returned inverted object
# is automatically queued.
QuantumTape._lock.acquire()
try:
QueuingContext.append(new_tape)
except Exception as _:
QuantumTape._lock.release()
raise
QuantumTape._lock.release()

return new_tape

# ========================================================
# Parameter handling
# ========================================================
Expand Down
7 changes: 6 additions & 1 deletion pennylane/templates/embeddings/amplitude.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def __init__(self, features, wires, pad_with=None, normalize=False, pad=None, do
if pad is not None:
warnings.warn(
"The pad argument will be replaced by the pad_with option in future versions of PennyLane.",
PendingDeprecationWarning,
UserWarning,
)
if pad_with is None:
pad_with = pad
Expand All @@ -143,6 +143,11 @@ def __init__(self, features, wires, pad_with=None, normalize=False, pad=None, do
features = self._preprocess(features, wires, pad_with, normalize)
super().__init__(features, wires=wires, do_queue=do_queue)

def adjoint(self): # pylint: disable=arguments-differ
return qml.adjoint(qml.templates.MottonenStatePreparation)(
self.parameters[0], wires=self.wires
)

def expand(self):

with qml.tape.QuantumTape() as tape:
Expand Down
3 changes: 2 additions & 1 deletion pennylane/templates/layers/particle_conserving_u1.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,13 +266,14 @@ def expand(self):

with qml.tape.QuantumTape() as tape:

qml.BasisState(self.init_state, wires=self.wires)
qml.templates.BasisEmbedding(self.init_state, wires=self.wires)

for l in range(self.n_layers):
for i, wires_ in enumerate(nm_wires):
u1_ex_gate(
self.parameters[0][l, i, 0], self.parameters[0][l, i, 1], wires=wires_
)

return tape

@staticmethod
Expand Down
2 changes: 1 addition & 1 deletion pennylane/templates/layers/particle_conserving_u2.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ def expand(self):

with qml.tape.QuantumTape() as tape:

qml.BasisState(self.init_state, wires=self.wires)
qml.templates.BasisEmbedding(self.init_state, wires=self.wires)

for l in range(self.n_layers):

Expand Down
Loading

0 comments on commit 53b8d65

Please sign in to comment.