PennyLaneAI / pennylane

PennyLane is a cross-platform Python library for quantum computing, quantum machine learning, and quantum chemistry. Train a quantum computer the same way as a neural network.
https://pennylane.ai
Apache License 2.0
2.24k stars 581 forks source link

[BUG] Adjoint of some qutrit non_parametric ops not supported by default.qutrit device #4347

Closed Gabriel-Bottrill closed 1 year ago

Gabriel-Bottrill commented 1 year ago

Expected behavior

qml.adjoint of qutrit operations should be supported by the default.qutrit device.

Actual behavior

The adjoint of TAdd and TClock operations is not supported by default.qutrit device.

Additional information

This is also the case for THadamard with no subspace however it seems purposeful in that case.

The source code makes the generalized THadamard's adjoint raise an error.

Source code

@qml.qnode(qml.device("default.qutrit",wires=2))
def circuit():
    qml.adjoint(qml.TAdd)(wires=(0,1))
    return qml.expval(qml.GellMann(wires=0,index=3))

circuit()

Tracebacks

DeviceError                               Traceback (most recent call last)

<ipython-input-20-f56b85b37345> in <cell line: 6>()
      4     return qml.expval(qml.GellMann(wires=0,index=3))
      5 
----> 6 circuit()

/usr/local/lib/python3.10/dist-packages/pennylane/qnode.py in __call__(self, *args, **kwargs)
    964                 self.execute_kwargs.pop("mode")
    965             # pylint: disable=unexpected-keyword-arg
--> 966             res = qml.execute(
    967                 [self.tape],
    968                 device=self.device,

/usr/local/lib/python3.10/dist-packages/pennylane/interfaces/execution.py in execute(tapes, device, gradient_fn, interface, grad_on_execution, gradient_kwargs, cache, cachesize, max_diff, override_shots, expand_fn, max_expansion, device_batch_transform)
    640             _execute = _get_jax_execute_fn(interface, tapes)
    641 
--> 642         res = _execute(
    643             tapes, device, execute_fn, gradient_fn, gradient_kwargs, _n=1, max_diff=max_diff
    644         )

/usr/local/lib/python3.10/dist-packages/pennylane/interfaces/autograd.py in execute(tapes, device, execute_fn, gradient_fn, gradient_kwargs, _n, max_diff)
    317         [autograd.builtins.list(t.get_parameters()) for t in tapes]
    318     )
--> 319     return _execute(
    320         parameters,
    321         tapes=tapes,

/usr/local/lib/python3.10/dist-packages/autograd/tracer.py in f_wrapped(*args, **kwargs)
     46             return new_box(ans, trace, node)
     47         else:
---> 48             return f_raw(*args, **kwargs)
     49     f_wrapped.fun = f_raw
     50     f_wrapped._is_autograd_primitive = True

/usr/local/lib/python3.10/dist-packages/pennylane/interfaces/autograd.py in _execute(parameters, tapes, device, execute_fn, gradient_fn, gradient_kwargs, _n, max_diff)
    361     """
    362     unwrapped_tapes = tuple(convert_to_numpy_parameters(t) for t in tapes)
--> 363     res, jacs = execute_fn(unwrapped_tapes, **gradient_kwargs)
    364 
    365     return res, jacs

/usr/local/lib/python3.10/dist-packages/pennylane/interfaces/execution.py in wrapper(tapes, **kwargs)
    285             # execute all unique tapes that do not exist in the cache
    286             # convert to list as new device interface returns a tuple
--> 287             res = list(fn(execution_tapes.values(), **kwargs))
    288 
    289         final_res = []

/usr/local/lib/python3.10/dist-packages/pennylane/interfaces/execution.py in fn(tapes, **kwargs)
    208         def fn(tapes: Sequence[QuantumTape], **kwargs):  # pylint: disable=function-redefined
    209             tapes = [expand_fn(tape) for tape in tapes]
--> 210             return original_fn(tapes, **kwargs)
    211 
    212     @wraps(fn)

/usr/lib/python3.10/contextlib.py in inner(*args, **kwds)
     77         def inner(*args, **kwds):
     78             with self._recreate_cm():
---> 79                 return func(*args, **kwds)
     80         return inner
     81 

/usr/local/lib/python3.10/dist-packages/pennylane/_qubit_device.py in batch_execute(self, circuits)
    601             self.reset()
    602 
--> 603             res = self.execute(circuit)
    604             results.append(res)
    605 

/usr/local/lib/python3.10/dist-packages/pennylane/_qubit_device.py in execute(self, circuit, **kwargs)
    315             return self._execute_legacy(circuit, **kwargs)
    316 
--> 317         self.check_validity(circuit.operations, circuit.observables)
    318 
    319         # apply all circuit operations

/usr/local/lib/python3.10/dist-packages/pennylane/_device.py in check_validity(self, queue, observables)
    897 
    898             if not self.stopping_condition(o):
--> 899                 raise DeviceError(
    900                     f"Gate {operation_name} not supported on device {self.short_name}"
    901                 )

DeviceError: Gate Adjoint(TAdd) not supported on device default.qutrit

System information

Name: PennyLane
Version: 0.32.0.dev0
Summary: PennyLane is a Python quantum machine learning library by Xanadu Inc.
Home-page: https://github.com/PennyLaneAI/pennylane
Author: 
Author-email: 
License: Apache License 2.0
Location: /usr/local/lib/python3.10/dist-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, requests, rustworkx, scipy, semantic-version, toml
Required-by: PennyLane-Lightning

Platform info:           Linux-5.15.107+-x86_64-with-glibc2.31
Python version:          3.10.12
Numpy version:           1.22.4
Scipy version:           1.10.0
Installed devices:
None

Existing GitHub issues

isaacdevlugt commented 1 year ago

Hey @Gabriel-Bottrill! Sorry for the late response, but it looks like our team is already working on addressing your issue 🎉.

albi3ro commented 1 year ago

@mudit2812 @Gabriel-Bottrill Looks like the PR is merged. Are we good to close this issue?

mudit2812 commented 1 year ago

Yep, closing it now.