Skip to content

Commit

Permalink
Enforce passing by keyword argument in QNode and qml.execute (#6610)
Browse files Browse the repository at this point in the history
**Context:**

Passing too many arguments positionally is error prone. It can be
difficult to remember what the proper order of the arguements is, and it
can be easy to reorder keyword arguments.

**Description of the Change:**

Start mandating that various keyword arguments *are* passed as keyword
arguments in `QNode` and `qml.execute`

**Benefits:**

We forbid entire classes of mistakes.

**Possible Drawbacks:**

**Related GitHub Issues:**
  • Loading branch information
albi3ro authored Nov 27, 2024
1 parent 2d074cc commit 672ba48
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 18 deletions.
3 changes: 3 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@
visualizations, allowing global and per-wire customization with options like `color`, `linestyle`, and `linewidth`.
[(#6486)](https://github.com/PennyLaneAI/pennylane/pull/6486)

* `QNode` and `qml.execute` now forbid certain keyword arguments from being passed positionally.
[(#6610)](https://github.com/PennyLaneAI/pennylane/pull/6610)

* Shortened the string representation for the `qml.S`, `qml.T`, and `qml.SX` operators.
[(#6542)](https://github.com/PennyLaneAI/pennylane/pull/6542)

Expand Down
29 changes: 11 additions & 18 deletions pennylane/workflow/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ def execute(
device: Union["qml.devices.LegacyDevice", "qml.devices.Device"],
diff_method: Optional[Union[Callable, str, qml.transforms.core.TransformDispatcher]] = None,
interface: Optional[str] = "auto",
*,
transform_program=None,
inner_transform=None,
config=None,
Expand Down Expand Up @@ -411,9 +412,16 @@ def cost_fn(params, x):

gradient_kwargs = gradient_kwargs or {}
mcm_config = mcm_config or {}
config = config or _get_execution_config(
diff_method, grad_on_execution, interface, device, device_vjp, mcm_config, gradient_kwargs
)
if not config:
config = qml.devices.ExecutionConfig(
interface=interface,
gradient_method=diff_method,
grad_on_execution=None if grad_on_execution == "best" else grad_on_execution,
use_device_jacobian_product=device_vjp,
mcm_config=mcm_config,
gradient_keyword_arguments=gradient_kwargs,
)
config = device.setup_execution_config(config)

is_gradient_transform = isinstance(diff_method, qml.transforms.core.TransformDispatcher)
transform_program, inner_transform = _make_transform_programs(
Expand Down Expand Up @@ -601,18 +609,3 @@ def _make_transform_programs(
transform_program = device.preprocess_transforms(config)

return transform_program, inner_transform


def _get_execution_config(
diff_method, grad_on_execution, interface, device, device_vjp, mcm_config, gradient_kwargs
):
"""Helper function to get the execution config."""
config = qml.devices.ExecutionConfig(
interface=interface,
gradient_method=diff_method,
grad_on_execution=None if grad_on_execution == "best" else grad_on_execution,
use_device_jacobian_product=device_vjp,
mcm_config=mcm_config,
gradient_keyword_arguments=gradient_kwargs,
)
return device.setup_execution_config(config)
1 change: 1 addition & 0 deletions pennylane/workflow/qnode.py
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,7 @@ def __init__(
device: SupportedDeviceAPIs,
interface: SupportedInterfaceUserInput = "auto",
diff_method: Union[TransformDispatcher, SupportedDiffMethods] = "best",
*,
grad_on_execution: Literal[True, False, "best"] = "best",
cache: Union[Cache, Literal["auto", True, False]] = "auto",
cachesize: int = 10000,
Expand Down

0 comments on commit 672ba48

Please sign in to comment.