Skip to content

Commit c0b6c18

Browse files
Merge pull request tensorflow#484 from quantumlib/qsim-invert-masks
Support invert_mask in qsimcirq
2 parents 1630c0e + 25b838c commit c0b6c18

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

qsimcirq/qsim_simulator.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -379,8 +379,9 @@ def _sample_measure_results(
379379
for i in range(repetitions):
380380
for key, op in meas_ops.items():
381381
meas_indices = [qubit_map[qubit] for qubit in op.qubits]
382+
invert_mask = op.gate.full_invert_mask()
382383
for j, q in enumerate(meas_indices):
383-
results[key][i][j] = full_results[i][q]
384+
results[key][i][j] = full_results[i][q] ^ invert_mask[j]
384385
else:
385386
options["c"] = self._translate_circuit(
386387
program,
@@ -391,8 +392,11 @@ def _sample_measure_results(
391392
options["s"] = self.get_seed()
392393
measurements = sampler_fn(options)
393394
for key, bound in bounds.items():
395+
invert_mask = meas_ops[key].gate.full_invert_mask()
394396
for j in range(bound[1] - bound[0]):
395-
results[key][i][j] = int(measurements[bound[0] + j])
397+
results[key][i][j] = int(
398+
measurements[bound[0] + j] ^ invert_mask[j]
399+
)
396400

397401
return results
398402

qsimcirq_tests/qsimcirq_test.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,46 @@ def test_cirq_qsim_run(mode: str):
361361
assert value.shape == (5, 1)
362362

363363

364+
def test_qsim_invert_mask():
365+
q0, q1 = cirq.LineQubit.range(2)
366+
circuit = cirq.Circuit(
367+
cirq.measure(q0, q1, key="d", invert_mask=[False, True]),
368+
)
369+
cirq_sample = cirq.Simulator().sample(circuit, repetitions=5)
370+
qsim_sample = qsimcirq.QSimSimulator().sample(circuit, repetitions=5)
371+
assert qsim_sample.equals(cirq_sample)
372+
373+
374+
def test_qsim_invert_mask_different_qubits():
375+
q0, q1 = cirq.LineQubit.range(2)
376+
circuit = cirq.Circuit(
377+
cirq.measure(q1, key="a", invert_mask=[True]),
378+
cirq.measure(q0, key="b", invert_mask=[True]),
379+
cirq.measure(q0, q1, key="c", invert_mask=[False, True]),
380+
cirq.measure(q1, q0, key="d", invert_mask=[False, True]),
381+
)
382+
cirq_sample = cirq.Simulator().sample(circuit, repetitions=5)
383+
qsim_sample = qsimcirq.QSimSimulator().sample(circuit, repetitions=5)
384+
assert qsim_sample.equals(cirq_sample)
385+
386+
387+
def test_qsim_invert_mask_intermediate_measure():
388+
q0, q1 = cirq.LineQubit.range(2)
389+
# The dataframe generated by this should be all zeroes.
390+
circuit = cirq.Circuit(
391+
cirq.measure(q0, q1, key="a", invert_mask=[False, False]),
392+
cirq.X(q0),
393+
cirq.measure(q0, q1, key="b", invert_mask=[True, False]),
394+
cirq.X(q1),
395+
cirq.measure(q0, q1, key="c", invert_mask=[True, True]),
396+
cirq.X(q0),
397+
cirq.measure(q0, q1, key="d", invert_mask=[False, True]),
398+
)
399+
cirq_sample = cirq.Simulator().sample(circuit, repetitions=5)
400+
qsim_sample = qsimcirq.QSimSimulator().sample(circuit, repetitions=5)
401+
assert qsim_sample.equals(cirq_sample)
402+
403+
364404
@pytest.mark.parametrize("mode", ["noiseless", "noisy"])
365405
def test_qsim_run_vs_cirq_run(mode: str):
366406
# Simple circuit, want to check mapping of qubit(s) to their measurements

0 commit comments

Comments
 (0)