Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CZSWAP support to crumble #701

Merged
merged 8 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ jobs:
- run: diff <(python -c "import stim; stim.main(command_line_args=['help', 'gates_markdown'])") doc/gates.md
- run: diff <(python -c "import stim; stim.main(command_line_args=['help', 'formats_markdown'])") doc/result_formats.md
- run: diff <(python -c "import stim; stim.main(command_line_args=['help', 'commands_markdown'])") doc/usage_command_line.md
- run: diff <(dev/gen_known_gates_for_js.sh) glue/crumble/test/generated_gate_name_list.test.js
- run: python doc/stim.pyi
- run: npm install -g [email protected] [email protected]
- run: diff <(dev/regen_crumble_to_cpp_string_write_to_stdout.sh) src/stim/diagram/crumble_data.cc
Expand Down
12 changes: 12 additions & 0 deletions dev/gen_known_gates_for_js.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash
set -e

#########################################################################
# Generates javascript exporting a string KNOWN_GATE_NAMES_FROM_STIM.
#########################################################################

echo "const KNOWN_GATE_NAMES_FROM_STIM = \`"
python -c "import stim; stim.main(command_line_args=['help', 'gates'])" | grep " " | sed 's/^ *//g'
echo "\`"
echo
echo "export {KNOWN_GATE_NAMES_FROM_STIM};"
1 change: 1 addition & 0 deletions dev/regen_docs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ python dev/gen_sinter_api_reference.py -dev > doc/sinter_api.md
python -c "import stim; stim.main(command_line_args=['help', 'gates_markdown'])" > doc/gates.md
python -c "import stim; stim.main(command_line_args=['help', 'formats_markdown'])" > doc/result_formats.md
python -c "import stim; stim.main(command_line_args=['help', 'commands_markdown'])" > doc/usage_command_line.md
dev/gen_known_gates_for_js.sh > glue/crumble/test/generated_gate_name_list.test.js
55 changes: 16 additions & 39 deletions glue/crumble/circuit/circuit.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {Operation} from "./operation.js"
import {GATE_MAP} from "../gates/gateset.js"
import {GATE_ALIAS_MAP, GATE_MAP} from "../gates/gateset.js"
import {Layer} from "./layer.js"
import {make_mpp_gate} from '../gates/gateset_mpp.js';
import {describe} from "../base/describe.js";

/**
* @param {!Iterator<TItem>}items
Expand Down Expand Up @@ -92,6 +93,9 @@ function simplifiedMPP(args, combinedTargets) {
let bases = '';
let qubits = [];
for (let t of combinedTargets) {
if (t[0] === '!') {
t = t.substring(1);
}
if (t[0] === 'X' || t[0] === 'Y' || t[0] === 'Z') {
bases += t[0];
let v = parseInt(t.substring(1));
Expand Down Expand Up @@ -216,32 +220,17 @@ class Circuit {
let reverse_pairs = false;
if (name === '') {
return;
} else if (name === 'XCZ') {
reverse_pairs = true;
name = 'CX';
} else if (name === 'SWAPCX') {
reverse_pairs = true;
name = 'CXSWAP';
} else if (name === 'CNOT') {
name = 'CX';
} else if (name === 'RZ') {
name = 'R';
} else if (name === 'MZ') {
name = 'M';
} else if (name === 'MRZ') {
name = 'MR';
} else if (name === 'ZCX') {
name = 'CX';
} else if (name === 'ZCY') {
name = 'CY';
} else if (name === 'ZCZ') {
name = 'CZ';
} else if (name === 'YCX') {
reverse_pairs = true;
name = 'XCY';
} else if (name === 'YCZ') {
reverse_pairs = true;
name = 'CY';
}
let alias = GATE_ALIAS_MAP.get(name);
if (alias !== undefined) {
if (alias.ignore) {
return;
} else if (alias.name !== undefined) {
reverse_pairs = alias.reverse_pairs !== undefined && alias.reverse_pairs;
name = alias.name;
} else {
throw new Error(`Unimplemented alias ${name}: ${describe(alias)}.`);
}
} else if (name === 'TICK') {
layers.push(new Layer());
return;
Expand All @@ -258,17 +247,6 @@ class Circuit {
}
}
return;
} else if (name === "X_ERROR" ||
name === "Y_ERROR" ||
name === "Z_ERROR" ||
name === "DETECTOR" ||
name === "OBSERVABLE_INCLUDE" ||
name === "DEPOLARIZE1" ||
name === "DEPOLARIZE2" ||
name === "SHIFT_COORDS" ||
name === "REPEAT" ||
name === "}") {
return;
} else if (name.startsWith('QUBIT_COORDS')) {
let x = args.length < 1 ? 0 : args[0];
let y = args.length < 2 ? 0 : args[1];
Expand All @@ -294,7 +272,6 @@ class Circuit {
break;
}
}
let t = parseInt(targ);
if (typeof parseInt(targ) !== 'number') {
throw new Error(line);
}
Expand Down
117 changes: 117 additions & 0 deletions glue/crumble/circuit/circuit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -531,3 +531,120 @@ QUBIT_COORDS(6, 0) 6
MPP Z0*Z1*Z2 Z3*Z4*Z5*X6
`.trim())
});

test("circuit.fromStimCircuit_manygates", () => {
let c = Circuit.fromStimCircuit(`
QUBIT_COORDS(1, 2, 3) 0

# Pauli gates
I 0
X 1
Y 2
Z 3
TICK

# Single Qubit Clifford Gates
C_XYZ 0
C_ZYX 1
H_XY 2
H_XZ 3
H_YZ 4
SQRT_X 0
SQRT_X_DAG 1
SQRT_Y 2
SQRT_Y_DAG 3
SQRT_Z 4
SQRT_Z_DAG 5
TICK

# Two Qubit Clifford Gates
CXSWAP 0 1
ISWAP 2 3
ISWAP_DAG 4 5
SWAP 6 7
SWAPCX 8 9
CZSWAP 10 11
SQRT_XX 0 1
SQRT_XX_DAG 2 3
SQRT_YY 4 5
SQRT_YY_DAG 6 7
SQRT_ZZ 8 9
SQRT_ZZ_DAG 10 11
XCX 0 1
XCY 2 3
XCZ 4 5
YCX 6 7
YCY 8 9
YCZ 10 11
ZCX 12 13
ZCY 14 15
ZCZ 16 17
TICK

# Noise Channels
CORRELATED_ERROR(0.01) X1 Y2 Z3
ELSE_CORRELATED_ERROR(0.02) X4 Y7 Z6
DEPOLARIZE1(0.02) 0
DEPOLARIZE2(0.03) 1 2
PAULI_CHANNEL_1(0.01, 0.02, 0.03) 3
PAULI_CHANNEL_2(0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009, 0.010, 0.011, 0.012, 0.013, 0.014, 0.015) 4 5
X_ERROR(0.01) 0
Y_ERROR(0.02) 1
Z_ERROR(0.03) 2
HERALDED_ERASE(0.04) 3
HERALDED_PAULI_CHANNEL_1(0.01, 0.02, 0.03, 0.04) 6
TICK

# Collapsing Gates
MPP X0*Y1*Z2 Z0*Z1
MRX 0
MRY 1
MRZ 2
MX 3
MY 4
MZ 5 6
RX 7
RY 8
RZ 9
TICK

# Pair Measurement Gates
MXX 0 1 2 3
MYY 4 5
MZZ 6 7
TICK

# Control Flow
REPEAT 3 {
H 0
CX 0 1
S 1
TICK
}
TICK

# Annotations
MR 0
X_ERROR(0.1) 0
MR(0.01) 0
SHIFT_COORDS(1, 2, 3)
DETECTOR(1, 2, 3) rec[-1]
OBSERVABLE_INCLUDE(0) rec[-1]
MPAD 0 1 0
TICK

# Inverted measurements.
MRX !0
MY !1
MZZ !2 3
MYY !4 !5
MPP X6*!Y7*Z8
TICK

# Feedback
CX rec[-1] 0
CY sweep[0] 1
CZ 2 rec[-1]
`);
assertThat(c).isNotEqualTo(undefined);
})
18 changes: 18 additions & 0 deletions glue/crumble/circuit/pauli_frame.js
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,24 @@ class PauliFrame {
}
}

/**
* @param {!Array<!int>} targets
*/
do_cz_swap(targets) {
for (let k = 0; k < targets.length; k += 2) {
let c = k;
let t = k + 1;
let xc = this.xs[c];
let zc = this.zs[c];
let xt = this.xs[t];
let zt = this.zs[t];
this.xs[c] = xt;
this.zs[c] = zt ^ xc;
this.xs[t] = xc;
this.zs[t] = zc ^ xt;
}
}

/**
* @param {!Array<!int>} targets
*/
Expand Down
Loading
Loading