From d8afc0ffa9a83cbd97f0b6c2c13f6e5288466b8b Mon Sep 17 00:00:00 2001 From: donghufeng Date: Mon, 17 Jul 2023 22:37:22 +0800 Subject: [PATCH 001/100] fix channel string expression --- mindquantum/core/gates/basic.py | 13 +++++ mindquantum/core/gates/channel.py | 60 +++++++++++--------- mindquantum/io/display/circuit_svg_drawer.py | 40 +++++++++++-- 3 files changed, 81 insertions(+), 32 deletions(-) diff --git a/mindquantum/core/gates/basic.py b/mindquantum/core/gates/basic.py index 1ee788ad0..14b886c5a 100644 --- a/mindquantum/core/gates/basic.py +++ b/mindquantum/core/gates/basic.py @@ -731,6 +731,19 @@ def diff_matrix(self, pr=None, about_what=None): class NoiseGate(NoneParameterGate): """Noise gate class.""" + def __str_in_terminal__(self): + """Return a string representation of the object.""" + qubit_s = QuantumGate.__qubits_expression__(self) + pr_s = self.__type_specific_str__() + string = join_without_empty('|', [pr_s, qubit_s]) + return self.name + (f'({string})' if string else '') + + def __str_in_circ__(self): + """Return a string representation of the object.""" + pr_s = self.__type_specific_str__() + string = join_without_empty('|', [pr_s]) + return self.name + (f'({string})' if string else '') + def on(self, obj_qubits, ctrl_qubits=None): """ Define which qubit the gate act on. diff --git a/mindquantum/core/gates/channel.py b/mindquantum/core/gates/channel.py index aa051a2bc..f667136ad 100644 --- a/mindquantum/core/gates/channel.py +++ b/mindquantum/core/gates/channel.py @@ -56,7 +56,7 @@ class PauliChannel(NoiseGate, SelfHermitianGate): >>> circ += PauliChannel(0.8, 0.1, 0.1).on(0) >>> circ.measure_all() >>> print(circ) - q0: ──PC────M(q0)── + q0: ──PC(px=0.8, py=0.1, pz=0.1)────M(q0)── >>> from mindquantum.simulator import Simulator >>> sim = Simulator('mqvector', 1) >>> sim.sampling(circ, shots=1000, seed=42) @@ -96,6 +96,10 @@ def __extra_prop__(self): """Extra prop magic method.""" return {'px': self.px, 'py': self.py, 'pz': self.pz} + def __type_specific_str__(self): + """Return a string representation of the object.""" + return f'px={self.px}, py={self.py}, pz={self.pz}' + def get_cpp_obj(self): """Get underlying C++ object.""" return mb.gate.PauliChannel(self.px, self.py, self.pz, self.obj_qubits, self.ctrl_qubits) @@ -137,7 +141,7 @@ class BitFlipChannel(PauliChannel): >>> circ = Circuit() >>> circ += BitFlipChannel(0.02).on(0) >>> print(circ) - q0: ──BF(0.02)── + q0: ──BFC(p=0.02)── """ # pylint: disable=invalid-name @@ -158,9 +162,9 @@ def __extra_prop__(self): prop['p'] = self.p return prop - def __str_in_circ__(self): - """Return a string representation of the object in a quantum circuit.""" - return f"BF({self.p})" + def __type_specific_str__(self): + """Return a string representation of the object.""" + return f'p={self.p}' class PhaseFlipChannel(PauliChannel): @@ -188,7 +192,7 @@ class PhaseFlipChannel(PauliChannel): >>> circ = Circuit() >>> circ += PhaseFlipChannel(0.02).on(0) >>> print(circ) - q0: ──PF(0.02)── + q0: ──PFC(p=0.02)── """ # pylint: disable=invalid-name @@ -209,9 +213,9 @@ def __extra_prop__(self): prop['p'] = self.p return prop - def __str_in_circ__(self): - """Return a string representation of the object in a quantum circuit.""" - return f"PF({self.p})" + def __type_specific_str__(self): + """Return a string representation of the object.""" + return f'p={self.p}' class BitPhaseFlipChannel(PauliChannel): @@ -240,7 +244,7 @@ class BitPhaseFlipChannel(PauliChannel): >>> circ = Circuit() >>> circ += BitPhaseFlipChannel(0.02).on(0) >>> print(circ) - q0: ──BPF(0.02)── + q0: ──BPFC(p=0.02)── """ # pylint: disable=invalid-name @@ -261,9 +265,9 @@ def __extra_prop__(self): prop['p'] = self.p return prop - def __str_in_circ__(self): - """Return a string representation of the object in a quantum circuit.""" - return f"BPF({self.p})" + def __type_specific_str__(self): + """Return a string representation of the object.""" + return f'p={self.p}' class DepolarizingChannel(NoiseGate, SelfHermitianGate): @@ -300,11 +304,11 @@ class DepolarizingChannel(NoiseGate, SelfHermitianGate): >>> from mindquantum.core.circuit import Circuit >>> circ = Circuit() >>> circ += DepolarizingChannel(0.02).on(0) - >>> circ += DepolarizingChannel(0.01).on([1, 2]) + >>> circ += DepolarizingChannel(0.01).on([0, 1]) >>> print(circ) - q0: ──Dep(0.02)────Dep(0.01)── - │ - q1: ───────────────Dep(0.01)── + q0: ──DC(p=0.02)────DC(p=0.01)── + │ + q1: ────────────────DC(p=0.01)── """ # pylint: disable=invalid-name @@ -351,9 +355,9 @@ def __extra_prop__(self): """Extra prop magic method.""" return {'p': self.p} - def __str_in_circ__(self): - """Return a string representation of the object in a quantum circuit.""" - return f"Dep({self.p})" + def __type_specific_str__(self): + """Return a string representation of the object.""" + return f'p={self.p}' class AmplitudeDampingChannel(NoiseGate, NonHermitianGate): @@ -385,7 +389,7 @@ class AmplitudeDampingChannel(NoiseGate, NonHermitianGate): >>> circ = Circuit() >>> circ += AmplitudeDampingChannel(0.02).on(0) >>> print(circ) - q0: ──AD(0.02)── + q0: ──ADC(γ=0.02)── """ def __init__(self, gamma: float, **kwargs): @@ -406,9 +410,9 @@ def __eq__(self, other): """Equality comparison operator.""" return BasicGate.__eq__(self, other) and self.gamma == other.gamma - def __str_in_circ__(self): - """Return a string representation of the object in a quantum circuit.""" - return f"AD({self.gamma})" + def __type_specific_str__(self): + """Return a string representation of the object.""" + return f'γ={self.gamma}' def get_cpp_obj(self): """Get underlying C++ object.""" @@ -450,7 +454,7 @@ class PhaseDampingChannel(NoiseGate, NonHermitianGate): >>> circ = Circuit() >>> circ += PhaseDampingChannel(0.02).on(0) >>> print(circ) - q0: ──PD(0.02)── + q0: ──PDC(γ=0.02)── """ def __init__(self, gamma: float, **kwargs): @@ -471,9 +475,9 @@ def __eq__(self, other): """Equality comparison operator.""" return super().__eq__(other) and self.gamma == other.gamma - def __str_in_circ__(self): - """Return a string representation of the object in a quantum circuit.""" - return f"PD({self.gamma})" + def __type_specific_str__(self): + """Return a string representation of the object.""" + return f'γ={self.gamma}' def get_cpp_obj(self): """Get underlying C++ object.""" diff --git a/mindquantum/io/display/circuit_svg_drawer.py b/mindquantum/io/display/circuit_svg_drawer.py index 8cd6e6f64..479610c13 100644 --- a/mindquantum/io/display/circuit_svg_drawer.py +++ b/mindquantum/io/display/circuit_svg_drawer.py @@ -836,10 +836,7 @@ def __init__(self, g, svg_config): """Initialize an SVGGate object.""" super().__init__(g, svg_config) self.rect = self.create_n_qubits_rect(g.n_qubits) - if isinstance(g, NoiseGate): - self.rect.fill(self.svg_config['noise_fill']) - else: - self.rect.fill(self.svg_config['npg_fill']) + self.rect.fill(self.svg_config['npg_fill']) self.rect.fill_opacity(self.svg_config['npg_fill_opacity']) self.rect.stroke(self.svg_config['npg_stroke']) self.rect.stroke_width(self.svg_config['gate_stroke_width']) @@ -865,6 +862,39 @@ def __init__(self, g, svg_config): self.move_to_create_qubit() +class SVGChannel(SVGBasicGate): + """SVG for noise channel.""" + + def __init__(self, gate, svg_config): + """Initialize an SVGParameterGate object.""" + super().__init__(gate, svg_config) + self.rect1 = self.create_n_qubits_rect(max(self.obj_qubits) - min(self.obj_qubits) + 1) + self.rect1.fill(self.svg_config['noise_fill']) + self.rect1.fill_opacity(self.svg_config['npg_fill_opacity']) + self.rect1.stroke(self.svg_config['npg_stroke']) + self.rect1.stroke_width(self.svg_config['gate_stroke_width']) + self.name_text = self.create_name_text(self.name) + self.name_text.shift(0, self.rect1.get('height') / 2 - self.svg_config['gate_size'] / 10) + coeff_str = f"{gate.__type_specific_str__()}" + + self.coeff_text = self.create_name_text(coeff_str) + self.coeff_text.shift(0, self.rect1.get('height') / 2 + self.svg_config['gate_size'] * 0.3) + self.coeff_text.font_size(self.svg_config['gate_name_font_size'] * 0.7) + self.rect1.fit_text(self.name_text) + self.rect1.fit_text(self.coeff_text) + self.rect1.fit_text(self.name_text) + color = get_bound_color(self.svg_config, self.svg_config['npg_fill'], self.svg_config['npg_stroke']) + self.obj_dots = self.create_obj_dots(self.rect1.right, color) + self.ctrl_dots = self.create_ctrl_dots(self.rect1.right / 2, color) + self.add(self.ctrl_dots) + self.add(self.rect1) + self.add(self.name_text) + self.add(self.coeff_text) + self.add(self.obj_dots) + self.as_background(self.ctrl_dots, self.rect1, self.obj_dots) + self.move_to_create_qubit() + + class SVGSWAPGate(SVGBasicGate): """Style for swap gate.""" @@ -1023,6 +1053,8 @@ def add_to_gate_container(gate_container: GateContainer, gate, svg_config, n_qub gate_container.add(SVGSWAPGate(gate, svg_config)) elif isinstance(gate, ParameterGate) and not isinstance(gate, (TGate, SGate)): gate_container.add(SVGParameterGate(gate, svg_config)) + elif isinstance(gate, NoiseGate): + gate_container.add(SVGChannel(gate, svg_config)) else: gate_container.add(SVGGate(gate, svg_config)) From 2e07285f2fd90e1010968d0c2fa5a637bf141eb2 Mon Sep 17 00:00:00 2001 From: donghufeng Date: Tue, 18 Jul 2023 01:16:01 +0800 Subject: [PATCH 002/100] fix wall --- .cppcheck.suppressions | 2 - ccsrc/include/core/mq_base_types.hpp | 5 +- ccsrc/include/core/utils.hpp | 2 +- ccsrc/include/math/tensor/matrix.hpp | 10 +- ccsrc/include/ops/basic_gate.hpp | 103 +++++++++--------- ccsrc/include/ops/gates.hpp | 6 +- .../densitymatrix/densitymatrix_state.hpp | 1 - .../densitymatrix/densitymatrix_state.tpp | 1 - .../detail/cpu_densitymatrix_policy.hpp | 1 - ccsrc/include/simulator/types.hpp | 26 ----- ccsrc/include/simulator/utils.hpp | 2 +- .../vector/detail/cpu_vector_policy.hpp | 1 - .../vector/detail/gpu_vector_policy.cuh | 1 - .../simulator/vector/runtime/rt_gate.h | 7 +- .../include/simulator/vector/vector_state.hpp | 1 - .../include/simulator/vector/vector_state.tpp | 3 +- ccsrc/lib/device/mapping.cpp | 3 +- ccsrc/lib/mq_base/gates/gates.cpp | 12 +- .../cpu_densitymatrix_core_gate_expect.cpp | 14 +-- .../cpu_densitymatrix_core_policy.cpp | 9 +- ccsrc/lib/simulator/utils.cpp | 2 - .../cpu_common/cpu_vector_core_policy.cpp | 11 +- ccsrc/python/mqbackend/lib/binding.cc | 72 ++++++------ .../python/densitymatrix/bind_mat_state.hpp | 4 +- .../include/python/vector/bind_vec_state.h | 3 +- 25 files changed, 129 insertions(+), 173 deletions(-) delete mode 100644 ccsrc/include/simulator/types.hpp diff --git a/.cppcheck.suppressions b/.cppcheck.suppressions index 95beba572..6c352b5a0 100644 --- a/.cppcheck.suppressions +++ b/.cppcheck.suppressions @@ -57,7 +57,6 @@ syntaxError:ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatri syntaxError:ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_policy.cpp unknownMacro:ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_rot_pauli.cpp -unknownMacro:ccsrc/include/simulator/densitymatrix/detail/cpu_densitymatrix_policy.hpp unknownMacro:ccsrc/include/core/sparse/paulimat.hpp unknownMacro:ccsrc/include/core/sparse/paulimat.hpp:58 unknownMacro:ccsrc/lib/simulator/vector/detail/cpu_vector_policy_single_ops.cpp @@ -69,7 +68,6 @@ unknownMacro:ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_matrix unknownMacro:ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_x_like.cpp unknownMacro:ccsrc/lib/simulator/vector/detail/cpu_avx_double/cpu_vector_core_matrix_gate.cpp unknownMacro:ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_matrix_gate.cpp -unknownMacro:ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp unreadVariable:ccsrc/lib/experimental/decompositions/time_evolution.cpp diff --git a/ccsrc/include/core/mq_base_types.hpp b/ccsrc/include/core/mq_base_types.hpp index b19d9dd49..096d1b688 100644 --- a/ccsrc/include/core/mq_base_types.hpp +++ b/ccsrc/include/core/mq_base_types.hpp @@ -41,7 +41,10 @@ namespace mindquantum { p != obj.end(); \ p++ -using Index = int64_t; +using Index = std::size_t; +using qbit_t = int64_t; +using qbits_t = std::vector; +using index_t = std::size_t; template using VT = std::vector; diff --git a/ccsrc/include/core/utils.hpp b/ccsrc/include/core/utils.hpp index 6456ce0fc..cacd994fa 100644 --- a/ccsrc/include/core/utils.hpp +++ b/ccsrc/include/core/utils.hpp @@ -117,7 +117,7 @@ inline uint32_t CountOne(uint32_t n) { return __builtin_popcount(n); } -inline uint64_t CountOne(int64_t n) { +inline uint64_t CountOne(uint64_t n) { return __builtin_popcount(n); } #endif // _MSC_VER diff --git a/ccsrc/include/math/tensor/matrix.hpp b/ccsrc/include/math/tensor/matrix.hpp index e78a77fed..640ef613e 100644 --- a/ccsrc/include/math/tensor/matrix.hpp +++ b/ccsrc/include/math/tensor/matrix.hpp @@ -14,6 +14,8 @@ #ifndef MATH_TENSOR_MATRIX #define MATH_TENSOR_MATRIX +#include +#include #include #include @@ -40,9 +42,7 @@ struct Matrix : public Tensor { } std::vector tmp; for (auto& row : m) { - for (auto& data : row) { - tmp.push_back(data); - } + std::copy(row.begin(), row.end(), std::back_inserter(tmp)); } auto t = Tensor(tmp); this->dtype = t.dtype; @@ -52,8 +52,8 @@ struct Matrix : public Tensor { t.data = nullptr; } Matrix() = default; - Matrix(TDtype dtype, TDevice device, void* data, size_t n_col, size_t n_row) - : n_col(n_col), n_row(n_row), Tensor(dtype, device, data, n_col * n_row) { + Matrix(TDtype dtype, TDevice device, void* data, size_t n_row, size_t n_col) + : Tensor(dtype, device, data, n_col * n_row), n_row(n_row), n_col(n_col) { } Matrix(Tensor&& other, size_t n_row, size_t n_col) : n_row(n_row), n_col(n_col) { if (n_col * n_row != other.dim) { diff --git a/ccsrc/include/ops/basic_gate.hpp b/ccsrc/include/ops/basic_gate.hpp index 41d20eaa1..a6dd14bf2 100644 --- a/ccsrc/include/ops/basic_gate.hpp +++ b/ccsrc/include/ops/basic_gate.hpp @@ -37,10 +37,10 @@ namespace mindquantum { struct BasicGate { GateID id_ = GateID::I; - VT obj_qubits_ = {}; - VT ctrl_qubits_ = {}; + qbits_t obj_qubits_ = {}; + qbits_t ctrl_qubits_ = {}; BasicGate() = default; - BasicGate(GateID id, const VT& obj_qubits, const VT& ctrl_qubits) + BasicGate(GateID id, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits) : id_(id), obj_qubits_(obj_qubits), ctrl_qubits_(ctrl_qubits) { } virtual bool Parameterized() { @@ -53,66 +53,66 @@ struct BasicGate { struct MeasureGate : public BasicGate { std::string name_; - MeasureGate(const std::string& name, const VT& obj_qubits) - : name_(name), BasicGate(GateID::M, obj_qubits, {}) { + MeasureGate(const std::string& name, const qbits_t& obj_qubits) + : BasicGate(GateID::M, obj_qubits, {}), name_(name) { } }; struct IGate : public BasicGate { - explicit IGate(const VT& obj_qubits, const VT& ctrl_qubits = {}) + explicit IGate(const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : BasicGate(GateID::I, obj_qubits, ctrl_qubits) { } }; struct XGate : public BasicGate { - explicit XGate(const VT& obj_qubits, const VT& ctrl_qubits = {}) + explicit XGate(const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : BasicGate(GateID::X, obj_qubits, ctrl_qubits) { } }; struct YGate : public BasicGate { - explicit YGate(const VT& obj_qubits, const VT& ctrl_qubits = {}) + explicit YGate(const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : BasicGate(GateID::Y, obj_qubits, ctrl_qubits) { } }; struct ZGate : public BasicGate { - explicit ZGate(const VT& obj_qubits, const VT& ctrl_qubits = {}) + explicit ZGate(const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : BasicGate(GateID::Z, obj_qubits, ctrl_qubits) { } }; struct HGate : public BasicGate { - explicit HGate(const VT& obj_qubits, const VT& ctrl_qubits = {}) + explicit HGate(const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : BasicGate(GateID::H, obj_qubits, ctrl_qubits) { } }; struct SWAPGate : public BasicGate { - explicit SWAPGate(const VT& obj_qubits, const VT& ctrl_qubits = {}) + explicit SWAPGate(const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : BasicGate(GateID::SWAP, obj_qubits, ctrl_qubits) { } }; struct ISWAPGate : public BasicGate { bool daggered_; - ISWAPGate(bool daggered, const VT& obj_qubits, const VT& ctrl_qubits = {}) - : daggered_(daggered), BasicGate(GateID::ISWAP, obj_qubits, ctrl_qubits) { + ISWAPGate(bool daggered, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) + : BasicGate(GateID::ISWAP, obj_qubits, ctrl_qubits), daggered_(daggered) { } }; struct SGate : public BasicGate { - explicit SGate(const VT& obj_qubits, const VT& ctrl_qubits = {}) + explicit SGate(const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : BasicGate(GateID::S, obj_qubits, ctrl_qubits) { } }; struct SdagGate : public BasicGate { - explicit SdagGate(const VT& obj_qubits, const VT& ctrl_qubits = {}) + explicit SdagGate(const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : BasicGate(GateID::Sdag, obj_qubits, ctrl_qubits) { } }; struct TGate : public BasicGate { - explicit TGate(const VT& obj_qubits, const VT& ctrl_qubits = {}) + explicit TGate(const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : BasicGate(GateID::T, obj_qubits, ctrl_qubits) { } }; struct TdagGate : public BasicGate { - explicit TdagGate(const VT& obj_qubits, const VT& ctrl_qubits = {}) + explicit TdagGate(const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : BasicGate(GateID::Tdag, obj_qubits, ctrl_qubits) { } }; @@ -123,9 +123,9 @@ struct Parameterizable : public BasicGate { bool parameterized_; bool grad_required_; std::pair, tensor::Matrix> jacobi; - Parameterizable(GateID id, const VT& prs, const VT& obj_qubits, - const VT& ctrl_qubits) - : n_pr(prs.size()), prs_(prs), BasicGate(id, obj_qubits, ctrl_qubits) { + Parameterizable(GateID id, const VT& prs, const qbits_t& obj_qubits, + const qbits_t& ctrl_qubits) + : BasicGate(id, obj_qubits, ctrl_qubits), n_pr(prs.size()), prs_(prs) { parameterized_ = !std::all_of(this->prs_.begin(), this->prs_.end(), [](const auto& pr) { return pr.IsConst(); }); grad_required_ = std::any_of(this->prs_.begin(), this->prs_.end(), @@ -141,67 +141,67 @@ struct Parameterizable : public BasicGate { }; struct RXGate : public Parameterizable { - RXGate(const parameter::ParameterResolver pr, const VT& obj_qubits, const VT& ctrl_qubits = {}) + RXGate(const parameter::ParameterResolver pr, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : Parameterizable(GateID::RX, {pr}, obj_qubits, ctrl_qubits) { } }; struct RYGate : public Parameterizable { - RYGate(const parameter::ParameterResolver pr, const VT& obj_qubits, const VT& ctrl_qubits = {}) + RYGate(const parameter::ParameterResolver pr, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : Parameterizable(GateID::RY, {pr}, obj_qubits, ctrl_qubits) { } }; struct RZGate : public Parameterizable { - RZGate(const parameter::ParameterResolver pr, const VT& obj_qubits, const VT& ctrl_qubits = {}) + RZGate(const parameter::ParameterResolver pr, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : Parameterizable(GateID::RZ, {pr}, obj_qubits, ctrl_qubits) { } }; struct RxxGate : public Parameterizable { - RxxGate(const parameter::ParameterResolver pr, const VT& obj_qubits, const VT& ctrl_qubits = {}) + RxxGate(const parameter::ParameterResolver pr, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : Parameterizable(GateID::Rxx, {pr}, obj_qubits, ctrl_qubits) { } }; struct RyyGate : public Parameterizable { - RyyGate(const parameter::ParameterResolver pr, const VT& obj_qubits, const VT& ctrl_qubits = {}) + RyyGate(const parameter::ParameterResolver pr, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : Parameterizable(GateID::Ryy, {pr}, obj_qubits, ctrl_qubits) { } }; struct RzzGate : public Parameterizable { - RzzGate(const parameter::ParameterResolver pr, const VT& obj_qubits, const VT& ctrl_qubits = {}) + RzzGate(const parameter::ParameterResolver pr, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : Parameterizable(GateID::Rzz, {pr}, obj_qubits, ctrl_qubits) { } }; struct RxyGate : public Parameterizable { - RxyGate(const parameter::ParameterResolver pr, const VT& obj_qubits, const VT& ctrl_qubits = {}) + RxyGate(const parameter::ParameterResolver pr, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : Parameterizable(GateID::Rxy, {pr}, obj_qubits, ctrl_qubits) { } }; struct RxzGate : public Parameterizable { - RxzGate(const parameter::ParameterResolver pr, const VT& obj_qubits, const VT& ctrl_qubits = {}) + RxzGate(const parameter::ParameterResolver pr, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : Parameterizable(GateID::Rxz, {pr}, obj_qubits, ctrl_qubits) { } }; struct RyzGate : public Parameterizable { - RyzGate(const parameter::ParameterResolver pr, const VT& obj_qubits, const VT& ctrl_qubits = {}) + RyzGate(const parameter::ParameterResolver pr, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : Parameterizable(GateID::Ryz, {pr}, obj_qubits, ctrl_qubits) { } }; struct GPGate : public Parameterizable { - GPGate(const parameter::ParameterResolver pr, const VT& obj_qubits, const VT& ctrl_qubits = {}) + GPGate(const parameter::ParameterResolver pr, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : Parameterizable(GateID::GP, {pr}, obj_qubits, ctrl_qubits) { } }; struct PSGate : public Parameterizable { - PSGate(const parameter::ParameterResolver pr, const VT& obj_qubits, const VT& ctrl_qubits = {}) + PSGate(const parameter::ParameterResolver pr, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : Parameterizable(GateID::PS, {pr}, obj_qubits, ctrl_qubits) { } }; struct PauliChannel : public BasicGate { VT cumulative_probs_; VT probs_; - PauliChannel(double px, double py, double pz, const VT& obj_qubits, - const VT& ctrl_qubits = {}) // for pauli channel - : probs_{px, py, pz, 1 - px - py - pz}, BasicGate(GateID::PL, obj_qubits, ctrl_qubits) { + PauliChannel(double px, double py, double pz, const qbits_t& obj_qubits, + const qbits_t& ctrl_qubits = {}) // for pauli channel + : BasicGate(GateID::PL, obj_qubits, ctrl_qubits), probs_{px, py, pz, 1 - px - py - pz} { double sum = 0.; cumulative_probs_.push_back(sum); for (auto it = probs_.begin(); it != probs_.end(); it++) { @@ -212,16 +212,15 @@ struct PauliChannel : public BasicGate { }; struct DepolarizingChannel : public BasicGate { double prob_; - DepolarizingChannel(double p, const VT& obj_qubits, const VT& ctrl_qubits = {}) - : prob_(p), BasicGate(GateID::DEP, obj_qubits, ctrl_qubits) { + DepolarizingChannel(double p, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) + : BasicGate(GateID::DEP, obj_qubits, ctrl_qubits), prob_(p) { } }; struct KrausChannel : public BasicGate { VT kraus_operator_set_; template - KrausChannel(const VT>>& kraus_operator_set, const VT& obj_qubits, - const VT& ctrl_qubits = {}) + KrausChannel(const VT>>& kraus_operator_set, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) : BasicGate(GateID::KRAUS, obj_qubits, ctrl_qubits) { std::transform(kraus_operator_set.begin(), kraus_operator_set.end(), std::back_inserter(kraus_operator_set_), [](auto& k) { return tensor::Matrix(k); }); @@ -231,15 +230,15 @@ struct KrausChannel : public BasicGate { struct AmplitudeDampingChannel : public BasicGate { double damping_coeff_; bool daggered_; - AmplitudeDampingChannel(bool daggered, double damping_coeff, const VT& obj_qubits, - const VT& ctrl_qubits = {}) - : daggered_(daggered), damping_coeff_(damping_coeff), BasicGate(GateID::AD, obj_qubits, ctrl_qubits) { + AmplitudeDampingChannel(bool daggered, double damping_coeff, const qbits_t& obj_qubits, + const qbits_t& ctrl_qubits = {}) + : BasicGate(GateID::AD, obj_qubits, ctrl_qubits), damping_coeff_(damping_coeff), daggered_(daggered) { } }; struct PhaseDampingChannel : public BasicGate { double damping_coeff_; - PhaseDampingChannel(double damping_coeff, const VT& obj_qubits, const VT& ctrl_qubits = {}) - : damping_coeff_(damping_coeff), BasicGate(GateID::PD, obj_qubits, ctrl_qubits) { + PhaseDampingChannel(double damping_coeff, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) + : BasicGate(GateID::PD, obj_qubits, ctrl_qubits), damping_coeff_(damping_coeff) { } }; @@ -249,20 +248,20 @@ struct CustomGate : public Parameterizable { NumbaMatFunWrapper numba_param_diff_matrix_; tensor::Matrix base_matrix_; CustomGate(const std::string& name, uint64_t m_addr, uint64_t dm_addr, int dim, - const parameter::ParameterResolver pr, const VT& obj_qubits, const VT& ctrl_qubits = {}) - : name_(name) + const parameter::ParameterResolver pr, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits = {}) + : Parameterizable(GateID::CUSTOM, {pr}, obj_qubits, ctrl_qubits) + , name_(name) , numba_param_matrix_(m_addr, dim) - , numba_param_diff_matrix_(dm_addr, dim) - , Parameterizable(GateID::CUSTOM, {pr}, obj_qubits, ctrl_qubits) { + , numba_param_diff_matrix_(dm_addr, dim) { if (!this->Parameterized()) { base_matrix_ = this->numba_param_matrix_(tensor::ops::cpu::to_vector(this->prs_[0].const_value)[0]); } } - CustomGate(const std::string& name, const tensor::Matrix& mat, const VT& obj_qubits, - const VT& ctrl_qubits = {}) - : name_(name) - , base_matrix_(mat) - , Parameterizable(GateID::CUSTOM, {parameter::ParameterResolver()}, obj_qubits, ctrl_qubits) { + CustomGate(const std::string& name, const tensor::Matrix& mat, const qbits_t& obj_qubits, + const qbits_t& ctrl_qubits = {}) + : Parameterizable(GateID::CUSTOM, {parameter::ParameterResolver()}, obj_qubits, ctrl_qubits) + , name_(name) + , base_matrix_(mat) { } }; } // namespace mindquantum diff --git a/ccsrc/include/ops/gates.hpp b/ccsrc/include/ops/gates.hpp index 9e93a7e33..bf413deda 100644 --- a/ccsrc/include/ops/gates.hpp +++ b/ccsrc/include/ops/gates.hpp @@ -68,15 +68,15 @@ struct U3 : public Parameterizable { parameter::ParameterResolver lambda; tensor::Matrix base_matrix_; U3(const parameter::ParameterResolver& theta, const parameter::ParameterResolver& phi, - const parameter::ParameterResolver& lambda, const VT& obj_qubits, const VT& ctrl_qubits); + const parameter::ParameterResolver& lambda, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits); }; struct FSim : public Parameterizable { parameter::ParameterResolver theta; parameter::ParameterResolver phi; tensor::Matrix base_matrix_; - FSim(const parameter::ParameterResolver& theta, const parameter::ParameterResolver& phi, - const VT& obj_qubits, const VT& ctrl_qubits); + FSim(const parameter::ParameterResolver& theta, const parameter::ParameterResolver& phi, const qbits_t& obj_qubits, + const qbits_t& ctrl_qubits); }; } // namespace mindquantum #endif // MINDQUANTUM_GATE_GATES_HPP_ diff --git a/ccsrc/include/simulator/densitymatrix/densitymatrix_state.hpp b/ccsrc/include/simulator/densitymatrix/densitymatrix_state.hpp index 53226bf28..e1a7ebc42 100644 --- a/ccsrc/include/simulator/densitymatrix/densitymatrix_state.hpp +++ b/ccsrc/include/simulator/densitymatrix/densitymatrix_state.hpp @@ -38,7 +38,6 @@ #include "ops/gates.hpp" #include "ops/hamiltonian.hpp" #include "simulator/timer.h" -#include "simulator/types.hpp" #include "simulator/utils.hpp" namespace mindquantum::sim::densitymatrix::detail { diff --git a/ccsrc/include/simulator/densitymatrix/densitymatrix_state.tpp b/ccsrc/include/simulator/densitymatrix/densitymatrix_state.tpp index 23d7421f4..d615a5cf4 100644 --- a/ccsrc/include/simulator/densitymatrix/densitymatrix_state.tpp +++ b/ccsrc/include/simulator/densitymatrix/densitymatrix_state.tpp @@ -43,7 +43,6 @@ #include "ops/gates.hpp" #include "ops/hamiltonian.hpp" #include "simulator/densitymatrix/densitymatrix_state.hpp" -#include "simulator/types.hpp" namespace mindquantum::sim::densitymatrix::detail { diff --git a/ccsrc/include/simulator/densitymatrix/detail/cpu_densitymatrix_policy.hpp b/ccsrc/include/simulator/densitymatrix/detail/cpu_densitymatrix_policy.hpp index cb4376074..45f5d1527 100644 --- a/ccsrc/include/simulator/densitymatrix/detail/cpu_densitymatrix_policy.hpp +++ b/ccsrc/include/simulator/densitymatrix/detail/cpu_densitymatrix_policy.hpp @@ -26,7 +26,6 @@ #include "core/mq_base_types.hpp" #include "core/utils.hpp" #include "math/tensor/traits.hpp" -#include "simulator/types.hpp" // Warning: only correct when x >= y #define IdxMap(x, y) (((x) * ((x) + 1)) / 2 + (y)) diff --git a/ccsrc/include/simulator/types.hpp b/ccsrc/include/simulator/types.hpp deleted file mode 100644 index 7ea2e2ab1..000000000 --- a/ccsrc/include/simulator/types.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2022 -// -// 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 INCLUDE_VECTOR_TYPES_HPP -#define INCLUDE_VECTOR_TYPES_HPP -#include -#include - -namespace mindquantum::sim { -using qbit_t = int64_t; -using qbits_t = std::vector; -using index_t = std::size_t; -} // namespace mindquantum::sim - -#endif diff --git a/ccsrc/include/simulator/utils.hpp b/ccsrc/include/simulator/utils.hpp index 222e3e20a..f28429766 100644 --- a/ccsrc/include/simulator/utils.hpp +++ b/ccsrc/include/simulator/utils.hpp @@ -19,7 +19,7 @@ #include #include "core/mq_base_types.hpp" -#include "simulator/types.hpp" + namespace mindquantum::sim { index_t QIndexToMask(qbits_t objs); PauliMask GenPauliMask(const std::vector& pws); diff --git a/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp b/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp index 9eaf35a0d..2bb6e2653 100644 --- a/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp +++ b/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp @@ -29,7 +29,6 @@ #include "core/sparse/csrhdmatrix.hpp" #include "core/utils.hpp" #include "math/tensor/traits.hpp" -#include "simulator/types.hpp" namespace mindquantum::sim::vector::detail { struct CPUVectorPolicyAvxFloat; diff --git a/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh b/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh index b8a63f5d2..efd346c2a 100644 --- a/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh +++ b/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh @@ -26,7 +26,6 @@ #include "core/mq_base_types.hpp" #include "core/sparse/csrhdmatrix.hpp" #include "math/tensor/traits.hpp" -#include "simulator/types.hpp" #include "thrust/complex.h" #include "thrust/functional.h" diff --git a/ccsrc/include/simulator/vector/runtime/rt_gate.h b/ccsrc/include/simulator/vector/runtime/rt_gate.h index 44969ed2e..33d3f3f38 100644 --- a/ccsrc/include/simulator/vector/runtime/rt_gate.h +++ b/ccsrc/include/simulator/vector/runtime/rt_gate.h @@ -25,13 +25,12 @@ namespace mindquantum::sim::rt { struct Gate { GateID gate = GateID::null; - std::vector objs; - std::vector ctrls; + qbits_t objs; + qbits_t ctrls; double ang = 0; std::string m_key = ""; Gate() = default; - Gate(GateID gate, const std::vector &objs, const std::vector &ctrls) - : gate(gate), objs(objs), ctrls(ctrls) { + Gate(GateID gate, const qbits_t &objs, const qbits_t &ctrls) : gate(gate), objs(objs), ctrls(ctrls) { } void Reset() { diff --git a/ccsrc/include/simulator/vector/vector_state.hpp b/ccsrc/include/simulator/vector/vector_state.hpp index 4c2f42805..bd7cc4bfb 100644 --- a/ccsrc/include/simulator/vector/vector_state.hpp +++ b/ccsrc/include/simulator/vector/vector_state.hpp @@ -40,7 +40,6 @@ #include "ops/gates.hpp" #include "ops/hamiltonian.hpp" #include "simulator/timer.h" -#include "simulator/types.hpp" #include "simulator/utils.hpp" namespace mindquantum::sim::vector::detail { diff --git a/ccsrc/include/simulator/vector/vector_state.tpp b/ccsrc/include/simulator/vector/vector_state.tpp index b97b4f016..d5b97bc58 100644 --- a/ccsrc/include/simulator/vector/vector_state.tpp +++ b/ccsrc/include/simulator/vector/vector_state.tpp @@ -44,7 +44,6 @@ #include "ops/gate_id.hpp" #include "ops/gates.hpp" #include "ops/hamiltonian.hpp" -#include "simulator/types.hpp" #include "simulator/vector/vector_state.hpp" namespace mindquantum::sim::vector::detail { @@ -415,7 +414,7 @@ void VectorState::ApplyDepolarizingChannel(const std::shared_ptr obj{obj_qubit}; + qbits_t obj{obj_qubit}; if (gate_index == 0) { qs_policy_t::ApplyX(&qs, obj, gate->ctrl_qubits_, dim); } else if (gate_index == 1) { diff --git a/ccsrc/lib/device/mapping.cpp b/ccsrc/lib/device/mapping.cpp index ba15dde67..cf1a75d40 100644 --- a/ccsrc/lib/device/mapping.cpp +++ b/ccsrc/lib/device/mapping.cpp @@ -22,6 +22,7 @@ #include #include "core/mq_base_types.hpp" +#include "device/topology.hpp" #include "ops/basic_gate.hpp" #include "ops/gate_id.hpp" @@ -52,7 +53,7 @@ VT> GetCircuitDAG(int n, const VT& gates) { std::pair> GateToAbstractGate(const VT>& gates) { VT abs_circ; - Index max_qubit = 0; + qbit_t max_qubit = 0; for (size_t i = 0; i < gates.size(); i++) { auto gate = gates[i]; if (gate->obj_qubits_.size() + gate->ctrl_qubits_.size() > 2) { diff --git a/ccsrc/lib/mq_base/gates/gates.cpp b/ccsrc/lib/mq_base/gates/gates.cpp index 85fcc3f76..56a2e3444 100644 --- a/ccsrc/lib/mq_base/gates/gates.cpp +++ b/ccsrc/lib/mq_base/gates/gates.cpp @@ -72,19 +72,19 @@ tensor::Matrix U3DiffLambdaMatrix(tensor::Tensor theta, tensor::Tensor phi, tens } U3::U3(const parameter::ParameterResolver& theta, const parameter::ParameterResolver& phi, - const parameter::ParameterResolver& lambda, const VT& obj_qubits, const VT& ctrl_qubits) - : theta(theta) + const parameter::ParameterResolver& lambda, const qbits_t& obj_qubits, const qbits_t& ctrl_qubits) + : Parameterizable(GateID::U3, {theta, phi, lambda}, obj_qubits, ctrl_qubits) + , theta(theta) , phi(phi) - , lambda(lambda) - , Parameterizable(GateID::U3, {theta, phi, lambda}, obj_qubits, ctrl_qubits) { + , lambda(lambda) { if (!this->parameterized_) { this->base_matrix_ = U3Matrix(theta.const_value, phi.const_value, lambda.const_value); } } FSim::FSim(const parameter::ParameterResolver& theta, const parameter::ParameterResolver& phi, - const VT& obj_qubits, const VT& ctrl_qubits) - : theta(theta), phi(phi), Parameterizable(GateID::FSim, {theta, phi}, obj_qubits, ctrl_qubits) { + const qbits_t& obj_qubits, const qbits_t& ctrl_qubits) + : Parameterizable(GateID::FSim, {theta, phi}, obj_qubits, ctrl_qubits), theta(theta), phi(phi) { if (!this->parameterized_) { this->base_matrix_ = FSimMatrix(theta.const_value, phi.const_value); } diff --git a/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_gate_expect.cpp b/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_gate_expect.cpp index 9b65011f2..dc3ff95b0 100644 --- a/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_gate_expect.cpp +++ b/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_gate_expect.cpp @@ -38,8 +38,8 @@ auto CPUDensityMatrixPolicyBase::HamiltonianMatrix(const s dim, DimTh, for (omp::idx_t i = 0; i < dim; i++) { auto j = (i ^ mask_f); if (i <= j) { - auto axis2power = CountOne(static_cast(i & mask.mask_z)); // -1 - auto axis3power = CountOne(static_cast(i & mask.mask_y)); // -1j + auto axis2power = CountOne(i & mask.mask_z); // -1 + auto axis3power = CountOne(i & mask.mask_y); // -1j auto c = ComplexCast::apply( POLAR[static_cast((mask.num_y + 2 * axis3power + 2 * axis2power) & 3)]); out[IdxMap(j, i)] += coeff * c; @@ -72,8 +72,8 @@ auto CPUDensityMatrixPolicyBase::GetExpectation(const qs_d for (omp::idx_t i = 0; i < dim; i++) { auto j = (i ^ mask_f); if (i <= j) { - auto axis2power = CountOne(static_cast(i & mask.mask_z)); // -1 - auto axis3power = CountOne(static_cast(i & mask.mask_y)); // -1j + auto axis2power = CountOne(i & mask.mask_z); // -1 + auto axis3power = CountOne(i & mask.mask_y); // -1j auto c = ComplexCast::apply( POLAR[static_cast((mask.num_y + 2 * axis3power + 2 * axis2power) & 3)]); auto e = std::conj(qs[IdxMap(j, i)]) * coeff * c; @@ -867,7 +867,6 @@ auto CPUDensityMatrixPolicyBase::ExpectDiffFSimTheta(const index_t r0; SHIFT_BIT_TWO(mask.obj_low_mask, mask.obj_rev_low_mask, mask.obj_high_mask, mask.obj_rev_high_mask, l, r0); - auto r3 = r0 + mask.obj_mask; auto r1 = r0 + mask.obj_min_mask; auto r2 = r0 + mask.obj_max_mask; qs_data_t this_res = 0; @@ -889,7 +888,6 @@ auto CPUDensityMatrixPolicyBase::ExpectDiffFSimTheta(const SHIFT_BIT_TWO(mask.obj_low_mask, mask.obj_rev_low_mask, mask.obj_high_mask, mask.obj_rev_high_mask, l, r0); if ((r0 & mask.ctrl_mask) == mask.ctrl_mask) { - auto r3 = r0 + mask.obj_mask; auto r1 = r0 + mask.obj_min_mask; auto r2 = r0 + mask.obj_max_mask; qs_data_t this_res = 0; @@ -934,8 +932,6 @@ auto CPUDensityMatrixPolicyBase::ExpectDiffFSimPhi(const q SHIFT_BIT_TWO(mask.obj_low_mask, mask.obj_rev_low_mask, mask.obj_high_mask, mask.obj_rev_high_mask, l, r0); auto r3 = r0 + mask.obj_mask; - auto r1 = r0 + mask.obj_min_mask; - auto r2 = r0 + mask.obj_max_mask; qs_data_t this_res = 0; for (index_t col = 0; col < dim; col++) { this_res += GetValue(qs, r3, col) * GetValue(ham_matrix, col, r3); @@ -955,8 +951,6 @@ auto CPUDensityMatrixPolicyBase::ExpectDiffFSimPhi(const q l, r0); if ((r0 & mask.ctrl_mask) == mask.ctrl_mask) { auto r3 = r0 + mask.obj_mask; - auto r1 = r0 + mask.obj_min_mask; - auto r2 = r0 + mask.obj_max_mask; qs_data_t this_res = 0; for (index_t col = 0; col < dim; col++) { this_res += GetValue(qs, r3, col) * GetValue(ham_matrix, col, r3); diff --git a/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_policy.cpp b/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_policy.cpp index 6fcb5ee30..42ad74b9a 100644 --- a/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_policy.cpp +++ b/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_policy.cpp @@ -17,7 +17,6 @@ #include "core/utils.hpp" #include "math/pr/parameter_resolver.hpp" -#include "simulator/types.hpp" #include "simulator/utils.hpp" #ifdef __x86_64__ # include "simulator/densitymatrix/detail/cpu_densitymatrix_avx_double_policy.hpp" @@ -255,8 +254,8 @@ void CPUDensityMatrixPolicyBase::ApplyTerms(qs_data_p_t* q dim, DimTh, for (omp::idx_t i = 0; i < dim; i++) { auto j = (i ^ mask_f); if (i <= j) { - auto axis2power = CountOne(static_cast(i & mask.mask_z)); // -1 - auto axis3power = CountOne(static_cast(i & mask.mask_y)); // -1j + auto axis2power = CountOne(i & mask.mask_z); // -1 + auto axis3power = CountOne(i & mask.mask_y); // -1j auto c = ComplexCast::apply( POLAR[static_cast((mask.num_y + 2 * axis3power + 2 * axis2power) & 3)]); for (index_t col = 0; col < dim; col++) { @@ -279,8 +278,8 @@ void CPUDensityMatrixPolicyBase::ApplyTerms(qs_data_p_t* q dim, DimTh, for (omp::idx_t i = 0; i < dim; i++) { auto j = (i ^ mask_f); if (i <= j) { - auto axis2power = CountOne(static_cast(i & mask.mask_z)); // -1 - auto axis3power = CountOne(static_cast(i & mask.mask_y)); // -1j + auto axis2power = CountOne(i & mask.mask_z); // -1 + auto axis3power = CountOne(i & mask.mask_y); // -1j auto c = ComplexCast::apply( POLAR[static_cast((mask.num_y + 2 * axis3power + 2 * axis2power) & 3)]); for (index_t row = 0; row <= i; row++) { diff --git a/ccsrc/lib/simulator/utils.cpp b/ccsrc/lib/simulator/utils.cpp index 2ae86ef22..65c90574e 100644 --- a/ccsrc/lib/simulator/utils.cpp +++ b/ccsrc/lib/simulator/utils.cpp @@ -17,8 +17,6 @@ #include #include -#include "simulator/types.hpp" - namespace mindquantum::sim { index_t QIndexToMask(qbits_t objs) { return std::accumulate(objs.begin(), objs.end(), index_t(0), [](index_t a, qbit_t b) { return a + (1UL << b); }); diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_policy.cpp b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_policy.cpp index 1a4acfa6e..a244a0317 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_policy.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_policy.cpp @@ -21,7 +21,6 @@ #include "core/utils.hpp" #include "math/pr/parameter_resolver.hpp" -#include "simulator/types.hpp" #include "simulator/utils.hpp" #ifdef __x86_64__ # include "simulator/vector/detail/cpu_vector_avx_double_policy.hpp" @@ -143,8 +142,8 @@ auto CPUVectorPolicyBase::ApplyTerms(qs_data_p_t* qs_p, dim, DimTh, for (omp::idx_t i = 0; i < dim; i++) { auto j = (i ^ mask_f); if (i <= j) { - auto axis2power = CountOne(static_cast(i & mask.mask_z)); // -1 - auto axis3power = CountOne(static_cast(i & mask.mask_y)); // -1j + auto axis2power = CountOne(i & mask.mask_z); // -1 + auto axis3power = CountOne(i & mask.mask_y); // -1j auto c = ComplexCast::apply( POLAR[static_cast((mask.num_y + 2 * axis3power + 2 * axis2power) & 3)]); out[j] += qs[i] * coeff * c; @@ -185,8 +184,8 @@ auto CPUVectorPolicyBase::ExpectationOfTerms(const qs_data for (omp::idx_t i = 0; i < dim; i++) { auto j = (i ^ mask_f); if (i <= j) { - auto axis2power = CountOne(static_cast(i & mask.mask_z)); // -1 - auto axis3power = CountOne(static_cast(i & mask.mask_y)); // -1j + auto axis2power = CountOne(i & mask.mask_z); // -1 + auto axis3power = CountOne(i & mask.mask_y); // -1j auto c = ComplexCast::apply( POLAR[static_cast((mask.num_y + 2 * axis3power + 2 * axis2power) & 3)]); auto tmp = std::conj(bra[j]) * ket[i] * coeff * c; @@ -219,7 +218,7 @@ auto CPUVectorPolicyBase::GroundStateOfZZs(const std::map(i & mask)) & 1) { + if (CountOne(i & mask) & 1) { ith_energy -= coeff; } else { ith_energy += coeff; diff --git a/ccsrc/python/mqbackend/lib/binding.cc b/ccsrc/python/mqbackend/lib/binding.cc index 1d467fc14..3639b07ec 100644 --- a/ccsrc/python/mqbackend/lib/binding.cc +++ b/ccsrc/python/mqbackend/lib/binding.cc @@ -67,111 +67,113 @@ void init_logging(pybind11::module &module); // NOLINT(runtime/references)NOLIN void BindTypeIndependentGate(py::module &module) { // NOLINT(runtime/references) using mindquantum::Index; + using mindquantum::qbits_t; using mindquantum::VT; py::class_>( module, "MeasureGate") - .def(py::init &>(), "name"_a, "obj_qubits"_a); + .def(py::init(), "name"_a, "obj_qubits"_a); py::class_>(module, "IGate") - .def(py::init &, const VT &>(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); + .def(py::init(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "XGate") - .def(py::init &, const VT &>(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); + .def(py::init(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "YGate") - .def(py::init &, const VT &>(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); + .def(py::init(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "ZGate") - .def(py::init &, const VT &>(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); + .def(py::init(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "HGate") - .def(py::init &, const VT &>(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); + .def(py::init(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "ISWAPGate") - .def(py::init &, const VT &>(), "daggered"_a, "obj_qubits"_a, + .def(py::init(), "daggered"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "SWAPGate") - .def(py::init &, const VT &>(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); + .def(py::init(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "SGate") - .def(py::init &, const VT &>(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); + .def(py::init(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "SdagGate") - .def(py::init &, const VT &>(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); + .def(py::init(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "TGate") - .def(py::init &, const VT &>(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); + .def(py::init(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "TdagGate") - .def(py::init &, const VT &>(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); + .def(py::init(), "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>( module, "PauliChannel") - .def(py::init &, const VT &>(), "px"_a, "py"_a, "pz"_a, + .def(py::init(), "px"_a, "py"_a, "pz"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "DepolarizingChannel") - .def(py::init &, const VT &>(), "p"_a, "obj_qubits"_a, + .def(py::init(), "p"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "AmplitudeDampingChannel") - .def(py::init &, const VT &>(), "daggered"_a, "damping_coeff"_a, + .def(py::init(), "daggered"_a, "damping_coeff"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "PhaseDampingChannel") - .def(py::init &, const VT &>(), "damping_coeff"_a, "obj_qubits"_a, + .def(py::init(), "damping_coeff"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); } void BindTypeDependentGate(py::module &module) { // NOLINT(runtime/references) using mindquantum::CT; using mindquantum::Index; + using mindquantum::qbits_t; using mindquantum::VT; using mindquantum::VVT; using parameter::ParameterResolver; py::class_>(module, "RXGate") - .def(py::init &, const VT &>(), "pr"_a, "obj_qubits"_a, + .def(py::init(), "pr"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "RYGate") - .def(py::init &, const VT &>(), "pr"_a, "obj_qubits"_a, + .def(py::init(), "pr"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "RZGate") - .def(py::init &, const VT &>(), "pr"_a, "obj_qubits"_a, + .def(py::init(), "pr"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "RxxGate") - .def(py::init &, const VT &>(), "pr"_a, "obj_qubits"_a, + .def(py::init(), "pr"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "RyyGate") - .def(py::init &, const VT &>(), "pr"_a, "obj_qubits"_a, + .def(py::init(), "pr"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "RzzGate") - .def(py::init &, const VT &>(), "pr"_a, "obj_qubits"_a, + .def(py::init(), "pr"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "RxyGate") - .def(py::init &, const VT &>(), "pr"_a, "obj_qubits"_a, + .def(py::init(), "pr"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "RxzGate") - .def(py::init &, const VT &>(), "pr"_a, "obj_qubits"_a, + .def(py::init(), "pr"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "RyzGate") - .def(py::init &, const VT &>(), "pr"_a, "obj_qubits"_a, + .def(py::init(), "pr"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "GPGate") - .def(py::init &, const VT &>(), "pr"_a, "obj_qubits"_a, + .def(py::init(), "pr"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "PSGate") - .def(py::init &, const VT &>(), "pr"_a, "obj_qubits"_a, + .def(py::init(), "pr"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "u3") - .def(py::init &, const VT &>(), + .def(py::init(), "theta"_a, "phi"_a, "lambda"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "fsim") - .def(py::init &, const VT &>(), + .def(py::init(), "theta"_a, "phi"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>( module, "KrausChannel") - .def(py::init>> &, const VT &, const VT &>(), "kraus_operator_set"_a, + .def(py::init>> &, const qbits_t &, const qbits_t &>(), "kraus_operator_set"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()); py::class_>(module, "CustomGate") - .def(py::init &, - const VT &>(), - "name"_a, "m_addr"_a, "dm_addr"_a, "dim"_a, "pr"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()) - .def(py::init &, const VT &>(), "name"_a, "mat"_a, + .def( + py::init(), + "name"_a, "m_addr"_a, "dm_addr"_a, "dim"_a, "pr"_a, "obj_qubits"_a, "ctrl_qubits"_a = VT()) + .def(py::init(), "name"_a, "mat"_a, "obj_qubits"_a, "ctrl_qubits"_a); } template diff --git a/ccsrc/python/simulator/include/python/densitymatrix/bind_mat_state.hpp b/ccsrc/python/simulator/include/python/densitymatrix/bind_mat_state.hpp index 4f879aa10..0e2f74fb9 100644 --- a/ccsrc/python/simulator/include/python/densitymatrix/bind_mat_state.hpp +++ b/ccsrc/python/simulator/include/python/densitymatrix/bind_mat_state.hpp @@ -22,7 +22,6 @@ #include #include "math/pr/parameter_resolver.hpp" -#include "simulator/types.hpp" #ifdef __CUDACC__ # include "simulator/densitymatrix/detail/gpu_densitymatrix_double_policy.cuh" @@ -43,8 +42,7 @@ template auto BindSim(pybind11::module& module, const std::string_view& name) { // NOLINT using namespace pybind11::literals; // NOLINT - using qbit_t = mindquantum::sim::qbit_t; - using calc_type = typename sim_t::calc_type; + using qbit_t = mindquantum::qbit_t; return pybind11::class_(module, name.data()) .def(pybind11::init(), "n_qubits"_a, "seed"_a = 42) diff --git a/ccsrc/python/simulator/include/python/vector/bind_vec_state.h b/ccsrc/python/simulator/include/python/vector/bind_vec_state.h index 33ad5aa7c..9b4dba96e 100644 --- a/ccsrc/python/simulator/include/python/vector/bind_vec_state.h +++ b/ccsrc/python/simulator/include/python/vector/bind_vec_state.h @@ -22,7 +22,6 @@ #include #include "math/pr/parameter_resolver.hpp" -#include "simulator/types.hpp" #ifdef __CUDACC__ # include "simulator/vector/detail/gpu_vector_double_policy.cuh" @@ -45,7 +44,7 @@ template auto BindSim(pybind11::module& module, const std::string_view& name) { // NOLINT using namespace pybind11::literals; // NOLINT - using qbit_t = mindquantum::sim::qbit_t; + using qbit_t = mindquantum::qbit_t; using calc_type = typename sim_t::calc_type; using circuit_t = typename sim_t::circuit_t; From 2cc83225e722c9cb255459cc681c7d9b98e2f024 Mon Sep 17 00:00:00 2001 From: donghufeng Date: Tue, 18 Jul 2023 23:00:10 +0800 Subject: [PATCH 003/100] fix wall --- .cppcheck.suppressions | 1 + CMakeLists.txt | 2 +- ccsrc/include/math/tensor/matrix.hpp | 2 +- .../math/tensor/ops_cpu/advance_math.hpp | 49 +++++++++++++------ .../math/tensor/ops_cpu/basic_math.hpp | 12 ++--- .../densitymatrix/densitymatrix_state.tpp | 2 +- .../detail/cpu_densitymatrix_policy.hpp | 2 +- .../vector/detail/cpu_vector_policy.hpp | 2 +- .../vector/detail/gpu_vector_policy.cuh | 2 +- .../include/simulator/vector/vector_state.tpp | 4 +- ccsrc/lib/device/mapping.cpp | 12 ++--- ccsrc/lib/math/CMakeLists.txt | 2 +- .../math/operators/fermion_operator_view.cpp | 21 ++++---- .../math/operators/qubit_operator_view.cpp | 8 +-- .../operators/transform/bravyi_kitaev.cpp | 2 +- .../transform/bravyi_kitaev_superfast.cpp | 25 +++++----- .../operators/transform/jordan_wigner.cpp | 4 +- ccsrc/lib/math/operators/transform/parity.cpp | 6 +-- .../math/operators/transform/ternary_tree.cpp | 10 ++-- ccsrc/lib/math/pr/parameter_resolver.cpp | 6 +-- ccsrc/lib/math/tensor/ops_cpu/basic_math.cpp | 8 +-- .../math/tensor/ops_cpu/memory_operator.cpp | 1 + .../cpu_densitymatrix_core_policy.cpp | 6 +-- .../cpu_common/cpu_vector_core_policy.cpp | 2 +- .../detail/gpu/gpu_vector_core_policy.cu | 2 +- .../python/core/sparse/csrhdmatrix.hpp | 4 +- 26 files changed, 111 insertions(+), 86 deletions(-) diff --git a/.cppcheck.suppressions b/.cppcheck.suppressions index 6c352b5a0..2783ab57f 100644 --- a/.cppcheck.suppressions +++ b/.cppcheck.suppressions @@ -59,6 +59,7 @@ syntaxError:ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatri unknownMacro:ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_rot_pauli.cpp unknownMacro:ccsrc/include/core/sparse/paulimat.hpp unknownMacro:ccsrc/include/core/sparse/paulimat.hpp:58 +unknownMacro:ccsrc/include/math/tensor/ops_cpu/basic_math.hpp unknownMacro:ccsrc/lib/simulator/vector/detail/cpu_vector_policy_single_ops.cpp unknownMacro:ccsrc/lib/simulator/vector/detail/cpu_vector_policy_xlike.cpp unknownMacro:ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_z_like.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index cab237acb..f2cb82ecd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,7 +57,7 @@ set(MQ_INSTALL_DOCDIR "${CMAKE_INSTALL_DATADIR}/doc/mindquantum") set(MQ_INSTALL_CMAKEDIR "${MQ_INSTALL_DATADIR}/cmake") set(MQ_INSTALL_3RDPARTYDIR "${MQ_INSTALL_LIBDIR}/third_party") -add_compile_options(-Wall -Wextra -Wfloat-equal) +# add_compile_options(-Wall -Wextra -Wfloat-equal) foreach( _type diff --git a/ccsrc/include/math/tensor/matrix.hpp b/ccsrc/include/math/tensor/matrix.hpp index 640ef613e..99dfdb107 100644 --- a/ccsrc/include/math/tensor/matrix.hpp +++ b/ccsrc/include/math/tensor/matrix.hpp @@ -46,7 +46,7 @@ struct Matrix : public Tensor { } auto t = Tensor(tmp); this->dtype = t.dtype; - this->device = t.device; + this->device = device; this->data = t.data; this->dim = t.dim; t.data = nullptr; diff --git a/ccsrc/include/math/tensor/ops_cpu/advance_math.hpp b/ccsrc/include/math/tensor/ops_cpu/advance_math.hpp index 8fad8cab5..44493960a 100644 --- a/ccsrc/include/math/tensor/ops_cpu/advance_math.hpp +++ b/ccsrc/include/math/tensor/ops_cpu/advance_math.hpp @@ -48,6 +48,9 @@ template Tensor imag(void* data, size_t len) { constexpr TDtype real_t = to_real_dtype_t; if constexpr (dtype == real_t) { + if (data == nullptr) { + throw std::runtime_error("data cannot be nullptr."); + } return cpu::zeros(len, dtype); } else { auto out = ops::cpu::init(len); @@ -116,11 +119,12 @@ bool is_all_zero(void* data, size_t len) { auto c_data = reinterpret_cast*>(data); for (size_t i = 0; i < len; i++) { if constexpr (is_complex_v>) { - if (std::real(c_data[i]) != 0 || std::imag(c_data[i]) != 0) { + if ((std::real(c_data[i]) > 0) || (std::real(c_data[i]) < 0) || (std::imag(c_data[i]) > 0) + || (std::imag(c_data[i]) < 0)) { return false; } } else { - if (c_data[i] != 0) { + if ((c_data[i] > 0) || (c_data[i] < 0)) { return false; } } @@ -132,17 +136,17 @@ bool is_all_zero(const Tensor& t); // ----------------------------------------------------------------------------- template bool operator==(T1 a, const std::complex& b) { - return a == b.real(); + return (!(a > b.real())) && (!(a < b.real())); } template bool operator==(const std::complex& a, T2 b) { - return a.real() == b; + return (!(a.real() > b)) && (!(a.real() < b)); } template bool operator==(const std::complex& a, const std::complex b) { - return (a.real() == b.real()) && (a.imag() == b.imag()); + return !(a.real() > b.real()) && !(a.real() < b.real()) && !(a.imag() > b.imag()) && !(a.imag() < b.imag()); } template @@ -155,19 +159,36 @@ std::vector is_equal_to(void* lhs, size_t lhs_len, void* rhs, size_t rhs_l auto c_lhs = reinterpret_cast(lhs); auto c_rhs = reinterpret_cast(rhs); std::vector out; - if (lhs_len == 1) { - for (size_t i = 0; i < rhs_len; i++) { - out.push_back(c_lhs[0] == c_rhs[i]); - } - } else if (rhs_len == 1) { - for (size_t i = 0; i < lhs_len; i++) { - out.push_back(c_lhs[i] == c_rhs[0]); + if constexpr (!is_complex_dtype_v && !is_complex_dtype_v) { + if (lhs_len == 1) { + for (size_t i = 0; i < rhs_len; i++) { + out.push_back(!(c_lhs[0] > c_rhs[i]) && !(c_lhs[0] < c_rhs[i])); + } + } else if (rhs_len == 1) { + for (size_t i = 0; i < lhs_len; i++) { + out.push_back(!(c_lhs[i] > c_rhs[0]) && !(c_lhs[i] < c_rhs[0])); + } + } else { + for (size_t i = 0; i < lhs_len; i++) { + out.push_back(!(c_lhs[i] > c_rhs[i]) && !(c_lhs[i] < c_rhs[i])); + } } } else { - for (size_t i = 0; i < lhs_len; i++) { - out.push_back(c_lhs[i] == c_rhs[i]); + if (lhs_len == 1) { + for (size_t i = 0; i < rhs_len; i++) { + out.push_back(c_lhs[0] == c_rhs[i]); + } + } else if (rhs_len == 1) { + for (size_t i = 0; i < lhs_len; i++) { + out.push_back(c_lhs[i] == c_rhs[0]); + } + } else { + for (size_t i = 0; i < lhs_len; i++) { + out.push_back(c_lhs[i] == c_rhs[i]); + } } } + return out; } diff --git a/ccsrc/include/math/tensor/ops_cpu/basic_math.hpp b/ccsrc/include/math/tensor/ops_cpu/basic_math.hpp index be985b6ee..c064f6c6d 100644 --- a/ccsrc/include/math/tensor/ops_cpu/basic_math.hpp +++ b/ccsrc/include/math/tensor/ops_cpu/basic_math.hpp @@ -54,7 +54,6 @@ void InplaceBinary(void* data, size_t len, void* other) { auto c_other = reinterpret_cast(other); auto ops = binary_ops<>(); auto caster = cast_value(); - auto first = c_other[0]; for (size_t i = 0; i < len; i++) { if constexpr (is_array) { if constexpr (reverse) { @@ -64,9 +63,9 @@ void InplaceBinary(void* data, size_t len, void* other) { } } else { if constexpr (reverse) { - c_data[i] = ops(caster(first), c_data[i]); + c_data[i] = ops(caster(c_other[0]), c_data[i]); } else { - c_data[i] = ops(c_data[i], caster(first)); + c_data[i] = ops(c_data[i], caster(c_other[0])); } } } @@ -83,7 +82,6 @@ Tensor GenerateBinary(void* data, size_t len, void* other) { auto ops = binary_ops<>(); auto caster0 = cast_value, to_device_t>(); auto caster1 = cast_value, to_device_t>(); - auto first = c_other[0]; for (size_t i = 0; i < len; i++) { if constexpr (is_array) { if constexpr (reverse) { @@ -93,9 +91,9 @@ Tensor GenerateBinary(void* data, size_t len, void* other) { } } else { if constexpr (reverse) { - c_des[i] = ops(caster1(first), caster0(c_data[i])); + c_des[i] = ops(caster1(c_other[0]), caster0(c_data[i])); } else { - c_des[i] = ops(caster0(c_data[i]), caster1(first)); + c_des[i] = ops(caster0(c_data[i]), caster1(c_other[0])); } } } @@ -563,7 +561,7 @@ Matrix MatMul(const Matrix& m1, const Matrix& m2); // ----------------------------------------------------------------------------- template -Tensor MatMul(void* m1, size_t* indptr, size_t* indices, size_t n_row, size_t n_col, size_t nnz, void* m2, size_t len) { +Tensor MatMul(void* m1, size_t* indptr, size_t* indices, size_t n_row, size_t n_col, void* m2, size_t len) { if (n_col != len) { throw std::runtime_error("Dimension mismatch: cannot multiply matrix and vector."); } diff --git a/ccsrc/include/simulator/densitymatrix/densitymatrix_state.tpp b/ccsrc/include/simulator/densitymatrix/densitymatrix_state.tpp index d615a5cf4..6a939cb45 100644 --- a/ccsrc/include/simulator/densitymatrix/densitymatrix_state.tpp +++ b/ccsrc/include/simulator/densitymatrix/densitymatrix_state.tpp @@ -117,7 +117,7 @@ tensor::TDtype DensityMatrixState::DType() { template void DensityMatrixState::Reset() { - qs_policy_t::Reset(&qs, dim); + qs_policy_t::Reset(&qs); } template diff --git a/ccsrc/include/simulator/densitymatrix/detail/cpu_densitymatrix_policy.hpp b/ccsrc/include/simulator/densitymatrix/detail/cpu_densitymatrix_policy.hpp index 45f5d1527..cacce935c 100644 --- a/ccsrc/include/simulator/densitymatrix/detail/cpu_densitymatrix_policy.hpp +++ b/ccsrc/include/simulator/densitymatrix/detail/cpu_densitymatrix_policy.hpp @@ -60,7 +60,7 @@ struct CPUDensityMatrixPolicyBase { static void SwapValue(qs_data_p_t qs, index_t x0, index_t y0, index_t x1, index_t y1, qs_data_t coeff); static qs_data_p_t InitState(index_t dim, bool zero_state = true); - static void Reset(qs_data_p_t* qs_p, index_t dim, bool zero_state = true); + static void Reset(qs_data_p_t* qs_p); static void FreeState(qs_data_p_t* qs_p); static void Display(const qs_data_p_t& qs, qbit_t n_qubits, qbit_t q_limit = 10); static void SetToZeroExcept(qs_data_p_t* qs_p, index_t ctrl_mask, index_t dim); diff --git a/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp b/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp index 2bb6e2653..0704fae9d 100644 --- a/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp +++ b/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp @@ -51,7 +51,7 @@ struct CPUVectorPolicyBase { // ======================================================================================================== static qs_data_p_t InitState(index_t dim, bool zero_state = true); - static void Reset(qs_data_p_t* qs_p, index_t dim); + static void Reset(qs_data_p_t* qs_p); static void FreeState(qs_data_p_t* qs_p); static void Display(const qs_data_p_t& qs, qbit_t n_qubits, qbit_t q_limit = 10); static void SetToZeroExcept(qs_data_p_t* qs_p, index_t ctrl_mask, index_t dim); diff --git a/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh b/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh index efd346c2a..73766cfa3 100644 --- a/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh +++ b/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh @@ -42,7 +42,7 @@ struct GPUVectorPolicyBase { using py_qs_data_t = std::complex; using py_qs_datas_t = std::vector; static qs_data_p_t InitState(index_t dim, bool zero_state = true); - static void Reset(qs_data_p_t* qs_p, index_t dim); + static void Reset(qs_data_p_t* qs_p); static void FreeState(qs_data_p_t* qs_p); static void Display(const qs_data_p_t& qs, qbit_t n_qubits, qbit_t q_limit = 10); static void SetToZeroExcept(qs_data_p_t* qs_p, index_t ctrl_mask, index_t dim); diff --git a/ccsrc/include/simulator/vector/vector_state.tpp b/ccsrc/include/simulator/vector/vector_state.tpp index d5b97bc58..26656709f 100644 --- a/ccsrc/include/simulator/vector/vector_state.tpp +++ b/ccsrc/include/simulator/vector/vector_state.tpp @@ -127,7 +127,7 @@ tensor::TDtype VectorState::DType() { template void VectorState::Reset() { - qs_policy_t::Reset(&qs, dim); + qs_policy_t::Reset(&qs); } template @@ -404,7 +404,7 @@ void VectorState::ApplyDepolarizingChannel(const std::shared_ptrobj_qubits_) { + for (qbit_t obj_qubit : gate->obj_qubits_) { int gate_index = 0; for (int i = 0; i < 4; i++) { if (s <= gap * (i + 1) / 4) { diff --git a/ccsrc/lib/device/mapping.cpp b/ccsrc/lib/device/mapping.cpp index cf1a75d40..9fba4b2a5 100644 --- a/ccsrc/lib/device/mapping.cpp +++ b/ccsrc/lib/device/mapping.cpp @@ -33,7 +33,7 @@ VT> GetCircuitDAG(int n, const VT& gates) { VT last(n, -1); VT> DAG(m); - for (int i = 0; i < gates.size(); ++i) { + for (int i = 0; i < static_cast(gates.size()); ++i) { int q1 = gates[i].q1; int q2 = gates[i].q2; @@ -95,7 +95,7 @@ bool SABRE::IsExecutable(const VT& pi, int g) const { VT SABRE::GetReversePi(const VT& pi) const { VT rpi(pi.size()); - for (int i = 0; i < pi.size(); ++i) { + for (int i = 0; i < static_cast(pi.size()); ++i) { rpi[pi[i]] = i; } return rpi; @@ -182,7 +182,7 @@ SABRE::SABRE(const VT>& circ, const std::shared_ptrDAG = GetCircuitDAG(num_logical, gates); this->RDAG = VT>(this->DAG.size()); - for (int x; x < DAG.size(); ++x) { + for (int x = 0; x < static_cast(DAG.size()); ++x) { for (int y : DAG[x]) RDAG[y].push_back(x); } @@ -212,12 +212,12 @@ VT SABRE::HeuristicSearch(VT& pi, const VT>& DAG) { VT decay(pi.size(), 1); // decay of logical qubits VT indeg(DAG.size(), 0); // in-degree of DAG nodes - for (int i = 0; i < DAG.size(); ++i) + for (int i = 0; i < static_cast(DAG.size()); ++i) for (int j : DAG[i]) indeg[j]++; std::list F; // front layer - for (int i = 0; i < DAG.size(); ++i) + for (int i = 0; i < static_cast(DAG.size()); ++i) if (indeg[i] == 0) F.push_back(i); @@ -298,7 +298,7 @@ std::pair>, std::pair, VT>> SABRE::Solve(int iter_num, d // generate random initial mapping VT pi(this->num_physical); - for (int i = 0; i < pi.size(); ++i) + for (int i = 0; i < static_cast(pi.size()); ++i) pi[i] = i; auto seed = std::chrono::system_clock::now().time_since_epoch().count(); diff --git a/ccsrc/lib/math/CMakeLists.txt b/ccsrc/lib/math/CMakeLists.txt index c463e2b91..4082c2480 100644 --- a/ccsrc/lib/math/CMakeLists.txt +++ b/ccsrc/lib/math/CMakeLists.txt @@ -19,7 +19,7 @@ add_library(mq_math) force_at_least_cxx17_workaround(mq_math) append_to_property(mq_install_targets GLOBAL mq_math) -target_link_libraries(mq_math PUBLIC include_lib cmake_config cxx20_compat) +target_link_libraries(mq_math PUBLIC ${MQ_OPENMP_TARGET} include_lib cmake_config cxx20_compat) # ============================================================================== diff --git a/ccsrc/lib/math/operators/fermion_operator_view.cpp b/ccsrc/lib/math/operators/fermion_operator_view.cpp index 3d28f7e73..c24a675d5 100644 --- a/ccsrc/lib/math/operators/fermion_operator_view.cpp +++ b/ccsrc/lib/math/operators/fermion_operator_view.cpp @@ -126,7 +126,7 @@ std::vector SingleFermionStr::NumOneMask(const compress_term_t& fermio uint64_t SingleFermionStr::PrevOneMask(const std::vector& one_mask, size_t idx) { uint64_t out = 0; - for (int i = 0; i < idx; i++) { + for (size_t i = 0; i < idx; i++) { if (i < one_mask.size()) { out += __builtin_popcount(one_mask[i]); } @@ -185,7 +185,7 @@ bool SingleFermionStr::InplaceMulCompressTerm(const term_t& term, compress_term_ for (size_t i = ori_term.size(); i < group_id + 1; i++) { ori_term.push_back(0); } - ori_term[group_id] = ori_term[group_id] & (~local_mask) | (static_cast(word)) << local_id; + ori_term[group_id] = (ori_term[group_id] & (~local_mask)) | (static_cast(word)) << local_id; } else { TermValue lhs = static_cast((ori_term[group_id] & local_mask) >> local_id); auto res = fermion_product_map.at(lhs).at(word); @@ -195,10 +195,11 @@ bool SingleFermionStr::InplaceMulCompressTerm(const term_t& term, compress_term_ } return false; } - ori_term[group_id] = ori_term[group_id] & (~local_mask) | (static_cast(res)) << local_id; - one_mask = (one_mask + __builtin_popcount(static_cast(word)) - & __builtin_popcount(ori_term[group_id] & low_mask)) - & 1; + ori_term[group_id] = (ori_term[group_id] & (~local_mask)) | (static_cast(res)) << local_id; + one_mask + = (one_mask + + (__builtin_popcount(static_cast(word)) & __builtin_popcount(ori_term[group_id] & low_mask))) + & 1; } if (one_mask & 1) { coeff *= -1.0; @@ -210,7 +211,7 @@ bool SingleFermionStr::IsSameString(const key_t& k1, const key_t& k2) { if (k1[0] != k2[0]) { return false; } - for (int i = 1; i < std::max(k1.size(), k2.size()); i++) { + for (std::size_t i = 1; i < std::max(k1.size(), k2.size()); i++) { uint64_t this_fermion, other_fermion; if (i >= k1.size()) { this_fermion = 0; @@ -289,11 +290,11 @@ auto SingleFermionStr::Mul(const compress_term_t& lhs, const compress_term_t& rh fermion_string.push_back(s); return {fermion_string, coeff}; } - int min_size = std::min(l_k.size(), r_k.size()); - int max_size = std::max(l_k.size(), r_k.size()); + std::size_t min_size = std::min(l_k.size(), r_k.size()); + std::size_t max_size = std::max(l_k.size(), r_k.size()); int one_in_low = 0; int total_one = 0; - for (int i = 0; i < max_size; i++) { + for (std::size_t i = 0; i < max_size; i++) { if (i < min_size) { total_one += one_in_low & __builtin_popcount(r_k[i]); one_in_low += __builtin_popcount(l_k[i]); diff --git a/ccsrc/lib/math/operators/qubit_operator_view.cpp b/ccsrc/lib/math/operators/qubit_operator_view.cpp index e5b36771a..b11d21134 100644 --- a/ccsrc/lib/math/operators/qubit_operator_view.cpp +++ b/ccsrc/lib/math/operators/qubit_operator_view.cpp @@ -106,12 +106,12 @@ void SinglePauliStr::InplaceMulCompressTerm(const term_t& term, compress_term_t& for (size_t i = pauli_string.size(); i < group_id + 1; i++) { pauli_string.push_back(0); } - pauli_string[group_id] = pauli_string[group_id] & (~local_mask) | (static_cast(word)) << local_id; + pauli_string[group_id] = (pauli_string[group_id] & (~local_mask)) | (static_cast(word)) << local_id; } else { TermValue lhs = static_cast((pauli_string[group_id] & local_mask) >> local_id); auto [t, res] = pauli_product_map.at(lhs).at(word); coeff = coeff * t; - pauli_string[group_id] = pauli_string[group_id] & (~local_mask) | (static_cast(res)) << local_id; + pauli_string[group_id] = (pauli_string[group_id] & (~local_mask)) | (static_cast(res)) << local_id; } } @@ -119,7 +119,7 @@ bool SinglePauliStr::IsSameString(const key_t& k1, const key_t& k2) { if (k1[0] != k2[0]) { return false; } - for (int i = 1; i < std::max(k1.size(), k2.size()); i++) { + for (std::size_t i = 1; i < std::max(k1.size(), k2.size()); i++) { uint64_t this_pauli, other_pauli; if (i >= k1.size()) { this_pauli = 0; @@ -188,7 +188,7 @@ auto SinglePauliStr::Mul(const compress_term_t& lhs, const compress_term_t& rhs) auto [t, s] = MulSingleCompressTerm(l_k[i], r_k[i]); coeff = coeff * t; pauli_string.push_back(s); - } else if (i >= l_k.size()) { + } else if (i >= static_cast(l_k.size())) { pauli_string.push_back(r_k[i]); } else { pauli_string.push_back(l_k[i]); diff --git a/ccsrc/lib/math/operators/transform/bravyi_kitaev.cpp b/ccsrc/lib/math/operators/transform/bravyi_kitaev.cpp index 61622f976..059bbe70e 100644 --- a/ccsrc/lib/math/operators/transform/bravyi_kitaev.cpp +++ b/ccsrc/lib/math/operators/transform/bravyi_kitaev.cpp @@ -83,7 +83,7 @@ std::unordered_set update_set(qubit_op_t::term_t */ std::unordered_set indices; qubit_op_t::term_t::first_type index = idx + 1; - while (index <= n_qubits) { + while (index <= static_cast(n_qubits)) { indices.insert(index - 1); index += index & (-index); } diff --git a/ccsrc/lib/math/operators/transform/bravyi_kitaev_superfast.cpp b/ccsrc/lib/math/operators/transform/bravyi_kitaev_superfast.cpp index cf77e32fa..796d7f3d4 100644 --- a/ccsrc/lib/math/operators/transform/bravyi_kitaev_superfast.cpp +++ b/ccsrc/lib/math/operators/transform/bravyi_kitaev_superfast.cpp @@ -176,11 +176,11 @@ edge_enum_t enumerate_edges(const edge_matrix_t& edge_matrix) { return edge_enum; } -qubit_op_t get_b(int i, const edge_matrix_t& edge_matrix, edge_enum_t& edge_enum) { +qubit_op_t get_b(int i, const edge_matrix_t& edge_matrix, const edge_enum_t& edge_enum) { qubit_op_t::terms_t terms; - for (int j = 0; j < edge_matrix[i].size(); j++) { + for (int j = 0; j < static_cast(edge_matrix[i].size()); j++) { if (edge_matrix[i][j] != 0) { - terms.emplace_back(edge_enum[std::pair{i, j}], + terms.emplace_back(edge_enum.at(std::pair{i, j}), qubit::TermValue::Z); // not sure if it is correct } } @@ -188,18 +188,18 @@ qubit_op_t get_b(int i, const edge_matrix_t& edge_matrix, edge_enum_t& edge_enum return out; } -qubit_op_t get_a(int i, int j, const edge_matrix_t& edge_matrix, edge_enum_t& edge_enum) { +qubit_op_t get_a(int i, int j, const edge_matrix_t& edge_matrix, const edge_enum_t& edge_enum) { qubit_op_t::terms_t terms; - terms.emplace_back(edge_enum[std::pair{i, j}], qubit::TermValue::X); + terms.emplace_back(edge_enum.at(std::pair{i, j}), qubit::TermValue::X); for (int k = 0; k < j; k++) { if (edge_matrix[k][i] != 0) { - terms.emplace_back(edge_enum[std::pair{k, i}], + terms.emplace_back(edge_enum.at(std::pair{k, i}), qubit::TermValue::Z); // not sure if it is correct } } for (int s = 0; s < i; s++) { if (edge_matrix[s][j] != 0) { - terms.emplace_back(edge_enum[std::pair{s, j}], + terms.emplace_back(edge_enum.at(std::pair{s, j}), qubit::TermValue::Z); // not sure if it is correct } } @@ -207,30 +207,31 @@ qubit_op_t get_a(int i, int j, const edge_matrix_t& edge_matrix, edge_enum_t& ed return out; } -qubit_op_t transformed_number_operator(int i, const edge_matrix_t& edge_matrix, edge_enum_t& edge_enum) { +qubit_op_t transformed_number_operator(int i, const edge_matrix_t& edge_matrix, const edge_enum_t& edge_enum) { return (qubit_op_t("") - get_b(i, edge_matrix, edge_enum)) * tensor::ops::init_with_value(0.5); } -qubit_op_t transformed_excitation_operator(int i, int j, const edge_matrix_t& edge_matrix, edge_enum_t& edge_enum) { +qubit_op_t transformed_excitation_operator(int i, int j, const edge_matrix_t& edge_matrix, + const edge_enum_t& edge_enum) { qubit_op_t a_ij = get_a(i, j, edge_matrix, edge_enum); return (a_ij * get_b(j, edge_matrix, edge_enum) + get_b(i, edge_matrix, edge_enum) * a_ij) * tensor::ops::init_with_value(std::complex(0, -0.5)); } -qubit_op_t transformed_exchange_operator(int i, int j, const edge_matrix_t& edge_matrix, edge_enum_t& edge_enum) { +qubit_op_t transformed_exchange_operator(int i, int j, const edge_matrix_t& edge_matrix, const edge_enum_t& edge_enum) { return ((qubit_op_t("") - get_b(i, edge_matrix, edge_enum)) * (qubit_op_t("") - get_b(j, edge_matrix, edge_enum)) * tensor::ops::init_with_value(0.25)); } qubit_op_t transformed_number_excitation_operator(int i, int j, int k, const edge_matrix_t& edge_matrix, - edge_enum_t& edge_enum) { + const edge_enum_t& edge_enum) { auto a_ik = get_a(i, k, edge_matrix, edge_enum); return ((a_ik * get_b(k, edge_matrix, edge_enum) + get_b(i, edge_matrix, edge_enum) * a_ik) * (qubit_op_t("") - get_b(j, edge_matrix, edge_enum)) * tensor::ops::init_with_value(-0.25)); } qubit_op_t transformed_double_excitation_operator(int i, int j, int k, int l, const edge_matrix_t& edge_matrix, - edge_enum_t& edge_enum) { + const edge_enum_t& edge_enum) { auto b_i = get_b(i, edge_matrix, edge_enum); auto b_j = get_b(j, edge_matrix, edge_enum); auto b_k = get_b(k, edge_matrix, edge_enum); diff --git a/ccsrc/lib/math/operators/transform/jordan_wigner.cpp b/ccsrc/lib/math/operators/transform/jordan_wigner.cpp index d7a2a7e3d..081f2bb85 100644 --- a/ccsrc/lib/math/operators/transform/jordan_wigner.cpp +++ b/ccsrc/lib/math/operators/transform/jordan_wigner.cpp @@ -88,7 +88,7 @@ fermion_op_t reverse_jordan_wigner(const qubit_op_t& ops, int n_qubits) { if (n_qubits <= 0) { n_qubits = local_n_qubits; } - if (n_qubits < local_n_qubits) { + if (n_qubits < static_cast(local_n_qubits)) { throw std::runtime_error("Target qubits number is less than local qubits of operator."); } auto transf_op = fermion_op_t(); @@ -116,7 +116,7 @@ fermion_op_t reverse_jordan_wigner(const qubit_op_t& ops, int n_qubits) { } trans_pauli += raising_term; trans_pauli += lowering_term; - for (auto j = 0; j < idx; j++) { + for (auto j = 0; j < static_cast(idx); j++) { working_term = qubit_op_t({idx - 1 - j, qubit::TermValue::Z}) * working_term; } auto s_coeff = working_term.singlet_coeff(); diff --git a/ccsrc/lib/math/operators/transform/parity.cpp b/ccsrc/lib/math/operators/transform/parity.cpp index 2d1556b17..1caf4a01e 100644 --- a/ccsrc/lib/math/operators/transform/parity.cpp +++ b/ccsrc/lib/math/operators/transform/parity.cpp @@ -17,7 +17,7 @@ namespace operators::transform { qubit_op_t parity(const fermion_op_t& ops, int n_qubits) { - auto local_n_qubits = ops.count_qubits(); + int local_n_qubits = ops.count_qubits(); if (n_qubits <= 0) { n_qubits = local_n_qubits; } @@ -29,10 +29,10 @@ qubit_op_t parity(const fermion_op_t& ops, int n_qubits) { auto transformed_term = qubit_op_t("", coeff); for (const auto& [idx, value] : term) { qlist_t x1 = {}, z1 = {}, x2 = {}; - for (auto i = idx; i < n_qubits; i++) { + for (auto i = idx; i < static_cast(n_qubits); i++) { x1.push_back((i)); } - for (auto i = idx + 1; i < n_qubits; i++) { + for (auto i = idx + 1; i < static_cast(n_qubits); i++) { x2.push_back((i)); } if (idx > 0) { diff --git a/ccsrc/lib/math/operators/transform/ternary_tree.cpp b/ccsrc/lib/math/operators/transform/ternary_tree.cpp index 45200705a..55c7c1b8b 100644 --- a/ccsrc/lib/math/operators/transform/ternary_tree.cpp +++ b/ccsrc/lib/math/operators/transform/ternary_tree.cpp @@ -11,6 +11,8 @@ // 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 + #include "math/operators/transform.hpp" namespace operators::transform { qubit_op_t ternary_tree(const fermion_op_t& ops, int n_qubits) { @@ -21,7 +23,7 @@ qubit_op_t ternary_tree(const fermion_op_t& ops, int n_qubits) { auto transformed_term = qubit_op_t("", coeff); for (const auto& [idx, value] : term) { qlist_t p1 = {}; - if (2 * idx < 3 * d) { + if (2 * idx < static_cast(3 * d)) { for (int k = h; k > -1; k--) { p1.push_back((2 * idx / static_cast(std::round(std::pow(3, k))) % 3)); } @@ -33,7 +35,7 @@ qubit_op_t ternary_tree(const fermion_op_t& ops, int n_qubits) { qlist_t x1 = {}; qlist_t y1 = {}; qlist_t z1 = {}; - for (int k = 0; k < p1.size(); k++) { + for (int k = 0; k < static_cast(p1.size()); k++) { auto tmp = p1[k]; if (tmp == 0) { x1.push_back((get_qubit_index(p1, k))); @@ -44,7 +46,7 @@ qubit_op_t ternary_tree(const fermion_op_t& ops, int n_qubits) { } } qlist_t p2 = {}; - if (2 * idx < 3 * d) { + if (2 * idx < static_cast(3 * d)) { for (int k = h; k > -1; k--) { p2.push_back(((2 * idx + 1) / static_cast(std::round(std::pow(3, k))) % 3)); } @@ -56,7 +58,7 @@ qubit_op_t ternary_tree(const fermion_op_t& ops, int n_qubits) { qlist_t x2 = {}; qlist_t y2 = {}; qlist_t z2 = {}; - for (int k = 0; k < p2.size(); k++) { + for (int k = 0; k < static_cast(p2.size()); k++) { auto tmp = p2[k]; if (tmp == 0) { x2.push_back((get_qubit_index(p2, k))); diff --git a/ccsrc/lib/math/pr/parameter_resolver.cpp b/ccsrc/lib/math/pr/parameter_resolver.cpp index fffa678c1..d84154c86 100644 --- a/ccsrc/lib/math/pr/parameter_resolver.cpp +++ b/ccsrc/lib/math/pr/parameter_resolver.cpp @@ -76,7 +76,7 @@ std::string ParameterResolver::ToString() const { out += " data: [],\n"; } else { out += " data: [\n"; - int i = 0; + std::size_t i = 0; for (auto& [k, v] : this->data_) { out += " " + k + ": " + tn::ops::to_string(v, true); i += 1; @@ -90,7 +90,7 @@ std::string ParameterResolver::ToString() const { out += " const: " + tn::ops::to_string(this->const_value, true); if (this->no_grad_parameters_.size() != 0) { out += ",\n no grad parameters: {"; - int i = 0; + std::size_t i = 0; for (auto& v : this->no_grad_parameters_) { out += v; i += 1; @@ -102,7 +102,7 @@ std::string ParameterResolver::ToString() const { } if (this->encoder_parameters_.size() != 0) { out += ",\n encoder parameters: {"; - int i = 0; + std::size_t i = 0; for (auto& v : this->encoder_parameters_) { out += v; i += 1; diff --git a/ccsrc/lib/math/tensor/ops_cpu/basic_math.cpp b/ccsrc/lib/math/tensor/ops_cpu/basic_math.cpp index 7a250abd8..aba3a6d60 100644 --- a/ccsrc/lib/math/tensor/ops_cpu/basic_math.cpp +++ b/ccsrc/lib/math/tensor/ops_cpu/basic_math.cpp @@ -53,19 +53,19 @@ Matrix MatMul(const Matrix& m1, const Matrix& m2) { switch (m2.dtype) { \ case TDtype::Float32: { \ return MatMul(m1.data_.data, m1.indptr_, m1.indices_, m1.n_row, m1.n_col, \ - m1.nnz, m2.data, m2.dim); \ + m2.data, m2.dim); \ } \ case TDtype::Float64: { \ return MatMul(m1.data_.data, m1.indptr_, m1.indices_, m1.n_row, m1.n_col, \ - m1.nnz, m2.data, m2.dim); \ + m2.data, m2.dim); \ } \ case TDtype::Complex64: { \ return MatMul(m1.data_.data, m1.indptr_, m1.indices_, m1.n_row, m1.n_col, \ - m1.nnz, m2.data, m2.dim); \ + m2.data, m2.dim); \ } \ case TDtype::Complex128: { \ return MatMul(m1.data_.data, m1.indptr_, m1.indices_, m1.n_row, \ - m1.n_col, m1.nnz, m2.data, m2.dim); \ + m1.n_col, m2.data, m2.dim); \ } \ } \ break; \ diff --git a/ccsrc/lib/math/tensor/ops_cpu/memory_operator.cpp b/ccsrc/lib/math/tensor/ops_cpu/memory_operator.cpp index 565adfedd..82b4cd09c 100644 --- a/ccsrc/lib/math/tensor/ops_cpu/memory_operator.cpp +++ b/ccsrc/lib/math/tensor/ops_cpu/memory_operator.cpp @@ -51,6 +51,7 @@ Tensor init(size_t len, TDtype dtype) { case (TDtype::Complex128): \ return cast_to(data, len); \ } \ + break; \ } Tensor cast_to(const Tensor& t, TDtype des) { auto& data = t.data; diff --git a/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_policy.cpp b/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_policy.cpp index 42ad74b9a..4ae39320d 100644 --- a/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_policy.cpp +++ b/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_policy.cpp @@ -39,7 +39,7 @@ auto CPUDensityMatrixPolicyBase::InitState(index_t dim, bo } template -void CPUDensityMatrixPolicyBase::Reset(qs_data_p_t* qs_p, index_t dim, bool zero_state) { +void CPUDensityMatrixPolicyBase::Reset(qs_data_p_t* qs_p) { derived::FreeState(qs_p); } @@ -222,7 +222,7 @@ auto CPUDensityMatrixPolicyBase::PureStateVector(const qs_ return qs_vector; } py_qs_datas_t qs_vector(dim); - index_t base; + index_t base = 0; calc_type base_value; for (index_t i = 0; i < dim; i++) { if (qs[IdxMap(i, i)].real() > 1e-8) { @@ -269,7 +269,7 @@ void CPUDensityMatrixPolicyBase::ApplyTerms(qs_data_p_t* q } }) } - Reset(qs_p, dim, false); + Reset(qs_p); for (const auto& [pauli_string, coeff_] : ham) { auto mask = GenPauliMask(pauli_string); auto mask_f = mask.mask_x | mask.mask_y; diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_policy.cpp b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_policy.cpp index a244a0317..0081036a3 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_policy.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_policy.cpp @@ -44,7 +44,7 @@ auto CPUVectorPolicyBase::InitState(index_t dim, bool zero } template -void CPUVectorPolicyBase::Reset(qs_data_p_t* qs_p, index_t dim) { +void CPUVectorPolicyBase::Reset(qs_data_p_t* qs_p) { derived::FreeState(qs_p); } diff --git a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_policy.cu b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_policy.cu index f01337877..931454384 100644 --- a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_policy.cu +++ b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_policy.cu @@ -54,7 +54,7 @@ void GPUVectorPolicyBase::FreeState(qs_data_p_t* qs_p) { } template -void GPUVectorPolicyBase::Reset(qs_data_p_t* qs_p, index_t dim) { +void GPUVectorPolicyBase::Reset(qs_data_p_t* qs_p) { derived::FreeState(qs_p); } diff --git a/ccsrc/python/core/include/python/core/sparse/csrhdmatrix.hpp b/ccsrc/python/core/include/python/core/sparse/csrhdmatrix.hpp index 37ec1eb13..fdb676d72 100644 --- a/ccsrc/python/core/include/python/core/sparse/csrhdmatrix.hpp +++ b/ccsrc/python/core/include/python/core/sparse/csrhdmatrix.hpp @@ -41,11 +41,11 @@ struct CsrHdMatrix : sparse::CsrHdMatrix { Index *indptr_py = static_cast(indptr.request().ptr); Index *indices_py = static_cast(indices.request().ptr); CTP data_py = static_cast *>(data.request().ptr); - for (size_t i = 0; i < data.size(); i++) { + for (size_t i = 0; i < static_cast(data.size()); i++) { indices_[i] = indices_py[i]; data_[i] = data_py[i]; } - for (size_t i = 0; i < indptr.size(); i++) { + for (size_t i = 0; i < static_cast(indptr.size()); i++) { indptr_[i] = indptr_py[i]; } } From 23a56c9ef3fd616ad694f5f733b521af1d454aa6 Mon Sep 17 00:00:00 2001 From: donghufeng Date: Tue, 18 Jul 2023 23:39:05 +0800 Subject: [PATCH 004/100] fix countone input --- .cppcheck.suppressions | 1 - ccsrc/include/core/sparse/paulimat.hpp | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.cppcheck.suppressions b/.cppcheck.suppressions index 2783ab57f..cfee1fe53 100644 --- a/.cppcheck.suppressions +++ b/.cppcheck.suppressions @@ -58,7 +58,6 @@ syntaxError:ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatri unknownMacro:ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_rot_pauli.cpp unknownMacro:ccsrc/include/core/sparse/paulimat.hpp -unknownMacro:ccsrc/include/core/sparse/paulimat.hpp:58 unknownMacro:ccsrc/include/math/tensor/ops_cpu/basic_math.hpp unknownMacro:ccsrc/lib/simulator/vector/detail/cpu_vector_policy_single_ops.cpp unknownMacro:ccsrc/lib/simulator/vector/detail/cpu_vector_policy_xlike.cpp diff --git a/ccsrc/include/core/sparse/paulimat.hpp b/ccsrc/include/core/sparse/paulimat.hpp index ee1fdb22e..54f3e4e3c 100644 --- a/ccsrc/include/core/sparse/paulimat.hpp +++ b/ccsrc/include/core/sparse/paulimat.hpp @@ -56,8 +56,8 @@ struct PauliMat { dim_, 1UL << nQubitTh, for (Index i = 0; i < dim_; i++) { auto j = (i ^ mask_f); col_[i] = j; - auto axis2power = CountOne(i & mask.mask_z); // -1 - auto axis3power = CountOne(i & mask.mask_y); // -1j + auto axis2power = CountOne(static_cast(i & mask.mask_z)); // -1 + auto axis3power = CountOne(static_cast(i & mask.mask_y)); // -1j // (-1)^a2*(-1j)^a3*(1j)^a1=(1j)^2a2*(1j)^3a3*(1j)^a1=(1j)^(a1+2*a2+3*a3) coeff_[j] = static_cast((mask.num_y + 2 * axis3power + 2 * axis2power) & 3); }) From d4a9525c60d63c75aadd580b917a059eca2c8916 Mon Sep 17 00:00:00 2001 From: donghufeng Date: Wed, 19 Jul 2023 17:00:33 +0800 Subject: [PATCH 005/100] fix reverse adder bug --- mindquantum/core/circuit/channel_adder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mindquantum/core/circuit/channel_adder.py b/mindquantum/core/circuit/channel_adder.py index 0b92d6710..f381c6022 100644 --- a/mindquantum/core/circuit/channel_adder.py +++ b/mindquantum/core/circuit/channel_adder.py @@ -84,8 +84,8 @@ class ReverseAdder(ChannelAdderBase): def __init__(self, adder: ChannelAdderBase): """Initialize a channel adder.""" - super().__init__(adder.add_after) self.adder = adder + super().__init__(adder.add_after) def _accepter(self, *args, **kwargs) -> typing.List[typing.Union[FunctionType, MethodType]]: """Construct accepter rules.""" From 17f2dce498a169c2927acb30d53213b2f42b3a73 Mon Sep 17 00:00:00 2001 From: donghufeng Date: Wed, 19 Jul 2023 17:10:28 +0800 Subject: [PATCH 006/100] show expression of channel parameter --- mindquantum/core/gates/channel.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/mindquantum/core/gates/channel.py b/mindquantum/core/gates/channel.py index f667136ad..7ce09077c 100644 --- a/mindquantum/core/gates/channel.py +++ b/mindquantum/core/gates/channel.py @@ -22,6 +22,7 @@ from mindquantum import mqbackend as mb from mindquantum.utils.f import _check_num_array +from mindquantum.utils.string_utils import string_expression from .basic import BasicGate, NoiseGate, NonHermitianGate, SelfHermitianGate @@ -98,7 +99,7 @@ def __extra_prop__(self): def __type_specific_str__(self): """Return a string representation of the object.""" - return f'px={self.px}, py={self.py}, pz={self.pz}' + return f'px={string_expression(self.px)}, py={string_expression(self.py)}, pz={string_expression(self.pz)}' def get_cpp_obj(self): """Get underlying C++ object.""" @@ -164,7 +165,7 @@ def __extra_prop__(self): def __type_specific_str__(self): """Return a string representation of the object.""" - return f'p={self.p}' + return f'p={string_expression(self.p)}' class PhaseFlipChannel(PauliChannel): @@ -215,7 +216,7 @@ def __extra_prop__(self): def __type_specific_str__(self): """Return a string representation of the object.""" - return f'p={self.p}' + return f'p={string_expression(self.p)}' class BitPhaseFlipChannel(PauliChannel): @@ -267,7 +268,7 @@ def __extra_prop__(self): def __type_specific_str__(self): """Return a string representation of the object.""" - return f'p={self.p}' + return f'p={string_expression(self.p)}' class DepolarizingChannel(NoiseGate, SelfHermitianGate): @@ -357,7 +358,7 @@ def __extra_prop__(self): def __type_specific_str__(self): """Return a string representation of the object.""" - return f'p={self.p}' + return f'p={string_expression(self.p)}' class AmplitudeDampingChannel(NoiseGate, NonHermitianGate): @@ -412,7 +413,7 @@ def __eq__(self, other): def __type_specific_str__(self): """Return a string representation of the object.""" - return f'γ={self.gamma}' + return f'γ={string_expression(self.gamma)}' def get_cpp_obj(self): """Get underlying C++ object.""" @@ -477,7 +478,7 @@ def __eq__(self, other): def __type_specific_str__(self): """Return a string representation of the object.""" - return f'γ={self.gamma}' + return f'γ={string_expression(self.gamma)}' def get_cpp_obj(self): """Get underlying C++ object.""" From 1c0f2451abbbcbaf9f982ad9e2d3cc28e9ed4b96 Mon Sep 17 00:00:00 2001 From: donghufeng Date: Wed, 19 Jul 2023 21:22:05 +0800 Subject: [PATCH 007/100] fix const --- ccsrc/include/math/operators/transform.hpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/ccsrc/include/math/operators/transform.hpp b/ccsrc/include/math/operators/transform.hpp index c3837c56f..312301541 100644 --- a/ccsrc/include/math/operators/transform.hpp +++ b/ccsrc/include/math/operators/transform.hpp @@ -62,21 +62,22 @@ edge_matrix_t get_edge_matrix(const fermion_op_t& ops); edge_enum_t enumerate_edges(const edge_matrix_t& edge_matrix); -qubit_op_t get_b(int i, const edge_matrix_t& edge_matrix, edge_enum_t& edge_enum); +qubit_op_t get_b(int i, const edge_matrix_t& edge_matrix, const edge_enum_t& edge_enum); -qubit_op_t get_a(int i, int j, const edge_matrix_t& edge_matrix, edge_enum_t& edge_enum); +qubit_op_t get_a(int i, int j, const edge_matrix_t& edge_matrix, const edge_enum_t& edge_enum); -qubit_op_t transformed_number_operator(int i, const edge_matrix_t& edge_matrix, edge_enum_t& edge_enum); +qubit_op_t transformed_number_operator(int i, const edge_matrix_t& edge_matrix, const edge_enum_t& edge_enum); -qubit_op_t transformed_excitation_operator(int i, int j, const edge_matrix_t& edge_matrix, edge_enum_t& edge_enum); +qubit_op_t transformed_excitation_operator(int i, int j, const edge_matrix_t& edge_matrix, + const edge_enum_t& edge_enum); -qubit_op_t transformed_exchange_operator(int i, int j, const edge_matrix_t& edge_matrix, edge_enum_t& edge_enum); +qubit_op_t transformed_exchange_operator(int i, int j, const edge_matrix_t& edge_matrix, const edge_enum_t& edge_enum); qubit_op_t transformed_number_excitation_operator(int i, int j, int k, const edge_matrix_t& edge_matrix, - edge_enum_t& edge_enum); + const edge_enum_t& edge_enum); qubit_op_t transformed_double_excitation_operator(int i, int j, int k, int l, const edge_matrix_t& edge_matrix, - edge_enum_t& edge_enum); + const edge_enum_t& edge_enum); qubit_op_t bravyi_kitaev_superfast(const fermion_op_t& ops); } // namespace operators::transform From a3846f447dd478796f3c4b04ee2acdb007f11695 Mon Sep 17 00:00:00 2001 From: donghufeng Date: Thu, 20 Jul 2023 22:32:51 +0800 Subject: [PATCH 008/100] set vigo position --- mindquantum/device/chip.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mindquantum/device/chip.py b/mindquantum/device/chip.py index f2a589e71..e58ea17c1 100644 --- a/mindquantum/device/chip.py +++ b/mindquantum/device/chip.py @@ -35,6 +35,11 @@ def __init__(self): topology = QubitsTopology([QubitNode(i) for i in range(5)]) _ = topology[0] >> topology[1] >> topology[3] >> topology[4] _ = topology[1] >> topology[2] + topology[0].set_poi(0, 0) + topology[1].set_poi(1, 0) + topology[2].set_poi(2, 0) + topology[3].set_poi(1, 1) + topology[4].set_poi(1, 2) super().__init__(topology) self.noise_model = vigo_noise_model From 8b7dd7fc3fd5db607c39859732343812b2dd28cc Mon Sep 17 00:00:00 2001 From: donghufeng Date: Thu, 20 Jul 2023 23:31:00 +0800 Subject: [PATCH 009/100] add noise channel --- .../mindquantum.core.circuit.BitFlipAdder.rst | 2 +- ...quantum.core.circuit.NoiseChannelAdder.rst | 11 ++++++ docs/api_python/mindquantum.core.circuit.rst | 1 + .../mindquantum.core.gates.NoiseGate.rst | 20 ++++++++++ docs/api_python/mindquantum.core.gates.rst | 1 + .../mindquantum.core.circuit.rst | 1 + docs/api_python_en/mindquantum.core.gates.rst | 1 + mindquantum/core/circuit/__init__.py | 1 + mindquantum/core/circuit/channel_adder.py | 38 ++++++++++++++++++- mindquantum/core/gates/__init__.py | 1 + mindquantum/core/gates/basic.py | 10 ++++- 11 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 docs/api_python/mindquantum.core.circuit.NoiseChannelAdder.rst create mode 100644 docs/api_python/mindquantum.core.gates.NoiseGate.rst diff --git a/docs/api_python/mindquantum.core.circuit.BitFlipAdder.rst b/docs/api_python/mindquantum.core.circuit.BitFlipAdder.rst index ab1345708..1a3c482c3 100644 --- a/docs/api_python/mindquantum.core.circuit.BitFlipAdder.rst +++ b/docs/api_python/mindquantum.core.circuit.BitFlipAdder.rst @@ -1,5 +1,5 @@ mindquantum.core.circuit.BitFlipAdder -======================================== +===================================== .. py:class:: mindquantum.core.circuit.BitFlipAdder(flip_rate: float, with_ctrl=True, add_after: bool = True) diff --git a/docs/api_python/mindquantum.core.circuit.NoiseChannelAdder.rst b/docs/api_python/mindquantum.core.circuit.NoiseChannelAdder.rst new file mode 100644 index 000000000..ed45ab881 --- /dev/null +++ b/docs/api_python/mindquantum.core.circuit.NoiseChannelAdder.rst @@ -0,0 +1,11 @@ +mindquantum.core.circuit.NoiseChannelAdder +========================================== + +.. py:class:: mindquantum.core.circuit.NoiseChannelAdder(channel: NoiseGate, with_ctrl=True, add_after: bool = True) + + 添加一个单比特量子信道。 + + 参数: + - **channel** (:class:`~.core.gates.NoiseGate`) - 一个单比特量子信道。 + - **with_ctrl** (bool) - 是否在控制为上添加比特。默认值: ``True``。 + - **add_after** (bool) - 是否在量子门后面添加信道。如果为 ``False``,信道将会加在量子门前面。默认值: ``True``。 diff --git a/docs/api_python/mindquantum.core.circuit.rst b/docs/api_python/mindquantum.core.circuit.rst index e9799e833..9ca4fa3fd 100644 --- a/docs/api_python/mindquantum.core.circuit.rst +++ b/docs/api_python/mindquantum.core.circuit.rst @@ -50,6 +50,7 @@ Channel adder :template: classtemplate.rst mindquantum.core.circuit.ChannelAdderBase + mindquantum.core.circuit.NoiseChannelAdder mindquantum.core.circuit.MeasureAccepter mindquantum.core.circuit.ReverseAdder mindquantum.core.circuit.NoiseExcluder diff --git a/docs/api_python/mindquantum.core.gates.NoiseGate.rst b/docs/api_python/mindquantum.core.gates.NoiseGate.rst new file mode 100644 index 000000000..17874e8aa --- /dev/null +++ b/docs/api_python/mindquantum.core.gates.NoiseGate.rst @@ -0,0 +1,20 @@ +mindquantum.core.gates.NoiseGate +================================ + +.. py:class:: mindquantum.core.gates.NoiseGate(name, n_qubits, obj_qubits=None, ctrl_qubits=None) + + 噪声信道。 + + 参数: + - **name** (str) - 此门的名称。 + - **n_qubits** (int) - 这个门有多少个量子比特。 + - **obj_qubits** (int, list[int]) - 具体门作用在哪个量子比特上。 + - **ctrl_qubits** (int, list[int]) - 指定控制量子比特。默认值: `None`。 + + .. py:method:: on(obj_qubits, ctrl_qubits=None) + + 定义门作用于哪个量子比特和控制量子比特。 + + 参数: + - **obj_qubits** (int, list[int]) - 指定门作用在哪个量子比特上。 + - **ctrl_qubits** (int, list[int]) - 噪声信道的控制量子比特应该总是 ``None``。 diff --git a/docs/api_python/mindquantum.core.gates.rst b/docs/api_python/mindquantum.core.gates.rst index 8a8c27fa1..71bb8b4ea 100644 --- a/docs/api_python/mindquantum.core.gates.rst +++ b/docs/api_python/mindquantum.core.gates.rst @@ -18,6 +18,7 @@ mindquantum.core.gates mindquantum.core.gates.NoneParameterGate mindquantum.core.gates.ParameterGate mindquantum.core.gates.QuantumGate + mindquantum.core.gates.NoiseGate 通用量子门 ------------- diff --git a/docs/api_python_en/mindquantum.core.circuit.rst b/docs/api_python_en/mindquantum.core.circuit.rst index 7206779ad..92718b4d7 100644 --- a/docs/api_python_en/mindquantum.core.circuit.rst +++ b/docs/api_python_en/mindquantum.core.circuit.rst @@ -47,6 +47,7 @@ Channel adder :template: classtemplate.rst mindquantum.core.circuit.ChannelAdderBase + mindquantum.core.circuit.NoiseChannelAdder mindquantum.core.circuit.MeasureAccepter mindquantum.core.circuit.ReverseAdder mindquantum.core.circuit.NoiseExcluder diff --git a/docs/api_python_en/mindquantum.core.gates.rst b/docs/api_python_en/mindquantum.core.gates.rst index d94661291..a58d7f202 100644 --- a/docs/api_python_en/mindquantum.core.gates.rst +++ b/docs/api_python_en/mindquantum.core.gates.rst @@ -15,6 +15,7 @@ Base Class mindquantum.core.gates.NoneParameterGate mindquantum.core.gates.ParameterGate mindquantum.core.gates.QuantumGate + mindquantum.core.gates.NoiseGate Quantum Gate ------------- diff --git a/mindquantum/core/circuit/__init__.py b/mindquantum/core/circuit/__init__.py index b492b99dd..e23eb0369 100644 --- a/mindquantum/core/circuit/__init__.py +++ b/mindquantum/core/circuit/__init__.py @@ -24,6 +24,7 @@ ChannelAdderBase, MeasureAccepter, MixerAdder, + NoiseChannelAdder, NoiseExcluder, ReverseAdder, SequentialAdder, diff --git a/mindquantum/core/circuit/channel_adder.py b/mindquantum/core/circuit/channel_adder.py index f381c6022..cc32f1468 100644 --- a/mindquantum/core/circuit/channel_adder.py +++ b/mindquantum/core/circuit/channel_adder.py @@ -16,8 +16,10 @@ import typing from types import FunctionType, MethodType +from mindquantum.utils.type_value_check import _check_input_type + from .. import gates -from ..gates import BasicGate +from ..gates import BasicGate, NoiseGate from .circuit import Circuit @@ -136,7 +138,6 @@ class BitFlipAdder(ChannelAdderBase): def __init__(self, flip_rate: float, with_ctrl=True, add_after: bool = True): """Initialize a BitFlipAdder.""" super().__init__(add_after=add_after) - self.with_ctrl = True self.flip_rate = flip_rate self.with_ctrl = with_ctrl @@ -152,6 +153,38 @@ def _handler(self, g: BasicGate, *args, **kwargs): return circ +class NoiseChannelAdder(ChannelAdderBase): + """ + Add single qubit quantum channel. + + Args: + channel (:class:`~.core.gates.NoiseGate`): A single qubit quantum channel. + with_ctrl (bool): Whether add quantum channel for control qubits. Default: ``True``. + add_after (bool): Whether add this channel after quantum gate or not. If ``False``, the + channel will add before quantum gate. Default: ``True``. + """ + + def __init__(self, channel: NoiseGate, with_ctrl=True, add_after: bool = True): + """Initialize a BitFlipAdder.""" + _check_input_type("channel", NoiseGate, channel) + if channel.n_qubits != 1: + raise ValueError(f"Requires a single qubit channel, but get {channel.n_qubits}, please customize a adder.") + super().__init__(add_after=add_after) + self.with_ctrl = with_ctrl + self.channel = channel + + def __repr__(self): + """Return string expression of adder.""" + return f"NoiseChannelAdder" + + def _handler(self, g: BasicGate, *args, **kwargs): + """Create action you will do if a gate is acceptable.""" + circ = Circuit() + for qubit in g.obj_qubits + (g.ctrl_qubits if self.with_ctrl else []): + circ += self.channel.on(qubit) + return circ + + class MixerAdder(ChannelAdderBase): """ Execute each adder if all accepter and excluder are met. @@ -223,6 +256,7 @@ def __repr__(self): __all__ = [ "ChannelAdderBase", + "NoiseChannelAdder", "MeasureAccepter", "ReverseAdder", "NoiseExcluder", diff --git a/mindquantum/core/gates/__init__.py b/mindquantum/core/gates/__init__.py index 65e3794b7..65cd745dd 100644 --- a/mindquantum/core/gates/__init__.py +++ b/mindquantum/core/gates/__init__.py @@ -80,6 +80,7 @@ __all__ = [ "BasicGate", "QuantumGate", + "NoiseGate", "NoneParameterGate", "ParameterGate", "HERMITIAN_PROPERTIES", diff --git a/mindquantum/core/gates/basic.py b/mindquantum/core/gates/basic.py index 14b886c5a..182df7c8c 100644 --- a/mindquantum/core/gates/basic.py +++ b/mindquantum/core/gates/basic.py @@ -729,7 +729,15 @@ def diff_matrix(self, pr=None, about_what=None): class NoiseGate(NoneParameterGate): - """Noise gate class.""" + """ + Noise gate class. + + Args: + name (str): the name of this gate. + n_qubits (int): how many qubits is this gate. + obj_qubits (int, list[int]): Specific which qubits the gate act on. + ctrl_qubits (int, list[int]): Specific the control qubits. Default, ``None``. + """ def __str_in_terminal__(self): """Return a string representation of the object.""" From 71780e194ed3bc556764ca56ba1a588870229071 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Fri, 21 Jul 2023 14:29:36 +0800 Subject: [PATCH 010/100] channel adder: test & docing & type check --- mindquantum/core/circuit/channel_adder.py | 154 ++++++++++++++++-- pyproject.toml | 5 +- .../test_circuit/test_channel_adder.py | 135 +++++++++++++++ 3 files changed, 275 insertions(+), 19 deletions(-) create mode 100644 tests/st/test_core/test_circuit/test_channel_adder.py diff --git a/mindquantum/core/circuit/channel_adder.py b/mindquantum/core/circuit/channel_adder.py index cc32f1468..52c11d8ec 100644 --- a/mindquantum/core/circuit/channel_adder.py +++ b/mindquantum/core/circuit/channel_adder.py @@ -40,6 +40,7 @@ class ChannelAdderBase: def __init__(self, add_after=True): """Initialize a ChannelAdderBase.""" + _check_input_type("add_after", bool, add_after) self.add_after = add_after self.accepter = [] # a list of function, which act as rules to accept considering gate to add noise channel. self.excluder = [] # a list of function, which act as rules to deny considering gate to add noise channel. @@ -59,7 +60,7 @@ def __call__(self, circ: Circuit) -> Circuit: out += g return out - def __repr__(self): + def __repr__(self) -> str: """Return string expression of adder.""" return f"{self.__class__.__name__}<>" @@ -67,11 +68,11 @@ def _accepter(self, *args, **kwargs) -> typing.List[typing.Union[FunctionType, M """Construct accepter rules.""" return [] - def _excluder(self, *args, **kwargs): + def _excluder(self, *args, **kwargs) -> typing.List[typing.Union[FunctionType, MethodType]]: """Construct excluder rules.""" return [] - def _handler(self, g: BasicGate, *args, **kwargs): + def _handler(self, g: BasicGate, *args, **kwargs) -> Circuit: """Create action you will do if a gate is acceptable.""" return Circuit() @@ -82,10 +83,22 @@ class ReverseAdder(ChannelAdderBase): Args: adder (:class:`~.core.circuit.ChannelAdderBase`): A channel adder. + + Examples: + >>> from mindquantum.core.circuit import ReverseAdder, MeasureAccepter, BitFlipAdder, MixerAdder + >>> from mindquantum.core.circuit import Circuit + >>> circ = Circuit().rx('a', 0).measure_all() + >>> only_measure = MixerAdder([BitFlipAdder(0.1), MeasureAccepter()]) + >>> only_measure(circ) + q0: ──RX(a)────M(q0)────BFC(p=1/10)── + >>> no_measure = ReverseAdder(only_measure) + >>> no_measure(circ) + q0: ──RX(a)────BFC(p=1/10)────M(q0)── """ def __init__(self, adder: ChannelAdderBase): """Initialize a channel adder.""" + _check_input_type("adder", ChannelAdderBase, adder) self.adder = adder super().__init__(adder.add_after) @@ -93,13 +106,40 @@ def _accepter(self, *args, **kwargs) -> typing.List[typing.Union[FunctionType, M """Construct accepter rules.""" return self.adder._excluder() - def _excluder(self, *args, **kwargs): + def _excluder(self, *args, **kwargs) -> typing.List[typing.Union[FunctionType, MethodType]]: """Construct excluder rules.""" return self.adder._accepter() + def __repr__(self) -> str: + """Return string expression of adder.""" + strs = ["ReverseAdder<"] + for i in self.adder.__repr__().split('\n'): + strs.append(" " + i) + strs.append(">") + return '\n'.join(strs) + + def _handler(self, g: BasicGate, *args, **kwargs) -> Circuit: + """Create action you will do if a gate is acceptable.""" + out = Circuit() + out += self.adder._handler(g) + return out + class MeasureAccepter(ChannelAdderBase): - """Select measurement gate.""" + """ + Select measurement gate. + + Args: + add_after (bool): Whether add channel after gate or before gate. Default: ``True``. + + Examples: + >>> from mindquantum.core.circuit import MeasureAccepter, BitFlipAdder, MixerAdder + >>> from mindquantum.core.circuit import Circuit + >>> circ = Circuit().rx('a', 0).h(0).measure_all() + >>> only_measure = MixerAdder([BitFlipAdder(0.1), MeasureAccepter()], add_after=False) + >>> only_measure(circ) + q0: ──RX(a)────H────BFC(p=1/10)────M(q0)── + """ def __init__(self): """Initialize a MeasureAccepter.""" @@ -116,9 +156,22 @@ class NoiseExcluder(ChannelAdderBase): Args: add_after (bool): Whether add channel after gate or before gate. Default: ``True``. + + Examples: + >>> from mindquantum.core.circuit import Circuit, NoiseExcluder, BitFlipAdder, MixerAdder + >>> from mindquantum.core.gates import DepolarizingChannel + >>> circ = Circuit().x(0) + >>> circ += DepolarizingChannel(0.1).on(0) + >>> circ + q0: ──X────DC(p=1/10)── + >>> BitFlipAdder(0.1)(circ) + q0: ──X────BFC(p=1/10)────DC(p=1/10)────BFC(p=1/10)── + >>> adder = MixerAdder([NoiseExcluder(), BitFlipAdder(0.1)]) + >>> adder(circ) + q0: ──X────BFC(p=1/10)────DC(p=1/10)── """ - def _excluder(self, *args, **kwargs): + def _excluder(self, *args, **kwargs) -> typing.List[typing.Union[FunctionType, MethodType]]: """Construct excluder rules.""" return [lambda x: isinstance(x, gates.NoiseGate)] @@ -133,19 +186,30 @@ class BitFlipAdder(ChannelAdderBase): with_ctrl (bool): Whether add bit flip channel for control qubits. Default: ``True``. add_after (bool): Whether add this channel after quantum gate or not. If ``False``, the channel will add before quantum gate. Default: ``True``. + + Examples: + >>> from mindquantum.core.circuit import BitFlipAdder + >>> from mindquantum.core.circuit import Circuit + >>> circ = Circuit().h(0).x(1, 0) + >>> adder = BitFlipAdder(0.1, with_ctrl=False) + >>> adder(circ) + q0: ──H────BFC(p=1/10)────●───────────────── + │ + q1: ──────────────────────X────BFC(p=1/10)── """ def __init__(self, flip_rate: float, with_ctrl=True, add_after: bool = True): """Initialize a BitFlipAdder.""" + _check_input_type("with_ctrl", bool, with_ctrl) super().__init__(add_after=add_after) self.flip_rate = flip_rate self.with_ctrl = with_ctrl - def __repr__(self): + def __repr__(self) -> str: """Return string expression of adder.""" return f"BitFlipAdder" - def _handler(self, g: BasicGate, *args, **kwargs): + def _handler(self, g: BasicGate, *args, **kwargs) -> Circuit: """Create action you will do if a gate is acceptable.""" circ = Circuit() for qubit in g.obj_qubits + (g.ctrl_qubits if self.with_ctrl else []): @@ -162,22 +226,34 @@ class NoiseChannelAdder(ChannelAdderBase): with_ctrl (bool): Whether add quantum channel for control qubits. Default: ``True``. add_after (bool): Whether add this channel after quantum gate or not. If ``False``, the channel will add before quantum gate. Default: ``True``. + + Examples: + >>> from mindquantum.core.circuit import NoiseChannelAdder, Circuit + >>> from mindquantum.core.gates import AmplitudeDampingChannel + >>> circ = Circuit().h(0).x(1, 0) + >>> channel = AmplitudeDampingChannel(0.3) + >>> adder = NoiseChannelAdder(channel, with_ctrl=True, add_after=True) + >>> adder(circ) + q0: ──H────ADC(γ=3/10)────●────ADC(γ=3/10)── + │ + q1: ──────────────────────X────ADC(γ=3/10)── """ def __init__(self, channel: NoiseGate, with_ctrl=True, add_after: bool = True): """Initialize a BitFlipAdder.""" _check_input_type("channel", NoiseGate, channel) + _check_input_type("with_ctrl", bool, with_ctrl) if channel.n_qubits != 1: raise ValueError(f"Requires a single qubit channel, but get {channel.n_qubits}, please customize a adder.") super().__init__(add_after=add_after) self.with_ctrl = with_ctrl self.channel = channel - def __repr__(self): + def __repr__(self) -> str: """Return string expression of adder.""" return f"NoiseChannelAdder" - def _handler(self, g: BasicGate, *args, **kwargs): + def _handler(self, g: BasicGate, *args, **kwargs) -> Circuit: """Create action you will do if a gate is acceptable.""" circ = Circuit() for qubit in g.obj_qubits + (g.ctrl_qubits if self.with_ctrl else []): @@ -192,15 +268,27 @@ class MixerAdder(ChannelAdderBase): Args: adders (List[:class:`~.core.gates.BitFlipChannel`]): The adders you want to mix. add_after (bool): Whether add channel after quantum gate or not. If ``False``, the - channel will add before quantum gate. Default: ``True``. + channel will add before quantum gate. This `add_after` will override all`add_after` + of sub adder. Default: ``True``. + + Examples: + >>> from mindquantum.core.circuit import MeasureAccepter, BitFlipAdder, MixerAdder + >>> from mindquantum.core.circuit import Circuit + >>> circ = Circuit().rx('a', 0).h(0).measure_all() + >>> only_measure = MixerAdder([BitFlipAdder(0.1), MeasureAccepter()], add_after=False) + >>> only_measure(circ) + q0: ──RX(a)────H────BFC(p=1/10)────M(q0)── """ def __init__(self, adders: typing.List[ChannelAdderBase], add_after=True): """Initialize a MixerAdder.""" + _check_input_type("adders", list, adders) + for adder in adders: + _check_input_type("Element of adders", ChannelAdderBase, adder) self.adders = adders super().__init__(add_after=add_after) - def __repr__(self): + def __repr__(self) -> str: """Return string expression of adder.""" strs = ["MixerAdder<"] for adder in self.adders: @@ -209,15 +297,15 @@ def __repr__(self): strs.append(">") return '\n'.join(strs) - def _accepter(self, *args, **kwargs): + def _accepter(self, *args, **kwargs) -> typing.List[typing.Union[FunctionType, MethodType]]: """Construct accepter rules.""" return [item for adder in self.adders for item in adder._accepter()] - def _excluder(self, *args, **kwargs): + def _excluder(self, *args, **kwargs) -> typing.List[typing.Union[FunctionType, MethodType]]: """Construct excluder rules.""" return [item for adder in self.adders for item in adder._excluder()] - def _handler(self, g: BasicGate, *args, **kwargs): + def _handler(self, g: BasicGate, *args, **kwargs) -> Circuit: """Create action you will do if a gate is acceptable.""" out = Circuit() for adder in self.adders: @@ -231,20 +319,52 @@ class SequentialAdder(ChannelAdderBase): Args: adders (List[:class:`~.core.circuit.ChannelAdderBase`]): The adder you want to apply. + + Examples: + >>> from mindquantum.core.circuit import SequentialAdder, MixerAdder, BitFlipAdder, NoiseChannelAdder + >>> from mindquantum.core.circuit import MeasureAccepter, ReverseAdder, NoiseChannelAdder, Circuit + >>> from mindquantum.core.circuit import NoiseExcluder + >>> from mindquantum.core.gates import DepolarizingChannel + >>> circ = Circuit().h(0).x(1, 0).measure_all() + >>> circ + q0: ──H────●────M(q0)── + │ + q1: ───────X────M(q1)── + >>> bitflip_error_for_measure = MixerAdder([ + ... BitFlipAdder(0.1), + ... MeasureAccepter(), + ... NoiseExcluder() + ... ], add_after=False) + >>> depolarizing_for_gate = MixerAdder([ + ... NoiseChannelAdder(DepolarizingChannel(0.1)), + ... ReverseAdder(MeasureAccepter()), + ... NoiseExcluder() + ... ]) + >>> adder = SequentialAdder([ + ... bitflip_error_for_measure, + ... depolarizing_for_gate, + ... ]) + >>> adder(circ) + q0: ──H────DC(p=1/10)────●────DC(p=1/10)────BFC(p=1/10)────M(q0)── + │ + q1: ─────────────────────X────DC(p=1/10)────BFC(p=1/10)────M(q1)── """ def __init__(self, adders: typing.List[ChannelAdderBase]): """Initialize a SequentialAdder.""" + _check_input_type("adders", list, adders) + for adder in adders: + _check_input_type("Element of adders", ChannelAdderBase, adder) super().__init__() self.adders = adders - def __call__(self, circ: Circuit): + def __call__(self, circ: Circuit) -> Circuit: """Add noise channel after acceptable quantum gate.""" for adder in self.adders: circ = adder(circ) return circ - def __repr__(self): + def __repr__(self) -> str: """Return string expression of adder.""" strs = ["SequentialAdder<"] for adder in self.adders: diff --git a/pyproject.toml b/pyproject.toml index 12c1380d8..0180920e1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -172,7 +172,6 @@ minversion = '6.0' testpaths = ['tests'] addopts = "--ignore='tests/quick_test.py'" norecursedirs = ['third_party', 'mindquantum/ccsrc'] -mock_use_standalone_module = true markers = [ 'cxx_exp_projectq: tests involving the ProjectQ simulator', 'env_onecard: test marker used on MindSpore CI for certain GPU runs', @@ -188,12 +187,14 @@ filterwarnings = [ 'ignore:.*MindSpore not installed.*:UserWarning', 'ignore:.*distutils Version classes are deprecated. Use packaging.version instead:DeprecationWarning', 'ignore:.*ParameterResolver.__float__ returned non-float.*:DeprecationWarning', + 'ignore:.*Override n_qubits and n_electrons with manually set*', 'ignore:.*the matrix subclass is not the recommended way to represent.*:PendingDeprecationWarning', # From external packages 'ignore:.*Call to deprecated create function Descriptor.*:DeprecationWarning', # from cirq_google 'ignore:.*Call to deprecated create function EnumDescriptor.*:DeprecationWarning', # from cirq_google 'ignore:.*Call to deprecated create function EnumValueDescriptor.*:DeprecationWarning', # from cirq_google - 'ignore:.*Call to deprecated create function FieldDescriptor.*:DeprecationWarning' # from cirq_google + 'ignore:.*Call to deprecated create function FieldDescriptor.*:DeprecationWarning', # from cirq_google + 'ignore:.*astroid.node_classes.*is deprecated*' ] diff --git a/tests/st/test_core/test_circuit/test_channel_adder.py b/tests/st/test_core/test_circuit/test_channel_adder.py new file mode 100644 index 000000000..29f059901 --- /dev/null +++ b/tests/st/test_core/test_circuit/test_channel_adder.py @@ -0,0 +1,135 @@ +# 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. +# ============================================================================ +"""Test channel adder.""" + +from mindquantum.core.circuit import ( + BitFlipAdder, + Circuit, + MeasureAccepter, + MixerAdder, + NoiseChannelAdder, + NoiseExcluder, + ReverseAdder, + SequentialAdder, +) +from mindquantum.core.gates import ( + AmplitudeDampingChannel, + BitFlipChannel, + DepolarizingChannel, + Measure, + X, +) + + +def test_reverse_adder(): + """ + Description: test reverse adder. + Expectation: success. + """ + circ = Circuit().rx('a', 0).measure_all() + only_measure = MixerAdder([BitFlipAdder(0.1), MeasureAccepter()]) + no_measure = ReverseAdder(only_measure) + new_circ = no_measure(circ) + exp_circ = (Circuit().rx('a', 0) + BitFlipChannel(0.1).on(0)).measure_all() + assert new_circ == exp_circ + + +def test_measure_accepter(): + """ + Description: test measure accepter. + Expectation: success. + """ + circ = Circuit().rx('a', 0).h(0).measure_all() + only_measure = MixerAdder([BitFlipAdder(0.1), MeasureAccepter()], add_after=False) + new_circ = only_measure(circ) + exp_circ = (Circuit().rx('a', 0).h(0) + BitFlipChannel(0.1).on(0)).measure_all() + assert new_circ == exp_circ + + +def test_noise_excluder(): + """ + Description: test noise excluder. + Expectation: success. + """ + circ = Circuit().x(0) + circ += DepolarizingChannel(0.1).on(0) + adder = MixerAdder([NoiseExcluder(), BitFlipAdder(0.1)]) + new_circ = adder(circ) + exp_circ = Circuit().x(0) + BitFlipChannel(0.1).on(0) + DepolarizingChannel(0.1).on(0) + assert new_circ == exp_circ + + +def test_bit_flip_adder(): + """ + Description: test bit flip adder. + Expectation: success. + """ + circ = Circuit().h(0).x(1, 0) + adder = BitFlipAdder(0.1, with_ctrl=False) + channel = BitFlipChannel(0.1) + new_circ = adder(circ) + exp_circ = Circuit().h(0) + channel.on(0) + X.on(1, 0) + channel.on(1) + assert new_circ == exp_circ + + +def test_noise_channel_adder(): + """ + Description: test noise channel adder. + Expectation: success. + """ + circ = Circuit().h(0).x(1, 0) + channel = AmplitudeDampingChannel(0.3) + adder = NoiseChannelAdder(channel, with_ctrl=True, add_after=True) + new_circ = adder(circ) + exp_circ = Circuit().h(0) + channel.on(0) + X.on(1, 0) + channel.on(1) + channel.on(0) + assert new_circ == exp_circ + + +def test_mixer_adder(): + """ + Description: test mixer adder. + Expectation: success. + """ + circ = Circuit().rx('a', 0).h(0).measure_all() + only_measure = MixerAdder([BitFlipAdder(0.1), MeasureAccepter()], add_after=False) + new_circ = only_measure(circ) + exp_circ = Circuit().rx('a', 0).h(0) + BitFlipChannel(0.1).on(0) + exp_circ.measure_all() + assert new_circ == exp_circ + + +def test_sequential_adder(): + """ + Description: test sequential adder. + Expectation: success. + """ + circ = Circuit().h(0).x(1, 0).measure_all() + bitflip_error_for_measure = MixerAdder([BitFlipAdder(0.1), MeasureAccepter(), NoiseExcluder()], add_after=False) + depolarizing_for_gate = MixerAdder( + [NoiseChannelAdder(DepolarizingChannel(0.1)), ReverseAdder(MeasureAccepter()), NoiseExcluder()] + ) + adder = SequentialAdder( + [ + bitflip_error_for_measure, + depolarizing_for_gate, + ] + ) + new_circ = adder(circ) + noise_1 = DepolarizingChannel(0.1) + bfc = BitFlipChannel(0.1) + exp_circ = Circuit().h(0) + noise_1.on(0) + X.on(1, 0) + noise_1.on(1) + exp_circ += Circuit([noise_1.on(0), bfc.on(0), Measure().on(0), bfc.on(1)]) + exp_circ += Measure().on(1) + assert exp_circ == new_circ From d74a3312f26fa09deed6ac1b24decf1c6a762eda Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Fri, 21 Jul 2023 14:59:29 +0800 Subject: [PATCH 011/100] test error mitigation --- .../test_error_mitigation/test_folding.py | 37 ++++++++++++ .../test_error_mitigation/test_zne.py | 58 +++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 tests/st/test_algorithm/test_error_mitigation/test_folding.py create mode 100644 tests/st/test_algorithm/test_error_mitigation/test_zne.py diff --git a/tests/st/test_algorithm/test_error_mitigation/test_folding.py b/tests/st/test_algorithm/test_error_mitigation/test_folding.py new file mode 100644 index 000000000..be7ad65af --- /dev/null +++ b/tests/st/test_algorithm/test_error_mitigation/test_folding.py @@ -0,0 +1,37 @@ +# 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. +# ============================================================================ +"""Test folding circuit.""" +import numpy as np + +from mindquantum.algorithm.error_mitigation import fold_at_random +from mindquantum.utils import random_circuit + + +def test_folding_circuit(): + """ + Description: Test folding circuit + Expectation: success + """ + np.random.seed(42) + circ = random_circuit(4, 20) + locally_folding = fold_at_random(circ, 2.3) + globally_folding = fold_at_random(circ, 2.3, 'globally') + assert locally_folding[30].hermitian() == circ[12] + assert locally_folding[30].hermitian() == globally_folding[25] + matrix_1 = circ.matrix() + matrix_2 = locally_folding.matrix() + matrix_3 = globally_folding.matrix() + assert np.allclose(matrix_1, matrix_2, atol=1e-4) + assert np.allclose(matrix_1, matrix_3, atol=1e-4) diff --git a/tests/st/test_algorithm/test_error_mitigation/test_zne.py b/tests/st/test_algorithm/test_error_mitigation/test_zne.py new file mode 100644 index 000000000..ecc9d858b --- /dev/null +++ b/tests/st/test_algorithm/test_error_mitigation/test_zne.py @@ -0,0 +1,58 @@ +# 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. +# ============================================================================ +"""Test zero noise extrapolation.""" + +import numpy as np + +from mindquantum.algorithm.error_mitigation import zne +from mindquantum.core.circuit import Circuit +from mindquantum.core.circuit.channel_adder import BitFlipAdder +from mindquantum.core.gates import RX, RY, RZ +from mindquantum.core.operators import Hamiltonian, QubitOperator +from mindquantum.simulator import Simulator +from mindquantum.simulator.noise import NoiseBackend + + +def execute(circ: Circuit, noise_level: float, ham: Hamiltonian, seed=42): + """Simulator executor.""" + return Simulator(NoiseBackend('mqmatrix', circ.n_qubits, BitFlipAdder(noise_level), seed=seed)).get_expectation( + ham, circ + ) + + +def rb_circ(n_gate): + """Generate random benchmark circuit.""" + circ = Circuit() + for _ in range(n_gate): + circ += np.random.choice([RX, RY, RZ])(np.random.uniform(-1, 1)).on(0) + return circ + + +def test_zne(): + """ + Description: Test zne + Expectation: success + """ + np.random.seed(42) + circ = rb_circ(50) + ham = Hamiltonian(QubitOperator('Z0')) + noise_level = 0.001 + true_value = execute(circ, 0.0, ham) + noisy_value = execute(circ, noise_level, ham) + zne_value = zne(circ, execute, scaling=np.linspace(1, 3, 3), args=(noise_level, ham)) + error_1 = abs((true_value - noisy_value) / true_value) + error_2 = abs((true_value - zne_value) / true_value) + assert np.allclose(error_1, 0.047095940433263844) + assert np.allclose(error_2, 0.014593005275941016) From e2c84485b52eeb726138e7ec6f91bf5be66ac6c6 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Fri, 21 Jul 2023 18:12:14 +0800 Subject: [PATCH 012/100] topology: test & docing --- .../mindquantum.device.QubitNode.rst | 7 ++ mindquantum/device/topology.py | 50 +++++++++ tests/st/test_device/test_topology.py | 103 ++++++++++++++++++ 3 files changed, 160 insertions(+) create mode 100644 tests/st/test_device/test_topology.py diff --git a/docs/api_python/mindquantum.device.QubitNode.rst b/docs/api_python/mindquantum.device.QubitNode.rst index 2b13ee130..be3b0e815 100644 --- a/docs/api_python/mindquantum.device.QubitNode.rst +++ b/docs/api_python/mindquantum.device.QubitNode.rst @@ -45,6 +45,13 @@ mindquantum.device.QubitNode 返回: int,量子比特的 id。 + .. py:method:: set_color(self, color:str) + + 设置量子比特的颜色。 + + 参数: + - **color** (str) - 新的颜色。 + .. py:method:: set_poi(poi_x: float, poi_y: float) 设置量子比特的位置坐标。 diff --git a/mindquantum/device/topology.py b/mindquantum/device/topology.py index 151ff6dd9..2864af81c 100644 --- a/mindquantum/device/topology.py +++ b/mindquantum/device/topology.py @@ -14,8 +14,11 @@ # ============================================================================ """Qubit node an topology of quantum chip.""" +import numbers import typing +from mindquantum.utils.type_value_check import _check_input_type, _check_int_type + from ..mqbackend.device import QubitNode as QubitNode_ from ..mqbackend.device import QubitsTopology as QubitsTopology_ @@ -44,6 +47,10 @@ class QubitNode: def __init__(self, qubit_id: int, color: str = '#000000', poi_x: float = 0.0, poi_y: float = 0.0) -> None: """Initialize a qubit node.""" + _check_int_type("qubit_id", qubit_id) + _check_input_type("color", str, color) + _check_input_type("poi_x", numbers.Real, poi_x) + _check_input_type("poi_y", numbers.Real, poi_y) self.id_ = qubit_id self.color_ = color self.poi_x_ = poi_x @@ -123,6 +130,7 @@ def __lshift__(self, other: "QubitNode") -> "QubitNode": >>> topology.is_coupled_with(0, 1) True """ + _check_input_type("other", QubitNode, other) if self.qubit_id == other.qubit_id: raise RuntimeError("Cannot disconnect itself.") self.neighbor.add(other.qubit_id) @@ -155,6 +163,7 @@ def __lt__(self, other: "QubitNode") -> "QubitNode": >>> q.qubit_id == q0.qubit_id True """ + _check_input_type("other", QubitNode, other) if self.qubit_id == other.qubit_id: raise RuntimeError("Cannot disconnect itself.") if other.qubit_id in self.neighbor: @@ -186,6 +195,7 @@ def __rshift__(self, other: "QubitNode") -> "QubitNode": >>> topology.is_coupled_with(0, 1) True """ + _check_input_type("other", QubitNode, other) if self.qubit_id == other.qubit_id: raise RuntimeError("Cannot disconnect itself.") self.neighbor.add(other.qubit_id) @@ -193,6 +203,23 @@ def __rshift__(self, other: "QubitNode") -> "QubitNode": return other + def set_color(self, color: str) -> None: + """ + Set the color of this qubit. + + Args: + color (str): The new color. + + Examples: + >>> from mindquantum.device import QubitNode + >>> q0 = QubitNode(1) + >>> q0.set_color('#ababab') + >>> q0.color + '#ababab' + """ + _check_input_type("color", str, color) + self.color_ = color + def set_poi(self, poi_x: float, poi_y: float) -> None: """ Set the position of this qubit. @@ -208,6 +235,8 @@ def set_poi(self, poi_x: float, poi_y: float) -> None: >>> print(q0.poi_x, q0.poi_y) 1 0 """ + _check_input_type("poi_x", numbers.Real, poi_x) + _check_input_type("poi_y", numbers.Real, poi_y) self.poi_x_, self.poi_y_ = poi_x, poi_y @property @@ -275,6 +304,9 @@ class QubitsTopology: def __init__(self, qubits: typing.List[QubitNode]) -> None: """Initialize a physical qubit topology.""" + _check_input_type("qubits", list, qubits) + for qubit in qubits: + _check_input_type("Element of qubits", QubitNode, qubit) self.qubits: typing.Dict[int, QubitNode] = {} for node in qubits: if node.qubit_id in self.qubits: @@ -298,6 +330,7 @@ def __getitem__(self, qubit_id: int) -> QubitNode: >>> topology[2].qubit_id 2 """ + _check_int_type("qubit_id", qubit_id) return self.qubits[qubit_id] def __get_cpp_obj__(self): @@ -318,6 +351,7 @@ def add_qubit_node(self, qubit: QubitNode) -> None: >>> topology.all_qubit_id() {0, 1, 2} """ + _check_input_type("qubit", QubitNode, qubit) if qubit.qubit_id in self.qubits: raise ValueError(f"Qubit with id {qubit.qubit_id} already exists.") self.qubits[qubit.qubit_id] = qubit @@ -400,6 +434,7 @@ def has_qubit_node(self, qubit_id: int) -> bool: >>> topology.has_qubit_node(0) True """ + _check_int_type("qubit_id", qubit_id) return qubit_id in self.qubits def is_coupled_with(self, id1: int, id2: int) -> bool: @@ -422,6 +457,8 @@ def is_coupled_with(self, id1: int, id2: int) -> bool: >>> topology.is_coupled_with(0, 1) True """ + _check_int_type("id1", id1) + _check_int_type("id2", id2) return id2 in self.qubits[id1].neighbor def isolate_with_near(self, qubit_id: int) -> None: @@ -441,6 +478,7 @@ def isolate_with_near(self, qubit_id: int) -> None: >>> topology.edges_with_id() set() """ + _check_int_type("qubit_id", qubit_id) current_node = self[qubit_id] other_nodes = [self[i] for i in current_node.neighbor] for node in other_nodes: @@ -480,6 +518,9 @@ def choose(self, ids: typing.List[int]) -> typing.List[QubitNode]: >>> print(nodes[0].qubit_id, nodes[1].qubit_id) 0 1 """ + _check_input_type("ids", list, ids) + for qubit_id in ids: + _check_int_type("Element of ids", qubit_id) return [self[i] for i in ids] def remove_isolate_node(self) -> None: @@ -521,6 +562,7 @@ def remove_qubit_node(self, qubit_id: int) -> None: >>> topology.all_qubit_id() {0, 2} """ + _check_int_type("qubit_id", qubit_id) will_remove = self.qubits[qubit_id] near_qubits = [self[i] for i in will_remove.neighbor] for node in near_qubits: @@ -542,6 +584,8 @@ def set_color(self, qubit_id: int, color: str) -> None: >>> topology[0].color '#ababab' """ + _check_int_type("qubit_id", qubit_id) + _check_input_type("color", str, color) self[qubit_id].color_ = color def set_position(self, qubit_id: int, poi_x: float, poi_y: float) -> None: @@ -560,6 +604,9 @@ def set_position(self, qubit_id: int, poi_x: float, poi_y: float) -> None: >>> topology[0].poi_x, topology[0].poi_y (1, 1) """ + _check_int_type("qubit_id", qubit_id) + _check_input_type("poi_x", numbers.Real, poi_x) + _check_input_type("poi_y", numbers.Real, poi_y) self[qubit_id].set_poi(poi_x, poi_y) def size(self) -> int: @@ -596,6 +643,7 @@ class LinearQubits(QubitsTopology): def __init__(self, n_qubits: int): """Initialize a linear topology.""" + _check_int_type("n_qubits", n_qubits) nodes = [QubitNode(i, poi_x=i) for i in range(n_qubits)] left_node = nodes[0] for node in nodes[1:]: @@ -620,6 +668,8 @@ class GridQubits(QubitsTopology): def __init__(self, n_row: int, n_col: int) -> None: """Initialize a grid topology with row and col number.""" + _check_int_type("n_row", n_row) + _check_int_type("n_col", n_col) self.n_row_ = n_row self.n_col_ = n_col qubits = [] diff --git a/tests/st/test_device/test_topology.py b/tests/st/test_device/test_topology.py new file mode 100644 index 000000000..28922147b --- /dev/null +++ b/tests/st/test_device/test_topology.py @@ -0,0 +1,103 @@ +# 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. +# ============================================================================ +"""Test topology of device.""" + +from mindquantum.device import GridQubits, LinearQubits, QubitNode, QubitsTopology + + +def test_qubit_node_property(): + """ + Description: Test qubit node + Expectation: success + """ + qubit = QubitNode(1) + qubit.set_poi(1.0, 2.0) + qubit.set_color("#ababab") + assert qubit.qubit_id == 1 + assert qubit.color == '#ababab' + assert qubit.poi_x == 1.0 + assert qubit.poi_y == 2.0 + + +def test_qubit_connection(): + """ + Description: Test qubit node connection + Expectation: success + """ + q0 = QubitNode(0) + q1 = QubitNode(1) + q2 = QubitNode(2) + assert q0 == (q0 << q1) + assert q1.qubit_id in q0.neighbor + assert q0 == (q0 < q1) + assert q1.qubit_id not in q0.neighbor + assert q2 == (q1 >> q2) + assert q2.qubit_id in q1.neighbor + assert q2 == (q1 > q2) + assert q2.qubit_id not in q1.neighbor + + +def test_topology(): + """ + Description: Test topology + Expectation: success + """ + topology = QubitsTopology([QubitNode(i, poi_x=i, poi_y=i) for i in range(4)]) + topology.add_qubit_node(QubitNode(4)) + assert topology.size() == 5 + assert topology.all_qubit_id() == set(range(5)) + _ = topology[0] >> topology[1] >> topology[2] >> topology[3] >> topology[4] + topology.remove_qubit_node(4) + assert topology.size() == 4 + assert not topology.has_qubit_node(4) + assert topology.edges_with_id() == {(0, 1), (1, 2), (2, 3)} + _ = topology[3] > topology[2] + assert not topology.is_coupled_with(2, 3) + topology.isolate_with_near(0) + assert topology.n_edges() == 1 + topology.remove_isolate_node() + assert topology.size() == 2 + topology.set_color(1, '#ababab') + assert topology[1].color == '#ababab' + topology.set_position(2, 3.0, 4.0) + assert topology[2].poi_x + topology[2].poi_y == 7.0 + + +def test_linear_qubits(): + """ + Description: Test linear qubits topology + Expectation: success + """ + topology = LinearQubits(4) + assert topology.size() == 4 + topology.isolate_with_near(2) + topology.remove_isolate_node() + assert topology.size() == 2 + + +def test_grid_qubits(): + """ + Description: Test grid qubits topology + Expectation: success + """ + topology = GridQubits(4, 5) + assert topology.size() == 20 + assert topology.n_row() == 4 + assert topology.n_col() == 5 + assert topology.n_edges() == 31 + topology.isolate_with_near(2) + topology.remove_isolate_node() + assert topology.size() == 19 + assert topology.n_edges() == 28 From f3ae18dbc871500ffd5f88da04eb50713d1cc693 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Mon, 24 Jul 2023 09:24:42 +0800 Subject: [PATCH 013/100] always exclude barrier --- mindquantum/core/circuit/channel_adder.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mindquantum/core/circuit/channel_adder.py b/mindquantum/core/circuit/channel_adder.py index 52c11d8ec..643f36b28 100644 --- a/mindquantum/core/circuit/channel_adder.py +++ b/mindquantum/core/circuit/channel_adder.py @@ -19,7 +19,7 @@ from mindquantum.utils.type_value_check import _check_input_type from .. import gates -from ..gates import BasicGate, NoiseGate +from ..gates import BarrierGate, BasicGate, NoiseGate from .circuit import Circuit @@ -51,6 +51,8 @@ def __call__(self, circ: Circuit) -> Circuit: """Add noise channel after acceptable quantum gate.""" out = Circuit() for g in circ: + if isinstance(g, BarrierGate): + continue if self.add_after: out += g if all(rule(g) for rule in self.accepter): From 2dfed8ceade15f5eedcd48f2ad9df3ec5cbabaa0 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Mon, 24 Jul 2023 09:50:23 +0800 Subject: [PATCH 014/100] qubit number constrain adder --- ...ntum.core.circuit.QubitNumberConstrain.rst | 11 +++++ docs/api_python/mindquantum.core.circuit.rst | 1 + .../mindquantum.core.circuit.rst | 1 + mindquantum/core/circuit/__init__.py | 1 + mindquantum/core/circuit/channel_adder.py | 47 ++++++++++++++++++- .../test_circuit/test_channel_adder.py | 14 ++++++ 6 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 docs/api_python/mindquantum.core.circuit.QubitNumberConstrain.rst diff --git a/docs/api_python/mindquantum.core.circuit.QubitNumberConstrain.rst b/docs/api_python/mindquantum.core.circuit.QubitNumberConstrain.rst new file mode 100644 index 000000000..03be3aec5 --- /dev/null +++ b/docs/api_python/mindquantum.core.circuit.QubitNumberConstrain.rst @@ -0,0 +1,11 @@ +mindquantum.core.circuit.QubitNumberConstrain +============================================= + +.. py:class:: mindquantum.core.circuit.QubitNumberConstrain(adder: ChannelAdderBase) + + 翻转给定信道添加器的接受和拒绝规则。 + + 参数: + - **n_qubits** (int) - 量子门的比特数目。 + - **with_ctrl** (bool) - 控制比特是否算在总比特数目之内。默认值: ``True`` 。 + - **add_after** (bool) - 在量子门前面或者后面添加量子信道。默认值: ``True``。 diff --git a/docs/api_python/mindquantum.core.circuit.rst b/docs/api_python/mindquantum.core.circuit.rst index 9ca4fa3fd..3d92d5a78 100644 --- a/docs/api_python/mindquantum.core.circuit.rst +++ b/docs/api_python/mindquantum.core.circuit.rst @@ -57,6 +57,7 @@ Channel adder mindquantum.core.circuit.BitFlipAdder mindquantum.core.circuit.MixerAdder mindquantum.core.circuit.SequentialAdder + mindquantum.core.circuit.QubitNumberConstrain functional ---------- diff --git a/docs/api_python_en/mindquantum.core.circuit.rst b/docs/api_python_en/mindquantum.core.circuit.rst index 92718b4d7..1f6303837 100644 --- a/docs/api_python_en/mindquantum.core.circuit.rst +++ b/docs/api_python_en/mindquantum.core.circuit.rst @@ -54,6 +54,7 @@ Channel adder mindquantum.core.circuit.BitFlipAdder mindquantum.core.circuit.MixerAdder mindquantum.core.circuit.SequentialAdder + mindquantum.core.circuit.QubitNumberConstrain shortcut ---------- diff --git a/mindquantum/core/circuit/__init__.py b/mindquantum/core/circuit/__init__.py index e23eb0369..991937cb3 100644 --- a/mindquantum/core/circuit/__init__.py +++ b/mindquantum/core/circuit/__init__.py @@ -26,6 +26,7 @@ MixerAdder, NoiseChannelAdder, NoiseExcluder, + QubitNumberConstrain, ReverseAdder, SequentialAdder, ) diff --git a/mindquantum/core/circuit/channel_adder.py b/mindquantum/core/circuit/channel_adder.py index 643f36b28..04352b3e1 100644 --- a/mindquantum/core/circuit/channel_adder.py +++ b/mindquantum/core/circuit/channel_adder.py @@ -16,7 +16,7 @@ import typing from types import FunctionType, MethodType -from mindquantum.utils.type_value_check import _check_input_type +from mindquantum.utils.type_value_check import _check_input_type, _check_int_type from .. import gates from ..gates import BarrierGate, BasicGate, NoiseGate @@ -263,6 +263,49 @@ def _handler(self, g: BasicGate, *args, **kwargs) -> Circuit: return circ +class QubitNumberConstrain(ChannelAdderBase): + """ + Only add noise channel for n_qubits quantum gate. + + Args: + n_qubits (int): The number qubit of quantum gate. + with_ctrl (bool): Whether control qubits also contribute to `n_qubits` or not. Default: ``True``. + add_after (bool): Whether add channel after gate or before gate. Default: ``True``. + + Examples: + >>> from mindquantum.core.circuit import QubitNumberConstrain, Circuit, BitFlipAdder, MixerAdder + >>> circ = Circuit().h(0).x(1, 0) + >>> circ + q0: ──H────●── + │ + q1: ───────X── + >>> adder = MixerAdder([ + ... QubitNumberConstrain(2), + ... BitFlipAdder(0.1) + ... ]) + >>> adder(circ) + q0: ──H────●────BFC(p=1/10)── + │ + q1: ───────X────BFC(p=1/10)── + """ + + def __init__(self, n_qubits: int, with_ctrl: bool = True, add_after: bool = True): + """Initialize a QubitNumberConstrain.""" + _check_int_type("n_qubits", n_qubits) + _check_input_type("with_ctrl", bool, with_ctrl) + self.n_qubits = n_qubits + self.with_ctrl = with_ctrl + super().__init__(add_after) + + def __repr__(self) -> str: + """Return string expression of adder.""" + return f"QubitNumberConstrain" + + def _accepter(self, *args, **kwargs) -> typing.List[typing.Union[FunctionType, MethodType]]: + """Construct accepter rules.""" + return [lambda x: self.n_qubits == (len(x.obj_qubits) + len(x.ctrl_qubits) * self.with_ctrl)] + + class MixerAdder(ChannelAdderBase): """ Execute each adder if all accepter and excluder are met. @@ -385,4 +428,6 @@ def __repr__(self) -> str: "BitFlipAdder", "MixerAdder", "SequentialAdder", + "QubitNumberConstrain", ] +__all__.sort() diff --git a/tests/st/test_core/test_circuit/test_channel_adder.py b/tests/st/test_core/test_circuit/test_channel_adder.py index 29f059901..cbc665f08 100644 --- a/tests/st/test_core/test_circuit/test_channel_adder.py +++ b/tests/st/test_core/test_circuit/test_channel_adder.py @@ -21,6 +21,7 @@ MixerAdder, NoiseChannelAdder, NoiseExcluder, + QubitNumberConstrain, ReverseAdder, SequentialAdder, ) @@ -133,3 +134,16 @@ def test_sequential_adder(): exp_circ += Circuit([noise_1.on(0), bfc.on(0), Measure().on(0), bfc.on(1)]) exp_circ += Measure().on(1) assert exp_circ == new_circ + + +def test_qubit_number_constrain(): + """ + Description: test qubit number constrain. + Expectation: success. + """ + circ = Circuit().h(0).x(1, 0) + adder = MixerAdder([QubitNumberConstrain(2), BitFlipAdder(0.1)]) + new_circ = adder(circ) + bit_flip = BitFlipChannel(0.1) + exp_circ = circ + bit_flip.on(1) + bit_flip.on(0) + assert new_circ == exp_circ From 08f2d9f9d26e5db1756690ded1f70657cc3af883 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Mon, 24 Jul 2023 10:49:30 +0800 Subject: [PATCH 015/100] qubit id constrain adder --- ...dquantum.core.circuit.QubitIDConstrain.rst | 10 ++++ ...ntum.core.circuit.QubitNumberConstrain.rst | 2 +- docs/api_python/mindquantum.core.circuit.rst | 1 + .../mindquantum.core.circuit.rst | 1 + mindquantum/core/circuit/__init__.py | 1 + mindquantum/core/circuit/channel_adder.py | 50 ++++++++++++++++++- .../test_circuit/test_channel_adder.py | 32 ++++++++++++ 7 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 docs/api_python/mindquantum.core.circuit.QubitIDConstrain.rst diff --git a/docs/api_python/mindquantum.core.circuit.QubitIDConstrain.rst b/docs/api_python/mindquantum.core.circuit.QubitIDConstrain.rst new file mode 100644 index 000000000..db830d2cb --- /dev/null +++ b/docs/api_python/mindquantum.core.circuit.QubitIDConstrain.rst @@ -0,0 +1,10 @@ +mindquantum.core.circuit.QubitIDConstrain +========================================= + +.. py:class:: mindquantum.core.circuit.QubitIDConstrain(adder: ChannelAdderBase) + + 只将噪声信道作用在给定比特序号的量子门上。 + + 参数: + - **qubit_ids** (Union[int, List[int]]) - 想要选择的比特序号的列表。 + - **add_after** (bool) - 在量子门前面或者后面添加量子信道。默认值: ``True``。 diff --git a/docs/api_python/mindquantum.core.circuit.QubitNumberConstrain.rst b/docs/api_python/mindquantum.core.circuit.QubitNumberConstrain.rst index 03be3aec5..69e2bc310 100644 --- a/docs/api_python/mindquantum.core.circuit.QubitNumberConstrain.rst +++ b/docs/api_python/mindquantum.core.circuit.QubitNumberConstrain.rst @@ -3,7 +3,7 @@ mindquantum.core.circuit.QubitNumberConstrain .. py:class:: mindquantum.core.circuit.QubitNumberConstrain(adder: ChannelAdderBase) - 翻转给定信道添加器的接受和拒绝规则。 + 只将噪声信道作用在比特数为 ``n_qubits`` 的量子门上。 参数: - **n_qubits** (int) - 量子门的比特数目。 diff --git a/docs/api_python/mindquantum.core.circuit.rst b/docs/api_python/mindquantum.core.circuit.rst index 3d92d5a78..20cc2a1dd 100644 --- a/docs/api_python/mindquantum.core.circuit.rst +++ b/docs/api_python/mindquantum.core.circuit.rst @@ -58,6 +58,7 @@ Channel adder mindquantum.core.circuit.MixerAdder mindquantum.core.circuit.SequentialAdder mindquantum.core.circuit.QubitNumberConstrain + mindquantum.core.circuit.QubitIDConstrain functional ---------- diff --git a/docs/api_python_en/mindquantum.core.circuit.rst b/docs/api_python_en/mindquantum.core.circuit.rst index 1f6303837..7886e5c63 100644 --- a/docs/api_python_en/mindquantum.core.circuit.rst +++ b/docs/api_python_en/mindquantum.core.circuit.rst @@ -55,6 +55,7 @@ Channel adder mindquantum.core.circuit.MixerAdder mindquantum.core.circuit.SequentialAdder mindquantum.core.circuit.QubitNumberConstrain + mindquantum.core.circuit.QubitIDConstrain shortcut ---------- diff --git a/mindquantum/core/circuit/__init__.py b/mindquantum/core/circuit/__init__.py index 991937cb3..29cc74ac9 100644 --- a/mindquantum/core/circuit/__init__.py +++ b/mindquantum/core/circuit/__init__.py @@ -26,6 +26,7 @@ MixerAdder, NoiseChannelAdder, NoiseExcluder, + QubitIDConstrain, QubitNumberConstrain, ReverseAdder, SequentialAdder, diff --git a/mindquantum/core/circuit/channel_adder.py b/mindquantum/core/circuit/channel_adder.py index 04352b3e1..39084a04a 100644 --- a/mindquantum/core/circuit/channel_adder.py +++ b/mindquantum/core/circuit/channel_adder.py @@ -265,7 +265,7 @@ def _handler(self, g: BasicGate, *args, **kwargs) -> Circuit: class QubitNumberConstrain(ChannelAdderBase): """ - Only add noise channel for n_qubits quantum gate. + Only add noise channel for ``n_qubits`` quantum gate. Args: n_qubits (int): The number qubit of quantum gate. @@ -306,6 +306,53 @@ def _accepter(self, *args, **kwargs) -> typing.List[typing.Union[FunctionType, M return [lambda x: self.n_qubits == (len(x.obj_qubits) + len(x.ctrl_qubits) * self.with_ctrl)] +class QubitIDConstrain(ChannelAdderBase): + """ + Select gate with qubit id in given list. + + Args: + qubit_ids (Union[int, List[int]]): The qubit id list you want to select. + add_after (bool): Whether add channel after gate or before gate. Default: ``True``. + + Examples: + >>> from mindquantum.core.circuit import MixerAdder, BitFlipAdder, QubitIDConstrain, Circuit + >>> circ = Circuit().h(0).h(1).h(2).x(1, 0).x(2, 1) + >>> circ + q0: ──H────●─────── + │ + q1: ──H────X────●── + │ + q2: ──H─────────X── + >>> adder = MixerAdder([ + ... QubitIDConstrain([0, 1]), + ... BitFlipAdder(0.1), + ... ]) + >>> adder(circ) + q0: ──H────BFC(p=1/10)────●────BFC(p=1/10)─────── + │ + q1: ──H────BFC(p=1/10)────X────BFC(p=1/10)────●── + │ + q2: ──H───────────────────────────────────────X── + """ + + def __init__(self, qubit_ids: typing.Union[int, typing.List[int]], add_after: bool = True): + """Initialize a QubitIDConstrain.""" + self.qubit_ids = [] + if isinstance(qubit_ids, int): + self.qubit_ids.append(qubit_ids) + elif isinstance(qubit_ids, list): + for qubit_id in qubit_ids: + _check_int_type("Element of qubit_ids", qubit_id) + self.qubit_ids.extend(qubit_ids) + else: + raise TypeError(f"qubit_ids requires a int or a list, but get {type(qubit_ids)}.") + super().__init__(add_after) + + def _accepter(self, *args, **kwargs) -> typing.List[typing.Union[FunctionType, MethodType]]: + """Construct accepter rules.""" + return [lambda x: all(i in self.qubit_ids for i in x.obj_qubits + x.ctrl_qubits)] + + class MixerAdder(ChannelAdderBase): """ Execute each adder if all accepter and excluder are met. @@ -429,5 +476,6 @@ def __repr__(self) -> str: "MixerAdder", "SequentialAdder", "QubitNumberConstrain", + "QubitIDConstrain", ] __all__.sort() diff --git a/tests/st/test_core/test_circuit/test_channel_adder.py b/tests/st/test_core/test_circuit/test_channel_adder.py index cbc665f08..3f9bef7ba 100644 --- a/tests/st/test_core/test_circuit/test_channel_adder.py +++ b/tests/st/test_core/test_circuit/test_channel_adder.py @@ -21,6 +21,7 @@ MixerAdder, NoiseChannelAdder, NoiseExcluder, + QubitIDConstrain, QubitNumberConstrain, ReverseAdder, SequentialAdder, @@ -29,6 +30,7 @@ AmplitudeDampingChannel, BitFlipChannel, DepolarizingChannel, + H, Measure, X, ) @@ -147,3 +149,33 @@ def test_qubit_number_constrain(): bit_flip = BitFlipChannel(0.1) exp_circ = circ + bit_flip.on(1) + bit_flip.on(0) assert new_circ == exp_circ + + +def test_qubit_id_constrain(): + """ + Description: test qubit id constrain. + Expectation: success. + """ + circ = Circuit().h(0).h(1).h(2).x(1, 0).x(2, 1) + adder = MixerAdder( + [ + QubitIDConstrain([0, 1]), + BitFlipAdder(0.1), + ] + ) + new_circ = adder(circ) + bit_flip = BitFlipChannel(0.1) + exp_circ = Circuit( + [ + H.on(0), + bit_flip.on(0), + H.on(1), + bit_flip.on(1), + H.on(2), + X.on(1, 0), + bit_flip.on(1), + bit_flip.on(0), + X.on(2, 1), + ] + ) + assert new_circ == exp_circ From abf0c2108033b4e9d9c1107cffa04a10468b1e2b Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Mon, 24 Jul 2023 11:03:37 +0800 Subject: [PATCH 016/100] Now can focus on certrain qubit when adding channel. --- .../mindquantum.core.circuit.BitFlipAdder.rst | 3 +- ...quantum.core.circuit.NoiseChannelAdder.rst | 3 +- mindquantum/core/circuit/channel_adder.py | 48 +++++++++++++++---- .../test_circuit/test_channel_adder.py | 16 +++++-- 4 files changed, 54 insertions(+), 16 deletions(-) diff --git a/docs/api_python/mindquantum.core.circuit.BitFlipAdder.rst b/docs/api_python/mindquantum.core.circuit.BitFlipAdder.rst index 1a3c482c3..a40ddee81 100644 --- a/docs/api_python/mindquantum.core.circuit.BitFlipAdder.rst +++ b/docs/api_python/mindquantum.core.circuit.BitFlipAdder.rst @@ -1,11 +1,12 @@ mindquantum.core.circuit.BitFlipAdder ===================================== -.. py:class:: mindquantum.core.circuit.BitFlipAdder(flip_rate: float, with_ctrl=True, add_after: bool = True) +.. py:class:: mindquantum.core.circuit.BitFlipAdder(flip_rate: float, with_ctrl=True, focus_on: int = None, add_after: bool = True) 在量子门前面或者后面添加一个比特翻转信道。 参数: - **flip_rate** (float) - 比特翻转信道的翻转概率。具体请参考 :class:`~.core.gates.BitFlipChannel`。 - **with_ctrl** (bool) - 是否在控制为上添加比特。默认值: ``True``。 + - **focus_on** (bool) - 只讲该噪声信道作用在 ``focus_on`` 比特上。如果为 ``None``,则作用在量子门的所有比特上。默认值: ``None``。 - **add_after** (bool) - 是否在量子门后面添加信道。如果为 ``False``,信道将会加在量子门前面。默认值: ``True``。 diff --git a/docs/api_python/mindquantum.core.circuit.NoiseChannelAdder.rst b/docs/api_python/mindquantum.core.circuit.NoiseChannelAdder.rst index ed45ab881..469e98f77 100644 --- a/docs/api_python/mindquantum.core.circuit.NoiseChannelAdder.rst +++ b/docs/api_python/mindquantum.core.circuit.NoiseChannelAdder.rst @@ -1,11 +1,12 @@ mindquantum.core.circuit.NoiseChannelAdder ========================================== -.. py:class:: mindquantum.core.circuit.NoiseChannelAdder(channel: NoiseGate, with_ctrl=True, add_after: bool = True) +.. py:class:: mindquantum.core.circuit.NoiseChannelAdder(channel: NoiseGate, with_ctrl=True, focus_on: int = None, add_after: bool = True) 添加一个单比特量子信道。 参数: - **channel** (:class:`~.core.gates.NoiseGate`) - 一个单比特量子信道。 - **with_ctrl** (bool) - 是否在控制为上添加比特。默认值: ``True``。 + - **focus_on** (bool) - 只讲该噪声信道作用在 ``focus_on`` 比特上。如果为 ``None``,则作用在量子门的所有比特上。默认值: ``None``。 - **add_after** (bool) - 是否在量子门后面添加信道。如果为 ``False``,信道将会加在量子门前面。默认值: ``True``。 diff --git a/mindquantum/core/circuit/channel_adder.py b/mindquantum/core/circuit/channel_adder.py index 39084a04a..090a04cd6 100644 --- a/mindquantum/core/circuit/channel_adder.py +++ b/mindquantum/core/circuit/channel_adder.py @@ -186,6 +186,8 @@ class BitFlipAdder(ChannelAdderBase): flip_rate (float): The flip rate for bit flip channel. For more detail please refers to :class:`~.core.gates.BitFlipChannel`. with_ctrl (bool): Whether add bit flip channel for control qubits. Default: ``True``. + focus_on (int): Only add this noise channel on ``focus_on`` qubit. If ``None``, add to + all qubits of selected quantum gate. Default: ``None``. add_after (bool): Whether add this channel after quantum gate or not. If ``False``, the channel will add before quantum gate. Default: ``True``. @@ -193,19 +195,27 @@ class BitFlipAdder(ChannelAdderBase): >>> from mindquantum.core.circuit import BitFlipAdder >>> from mindquantum.core.circuit import Circuit >>> circ = Circuit().h(0).x(1, 0) - >>> adder = BitFlipAdder(0.1, with_ctrl=False) - >>> adder(circ) + >>> adder1 = BitFlipAdder(0.1, with_ctrl=False) + >>> adder1(circ) q0: ──H────BFC(p=1/10)────●───────────────── │ q1: ──────────────────────X────BFC(p=1/10)── + >>> adder2 = BitFlipAdder(0.1, with_ctrl=False, focus_on=1) + >>> adder2(circ) + q0: ──H────●───────────────── + │ + q1: ───────X────BFC(p=1/10)── """ - def __init__(self, flip_rate: float, with_ctrl=True, add_after: bool = True): + def __init__(self, flip_rate: float, with_ctrl=True, focus_on: int = None, add_after: bool = True): """Initialize a BitFlipAdder.""" _check_input_type("with_ctrl", bool, with_ctrl) super().__init__(add_after=add_after) self.flip_rate = flip_rate self.with_ctrl = with_ctrl + if focus_on is not None: + _check_int_type("focus_on", focus_on) + self.focus_on = focus_on def __repr__(self) -> str: """Return string expression of adder.""" @@ -214,8 +224,12 @@ def __repr__(self) -> str: def _handler(self, g: BasicGate, *args, **kwargs) -> Circuit: """Create action you will do if a gate is acceptable.""" circ = Circuit() - for qubit in g.obj_qubits + (g.ctrl_qubits if self.with_ctrl else []): - circ += gates.BitFlipChannel(self.flip_rate).on(qubit) + if self.focus_on is None: + for qubit in g.obj_qubits + (g.ctrl_qubits if self.with_ctrl else []): + circ += gates.BitFlipChannel(self.flip_rate).on(qubit) + else: + if self.focus_on in g.obj_qubits or self.focus_on in g.ctrl_qubits: + circ += gates.BitFlipChannel(self.flip_rate).on(self.focus_on) return circ @@ -226,6 +240,8 @@ class NoiseChannelAdder(ChannelAdderBase): Args: channel (:class:`~.core.gates.NoiseGate`): A single qubit quantum channel. with_ctrl (bool): Whether add quantum channel for control qubits. Default: ``True``. + focus_on (int): Only add this noise channel on ``focus_on`` qubit. If ``None``, add to + all qubits of selected quantum gate. Default: ``None``. add_after (bool): Whether add this channel after quantum gate or not. If ``False``, the channel will add before quantum gate. Default: ``True``. @@ -234,14 +250,19 @@ class NoiseChannelAdder(ChannelAdderBase): >>> from mindquantum.core.gates import AmplitudeDampingChannel >>> circ = Circuit().h(0).x(1, 0) >>> channel = AmplitudeDampingChannel(0.3) - >>> adder = NoiseChannelAdder(channel, with_ctrl=True, add_after=True) - >>> adder(circ) + >>> adder1 = NoiseChannelAdder(channel, with_ctrl=True, add_after=True) + >>> adder1(circ) q0: ──H────ADC(γ=3/10)────●────ADC(γ=3/10)── │ q1: ──────────────────────X────ADC(γ=3/10)── + >>> adder2 = NoiseChannelAdder(channel, with_ctrl=True, focus_on=1, add_after=True) + >>> adder2(circ) + q0: ──H────●───────────────── + │ + q1: ───────X────ADC(γ=3/10)── """ - def __init__(self, channel: NoiseGate, with_ctrl=True, add_after: bool = True): + def __init__(self, channel: NoiseGate, with_ctrl=True, focus_on: int = None, add_after: bool = True): """Initialize a BitFlipAdder.""" _check_input_type("channel", NoiseGate, channel) _check_input_type("with_ctrl", bool, with_ctrl) @@ -250,6 +271,9 @@ def __init__(self, channel: NoiseGate, with_ctrl=True, add_after: bool = True): super().__init__(add_after=add_after) self.with_ctrl = with_ctrl self.channel = channel + if focus_on is not None: + _check_int_type("focus_on", focus_on) + self.focus_on = focus_on def __repr__(self) -> str: """Return string expression of adder.""" @@ -258,8 +282,12 @@ def __repr__(self) -> str: def _handler(self, g: BasicGate, *args, **kwargs) -> Circuit: """Create action you will do if a gate is acceptable.""" circ = Circuit() - for qubit in g.obj_qubits + (g.ctrl_qubits if self.with_ctrl else []): - circ += self.channel.on(qubit) + if self.focus_on is None: + for qubit in g.obj_qubits + (g.ctrl_qubits if self.with_ctrl else []): + circ += self.channel.on(qubit) + else: + if self.focus_on in g.obj_qubits or self.focus_on in g.ctrl_qubits: + circ += self.channel.on(self.focus_on) return circ diff --git a/tests/st/test_core/test_circuit/test_channel_adder.py b/tests/st/test_core/test_circuit/test_channel_adder.py index 3f9bef7ba..25955e7db 100644 --- a/tests/st/test_core/test_circuit/test_channel_adder.py +++ b/tests/st/test_core/test_circuit/test_channel_adder.py @@ -80,11 +80,15 @@ def test_bit_flip_adder(): Expectation: success. """ circ = Circuit().h(0).x(1, 0) - adder = BitFlipAdder(0.1, with_ctrl=False) + adder1 = BitFlipAdder(0.1, with_ctrl=False) channel = BitFlipChannel(0.1) - new_circ = adder(circ) + new_circ = adder1(circ) exp_circ = Circuit().h(0) + channel.on(0) + X.on(1, 0) + channel.on(1) assert new_circ == exp_circ + adder2 = BitFlipAdder(0.1, with_ctrl=False, focus_on=1) + new_circ2 = adder2(circ) + exp_circ2 = circ + channel.on(1) + assert new_circ2 == exp_circ2 def test_noise_channel_adder(): @@ -94,10 +98,14 @@ def test_noise_channel_adder(): """ circ = Circuit().h(0).x(1, 0) channel = AmplitudeDampingChannel(0.3) - adder = NoiseChannelAdder(channel, with_ctrl=True, add_after=True) - new_circ = adder(circ) + adder1 = NoiseChannelAdder(channel, with_ctrl=True, add_after=True) + new_circ = adder1(circ) exp_circ = Circuit().h(0) + channel.on(0) + X.on(1, 0) + channel.on(1) + channel.on(0) assert new_circ == exp_circ + adder2 = NoiseChannelAdder(channel, with_ctrl=True, focus_on=1, add_after=True) + new_circ2 = adder2(circ) + exp_circ2 = circ + channel.on(1) + assert new_circ2 == exp_circ2 def test_mixer_adder(): From a66a2e57f67685c02f60e9451cf815df8757e7a4 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Mon, 24 Jul 2023 14:35:57 +0800 Subject: [PATCH 017/100] fix bug for flitting barrier for channel adder --- mindquantum/core/circuit/channel_adder.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mindquantum/core/circuit/channel_adder.py b/mindquantum/core/circuit/channel_adder.py index 090a04cd6..8c040d058 100644 --- a/mindquantum/core/circuit/channel_adder.py +++ b/mindquantum/core/circuit/channel_adder.py @@ -51,11 +51,9 @@ def __call__(self, circ: Circuit) -> Circuit: """Add noise channel after acceptable quantum gate.""" out = Circuit() for g in circ: - if isinstance(g, BarrierGate): - continue if self.add_after: out += g - if all(rule(g) for rule in self.accepter): + if not isinstance(g, BarrierGate) and all(rule(g) for rule in self.accepter): if not any(rule(g) for rule in self.excluder): out += self._handler(g) if not self.add_after: From 2d38a34ebf9f27d427d5469aa25901aa38369798 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Mon, 24 Jul 2023 14:52:58 +0800 Subject: [PATCH 018/100] update noise simulator tutorial --- docs/noise_simulator.ipynb | 1024 ++++++++++++++++++---- docs/noise_simulator_en.ipynb | 1544 +++++++++++++++++++++++++++++++++ 2 files changed, 2408 insertions(+), 160 deletions(-) create mode 100644 docs/noise_simulator_en.ipynb diff --git a/docs/noise_simulator.ipynb b/docs/noise_simulator.ipynb index 052462c51..1f91a0dd7 100644 --- a/docs/noise_simulator.ipynb +++ b/docs/noise_simulator.ipynb @@ -1,13 +1,16 @@ { "cells": [ { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# 噪声模拟器\n", "\n", - "MindQuantum 中包含各种噪声信道,利用噪声信道我们可以对真实的量子芯片进行模拟。下面介绍如何利用 MindQuantum 完成此任务。\n", + "[![下载Notebook](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/master/resource/_static/logo_notebook.png)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/master/mindquantum/zh_cn/mindspore_noise_simulator.ipynb) \n", + "[![下载样例代码](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/master/resource/_static/logo_download_code.png)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/master/mindquantum/zh_cn/mindspore_noise_simulator.py) \n", + "[![查看源文件](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/master/resource/_static/logo_source.png)](https://gitee.com/mindspore/docs/blob/master/docs/mindquantum/docs/source_zh_cn/noise_simulator.ipynb)\n", + "\n", + "MindQuantum 中包含各种噪声信道,利用噪声信道我们可以对真实的量子芯片进行模拟。在 MindQuantum 中,我们定义了各种 `ChannelAdder`,可以有选择性的在量子线路的不同位置添加噪声信道,依次完成含噪声的量子模拟。下面介绍如何利用 MindQuantum 完成此任务。\n", "\n", "## ChannelAdder\n", "\n", @@ -19,16 +22,25 @@ "\n", "- `_handler(BasicGate)`:输入一个量子门,返回一段量子线路,表示在输入量子门后添加一段自定义的信道。\n", "\n", - "我们从定义类 `ChannelAdder` 的 `__call__` 函数,直接调用 `ChannelAdder` 即可生成处理后的量子线路。\n", + "我们重定义类 `ChannelAdder` 的 `__call__` 函数,直接调用 `ChannelAdder` 即可生成处理后的量子线路。\n", "下面介绍几中 `ChannelAdder`。\n", "\n", "### BitFlipAdder\n", "\n", + "`BitFlipAdder` 的接口定义为:\n", + "\n", "```python\n", - "BitFlipAdder(flip_rate: float = None, with_ctrl=True, device: NaiveChip = None, add_after: bool = True)\n", + "BitFlipAdder(flip_rate: float, with_ctrl=True, focus_on: int = None, add_after: bool = True)\n", "```\n", "\n", - "该 `Adder` 会在所有门后(如果 `add_after` 为 `True`, 否则是在量子门前)添加一个比特翻转信道:" + "该 `Adder` 会在量子门后添加一个比特翻转信道,接口的参数含义为:\n", + "\n", + "- **flip_rate** (float):比特翻转信道的翻转概率。\n", + "- **with_ctrl** (bool):是否在控制为上添加比特。默认值: ``True``。\n", + "- **focus_on** (bool):只讲该噪声信道作用在 ``focus_on`` 比特上。如果为 ``None``,则作用在量子门的所有比特上。默认值: ``None``。\n", + "- **add_after** (bool):是否在量子门后面添加信道。如果为 ``False``,信道将会加在量子门前面。默认值: ``True``。\n", + "\n", + "例如,我们可以通过如下接口,在给定量子线路的每个量子门后都添加一个翻转概率为 ``0.3`` 的比特翻转信道:" ] }, { @@ -39,7 +51,7 @@ { "data": { "image/svg+xml": [ - "
\n", + "\n", "\n", "\n", "q0:\n", @@ -71,10 +83,10 @@ "Z\n", " \n", "\n", - "
" + "" ], "text/plain": [ - "" + "" ] }, "execution_count": 1, @@ -99,16 +111,16 @@ { "data": { "image/svg+xml": [ - "
\n", - "\n", + "\n", + "\n", "\n", "q0:\n", " \n", "\n", "q1:\n", " \n", - "\n", - "\n", + "\n", + "\n", "\n", "\n", "\n", @@ -116,10 +128,13 @@ " \n", "\n", "\n", - "\n", - "\n", + "\n", + "\n", "BFC\n", " \n", + "\n", + "p=3/10\n", + " \n", "\n", "\n", "\n", @@ -131,28 +146,34 @@ " \n", "\n", "\n", - "\n", - "\n", + "\n", + "\n", "BFC\n", " \n", + "\n", + "p=3/10\n", + " \n", "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", "Z\n", " \n", "\n", "\n", - "\n", - "\n", + "\n", + "\n", "BFC\n", " \n", + "\n", + "p=3/10\n", + " \n", "\n", - "
" + "" ], "text/plain": [ - "" + "" ] }, "execution_count": 2, @@ -167,7 +188,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -181,7 +201,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -191,9 +210,9 @@ "MixerAdder(adders: typing.List[ChannelAdderBase])\n", "```\n", "\n", - "`MixerAdder` 可以加多个 `Adder` 混合起来,保证量子门在每一个 `Adder` 中的接受函数集和拒绝函数集同时满足时,顺序添加 `_handler` 产生的量子线路。\n", + "`MixerAdder` 可以将多个 `Adder` 混合起来,保证量子门在每一个 `Adder` 中的接受函数集和拒绝函数集同时满足时,顺序添加 `_handler` 产生的量子线路。\n", "\n", - "举例来说,我们可以将上文提到的 `BitFlipAdder` 和 `MeasureAccepter` 混合起来,达到只在测量门前添加比特翻转信道的功能。" + "举例来说,我们可以将上文提到的 `BitFlipAdder` 和 `MeasureAccepter` 混合起来,达到只在测量门前添加比特翻转信道的功能:" ] }, { @@ -214,7 +233,7 @@ { "data": { "image/svg+xml": [ - "
\n", + "\n", "\n", "\n", "q0:\n", @@ -250,7 +269,7 @@ "\n", "\n", "\n", - "
" + "" ] }, "metadata": {}, @@ -259,16 +278,16 @@ { "data": { "image/svg+xml": [ - "
\n", - "\n", + "\n", + "\n", "\n", "q0:\n", " \n", "\n", "q1:\n", " \n", - "\n", - "\n", + "\n", + "\n", "\n", "\n", "\n", @@ -292,19 +311,22 @@ " \n", "\n", "\n", - "\n", - "\n", + "\n", + "\n", "BFC\n", " \n", + "\n", + "p=1/100\n", + " \n", "\n", - "\n", - "\n", - "\n", - "\n", - "
" + "\n", + "\n", + "\n", + "\n", + "" ], "text/plain": [ - "" + "" ] }, "execution_count": 3, @@ -329,7 +351,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -339,14 +360,16 @@ "SequentialAdder(adders: typing.List[ChannelAdderBase])\n", "```\n", "\n", - "`SequentialAdder` 是由多个 `Adder` 顺序构成类,量子线路会经过 `SequentialAdder` 中的 `Adder` 依次处理,生成最终的量子线路。例如,我们想构建一个先在测量门前添加一个 $p=0.01$ 的比特翻转信道,然后在 `q1` 比特上的非测量门和非噪声信道后添加 $p=0.05$ 的比特翻转信道。\n", + "`SequentialAdder` 是由多个 `Adder` 顺序构成类,量子线路会经过 `SequentialAdder` 中的 `Adder` 依次处理,生成最终的量子线路。例如,我们想构建一个先在测量门前添加一个 $p=0.01$ 的比特翻转信道,然后在 `q1` 比特上的非测量门和非噪声信道后添加 $p=0.05$ 的去极化信道。\n", + "\n", + "### 自定义 `Adder`\n", "\n", "我们首先自定义在某个特比特添加比特翻转信道的 `Adder`" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -358,17 +381,18 @@ " MeasureAccepter<>\n", " BitFlipAdder\n", " >\n", - " CustomBitFlipAdder\n", + " CustomDepolarizingAdder\n", ">\n" ] } ], "source": [ "from mindquantum.core.circuit.channel_adder import ChannelAdderBase, SequentialAdder\n", - "class CustomBitFlipAdder(ChannelAdderBase):\n", - " def __init__(self, q, flip_rate):\n", + "\n", + "class CustomDepolarizingAdder(ChannelAdderBase):\n", + " def __init__(self, q, p):\n", " self.q = q\n", - " self.flip_rate = flip_rate\n", + " self.p = p\n", " super().__init__()\n", "\n", " def _accepter(self):\n", @@ -378,30 +402,30 @@ " return [lambda x: isinstance(x, (G.Measure, G.NoiseGate))]\n", "\n", " def _handler(self, g):\n", - " return Circuit([G.BitFlipChannel(self.flip_rate).on(self.q)])\n", + " return Circuit([G.DepolarizingChannel(self.p).on(self.q)])\n", "\n", " def __repr__(self):\n", - " return f\"CustomBitFlipAdder\"\n", + " return f\"CustomDepolarizingAdder\"\n", "\n", "seq_adder = SequentialAdder([\n", " MixerAdder([\n", " MeasureAccepter(),\n", " BitFlipAdder(flip_rate=0.01),\n", " ], add_after=False),\n", - " CustomBitFlipAdder(q=1, flip_rate=0.05),\n", + " CustomDepolarizingAdder(q=1, p=0.05),\n", "])\n", "print(seq_adder)" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ - "
\n", + "\n", "\n", "\n", "q0:\n", @@ -437,7 +461,7 @@ "\n", "\n", "\n", - "
" + "" ] }, "metadata": {}, @@ -446,16 +470,16 @@ { "data": { "image/svg+xml": [ - "
\n", - "\n", + "\n", + "\n", "\n", "q0:\n", " \n", "\n", "q1:\n", " \n", - "\n", - "\n", + "\n", + "\n", "\n", "\n", "\n", @@ -472,41 +496,50 @@ " \n", "\n", "\n", - "\n", - "\n", - "BFC\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/20\n", " \n", "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", "Z\n", " \n", "\n", "\n", - "\n", - "\n", - "BFC\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/20\n", " \n", "\n", "\n", - "\n", - "\n", + "\n", + "\n", "BFC\n", " \n", + "\n", + "p=1/100\n", + " \n", "\n", - "\n", - "\n", - "\n", - "\n", - "
" + "\n", + "\n", + "\n", + "\n", + "" ], "text/plain": [ - "" + "" ] }, - "execution_count": 6, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -519,24 +552,681 @@ ] }, { - "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "上述自定义量子信道也可以通过 MindQuantum 中的预定义信道搭建而成。" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "SequentialAdder<\n", + " MixerAdder<\n", + " MeasureAccepter<>\n", + " BitFlipAdder\n", + " >\n", + " MixerAdder<\n", + " ReverseAdder<\n", + " MeasureAccepter<>\n", + " >\n", + " NoiseExcluder<>\n", + " NoiseChannelAdder\n", + " >\n", + ">\n" + ] + } + ], + "source": [ + "from mindquantum.core.circuit import ReverseAdder, NoiseExcluder, NoiseChannelAdder\n", + "seq_adder = SequentialAdder([\n", + " MixerAdder([\n", + " MeasureAccepter(),\n", + " BitFlipAdder(flip_rate=0.01),\n", + " ], add_after=False),\n", + " MixerAdder([\n", + " ReverseAdder(MeasureAccepter()),\n", + " NoiseExcluder(),\n", + " NoiseChannelAdder(G.DepolarizingChannel(0.05), focus_on=1),\n", + " ])\n", + "])\n", + "print(seq_adder)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "q0:\n", + " \n", + "\n", + "q1:\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "H\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "a\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/20\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Z\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/20\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "BFC\n", + " \n", + "\n", + "p=1/100\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "seq_adder(circ).svg()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 更复杂的例子\n", + "\n", + "下面我们来搭建一个更复杂的 `ChannelAdder` 例子,在该例子中,芯片的不同比特上的单比特门操作的噪声可以忽略不记,而双比特门在不同比特上具有不同的去极化信道,且线路的测量具有一个翻转概率为0.01的比特翻转错误。\n", + "\n", + "我们假设不同比特上的去极化信道为:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "dc0 = G.DepolarizingChannel(0.01)\n", + "dc1 = G.DepolarizingChannel(0.02)\n", + "dc2 = G.DepolarizingChannel(0.03)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "然后,我们定义出满足要求的 `Adder`:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "SequentialAdder<\n", + " MixerAdder<\n", + " NoiseExcluder<>\n", + " ReverseAdder<\n", + " MeasureAccepter<>\n", + " >\n", + " QubitNumberConstrain\n", + " NoiseChannelAdder\n", + " >\n", + " MixerAdder<\n", + " NoiseExcluder<>\n", + " ReverseAdder<\n", + " MeasureAccepter<>\n", + " >\n", + " QubitNumberConstrain\n", + " NoiseChannelAdder\n", + " >\n", + " MixerAdder<\n", + " NoiseExcluder<>\n", + " ReverseAdder<\n", + " MeasureAccepter<>\n", + " >\n", + " QubitNumberConstrain\n", + " NoiseChannelAdder\n", + " >\n", + " MixerAdder<\n", + " NoiseExcluder<>\n", + " MeasureAccepter<>\n", + " BitFlipAdder\n", + " >\n", + ">" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from mindquantum.core.circuit import QubitNumberConstrain\n", + "noise_adder = SequentialAdder([\n", + " MixerAdder([\n", + " NoiseExcluder(),\n", + " ReverseAdder(MeasureAccepter()),\n", + " QubitNumberConstrain(2),\n", + " NoiseChannelAdder(dc0, focus_on=0),\n", + " ]),\n", + " MixerAdder([\n", + " NoiseExcluder(),\n", + " ReverseAdder(MeasureAccepter()),\n", + " QubitNumberConstrain(2),\n", + " NoiseChannelAdder(dc1, focus_on=1),\n", + " ]),\n", + " MixerAdder([\n", + " NoiseExcluder(),\n", + " ReverseAdder(MeasureAccepter()),\n", + " QubitNumberConstrain(2),\n", + " NoiseChannelAdder(dc2, focus_on=2),\n", + " ]),\n", + " MixerAdder([\n", + " NoiseExcluder(),\n", + " MeasureAccepter(),\n", + " BitFlipAdder(0.01)\n", + " ], add_after=False),\n", + "])\n", + "noise_adder" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "假设我们想要处理的量子线路是哈密顿量 $H=a_{01} Z_0Z_1 + a_{12} Z_1Z_2 + b_0 X_0 + b_1 X_1 + b_2 X_2$ 含时演化的一阶Trotter近似线路:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + " b_0 [X0] +\n", + " b_1 [X1] +\n", + " b_2 [X2] +\n", + "a_01 [Z0 Z1] +\n", + "a_12 [Z1 Z2]" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from mindquantum.core.operators import TimeEvolution, QubitOperator\n", + "\n", + "ham = sum([\n", + " QubitOperator('X0', 'b_0'),\n", + " QubitOperator('X1', 'b_1'),\n", + " QubitOperator('X2', 'b_2'),\n", + " QubitOperator('Z0 Z1', 'a_01'),\n", + " QubitOperator('Z1 Z2', 'a_12')\n", + "])\n", + "ham" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "q0:\n", + " \n", + "\n", + "q1:\n", + " \n", + "\n", + "q2:\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "2*b_0\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "2*b_1\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "2*b_2\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "RZ\n", + " \n", + "\n", + "2*a_01\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "RZ\n", + " \n", + "\n", + "2*a_12\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "circ = TimeEvolution(ham).circuit\n", + "circ.barrier()\n", + "circ.measure_all()\n", + "circ.svg()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "此线路经过上述定义的 `noise_adder` 处理后的量子线路为:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "q0:\n", + " \n", + "\n", + "q1:\n", + " \n", + "\n", + "q2:\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "2*b_0\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "2*b_1\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "2*b_2\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/50\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/100\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "RZ\n", + " \n", + "\n", + "2*a_01\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/50\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/100\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=0.03\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/50\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "RZ\n", + " \n", + "\n", + "2*a_12\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=0.03\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/50\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BFC\n", + " \n", + "\n", + "p=1/100\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BFC\n", + " \n", + "\n", + "p=1/100\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BFC\n", + " \n", + "\n", + "p=1/100\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "noise_adder(circ).svg()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### `ChannelAdder` 列表\n", + "\n", + "下面列举出 MindQuantum 中现有的一些 `ChannelAdder`,并给出具体含义:\n", + "\n", + "|`ChannelAdder`| 功能|\n", + "|--|--|\n", + "|ChannelAdderBase|在量子门前面或者后面添加信道|\n", + "|NoiseChannelAdder|添加一个单比特量子信道|\n", + "|MeasureAccepter|选取测量门|\n", + "|ReverseAdder|翻转给定信道添加器的接受和拒绝规则|\n", + "|NoiseExcluder|排除噪声门|\n", + "|BitFlipAdder|在量子门前面或者后面添加一个比特翻转信道|\n", + "|MixerAdder|在子添加器的接受集被满足、拒绝集被拒绝时依次执行所有的添加器|\n", + "|SequentialAdder|依次执行每一个添加器|\n", + "|QubitNumberConstrain|只将噪声信道作用在比特数为 ``n_qubits`` 的量子门上|\n", + "|QubitIDConstrain|只将噪声信道作用在给定比特序号的量子门上|\n", + "\n", + "MindQuantum 中 `ChannelAdder` 的API接口文档请参考:[channel_adder](https://mindspore.cn/mindquantum/docs/zh-CN/master/mindquantum.core.circuit.html#channel-adder)" + ] + }, + { "cell_type": "markdown", "metadata": {}, "source": [ "## 基于 `ChannelAdder` 的噪声模拟器\n", "\n", - "我们可以将如上定义的各种 `Adder` 与现有的模拟器组合,构成一个含噪声模拟器。更进一步,我们可以根据定义的芯片参数与拓扑图,生成一个针对该芯片的噪声模拟器。第二种正在开发中,这里先介绍第一种。" + "我们可以将如上定义的各种 `Adder` 与现有的模拟器组合,构成一个含噪声模拟器。" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ - "
\n", + "\n", "\n", "\n", "q0:\n", @@ -572,7 +1262,7 @@ "\n", "\n", "\n", - "
" + "" ] }, "metadata": {}, @@ -581,7 +1271,7 @@ { "data": { "image/svg+xml": [ - "
\n", + "\n", "\n", "\n", "Shots:\n", @@ -598,66 +1288,83 @@ "\n", "\n", "\n", - "0.155\n", + "0.153\n", " \n", "\n", "\n", "\n", - "0.31\n", + "0.306\n", " \n", "\n", "\n", "\n", - "0.465\n", + "0.459\n", " \n", "\n", "\n", "\n", - "0.62\n", + "0.612\n", " \n", "\n", "\n", "\n", - "0.774\n", + "0.765\n", " \n", "\n", "\n", "0\n", " \n", "\n", - "\n", - "\n", - "7745\n", + "\n", + "\n", + "7648\n", " \n", "\n", "1\n", " \n", "\n", - "\n", - "\n", - "2255\n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "2352\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", "probability\n", " \n", - "
" + "" ], "text/plain": [ - "" + "" ] }, "metadata": {}, "output_type": "display_data" - }, + } + ], + "source": [ + "from mindquantum.simulator import Simulator\n", + "from mindquantum.simulator.noise import NoiseBackend\n", + "\n", + "noiseless_sim = Simulator('mqvector', 2)\n", + "noiseless_circ = Circuit().h(0).rx(1.0, 1).z(1, 0).measure(1)\n", + "display_svg(noiseless_circ.svg())\n", + "res1 = noiseless_sim.sampling(noiseless_circ, shots=10000)\n", + "display(res1.svg())" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ { "data": { "image/svg+xml": [ - "
\n", + "\n", "\n", "\n", "Shots:\n", @@ -674,57 +1381,57 @@ "\n", "\n", "\n", - "0.142\n", + "0.148\n", " \n", "\n", "\n", "\n", - "0.284\n", + "0.297\n", " \n", "\n", "\n", "\n", - "0.427\n", + "0.445\n", " \n", "\n", "\n", "\n", - "0.569\n", + "0.594\n", " \n", "\n", "\n", "\n", - "0.711\n", + "0.742\n", " \n", "\n", "\n", "0\n", " \n", "\n", - "\n", - "\n", - "7112\n", + "\n", + "\n", + "7420\n", " \n", "\n", "1\n", " \n", "\n", - "\n", - "\n", - "2888\n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "2580\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", "probability\n", " \n", - "
" + "" ], "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -733,16 +1440,16 @@ { "data": { "image/svg+xml": [ - "
\n", - "\n", + "\n", + "\n", "\n", "q0:\n", " \n", "\n", "q1:\n", " \n", - "\n", - "\n", + "\n", + "\n", "\n", "\n", "\n", @@ -759,38 +1466,47 @@ " \n", "\n", "\n", - "\n", - "\n", - "BFC\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/20\n", " \n", "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", "Z\n", " \n", "\n", "\n", - "\n", - "\n", - "BFC\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/20\n", " \n", "\n", "\n", - "\n", - "\n", + "\n", + "\n", "BFC\n", " \n", + "\n", + "p=1/100\n", + " \n", "\n", - "\n", - "\n", - "\n", - "\n", - "
" + "\n", + "\n", + "\n", + "\n", + "" ], "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -798,17 +1514,6 @@ } ], "source": [ - "from mindquantum.simulator import Simulator\n", - "from mindquantum.simulator.noise import NoiseBackend\n", - "\n", - "noiseless_sim = Simulator('mqvector', 2)\n", - "noiseless_circ = Circuit().h(0).rx(1.0, 1).z(1, 0).measure(1)\n", - "display_svg(noiseless_circ.svg())\n", - "res1 = noiseless_sim.sampling(noiseless_circ, shots=10000)\n", - "display(res1.svg())\n", - "\n", - "\n", - "\n", "noise_sim = Simulator(NoiseBackend('mqvector', 2, seq_adder))\n", "res2 = noise_sim.sampling(noiseless_circ, shots=10000)\n", "display(res2.svg())\n", @@ -818,7 +1523,7 @@ ], "metadata": { "kernelspec": { - "display_name": "base", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -833,8 +1538,7 @@ "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.13" - }, - "orig_nbformat": 4 + } }, "nbformat": 4, "nbformat_minor": 2 diff --git a/docs/noise_simulator_en.ipynb b/docs/noise_simulator_en.ipynb new file mode 100644 index 000000000..9f5ba59d6 --- /dev/null +++ b/docs/noise_simulator_en.ipynb @@ -0,0 +1,1544 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Noise simulator\n", + "\n", + "[![Download Notebook](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/master/resource/_static/logo_notebook_en.png)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/master/mindquantum/en/mindspore_noise_simulator.ipynb) \n", + "[![Download Code](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/master/resource/_static/logo_download_code_en.png)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/master/mindquantum/en/mindspore_noise_simulator.py) \n", + "[![View source on Gitee](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/master/resource/_static/logo_source_en.png)](https://gitee.com/mindspore/docs/blob/master/docs/mindquantum/docs/source_en/noise_simulator.ipynb)\n", + "\n", + "## ChannelAdder\n", + "\n", + "`ChannelAdder` is a processor that can add specific channels at specific positions in the quantum circuit, such as adding a bit flip channel after a measurement gate. The `ChannelAdder` class mainly consists of three functions: `_accepter()`, `_excluder()`, and `_handler(BasicGate)`, whose functions are as follows:\n", + "\n", + "- `_accepter()`: Returns a list of functions called the accept rule set, where each accept rule function takes a quantum gate as input. When the function returns `True`, we can add a channel after that quantum gate.\n", + "\n", + "- `_excluder()`: Returns a list of functions called the reject rule set, where each reject rule function takes a quantum gate as input. When the function returns `True`, we reject adding a channel after that quantum gate.\n", + "\n", + "- `_handler(BasicGate)`: Takes a quantum gate as input and returns a section of the quantum circuit that represents a custom channel added after the input quantum gate.\n", + "\n", + "We redefine the `__call__` function of the `ChannelAdder` class and you can directly call `ChannelAdder` to generate the processed quantum circuit.\n", + "Here are several types of `ChannelAdder`.\n", + "\n", + "### BitFlipAdder\n", + "\n", + "The interface definition of `BitFlipAdder` is:\n", + "\n", + "```python\n", + "BitFlipAdder(flip_rate: float, with_ctrl=True, focus_on: int = None, add_after: bool = True)\n", + "```\n", + "This `Adder` adds a bit flip channel after a quantum gate. The arguments of the interface are:\n", + "\n", + "- **flip_rate** (float): The flip probability of the bit flip channel.\n", + "- **with_ctrl** (bool): Whether to add bits on control. Default value: ``True``.\n", + "- **focus_on** (bool): Only apply this noise channel to ``focus_on`` bits. If it is ``None``, it will act on all bits of the quantum gate. Default value: ``None``.\n", + "- **add_after** (bool): Whether to add the channel after the quantum gate. If it is ``False``, the channel will be added before the quantum gate. Default value: ``True``.\n", + "\n", + "For example, we can add a bit flip channel with a flip probability of ``0.3`` after each quantum gate in the given quantum circuit:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "q0:\n", + " \n", + "\n", + "q1:\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "H\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "a\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Z\n", + " \n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from mindquantum.core.circuit.channel_adder import BitFlipAdder\n", + "from mindquantum.core import gates as G\n", + "from mindquantum.core.circuit import Circuit\n", + "\n", + "circ = Circuit()+G.H(0)+G.RX('a').on(1)+G.Z(1, 0)\n", + "circ.svg()" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "q0:\n", + " \n", + "\n", + "q1:\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "H\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "BFC\n", + " \n", + "\n", + "p=3/10\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "a\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "BFC\n", + " \n", + "\n", + "p=3/10\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Z\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "BFC\n", + " \n", + "\n", + "p=3/10\n", + " \n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bit_flip_adder = BitFlipAdder(0.3, with_ctrl=False)\n", + "new_circ = bit_flip_adder(circ)\n", + "new_circ.svg()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### MeasureAccepter\n", + "\n", + "```python\n", + "MeasureAccepter()\n", + "```\n", + "\n", + "This `Adder` selects those measurement gates. It is currently only an `Accepter` and does not change any gates in the quantum circuit. It needs to be used with other `Adders` such as `MixerAdder`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### MixerAdder\n", + "\n", + "```python\n", + "MixerAdder(adders: typing.List[ChannelAdderBase])\n", + "```\n", + "\n", + "`MixerAdder` can mix multiple `Adder`s to ensure that the quantum gates are added in sequence according to the `_handler` generated by each `Adder` when the accept function set and reject function set of each quantum gate in each `Adder` are satisfied at the same time.\n", + "\n", + "For example, we can mix `BitFlipAdder` and `MeasureAccepter` mentioned above to achieve the function of adding bit flip channels only before measurement gates:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MixerAdder<\n", + " BitFlipAdder\n", + " MeasureAccepter<>\n", + ">\n" + ] + }, + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "q0:\n", + " \n", + "\n", + "q1:\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "H\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "a\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Z\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "q0:\n", + " \n", + "\n", + "q1:\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "H\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "a\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Z\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "BFC\n", + " \n", + "\n", + "p=1/100\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.display import display_svg\n", + "from mindquantum.core.circuit.channel_adder import MixerAdder, MeasureAccepter\n", + "\n", + "mixer = MixerAdder([\n", + " BitFlipAdder(flip_rate=0.01),\n", + " MeasureAccepter(),\n", + "], add_after=False)\n", + "print(mixer)\n", + "\n", + "circ = Circuit() + G.H(0) + G.RX('a').on(1) + G.Z(1, 0) + G.Measure().on(0)\n", + "display_svg(circ.svg())\n", + "new_circ = mixer(circ)\n", + "new_circ.svg()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### SequentialAdder\n", + "\n", + "```python\n", + "SequentialAdder(adders: typing.List[ChannelAdderBase])\n", + "```\n", + "\n", + "`SequentialAdder` is a class composed of multiple `Adder`s in sequence. The quantum circuit will be processed by the `Adder`s in `SequentialAdder` in turn to generate the final quantum circuit. For example, we want to construct a quantum circuit that first adds a bit flip channel with $p=0.01$ before the measurement gate, and then adds a depolarizing channel with $p=0.05$ after the non-measurement gate and non-noise channel on the `q1` bit.\n", + "\n", + "### Custom `Adder`\n", + "\n", + "First, we customize an `Adder` that adds a bit flip channel to a specific bit:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "SequentialAdder<\n", + " MixerAdder<\n", + " MeasureAccepter<>\n", + " BitFlipAdder\n", + " >\n", + " CustomDepolarizingAdder\n", + ">\n" + ] + } + ], + "source": [ + "from mindquantum.core.circuit.channel_adder import ChannelAdderBase, SequentialAdder\n", + "\n", + "class CustomDepolarizingAdder(ChannelAdderBase):\n", + " def __init__(self, q, p):\n", + " self.q = q\n", + " self.p = p\n", + " super().__init__()\n", + "\n", + " def _accepter(self):\n", + " return [lambda x: self.q in x.obj_qubits or self.q in x.ctrl_qubits]\n", + "\n", + " def _excluder(self):\n", + " return [lambda x: isinstance(x, (G.Measure, G.NoiseGate))]\n", + "\n", + " def _handler(self, g):\n", + " return Circuit([G.DepolarizingChannel(self.p).on(self.q)])\n", + "\n", + " def __repr__(self):\n", + " return f\"CustomDepolarizingAdder\"\n", + "\n", + "seq_adder = SequentialAdder([\n", + " MixerAdder([\n", + " MeasureAccepter(),\n", + " BitFlipAdder(flip_rate=0.01),\n", + " ], add_after=False),\n", + " CustomDepolarizingAdder(q=1, p=0.05),\n", + "])\n", + "print(seq_adder)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "q0:\n", + " \n", + "\n", + "q1:\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "H\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "a\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Z\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "q0:\n", + " \n", + "\n", + "q1:\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "H\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "a\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/20\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Z\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/20\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "BFC\n", + " \n", + "\n", + "p=1/100\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "circ = Circuit() + G.H(0) + G.RX('a').on(1) + G.Z(1, 0) + G.Measure().on(0)\n", + "display_svg(circ.svg())\n", + "new_circ = seq_adder(circ)\n", + "new_circ.svg()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The custom quantum channel above can also be constructed using the predefined channels in MindQuantum." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "SequentialAdder<\n", + " MixerAdder<\n", + " MeasureAccepter<>\n", + " BitFlipAdder\n", + " >\n", + " MixerAdder<\n", + " ReverseAdder<\n", + " MeasureAccepter<>\n", + " >\n", + " NoiseExcluder<>\n", + " NoiseChannelAdder\n", + " >\n", + ">\n" + ] + } + ], + "source": [ + "from mindquantum.core.circuit import ReverseAdder, NoiseExcluder, NoiseChannelAdder\n", + "seq_adder = SequentialAdder([\n", + " MixerAdder([\n", + " MeasureAccepter(),\n", + " BitFlipAdder(flip_rate=0.01),\n", + " ], add_after=False),\n", + " MixerAdder([\n", + " ReverseAdder(MeasureAccepter()),\n", + " NoiseExcluder(),\n", + " NoiseChannelAdder(G.DepolarizingChannel(0.05), focus_on=1),\n", + " ])\n", + "])\n", + "print(seq_adder)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "q0:\n", + " \n", + "\n", + "q1:\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "H\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "a\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/20\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Z\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/20\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "BFC\n", + " \n", + "\n", + "p=1/100\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "seq_adder(circ).svg()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### A more complex example:\n", + "\n", + "We now build a more complex `ChannelAdder` example where the noise of single qubit gate operations on different bits of the chip can be ignored, while the two qubit gates have different depolarizing channels on different bits, and the measurement of the circuit has a bit flip error with a flip probability of 0.01.\n", + "\n", + "We assume that the depolarizing channels on different bits are:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "dc0 = G.DepolarizingChannel(0.01)\n", + "dc1 = G.DepolarizingChannel(0.02)\n", + "dc2 = G.DepolarizingChannel(0.03)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then we define an `Adder` that meets the requirements:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "SequentialAdder<\n", + " MixerAdder<\n", + " NoiseExcluder<>\n", + " ReverseAdder<\n", + " MeasureAccepter<>\n", + " >\n", + " QubitNumberConstrain\n", + " NoiseChannelAdder\n", + " >\n", + " MixerAdder<\n", + " NoiseExcluder<>\n", + " ReverseAdder<\n", + " MeasureAccepter<>\n", + " >\n", + " QubitNumberConstrain\n", + " NoiseChannelAdder\n", + " >\n", + " MixerAdder<\n", + " NoiseExcluder<>\n", + " ReverseAdder<\n", + " MeasureAccepter<>\n", + " >\n", + " QubitNumberConstrain\n", + " NoiseChannelAdder\n", + " >\n", + " MixerAdder<\n", + " NoiseExcluder<>\n", + " MeasureAccepter<>\n", + " BitFlipAdder\n", + " >\n", + ">" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from mindquantum.core.circuit import QubitNumberConstrain\n", + "noise_adder = SequentialAdder([\n", + " MixerAdder([\n", + " NoiseExcluder(),\n", + " ReverseAdder(MeasureAccepter()),\n", + " QubitNumberConstrain(2),\n", + " NoiseChannelAdder(dc0, focus_on=0),\n", + " ]),\n", + " MixerAdder([\n", + " NoiseExcluder(),\n", + " ReverseAdder(MeasureAccepter()),\n", + " QubitNumberConstrain(2),\n", + " NoiseChannelAdder(dc1, focus_on=1),\n", + " ]),\n", + " MixerAdder([\n", + " NoiseExcluder(),\n", + " ReverseAdder(MeasureAccepter()),\n", + " QubitNumberConstrain(2),\n", + " NoiseChannelAdder(dc2, focus_on=2),\n", + " ]),\n", + " MixerAdder([\n", + " NoiseExcluder(),\n", + " MeasureAccepter(),\n", + " BitFlipAdder(0.01)\n", + " ], add_after=False),\n", + "])\n", + "noise_adder" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Suppose the quantum circuit we want to process is the first-order Trotter approximation circuit of the time-evolving Hamiltonian\n", + "\n", + "$$H=a_{01} Z_0Z_1 + a_{12} Z_1Z_2 + b_0 X_0 + b_1 X_1 + b_2 X_2$$" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + " b_0 [X0] +\n", + " b_1 [X1] +\n", + " b_2 [X2] +\n", + "a_01 [Z0 Z1] +\n", + "a_12 [Z1 Z2]" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from mindquantum.core.operators import TimeEvolution, QubitOperator\n", + "\n", + "ham = sum([\n", + " QubitOperator('X0', 'b_0'),\n", + " QubitOperator('X1', 'b_1'),\n", + " QubitOperator('X2', 'b_2'),\n", + " QubitOperator('Z0 Z1', 'a_01'),\n", + " QubitOperator('Z1 Z2', 'a_12')\n", + "])\n", + "ham" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "q0:\n", + " \n", + "\n", + "q1:\n", + " \n", + "\n", + "q2:\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "2*b_0\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "2*b_1\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "2*b_2\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "RZ\n", + " \n", + "\n", + "2*a_01\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "RZ\n", + " \n", + "\n", + "2*a_12\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "circ = TimeEvolution(ham).circuit\n", + "circ.barrier()\n", + "circ.measure_all()\n", + "circ.svg()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is the processed quantum circuit after being processed by the ``noise_adder`` defined above:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "q0:\n", + " \n", + "\n", + "q1:\n", + " \n", + "\n", + "q2:\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "2*b_0\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "2*b_1\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "2*b_2\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/50\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/100\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "RZ\n", + " \n", + "\n", + "2*a_01\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/50\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/100\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=0.03\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/50\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "RZ\n", + " \n", + "\n", + "2*a_12\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=0.03\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/50\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BFC\n", + " \n", + "\n", + "p=1/100\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BFC\n", + " \n", + "\n", + "p=1/100\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BFC\n", + " \n", + "\n", + "p=1/100\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "noise_adder(circ).svg()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### `ChannelAdder` list\n", + "\n", + "Here are some of the existing `ChannelAdder`s in MindQuantum and their specific meanings:\n", + "\n", + "|`ChannelAdder`| Function|\n", + "|--|--|\n", + "|ChannelAdderBase|Add channels before or after quantum gates|\n", + "|NoiseChannelAdder|Add a single-bit quantum channel|\n", + "|MeasureAccepter|Select measurement gates|\n", + "|ReverseAdder|Flip the accept and reject rules of the given channel adder|\n", + "|NoiseExcluder|Exclude noise gates|\n", + "|BitFlipAdder|Add a bit flip channel before or after the quantum gate|\n", + "|MixerAdder|Execute all adders in sequence when the accept and reject sets of the sub-adders are met|\n", + "|SequentialAdder|Execute each adder in sequence|\n", + "|QubitNumberConstrain|Only apply noise channels to quantum gates with ``n_qubits`` bits|\n", + "|QubitIDConstrain|Only apply noise channels to quantum gates with the given bit number|\n", + "\n", + "For API documentation of `ChannelAdder` in MindQuantum, please refer to: [channel_adder](https://www.mindspore.cn/mindquantum/docs/en/master/mindquantum.core.circuit.html#channel-adder)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Noise simulator based on `ChannelAdder`\n", + "\n", + "We can combine the various `Adder` defined above with existing simulators to create a noisy simulator." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "q0:\n", + " \n", + "\n", + "q1:\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "H\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "1\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Z\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "Shots:\n", + " 10000\n", + " \n", + "\n", + "Keys: q1\n", + " \n", + "\n", + "\n", + "\n", + "0.0\n", + " \n", + "\n", + "\n", + "\n", + "0.153\n", + " \n", + "\n", + "\n", + "\n", + "0.306\n", + " \n", + "\n", + "\n", + "\n", + "0.459\n", + " \n", + "\n", + "\n", + "\n", + "0.612\n", + " \n", + "\n", + "\n", + "\n", + "0.765\n", + " \n", + "\n", + "\n", + "0\n", + " \n", + "\n", + "\n", + "\n", + "7652\n", + " \n", + "\n", + "1\n", + " \n", + "\n", + "\n", + "\n", + "2348\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "probability\n", + " \n", + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from mindquantum.simulator import Simulator\n", + "from mindquantum.simulator.noise import NoiseBackend\n", + "\n", + "noiseless_sim = Simulator('mqvector', 2)\n", + "noiseless_circ = Circuit().h(0).rx(1.0, 1).z(1, 0).measure(1)\n", + "display_svg(noiseless_circ.svg())\n", + "res1 = noiseless_sim.sampling(noiseless_circ, shots=10000)\n", + "display(res1.svg())" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "Shots:\n", + " 10000\n", + " \n", + "\n", + "Keys: q1\n", + " \n", + "\n", + "\n", + "\n", + "0.0\n", + " \n", + "\n", + "\n", + "\n", + "0.147\n", + " \n", + "\n", + "\n", + "\n", + "0.295\n", + " \n", + "\n", + "\n", + "\n", + "0.442\n", + " \n", + "\n", + "\n", + "\n", + "0.59\n", + " \n", + "\n", + "\n", + "\n", + "0.737\n", + " \n", + "\n", + "\n", + "0\n", + " \n", + "\n", + "\n", + "\n", + "7370\n", + " \n", + "\n", + "1\n", + " \n", + "\n", + "\n", + "\n", + "2630\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "probability\n", + " \n", + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "q0:\n", + " \n", + "\n", + "q1:\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "H\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "RX\n", + " \n", + "\n", + "1\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/20\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Z\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "DC\n", + " \n", + "\n", + "p=1/20\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "BFC\n", + " \n", + "\n", + "p=1/100\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "noise_sim = Simulator(NoiseBackend('mqvector', 2, seq_adder))\n", + "res2 = noise_sim.sampling(noiseless_circ, shots=10000)\n", + "display(res2.svg())\n", + "display(noise_sim.backend.transform_circ(noiseless_circ).svg())" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From abff2159bebb75768a49629fd8719918dcc8e916 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Mon, 24 Jul 2023 16:13:13 +0800 Subject: [PATCH 019/100] fix typo --- docs/noise_simulator_en.ipynb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/noise_simulator_en.ipynb b/docs/noise_simulator_en.ipynb index 9f5ba59d6..47a354381 100644 --- a/docs/noise_simulator_en.ipynb +++ b/docs/noise_simulator_en.ipynb @@ -30,6 +30,7 @@ "```python\n", "BitFlipAdder(flip_rate: float, with_ctrl=True, focus_on: int = None, add_after: bool = True)\n", "```\n", + "\n", "This `Adder` adds a bit flip channel after a quantum gate. The arguments of the interface are:\n", "\n", "- **flip_rate** (float): The flip probability of the bit flip channel.\n", @@ -686,7 +687,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### A more complex example:\n", + "### A more complex example\n", "\n", "We now build a more complex `ChannelAdder` example where the noise of single qubit gate operations on different bits of the chip can be ignored, while the two qubit gates have different depolarizing channels on different bits, and the measurement of the circuit has a bit flip error with a flip probability of 0.01.\n", "\n", From 44654fc7ee91108e6374a325df022a4ec4a08381 Mon Sep 17 00:00:00 2001 From: donghufeng Date: Mon, 24 Jul 2023 22:19:54 +0800 Subject: [PATCH 020/100] compress svg string --- mindquantum/io/display/circuit_svg_drawer.py | 6 +++--- tests/st/test_io/test_svg.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mindquantum/io/display/circuit_svg_drawer.py b/mindquantum/io/display/circuit_svg_drawer.py index 479610c13..bf155e59b 100644 --- a/mindquantum/io/display/circuit_svg_drawer.py +++ b/mindquantum/io/display/circuit_svg_drawer.py @@ -373,7 +373,7 @@ def scale(self, scale): def to_string(self): """Return the string format of text svg.""" - return ' '.join([self.head] + self._prop_to_str() + [f'>\n{self.text}\n'] + [self.tail]) + return ' '.join([self.head] + self._prop_to_str() + [f'>{self.text}'] + [self.tail]) def dominant_baseline(self, dominant_baseline): """Set dominant baseline of text.""" @@ -648,7 +648,7 @@ def shift(self, x, y): def to_string(self): """Convert whole svg to a string.""" - return '\n'.join([i.to_string() for i in self.element]) + return ''.join([i.to_string() for i in self.element]) def _repr_svg_(self): """Magic method for rendering svg in jupyter notebook.""" @@ -660,7 +660,7 @@ def _repr_svg_(self): f"xmlns:xlink=\"http://www.w3.org/1999/xlink\">" ) tail = "" - return f"{head}\n{self.to_string()}\n{tail}" + return f"{head}{self.to_string()}{tail}" def to_file(self, filename='circuit.svg'): """Save svg file.""" diff --git a/tests/st/test_io/test_svg.py b/tests/st/test_io/test_svg.py index fc7d358ab..e99e9136a 100644 --- a/tests/st/test_io/test_svg.py +++ b/tests/st/test_io/test_svg.py @@ -29,7 +29,7 @@ def test_measure_svg(): res = sim.sampling(circ, shots=100, seed=42) text = res.svg()._repr_svg_().split('bar') # pylint: disable=protected-access text = "bar".join([text[0]] + ['"'.join(i.split('"')[1:]) for i in text[1:]]) - len_text_exp = 9380 + len_text_exp = 9257 assert len(text) == len_text_exp @@ -40,4 +40,4 @@ def test_circuit_svg(): """ # pylint: disable=protected-access text = (qft(range(3)) + RX({'a': 1.2}).on(1) + BarrierGate()).measure_all().svg()._repr_svg_().strip() - assert len(text) in (7079, 7078, 7130, 7033) + assert len(text) in (7079, 7078, 7130, 7033, 6941) From 247c422bbadd6e17e8c8b0379a3ed7b066fe2c69 Mon Sep 17 00:00:00 2001 From: donghufeng Date: Wed, 26 Jul 2023 00:29:39 +0800 Subject: [PATCH 021/100] add more ansatz --- mindquantum/algorithm/nisq/qnn/__init__.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/mindquantum/algorithm/nisq/qnn/__init__.py b/mindquantum/algorithm/nisq/qnn/__init__.py index 699cec628..88d724080 100644 --- a/mindquantum/algorithm/nisq/qnn/__init__.py +++ b/mindquantum/algorithm/nisq/qnn/__init__.py @@ -12,10 +12,24 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================ - """Algorithm for IQP Encoding.""" +from . import arxiv_1905_10876 +from .arxiv_1905_10876 import ( + Ansatz1, + Ansatz2, + Ansatz3, + Ansatz4, + Ansatz5, + Ansatz6, + Ansatz7, + Ansatz8, + Ansatz9, + Ansatz10, +) from .iqp_encoding import IQPEncoding from .strongly_entangling import StronglyEntangling __all__ = ['IQPEncoding', 'StronglyEntangling'] +__all__.extend(arxiv_1905_10876.__all__) +__all__.sort() From 1108a5b56db7ca59c8eaeaa02efcd069cb7d8daa Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Wed, 26 Jul 2023 09:26:35 +0800 Subject: [PATCH 022/100] fix repeat of qubits --- mindquantum/core/gates/basic.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mindquantum/core/gates/basic.py b/mindquantum/core/gates/basic.py index 182df7c8c..7d83b356a 100644 --- a/mindquantum/core/gates/basic.py +++ b/mindquantum/core/gates/basic.py @@ -185,6 +185,10 @@ def on(self, obj_qubits, ctrl_qubits=None): # pylint: disable=invalid-name _check_input_type("ctrl_qubits", (int, Iterable), ctrl_qubits) if set(obj_qubits) & set(ctrl_qubits): raise ValueError("Obj_qubit and ctrl_qubit cannot have same qubits.") + if len(set(obj_qubits)) != len(obj_qubits): + raise ValueError("obj_qubits cannot be repeated.") + if len(set(ctrl_qubits)) != len(ctrl_qubits): + raise ValueError("ctrl_qubits cannot be repeated.") if self.n_qubits: if len(obj_qubits) != self.n_qubits: raise ValueError( From 09c7bc62a76ae79c3571da6bf5a2dcd30306f67d Mon Sep 17 00:00:00 2001 From: huan <3174348550@qq.com> Date: Wed, 26 Jul 2023 11:37:49 +0800 Subject: [PATCH 023/100] modify the error links in mindquantum --- .../advanced_operations_of_quantum_circuit_en.ipynb | 3 +-- docs/source_en/quantum_measurement_en.ipynb | 3 +-- docs/source_en/quantum_simulator _en.ipynb | 3 +-- tutorials/0.frequently_asked_questions.ipynb | 4 +--- tutorials/advanced_operations_of_quantum_circuit.ipynb | 3 +-- tutorials/bloch_sphere.ipynb | 3 +-- tutorials/classification_of_iris_by_qnn.ipynb | 3 +-- tutorials/get_gradient_of_PQC_with_mindquantum.ipynb | 7 ------- tutorials/grover_search_algorithm.ipynb | 2 -- .../initial_experience_of_quantum_neural_network.ipynb | 3 +-- tutorials/parameterized_quantum_circuit.ipynb | 3 +-- tutorials/quantum_measurement.ipynb | 3 +-- tutorials/quantum_simulator.ipynb | 3 +-- tutorials/shor_algorithm.ipynb | 3 +-- 14 files changed, 12 insertions(+), 34 deletions(-) diff --git a/docs/source_en/advanced_operations_of_quantum_circuit_en.ipynb b/docs/source_en/advanced_operations_of_quantum_circuit_en.ipynb index 3e8ecbb90..2e393bd1c 100644 --- a/docs/source_en/advanced_operations_of_quantum_circuit_en.ipynb +++ b/docs/source_en/advanced_operations_of_quantum_circuit_en.ipynb @@ -727,8 +727,7 @@ "Finally, we use the add_prefix method to prefix the parameter names of all parameter quantum gates constructed by shift with a number.\n", "\n", "So far, through these advanced operations of quantum circuit provided by MindQuantum, we have built the required Encoder with only two lines of code!\n", - "\n", - "For more information about MindQuantum API, please click: [https://mindspore.cn/mindquantum/](https://mindspore.cn/mindquantum/)." + "\n" ] } ], diff --git a/docs/source_en/quantum_measurement_en.ipynb b/docs/source_en/quantum_measurement_en.ipynb index 8fc5f8cb4..feae76229 100644 --- a/docs/source_en/quantum_measurement_en.ipynb +++ b/docs/source_en/quantum_measurement_en.ipynb @@ -961,8 +961,7 @@ "We learned to recognize an important operation in quantum computing - measurement, used MindQuantum to measure quantum circuits to verify our theoretical results, and used different visualization tools to display the measurement results.\n", "\n", "To learn higher-level operations on quantum circuits in MindQuantum, build and train quantum-classical hybrid neural networks, see the documentation for `get_expectation_with_grad()` and `apply_hamitonian()`.\n", - "\n", - "For more information about MindQuantum API, please click: [https://mindspore.cn/mindquantum/](https://mindspore.cn/mindquantum/)." + "\n" ] } ], diff --git a/docs/source_en/quantum_simulator _en.ipynb b/docs/source_en/quantum_simulator _en.ipynb index dbccc907f..dfbeffaa0 100644 --- a/docs/source_en/quantum_simulator _en.ipynb +++ b/docs/source_en/quantum_simulator _en.ipynb @@ -553,8 +553,7 @@ "We can see that '00' appears 495 times and '11' appears 505 times in the sampling result. In fact, the RY gate parameter is assigned to 0, which is the I gate and equivalent to not doing any operation on the circuit. Therefore, the sampling circuit is essentially the same as the above Non-parameterized circuit. It can be observed that the results of two times sampling are almost the same, as expected.\n", "\n", "If you want to learn more about how to measure quantum circuits and understand the theoretical explanation of the distribution of sampling results, please click: [Quantum Measurement Tutorial](https://gitee.com/buyulin/mindquantum/blob/master/tutorials/quantum_measurement.ipynb ).\n", - "\n", - "For more information about MindQuantum API, please click: [https://mindspore.cn/mindquantum/](https://mindspore.cn/mindquantum/)." + "\n" ] } ], diff --git a/tutorials/0.frequently_asked_questions.ipynb b/tutorials/0.frequently_asked_questions.ipynb index 810620b1f..440762b15 100644 --- a/tutorials/0.frequently_asked_questions.ipynb +++ b/tutorials/0.frequently_asked_questions.ipynb @@ -46,7 +46,6 @@ } ], "source": [ - "import mindquantum as mq\n", "from mindquantum import X\n", "\n", "X.on(1, 0)" @@ -395,8 +394,7 @@ "![](./images/error_circuit.png)\n", "\n", "这个时候,我们只需要打开浏览器的设置,找到“外观”,找到“自定义字体”,然后在“宽度固定的字体”(有的浏览器为“等宽字体”)下,选择“Consolas”字体即可。此外,用户还可以下载并安装开源的[Fira Code](https://github.com/tonsky/FiraCode)字体来获得更优质的输出。当我们设置好等宽字体后,就可以看到最开始打印的量子线路了。(如下网址提供了一些等宽字体供用户自行选择[https://zhuanlan.zhihu.com/p/116230037/](https://zhuanlan.zhihu.com/p/116230037/))\n", - "\n", - "若想查询更多关于MindQuantum的API,请点击:[https://mindspore.cn/mindquantum/](https://mindspore.cn/mindquantum/)。" + "\n" ] } ], diff --git a/tutorials/advanced_operations_of_quantum_circuit.ipynb b/tutorials/advanced_operations_of_quantum_circuit.ipynb index 73a584492..9eb7f5f53 100644 --- a/tutorials/advanced_operations_of_quantum_circuit.ipynb +++ b/tutorials/advanced_operations_of_quantum_circuit.ipynb @@ -716,8 +716,7 @@ "最后,我们使用add_prefix方法为通过shift构造的所有含参量子门的参数名加上一个数字前缀。\n", "\n", "至此,通过MindQuantum提供的这些量子线路高阶操作,我们仅用两行代码就构建了所需的Encoder!\n", - "\n", - "若想查询更多关于MindQuantum的API,请点击:[https://mindspore.cn/mindquantum/](https://mindspore.cn/mindquantum/)。" + "\n" ] } ], diff --git a/tutorials/bloch_sphere.ipynb b/tutorials/bloch_sphere.ipynb index dbaaff060..a71632429 100644 --- a/tutorials/bloch_sphere.ipynb +++ b/tutorials/bloch_sphere.ipynb @@ -316,8 +316,7 @@ "![bloch-sphere-anim](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/master/docs/mindquantum/docs/source_zh_cn/images/bloch_sphere.gif)\n", "\n", "由此,我们可以看到单比特的量子态在布洛赫球中已经动起来了。\n", - "\n", - "若想查询更多关于MindQuantum的API,请点击:[https://mindspore.cn/mindquantum/](https://mindspore.cn/mindquantum/)。" + "\n" ] } ], diff --git a/tutorials/classification_of_iris_by_qnn.ipynb b/tutorials/classification_of_iris_by_qnn.ipynb index cb6c95e8d..b5144de16 100644 --- a/tutorials/classification_of_iris_by_qnn.ipynb +++ b/tutorials/classification_of_iris_by_qnn.ipynb @@ -723,8 +723,7 @@ "从上述打印的可以看到,预测分类结果和实际分类结果完全一致,模型预测的准确率达到了100%。\n", "\n", "至此,我们体验了如何通过搭建量子神经网络来解决经典机器学习中的经典问题——鸢尾花分类问题。相信大家也对使用MindQuantum有了更进一步的了解!期待大家挖掘更多的问题,充分发挥MindQuantum强大的功能!\n", - "\n", - "若想查询更多关于MindQuantum的API,请点击:[https://mindspore.cn/mindquantum/](https://mindspore.cn/mindquantum/)。" + "\n" ] } ], diff --git a/tutorials/get_gradient_of_PQC_with_mindquantum.ipynb b/tutorials/get_gradient_of_PQC_with_mindquantum.ipynb index 9ba7c94bf..3fe19ad27 100644 --- a/tutorials/get_gradient_of_PQC_with_mindquantum.ipynb +++ b/tutorials/get_gradient_of_PQC_with_mindquantum.ipynb @@ -554,13 +554,6 @@ "source": [ "print(circuit.get_qs(pr=rot_angle, ket=True))" ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "若想查询更多关于MindQuantum的API,请点击:[https://mindspore.cn/mindquantum/](https://mindspore.cn/mindquantum/)。" - ] } ], "metadata": { diff --git a/tutorials/grover_search_algorithm.ipynb b/tutorials/grover_search_algorithm.ipynb index 08058ea72..7192cc62b 100644 --- a/tutorials/grover_search_algorithm.ipynb +++ b/tutorials/grover_search_algorithm.ipynb @@ -942,8 +942,6 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "若想查询更多关于MindQuantum的API,请点击:[https://mindspore.cn/mindquantum/](https://mindspore.cn/mindquantum/)。\n", - "\n", "### **参考文献:**\n", "\n", "\\[1\\] L. K. Grover, A fast quantum mechanical algorithm for database search\\[C\\]// Proceedings of the twenty-eighth annual ACM symposium on Theory of computing. ACM, 1996: 212-219.\n", diff --git a/tutorials/initial_experience_of_quantum_neural_network.ipynb b/tutorials/initial_experience_of_quantum_neural_network.ipynb index c8fd87afc..4db8c675e 100644 --- a/tutorials/initial_experience_of_quantum_neural_network.ipynb +++ b/tutorials/initial_experience_of_quantum_neural_network.ipynb @@ -654,8 +654,7 @@ "综上所述,我们搭建了一个简单的量子神经网络,通过训练Ansatz中的参数,抵消了Encoder对初始量子态产生的误差,使得最后的量子态仍为$|0\\rangle$​,且保真度达到100.00%。\n", "\n", "至此,我们通过MindQuantum完成了对量子神经网络的初体验!赶紧动手体验一下量子编程的乐趣吧!\n", - "\n", - "若想查询更多关于MindQuantum的API,请点击:[https://mindspore.cn/mindquantum/](https://mindspore.cn/mindquantum/)。" + "\n" ] } ], diff --git a/tutorials/parameterized_quantum_circuit.ipynb b/tutorials/parameterized_quantum_circuit.ipynb index 12b3c25ed..3379d8d12 100644 --- a/tutorials/parameterized_quantum_circuit.ipynb +++ b/tutorials/parameterized_quantum_circuit.ipynb @@ -491,8 +491,7 @@ "从对Encoder的Summary中可以看到,该量子线路由3个量子门组成,其中有1个含参量子门且参数为theta,该量子线路调控的量子比特数为3。\n", "\n", "因此,我们可以根据自身所需求解的问题,搭建对应的量子线路。赶紧动手搭建属于你的第一个量子线路吧!\n", - "\n", - "若想查询更多关于MindQuantum的API,请点击:[https://mindspore.cn/mindquantum/](https://mindspore.cn/mindquantum/)。" + "\n" ] } ], diff --git a/tutorials/quantum_measurement.ipynb b/tutorials/quantum_measurement.ipynb index ef067eadf..8f89cc1ca 100644 --- a/tutorials/quantum_measurement.ipynb +++ b/tutorials/quantum_measurement.ipynb @@ -949,8 +949,7 @@ "我们学习认识了量子计算中重要的一个操作——测量,还使用MindQuantum测量量子线路验证我们的理论结果,并使用不同可视化工具展示出测量结果。\n", "\n", "想学习MindQuantum中量子线路的高阶操作,构建并训练量子经典混合神经网络,请查看`get_expectation_with_grad()`和`apply_hamitonian()`的文档。\n", - "\n", - "若想查询更多关于MindQuantum的API,请点击:[https://mindspore.cn/mindquantum/](https://mindspore.cn/mindquantum/)。" + "\n" ] } ], diff --git a/tutorials/quantum_simulator.ipynb b/tutorials/quantum_simulator.ipynb index 25dcb81a8..9d8e0ee49 100644 --- a/tutorials/quantum_simulator.ipynb +++ b/tutorials/quantum_simulator.ipynb @@ -541,8 +541,7 @@ "我们可以看到,采样结果中'00'出现了513次,'11'出现了487次。事实上把RY门参数赋值为0,它即为我们熟悉的I门,相当于不对线路做任何操作,因此该采样线路与上面不含参线路本质是同一个,可以观察到二次采样结果几乎相同,符合预期结果。\n", "\n", "想进一步学习如何对量子线路做测量操作,想了解采样结果分布的理论解释,请点击:[量子测量教程](https://www.mindspore.cn/mindquantum/docs/zh-CN/master/quantum_measurement.html)。\n", - "\n", - "若想查询更多关于MindQuantum的API,请点击:[https://mindspore.cn/mindquantum/](https://mindspore.cn/mindquantum/)。" + "\n" ] } ], diff --git a/tutorials/shor_algorithm.ipynb b/tutorials/shor_algorithm.ipynb index d61b26419..accfc18be 100644 --- a/tutorials/shor_algorithm.ipynb +++ b/tutorials/shor_algorithm.ipynb @@ -500,8 +500,7 @@ "从运行结果可以看到,我们成功的分解出15的两个质因数:3和5。\n", "\n", "至此,我们成功的使用MindQuantum实现了Shor算法。\n", - "\n", - "若想查询更多关于MindQuantum的API,请点击:[https://mindspore.cn/mindquantum/](https://mindspore.cn/mindquantum/)。" + "\n" ] } ], From 6115420b5a25628b33f69b67f418bfbf91384535 Mon Sep 17 00:00:00 2001 From: donghufeng Date: Thu, 27 Jul 2023 00:13:21 +0800 Subject: [PATCH 024/100] add more ansatz --- .../mindquantum.algorithm.nisq.Ansatz1.rst | 15 + .../mindquantum.algorithm.nisq.Ansatz10.rst | 15 + .../mindquantum.algorithm.nisq.Ansatz11.rst | 15 + .../mindquantum.algorithm.nisq.Ansatz12.rst | 15 + .../mindquantum.algorithm.nisq.Ansatz13.rst | 15 + .../mindquantum.algorithm.nisq.Ansatz14.rst | 15 + .../mindquantum.algorithm.nisq.Ansatz15.rst | 15 + .../mindquantum.algorithm.nisq.Ansatz16.rst | 15 + .../mindquantum.algorithm.nisq.Ansatz17.rst | 15 + .../mindquantum.algorithm.nisq.Ansatz18.rst | 15 + .../mindquantum.algorithm.nisq.Ansatz19.rst | 15 + .../mindquantum.algorithm.nisq.Ansatz2.rst | 15 + .../mindquantum.algorithm.nisq.Ansatz3.rst | 15 + .../mindquantum.algorithm.nisq.Ansatz4.rst | 15 + .../mindquantum.algorithm.nisq.Ansatz5.rst | 15 + .../mindquantum.algorithm.nisq.Ansatz6.rst | 15 + .../mindquantum.algorithm.nisq.Ansatz7.rst | 15 + .../mindquantum.algorithm.nisq.Ansatz8.rst | 15 + .../mindquantum.algorithm.nisq.Ansatz9.rst | 15 + .../api_python/mindquantum.algorithm.nisq.rst | 19 + ...tum.core.parameterresolver.PRGenerator.rst | 20 + .../mindquantum.core.parameterresolver.rst | 1 + .../mindquantum.algorithm.nisq.rst | 19 + mindquantum/algorithm/nisq/_ansatz.py | 33 + mindquantum/algorithm/nisq/qnn/__init__.py | 9 + .../algorithm/nisq/qnn/arxiv_1905_10876.py | 943 ++++++++++++++++++ .../core/parameterresolver/__init__.py | 3 +- .../core/parameterresolver/pr_generator.py | 75 ++ 28 files changed, 1406 insertions(+), 1 deletion(-) create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz1.rst create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz10.rst create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz11.rst create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz12.rst create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz13.rst create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz14.rst create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz15.rst create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz16.rst create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz17.rst create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz18.rst create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz19.rst create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz2.rst create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz3.rst create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz4.rst create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz5.rst create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz6.rst create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz7.rst create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz8.rst create mode 100644 docs/api_python/mindquantum.algorithm.nisq.Ansatz9.rst create mode 100644 docs/api_python/mindquantum.core.parameterresolver.PRGenerator.rst create mode 100644 mindquantum/algorithm/nisq/qnn/arxiv_1905_10876.py create mode 100644 mindquantum/core/parameterresolver/pr_generator.py diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz1.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz1.rst new file mode 100644 index 000000000..823d62252 --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz1.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz1 +================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz1(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路1。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz10.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz10.rst new file mode 100644 index 000000000..339cf66d2 --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz10.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz10 +=================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz10(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路10。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz11.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz11.rst new file mode 100644 index 000000000..a370c1e7d --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz11.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz11 +=================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz11(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路11。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz12.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz12.rst new file mode 100644 index 000000000..33338f759 --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz12.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz12 +=================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz12(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路12。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz13.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz13.rst new file mode 100644 index 000000000..7a26c1564 --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz13.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz13 +=================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz13(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路13。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz14.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz14.rst new file mode 100644 index 000000000..2993c70a6 --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz14.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz14 +=================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz14(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路14。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz15.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz15.rst new file mode 100644 index 000000000..3b486c851 --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz15.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz15 +=================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz15(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路15。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz16.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz16.rst new file mode 100644 index 000000000..83c4550da --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz16.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz16 +=================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz16(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路16。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz17.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz17.rst new file mode 100644 index 000000000..04bd93988 --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz17.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz17 +=================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz17(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路17。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz18.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz18.rst new file mode 100644 index 000000000..e76ff2c44 --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz18.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz18 +=================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz18(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路18。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz19.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz19.rst new file mode 100644 index 000000000..8ea7d6db4 --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz19.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz19 +=================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz19(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路19。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz2.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz2.rst new file mode 100644 index 000000000..d68bdad21 --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz2.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz2 +================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz2(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路2。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz3.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz3.rst new file mode 100644 index 000000000..73337ec83 --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz3.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz3 +================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz3(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路3。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz4.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz4.rst new file mode 100644 index 000000000..64f699840 --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz4.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz4 +================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz4(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路4。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz5.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz5.rst new file mode 100644 index 000000000..7b219d6ff --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz5.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz5 +================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz5(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路5。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz6.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz6.rst new file mode 100644 index 000000000..849925c79 --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz6.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz6 +================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz6(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路6。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz7.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz7.rst new file mode 100644 index 000000000..51ac0efe2 --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz7.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz7 +================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz7(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路7。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz8.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz8.rst new file mode 100644 index 000000000..8a96965ff --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz8.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz8 +================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz8(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路8。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.Ansatz9.rst b/docs/api_python/mindquantum.algorithm.nisq.Ansatz9.rst new file mode 100644 index 000000000..b194fd343 --- /dev/null +++ b/docs/api_python/mindquantum.algorithm.nisq.Ansatz9.rst @@ -0,0 +1,15 @@ +mindquantum.algorithm.nisq.Ansatz9 +================================== + +.. py:class:: mindquantum.algorithm.nisq.Ansatz9(n_qubits: int, depth: int, prefix: str = '', subfix: str = '') + + Arxiv 论文中所提及的量子线路9。 + + 请参考论文 `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + 参数: + - **n_qubits** (int) - 量子线路的总比特数。 + - **depth** (int) - ansatz 的循环层数。 + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 diff --git a/docs/api_python/mindquantum.algorithm.nisq.rst b/docs/api_python/mindquantum.algorithm.nisq.rst index 3892d4a76..e54c01883 100644 --- a/docs/api_python/mindquantum.algorithm.nisq.rst +++ b/docs/api_python/mindquantum.algorithm.nisq.rst @@ -40,6 +40,25 @@ Ansatz mindquantum.algorithm.nisq.QubitUCCAnsatz mindquantum.algorithm.nisq.StronglyEntangling mindquantum.algorithm.nisq.UCCAnsatz + mindquantum.algorithm.nisq.Ansatz1 + mindquantum.algorithm.nisq.Ansatz2 + mindquantum.algorithm.nisq.Ansatz3 + mindquantum.algorithm.nisq.Ansatz4 + mindquantum.algorithm.nisq.Ansatz5 + mindquantum.algorithm.nisq.Ansatz6 + mindquantum.algorithm.nisq.Ansatz7 + mindquantum.algorithm.nisq.Ansatz8 + mindquantum.algorithm.nisq.Ansatz9 + mindquantum.algorithm.nisq.Ansatz10 + mindquantum.algorithm.nisq.Ansatz11 + mindquantum.algorithm.nisq.Ansatz12 + mindquantum.algorithm.nisq.Ansatz13 + mindquantum.algorithm.nisq.Ansatz14 + mindquantum.algorithm.nisq.Ansatz15 + mindquantum.algorithm.nisq.Ansatz16 + mindquantum.algorithm.nisq.Ansatz17 + mindquantum.algorithm.nisq.Ansatz18 + mindquantum.algorithm.nisq.Ansatz19 Generator ------------- diff --git a/docs/api_python/mindquantum.core.parameterresolver.PRGenerator.rst b/docs/api_python/mindquantum.core.parameterresolver.PRGenerator.rst new file mode 100644 index 000000000..ab2940f3a --- /dev/null +++ b/docs/api_python/mindquantum.core.parameterresolver.PRGenerator.rst @@ -0,0 +1,20 @@ +.. py:class:: mindquantum.core.parameterresolver.PRGenerator(prefix: str = '', subfix: str = '', dtype=None) + + 一个一个的生成参数。 + + 参数: + - **prefix** (str) - 参数的前缀。默认值: ``''``。 + - **subfix** (str) - 参数的后缀。默认值: ``''``。 + - **dtype** (mindquantum.dtype) - 改参数解析器的数据类型。如果为 ``None``,则类型为 ``mindquantum.float64``。默认: ``None``。 + + .. py:method:: reset() + + 重置参数生成器到初态。 + + .. py:method:: new() + + 生成下一个新的参数。 + + .. py:method:: size() + + 返回已生成的参数的个数。 diff --git a/docs/api_python/mindquantum.core.parameterresolver.rst b/docs/api_python/mindquantum.core.parameterresolver.rst index 7ada55d72..9caa88b20 100644 --- a/docs/api_python/mindquantum.core.parameterresolver.rst +++ b/docs/api_python/mindquantum.core.parameterresolver.rst @@ -7,6 +7,7 @@ mindquantum.core.parameterresolver 参数解析器模块,用于声明MindSpore Quantum中所使用到的参数。 .. include:: mindquantum.core.parameterresolver.ParameterResolver.rst +.. include:: mindquantum.core.parameterresolver.PRGenerator.rst .. automodule:: mindquantum.core.parameterresolver :members: diff --git a/docs/api_python_en/mindquantum.algorithm.nisq.rst b/docs/api_python_en/mindquantum.algorithm.nisq.rst index f93a89726..49deef292 100644 --- a/docs/api_python_en/mindquantum.algorithm.nisq.rst +++ b/docs/api_python_en/mindquantum.algorithm.nisq.rst @@ -37,6 +37,25 @@ Ansatz mindquantum.algorithm.nisq.QubitUCCAnsatz mindquantum.algorithm.nisq.StronglyEntangling mindquantum.algorithm.nisq.UCCAnsatz + mindquantum.algorithm.nisq.Ansatz1 + mindquantum.algorithm.nisq.Ansatz2 + mindquantum.algorithm.nisq.Ansatz3 + mindquantum.algorithm.nisq.Ansatz4 + mindquantum.algorithm.nisq.Ansatz5 + mindquantum.algorithm.nisq.Ansatz6 + mindquantum.algorithm.nisq.Ansatz7 + mindquantum.algorithm.nisq.Ansatz8 + mindquantum.algorithm.nisq.Ansatz9 + mindquantum.algorithm.nisq.Ansatz10 + mindquantum.algorithm.nisq.Ansatz11 + mindquantum.algorithm.nisq.Ansatz12 + mindquantum.algorithm.nisq.Ansatz13 + mindquantum.algorithm.nisq.Ansatz14 + mindquantum.algorithm.nisq.Ansatz15 + mindquantum.algorithm.nisq.Ansatz16 + mindquantum.algorithm.nisq.Ansatz17 + mindquantum.algorithm.nisq.Ansatz18 + mindquantum.algorithm.nisq.Ansatz19 Generator ----------- diff --git a/mindquantum/algorithm/nisq/_ansatz.py b/mindquantum/algorithm/nisq/_ansatz.py index 0ea1c266f..747220938 100644 --- a/mindquantum/algorithm/nisq/_ansatz.py +++ b/mindquantum/algorithm/nisq/_ansatz.py @@ -14,9 +14,13 @@ # ============================================================================ """Base class of ansatz.""" +import inspect +import typing from abc import abstractmethod from mindquantum.core.circuit import Circuit +from mindquantum.core.gates import NoneParameterGate, ParameterGate +from mindquantum.core.parameterresolver import PRGenerator class Ansatz: # pylint: disable=too-few-public-methods @@ -48,3 +52,32 @@ def circuit(self) -> Circuit: Circuit, the quantum circuit of this ansatz. """ return self._circuit + + +def single_qubit_gate_layer( + gate: typing.Union[ParameterGate, NoneParameterGate], n_qubits: int, stop: int = None, pr_gen: PRGenerator = None +): + """ + Generate a single qubit gate layer. + + Args: + gate (Union[:class:`~.core.gates.ParameterGate`, :class:`~.core.gates.NoneParameterGate`]): A + quantum gate, can be a class or a instance. + n_qubits (int): Number qubits of ansatz. If `stop` is not ``None``, then `n_qubits` would be the start qubit. + stop (int): The stop qubit. If ``None``, `n_qubits` would be the stop qubit. Default: ``None``. + pr_gen (:class:`~.core.parameterresolver.PRGenerator`): Object that generate parameters. If given `gate` is + a sub class of ParameterGate, then `pr_gen` cannot be ``None``. Default: ``None``. + """ + circ = Circuit() + q_range = range(n_qubits) + if stop is not None: + q_range = range(n_qubits, stop) + for i in q_range: + if inspect.isclass(gate): + if issubclass(gate, ParameterGate): + circ += gate(pr_gen.new()).on(i) + elif issubclass(gate, NoneParameterGate): + circ += gate().on(i) + else: + circ += gate.on(i) + return circ diff --git a/mindquantum/algorithm/nisq/qnn/__init__.py b/mindquantum/algorithm/nisq/qnn/__init__.py index 88d724080..5ef4005b9 100644 --- a/mindquantum/algorithm/nisq/qnn/__init__.py +++ b/mindquantum/algorithm/nisq/qnn/__init__.py @@ -26,6 +26,15 @@ Ansatz8, Ansatz9, Ansatz10, + Ansatz11, + Ansatz12, + Ansatz13, + Ansatz14, + Ansatz15, + Ansatz16, + Ansatz17, + Ansatz18, + Ansatz19, ) from .iqp_encoding import IQPEncoding from .strongly_entangling import StronglyEntangling diff --git a/mindquantum/algorithm/nisq/qnn/arxiv_1905_10876.py b/mindquantum/algorithm/nisq/qnn/arxiv_1905_10876.py new file mode 100644 index 000000000..67ccd6f4e --- /dev/null +++ b/mindquantum/algorithm/nisq/qnn/arxiv_1905_10876.py @@ -0,0 +1,943 @@ +# 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. +# ============================================================================ +"""These ansatz are adpot from arxiv 1906 10876.""" +# pylint: disable=too-few-public-methods +from mindquantum.algorithm.nisq._ansatz import Ansatz, single_qubit_gate_layer +from mindquantum.core.circuit import UN +from mindquantum.core.gates import BARRIER, RX, RY, RZ, H, X, Z +from mindquantum.core.parameterresolver import PRGenerator +from mindquantum.utils.type_value_check import ( + _check_input_type, + _check_int_type, + _check_value_should_not_less, +) + + +class Initializer: + """ + Initialize parameters for ansatz. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Initialize parameters.""" + _check_int_type('n_qubits', n_qubits) + _check_value_should_not_less('n_qubits', 0, n_qubits) + _check_value_should_not_less('depth', 1, depth) + _check_int_type('depth', depth) + _check_input_type('prefix', str, prefix) + self.n_qubits = n_qubits + self.depth = depth + self.pr_gen = PRGenerator(prefix, subfix) + + +class Ansatz1(Ansatz, Initializer): + """ + Ansatz 1 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz1 + >>> Ansatz1(3, 2).circuit + q0: ──RX(p0)────RZ(p1)─────RX(p6)─────RZ(p7)── + q1: ──RX(p2)────RZ(p3)─────RX(p8)─────RZ(p9)── + q2: ──RX(p4)────RZ(p5)────RX(p10)────RZ(p11)── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz1', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 1.""" + for _ in range(depth): + self._circuit += single_qubit_gate_layer(RX, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += BARRIER + + +class Ansatz2(Ansatz, Initializer): + """ + Ansatz 2 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz2 + >>> Ansatz2(3, 2).circuit + q0: ──RX(p0)────RZ(p1)─────────X─────RX(p6)─────RZ(p7)─────────X── + │ │ + q1: ──RX(p2)────RZ(p3)────X────●─────RX(p8)─────RZ(p9)────X────●── + │ │ + q2: ──RX(p4)────RZ(p5)────●─────────RX(p10)────RZ(p11)────●─────── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz2', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 2.""" + for _ in range(depth): + self._circuit += single_qubit_gate_layer(RX, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, self.n_qubits, pr_gen=self.pr_gen) + for i in range(self.n_qubits - 1): + self._circuit += X.on(self.n_qubits - 2 - i, self.n_qubits - 1 - i) + self._circuit += BARRIER + + +class Ansatz3(Ansatz, Initializer): + """ + Ansatz 3 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz3 + >>> Ansatz3(3, 1).circuit + q0: ──RX(p0)────RZ(p1)──────────────RZ(p7)── + │ + q1: ──RX(p2)────RZ(p3)────RZ(p6)──────●───── + │ + q2: ──RX(p4)────RZ(p5)──────●─────────────── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz3', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 3.""" + for _ in range(depth): + self._circuit += single_qubit_gate_layer(RX, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, self.n_qubits, pr_gen=self.pr_gen) + for i in range(self.n_qubits - 1): + self._circuit += RZ(self.pr_gen.new()).on(self.n_qubits - 2 - i, self.n_qubits - 1 - i) + self._circuit += BARRIER + + +class Ansatz4(Ansatz, Initializer): + """ + Ansatz 4 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz4 + >>> Ansatz4(3, 1).circuit + q0: ──RX(p0)────RZ(p1)──────────────RX(p7)── + │ + q1: ──RX(p2)────RZ(p3)────RX(p6)──────●───── + │ + q2: ──RX(p4)────RZ(p5)──────●─────────────── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz4', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 4.""" + for _ in range(depth): + self._circuit += single_qubit_gate_layer(RX, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, self.n_qubits, pr_gen=self.pr_gen) + for i in range(self.n_qubits - 1): + self._circuit += RX(self.pr_gen.new()).on(self.n_qubits - 2 - i, self.n_qubits - 1 - i) + self._circuit += BARRIER + + +class Ansatz5(Ansatz, Initializer): + """ + Ansatz 5 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz5 + >>> Ansatz5(3, 1).circuit + q0: ──RX(p0)────RZ(p3)──────────────RZ(p7)──────────────RZ(p9)───────●──────────●───────RX(p12)────RZ(p15)── + │ │ │ │ + q1: ──RX(p1)────RZ(p4)────RZ(p6)──────┼─────────●─────────●──────────┼───────RZ(p11)────RX(p13)────RZ(p16)── + │ │ │ │ + q2: ──RX(p2)────RZ(p5)──────●─────────●───────RZ(p8)──────────────RZ(p10)───────────────RX(p14)────RZ(p17)── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz5', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 5.""" + for _ in range(depth): + self._circuit += single_qubit_gate_layer(RX, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, self.n_qubits, pr_gen=self.pr_gen) + for ctrl in range(self.n_qubits)[::-1]: + for obj in range(self.n_qubits)[::-1]: + if obj != ctrl: + self._circuit += RZ(self.pr_gen.new()).on(obj, ctrl) + self._circuit += BARRIER + self._circuit += single_qubit_gate_layer(RX, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += BARRIER + + +class Ansatz6(Ansatz, Initializer): + """ + Ansatz 6 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz6 + >>> Ansatz6(3, 1).circuit + q0: ──RX(p0)────RZ(p3)──────────────RX(p7)──────────────RX(p9)───────●──────────●───────RX(p12)────RZ(p15)── + │ │ │ │ + q1: ──RX(p1)────RZ(p4)────RX(p6)──────┼─────────●─────────●──────────┼───────RX(p11)────RX(p13)────RZ(p16)── + │ │ │ │ + q2: ──RX(p2)────RZ(p5)──────●─────────●───────RX(p8)──────────────RX(p10)───────────────RX(p14)────RZ(p17)── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz6', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 6.""" + for _ in range(depth): + self._circuit += single_qubit_gate_layer(RX, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, self.n_qubits, pr_gen=self.pr_gen) + for ctrl in range(self.n_qubits)[::-1]: + for obj in range(self.n_qubits)[::-1]: + if obj != ctrl: + self._circuit += RX(self.pr_gen.new()).on(obj, ctrl) + self._circuit += BARRIER + self._circuit += single_qubit_gate_layer(RX, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += BARRIER + + +class Ansatz7(Ansatz, Initializer): + """ + Ansatz 7 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz7 + >>> Ansatz7(4, 1).circuit + q0: ──RX(p0)────RZ(p4)────RZ(p8)────RX(p10)────RZ(p14)───────────── + │ + q1: ──RX(p1)────RZ(p5)──────●───────RX(p11)────RZ(p15)────RZ(p18)── + │ + q2: ──RX(p2)────RZ(p6)────RZ(p9)────RX(p12)────RZ(p16)───────●───── + │ + q3: ──RX(p3)────RZ(p7)──────●───────RX(p13)────RZ(p17)───────────── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz7', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 7.""" + for _ in range(depth): + self._circuit += single_qubit_gate_layer(RX, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, self.n_qubits, pr_gen=self.pr_gen) + start = 0 + for i in range(start, self.n_qubits, 2): + obj = i + ctrl = obj + 1 + if ctrl >= self.n_qubits: + continue + self._circuit += RZ(self.pr_gen.new()).on(obj, ctrl) + self._circuit += BARRIER + self._circuit += single_qubit_gate_layer(RX, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, self.n_qubits, pr_gen=self.pr_gen) + start = 1 + for i in range(start, self.n_qubits, 2): + obj = i + ctrl = obj + 1 + if ctrl >= self.n_qubits: + continue + self._circuit += RZ(self.pr_gen.new()).on(obj, ctrl) + self._circuit += BARRIER + + +class Ansatz8(Ansatz, Initializer): + """ + Ansatz 8 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz8 + >>> Ansatz8(4, 1).circuit + q0: ──RX(p0)────RZ(p1)────RX(p8)────RX(p10)────RZ(p11)───────────── + │ + q1: ──RX(p2)────RZ(p3)──────●───────RX(p12)────RZ(p13)────RX(p18)── + │ + q2: ──RX(p4)────RZ(p5)────RX(p9)────RX(p14)────RZ(p15)───────●───── + │ + q3: ──RX(p6)────RZ(p7)──────●───────RX(p16)────RZ(p17)───────────── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz8', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 8.""" + for _ in range(depth): + self._circuit += single_qubit_gate_layer(RX, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, self.n_qubits, pr_gen=self.pr_gen) + start = 0 + for i in range(start, self.n_qubits, 2): + obj = i + ctrl = obj + 1 + if ctrl >= self.n_qubits: + continue + self._circuit += RX(self.pr_gen.new()).on(obj, ctrl) + self._circuit += BARRIER + self._circuit += single_qubit_gate_layer(RX, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, self.n_qubits, pr_gen=self.pr_gen) + start = 1 + for i in range(start, self.n_qubits, 2): + obj = i + ctrl = obj + 1 + if ctrl >= self.n_qubits: + continue + self._circuit += RX(self.pr_gen.new()).on(obj, ctrl) + self._circuit += BARRIER + + +class Ansatz9(Ansatz, Initializer): + """ + Ansatz 9 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz9 + >>> Ansatz9(4, 2).circuit + q0: ──H──────────────Z────RX(p0)────H──────────────Z────RX(p4)── + │ │ + q1: ──H─────────Z────●────RX(p1)────H─────────Z────●────RX(p5)── + │ │ + q2: ──H────Z────●─────────RX(p2)────H────Z────●─────────RX(p6)── + │ │ + q3: ──H────●──────────────RX(p3)────H────●──────────────RX(p7)── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz9', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 9.""" + for _ in range(depth): + self._circuit += UN(H, self.n_qubits) + for i in range(self.n_qubits - 1)[::-1]: + self._circuit += Z.on(i, i + 1) + self._circuit += BARRIER + self._circuit += single_qubit_gate_layer(RX, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += BARRIER + + +class Ansatz10(Ansatz, Initializer): + """ + Ansatz 10 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz10 + >>> Ansatz10(4, 2).circuit + q0: ──RY(p0)──────────────●────Z────RY(p4)──────────────●────Z─────RY(p8)── + │ │ │ │ + q1: ──RY(p1)─────────●────Z────┼────RY(p5)─────────●────Z────┼─────RY(p9)── + │ │ │ │ + q2: ──RY(p2)────●────Z─────────┼────RY(p6)────●────Z─────────┼────RY(p10)── + │ │ │ │ + q3: ──RY(p3)────Z──────────────●────RY(p7)────Z──────────────●────RY(p11)── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz10', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 10.""" + self._circuit += single_qubit_gate_layer(RY, self.n_qubits, pr_gen=self.pr_gen) + for _ in range(depth): + for i in range(self.n_qubits)[::-1]: + if self.n_qubits != 1: + self._circuit += Z.on(i, (i - 1) % self.n_qubits) + self._circuit += BARRIER + self._circuit += single_qubit_gate_layer(RY, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += BARRIER + + +class Ansatz11(Ansatz, Initializer): + """ + Ansatz 11 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz11 + >>> Ansatz11(4, 1).circuit + q0: ──RY(p0)────RZ(p1)────X───────────────────────────── + │ + q1: ──RY(p2)────RZ(p3)────●─────RY(p8)─────RZ(p9)────X── + │ + q2: ──RY(p4)────RZ(p5)────X────RY(p10)────RZ(p11)────●── + │ + q3: ──RY(p6)────RZ(p7)────●───────────────────────────── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz11', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 11.""" + for _ in range(depth): + self._circuit += single_qubit_gate_layer(RY, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, self.n_qubits, pr_gen=self.pr_gen) + start = 0 + for i in range(start, self.n_qubits, 2): + obj = i + ctrl = obj + 1 + if ctrl >= self.n_qubits: + continue + self._circuit += X.on(obj, ctrl) + self._circuit += BARRIER + self._circuit += single_qubit_gate_layer(RY, 1, self.n_qubits - 1, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, 1, self.n_qubits - 1, pr_gen=self.pr_gen) + start = 1 + for i in range(start, self.n_qubits, 2): + obj = i + ctrl = obj + 1 + if ctrl >= self.n_qubits: + continue + self._circuit += X.on(obj, ctrl) + self._circuit += BARRIER + + +class Ansatz12(Ansatz, Initializer): + """ + Ansatz 12 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz12 + >>> Ansatz12(4, 1).circuit + q0: ──RY(p0)────RZ(p1)────Z───────────────────────────── + │ + q1: ──RY(p2)────RZ(p3)────●─────RY(p8)─────RZ(p9)────Z── + │ + q2: ──RY(p4)────RZ(p5)────Z────RY(p10)────RZ(p11)────●── + │ + q3: ──RY(p6)────RZ(p7)────●───────────────────────────── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz12', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 12.""" + for _ in range(depth): + self._circuit += single_qubit_gate_layer(RY, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, self.n_qubits, pr_gen=self.pr_gen) + start = 0 + for i in range(start, self.n_qubits, 2): + obj = i + ctrl = obj + 1 + if ctrl >= self.n_qubits: + continue + self._circuit += Z.on(obj, ctrl) + self._circuit += BARRIER + self._circuit += single_qubit_gate_layer(RY, 1, self.n_qubits - 1, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, 1, self.n_qubits - 1, pr_gen=self.pr_gen) + start = 1 + for i in range(start, self.n_qubits, 2): + obj = i + ctrl = obj + 1 + if ctrl >= self.n_qubits: + continue + self._circuit += Z.on(obj, ctrl) + self._circuit += BARRIER + + +class Ansatz13(Ansatz, Initializer): + """ + Ansatz 13 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz13 + >>> Ansatz13(4, 1).circuit + q0: ──RY(p0)────RZ(p4)──────────────────────────●────────RY(p8)──────────────────●───────RZ(p14)───────────── + │ │ │ │ + q1: ──RY(p1)──────┼───────────────────●───────RZ(p7)─────RY(p9)──────────────────┼──────────●───────RZ(p15)── + │ │ │ │ + q2: ──RY(p2)──────┼─────────●───────RZ(p6)──────────────RY(p10)────RZ(p12)───────┼─────────────────────●───── + │ │ │ │ + q3: ──RY(p3)──────●───────RZ(p5)────────────────────────RY(p11)───────●───────RZ(p13)──────────────────────── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz13', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 13.""" + for _ in range(depth): + self._circuit += single_qubit_gate_layer(RY, self.n_qubits, pr_gen=self.pr_gen) + for ctrl in range(self.n_qubits)[::-1]: + obj = (ctrl + 1) % self.n_qubits + if obj != ctrl: + self._circuit += RZ(self.pr_gen.new()).on(obj, ctrl) + self._circuit += BARRIER + self._circuit += single_qubit_gate_layer(RY, self.n_qubits, pr_gen=self.pr_gen) + for idx in range(self.n_qubits - 1, 2 * self.n_qubits - 1): + ctrl = idx % self.n_qubits + obj = (ctrl - 1) % self.n_qubits + if obj != ctrl: + self._circuit += RZ(self.pr_gen.new()).on(obj, ctrl) + self._circuit += BARRIER + + +class Ansatz14(Ansatz, Initializer): + """ + Ansatz 14 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz14 + >>> Ansatz14(4, 1).circuit + q0: ──RY(p0)────RX(p4)──────────────────────────●────────RY(p8)──────────────────●───────RX(p14)───────────── + │ │ │ │ + q1: ──RY(p1)──────┼───────────────────●───────RX(p7)─────RY(p9)──────────────────┼──────────●───────RX(p15)── + │ │ │ │ + q2: ──RY(p2)──────┼─────────●───────RX(p6)──────────────RY(p10)────RX(p12)───────┼─────────────────────●───── + │ │ │ │ + q3: ──RY(p3)──────●───────RX(p5)────────────────────────RY(p11)───────●───────RX(p13)──────────────────────── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz14', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 14.""" + for _ in range(depth): + self._circuit += single_qubit_gate_layer(RY, self.n_qubits, pr_gen=self.pr_gen) + for ctrl in range(self.n_qubits)[::-1]: + obj = (ctrl + 1) % self.n_qubits + if obj != ctrl: + self._circuit += RX(self.pr_gen.new()).on(obj, ctrl) + self._circuit += BARRIER + self._circuit += single_qubit_gate_layer(RY, self.n_qubits, pr_gen=self.pr_gen) + for idx in range(self.n_qubits - 1, 2 * self.n_qubits - 1): + ctrl = idx % self.n_qubits + obj = (ctrl - 1) % self.n_qubits + if obj != ctrl: + self._circuit += RX(self.pr_gen.new()).on(obj, ctrl) + self._circuit += BARRIER + + +class Ansatz15(Ansatz, Initializer): + """ + Ansatz 15 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz15 + >>> Ansatz15(4, 1).circuit + q0: ──RY(p0)────X──────────────●────RY(p4)─────────●────X─────── + │ │ │ │ + q1: ──RY(p1)────┼─────────●────X────RY(p5)─────────┼────●────X── + │ │ │ │ + q2: ──RY(p2)────┼────●────X─────────RY(p6)────X────┼─────────●── + │ │ │ │ + q3: ──RY(p3)────●────X──────────────RY(p7)────●────X──────────── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz15', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 15.""" + for _ in range(depth): + self._circuit += single_qubit_gate_layer(RY, self.n_qubits, pr_gen=self.pr_gen) + for ctrl in range(self.n_qubits)[::-1]: + obj = (ctrl + 1) % self.n_qubits + if obj != ctrl: + self._circuit += X.on(obj, ctrl) + self._circuit += BARRIER + self._circuit += single_qubit_gate_layer(RY, self.n_qubits, pr_gen=self.pr_gen) + for idx in range(self.n_qubits - 1, 2 * self.n_qubits - 1): + ctrl = idx % self.n_qubits + obj = (ctrl - 1) % self.n_qubits + if obj != ctrl: + self._circuit += X.on(obj, ctrl) + self._circuit += BARRIER + + +class Ansatz16(Ansatz, Initializer): + """ + Ansatz 16 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz16 + >>> Ansatz16(4, 1).circuit + q0: ──RX(p0)────RZ(p1)────RZ(p8)───────────── + │ + q1: ──RX(p2)────RZ(p3)──────●───────RZ(p10)── + │ + q2: ──RX(p4)────RZ(p5)────RZ(p9)───────●───── + │ + q3: ──RX(p6)────RZ(p7)──────●──────────────── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz16', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 16.""" + for _ in range(depth): + self._circuit += single_qubit_gate_layer(RX, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, self.n_qubits, pr_gen=self.pr_gen) + start = 0 + for i in range(start, self.n_qubits, 2): + obj = i + ctrl = obj + 1 + if ctrl >= self.n_qubits: + continue + self._circuit += RZ(self.pr_gen.new()).on(obj, ctrl) + self._circuit += BARRIER + start = 1 + for i in range(start, self.n_qubits, 2): + obj = i + ctrl = obj + 1 + if ctrl >= self.n_qubits: + continue + self._circuit += RZ(self.pr_gen.new()).on(obj, ctrl) + self._circuit += BARRIER + + +class Ansatz17(Ansatz, Initializer): + """ + Ansatz 17 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz17 + >>> Ansatz17(4, 1).circuit + q0: ──RX(p0)────RZ(p1)────RX(p8)───────────── + │ + q1: ──RX(p2)────RZ(p3)──────●───────RX(p10)── + │ + q2: ──RX(p4)────RZ(p5)────RX(p9)───────●───── + │ + q3: ──RX(p6)────RZ(p7)──────●──────────────── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz17', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 17.""" + for _ in range(depth): + self._circuit += single_qubit_gate_layer(RX, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, self.n_qubits, pr_gen=self.pr_gen) + start = 0 + for i in range(start, self.n_qubits, 2): + obj = i + ctrl = obj + 1 + if ctrl >= self.n_qubits: + continue + self._circuit += RX(self.pr_gen.new()).on(obj, ctrl) + self._circuit += BARRIER + start = 1 + for i in range(start, self.n_qubits, 2): + obj = i + ctrl = obj + 1 + if ctrl >= self.n_qubits: + continue + self._circuit += RX(self.pr_gen.new()).on(obj, ctrl) + self._circuit += BARRIER + + +class Ansatz18(Ansatz, Initializer): + """ + Ansatz 18 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz18 + >>> Ansatz18(4, 1).circuit + q0: ──RX(p0)────RZ(p1)────RZ(p8)────────────────────────────●───── + │ │ + q1: ──RX(p2)────RZ(p3)──────┼────────────────────●───────RZ(p11)── + │ │ + q2: ──RX(p4)────RZ(p5)──────┼─────────●───────RZ(p10)───────────── + │ │ + q3: ──RX(p6)────RZ(p7)──────●───────RZ(p9)──────────────────────── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz18', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 18.""" + for _ in range(depth): + self._circuit += single_qubit_gate_layer(RX, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, self.n_qubits, pr_gen=self.pr_gen) + for ctrl in range(self.n_qubits)[::-1]: + obj = (ctrl + 1) % self.n_qubits + if obj != ctrl: + self._circuit += RZ(self.pr_gen.new()).on(obj, ctrl) + self._circuit += BARRIER + + +class Ansatz19(Ansatz, Initializer): + """ + Ansatz 19 implement from arxiv paper. + + Please refers to `Expressibility and entangling capability of parameterized quantum circuits for hybrid + quantum-classical algorithms `_. + + Args: + n_qubits (int): total qubits number of this ansatz. + depth (int): depth of ansatz. + prefix (str): prefix of parameters. Default: ``''``. + subfix (str): subfix of parameters. Default: ``''``. + + Examples: + >>> from mindquantum.algorithm.nisq import Ansatz19 + >>> Ansatz19(4, 1).circuit + q0: ──RX(p0)────RZ(p1)────RX(p8)────────────────────────────●───── + │ │ + q1: ──RX(p2)────RZ(p3)──────┼────────────────────●───────RX(p11)── + │ │ + q2: ──RX(p4)────RZ(p5)──────┼─────────●───────RX(p10)───────────── + │ │ + q3: ──RX(p6)────RZ(p7)──────●───────RX(p9)──────────────────────── + """ + + def __init__(self, n_qubits: int, depth: int, prefix: str = '', subfix: str = ''): + """Construct ansatz.""" + Initializer.__init__(self, n_qubits, depth, prefix, subfix) + Ansatz.__init__(self, 'Ansatz19', n_qubits, depth) + + def _implement(self, depth): # pylint: disable=arguments-differ + """Implement of ansatz 19.""" + for _ in range(depth): + self._circuit += single_qubit_gate_layer(RX, self.n_qubits, pr_gen=self.pr_gen) + self._circuit += single_qubit_gate_layer(RZ, self.n_qubits, pr_gen=self.pr_gen) + for ctrl in range(self.n_qubits)[::-1]: + obj = (ctrl + 1) % self.n_qubits + if obj != ctrl: + self._circuit += RX(self.pr_gen.new()).on(obj, ctrl) + self._circuit += BARRIER + + +__all__ = [ + 'Ansatz1', + 'Ansatz2', + 'Ansatz3', + 'Ansatz4', + 'Ansatz5', + 'Ansatz6', + 'Ansatz7', + 'Ansatz8', + 'Ansatz9', + 'Ansatz10', + 'Ansatz11', + 'Ansatz12', + 'Ansatz13', + 'Ansatz14', + 'Ansatz15', + 'Ansatz16', + 'Ansatz17', + 'Ansatz18', + 'Ansatz19', +] +__all__.sort() diff --git a/mindquantum/core/parameterresolver/__init__.py b/mindquantum/core/parameterresolver/__init__.py index b854f2877..ffa9b9ea2 100644 --- a/mindquantum/core/parameterresolver/__init__.py +++ b/mindquantum/core/parameterresolver/__init__.py @@ -15,5 +15,6 @@ """Parameter resolver. Help to generate parameter in mindspore quantum.""" from .parameterresolver import ParameterResolver, PRConvertible +from .pr_generator import PRGenerator -__all__ = ["ParameterResolver"] +__all__ = ["ParameterResolver", "PRGenerator"] diff --git a/mindquantum/core/parameterresolver/pr_generator.py b/mindquantum/core/parameterresolver/pr_generator.py new file mode 100644 index 000000000..2ca53f7a9 --- /dev/null +++ b/mindquantum/core/parameterresolver/pr_generator.py @@ -0,0 +1,75 @@ +# 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. +# ============================================================================ +"""Parameter Generator.""" + +import mindquantum as mq + +from .parameterresolver import ParameterResolver + + +class PRGenerator: + """ + Generate parameters one by one. + + Args: + prefix (str): The prefix of parameters. Default: ``''``. + subfix (str): The subfix of parameters. Default: ``''``. + dtype (mindquantum.dtype): the data type of this parameter resolver. If ``None``, + dtype would be ``mindquantum.float64``. Default: ``None``. + + Examples: + >>> from mindquantum.core.parameterresolver import PRGenerator + >>> pr_gen = PRGenerator() + >>> print(pr_gen.new()) + p0 + >>> print(pr_gen.new()) + p1 + >>> pr_gen.reset() + >>> print(pr_gen.new()) + p0 + >>> pr_gen.size() + 1 + """ + + def __init__(self, prefix: str = '', subfix: str = '', dtype=None): + """Initialize a pr generator.""" + if dtype is None: + self.dtype = mq.float64 + else: + self.dtype = dtype + self.prefix = prefix + self.subfix = subfix + if prefix: + self.prefix += '-' + if subfix: + self.subfix = '_' + self.subfix + self.current_idx = 0 + self.all_pr = [] + + def reset(self): + """Reset the pr generator to initialize state.""" + self.current_idx = 0 + self.all_pr = [] + + def new(self) -> ParameterResolver: + """Generate a new parameter.""" + out = ParameterResolver(f'{self.prefix}p{self.current_idx}{self.subfix}', dtype=self.dtype) + self.all_pr.append(out) + self.current_idx += 1 + return out + + def size(self): + """Get the total size of parameters that generated.""" + return self.current_idx From bddfaa424690239f69ef178d8e05f9d8a34f25fc Mon Sep 17 00:00:00 2001 From: sunil-fei <975538890@qq.com> Date: Thu, 27 Jul 2023 04:10:10 +0000 Subject: [PATCH 025/100] =?UTF-8?q?!1762=20=E5=A2=9E=E5=8A=A0=E9=83=A8?= =?UTF-8?q?=E5=88=86=E4=BB=A3=E7=A0=81=E9=99=A4=E6=95=B0=E9=9D=9E0?= =?UTF-8?q?=E5=88=A4=E6=96=AD=20*=20update=20mindquantum/io/display/bloch?= =?UTF-8?q?=5Fplt=5Fdrawer.py.=20*=20update=20mindquantum/io/display/bloch?= =?UTF-8?q?=5Fplt=5Fdrawer.py.=20*=20update=20mindquantum/io/display/bloch?= =?UTF-8?q?=5Fplt=5Fdrawer.py.=20*=20update=20mindquantum/io/display/bloch?= =?UTF-8?q?=5Fplt=5Fdrawer.py.=20*=20update=20mindquantum/io/display/bloch?= =?UTF-8?q?=5Fplt=5Fdrawer.py.=20*=20update=20mindquantum/io/display/bloch?= =?UTF-8?q?=5Fplt=5Fdrawer.py.=20*=20update=20mindquantum/io/display/bloch?= =?UTF-8?q?=5Fplt=5Fdrawer.py.=20*=20update=20mindquantum/io/display/bloch?= =?UTF-8?q?=5Fplt=5Fdrawer.py.=20*=20update=20mindquantum/io/display/measu?= =?UTF-8?q?re=5Fres=5Fdrawer.py.=20*=20update=20mindquantum/io/display/mea?= =?UTF-8?q?sure=5Fres=5Fdrawer.py.=20*=20update=20mindquantum/io/display/b?= =?UTF-8?q?loch=5Fplt=5Fdrawer.py.=20*=20update=20mindquantum/io/display/m?= =?UTF-8?q?easure=5Fres=5Fdrawer.py.=20*=20update=20mindquantum/io/display?= =?UTF-8?q?/bloch=5Fplt=5Fdrawer.py.=20*=20update=20mindquantum/io/display?= =?UTF-8?q?/bloch=5Fplt=5Fdrawer.py.=20*=20update=20mindquantum/io/display?= =?UTF-8?q?/measure=5Fres=5Fdrawer.py.=20*=20update=20mindquantum/io/displ?= =?UTF-8?q?ay/measure=5Fres=5Fdrawer.py.=20*=20update=20mindquantum/io/dis?= =?UTF-8?q?play/bloch=5Fplt=5Fdrawer.py.=20*=20update=20mindquantum/io/dis?= =?UTF-8?q?play/bloch=5Fplt=5Fdrawer.py.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mindquantum/io/display/bloch_plt_drawer.py | 3 ++- mindquantum/io/display/measure_res_drawer.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mindquantum/io/display/bloch_plt_drawer.py b/mindquantum/io/display/bloch_plt_drawer.py index b5a78cd8c..354b06e17 100644 --- a/mindquantum/io/display/bloch_plt_drawer.py +++ b/mindquantum/io/display/bloch_plt_drawer.py @@ -345,7 +345,8 @@ def state_to_cor(amp: np.ndarray): _check_input_type('amp', np.ndarray, amp) if amp.shape != (2,): raise ValueError(f"amp requires shape (2, ), but get {amp.shape}") - amp = amp / np.sqrt(np.vdot(amp, amp)) + if np.sqrt(np.vdot(amp, amp)) != 0: + amp = amp / np.sqrt(np.vdot(amp, amp)) global_phase = np.angle(amp[0]) amp = amp / np.exp(1j * global_phase) theta = 2 * np.arccos(np.real(amp[0])) diff --git a/mindquantum/io/display/measure_res_drawer.py b/mindquantum/io/display/measure_res_drawer.py index aca4a14bc..ae35d3b7b 100644 --- a/mindquantum/io/display/measure_res_drawer.py +++ b/mindquantum/io/display/measure_res_drawer.py @@ -37,7 +37,8 @@ def measure_text_drawer(res): # pylint: disable=too-many-locals deci = _res_text_drawer_config['deci'] keys = res.keys max_shot = max(res.data.values()) - max_prop = max_shot / res.shots + if res.shots != 0: + max_prop = max_shot / res.shots if max_prop == 0: max_prop = 1 if max_prop / 0.8 > 1: From ac01631e6b52264be3b3dd815dacb8e12e549982 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Tue, 25 Jul 2023 12:32:59 +0800 Subject: [PATCH 026/100] disable --cxx for github action --- .github/workflows/ci.yml | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fe8f3c600..21eb9c57f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -98,13 +98,13 @@ jobs: - name: Configure run: | - ./build_locally.sh --cxx --debug-cmake --test --ccache --no-gitee --debug \ + ./build_locally.sh --debug-cmake --test --ccache --no-gitee --debug \ --configure-only -c --clean-3rdparty --prefix="${{ github.workspace }}/install" \ --cmake-no-registry \ -- -DPython_FIND_UNVERSIONED_NAMES:STRING='FIRST' - name: Build - run: ./build_locally.sh --cxx --debug-cmake --test --ccache + run: ./build_locally.sh --debug-cmake --test --ccache - name: Install run: ./build_locally.sh --install # NB: no need to pass the other parameters @@ -176,7 +176,7 @@ jobs: env: VENV_PYTHON_TEST_PKGS: ${{ matrix.VENV_PYTHON_TEST_PKGS }} run: | - ./build.sh --cxx --debug-cmake --test \ + ./build.sh --debug-cmake --test \ --fast-build --no-build-isolation --no-delocate --ccache --cmake-no-registry --no-gitee # ============================================================================ @@ -242,12 +242,12 @@ jobs: - name: Configure run: >- - ./build_locally.sh --cxx --debug-cmake --test --ccache --only-pytest --no-gitee --debug + ./build_locally.sh --debug-cmake --test --ccache --only-pytest --no-gitee --debug --configure-only -c --clean-3rdparty --prefix="${{ github.workspace }}/install" --cmake-no-registry - name: Build - run: ./build_locally.sh --cxx --debug-cmake --test --ccache + run: ./build_locally.sh --debug-cmake --test --ccache - name: Install run: ./build_locally.sh --install # NB: no need to pass the other parameters @@ -325,12 +325,12 @@ jobs: - name: Configure run: >- - ./build_locally.sh --cxx --debug-cmake --test --ccache --only-pytest --no-gitee --debug + ./build_locally.sh --debug-cmake --test --ccache --only-pytest --no-gitee --debug --configure-only -c --logging --clean-3rdparty --prefix="${{ github.workspace }}/install" --cmake-no-registry -- -DENABLE_STACK_PROTECTION=ON - name: Build - run: ./build_locally.sh --cxx --debug-cmake --test --ccache + run: ./build_locally.sh --debug-cmake --test --ccache - name: Install run: ./build_locally.sh --install # NB: no need to pass the other parameters @@ -469,7 +469,7 @@ jobs: - name: Configure (Clang) if: matrix.clang != '8' run: >- - ./build_locally.sh --cxx --debug-cmake --test --ccache --only-pytest --no-gitee --debug + ./build_locally.sh --debug-cmake --test --ccache --only-pytest --no-gitee --debug --configure-only -c --clean-3rdparty --prefix="${{ github.workspace }}/install" --cmake-no-registry -- -DENABLE_STACK_PROTECTION=ON @@ -477,12 +477,12 @@ jobs: - name: Configure (Clang 8) if: matrix.clang == '8' run: >- - ./build_locally.sh --cxx --debug-cmake --test --ccache --only-pytest --no-gitee + ./build_locally.sh --debug-cmake --test --ccache --only-pytest --no-gitee --configure-only -c --clean-3rdparty --prefix="${{ github.workspace }}/install" --cmake-no-registry -- -DENABLE_STACK_PROTECTION=ON - name: Build - run: ./build_locally.sh --cxx --debug-cmake --test --ccache + run: ./build_locally.sh --debug-cmake --test --ccache - name: Install run: ./build_locally.sh --install # NB: no need to pass the other parameters @@ -952,7 +952,7 @@ jobs: CC: ${{ matrix.CC }} CXX: ${{ matrix.CXX }} run: >- - ./build_locally.sh --cxx --debug-cmake --test --ccache -v --only-pytest --no-gitee + ./build_locally.sh --debug-cmake --test --ccache -v --only-pytest --no-gitee --configure-only -c --clean-3rdparty --prefix="$PWD/install" --cmake-no-registry -- -G "MSYS Makefiles" @@ -962,7 +962,7 @@ jobs: env: CC: ${{ matrix.CC }} CXX: ${{ matrix.CXX }} - run: ./build_locally.sh --cxx --debug-cmake --test --ccache + run: ./build_locally.sh --debug-cmake --test --ccache - name: Install shell: msys2 {0} @@ -1092,7 +1092,7 @@ jobs: shell: bash --login -eo pipefail -o igncr {0} run: | export PATH="$PATH:$PWD/ccache/bin" - ./build_locally.sh --cxx --debug-cmake --test --ccache -v --only-pytest --no-gitee \ + ./build_locally.sh --debug-cmake --test --ccache -v --only-pytest --no-gitee \ --configure-only -c --clean-3rdparty --prefix=$PWD/install \ --cmake-no-registry ${{ matrix.cmake_generator }} @@ -1101,7 +1101,7 @@ jobs: shell: bash --login -eo pipefail -o igncr {0} run: | export PATH="$PATH:$PWD/ccache/bin" - ./build_locally.sh --cxx --debug-cmake --test --ccache + ./build_locally.sh --debug-cmake --test --ccache - name: Install shell: bash --login -eo pipefail -o igncr {0} @@ -1192,12 +1192,12 @@ jobs: - name: Configure run: >- - ./build_locally.sh --cxx --debug-cmake --gpu --test --ccache --only-pytest --no-gitee + ./build_locally.sh --debug-cmake --gpu --test --ccache --only-pytest --no-gitee --configure-only -c --clean-3rdparty --prefix="${{ github.workspace }}/install" --cmake-no-registry - name: Build - run: ./build_locally.sh --cxx --debug-cmake --gpu --test --ccache + run: ./build_locally.sh --debug-cmake --gpu --test --ccache - name: Install run: ./build_locally.sh --install @@ -1273,12 +1273,12 @@ jobs: - name: Configure run: >- - ./build_locally.sh --cxx --debug-cmake --gpu --test --ccache --only-pytest --no-gitee + ./build_locally.sh --debug-cmake --gpu --test --ccache --only-pytest --no-gitee --configure-only -c --clean-3rdparty --prefix="${{ github.workspace }}/install" --cmake-no-registry - name: Build - run: ./build_locally.sh --cxx --debug-cmake --gpu --test --ccache + run: ./build_locally.sh --debug-cmake --gpu --test --ccache - name: Install run: ./build_locally.sh --install @@ -1359,7 +1359,7 @@ jobs: # if [ -f /opt/intel/oneapi/tbb/latest/env/vars.sh ]; then # source /opt/intel/oneapi/tbb/latest/env/vars.sh # fi - # ./build_locally.sh --cxx --debug-cmake --test --gpu --no-gitee \ + # ./build_locally.sh --debug-cmake --test --gpu --no-gitee \ # --configure-only -c --clean-3rdparty --prefix="${{ github.workspace }}/install" # - name: Build @@ -1368,7 +1368,7 @@ jobs: # if [ -f /opt/intel/oneapi/tbb/latest/env/vars.sh ]; then # source /opt/intel/oneapi/tbb/latest/env/vars.sh # fi - # ./build_locally.sh --cxx --debug-cmake --test --gpu + # ./build_locally.sh --debug-cmake --test --gpu # - name: Install # run: ./build_locally.sh --install From 4314dd7709c2d8bba727e99eaba827b4c2a8bc2e Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Tue, 25 Jul 2023 12:45:28 +0800 Subject: [PATCH 027/100] enable on pull request --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 21eb9c57f..f0b542259 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,7 @@ on: push: branches-ignore: - 'test' + pull_request: env: CMAKE_VERSION: 3.22.3 From 4d7dd17e8943ee547b65018793e9319c34a0bc81 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Thu, 27 Jul 2023 12:24:19 +0800 Subject: [PATCH 028/100] fix conflict --- .github/workflows/ci.yml | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f0b542259..d631aaad8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -99,13 +99,13 @@ jobs: - name: Configure run: | - ./build_locally.sh --debug-cmake --test --ccache --no-gitee --debug \ + ./build_locally.sh --debug-cmake --ccache --no-gitee --debug \ --configure-only -c --clean-3rdparty --prefix="${{ github.workspace }}/install" \ --cmake-no-registry \ -- -DPython_FIND_UNVERSIONED_NAMES:STRING='FIRST' - name: Build - run: ./build_locally.sh --debug-cmake --test --ccache + run: ./build_locally.sh --debug-cmake --ccache - name: Install run: ./build_locally.sh --install # NB: no need to pass the other parameters @@ -177,7 +177,7 @@ jobs: env: VENV_PYTHON_TEST_PKGS: ${{ matrix.VENV_PYTHON_TEST_PKGS }} run: | - ./build.sh --debug-cmake --test \ + ./build.sh --debug-cmake \ --fast-build --no-build-isolation --no-delocate --ccache --cmake-no-registry --no-gitee # ============================================================================ @@ -243,12 +243,12 @@ jobs: - name: Configure run: >- - ./build_locally.sh --debug-cmake --test --ccache --only-pytest --no-gitee --debug + ./build_locally.sh --debug-cmake --ccache --only-pytest --no-gitee --debug --configure-only -c --clean-3rdparty --prefix="${{ github.workspace }}/install" --cmake-no-registry - name: Build - run: ./build_locally.sh --debug-cmake --test --ccache + run: ./build_locally.sh --debug-cmake --ccache - name: Install run: ./build_locally.sh --install # NB: no need to pass the other parameters @@ -326,12 +326,12 @@ jobs: - name: Configure run: >- - ./build_locally.sh --debug-cmake --test --ccache --only-pytest --no-gitee --debug + ./build_locally.sh --debug-cmake --ccache --only-pytest --no-gitee --debug --configure-only -c --logging --clean-3rdparty --prefix="${{ github.workspace }}/install" --cmake-no-registry -- -DENABLE_STACK_PROTECTION=ON - name: Build - run: ./build_locally.sh --debug-cmake --test --ccache + run: ./build_locally.sh --debug-cmake --ccache - name: Install run: ./build_locally.sh --install # NB: no need to pass the other parameters @@ -470,7 +470,7 @@ jobs: - name: Configure (Clang) if: matrix.clang != '8' run: >- - ./build_locally.sh --debug-cmake --test --ccache --only-pytest --no-gitee --debug + ./build_locally.sh --debug-cmake --ccache --only-pytest --no-gitee --debug --configure-only -c --clean-3rdparty --prefix="${{ github.workspace }}/install" --cmake-no-registry -- -DENABLE_STACK_PROTECTION=ON @@ -478,12 +478,12 @@ jobs: - name: Configure (Clang 8) if: matrix.clang == '8' run: >- - ./build_locally.sh --debug-cmake --test --ccache --only-pytest --no-gitee + ./build_locally.sh --debug-cmake --ccache --only-pytest --no-gitee --configure-only -c --clean-3rdparty --prefix="${{ github.workspace }}/install" --cmake-no-registry -- -DENABLE_STACK_PROTECTION=ON - name: Build - run: ./build_locally.sh --debug-cmake --test --ccache + run: ./build_locally.sh --debug-cmake --ccache - name: Install run: ./build_locally.sh --install # NB: no need to pass the other parameters @@ -953,7 +953,7 @@ jobs: CC: ${{ matrix.CC }} CXX: ${{ matrix.CXX }} run: >- - ./build_locally.sh --debug-cmake --test --ccache -v --only-pytest --no-gitee + ./build_locally.sh --debug-cmake --ccache -v --only-pytest --no-gitee --configure-only -c --clean-3rdparty --prefix="$PWD/install" --cmake-no-registry -- -G "MSYS Makefiles" @@ -963,7 +963,7 @@ jobs: env: CC: ${{ matrix.CC }} CXX: ${{ matrix.CXX }} - run: ./build_locally.sh --debug-cmake --test --ccache + run: ./build_locally.sh --debug-cmake --ccache - name: Install shell: msys2 {0} @@ -1093,7 +1093,7 @@ jobs: shell: bash --login -eo pipefail -o igncr {0} run: | export PATH="$PATH:$PWD/ccache/bin" - ./build_locally.sh --debug-cmake --test --ccache -v --only-pytest --no-gitee \ + ./build_locally.sh --debug-cmake --ccache -v --only-pytest --no-gitee \ --configure-only -c --clean-3rdparty --prefix=$PWD/install \ --cmake-no-registry ${{ matrix.cmake_generator }} @@ -1102,7 +1102,7 @@ jobs: shell: bash --login -eo pipefail -o igncr {0} run: | export PATH="$PATH:$PWD/ccache/bin" - ./build_locally.sh --debug-cmake --test --ccache + ./build_locally.sh --debug-cmake --ccache - name: Install shell: bash --login -eo pipefail -o igncr {0} @@ -1193,12 +1193,12 @@ jobs: - name: Configure run: >- - ./build_locally.sh --debug-cmake --gpu --test --ccache --only-pytest --no-gitee + ./build_locally.sh --debug-cmake --gpu --ccache --only-pytest --no-gitee --configure-only -c --clean-3rdparty --prefix="${{ github.workspace }}/install" --cmake-no-registry - name: Build - run: ./build_locally.sh --debug-cmake --gpu --test --ccache + run: ./build_locally.sh --debug-cmake --gpu --ccache - name: Install run: ./build_locally.sh --install @@ -1274,12 +1274,12 @@ jobs: - name: Configure run: >- - ./build_locally.sh --debug-cmake --gpu --test --ccache --only-pytest --no-gitee + ./build_locally.sh --debug-cmake --gpu --ccache --only-pytest --no-gitee --configure-only -c --clean-3rdparty --prefix="${{ github.workspace }}/install" --cmake-no-registry - name: Build - run: ./build_locally.sh --debug-cmake --gpu --test --ccache + run: ./build_locally.sh --debug-cmake --gpu --ccache - name: Install run: ./build_locally.sh --install @@ -1360,7 +1360,7 @@ jobs: # if [ -f /opt/intel/oneapi/tbb/latest/env/vars.sh ]; then # source /opt/intel/oneapi/tbb/latest/env/vars.sh # fi - # ./build_locally.sh --debug-cmake --test --gpu --no-gitee \ + # ./build_locally.sh --debug-cmake --gpu --no-gitee \ # --configure-only -c --clean-3rdparty --prefix="${{ github.workspace }}/install" # - name: Build @@ -1369,7 +1369,7 @@ jobs: # if [ -f /opt/intel/oneapi/tbb/latest/env/vars.sh ]; then # source /opt/intel/oneapi/tbb/latest/env/vars.sh # fi - # ./build_locally.sh --debug-cmake --test --gpu + # ./build_locally.sh --debug-cmake --gpu # - name: Install # run: ./build_locally.sh --install From f3c40dc67b34cbcba9b7fec19f519b4f91366054 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Tue, 25 Jul 2023 15:58:21 +0800 Subject: [PATCH 029/100] change owner --- .github/workflows/ci.yml | 56 +++------------------------------------- 1 file changed, 3 insertions(+), 53 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d631aaad8..63650df9c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -119,59 +119,6 @@ jobs: # ------------------------------------------------------------------------ - - name: In-build config files - if: matrix.test_install - run: | - cat ${{ github.workspace }}/build/mindquantumConfig.cmake - echo ---------- - cat ${{ github.workspace }}/build/mindquantumTargetsExternal.cmake - - - name: Out-of-build config files - if: matrix.test_install - run: | - cat ${{ github.workspace }}/build/config_for_install/mindquantumConfig.cmake - echo ---------- - cat ${{ github.workspace }}/build/config_for_install/mindquantumTargetsExternal.cmake - - - name: Setup installation test - if: matrix.test_install - run: | - mkdir other - cat << \EOF > other/CMakeLists.txt - cmake_minimum_required(VERSION 3.20) - project(test CXX) - find_package(mindquantum CONFIG REQUIRED) - set(CMAKE_CXX_STANDARD 20) - set(CMAKE_CXX_STANDARD_REQUIRED OFF) - set(CMAKE_CXX_EXTENSIONS OFF) - add_library(mylib STATIC test.cpp) - target_link_libraries(mylib PUBLIC mindquantum::mq_cxx_nextgen) - EOF - cat << \EOF > other/test.cpp - #include "experimental/ops/parametric/angle_gates.hpp" - double foo() { return mindquantum::ops::parametric::Rxx{1.3}.eval_full().angle(); } - EOF - - - name: Test (local) installation - if: matrix.test_install - run: | - . venv/bin/activate - unset Python_ROOT_DIR - hash -r - cmake -S other -B other/local_build -Dmindquantum_DEBUG=ON -Dmindquantum_ROOT=${{ github.workspace }}/build - cmake --build other/local_build --target all -v - - - name: Test (normal) installation - if: matrix.test_install - run: | - . venv/bin/activate - unset Python_ROOT_DIR - hash -r - cmake -S other -B other/build -Dmindquantum_DEBUG=ON -Dmindquantum_ROOT="${{ github.workspace }}/install" - cmake --build other/build --target all -v - - # ------------------------------------------------------------------------ - - name: Test (setup.py) installation if: matrix.test_bdist_wheel env: @@ -279,6 +226,9 @@ jobs: - name: Get history and tags for SCM versioning to work run: | + ls + pwd + git config --global --add safe.directory /__w/mindquantum/mindquantum git fetch --prune --unshallow git fetch --depth=1 origin +refs/tags/*:refs/tags/* From 0fef5ce21372104a055c59f5b5a7fd7fba2f5424 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Tue, 25 Jul 2023 16:18:26 +0800 Subject: [PATCH 030/100] install git for clang container --- .github/workflows/ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 63650df9c..1da43c02c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -286,11 +286,6 @@ jobs: - name: Install run: ./build_locally.sh --install # NB: no need to pass the other parameters - - name: Run C++ tests - run: | - cd build - catchsegv ctest --output-on-failure - - name: Run debugger in case of failure if: ${{ failure() }} run: | @@ -370,8 +365,13 @@ jobs: steps: - uses: actions/checkout@v3 + - name: install git + run: | + apt-get install -y git + - name: Get history and tags for SCM versioning to work run: | + git config --global --add safe.directory /__w/mindquantum/mindquantum git fetch --prune --unshallow git fetch --depth=1 origin +refs/tags/*:refs/tags/* From ff56d21a3d4a1509e3d90e1f1e5f6068ccb36eec Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Tue, 25 Jul 2023 16:26:35 +0800 Subject: [PATCH 031/100] update before install --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1da43c02c..dc592d317 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -367,7 +367,7 @@ jobs: - name: install git run: | - apt-get install -y git + apt-get update && apt-get install -y git - name: Get history and tags for SCM versioning to work run: | From cee56ec00f38b54e3dd191fe8529d1709d623c31 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Tue, 25 Jul 2023 16:29:22 +0800 Subject: [PATCH 032/100] delete change owner for clang --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc592d317..ad4cbc3fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -371,7 +371,6 @@ jobs: - name: Get history and tags for SCM versioning to work run: | - git config --global --add safe.directory /__w/mindquantum/mindquantum git fetch --prune --unshallow git fetch --depth=1 origin +refs/tags/*:refs/tags/* From b3f9f824e89996d4eac8a65322c8f270454d5ac6 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Tue, 25 Jul 2023 16:43:04 +0800 Subject: [PATCH 033/100] disable boost --- .github/workflows/ci.yml | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad4cbc3fa..d5e391eee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -683,9 +683,7 @@ jobs: strategy: fail-fast: false name: "MINGW64 • x64" - env: - BOOST_VERSION: 1.78.0 - BOOST_PATH: ${{github.workspace}}/boost/boost + steps: - uses: actions/checkout@v3 @@ -748,25 +746,7 @@ jobs: "CC='$Env:CC'" >> $Env:GITHUB_ENV "CXX='$Env:CXX'" >> $Env:GITHUB_ENV - # - name: Cache boost - # uses: actions/cache@v3 - # id: cache-boost - # with: - # path: ${{ env.BOOST_PATH }} - # key: boost-${{ env.BOOST_VERSION }} - - - name: Download and install Boost - uses: MarkusJx/install-boost@v2.4.3 - if: steps.cache-boost.outputs.cache-hit != 'true' - id: install-boost - with: - boost_version: ${{ env.BOOST_VERSION }} - platform_version: 2022 - toolset: mingw - - name: Configure - env: - BOOST_ROOT: ${{ env.BOOST_PATH }} run: >- ./build_locally.ps1 -Cxx -DebugCmake -Ninja -Test -OnlyPytest -NoGitee -ConfigureOnly -C -Clean3rdParty -Prefix "${{ github.workspace }}/install" From 44985c509b51801b1796bbc3a624da7d3d4bccd5 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Wed, 26 Jul 2023 09:16:59 +0800 Subject: [PATCH 034/100] show dir --- .github/workflows/ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d5e391eee..1753a0a38 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -226,8 +226,6 @@ jobs: - name: Get history and tags for SCM versioning to work run: | - ls - pwd git config --global --add safe.directory /__w/mindquantum/mindquantum git fetch --prune --unshallow git fetch --depth=1 origin +refs/tags/*:refs/tags/* @@ -371,6 +369,9 @@ jobs: - name: Get history and tags for SCM versioning to work run: | + ls + pwd + git config --global --add safe.directory /__w/mindquantum/mindquantum git fetch --prune --unshallow git fetch --depth=1 origin +refs/tags/*:refs/tags/* From c8891d6a80f696e3f0fa51bb4a32785720c560c3 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Wed, 26 Jul 2023 09:19:38 +0800 Subject: [PATCH 035/100] disable scm versioning --- .github/workflows/ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1753a0a38..d15c8ba2d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -369,11 +369,11 @@ jobs: - name: Get history and tags for SCM versioning to work run: | - ls - pwd - git config --global --add safe.directory /__w/mindquantum/mindquantum - git fetch --prune --unshallow - git fetch --depth=1 origin +refs/tags/*:refs/tags/* + ls -alth + # pwd + # git config --global --add safe.directory /__w/mindquantum/mindquantum + # git fetch --prune --unshallow + # git fetch --depth=1 origin +refs/tags/*:refs/tags/* - name: Prepare env run: > From e76cfe59155284c25548faf4d016d964c00ccf01 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Wed, 26 Jul 2023 09:50:31 +0800 Subject: [PATCH 036/100] install libomp for ubuntn clang --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d15c8ba2d..bce628252 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -367,6 +367,10 @@ jobs: run: | apt-get update && apt-get install -y git + - name: install libomp-dev + run: | + apt-get update && apt-get install -y libomp-dev + - name: Get history and tags for SCM versioning to work run: | ls -alth From b7f36f7fb3961f73055974401a2d33fab500b827 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Wed, 26 Jul 2023 10:05:10 +0800 Subject: [PATCH 037/100] set version for clang omp --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bce628252..e03bd50cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -367,9 +367,9 @@ jobs: run: | apt-get update && apt-get install -y git - - name: install libomp-dev + - name: install libomp-${{ matrix.clang }}-dev run: | - apt-get update && apt-get install -y libomp-dev + apt-get update && apt-get install -y libomp-${{ matrix.clang }}-dev - name: Get history and tags for SCM versioning to work run: | From 689b5f83b65ffd0a1b490aacba39e828a9502e91 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Wed, 26 Jul 2023 10:47:08 +0800 Subject: [PATCH 038/100] disable cxx for ci --- .github/workflows/ci.yml | 12 ++++++------ ccsrc/include/simulator/vector/vector_state.tpp | 4 ++-- ccsrc/lib/math/tensor/ops_cpu/memory_operator.cpp | 1 + .../cpu_common/cpu_densitymatrix_core_other_gate.cpp | 2 +- .../detail/cpu_common/cpu_vector_core_other_gate.cpp | 1 + .../vector/detail/gpu/gpu_vector_core_other_gate.cu | 1 + 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e03bd50cc..826ff177c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -562,13 +562,13 @@ jobs: CC: cl CXX: cl run: >- - ./build_locally.ps1 -Cxx -DebugCmake -Ninja -Test -CCache -OnlyPytest -NoGitee + ./build_locally.ps1 -DebugCmake -Ninja -Test -CCache -OnlyPytest -NoGitee -ConfigureOnly -C -Clean3rdParty -Prefix "${{ github.workspace }}/install" -CMakeNoRegistry -DUSE_PARALLEL_STL=OFF - name: Build - run: ./build_locally.ps1 -Cxx -DebugCmake -Ninja -Test -CCache + run: ./build_locally.ps1 -DebugCmake -Ninja -Test -CCache - name: Install run: ./build_locally.ps1 -Install @@ -654,13 +654,13 @@ jobs: CC: clang-cl CXX: clang-cl run: >- - ./build_locally.ps1 -Cxx -DebugCmake -Ninja -Test -CCache -OnlyPytest -NoGitee + ./build_locally.ps1 -DebugCmake -Ninja -Test -CCache -OnlyPytest -NoGitee -ConfigureOnly -C -Clean3rdParty -Prefix "${{ github.workspace }}/install" -CMakeNoRegistry -Verbose -DUSE_PARALLEL_STL=OFF - name: Build - run: ./build_locally.ps1 -Cxx -DebugCmake -Ninja -Test -CCache -Verbose + run: ./build_locally.ps1 -DebugCmake -Ninja -Test -CCache -Verbose - name: Install run: ./build_locally.ps1 -Install @@ -753,13 +753,13 @@ jobs: - name: Configure run: >- - ./build_locally.ps1 -Cxx -DebugCmake -Ninja -Test -OnlyPytest -NoGitee + ./build_locally.ps1 -DebugCmake -Ninja -Test -OnlyPytest -NoGitee -ConfigureOnly -C -Clean3rdParty -Prefix "${{ github.workspace }}/install" -CMakeNoRegistry --% -G "MinGW Makefiles" -DUSE_PARALLEL_STL=OFF - name: Build - run: ./build_locally.ps1 -Cxx -DebugCmake -Ninja -Test + run: ./build_locally.ps1 -DebugCmake -Ninja -Test - name: Install run: ./build_locally.ps1 -Install diff --git a/ccsrc/include/simulator/vector/vector_state.tpp b/ccsrc/include/simulator/vector/vector_state.tpp index 26656709f..b2281905a 100644 --- a/ccsrc/include/simulator/vector/vector_state.tpp +++ b/ccsrc/include/simulator/vector/vector_state.tpp @@ -1117,8 +1117,8 @@ auto VectorState::GetExpectationWithGradParameterShiftOneMulti( for (auto& gate : circ) { if (gate->GradRequired()) { auto p_gate = static_cast(gate.get()); - auto pr_shift = M_PI_2; - auto coeff = 0.5; + calc_type pr_shift = M_PI_2; + calc_type coeff = 0.5; if (gate->id_ == GateID::CUSTOM) { auto p_gate = static_cast(gate.get()); pr_shift = 0.001; diff --git a/ccsrc/lib/math/tensor/ops_cpu/memory_operator.cpp b/ccsrc/lib/math/tensor/ops_cpu/memory_operator.cpp index 82b4cd09c..715d6a5f4 100644 --- a/ccsrc/lib/math/tensor/ops_cpu/memory_operator.cpp +++ b/ccsrc/lib/math/tensor/ops_cpu/memory_operator.cpp @@ -14,6 +14,7 @@ #include "math/tensor/ops_cpu/memory_operator.hpp" +#include #include #include "math/tensor/traits.hpp" diff --git a/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_other_gate.cpp b/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_other_gate.cpp index e94ef560e..20f9f2b1b 100644 --- a/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_other_gate.cpp +++ b/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_other_gate.cpp @@ -19,8 +19,8 @@ # include "simulator/densitymatrix/detail/cpu_densitymatrix_arm_double_policy.hpp" # include "simulator/densitymatrix/detail/cpu_densitymatrix_arm_float_policy.hpp" #endif +#include "ops/gates.hpp" #include "simulator/densitymatrix/detail/cpu_densitymatrix_policy.hpp" - namespace mindquantum::sim::densitymatrix::detail { template void CPUDensityMatrixPolicyBase::ApplyH(qs_data_p_t* qs_p, const qbits_t& objs, diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_other_gate.cpp b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_other_gate.cpp index 6780531ac..df8508f32 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_other_gate.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_other_gate.cpp @@ -20,6 +20,7 @@ # include "simulator/vector/detail/cpu_vector_arm_double_policy.hpp" # include "simulator/vector/detail/cpu_vector_arm_float_policy.hpp" #endif +#include "ops/gates.hpp" #include "simulator/vector/detail/cpu_vector_policy.hpp" namespace mindquantum::sim::vector::detail { template diff --git a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_other_gate.cu b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_other_gate.cu index cd0c758d1..8c058a4ab 100644 --- a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_other_gate.cu +++ b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_other_gate.cu @@ -15,6 +15,7 @@ #include "config/openmp.hpp" +#include "ops/gates.hpp" #include "simulator/utils.hpp" #include "simulator/vector/detail/gpu_vector_double_policy.cuh" #include "simulator/vector/detail/gpu_vector_float_policy.cuh" From 43c5a2f22e6a2735c22c5a666b2596e49da9d10c Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Wed, 26 Jul 2023 11:13:07 +0800 Subject: [PATCH 039/100] disable cxx test in ci --- .github/workflows/ci.yml | 12 ++++++------ ccsrc/lib/math/tensor/CMakeLists.txt | 6 ++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 826ff177c..9e37911f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -562,13 +562,13 @@ jobs: CC: cl CXX: cl run: >- - ./build_locally.ps1 -DebugCmake -Ninja -Test -CCache -OnlyPytest -NoGitee + ./build_locally.ps1 -DebugCmake -Ninja -CCache -OnlyPytest -NoGitee -ConfigureOnly -C -Clean3rdParty -Prefix "${{ github.workspace }}/install" -CMakeNoRegistry -DUSE_PARALLEL_STL=OFF - name: Build - run: ./build_locally.ps1 -DebugCmake -Ninja -Test -CCache + run: ./build_locally.ps1 -DebugCmake -Ninja -CCache - name: Install run: ./build_locally.ps1 -Install @@ -654,13 +654,13 @@ jobs: CC: clang-cl CXX: clang-cl run: >- - ./build_locally.ps1 -DebugCmake -Ninja -Test -CCache -OnlyPytest -NoGitee + ./build_locally.ps1 -DebugCmake -Ninja -CCache -OnlyPytest -NoGitee -ConfigureOnly -C -Clean3rdParty -Prefix "${{ github.workspace }}/install" -CMakeNoRegistry -Verbose -DUSE_PARALLEL_STL=OFF - name: Build - run: ./build_locally.ps1 -DebugCmake -Ninja -Test -CCache -Verbose + run: ./build_locally.ps1 -DebugCmake -Ninja -CCache -Verbose - name: Install run: ./build_locally.ps1 -Install @@ -753,13 +753,13 @@ jobs: - name: Configure run: >- - ./build_locally.ps1 -DebugCmake -Ninja -Test -OnlyPytest -NoGitee + ./build_locally.ps1 -DebugCmake -Ninja -OnlyPytest -NoGitee -ConfigureOnly -C -Clean3rdParty -Prefix "${{ github.workspace }}/install" -CMakeNoRegistry --% -G "MinGW Makefiles" -DUSE_PARALLEL_STL=OFF - name: Build - run: ./build_locally.ps1 -DebugCmake -Ninja -Test + run: ./build_locally.ps1 -DebugCmake -Ninja - name: Install run: ./build_locally.ps1 -Install diff --git a/ccsrc/lib/math/tensor/CMakeLists.txt b/ccsrc/lib/math/tensor/CMakeLists.txt index a116da0d1..63e506248 100644 --- a/ccsrc/lib/math/tensor/CMakeLists.txt +++ b/ccsrc/lib/math/tensor/CMakeLists.txt @@ -20,10 +20,8 @@ target_sources(mq_math PRIVATE ${CMAKE_CURRENT_LIST_DIR}/traits.cpp ${CMAKE_CURRENT_LIST_DIR}/tensor.cpp ${CMAKE_CURRENT_LIST_DIR}/csr_matrix.cpp) -target_compile_options(mq_math PUBLIC "-Wno-return-type") -target_compile_options(mq_math PUBLIC "-Wno-narrowing") -target_compile_options(mq_math PUBLIC "-Wno-pointer-arith") -target_compile_options(mq_math PUBLIC "-g") +# target_compile_options(mq_math PUBLIC "-Wno-return-type") target_compile_options(mq_math PUBLIC "-Wno-narrowing") +# target_compile_options(mq_math PUBLIC "-Wno-pointer-arith") add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/ops) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/ops_cpu) From e69c2ef146a6e588bcdda90f21ca89b76f4227a6 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Wed, 26 Jul 2023 11:18:55 +0800 Subject: [PATCH 040/100] remove libssp --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9e37911f4..b5e12c446 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -798,7 +798,6 @@ jobs: patch make mingw-w64-clang-x86_64-toolchain - mingw-w64-clang-x86_64-libssp mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-ccache mingw-w64-clang-x86_64-gmp From b7908416fb92a836375ceea9b7e5d78733724632 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Wed, 26 Jul 2023 11:38:17 +0800 Subject: [PATCH 041/100] fix warning --- ccsrc/include/math/tensor/ops_cpu/basic_math.hpp | 3 ++- ccsrc/lib/math/tensor/ops/concrete_tensor.cpp | 2 ++ ccsrc/lib/math/tensor/ops_cpu/basic_math.cpp | 3 +++ ccsrc/lib/math/tensor/traits.cpp | 3 +++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ccsrc/include/math/tensor/ops_cpu/basic_math.hpp b/ccsrc/include/math/tensor/ops_cpu/basic_math.hpp index c064f6c6d..6194c106b 100644 --- a/ccsrc/include/math/tensor/ops_cpu/basic_math.hpp +++ b/ccsrc/include/math/tensor/ops_cpu/basic_math.hpp @@ -38,7 +38,8 @@ struct cast_value { } else if constexpr (!is_complex_v && is_complex_v) { return std::real(a); } else if constexpr (is_complex_v && is_complex_v) { - return {std::real(a), std::imag(a)}; + using real_des_t = to_device_t>>; + return {static_cast(std::real(a)), static_cast(std::imag(a))}; } else { return a; } diff --git a/ccsrc/lib/math/tensor/ops/concrete_tensor.cpp b/ccsrc/lib/math/tensor/ops/concrete_tensor.cpp index 5abb8f676..f44bf6d4a 100644 --- a/ccsrc/lib/math/tensor/ops/concrete_tensor.cpp +++ b/ccsrc/lib/math/tensor/ops/concrete_tensor.cpp @@ -29,12 +29,14 @@ Tensor zeros(size_t len, TDtype dtype, TDevice device) { return cpu::zeros(len, dtype); } else { } + return Tensor(); } Tensor ones(size_t len, TDtype dtype, TDevice device) { if (device == TDevice::CPU) { return cpu::ones(len, dtype); } else { } + return Tensor(); } } // namespace tensor::ops #endif diff --git a/ccsrc/lib/math/tensor/ops_cpu/basic_math.cpp b/ccsrc/lib/math/tensor/ops_cpu/basic_math.cpp index aba3a6d60..88c7895e6 100644 --- a/ccsrc/lib/math/tensor/ops_cpu/basic_math.cpp +++ b/ccsrc/lib/math/tensor/ops_cpu/basic_math.cpp @@ -15,6 +15,7 @@ #include "math/tensor/ops_cpu/basic_math.hpp" #include "math/tensor/csr_matrix.hpp" +#include "math/tensor/matrix.hpp" #include "math/tensor/tensor.hpp" #include "math/tensor/traits.hpp" @@ -44,6 +45,7 @@ Matrix MatMul(const Matrix& m1, const Matrix& m2) { MM_MatMul(TDtype::Complex64); MM_MatMul(TDtype::Complex128); } + return Matrix(); } #undef MM_MatMul @@ -78,6 +80,7 @@ Tensor MatMul(const CsrMatrix& m1, const Tensor& m2) { CSR_MatMul(TDtype::Complex64); CSR_MatMul(TDtype::Complex128); } + return Tensor(); } #undef CSR_MatMul } // namespace tensor::ops::cpu diff --git a/ccsrc/lib/math/tensor/traits.cpp b/ccsrc/lib/math/tensor/traits.cpp index 311af9c4e..f8964db15 100644 --- a/ccsrc/lib/math/tensor/traits.cpp +++ b/ccsrc/lib/math/tensor/traits.cpp @@ -43,6 +43,7 @@ TDtype ToRealType(TDtype dtype) { case TDtype::Complex128: return to_real_dtype_t; } + return TDtype::Float64; } TDtype ToComplexType(TDtype dtype) { @@ -55,6 +56,7 @@ TDtype ToComplexType(TDtype dtype) { case TDtype::Float64: return TDtype::Complex128; } + return TDtype::Complex128; } bool IsRealType(TDtype dtype) { @@ -139,5 +141,6 @@ TDtype upper_type_v(TDtype t1, TDtype t2) { UPPER_TYPE(TDtype::Complex128); UPPER_TYPE(TDtype::Complex64); } + return TDtype::Complex128; } } // namespace tensor From acc594d8ae154331c45fd01e25b4146ce7b8dbc8 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Wed, 26 Jul 2023 11:47:09 +0800 Subject: [PATCH 042/100] fix warning --- ccsrc/include/math/tensor/ops_cpu/basic_math.hpp | 16 ---------------- .../math/tensor/ops_cpu/memory_operator.hpp | 3 ++- ccsrc/include/math/tensor/ops_cpu/utils.hpp | 15 ++++++++------- ccsrc/lib/math/tensor/ops/memory_operator.cpp | 15 ++++++++++++++- 4 files changed, 24 insertions(+), 25 deletions(-) diff --git a/ccsrc/include/math/tensor/ops_cpu/basic_math.hpp b/ccsrc/include/math/tensor/ops_cpu/basic_math.hpp index 6194c106b..ff5f4f4da 100644 --- a/ccsrc/include/math/tensor/ops_cpu/basic_math.hpp +++ b/ccsrc/include/math/tensor/ops_cpu/basic_math.hpp @@ -30,22 +30,6 @@ #include "math/tensor/traits.hpp" namespace tensor::ops::cpu { -template -struct cast_value { - des_t operator()(const src_t& a) const { - if constexpr (std::is_same_v) { - return a; - } else if constexpr (!is_complex_v && is_complex_v) { - return std::real(a); - } else if constexpr (is_complex_v && is_complex_v) { - using real_des_t = to_device_t>>; - return {static_cast(std::real(a)), static_cast(std::imag(a))}; - } else { - return a; - } - } -}; - template class binary_ops> void InplaceBinary(void* data, size_t len, void* other) { diff --git a/ccsrc/include/math/tensor/ops_cpu/memory_operator.hpp b/ccsrc/include/math/tensor/ops_cpu/memory_operator.hpp index 64a9110d3..6b01875d9 100644 --- a/ccsrc/include/math/tensor/ops_cpu/memory_operator.hpp +++ b/ccsrc/include/math/tensor/ops_cpu/memory_operator.hpp @@ -56,8 +56,9 @@ Tensor cast_to(void* data, size_t len) { auto c_data = reinterpret_cast(data); auto out = cpu::init(len); auto c_out = reinterpret_cast(out.data); + auto caster = cast_value, to_device_t>(); for (size_t i = 0; i < len; i++) { - c_out[i] = number_convert, to_device_t>::apply(c_data[i]); + c_out[i] = caster(c_data[i]); } return out; } diff --git a/ccsrc/include/math/tensor/ops_cpu/utils.hpp b/ccsrc/include/math/tensor/ops_cpu/utils.hpp index 3a7ae6c18..58f3787d2 100644 --- a/ccsrc/include/math/tensor/ops_cpu/utils.hpp +++ b/ccsrc/include/math/tensor/ops_cpu/utils.hpp @@ -36,15 +36,16 @@ static constexpr bool is_complex_v = is_complex::v; // ----------------------------------------------------------------------------- -template -struct number_convert { - static des apply(const src& a) { - if constexpr (std::is_same_v) { +template +struct cast_value { + des_t operator()(const src_t& a) const { + if constexpr (std::is_same_v) { return a; - } else if constexpr (is_complex_v && !is_complex_v) { + } else if constexpr (!is_complex_v && is_complex_v) { return std::real(a); - } else if constexpr (is_complex_v && is_complex_v) { - return {std::real(a), std::imag(a)}; + } else if constexpr (is_complex_v && is_complex_v) { + using real_des_t = to_device_t>>; + return {static_cast(std::real(a)), static_cast(std::imag(a))}; } else { return a; } diff --git a/ccsrc/lib/math/tensor/ops/memory_operator.cpp b/ccsrc/lib/math/tensor/ops/memory_operator.cpp index af657368c..243e22f40 100644 --- a/ccsrc/lib/math/tensor/ops/memory_operator.cpp +++ b/ccsrc/lib/math/tensor/ops/memory_operator.cpp @@ -24,18 +24,21 @@ Tensor init(size_t len, TDtype dtype, TDevice device) { return cpu::init(len, dtype); } else { } + return Tensor(); } Tensor cast_to(const Tensor& t, TDtype target_dtype) { if (t.device == TDevice::CPU) { return cpu::cast_to(t, target_dtype); } + return Tensor(); } std::string to_string(const Tensor& t, bool simplify) { if (t.device == TDevice::CPU) { return cpu::to_string(t, simplify); } + return ""; } void destroy(Tensor* t) { @@ -52,6 +55,7 @@ Tensor init_with_value(float a, TDevice device) { return cpu::init_with_value(a); } else { } + return Tensor(); } Tensor init_with_value(double a, TDevice device) { @@ -59,6 +63,7 @@ Tensor init_with_value(double a, TDevice device) { return cpu::init_with_value(a); } else { } + return Tensor(); } Tensor init_with_value(const std::complex& a, TDevice device) { @@ -66,6 +71,7 @@ Tensor init_with_value(const std::complex& a, TDevice device) { return cpu::init_with_value(a); } else { } + return Tensor(); } Tensor init_with_value(const std::complex& a, TDevice device) { @@ -73,6 +79,7 @@ Tensor init_with_value(const std::complex& a, TDevice device) { return cpu::init_with_value(a); } else { } + return Tensor(); } Tensor init_with_vector(const std::vector& a, TDevice device) { @@ -80,24 +87,28 @@ Tensor init_with_vector(const std::vector& a, TDevice device) { return cpu::init_with_vector(a); } else { } + return Tensor(); } Tensor init_with_vector(const std::vector& a, TDevice device) { if (device == TDevice::CPU) { return cpu::init_with_vector(a); } else { } + return Tensor(); } Tensor init_with_vector(const std::vector>& a, TDevice device) { if (device == TDevice::CPU) { return cpu::init_with_vector(a); } else { } + return Tensor(); } Tensor init_with_vector(const std::vector>& a, TDevice device) { if (device == TDevice::CPU) { return cpu::init_with_vector(a); } else { } + return Tensor(); } // ----------------------------------------------------------------------------- @@ -107,6 +118,7 @@ Tensor copy(const Tensor& t) { return cpu::copy(t); } else { } + return Tensor(); } // ----------------------------------------------------------------------------- @@ -145,10 +157,11 @@ void set(Tensor* t, const Tensor& source, size_t idx) { // ----------------------------------------------------------------------------- Tensor get(const Tensor& t, size_t idx) { - if (t.device == TDevice::GPU) { + if (t.device == TDevice::CPU) { return cpu::get(t, idx); } else { } + return Tensor(); } } // namespace tensor::ops From 7bba084380d27457bfbacd662a2897894cc9ded8 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Wed, 26 Jul 2023 12:21:39 +0800 Subject: [PATCH 043/100] fix warning --- .cppcheck.suppressions | 2 ++ .../math/tensor/ops_cpu/advance_math.hpp | 1 + .../math/tensor/ops_cpu/basic_math.hpp | 6 ++++ .../detail/cpu_densitymatrix_policy.hpp | 4 ++- .../vector/detail/cpu_vector_policy.hpp | 4 ++- .../math/operators/fermion_operator_view.cpp | 5 +-- .../math/operators/qubit_operator_view.cpp | 5 +-- ccsrc/lib/math/tensor/ops/advance_math.cpp | 11 +++++++ ccsrc/lib/math/tensor/ops/basic_math.cpp | 31 +++++++++++++++++++ .../lib/math/tensor/ops_cpu/advance_math.cpp | 6 ++++ .../math/tensor/ops_cpu/concrete_tensor.cpp | 1 + .../math/tensor/ops_cpu/memory_operator.cpp | 3 ++ 12 files changed, 73 insertions(+), 6 deletions(-) diff --git a/.cppcheck.suppressions b/.cppcheck.suppressions index cfee1fe53..b952e10e0 100644 --- a/.cppcheck.suppressions +++ b/.cppcheck.suppressions @@ -68,6 +68,8 @@ unknownMacro:ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_matrix unknownMacro:ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_x_like.cpp unknownMacro:ccsrc/lib/simulator/vector/detail/cpu_avx_double/cpu_vector_core_matrix_gate.cpp unknownMacro:ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_matrix_gate.cpp +unknownMacro:ccsrc/include/simulator/densitymatrix/detail/cpu_densitymatrix_policy.hpp +unknownMacro:ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp unreadVariable:ccsrc/lib/experimental/decompositions/time_evolution.cpp diff --git a/ccsrc/include/math/tensor/ops_cpu/advance_math.hpp b/ccsrc/include/math/tensor/ops_cpu/advance_math.hpp index 44493960a..1307dd92a 100644 --- a/ccsrc/include/math/tensor/ops_cpu/advance_math.hpp +++ b/ccsrc/include/math/tensor/ops_cpu/advance_math.hpp @@ -265,6 +265,7 @@ Tensor ElementFunc(const Tensor& t, TDtype out_dtype, F&& func) { } } break; } + return Tensor(); } // ----------------------------------------------------------------------------- diff --git a/ccsrc/include/math/tensor/ops_cpu/basic_math.hpp b/ccsrc/include/math/tensor/ops_cpu/basic_math.hpp index ff5f4f4da..c23f08d0f 100644 --- a/ccsrc/include/math/tensor/ops_cpu/basic_math.hpp +++ b/ccsrc/include/math/tensor/ops_cpu/basic_math.hpp @@ -157,6 +157,7 @@ Tensor generate_binary(void* data, TDtype dtype, size_t len, T a) { return GenerateBinary(data, len, other); } } + return Tensor(); } // vector = number + vector @@ -178,6 +179,7 @@ Tensor generate_binary_rev(void* data, TDtype dtype, size_t len, T a) { return GenerateBinary(data, len, other); } } + return Tensor(); } // ----------------------------------------------------------------------------- @@ -250,6 +252,7 @@ Tensor generate_binary_array(void* data, TDtype dtype, size_t len, void* other) return GenerateBinary(data, len, other); } } + return Tensor(); } // vector = vector2 + vector1 @@ -270,6 +273,7 @@ Tensor generate_binary_array_rev(void* data, TDtype dtype, size_t len, void* oth return GenerateBinary(data, len, other); } } + return Tensor(); } // ----------------------------------------------------------------------------- @@ -445,6 +449,7 @@ Tensor generate_binary_array(void* data, TDtype src, size_t len, const Tensor& a } else { throw std::runtime_error("Dimension miss match."); } + return Tensor(); } template