quantumlib / Cirq

A Python framework for creating, editing, and invoking Noisy Intermediate Scale Quantum (NISQ) circuits.
Apache License 2.0
4.23k stars 1.01k forks source link

Qubits other than GridQubit don't work on Quantum Engine Simulator #1325

Closed kevinsung closed 4 years ago

kevinsung commented 5 years ago

I tried to run the following code through Quantum Engine:

import random

a, b = cirq.LineQubit.range(2)
circuit = cirq.Circuit.from_ops(cirq.X(a))
engine = cirq.google.Engine(api_key=api_key,
                            api='autopush-quantum.sandbox', 
                            **colab_auth)
name = 'example-%s' % ''.join(random.choice(
    string.ascii_uppercase + string.digits) for _ in range(6))
job = engine.run_sweep(
    job_config=cirq.google.JobConfig(project_id=project_id, program_id=name),
    program=circuit,
    repetitions=1000)

and got

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-18-cef5b731c112> in <module>()
     11     job_config=cirq.google.JobConfig(project_id=project_id, program_id=name),
     12     program=circuit,
---> 13     repetitions=1000)

/usr/local/lib/python3.6/dist-packages/cirq/google/engine/engine.py in run_sweep(self, program, job_config, params, repetitions, priority, target_route)
    356             sweep in sweeps]
    357         program_dict['operations'] = [op for op in
--> 358                                       schedule_to_proto_dicts(schedule)]
    359         code = {
    360             '@type': 'type.googleapis.com/cirq.api.google.v1.Program'}

/usr/local/lib/python3.6/dist-packages/cirq/google/engine/engine.py in <listcomp>(.0)
    355             sweep_to_proto_dict(sweep, repetitions) for
    356             sweep in sweeps]
--> 357         program_dict['operations'] = [op for op in
    358                                       schedule_to_proto_dicts(schedule)]
    359         code = {

/usr/local/lib/python3.6/dist-packages/cirq/google/programs.py in schedule_to_proto_dicts(schedule)
    154         op = gate_to_proto_dict(
    155             cast(ops.GateOperation, so.operation).gate,
--> 156             so.operation.qubits)
    157         time_picos = so.time.raw_picos()
    158         if last_time_picos is None:

/usr/local/lib/python3.6/dist-packages/cirq/google/programs.py in gate_to_proto_dict(gate, qubits)
     38             # coverage: ignore
     39             raise ValueError('Wrong number of qubits.')
---> 40         return _x_to_proto_dict(gate, qubits[0])
     41 
     42     if isinstance(gate, ops.YPowGate):

/usr/local/lib/python3.6/dist-packages/cirq/google/programs.py in _x_to_proto_dict(gate, q)
     69 def _x_to_proto_dict(gate: ops.XPowGate, q: ops.QubitId) -> Dict:
     70     exp_w = {
---> 71         'target': cast(devices.GridQubit, q).to_proto_dict(),
     72         'axis_half_turns':
     73             _parameterized_value_to_proto_dict(0),

AttributeError: 'LineQubit' object has no attribute 'to_proto_dict'

Maybe it makes sense to force the user to convert all their qubits to GridQubit, I don't know. I feel like my example should run, at least on the simulator.

google/programs.py has lines like

def _x_to_proto_dict(gate: ops.XPowGate, q: ops.QubitId) -> Dict:
    exp_w = {
        'target': cast(devices.GridQubit, q).to_proto_dict(),

where we cast q to a GridQubit. Shouldn't we instead just change the type annotation from QubitId to GridQubit?

Strilanc commented 5 years ago

I think this also falls under the purview of "we need to improve the serialization format". The simulator should presumably be happy to take arbitrary qubits. Even if we don't understand the user's qubit type we can rewrite into line qubits.

For hardware it might make sense to take line qubits and auto-lay them, but otherwise I agree that it should be force to grid qubit.

dabacon commented 4 years ago

This should be done for the simulator.