diff --git a/glue/crumble/circuit/circuit.js b/glue/crumble/circuit/circuit.js index a0fb3d0b2..048b80dd9 100644 --- a/glue/crumble/circuit/circuit.js +++ b/glue/crumble/circuit/circuit.js @@ -164,6 +164,7 @@ class Circuit { replaceAll('#!pragma ERR', 'ERR'). replaceAll('#!pragma MARK', 'MARK'). replaceAll('#!pragma POLYGON', 'POLYGON'). + replaceAll('#!pragma REVMARK', 'REVMARK'). replaceAll('_', ' '). replaceAll('Q(', 'QUBIT_COORDS('). replaceAll('DT', 'DETECTOR'). diff --git a/glue/crumble/circuit/layer.js b/glue/crumble/circuit/layer.js index 256e48f3f..b6f4e94ab 100644 --- a/glue/crumble/circuit/layer.js +++ b/glue/crumble/circuit/layer.js @@ -2,6 +2,8 @@ import {Operation} from "./operation.js" import {GATE_MAP} from "../gates/gateset.js"; import {groupBy} from "../base/seq.js"; +const MARKER_NAMES = ['MARKX', 'MARKY', 'MARKZ', 'REVMARKX', 'REVMARKY', 'REVMARKZ']; + class Layer { constructor() { this.id_ops = /** @type {!Map} */ new Map(); @@ -216,9 +218,12 @@ class Layer { * @param {!int} marker_index * @returns {!Map} */ - id_pauliFrameAfter(before, marker_index) { + id_pauliFrameAfter(before, marker_index, reverse=false) { let after = new Map(); let handled = new Set(); + const MARKX_NAME = reverse ? 'REVMARKX' : 'MARKX'; + const MARKY_NAME = reverse ? 'REVMARKY' : 'MARKY'; + const MARKZ_NAME = reverse ? 'REVMARKZ' : 'MARKZ'; for (let k of before.keys()) { let v = before.get(k); @@ -253,7 +258,7 @@ class Layer { } for (let op of this.markers) { - if (op.gate.name === 'MARKX' && op.args[0] === marker_index) { + if (op.gate.name === MARKX_NAME && op.args[0] === marker_index) { let key = op.id_targets[0]; let pauli = after.get(key); if (pauli === undefined || pauli === 'I') { @@ -266,7 +271,7 @@ class Layer { pauli = 'Y'; } after.set(key, pauli); - } else if (op.gate.name === 'MARKY' && op.args[0] === marker_index) { + } else if (op.gate.name === MARKY_NAME && op.args[0] === marker_index) { let key = op.id_targets[0]; let pauli = after.get(key); if (pauli === undefined || pauli === 'I') { @@ -279,7 +284,7 @@ class Layer { pauli = 'X'; } after.set(key, pauli); - } else if (op.gate.name === 'MARKZ' && op.args[0] === marker_index) { + } else if (op.gate.name === MARKZ_NAME && op.args[0] === marker_index) { let key = op.id_targets[0]; let pauli = after.get(key); if (pauli === undefined || pauli === 'I') { @@ -330,7 +335,7 @@ class Layer { if (index !== undefined && op.args[0] !== index) { return true; } - if (op.gate.name !== 'MARKX' && op.gate.name !== 'MARKY' && op.gate.name !== 'MARKZ') { + if (!(MARKER_NAMES.includes(op.gate.name))) { return true; } return op.id_targets[0] !== q; @@ -343,7 +348,7 @@ class Layer { */ put(op, allow_overwrite=true) { if (op.gate.is_marker) { - if (op.gate.name === 'MARKX' || op.gate.name === 'MARKY' || op.gate.name === 'MARKZ') { + if (MARKER_NAMES.includes(op.gate.name)) { this.id_dropMarkersAt(op.id_targets[0], op.args[0]); } this.markers.push(op); diff --git a/glue/crumble/circuit/layer.test.js b/glue/crumble/circuit/layer.test.js index 5c4c3c557..42a70b6e9 100644 --- a/glue/crumble/circuit/layer.test.js +++ b/glue/crumble/circuit/layer.test.js @@ -20,13 +20,17 @@ test("layer.put_get", () => { let marker1 = new Operation(GATE_MAP.get("MARKX"), '', new Float32Array([0]), new Uint32Array([4])); let marker2 = new Operation(GATE_MAP.get("MARKZ"), '', new Float32Array([1]), new Uint32Array([5])); + let marker3 = new Operation(GATE_MAP.get("REVMARKX"), '', new Float32Array([2]), new Uint32Array([4])); + let marker4 = new Operation(GATE_MAP.get("REVMARKZ"), '', new Float32Array([3]), new Uint32Array([5])); layer.put(marker1); layer.put(marker2); + layer.put(marker3); + layer.put(marker4); assertThat(layer.id_ops).isEqualTo(new Map([ [2, op], [3, op], ])); - assertThat(layer.markers).isEqualTo([marker1, marker2]); + assertThat(layer.markers).isEqualTo([marker1, marker2, marker3, marker4]); }); test("layer.filtered", () => { diff --git a/glue/crumble/circuit/pauli_frame.test.js b/glue/crumble/circuit/pauli_frame.test.js index 16e35aae7..f3988826c 100644 --- a/glue/crumble/circuit/pauli_frame.test.js +++ b/glue/crumble/circuit/pauli_frame.test.js @@ -36,6 +36,10 @@ test("pauli_frame.do_gate_vs_old_frame_updates", () => { if (g.name === 'DETECTOR' || g.name === 'OBSERVABLE_INCLUDE') { continue; } + if (g.name.startsWith('REVMARK')) { + // skipping REVMARKs since they are not supported by legacy implementation + continue; + } let before, after, returned; if (g.num_qubits === 1) { before = new PauliFrame(4, g.num_qubits); diff --git a/glue/crumble/circuit/propagated_pauli_frames.js b/glue/crumble/circuit/propagated_pauli_frames.js index 2a65df42f..356c2a169 100644 --- a/glue/crumble/circuit/propagated_pauli_frames.js +++ b/glue/crumble/circuit/propagated_pauli_frames.js @@ -122,14 +122,18 @@ class PropagatedPauliFrames { * @param {!int} marker_index * @returns {!PropagatedPauliFrames} */ - static fromCircuit(circuit, marker_index) { + static fromCircuit(circuit, marker_index, reverse = false) { let result = new PropagatedPauliFrames(new Map()); let bases = /** @type {!Map} */ new Map(); - for (let k = 0; k < circuit.layers.length; k++) { + const start = reverse ? circuit.layers.length - 1 : 0; + const end = reverse ? -1 : circuit.layers.length; + const step = reverse ? -1 : 1; + + for (let k = start; reverse ? k > end : k < end; k += step) { let layer = circuit.layers[k]; let prevBases = bases; - bases = layer.id_pauliFrameAfter(bases, marker_index); + bases = layer.id_pauliFrameAfter(bases, marker_index, reverse); let errors = new Set(); for (let key of [...bases.keys()]) { @@ -171,7 +175,7 @@ class PropagatedPauliFrames { } if (bases.size > 0) { - result.id_layers.set(k + 0.5, new PropagatedPauliFrameLayer(bases, new Set(), [])); + result.id_layers.set(reverse ? k - 0.5 : k + 0.5, new PropagatedPauliFrameLayer(bases, new Set(), [])); } if (errors.size > 0 || crossings.length > 0) { result.id_layers.set(k, new PropagatedPauliFrameLayer(new Map(), errors, crossings)); diff --git a/glue/crumble/crumble.html b/glue/crumble/crumble.html index 4dff02ecc..b0b08bc83 100644 --- a/glue/crumble/crumble.html +++ b/glue/crumble/crumble.html @@ -33,7 +33,7 @@
- +