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

Fix interleaved feedback being removed incorrectly #731

Merged
merged 1 commit into from
Mar 27, 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
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"));
}
Loading