Skip to content

Commit

Permalink
!2283 [CXX][PY] Add stabilizer simulator.
Browse files Browse the repository at this point in the history
Merge pull request !2283 from donghufeng/dev/stabilizer
  • Loading branch information
donghufeng authored and gitee-org committed Jan 31, 2024
2 parents 47abb33 + 3b4336f commit 02c4215
Show file tree
Hide file tree
Showing 64 changed files with 2,163 additions and 68 deletions.
2 changes: 2 additions & 0 deletions .cppcheck.suppressions
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,5 @@ useStlAlgorithm:ccsrc/include/ops/gates/terms_operator_base.tpp
useInitializationList:ccsrc/include/simulator/cintrin.h

ctuOneDefinitionRuleViolation:tests/core/test_circuit_block.cpp

unusedStructMember:ccsrc/include/simulator/stabilizer/stabilizer.h
1 change: 1 addition & 0 deletions .jenkins/check/config/filter_cmakelint.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
"mindquantum/cmake" "whitespace/indent"
"mindquantum/cmake/Modules" "whitespace/indent"
"mindquantum/cmake/Modules/apple" "whitespace/indent"
"mindquantum/ccsrc/lib/simulator/stabilizer/CMakeLists.txt" "whitespace/indent"
1 change: 1 addition & 0 deletions .jenkins/check/config/filter_cppcheck.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,4 @@
"mindquantum/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_dot_like.cpp" "syntaxError"
"mindquantum/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_gate_expect.cpp" "syntaxError"
"mindquantum/ccsrc/python/mqbackend/lib/binding.cc" "syntaxError"
"mindquantum/ccsrc/include/simulator/stabilizer/stabilizer.h" "unusedStructMember"
1 change: 1 addition & 0 deletions .jenkins/check/config/whitelizard.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ mindquantum/mindquantum/algorithm/nisq/chem/reference_state.py:get_reference_cir
mindquantum/mindquantum/io/display/circuit_text_drawer.py:rich_circuit
mindquantum/mindquantum/utils/f.py:random_insert_gates

mindquantum/ccsrc/lib/simulator/stabilizer/stabilizer.cpp:mindquantum::stabilizer::StabilizerTableau::Decompose
mindquantum/ccsrc/include/simulator/vector/vector_state.tpp:mindquantum::sim::vector::detail::VectorState<qs_policy_t_>::GetExpectationWithGradParameterShiftOneMulti
mindquantum/ccsrc/include/ops/gates.h:mindquantum::GetGateByName
mindquantum/ccsrc/include/ops/gates/qubit_operator.tpp:mindquantum::ops::QubitOperator<coeff_t>::sparse_matrix
Expand Down
1 change: 1 addition & 0 deletions .whitelizard.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ mindquantum/algorithm/nisq/chem/reference_state.py:get_reference_circuit
mindquantum/io/display/circuit_text_drawer.py:rich_circuit
mindquantum/utils/f.py:random_insert_gates

ccsrc/lib/simulator/stabilizer/stabilizer.cpp:mindquantum::stabilizer::StabilizerTableau::Decompose
ccsrc/include/simulator/vector/vector_state.tpp:mindquantum::sim::vector::detail::VectorState<qs_policy_t_>::GetExpectationWithGradParameterShiftOneMulti
ccsrc/include/ops/gates.h:mindquantum::GetGateByName
ccsrc/include/ops/gates/qubit_operator.tpp:mindquantum::ops::QubitOperator<coeff_t>::sparse_matrix
Expand Down
79 changes: 79 additions & 0 deletions ccsrc/include/math/longbits/longbits.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/**
* Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef MATH_LONGBITS_LONGBITS_H_
#define MATH_LONGBITS_LONGBITS_H_
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <stdexcept>
#include <string>
#include <vector>

#include <fmt/core.h>
namespace mindquantum {
class LongBits {
using ele_t = uint64_t;

public:
LongBits() = default;
explicit LongBits(size_t n_bits);

// -----------------------------------------------------------------------------

void operator^=(const LongBits& other);
void operator&=(const LongBits& other);
LongBits operator^(const LongBits& other) const;
LongBits operator&(const LongBits& other) const;
bool operator==(const LongBits& other) const;

// -----------------------------------------------------------------------------

void SetBit(size_t poi, bool val);

size_t GetBit(size_t poi) const;

std::string ToString() const;

void InplaceFlip();
LongBits Flip();

bool Any(size_t start, size_t end);

bool Any(size_t start);

private:
LongBits(size_t n_bits, const std::vector<ele_t>& data);

private:
size_t n_bits = 1;
std::vector<ele_t> data = {0};
};
} // namespace mindquantum

// -----------------------------------------------------------------------------

template <>
struct fmt::formatter<mindquantum::LongBits> {
constexpr auto parse(format_parse_context& ctx) { // NOLINT(runtime/references)
return ctx.begin();
}
template <typename FormatContext>
auto format(const mindquantum::LongBits& obj, FormatContext& ctx) { // NOLINT(runtime/references)
return format_to(ctx.out(), obj.ToString());
}
};
#endif
32 changes: 32 additions & 0 deletions ccsrc/include/simulator/stabilizer/query_element.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SIMULATOR_STABILIZER_QUERY_ELEMENT_H_
#define SIMULATOR_STABILIZER_QUERY_ELEMENT_H_
#include <utility>

#include "simulator/stabilizer/stabilizer.h"

namespace mindquantum::stabilizer {
std::pair<size_t, size_t> DetermineClass(size_t i);
void EvoClass1(StabilizerTableau* stab, size_t idx);
void EvoClass2(StabilizerTableau* stab, size_t idx);
void EvoClass3(StabilizerTableau* stab, size_t idx);
void EvoClass4(StabilizerTableau* stab, size_t idx);
StabilizerTableau QueryDoubleQubitsCliffordElem(size_t idx);
StabilizerTableau QuerySingleQubitCliffordElem(size_t idx);
void Verification();
} // namespace mindquantum::stabilizer
#endif
24 changes: 24 additions & 0 deletions ccsrc/include/simulator/stabilizer/random_benchmarking.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SIMULATOR_STABILIZER_RANDOM_BENCHMARKING_H_
#define SIMULATOR_STABILIZER_RANDOM_BENCHMARKING_H_
#include "simulator/stabilizer/query_element.h"
#include "simulator/stabilizer/stabilizer.h"
namespace mindquantum::stabilizer {
VT<StabilizerTableau> SingleQubitRBCircuit(size_t len, int seed);
VT<StabilizerTableau> DoubleQubitsRBCircuit(size_t len, int seed);
} // namespace mindquantum::stabilizer
#endif
79 changes: 79 additions & 0 deletions ccsrc/include/simulator/stabilizer/stabilizer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/**
* Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SIMULATOR_STABILIZER_STABILIZER_H_
#define SIMULATOR_STABILIZER_STABILIZER_H_
#include <cstddef>
#include <map>
#include <memory>
#include <random>
#include <string>
#include <vector>

#include "math/longbits/longbits.h"
#include "ops/basic_gate.h"
#include "ops/gate_id.h"
namespace mindquantum::stabilizer {
using stab_circ_t = VT<std::shared_ptr<BasicGate>>;

class StabilizerTableau {
using RndEngine = std::mt19937;

public:
StabilizerTableau() = default;
explicit StabilizerTableau(size_t n_qubits, unsigned seed = 42);

// -----------------------------------------------------------------------------
void SetSeed(unsigned new_seed);

std::string TableauToString() const;

std::string StabilizerToString() const;

size_t GetElement(size_t row, size_t col) const;
void SetElement(size_t row, size_t col, size_t val);
void Reset();
void ApplyX(size_t idx);
void ApplyY(size_t idx);
void ApplyZ(size_t idx);
void ApplySGate(size_t idx);
void ApplySdag(size_t idx);
void ApplyV(size_t idx);
void ApplyW(size_t idx);
void ApplyH(size_t idx);
void ApplyCNOT(size_t obj, size_t ctrl);
size_t ApplyMeasurement(size_t idx);
size_t ApplyGate(GateID g_id, size_t obj, size_t ctrl = 0);
std::map<std::string, int> ApplyCircuit(const stab_circ_t& circ);
VT<unsigned> Sampling(const stab_circ_t& circ, size_t shots, const MST<size_t>& key_map, unsigned int seed) const;
VT<unsigned> SamplingMeasurementEndingWithoutNoise(const stab_circ_t& circ, size_t shots,
const MST<size_t>& key_map, unsigned int seed) const;
void RowSum(size_t h, size_t i);
stab_circ_t Decompose() const;
VVT<size_t> TableauToVector() const;
bool operator==(const StabilizerTableau& other) const;

private:
size_t n_qubits = 1;
std::vector<LongBits> table;
LongBits phase;
unsigned seed = 0;
RndEngine rnd_eng_;
std::function<double()> rng_;
};

stab_circ_t CliffordCircDagger(const stab_circ_t& circ);
} // namespace mindquantum::stabilizer
#endif
1 change: 1 addition & 0 deletions ccsrc/lib/math/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ target_link_libraries(mq_math PUBLIC ${MQ_OPENMP_TARGET} include_lib cmake_confi
add_subdirectory(tensor)
add_subdirectory(pr)
add_subdirectory(operators)
add_subdirectory(longbits)
20 changes: 20 additions & 0 deletions ccsrc/lib/math/longbits/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# ==============================================================================
#
# Copyright 2023 <Huawei Technologies Co., Ltd>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# ==============================================================================
# lint_cmake: -whitespace/indent

target_sources(mq_math PRIVATE ${CMAKE_CURRENT_LIST_DIR}/longbits.cpp)
123 changes: 123 additions & 0 deletions ccsrc/lib/math/longbits/longbits.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/**
* Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "math/longbits/longbits.h"

#include <algorithm>
#include <cstdint>
#include <stdexcept>

#include <fmt/core.h>

namespace mindquantum {
#define REG_OPERATOR(op_eq, op) \
void LongBits::operator op_eq(const LongBits& other) { \
if (other.n_bits != this->n_bits) { \
throw std::runtime_error( \
fmt::format("n_bits of this ({}) is not equal with other ({})", this->n_bits, other.n_bits)); \
} \
for (size_t i = 0; i < data.size(); i++) { \
data[i] op_eq other.data[i]; \
} \
} \
LongBits LongBits::operator op(const LongBits& other) const { \
auto out = *this; \
out op_eq other; \
return out; \
}

REG_OPERATOR(^=, ^);
REG_OPERATOR(&=, &);

// -----------------------------------------------------------------------------

LongBits::LongBits(size_t n_bits) : n_bits(n_bits) {
if (n_bits == 0) {
throw std::runtime_error("n_bits cannot be zero.");
}
constexpr static auto ele_size = sizeof(ele_t) * 8;
auto n_ele = n_bits / ele_size + ((n_bits % ele_size) != 0);
data = std::vector<ele_t>(n_ele, 0);
}

LongBits::LongBits(size_t n_bits, const std::vector<ele_t>& data) : n_bits(n_bits), data(data) {
}

// -----------------------------------------------------------------------------

bool LongBits::operator==(const LongBits& other) const {
return n_bits == other.n_bits && data == other.data;
}

void LongBits::SetBit(size_t poi, bool val) {
if (poi > n_bits - 1) {
throw std::runtime_error(fmt::format("poi ({}) out of range: [{}, {}).", poi, 0, n_bits));
}
constexpr static auto ele_size = sizeof(ele_t) * 8;
size_t index_in = poi % ele_size;
size_t mask = static_cast<uint64_t>(1) << index_in;
size_t mask_val = static_cast<uint64_t>(val) << index_in;
ele_t& ele = data[poi / ele_size];
ele = (ele & ~mask) | mask_val;
}

size_t LongBits::GetBit(size_t poi) const {
if (poi > n_bits - 1) {
throw std::runtime_error(fmt::format("poi ({}) out of range: [{}, {}).", poi, 0, n_bits));
}
constexpr static auto ele_size = sizeof(ele_t) * 8;
return (data[poi / ele_size] >> (poi % ele_size)) & 1;
}

std::string LongBits::ToString() const {
std::string out = "";
for (size_t i = 0; i < n_bits; i++) {
out += (GetBit(i) == 0 ? "0" : "1");
}
std::reverse(out.begin(), out.end());
return out;
}

void LongBits::InplaceFlip() {
std::transform(data.begin(), data.end(), data.begin(), [](const auto& ele) { return ~ele; });
}

LongBits LongBits::Flip() {
auto out = *this;
out.InplaceFlip();
return out;
}

bool LongBits::Any(size_t start, size_t end) {
if (end <= start) {
throw std::runtime_error(fmt::format("end ({}) can not be less than start ({}).", end, start));
}
if (start >= n_bits) {
throw std::runtime_error(fmt::format("start ({}) out of range: [{}, {})", start, 0, n_bits));
}
end = std::min(end, n_bits);
for (size_t i = start; i < end; i++) {
if (GetBit(i) == 1) {
return true;
}
}
return false;
}

bool LongBits::Any(size_t start) {
return Any(start, n_bits);
}
#undef REG_OPERATOR
} // namespace mindquantum
Loading

0 comments on commit 02c4215

Please sign in to comment.