Quiz: Google Cirq
Answers with explanations at the end.
1. In Cirq, what does cirq.H(q[0]) return, and how does that differ from Qiskit's qc.h(0)?
2. A Cirq Bell circuit returns {0: 2043, 3: 2053}. Why are the keys integers, and what are the
corresponding Qiskit bitstrings?
3. What is len(circuit) in Cirq, and how does its meaning differ from Qiskit's qc.depth()?
4. Explain why cirq.Circuit([cirq.Moment([cirq.H(q0)]), cirq.Moment([cirq.CNOT(q0, q1)])])
compares equal to cirq.Circuit([cirq.H(q0), cirq.CNOT(q0, q1)]).
5. Three H gates on three different qubits. How many moments under EARLIEST? Under NEW? Are
the final states the same?
6. NEW_THEN_INLINE produced 1 moment in one experiment and 3 in another, with the same three
gates. What distinguished the two cases?
7. Why is the answer to question 6 dangerous during code review?
8. Apply X to qubit 0 of a two-qubit register. At which state-vector index does the amplitude
land in Cirq? In Qiskit? State each framework's convention.
9. Cirq reports a measurement result of 2 for a two-qubit circuit. What is the equivalent Qiskit
bitstring, and which qubit is excited?
10. Why can a Bell state not detect a reversed endianness convention? Name two other common test circuits with the same weakness.
11. State the general rule that questions 10 illustrates, in one sentence, without mentioning endianness.
12. reverse_bits is its own inverse. Why does that property argue for confining it to exactly one
function in a codebase?
13. What is the difference between cirq.Simulator().simulate(c) and
cirq.Simulator().run(c, repetitions=n)? What happens if you call run on a circuit with no
measurement?
14. You are unsure which qubit occupies which position in a Cirq state vector. What does the result object give you that settles it?
15. Cirq has no transpile() with optimization levels. What does it have instead, and name three
things Qiskit's transpiler provides that Cirq's equivalent does not.
16. optimize_for_target_gateset with CZTargetGateset turns H, CNOT into a sequence containing
PhXZ gates. What is PhXZ, and what is its Qiskit counterpart?
17. Chapter 8 documented a bug where binding a list of twelve values to parameters named
theta1 … theta12 put eleven of them in the wrong gate. Why can this not happen in Cirq?
18. circuit.with_noise(cirq.depolarize(0.05)) doubled the moment count. Why?
19. What does cirq.GridQubit(3, 4) know that a Qiskit qubit index does not? What does
cirq_google.Sycamore carry, and what does it not carry that Chapter 12 relied on?
20. You need to run a circuit on real superconducting hardware this afternoon, and you know both frameworks equally well. Which do you reach for, and is your reason about framework quality?
Answers
1. It returns an operation — a gate bound to qubits — which is a first-class value you can
store in a list, pass around, and reuse. Qiskit's qc.h(0) mutates the circuit and returns an
instruction-set reference. The difference is why Cirq circuits feel like data and Qiskit circuits feel
like builders.
2. Cirq reports measurement results as integers formed from the measured bits in the order given to
cirq.measure. 0 is '00' and 3 is '11'. (For a Bell state the two conventions happen to
agree — see question 10.)
3. len(circuit) is the number of moments, which is the depth — a structural property of the
object. Qiskit's depth() is a computed metric, derived by analyzing the gate dependency graph. In
Cirq the depth is what the circuit is; in Qiskit it is something you ask about it.
4. Because the default insertion strategy (EARLIEST) places H in moment 0 and CNOT in moment
1 — the CNOT depends on qubit 0, so it cannot slide left. Both constructions produce the same list of
moments, and the moment structure is the circuit's identity. Default insertion is a convenience for
producing a moment list you could have written by hand.
5. EARLIEST → 1 moment (the gates are independent and pack into one time slice). NEW →
3 moments. The final states are identical — verified with np.allclose. Same gates, same
result, three times the depth.
6. How the operations were handed to append. All three in a single call → one new moment then
two inlines → 1 moment. Three separate calls → each opens a new moment with nothing to inline →
3 moments. The strategy is scoped to an append call, not to the circuit.
7. Because converting a list comprehension into a for loop is one of the most common and most
innocuous-looking refactors in Python — and under NEW_THEN_INLINE it triples the depth without
changing a single gate. Every state-based test still passes, because the state is unchanged. The
only observable is len(circuit), and nobody asserts on it. Assert on it.
8. Cirq: index 2 (binary 10). Qiskit: index 1 (binary 01). Cirq is big-endian —
qubit 0 is the most significant bit, appearing leftmost in the order you listed the qubits. Qiskit is
little-endian — qubit 0 is the least significant bit, matching the convention $|q_1 q_0\rangle$.
9. 2 is binary 10; reversed for Qiskit it is '01'. Qubit 0 is excited in both readings —
the frameworks agree on the physics and disagree only about which end to write it from.
10. Because '00' and '11' are palindromes: reversing their bits gives back the same
strings, so the histogram is invariant under bit reversal and matches whether or not the convention is
right. Same weakness: GHZ states (000/111) and uniform superpositions (reversal permutes a
uniform distribution into itself).
11. A test whose expected output is invariant under the bug you are worried about is not a test for that bug.
12. Because two reversals cancel. A codebase with reversals in several modules has a bug whose presence depends on how many of those modules a given code path traverses — so it appears in some circuits and not others, survives some refactors and not others, and resists characterization. Confining it to one function makes the conversion count structurally obvious.
13. simulate() returns the full state vector — amplitudes and phases — and needs no
measurement. run() returns samples and requires one. Calling run on an unmeasured circuit
raises ValueError: Circuit has no measurements to sample. The method names encode Chapter 5's
distinction between a state and samples drawn from it.
14. result.qubit_map — e.g. {cirq.LineQubit(0): 0, cirq.LineQubit(1): 1} — the authoritative
statement of which qubit occupies which position, available directly on the simulate() result.
15. Target gatesets, applied via cirq.optimize_for_target_gateset, which do translation and
optimization. Qiskit additionally provides: an optimization_level dial, a unified
layout-and-routing stage with selectable heuristics, and seed_transpiler for reproducibility.
(Cirq has routing via cirq.RouteCQC, but as a separately invoked tool rather than a pipeline stage.)
16. PhXZ is a three-parameter single-qubit gate covering all of $SU(2)$ — a phased X-Z
rotation. Its Qiskit counterpart is the rz/sx decomposition (or U), which serves the same role:
the canonical form every single-qubit operation is compiled into.
17. Because cirq.ParamResolver binds by name through a dict, not by position through a list.
ParamResolver({theta1: 0.1, theta2: 0.2, ...}) has no ordering, so there is no ordering to get
wrong. Qiskit's bug arises from sorting parameter names lexicographically —
theta1, theta10, theta11, theta12, theta2, … — and then zipping a positional list against that order.
18. with_noise inserts a noise moment after every existing moment. Two original moments
become two original plus two noise moments, so operations went from 2 to 6 (one noise channel per
qubit per moment).
19. cirq.GridQubit(3, 4) knows its own geometry — is_adjacent(GridQubit(3, 5)) returns
True without consulting any device object. A Qiskit qubit index knows nothing; adjacency lives in a
separate coupling map. cirq_google.Sycamore carries topology (54 qubits, 88 coupling pairs) but
not calibration data — no per-qubit readout errors, gate errors, or $T_1$/$T_2$, which is exactly
what Chapter 12's layout scoring and preflight checks were built on.
20. Qiskit — because IBM offers open hardware access (sign up, get a token, run today) while Google's service has historically been available through research partnerships. The reason is about access policy, not framework quality. Cirq is excellent to learn and simulate with; the asymmetry is in who can get to a device.