Skip to content

Commit a9fcfca

Browse files
ddhawan11soranjhalbi3ro
authored andcommitted
Modified the signature for ResourceOperator class (#8279)
**Context:** Modified the signature for controlled decomposition of ResourceOperator class. **Description of the Change:** **Benefits:** **Possible Drawbacks:** **Related GitHub Issues:** --------- Co-authored-by: Soran Jahangiri <40344468+soranjh@users.noreply.github.com> Co-authored-by: Christina Lee <christina@xanadu.ai>
1 parent 1bba5e3 commit a9fcfca

File tree

3 files changed

+97
-14
lines changed

3 files changed

+97
-14
lines changed

‎doc/releases/changelog-dev.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
* The `qml.estimator.ResourceOperator`, `qml.estimator.CompressedResourceOp`, and `qml.estimator.GateCount` classes
1818
were added as base classes to represent quantum operators.
1919
[(#8227)](https://github.com/PennyLaneAI/pennylane/pull/8227)
20+
[(#8279)](https://github.com/PennyLaneAI/pennylane/pull/8279)
2021
* The :class:`~.estimator.Resources` class was added as a container class for resources.
2122
[(#8205)](https://github.com/PennyLaneAI/pennylane/pull/8205)
2223
* The test files were renamed to avoid the dual definition error with labs module.

‎pennylane/estimator/resource_operator.py‎

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -267,31 +267,45 @@ def resource_decomp(cls, *args, **kwargs) -> list[GateCount]:
267267
r"""Returns a list of actions that define the resources of the operator."""
268268

269269
@classmethod
270-
def adjoint_resource_decomp(cls, *args, **kwargs) -> list[GateCount]:
271-
r"""Returns a list representing the resources for the adjoint of the operator."""
270+
def adjoint_resource_decomp(cls, target_resource_params: dict | None = None) -> list[GateCount]:
271+
r"""Returns a list representing the resources for the adjoint of the operator.
272+
273+
Args:
274+
target_resource_params (dict | None): A dictionary containing the resource parameters
275+
of the target operator.
276+
"""
272277
raise ResourcesUndefinedError
273278

274279
@classmethod
275280
def controlled_resource_decomp(
276-
cls, ctrl_num_ctrl_wires: int, ctrl_num_ctrl_values: int, *args, **kwargs
281+
cls,
282+
num_ctrl_wires: int,
283+
num_zero_ctrl: int,
284+
target_resource_params: dict | None = None,
277285
) -> list[GateCount]:
278286
r"""Returns a list representing the resources for a controlled version of the operator.
279287
280288
Args:
281-
ctrl_num_ctrl_wires (int): the number of qubits the
289+
num_ctrl_wires (int): the number of qubits the
282290
operation is controlled on
283-
ctrl_num_ctrl_values (int): the number of control qubits, that are
291+
num_zero_ctrl (int): the number of control qubits, that are
284292
controlled when in the :math:`|0\rangle` state
293+
target_resource_params (dict | None): A dictionary containing the resource parameters
294+
of the target operator.
285295
"""
286296
raise ResourcesUndefinedError
287297

288298
@classmethod
289-
def pow_resource_decomp(cls, pow_z: int, *args, **kwargs) -> list[GateCount]:
299+
def pow_resource_decomp(
300+
cls, pow_z: int, target_resource_params: dict | None = None
301+
) -> list[GateCount]:
290302
r"""Returns a list representing the resources for an operator
291303
raised to a power.
292304
293305
Args:
294306
pow_z (int): exponent that the operator is being raised to
307+
target_resource_params (dict | None): A dictionary containing the resource parameters
308+
of the target operator.
295309
"""
296310
raise ResourcesUndefinedError
297311

‎tests/estimator/test_estimator_resOp.py‎

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
from pennylane.estimator import CompressedResourceOp, ResourceOperator, Resources
2626
from pennylane.estimator.resource_operator import (
2727
GateCount,
28-
ResourcesUndefinedError,
2928
_dequeue,
3029
_make_hashable,
3130
resource_rep,
@@ -304,6 +303,67 @@ class CNOT(DummyOp):
304303
num_wires = 2
305304

306305

306+
class DummyOp_decomps(ResourceOperator):
307+
"""Class for testing the resource_decomp methods"""
308+
309+
resource_keys = {"max_register_size"}
310+
311+
def __init__(self, max_register_size, wires=None):
312+
self.max_register_size = max_register_size
313+
self.num_wires = 2 * max_register_size
314+
super().__init__(wires=wires)
315+
316+
@property
317+
def resource_params(self):
318+
r"""Returns a dictionary containing the minimal information needed to compute the resources."""
319+
return {"max_register_size": self.max_register_size}
320+
321+
@classmethod
322+
def resource_rep(cls, max_register_size):
323+
r"""Returns a compressed representation containing only the parameters of
324+
the Operator that are needed to compute the resources.
325+
"""
326+
num_wires = 2 * max_register_size
327+
return CompressedResourceOp(cls, num_wires, {"max_register_size": max_register_size})
328+
329+
@classmethod
330+
def resource_decomp(cls, max_register_size):
331+
r"""Returns a dictionary representing the resources of the operator. The
332+
keys are the operators and the associated values are the counts.
333+
"""
334+
rx = resource_rep(RX, {"x": 1})
335+
return [GateCount(rx, max_register_size)]
336+
337+
@classmethod
338+
def controlled_resource_decomp(cls, num_ctrl_wires, num_zero_ctrl, target_resource_params):
339+
r"""Returns a list representing the resources of the operator. Each object in the list represents a gate and the
340+
number of times it occurs in the circuit.
341+
"""
342+
max_register_size = target_resource_params["max_register_size"]
343+
cnot = resource_rep(CNOT, {"x": None})
344+
rx = resource_rep(RX, {"x": 1})
345+
return [GateCount(cnot, max_register_size), GateCount(rx, max_register_size)]
346+
347+
@classmethod
348+
def adjoint_resource_decomp(cls, target_resource_params):
349+
r"""Returns a list representing the resources of the operator. Each object in the list represents a gate and the
350+
number of times it occurs in the circuit.
351+
"""
352+
max_register_size = target_resource_params["max_register_size"]
353+
rx = resource_rep(RX, {"x": 1})
354+
h = resource_rep(Hadamard, {"x": None})
355+
return [GateCount(rx, max_register_size), GateCount(h, 2 * max_register_size)]
356+
357+
@classmethod
358+
def pow_resource_decomp(cls, pow_z, target_resource_params):
359+
r"""Returns a list representing the resources of the operator. Each object in the list represents a gate and the
360+
number of times it occurs in the circuit.
361+
"""
362+
max_register_size = target_resource_params["max_register_size"]
363+
rx = resource_rep(RX, {"x": 1})
364+
return [GateCount(rx, max_register_size * pow_z)]
365+
366+
307367
class TestResourceOperator:
308368
"""Tests for the ResourceOperator class"""
309369

@@ -485,22 +545,30 @@ def test_matmul_error(self):
485545
def test_default_resource_keys(self):
486546
"""Test that default resource keys returns the correct result."""
487547
op1 = X
488-
assert op1.resource_keys == set()
548+
assert op1.resource_keys == set() # pylint: disable=comparison-with-callable
489549

490550
def test_adjoint_resource_decomp(self):
491551
"""Test that default adjoint operator returns the correct error."""
492-
with pytest.raises(ResourcesUndefinedError):
493-
X.adjoint_resource_decomp()
552+
dummy_params = {"max_register_size": 10}
553+
assert DummyOp_decomps.adjoint_resource_decomp(target_resource_params=dummy_params) == [
554+
GateCount(DummyCmprsRep("RX", 1), 10),
555+
GateCount(DummyCmprsRep("Hadamard", None), 20),
556+
]
494557

495558
def test_controlled_resource_decomp(self):
496559
"""Test that default controlled operator returns the correct error."""
497-
with pytest.raises(ResourcesUndefinedError):
498-
X.controlled_resource_decomp(ctrl_num_ctrl_wires=2, ctrl_num_ctrl_values=0)
560+
dummy_params = {"max_register_size": 10}
561+
assert DummyOp_decomps.controlled_resource_decomp(
562+
num_ctrl_wires=2, num_zero_ctrl=0, target_resource_params=dummy_params
563+
) == [GateCount(DummyCmprsRep("CNOT", None), 10), GateCount(DummyCmprsRep("RX", 1), 10)]
499564

500565
def test_pow_resource_decomp(self):
501566
"""Test that default power operator returns the correct error."""
502-
with pytest.raises(ResourcesUndefinedError):
503-
X.pow_resource_decomp(2)
567+
568+
dummy_params = {"max_register_size": 10}
569+
assert DummyOp_decomps.pow_resource_decomp(
570+
pow_z=2, target_resource_params=dummy_params
571+
) == [GateCount(DummyCmprsRep("RX", 1), 20)]
504572

505573
def test_tracking_name(self):
506574
"""Test that correct tracking name is returned."""

0 commit comments

Comments
 (0)