tensorflow / quantum

Hybrid Quantum-Classical Machine Learning in TensorFlow
https://www.tensorflow.org/quantum
Apache License 2.0
1.78k stars 571 forks source link

Unformatted Error Message When Creating PQC #434

Closed mikeevmm closed 3 years ago

mikeevmm commented 3 years ago

Environment

Using Linux Mint 20, python 3.8.5, and a virtual environment with tensorflow-quantum==0.4.0, tensorflow==2.3.1.

Problem

Creating a new parameterized quantum circuit (tfq.layers.PQC) fails with raised ValueError and message:

ValueError: Attempted to scan for symbols in circuit with unsupported ops inside. Expected op found in tfq.get_supported_gates but found:

with traceback (cleaned up to remove references to my setup):

Traceback (most recent call last):
  File "train.py", line 140, in <module>
    print(build_expectation_tensor(ansatz, observable))
  File "train.py", line 129, in build_expectation_tensor
    return tfq.layers.PQC(full_circuit, measurement)
  File "(...venv path...)/tensorflow_quantum/python/layers/high_level/pqc.py", line 186, in __init__
    sorted(util.get_circuit_symbols(model_circuit)))
  File "(...venv path...)/tensorflow_quantum/python/util.py", line 357, in get_circuit_symbols
    all_symbols |= _symbols_in_op(op.gate)
  File "(...venv path...)/tensorflow_quantum/python/util.py", line 339, in _symbols_in_op
    raise ValueError("Attempted to scan for symbols in circuit with unsupported"

MWE

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import tensorflow_quantum as tfq
import cirq
import sympy

if __name__ == "__main__":
    q0, q1 = cirq.GridQubit.rect(1,2)
    circuit = cirq.Circuit()

    symbol = sympy.Symbol("u")
    op = cirq.ZPowGate(exponent=symbol).on(q0).controlled_by(q1)
    circuit.append(op)

    measurement = [cirq.Z(qubit) for qubit in (q0, q1)]
    pqc = tfq.layers.PQC(circuit, measurement)

Further Comments

  1. The ValueError message has a .format call, but no {} in the text; these are likely missing at the end of the string.
  2. If instead of a controlled Rz rotation I use a simple control Pauli Z (i.e., cirq.Z.on(qubit).controlled_by(control)), I get a different error message1, that seems to relate to #200 . Is something like that happening here, but not being caught before _symbols_in_op is called?
  3. It wasn't obvious to me (before looking at #200) that that op found in tfq.get_supported_gates meant I should call tfq.get_supported_gates to see a list of what's supported; this may be just me, but please consider actually displaying the supported gates, or being more explicit about this ("call tfq.get_supported_gates to see supported gates").
  4. Has there been a reduction in the supported gates? I thought I'd already used controlled Rz gates with TFQ in the past, but I may be misremembering.

1 ValueError: Cannot serialize op cirq.Z(cirq.GridQubit(0, 0)).controlled_by(cirq.GridQubit(0, 1)) of type <class 'cirq.ops.controlled_gate.ControlledGate'>

Cheers

mikeevmm commented 3 years ago

Additionally: calling tfq.get_supported_gates() errors out, the function is under utils, so the call should be tfq.utils.get_supported_gates().

MichaelBroughton commented 3 years ago

Hi @mikeevmm , thanks for raising the issue. You are using a gate that isn't supported by TFQ. Any Cirq gate that has been turned into a controlled gate with .controlled_by was never supported anywhere in TFQ. If you recalled using controlled Rz operations before, perhaps they were in the form of a CZPowGate, which is supported since it doesn't use controlled_by ?

Either way, it looks like the underlying issue here is that the error strings presented to a user that does not use a supported gate are misleading. Should be a quick fix :)

MichaelBroughton commented 3 years ago

@mikeevmm if you are still interested we have just closed #422 which adds support for controlled_by on all of our gates, so the above snippet should now work on tfq-nightly.