Skip to content

Commit

Permalink
Fix interleaved feedback being removed incorrectly (#731)
Browse files Browse the repository at this point in the history
- When a pure-feedback instruction was between two instructions of the
same type, they were fused when partially reversed when the feedback
instruction was removed
- Fixed by turning off fusion while the circuit is only partially
reversed
- Fixes #730
  • Loading branch information
Strilanc authored Mar 27, 2024
1 parent bc638e3 commit c7988c0
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 7 deletions.
8 changes: 4 additions & 4 deletions src/stim/circuit/circuit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,8 @@ void Circuit::append_from_text(const char *text) {
READ_CONDITION::READ_UNTIL_END_OF_FILE);
}

void Circuit::safe_append(const CircuitInstruction &operation) {
safe_append(operation.gate_type, operation.targets, operation.args);
void Circuit::safe_append(const CircuitInstruction &operation, bool block_fusion) {
safe_append(operation.gate_type, operation.targets, operation.args, block_fusion);
}

void Circuit::safe_append_ua(const std::string &gate_name, const std::vector<uint32_t> &targets, double singleton_arg) {
Expand Down Expand Up @@ -433,7 +433,7 @@ void Circuit::safe_append_u(
safe_append(gate.id, converted, args);
}

void Circuit::safe_append(GateType gate_type, SpanRef<const GateTarget> targets, SpanRef<const double> args) {
void Circuit::safe_append(GateType gate_type, SpanRef<const GateTarget> targets, SpanRef<const double> args, bool block_fusion) {
auto flags = GATE_DATA[gate_type].flags;
if (flags & GATE_IS_BLOCK) {
throw std::invalid_argument("Can't append a block like a normal operation.");
Expand All @@ -446,7 +446,7 @@ void Circuit::safe_append(GateType gate_type, SpanRef<const GateTarget> targets,
to_add.args = arg_buf.take_copy(to_add.args);
to_add.targets = target_buf.take_copy(to_add.targets);

if (!operations.empty() && operations.back().can_fuse(to_add)) {
if (!block_fusion && !operations.empty() && operations.back().can_fuse(to_add)) {
// Extend targets of last gate.
fuse_data(operations.back().targets, to_add.targets, target_buf);
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/stim/circuit/circuit.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,14 @@ struct Circuit {
Circuit &operator*=(uint64_t repetitions);

/// Safely adds an operation at the end of the circuit, copying its data into the circuit's jagged data as needed.
void safe_append(const CircuitInstruction &operation);
void safe_append(const CircuitInstruction &operation, bool block_fusion = false);
/// Safely adds an operation at the end of the circuit, copying its data into the circuit's jagged data as needed.
void safe_append_ua(const std::string &gate_name, const std::vector<uint32_t> &targets, double singleton_arg);
/// Safely adds an operation at the end of the circuit, copying its data into the circuit's jagged data as needed.
void safe_append_u(
const std::string &gate_name, const std::vector<uint32_t> &targets, const std::vector<double> &args = {});
/// Safely adds an operation at the end of the circuit, copying its data into the circuit's jagged data as needed.
void safe_append(GateType gate_type, SpanRef<const GateTarget> targets, SpanRef<const double> args);
void safe_append(GateType gate_type, SpanRef<const GateTarget> targets, SpanRef<const double> args, bool block_fusion = false);
/// Safely copies a repeat block to the end of the circuit.
void append_repeat_block(uint64_t repeat_count, const Circuit &body);
/// Safely moves a repeat block to the end of the circuit.
Expand Down
2 changes: 1 addition & 1 deletion src/stim/simulators/transform_without_feedback.cc
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ struct WithoutFeedbackHelper {
if (GATE_DATA[op.gate_type].flags & GATE_CAN_TARGET_BITS) {
undo_feedback_capable_pcp_operation(op);
} else {
reversed_semi_flattened_output.safe_append(op);
reversed_semi_flattened_output.safe_append(op, true);
tracker.undo_gate(op);
}
}
Expand Down
30 changes: 30 additions & 0 deletions src/stim/simulators/transform_without_feedback.test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,33 @@ TEST(circuit_with_inlined_feedback, mpp) {
DETECTOR rec[-3] rec[-1]
)CIRCUIT"));
}

TEST(circuit_with_inlined_feedback, interleaved_feedback_does_not_reorder_operations) {
ASSERT_EQ(circuit_with_inlined_feedback(Circuit(R"CIRCUIT(
H 0
CZ
H 1
)CIRCUIT")), Circuit(R"CIRCUIT(
H 0 1
)CIRCUIT"));

ASSERT_EQ(circuit_with_inlined_feedback(Circuit(R"CIRCUIT(
M 0
CX
M 1
)CIRCUIT")), Circuit(R"CIRCUIT(
M 0 1
)CIRCUIT"));

ASSERT_EQ(circuit_with_inlined_feedback(Circuit(R"CIRCUIT(
M 0 1
CX
M 2
CX rec[-1] 3
M 3
DETECTOR rec[-1]
)CIRCUIT")), Circuit(R"CIRCUIT(
M 0 1 2 3
DETECTOR rec[-2] rec[-1]
)CIRCUIT"));
}

0 comments on commit c7988c0

Please sign in to comment.