Skip to content

Commit

Permalink
Second fix to reversing MPP ordering in error analysis (#175)
Browse files Browse the repository at this point in the history
- Within a non-qubit-overlapping subset there was already a reversal, so the new reversal was cancelling it instead of doing the right thing
- Maintain the reversal of qubit-overlapping subsets
  • Loading branch information
Strilanc authored Dec 14, 2021
1 parent 0da9430 commit fc4b355
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 16 deletions.
30 changes: 15 additions & 15 deletions src/stim/mem/simd_bits_range_ref.test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
using namespace stim;

TEST(simd_bits_range_ref, construct) {
alignas(64) uint64_t data[16]{};
simd_bits_range_ref ref((simd_word *)data, sizeof(data) / sizeof(simd_word));
alignas(64) std::array<uint64_t, 16> data{};
simd_bits_range_ref ref((simd_word *)data.data(), sizeof(data) / sizeof(simd_word));

ASSERT_EQ(ref.ptr_simd, (simd_word *)&data[0]);
ASSERT_EQ(ref.num_simd_words, 16 * sizeof(uint64_t) / sizeof(simd_word));
Expand All @@ -34,10 +34,10 @@ TEST(simd_bits_range_ref, construct) {
}

TEST(simd_bits_range_ref, aliased_editing_and_bit_refs) {
alignas(64) uint64_t data[16]{};
alignas(64) std::array<uint64_t, 16> data{};
auto c = (char *)&data;
simd_bits_range_ref ref((simd_word *)data, sizeof(data) / sizeof(simd_word));
const simd_bits_range_ref cref((simd_word *)data, sizeof(data) / sizeof(simd_word));
simd_bits_range_ref ref((simd_word *)data.data(), sizeof(data) / sizeof(simd_word));
const simd_bits_range_ref cref((simd_word *)data.data(), sizeof(data) / sizeof(simd_word));

ASSERT_EQ(c[0], 0);
ASSERT_EQ(c[13], 0);
Expand All @@ -54,8 +54,8 @@ TEST(simd_bits_range_ref, aliased_editing_and_bit_refs) {
}

TEST(simd_bits_range_ref, str) {
alignas(64) uint64_t data[8]{};
simd_bits_range_ref ref((simd_word *)data, sizeof(data) / sizeof(simd_word));
alignas(64) std::array<uint64_t, 8> data{};
simd_bits_range_ref ref((simd_word *)data.data(), sizeof(data) / sizeof(simd_word));
ASSERT_EQ(
ref.str(),
"________________________________________________________________"
Expand All @@ -80,8 +80,8 @@ TEST(simd_bits_range_ref, str) {
}

TEST(simd_bits_range_ref, randomize) {
alignas(64) uint64_t data[16]{};
simd_bits_range_ref ref((simd_word *)data, sizeof(data) / sizeof(simd_word));
alignas(64) std::array<uint64_t, 16> data{};
simd_bits_range_ref ref((simd_word *)data.data(), sizeof(data) / sizeof(simd_word));

ref.randomize(64 + 57, SHARED_TEST_RNG());
uint64_t mask = (1ULL << 57) - 1;
Expand Down Expand Up @@ -111,7 +111,7 @@ TEST(simd_bits_range_ref, randomize) {
}

TEST(simd_bits_range_ref, xor_assignment) {
alignas(64) uint64_t data[24]{};
alignas(64) std::array<uint64_t, 24> data{};
simd_bits_range_ref m0((simd_word *)&data[0], sizeof(data) / sizeof(simd_word) / 3);
simd_bits_range_ref m1((simd_word *)&data[8], sizeof(data) / sizeof(simd_word) / 3);
simd_bits_range_ref m2((simd_word *)&data[16], sizeof(data) / sizeof(simd_word) / 3);
Expand All @@ -128,7 +128,7 @@ TEST(simd_bits_range_ref, xor_assignment) {
}

TEST(simd_bits_range_ref, assignment) {
alignas(64) uint64_t data[16]{};
alignas(64) std::array<uint64_t, 16> data{};
simd_bits_range_ref m0((simd_word *)&data[0], sizeof(data) / sizeof(simd_word) / 2);
simd_bits_range_ref m1((simd_word *)&data[8], sizeof(data) / sizeof(simd_word) / 2);
m0.randomize(512, SHARED_TEST_RNG());
Expand All @@ -142,7 +142,7 @@ TEST(simd_bits_range_ref, assignment) {
}

TEST(simd_bits_range_ref, equality) {
alignas(64) uint64_t data[32]{};
alignas(64) std::array<uint64_t, 32> data{};
simd_bits_range_ref m0((simd_word *)&data[0], sizeof(data) / sizeof(simd_word) / 4);
simd_bits_range_ref m1((simd_word *)&data[8], sizeof(data) / sizeof(simd_word) / 4);
simd_bits_range_ref m4((simd_word *)&data[16], sizeof(data) / sizeof(simd_word) / 2);
Expand All @@ -161,7 +161,7 @@ TEST(simd_bits_range_ref, equality) {
}

TEST(simd_bits_range_ref, swap_with) {
alignas(64) uint64_t data[32]{};
alignas(64) std::array<uint64_t, 32> data{};
simd_bits_range_ref m0((simd_word *)&data[0], sizeof(data) / sizeof(simd_word) / 4);
simd_bits_range_ref m1((simd_word *)&data[8], sizeof(data) / sizeof(simd_word) / 4);
simd_bits_range_ref m2((simd_word *)&data[16], sizeof(data) / sizeof(simd_word) / 4);
Expand All @@ -178,7 +178,7 @@ TEST(simd_bits_range_ref, swap_with) {
}

TEST(simd_bits_range_ref, clear) {
alignas(64) uint64_t data[8]{};
alignas(64) std::array<uint64_t, 8> data{};
simd_bits_range_ref m0((simd_word *)&data[0], sizeof(data) / sizeof(simd_word));
m0.randomize(512, SHARED_TEST_RNG());
ASSERT_TRUE(m0.not_zero());
Expand All @@ -187,7 +187,7 @@ TEST(simd_bits_range_ref, clear) {
}

TEST(simd_bits_range_ref, not_zero256) {
alignas(64) uint64_t data[8]{};
alignas(64) std::array<uint64_t, 8> data{};
simd_bits_range_ref m0((simd_word *)&data[0], sizeof(data) / sizeof(simd_word));
ASSERT_FALSE(m0.not_zero());
m0[5] = true;
Expand Down
7 changes: 6 additions & 1 deletion src/stim/simulators/error_analyzer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,7 @@ void ErrorAnalyzer::add_error_combinations(
void ErrorAnalyzer::MPP(const OperationData &target_data) {
size_t n = target_data.targets.size();
std::vector<GateTarget> reversed_targets(n);
std::vector<GateTarget> reversed_measure_targets;
for (size_t k = 0; k < n; k++) {
reversed_targets[k] = target_data.targets[n-k-1];
}
Expand All @@ -1281,7 +1282,11 @@ void ErrorAnalyzer::MPP(const OperationData &target_data) {
H_XZ(h_xz);
H_YZ(h_yz);
ZCX(cnot);
MZ(meas);
reversed_measure_targets.clear();
for (size_t k = meas.targets.size(); k--;) {
reversed_measure_targets.push_back(meas.targets[k]);
}
MZ({meas.args, reversed_measure_targets});
ZCX(cnot);
H_YZ(h_yz);
H_XZ(h_xz);
Expand Down
44 changes: 44 additions & 0 deletions src/stim/simulators/error_analyzer.test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2516,6 +2516,36 @@ TEST(ErrorAnalyzer, mpp_ordering) {
detector D0
)MODEL"));

ASSERT_EQ(
ErrorAnalyzer::circuit_to_detector_error_model(
Circuit(R"CIRCUIT(
MPP X0*X1 X0 X0
DETECTOR rec[-1] rec[-2]
)CIRCUIT"),
false,
false,
false,
false),
DetectorErrorModel(R"MODEL(
detector D0
)MODEL"));

ASSERT_EQ(
ErrorAnalyzer::circuit_to_detector_error_model(
Circuit(R"CIRCUIT(
MPP X2*X1 X0
TICK
MPP X0
DETECTOR rec[-1] rec[-2]
)CIRCUIT"),
false,
false,
false,
false),
DetectorErrorModel(R"MODEL(
detector D0
)MODEL"));

ASSERT_THROW({
ErrorAnalyzer::circuit_to_detector_error_model(
Circuit(R"CIRCUIT(
Expand All @@ -2529,4 +2559,18 @@ TEST(ErrorAnalyzer, mpp_ordering) {
false,
false);
}, std::invalid_argument);

ASSERT_THROW({
ErrorAnalyzer::circuit_to_detector_error_model(
Circuit(R"CIRCUIT(
MPP X0 X2*X1
TICK
MPP X0
DETECTOR rec[-1] rec[-2]
)CIRCUIT"),
false,
false,
false,
false);
}, std::invalid_argument);
}

0 comments on commit fc4b355

Please sign in to comment.