From d72f4e213c13e654c151b2ca40d11f58164a4cf2 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Sat, 6 May 2023 19:45:59 +0800 Subject: [PATCH 1/8] use nullptr to work as zero state --- .cppcheck.suppressions | 1 + .jenkins/check/config/filter_cppcheck.txt | 1 + .jenkins/check/config/filter_cpplint.txt | 2 + ccsrc/include/core/sparse/algo.hpp | 53 +++++++++++ .../vector/detail/cpu_vector_policy.hpp | 14 ++- .../vector/detail/gpu_vector_policy.cuh | 15 ++- .../include/simulator/vector/vector_state.hpp | 32 +------ .../include/simulator/vector/vector_state.tpp | 93 ++++++++++++++++++- .../cpu_common/cpu_vector_core_dot_like.cpp | 21 +++++ .../cpu_common/cpu_vector_core_policy.cpp | 71 +++++++++++--- .../detail/gpu/gpu_vector_core_dot_like.cu | 42 +++++++++ .../detail/gpu/gpu_vector_core_policy.cu | 88 ++++++++++++++---- 12 files changed, 371 insertions(+), 62 deletions(-) diff --git a/.cppcheck.suppressions b/.cppcheck.suppressions index a9fb5ecb6..d1c685cdb 100644 --- a/.cppcheck.suppressions +++ b/.cppcheck.suppressions @@ -65,6 +65,7 @@ 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/.jenkins/check/config/filter_cppcheck.txt b/.jenkins/check/config/filter_cppcheck.txt index 6da280ddf..0024c9d1c 100644 --- a/.jenkins/check/config/filter_cppcheck.txt +++ b/.jenkins/check/config/filter_cppcheck.txt @@ -76,6 +76,7 @@ "mindquantum/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_swap_like.cpp" "unknownMacro" "mindquantum/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_gate_expect.cpp" "unknownMacro" "mindquantum/ccsrc/lib/simulator/densitymatrix/detail/cpu_common/cpu_densitymatrix_core_matrix_gate.cpp" "unknownMacro" +"mindquantum/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp" "unknownMacro" "mindquantum/ccsrc/lib/experimental/decompositions/time_evolution.cpp" "unreadVariable" diff --git a/.jenkins/check/config/filter_cpplint.txt b/.jenkins/check/config/filter_cpplint.txt index e1192817e..40b07edae 100644 --- a/.jenkins/check/config/filter_cpplint.txt +++ b/.jenkins/check/config/filter_cpplint.txt @@ -62,3 +62,5 @@ "mindquantum/ccsrc/include/simulator/alignedallocator.hpp" "whitespace/parens" "mindquantum/ccsrc/lib/math/operators/transform/bravyi_kitaev_superfast.cpp" "runtime/references" "mindquantum/ccsrc/python/math/lib/bind_math.cpp" "runtime/references" +"mindquantum/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_policy.cpp" "runtime/references" +"mindquantum/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp" "runtime/references" diff --git a/ccsrc/include/core/sparse/algo.hpp b/ccsrc/include/core/sparse/algo.hpp index b1d0bc6bd..30747b0e6 100644 --- a/ccsrc/include/core/sparse/algo.hpp +++ b/ccsrc/include/core/sparse/algo.hpp @@ -166,6 +166,29 @@ T2 *Csr_Dot_Vec(std::shared_ptr> a, T2 *vec) { return reinterpret_cast(new_vec); } +template +CT ExpectationOfCsr(std::shared_ptr> a, T2 *bra, T2 *ket) { + auto dim = a->dim_; + auto c_bra = reinterpret_cast>(bra); + auto c_ket = reinterpret_cast>(ket); + auto data = a->data_; + auto indptr = a->indptr_; + auto indices = a->indices_; + T2 res_real = 0, res_imag = 0; + THRESHOLD_OMP( + MQ_DO_PRAGMA(omp parallel for reduction(+:res_real, res_imag) schedule(static)), dim, 1UL << nQubitTh, + for (Index i = 0; i < dim; i++) { + CT sum = {0.0, 0.0}; + for (Index j = indptr[i]; j < indptr[i + 1]; j++) { + sum += data[j] * c_ket[indices[j]]; + } + auto tmp = std::conj(c_bra[i]) * sum; + res_real += std::real(tmp); + res_imag += std::imag(tmp); + }) + return {res_real, res_imag}; +} + template T2 *Csr_Dot_Vec(std::shared_ptr> a, std::shared_ptr> b, T2 *vec) { auto dim = a->dim_; @@ -192,5 +215,35 @@ T2 *Csr_Dot_Vec(std::shared_ptr> a, std::shared_ptr(new_vec); } + +template +CT ExpectationOfCsr(std::shared_ptr> a, std::shared_ptr> b, T2 *bra, T2 *ket) { + auto dim = a->dim_; + auto c_bra = reinterpret_cast>(bra); + auto c_ket = reinterpret_cast>(ket); + auto data = a->data_; + auto indptr = a->indptr_; + auto indices = a->indices_; + auto data_b = b->data_; + auto indptr_b = b->indptr_; + auto indices_b = b->indices_; + T2 res_real = 0, res_imag = 0; + + THRESHOLD_OMP( + MQ_DO_PRAGMA(omp parallel for reduction(+:res_real, res_imag) schedule(static)), dim, 1UL << nQubitTh, + for (Index i = 0; i < dim; i++) { + CT sum = {0.0, 0.0}; + for (Index j = indptr[i]; j < indptr[i + 1]; j++) { + sum += data[j] * c_ket[indices[j]]; + } + for (Index j = indptr_b[i]; j < indptr_b[i + 1]; j++) { + sum += data_b[j] * c_ket[indices_b[j]]; + } + auto tmp = std::conj(c_bra[i]) * sum; + res_real += std::real(tmp); + res_imag += std::imag(tmp); + }) + return {res_real, res_imag}; +} } // namespace mindquantum::sparse #endif // MINDQUANTUM_SPARSE_ALGO_H_ diff --git a/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp b/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp index 36350ae36..d37d47259 100644 --- a/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp +++ b/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp @@ -52,8 +52,8 @@ struct CPUVectorPolicyBase { // ======================================================================================================== static qs_data_p_t InitState(index_t dim, bool zero_state = true); - static void Reset(qs_data_p_t qs, index_t dim); - static void FreeState(qs_data_p_t qs); + static void Reset(qs_data_p_t& qs, index_t dim); + static void FreeState(qs_data_p_t& qs); static void Display(qs_data_p_t qs, qbit_t n_qubits, qbit_t q_limit = 10); static void SetToZeroExcept(qs_data_p_t qs, index_t ctrl_mask, index_t dim); template @@ -75,6 +75,8 @@ struct CPUVectorPolicyBase { static VT GetQS(qs_data_p_t qs, index_t dim); static void SetQS(qs_data_p_t qs, const VT& qs_out, index_t dim); static qs_data_p_t ApplyTerms(qs_data_p_t qs, const std::vector>& ham, index_t dim); + static py_qs_data_t ExpectationOfTerms(qs_data_p_t bra, qs_data_p_t ket, + const std::vector>& ham, index_t dim); static qs_data_p_t Copy(qs_data_p_t qs, index_t dim); template static py_qs_data_t ConditionVdot(qs_data_p_t bra, qs_data_p_t ket, index_t dim); @@ -86,6 +88,11 @@ struct CPUVectorPolicyBase { static qs_data_p_t CsrDotVec(const std::shared_ptr>& a, const std::shared_ptr>& b, qs_data_p_t vec, index_t dim); + static py_qs_data_t ExpectationOfCsr(const std::shared_ptr>& a, qs_data_p_t bra, + qs_data_p_t ket, index_t dim); + static py_qs_data_t ExpectationOfCsr(const std::shared_ptr>& a, + const std::shared_ptr>& b, qs_data_p_t bra, + qs_data_p_t ket, index_t dim); // X like operator // ======================================================================================================== @@ -183,6 +190,9 @@ struct CastTo { static constexpr tensor::TDtype src_dtype = policy_src::dtype; static constexpr tensor::TDtype des_dtype = policy_des::dtype; static typename policy_des::qs_data_p_t cast(typename policy_src::qs_data_p_t qs, size_t dim) { + if (qs == nullptr) { + return nullptr; + } if constexpr (std::is_same_v) { return policy_des::Copy(qs, dim); } else { diff --git a/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh b/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh index babea8294..99b91724c 100644 --- a/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh +++ b/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh @@ -43,8 +43,8 @@ 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, index_t dim); - static void FreeState(qs_data_p_t qs); + static void Reset(qs_data_p_t& qs, index_t dim); + static void FreeState(qs_data_p_t& qs); static void Display(qs_data_p_t qs, qbit_t n_qubits, qbit_t q_limit = 10); static void SetToZeroExcept(qs_data_p_t qs, index_t ctrl_mask, index_t dim); template @@ -66,6 +66,8 @@ struct GPUVectorPolicyBase { static py_qs_datas_t GetQS(qs_data_p_t qs, index_t dim); static void SetQS(qs_data_p_t qs, const py_qs_datas_t& qs_out, index_t dim); static qs_data_p_t ApplyTerms(qs_data_p_t qs, const std::vector>& ham, index_t dim); + static py_qs_data_t ExpectationOfTerms(qs_data_p_t bra, qs_data_p_t ket, + const std::vector>& ham, index_t dim); static qs_data_p_t Copy(qs_data_p_t qs, index_t dim); template static py_qs_data_t ConditionVdot(qs_data_p_t bra, qs_data_p_t ket, index_t dim); @@ -77,7 +79,11 @@ struct GPUVectorPolicyBase { static qs_data_p_t CsrDotVec(const std::shared_ptr>& a, const std::shared_ptr>& b, qs_data_p_t vec, index_t dim); - + static py_qs_data_t ExpectationOfCsr(const std::shared_ptr>& a, qs_data_p_t bra, + qs_data_p_t ket, index_t dim); + static py_qs_data_t ExpectationOfCsr(const std::shared_ptr>& a, + const std::shared_ptr>& b, qs_data_p_t bra, + qs_data_p_t ket, index_t dim); // X like operator // ======================================================================================================== @@ -209,6 +215,9 @@ struct CastTo { static constexpr tensor::TDtype src_dtype = policy_src::dtype; static constexpr tensor::TDtype des_dtype = policy_des::dtype; static typename policy_des::qs_data_p_t cast(typename policy_src::qs_data_p_t qs, size_t dim) { + if (qs == nullptr) { + return nullptr; + } if constexpr (std::is_same_v) { return policy_des::Copy(qs, dim); } diff --git a/ccsrc/include/simulator/vector/vector_state.hpp b/ccsrc/include/simulator/vector/vector_state.hpp index e6252f499..fdb2e7c14 100644 --- a/ccsrc/include/simulator/vector/vector_state.hpp +++ b/ccsrc/include/simulator/vector/vector_state.hpp @@ -135,34 +135,14 @@ class VectorState { //! Get expectation of given hamiltonian virtual py_qs_data_t GetExpectation(const Hamiltonian& ham, const circuit_t& circ, - const parameter::ParameterResolver& pr) { - auto ket = *this; - ket.ApplyCircuit(circ, pr); - auto bra = ket; - ket.ApplyHamiltonian(ham); - return qs_policy_t::Vdot(bra.qs, ket.qs, dim); - } + const parameter::ParameterResolver& pr); virtual py_qs_data_t GetExpectation(const Hamiltonian& ham, const circuit_t& circ_right, - const circuit_t& circ_left, const parameter::ParameterResolver& pr) { - auto ket = *this; - auto bra = *this; - ket.ApplyCircuit(circ_right, pr); - ket.ApplyHamiltonian(ham); - bra.ApplyCircuit(circ_left, pr); - return qs_policy_t::Vdot(bra.qs, ket.qs, dim); - } + const circuit_t& circ_left, const parameter::ParameterResolver& pr); virtual py_qs_data_t GetExpectation(const Hamiltonian& ham, const circuit_t& circ_right, const circuit_t& circ_left, const derived_t& simulator_left, - const parameter::ParameterResolver& pr) { - auto ket = *this; - auto bra = simulator_left; - ket.ApplyCircuit(circ_right, pr); - ket.ApplyHamiltonian(ham); - bra.ApplyCircuit(circ_left, pr); - return qs_policy_t::Vdot(bra.qs, ket.qs, dim); - } + const parameter::ParameterResolver& pr); //! Get the expectation of hamiltonian //! Here a single hamiltonian and single parameter data are needed @@ -176,6 +156,7 @@ class VectorState { virtual VVT GetExpectationWithGradOneMulti( const std::vector>>& hams, const circuit_t& circ, const circuit_t& herm_circ, const parameter::ParameterResolver& pr, const MST& p_map, int n_thread); + //! Get the expectation of hamiltonian //! Here multiple hamiltonian and multiple parameters are needed virtual VT> GetExpectationWithGradMultiMulti( @@ -207,10 +188,7 @@ class VectorState { const MST& key_map, unsigned seed); template class cast_policy> - VectorState astype(unsigned seed) { - return VectorState(cast_policy::cast(this->qs, this->dim), this->n_qubits, - seed); - } + VectorState astype(unsigned seed); protected: qs_data_p_t qs = nullptr; diff --git a/ccsrc/include/simulator/vector/vector_state.tpp b/ccsrc/include/simulator/vector/vector_state.tpp index b384cebf9..0136b32df 100644 --- a/ccsrc/include/simulator/vector/vector_state.tpp +++ b/ccsrc/include/simulator/vector/vector_state.tpp @@ -52,7 +52,6 @@ namespace mindquantum::sim::vector::detail { template VectorState::VectorState(qbit_t n_qubits, unsigned seed) : n_qubits(n_qubits), dim(1UL << n_qubits), seed(seed), rnd_eng_(seed) { - qs = qs_policy_t::InitState(dim); std::uniform_real_distribution dist(0., 1.); rng_ = std::bind(dist, std::ref(rnd_eng_)); } @@ -144,12 +143,18 @@ auto VectorState::GetQS() const -> VT { template void VectorState::SetQS(const VT& qs_out) { + if (this->qs == nullptr) { + this->qs = qs_policy_t::InitState(dim); + } qs_policy_t::SetQS(qs, qs_out, dim); } template index_t VectorState::ApplyGate(const std::shared_ptr& gate, const parameter::ParameterResolver& pr, bool diff) { + if (this->qs == nullptr) { + this->qs = qs_policy_t::InitState(dim); + } auto id = gate->id_; switch (id) { case GateID::I: @@ -343,6 +348,9 @@ index_t VectorState::ApplyGate(const std::shared_ptr& g template auto VectorState::ApplyMeasure(const std::shared_ptr& gate) -> index_t { + if (this->qs == nullptr) { + this->qs = qs_policy_t::InitState(dim); + } index_t one_mask = (1UL << gate->obj_qubits_[0]); auto one_amp = qs_policy_t::ConditionalCollect(qs, one_mask, one_mask, true, dim).real(); index_t collapse_mask = (static_cast(rng_() < one_amp) << gate->obj_qubits_[0]); @@ -353,6 +361,9 @@ auto VectorState::ApplyMeasure(const std::shared_ptr& g template void VectorState::ApplyChannel(const std::shared_ptr& gate) { + if (this->qs == nullptr) { + this->qs = qs_policy_t::InitState(dim); + } auto id = gate->id_; switch (id) { case GateID::PL: @@ -372,6 +383,9 @@ void VectorState::ApplyChannel(const std::shared_ptr& g template void VectorState::ApplyPauliChannel(const std::shared_ptr& gate) { + if (this->qs == nullptr) { + this->qs = qs_policy_t::InitState(dim); + } double r = static_cast(rng_()); auto g = static_cast(gate.get()); auto it = std::lower_bound(g->cumulative_probs_.begin(), g->cumulative_probs_.end(), r); @@ -392,6 +406,9 @@ void VectorState::ApplyPauliChannel(const std::shared_ptr void VectorState::ApplyKrausChannel(const std::shared_ptr& gate) { + if (this->qs == nullptr) { + this->qs = qs_policy_t::InitState(dim); + } auto tmp_qs = qs_policy_t::InitState(dim); calc_type prob = 0; auto g = static_cast(gate.get()); @@ -414,6 +431,9 @@ void VectorState::ApplyKrausChannel(const std::shared_ptr void VectorState::ApplyDampingChannel(const std::shared_ptr& gate) { + if (this->qs == nullptr) { + this->qs = qs_policy_t::InitState(dim); + } calc_type reduced_factor_b_square = qs_policy_t::OneStateVdot(qs, qs, gate->obj_qubits_[0], dim).real(); calc_type reduced_factor_b = std::sqrt(reduced_factor_b_square); if (reduced_factor_b < 1e-8) { @@ -445,6 +465,68 @@ void VectorState::ApplyDampingChannel(const std::shared_ptr +auto VectorState::GetExpectation(const Hamiltonian& ham, const circuit_t& circ, + const parameter::ParameterResolver& pr) -> py_qs_data_t { + py_qs_data_t out; + auto ket = *this; + ket.ApplyCircuit(circ, pr); + if (ham.how_to_ == ORIGIN) { + out = qs_policy_t::ExpectationOfTerms(ket.qs, ket.qs, ham.ham_, dim); + } else if (ham.how_to_ == BACKEND) { + out = qs_policy_t::ExpectationOfCsr(ham.ham_sparse_main_, ham.ham_sparse_second_, ket.qs, ket.qs, dim); + } else { + out = qs_policy_t::ExpectationOfCsr(ham.ham_sparse_main_, ket.qs, ket.qs, dim); + } + return out; +} + +template +auto VectorState::GetExpectation(const Hamiltonian& ham, const circuit_t& circ_right, + const circuit_t& circ_left, const parameter::ParameterResolver& pr) + -> py_qs_data_t { + py_qs_data_t out; + + auto ket = *this; + auto bra = *this; + ket.ApplyCircuit(circ_right, pr); + bra.ApplyCircuit(circ_left, pr); + if (ham.how_to_ == ORIGIN) { + out = qs_policy_t::ExpectationOfTerms(bra.qs, ket.qs, ham.ham_, dim); + } else if (ham.how_to_ == BACKEND) { + out = qs_policy_t::ExpectationOfCsr(ham.ham_sparse_main_, ham.ham_sparse_second_, bra.qs, ket.qs, dim); + } else { + out = qs_policy_t::ExpectationOfCsr(ham.ham_sparse_main_, bra.qs, ket.qs, dim); + } + return out; +} + +template +auto VectorState::GetExpectation(const Hamiltonian& ham, const circuit_t& circ_right, + const circuit_t& circ_left, const derived_t& simulator_left, + const parameter::ParameterResolver& pr) -> py_qs_data_t { + auto ket = *this; + auto bra = simulator_left; + ket.ApplyCircuit(circ_right, pr); + bra.ApplyCircuit(circ_left, pr); + py_qs_data_t out; + if (ham.how_to_ == ORIGIN) { + out = qs_policy_t::ExpectationOfTerms(bra.qs, ket.qs, ham.ham_, dim); + } else if (ham.how_to_ == BACKEND) { + out = qs_policy_t::ExpectationOfCsr(ham.ham_sparse_main_, ham.ham_sparse_second_, bra.qs, ket.qs, dim); + } else { + out = qs_policy_t::ExpectationOfCsr(ham.ham_sparse_main_, bra.qs, ket.qs, dim); + } + return out; +} + +template +template class cast_policy> +auto VectorState::astype(unsigned seed) -> VectorState { + return VectorState(cast_policy::cast(this->qs, this->dim), this->n_qubits, + seed); +} + template auto VectorState::ExpectDiffGate(qs_data_p_t bra, qs_data_p_t ket, const std::shared_ptr& gate, const parameter::ParameterResolver& pr, index_t dim) -> tensor::Matrix { @@ -557,6 +639,9 @@ auto VectorState::ExpectDiffFSim(qs_data_p_t bra, qs_data_p_t ket, template std::map VectorState::ApplyCircuit(const circuit_t& circ, const parameter::ParameterResolver& pr) { + if (this->qs == nullptr) { + this->qs = qs_policy_t::InitState(dim); + } std::map result; for (auto& g : circ) { if (g->id_ == GateID::M) { @@ -570,6 +655,9 @@ std::map VectorState::ApplyCircuit(const circuit template void VectorState::ApplyHamiltonian(const Hamiltonian& ham) { + if (this->qs == nullptr) { + this->qs = qs_policy_t::InitState(dim); + } qs_data_p_t new_qs; if (ham.how_to_ == ORIGIN) { new_qs = qs_policy_t::ApplyTerms(qs, ham.ham_, dim); @@ -588,6 +676,9 @@ auto VectorState::GetCircuitMatrix(const circuit_t& circ, const pa VVT> out((1UL << n_qubits), VT>((1UL << n_qubits), 0)); for (size_t i = 0; i < (1UL << n_qubits); i++) { auto sim = VectorState(n_qubits, seed); + if (sim.qs == nullptr) { + sim.qs = qs_policy_t::InitState(dim); + } for (qbit_t j = 0; j < n_qubits; ++j) { if ((i >> j) & 1) { qs_policy_t_::ApplyX(sim.qs, qbits_t({j}), qbits_t({}), sim.dim); diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_dot_like.cpp b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_dot_like.cpp index f21c2ab0e..daf65e584 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_dot_like.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_dot_like.cpp @@ -113,6 +113,27 @@ auto CPUVectorPolicyBase::CsrDotVec(const std::shared_ptr< return reinterpret_cast(out); } +template +auto CPUVectorPolicyBase::ExpectationOfCsr( + const std::shared_ptr>& a, qs_data_p_t bra, qs_data_p_t ket, index_t dim) + -> py_qs_data_t { + if (dim != a->dim_) { + throw std::runtime_error("Sparse hamiltonian size not match with quantum state size."); + } + return sparse::ExpectationOfCsr(a, reinterpret_cast(bra), + reinterpret_cast(ket)); +} +template +auto CPUVectorPolicyBase::ExpectationOfCsr( + const std::shared_ptr>& a, const std::shared_ptr>& b, + qs_data_p_t bra, qs_data_p_t ket, index_t dim) -> py_qs_data_t { + if ((dim != a->dim_) || (dim != b->dim_)) { + throw std::runtime_error("Sparse hamiltonian size not match with quantum state size."); + } + return sparse::ExpectationOfCsr(a, b, reinterpret_cast(bra), + reinterpret_cast(ket)); +} + #ifdef __x86_64__ template struct CPUVectorPolicyBase; template struct CPUVectorPolicyBase; 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 687b4ff32..b0f859d56 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,16 +44,15 @@ auto CPUVectorPolicyBase::InitState(index_t dim, bool zero } template -void CPUVectorPolicyBase::Reset(qs_data_p_t qs, index_t dim) { - THRESHOLD_OMP_FOR( - dim, DimTh, for (omp::idx_t i = 0; i < dim; i++) { qs[i] = 0; }) - qs[0] = 1; +void CPUVectorPolicyBase::Reset(qs_data_p_t& qs, index_t dim) { + derived::FreeState(qs); } template -void CPUVectorPolicyBase::FreeState(qs_data_p_t qs) { +void CPUVectorPolicyBase::FreeState(qs_data_p_t& qs) { if (qs != nullptr) { free(qs); + qs = nullptr; } } @@ -63,8 +62,15 @@ void CPUVectorPolicyBase::Display(qs_data_p_t qs, qbit_t n n_qubits = q_limit; } std::cout << n_qubits << " qubits cpu simulator (little endian)." << std::endl; - for (index_t i = 0; i < (1UL << n_qubits); i++) { - std::cout << "(" << qs[i].real() << ", " << qs[i].imag() << ")" << std::endl; + if (qs == nullptr) { + std::cout << "(" << 1 << ", " << 0 << ")" << std::endl; + for (index_t i = 0; i < (1UL << n_qubits) - 1; i++) { + std::cout << "(" << 0 << ", " << 0 << ")" << std::endl; + } + } else { + for (index_t i = 0; i < (1UL << n_qubits); i++) { + std::cout << "(" << qs[i].real() << ", " << qs[i].imag() << ")" << std::endl; + } } } @@ -80,17 +86,24 @@ void CPUVectorPolicyBase::SetToZeroExcept(qs_data_p_t qs, template auto CPUVectorPolicyBase::Copy(qs_data_p_t qs, index_t dim) -> qs_data_p_t { - qs_data_p_t out = derived::InitState(dim, false); - THRESHOLD_OMP_FOR( - dim, DimTh, for (omp::idx_t i = 0; i < dim; i++) { out[i] = qs[i]; }) + qs_data_p_t out = nullptr; + if (qs != nullptr) { + out = derived::InitState(dim, false); + THRESHOLD_OMP_FOR( + dim, DimTh, for (omp::idx_t i = 0; i < dim; i++) { out[i] = qs[i]; }) + } return out; }; template auto CPUVectorPolicyBase::GetQS(qs_data_p_t qs, index_t dim) -> VT { VT out(dim); - THRESHOLD_OMP_FOR( - dim, DimTh, for (omp::idx_t i = 0; i < dim; i++) { out[i] = qs[i]; }) + if (qs != nullptr) { + THRESHOLD_OMP_FOR( + dim, DimTh, for (omp::idx_t i = 0; i < dim; i++) { out[i] = qs[i]; }) + } else { + out[0] = 1.0; + } return out; } @@ -129,6 +142,40 @@ auto CPUVectorPolicyBase::ApplyTerms(qs_data_p_t qs, const return out; }; +template +auto CPUVectorPolicyBase::ExpectationOfTerms(qs_data_p_t bra, qs_data_p_t ket, + const std::vector>& ham, + index_t dim) -> py_qs_data_t { + py_qs_data_t out = 0.0; + for (const auto& [pauli_string, coeff_] : ham) { + auto mask = GenPauliMask(pauli_string); + auto mask_f = mask.mask_x | mask.mask_y; + auto coeff = coeff_; + calc_type res_real = 0, res_imag = 0; + // clang-format off + THRESHOLD_OMP( + MQ_DO_PRAGMA(omp parallel for reduction(+:res_real, res_imag) schedule(static)), 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 c = ComplexCast::apply( + POLAR[static_cast((mask.num_y + 2 * axis3power + 2 * axis2power) & 3)]); + auto tmp = std::conj(bra[j]) * ket[i] * coeff * c; + if (i != j) { + tmp += std::conj(bra[i]) * ket[j] * coeff / c; + } + res_real += std::real(tmp); + res_imag += std::imag(tmp); + } + }) + // clang-format on + out += py_qs_data_t(res_real, res_imag); + } + return out; +} + template auto CPUVectorPolicyBase::GroundStateOfZZs(const std::map& masks_value, qbit_t n_qubits) -> calc_type { diff --git a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_dot_like.cu b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_dot_like.cu index 074d63682..2988baea3 100644 --- a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_dot_like.cu +++ b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_dot_like.cu @@ -125,7 +125,49 @@ auto GPUVectorPolicyBase::CsrDotVec(const std::shared_ptr< } return out; } +template +auto GPUVectorPolicyBase::ExpectationOfCsr( + const std::shared_ptr>& a, qs_data_p_t bra, qs_data_p_t ket, index_t dim) + -> py_qs_data_t { + if (dim != a->dim_) { + throw std::runtime_error("Sparse hamiltonian size not match with quantum state size."); + } + auto host_bra = reinterpret_cast*>(malloc(dim * sizeof(std::complex))); + cudaMemcpy(host_bra, bra, sizeof(qs_data_t) * dim, cudaMemcpyDeviceToHost); + auto host_ket = reinterpret_cast*>(malloc(dim * sizeof(std::complex))); + cudaMemcpy(host_bra, ket, sizeof(qs_data_t) * dim, cudaMemcpyDeviceToHost); + auto out = sparse::ExpectationOfCsr(a, reinterpret_cast(host_bra), + reinterpret_cast(host_ket)); + if (host_bra != nullptr) { + free(host_bra); + } + if (host_ket != nullptr) { + free(host_ket); + } + return out; +} +template +auto GPUVectorPolicyBase::ExpectationOfCsr( + const std::shared_ptr>& a, const std::shared_ptr>& b, + qs_data_p_t bra, qs_data_p_t ket, index_t dim) -> py_qs_data_t { + if ((dim != a->dim_) || (dim != b->dim_)) { + throw std::runtime_error("Sparse hamiltonian size not match with quantum state size."); + } + auto host_bra = reinterpret_cast*>(malloc(dim * sizeof(std::complex))); + cudaMemcpy(host_bra, bra, sizeof(qs_data_t) * dim, cudaMemcpyDeviceToHost); + auto host_ket = reinterpret_cast*>(malloc(dim * sizeof(std::complex))); + cudaMemcpy(host_bra, ket, sizeof(qs_data_t) * dim, cudaMemcpyDeviceToHost); + auto out = sparse::ExpectationOfCsr(a, b, reinterpret_cast(host_bra), + reinterpret_cast(host_ket)); + if (host_bra != nullptr) { + free(host_bra); + } + if (host_ket != nullptr) { + free(host_ket); + } + return out; +} template struct GPUVectorPolicyBase; template struct GPUVectorPolicyBase; 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 02e8c7092..cdbbcb327 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 @@ -22,9 +22,9 @@ #include "simulator/vector/detail/gpu_vector_float_policy.cuh" #include "simulator/vector/detail/gpu_vector_policy.cuh" #include "thrust/device_ptr.h" +#include "thrust/device_vector.h" #include "thrust/functional.h" #include "thrust/inner_product.h" -#include "thrust/device_vector.h" namespace mindquantum::sim::vector::detail { template @@ -40,17 +40,16 @@ auto GPUVectorPolicyBase::InitState(index_t dim, bool zero } template -void GPUVectorPolicyBase::FreeState(qs_data_p_t qs) { +void GPUVectorPolicyBase::FreeState(qs_data_p_t& qs) { if (qs != nullptr) { cudaFree(qs); + qs = nullptr; } } template -void GPUVectorPolicyBase::Reset(qs_data_p_t qs, index_t dim) { - cudaMemset(qs, 0, sizeof(qs_data_t) * dim); - qs_data_t one(1, 0); - cudaMemcpy(qs, &one, sizeof(qs_data_t), cudaMemcpyHostToDevice); +void GPUVectorPolicyBase::Reset(qs_data_p_t& qs, index_t dim) { + derived::FreeState(qs); } template @@ -58,14 +57,21 @@ void GPUVectorPolicyBase::Display(qs_data_p_t qs, qbit_t n if (n_qubits > q_limit) { n_qubits = q_limit; } - std::complex* h_qs = reinterpret_cast*>( - malloc((1UL << n_qubits) * sizeof(std::complex))); - cudaMemcpy(h_qs, qs, sizeof(qs_data_t) * (1UL << n_qubits), cudaMemcpyDeviceToHost); - std::cout << n_qubits << " qubits cpu simulator (little endian)." << std::endl; - for (index_t i = 0; i < (1UL << n_qubits); i++) { - std::cout << "(" << h_qs[i].real() << ", " << h_qs[i].imag() << ")" << std::endl; + std::cout << n_qubits << " qubits gpu simulator (little endian)." << std::endl; + if (qs == nullptr) { + std::cout << "(" << 1 << ", " << 0 << ")" << std::endl; + for (index_t i = 0; i < (1UL << n_qubits) - 1; i++) { + std::cout << "(" << 0 << ", " << 0 << ")" << std::endl; + } + } else { + std::complex* h_qs = reinterpret_cast*>( + malloc((1UL << n_qubits) * sizeof(std::complex))); + cudaMemcpy(h_qs, qs, sizeof(qs_data_t) * (1UL << n_qubits), cudaMemcpyDeviceToHost); + for (index_t i = 0; i < (1UL << n_qubits); i++) { + std::cout << "(" << h_qs[i].real() << ", " << h_qs[i].imag() << ")" << std::endl; + } + free(h_qs); } - free(h_qs); } template @@ -81,7 +87,11 @@ void GPUVectorPolicyBase::SetToZeroExcept(qs_data_p_t qs, template auto GPUVectorPolicyBase::GetQS(qs_data_p_t qs, index_t dim) -> py_qs_datas_t { py_qs_datas_t out(dim); - cudaMemcpy(out.data(), qs, sizeof(qs_data_t) * dim, cudaMemcpyDeviceToHost); + if (qs == nullptr) { + out[0] = 1.0; + } else { + cudaMemcpy(out.data(), qs, sizeof(qs_data_t) * dim, cudaMemcpyDeviceToHost); + } return out; } @@ -93,6 +103,48 @@ void GPUVectorPolicyBase::SetQS(qs_data_p_t qs, const py_q cudaMemcpy(qs, qs_out.data(), sizeof(qs_data_t) * dim, cudaMemcpyHostToDevice); } +template +auto GPUVectorPolicyBase::ExpectationOfTerms(qs_data_p_t bra, qs_data_p_t ket, + const std::vector>& ham, + index_t dim) -> py_qs_data_t { + qs_data_t out = 0.0; + for (const auto& [pauli_string, coeff] : ham) { + auto mask = GenPauliMask(pauli_string); + auto mask_f = mask.mask_x | mask.mask_y; + auto mask_z = mask.mask_z; + auto mask_y = mask.mask_y; + auto num_y = mask.num_y; + auto this_coeff = qs_data_t(coeff); + thrust::counting_iterator i(0); + out += thrust::transform_reduce( + i, i + dim, + [=] __device__(index_t i) { + auto j = (i ^ mask_f); + qs_data_t tmp = 0.0; + if (i <= j) { + auto axis2power = __popcll(i & mask_z); + auto axis3power = __popcll(i & mask_y); + auto idx = (num_y + 2 * axis3power + 2 * axis2power) & 3; + auto c = qs_data_t(1, 0); + if (idx == 1) { + c = qs_data_t(0, 1); + } else if (idx == 2) { + c = qs_data_t(-1, 0); + } else if (idx == 3) { + c = qs_data_t(0, -1); + } + tmp += thrust::conj(bra[j]) * ket[i] * this_coeff * c; + if (i != j) { + tmp += thrust::conj(bra[i]) * ket[j] * this_coeff / c; + } + } + return tmp; + }, + qs_data_t(0, 0), thrust::plus()); + } + return out; +} + template auto GPUVectorPolicyBase::ApplyTerms(qs_data_p_t qs, const std::vector>& ham, index_t dim) -> qs_data_p_t { @@ -167,9 +219,11 @@ auto GPUVectorPolicyBase::GroundStateOfZZs(const std::map< template auto GPUVectorPolicyBase::Copy(qs_data_p_t qs, index_t dim) -> qs_data_p_t { - qs_data_p_t out; - cudaMalloc((void**) &out, sizeof(qs_data_t) * dim); // NOLINT - cudaMemcpy(out, qs, sizeof(qs_data_t) * dim, cudaMemcpyDeviceToDevice); + qs_data_p_t out = nullptr; + if (qs != nullptr) { + cudaMalloc((void**) &out, sizeof(qs_data_t) * dim); // NOLINT + cudaMemcpy(out, qs, sizeof(qs_data_t) * dim, cudaMemcpyDeviceToDevice); + } return out; }; -- Gitee From d90a35ce9b060aed488fb8963cfc1e12f2cc079f Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Sat, 6 May 2023 19:46:07 +0800 Subject: [PATCH 2/8] use nullptr to work as zero state --- ccsrc/include/simulator/vector/detail/CPPLINT.cfg | 1 + ccsrc/lib/simulator/vector/detail/cpu_common/CPPLINT.cfg | 1 + 2 files changed, 2 insertions(+) create mode 100644 ccsrc/include/simulator/vector/detail/CPPLINT.cfg create mode 100644 ccsrc/lib/simulator/vector/detail/cpu_common/CPPLINT.cfg diff --git a/ccsrc/include/simulator/vector/detail/CPPLINT.cfg b/ccsrc/include/simulator/vector/detail/CPPLINT.cfg new file mode 100644 index 000000000..cd2d10c42 --- /dev/null +++ b/ccsrc/include/simulator/vector/detail/CPPLINT.cfg @@ -0,0 +1 @@ +filter=-runtime/reference diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/CPPLINT.cfg b/ccsrc/lib/simulator/vector/detail/cpu_common/CPPLINT.cfg new file mode 100644 index 000000000..cd2d10c42 --- /dev/null +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/CPPLINT.cfg @@ -0,0 +1 @@ +filter=-runtime/reference -- Gitee From 77fce06484c07caefce0dfb14e24e8415013bc9c Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Sat, 6 May 2023 19:59:32 +0800 Subject: [PATCH 3/8] fix docing --- .jenkins/check/config/filter_cpplint.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.jenkins/check/config/filter_cpplint.txt b/.jenkins/check/config/filter_cpplint.txt index 40b07edae..1b8445873 100644 --- a/.jenkins/check/config/filter_cpplint.txt +++ b/.jenkins/check/config/filter_cpplint.txt @@ -63,4 +63,5 @@ "mindquantum/ccsrc/lib/math/operators/transform/bravyi_kitaev_superfast.cpp" "runtime/references" "mindquantum/ccsrc/python/math/lib/bind_math.cpp" "runtime/references" "mindquantum/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_policy.cpp" "runtime/references" +"mindquantum/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_policy.cu" "runtime/references" "mindquantum/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp" "runtime/references" -- Gitee From a0b1cfb10bc5b94c7610850eea022f1720353327 Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Sat, 6 May 2023 21:03:42 +0800 Subject: [PATCH 4/8] fix bug in vdot cpu --- .../vector/detail/cpu_common/cpu_vector_core_dot_like.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_dot_like.cpp b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_dot_like.cpp index daf65e584..beb41e849 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_dot_like.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_dot_like.cpp @@ -28,6 +28,13 @@ namespace mindquantum::sim::vector::detail { template auto CPUVectorPolicyBase::Vdot(qs_data_p_t bra, qs_data_p_t ket, index_t dim) -> py_qs_data_t { + if (bra == nullptr && ket == nullptr) { + return 1.0; + } else if (bra == nullptr) { + return ket[0]; + } else if (ket == nullptr) { + return std::conj(bra[0]); + } calc_type res_real = 0, res_imag = 0; // clang-format off THRESHOLD_OMP( -- Gitee From c0d3c05e84eda09b9e4e549ceaf0b85a16cad16e Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Mon, 8 May 2023 10:40:51 +0800 Subject: [PATCH 5/8] check nullptr -- part1 --- .../vector/detail/cpu_vector_policy.hpp | 50 ++++----- .../vector/detail/gpu_vector_policy.cuh | 38 +++---- .../include/simulator/vector/vector_state.hpp | 2 +- .../include/simulator/vector/vector_state.tpp | 37 +++---- .../cpu_common/cpu_vector_core_condition.cpp | 100 ++++++++++++------ .../cpu_common/cpu_vector_core_dot_like.cpp | 30 +++++- .../cpu_common/cpu_vector_core_policy.cpp | 42 ++++++-- .../cpu_common/cpu_vector_core_rot_pauli.cpp | 18 ++-- .../cpu_common/cpu_vector_core_z_like.cpp | 2 +- .../detail/gpu/gpu_vector_core_condition.cu | 40 ++++--- .../detail/gpu/gpu_vector_core_dot_like.cu | 41 ++++++- .../detail/gpu/gpu_vector_core_policy.cu | 42 ++++++-- .../detail/gpu/gpu_vector_core_rot_pauli.cu | 18 ++-- .../detail/gpu/gpu_vector_core_z_like.cu | 2 +- 14 files changed, 305 insertions(+), 157 deletions(-) diff --git a/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp b/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp index d37d47259..2cd5adf56 100644 --- a/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp +++ b/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp @@ -52,36 +52,36 @@ struct CPUVectorPolicyBase { // ======================================================================================================== static qs_data_p_t InitState(index_t dim, bool zero_state = true); - static void Reset(qs_data_p_t& qs, index_t dim); - static void FreeState(qs_data_p_t& qs); - static void Display(qs_data_p_t qs, qbit_t n_qubits, qbit_t q_limit = 10); - static void SetToZeroExcept(qs_data_p_t qs, index_t ctrl_mask, index_t dim); + static void Reset(qs_data_p_t* qs_p, index_t dim); + 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); template - static void ConditionalBinary(qs_data_p_t src, qs_data_p_t des, qs_data_t succ_coeff, qs_data_t fail_coeff, - index_t dim, const binary_op& op); - template - static void ConditionalBinary(qs_data_p_t src, qs_data_p_t des, index_t mask, index_t condi, qs_data_t succ_coeff, + static void ConditionalBinary(const qs_data_p_t& src, qs_data_p_t* des_p, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim, const binary_op& op); - static void ConditionalAdd(qs_data_p_t src, qs_data_p_t des, index_t mask, index_t condi, qs_data_t succ_coeff, - qs_data_t fail_coeff, index_t dim); - static void ConditionalMinus(qs_data_p_t src, qs_data_p_t des, index_t mask, index_t condi, qs_data_t succ_coeff, - qs_data_t fail_coeff, index_t dim); - static void ConditionalMul(qs_data_p_t src, qs_data_p_t des, index_t mask, index_t condi, qs_data_t succ_coeff, - qs_data_t fail_coeff, index_t dim); - static void ConditionalDiv(qs_data_p_t src, qs_data_p_t des, index_t mask, index_t condi, qs_data_t succ_coeff, - qs_data_t fail_coeff, index_t dim); - static void QSMulValue(qs_data_p_t src, qs_data_p_t des, qs_data_t value, index_t dim); - static qs_data_t ConditionalCollect(qs_data_p_t qs, index_t mask, index_t condi, bool abs, index_t dim); - static VT GetQS(qs_data_p_t qs, index_t dim); - static void SetQS(qs_data_p_t qs, const VT& qs_out, index_t dim); - static qs_data_p_t ApplyTerms(qs_data_p_t qs, const std::vector>& ham, index_t dim); - static py_qs_data_t ExpectationOfTerms(qs_data_p_t bra, qs_data_p_t ket, + template + static void ConditionalBinary(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, + qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim, const binary_op& op); + static void ConditionalAdd(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, + qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim); + static void ConditionalMinus(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, + qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim); + static void ConditionalMul(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, + qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim); + static void ConditionalDiv(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, + qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim); + static void QSMulValue(const qs_data_p_t& src, qs_data_p_t* des_p, qs_data_t value, index_t dim); + static qs_data_t ConditionalCollect(const qs_data_p_t& qs, index_t mask, index_t condi, bool abs, index_t dim); + static VT GetQS(const qs_data_p_t& qs, index_t dim); + static void SetQS(qs_data_p_t* qs, const VT& qs_out, index_t dim); + static qs_data_p_t ApplyTerms(qs_data_p_t* qs_p, const std::vector>& ham, index_t dim); + static py_qs_data_t ExpectationOfTerms(qs_data_p_t* bra_p, qs_data_p_t* ket_p, const std::vector>& ham, index_t dim); static qs_data_p_t Copy(qs_data_p_t qs, index_t dim); template - static py_qs_data_t ConditionVdot(qs_data_p_t bra, qs_data_p_t ket, index_t dim); - static py_qs_data_t OneStateVdot(qs_data_p_t bra, qs_data_p_t ket, qbit_t obj_qubit, index_t dim); - static py_qs_data_t ZeroStateVdot(qs_data_p_t bra, qs_data_p_t ket, qbit_t obj_qubit, index_t dim); + static py_qs_data_t ConditionVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, index_t dim); + static py_qs_data_t OneStateVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, qbit_t obj_qubit, index_t dim); + static py_qs_data_t ZeroStateVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, qbit_t obj_qubit, index_t dim); static py_qs_data_t Vdot(qs_data_p_t bra, qs_data_p_t ket, index_t dim); static qs_data_p_t CsrDotVec(const std::shared_ptr>& a, qs_data_p_t vec, 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 99b91724c..a15a43d51 100644 --- a/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh +++ b/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh @@ -43,36 +43,36 @@ 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, index_t dim); - static void FreeState(qs_data_p_t& qs); - static void Display(qs_data_p_t qs, qbit_t n_qubits, qbit_t q_limit = 10); - static void SetToZeroExcept(qs_data_p_t qs, index_t ctrl_mask, index_t dim); + static void Reset(qs_data_p_t* qs_p, index_t dim); + 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); template - static void ConditionalBinary(qs_data_p_t src, qs_data_p_t des, qs_data_t succ_coeff, qs_data_t fail_coeff, + static void ConditionalBinary(const qs_data_p_t& src, qs_data_p_t* des_p, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim, const binary_op& op); template - static void ConditionalBinary(qs_data_p_t src, qs_data_p_t des, index_t mask, index_t condi, qs_data_t succ_coeff, + static void ConditionalBinary(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim, const binary_op& op); - static void ConditionalAdd(qs_data_p_t src, qs_data_p_t des, index_t mask, index_t condi, qs_data_t succ_coeff, + static void ConditionalAdd(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim); - static void ConditionalMinus(qs_data_p_t src, qs_data_p_t des, index_t mask, index_t condi, qs_data_t succ_coeff, + static void ConditionalMinus(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim); - static void ConditionalMul(qs_data_p_t src, qs_data_p_t des, index_t mask, index_t condi, qs_data_t succ_coeff, + static void ConditionalMul(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim); - static void ConditionalDiv(qs_data_p_t src, qs_data_p_t des, index_t mask, index_t condi, qs_data_t succ_coeff, + static void ConditionalDiv(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim); - static void QSMulValue(qs_data_p_t src, qs_data_p_t des, qs_data_t value, index_t dim); - static qs_data_t ConditionalCollect(qs_data_p_t qs, index_t mask, index_t condi, bool abs, index_t dim); - static py_qs_datas_t GetQS(qs_data_p_t qs, index_t dim); - static void SetQS(qs_data_p_t qs, const py_qs_datas_t& qs_out, index_t dim); - static qs_data_p_t ApplyTerms(qs_data_p_t qs, const std::vector>& ham, index_t dim); - static py_qs_data_t ExpectationOfTerms(qs_data_p_t bra, qs_data_p_t ket, + static void QSMulValue(const qs_data_p_t& src, qs_data_p_t* des_p, qs_data_t value, index_t dim); + static qs_data_t ConditionalCollect(const qs_data_p_t& qs, index_t mask, index_t condi, bool abs, index_t dim); + static py_qs_datas_t GetQS(const qs_data_p_t& qs, index_t dim); + static void SetQS(qs_data_p_t* qs_p, const py_qs_datas_t& qs_out, index_t dim); + static qs_data_p_t ApplyTerms(qs_data_p_t* qs_p, const std::vector>& ham, index_t dim); + static py_qs_data_t ExpectationOfTerms(qs_data_p_t* bra_p, qs_data_p_t* ket_p, const std::vector>& ham, index_t dim); static qs_data_p_t Copy(qs_data_p_t qs, index_t dim); template - static py_qs_data_t ConditionVdot(qs_data_p_t bra, qs_data_p_t ket, index_t dim); - static py_qs_data_t OneStateVdot(qs_data_p_t bra, qs_data_p_t ket, qbit_t obj_qubit, index_t dim); - static py_qs_data_t ZeroStateVdot(qs_data_p_t bra, qs_data_p_t ket, qbit_t obj_qubit, index_t dim); + static py_qs_data_t ConditionVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, index_t dim); + static py_qs_data_t OneStateVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, qbit_t obj_qubit, index_t dim); + static py_qs_data_t ZeroStateVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, qbit_t obj_qubit, index_t dim); static py_qs_data_t Vdot(qs_data_p_t bra, qs_data_p_t ket, index_t dim); static qs_data_p_t CsrDotVec(const std::shared_ptr>& a, qs_data_p_t vec, index_t dim); diff --git a/ccsrc/include/simulator/vector/vector_state.hpp b/ccsrc/include/simulator/vector/vector_state.hpp index fdb2e7c14..2fa3c6e05 100644 --- a/ccsrc/include/simulator/vector/vector_state.hpp +++ b/ccsrc/include/simulator/vector/vector_state.hpp @@ -74,7 +74,7 @@ class VectorState { //! dtor ~VectorState() { - qs_policy_t::FreeState(qs); + qs_policy_t::FreeState(&qs); } virtual tensor::TDtype DType(); diff --git a/ccsrc/include/simulator/vector/vector_state.tpp b/ccsrc/include/simulator/vector/vector_state.tpp index 0136b32df..fa19824e1 100644 --- a/ccsrc/include/simulator/vector/vector_state.tpp +++ b/ccsrc/include/simulator/vector/vector_state.tpp @@ -84,7 +84,7 @@ VectorState::VectorState(const VectorState& sim) { template auto VectorState::operator=(const VectorState& sim) -> derived_t& { - qs_policy_t::FreeState(this->qs); + qs_policy_t::FreeState(&(this->qs)); this->qs = qs_policy_t::Copy(sim.qs, sim.dim); this->dim = sim.dim; this->n_qubits = sim.n_qubits; @@ -109,7 +109,7 @@ VectorState::VectorState(VectorState&& sim) { template auto VectorState::operator=(VectorState&& sim) -> derived_t& { - qs_policy_t::FreeState(this->qs); + qs_policy_t::FreeState(&(this->qs)); this->qs = sim.qs; this->dim = sim.dim; this->n_qubits = sim.n_qubits; @@ -128,7 +128,7 @@ tensor::TDtype VectorState::DType() { template void VectorState::Reset() { - qs_policy_t::Reset(qs, dim); + qs_policy_t::Reset(&qs, dim); } template @@ -143,10 +143,7 @@ auto VectorState::GetQS() const -> VT { template void VectorState::SetQS(const VT& qs_out) { - if (this->qs == nullptr) { - this->qs = qs_policy_t::InitState(dim); - } - qs_policy_t::SetQS(qs, qs_out, dim); + qs_policy_t::SetQS(&qs, qs_out, dim); } template @@ -355,7 +352,7 @@ auto VectorState::ApplyMeasure(const std::shared_ptr& g auto one_amp = qs_policy_t::ConditionalCollect(qs, one_mask, one_mask, true, dim).real(); index_t collapse_mask = (static_cast(rng_() < one_amp) << gate->obj_qubits_[0]); qs_data_t norm_fact = (collapse_mask == 0) ? 1 / std::sqrt(1 - one_amp) : 1 / std::sqrt(one_amp); - qs_policy_t::ConditionalMul(qs, qs, one_mask, collapse_mask, norm_fact, 0.0, dim); + qs_policy_t::ConditionalMul(qs, &qs, one_mask, collapse_mask, norm_fact, 0.0, dim); return static_cast(collapse_mask != 0); } @@ -420,13 +417,13 @@ void VectorState::ApplyKrausChannel(const std::shared_ptr(rng_()) <= prob) { - qs_policy_t::QSMulValue(tmp_qs, tmp_qs, renormal_factor, dim); - qs_policy_t::FreeState(qs); + qs_policy_t::QSMulValue(tmp_qs, &tmp_qs, renormal_factor, dim); + qs_policy_t::FreeState(&qs); qs = tmp_qs; tmp_qs = nullptr; } } - qs_policy_t::FreeState(tmp_qs); + qs_policy_t::FreeState(&tmp_qs); } template @@ -434,7 +431,7 @@ void VectorState::ApplyDampingChannel(const std::shared_ptrqs == nullptr) { this->qs = qs_policy_t::InitState(dim); } - calc_type reduced_factor_b_square = qs_policy_t::OneStateVdot(qs, qs, gate->obj_qubits_[0], dim).real(); + calc_type reduced_factor_b_square = qs_policy_t::OneStateVdot(&qs, &qs, gate->obj_qubits_[0], dim).real(); calc_type reduced_factor_b = std::sqrt(reduced_factor_b_square); if (reduced_factor_b < 1e-8) { return; @@ -453,15 +450,15 @@ void VectorState::ApplyDampingChannel(const std::shared_ptr m({{0, 1 / reduced_factor_b}, {0, 0}}); qs_policy_t::ApplySingleQubitMatrix(qs, tmp_qs, gate->obj_qubits_[0], gate->ctrl_qubits_, m, dim); } else { - qs_policy_t::ConditionalMul(qs, tmp_qs, (1UL << gate->obj_qubits_[0]), 1, 1 / reduced_factor_b, 0, dim); + qs_policy_t::ConditionalMul(qs, &tmp_qs, (1UL << gate->obj_qubits_[0]), 1, 1 / reduced_factor_b, 0, dim); } qs = tmp_qs; tmp_qs = nullptr; - qs_policy_t::FreeState(tmp_qs); + qs_policy_t::FreeState(&tmp_qs); } else { calc_type coeff_a = 1 / std::sqrt(1 - prob); calc_type coeff_b = std::sqrt(1 - damping_coeff) / std::sqrt(1 - prob); - qs_policy_t::ConditionalMul(qs, qs, (1UL << gate->obj_qubits_[0]), 0, coeff_a, coeff_b, dim); + qs_policy_t::ConditionalMul(qs, &qs, (1UL << gate->obj_qubits_[0]), 0, coeff_a, coeff_b, dim); } } @@ -472,7 +469,7 @@ auto VectorState::GetExpectation(const Hamiltonian& ham auto ket = *this; ket.ApplyCircuit(circ, pr); if (ham.how_to_ == ORIGIN) { - out = qs_policy_t::ExpectationOfTerms(ket.qs, ket.qs, ham.ham_, dim); + out = qs_policy_t::ExpectationOfTerms(&(ket.qs), &(ket.qs), ham.ham_, dim); } else if (ham.how_to_ == BACKEND) { out = qs_policy_t::ExpectationOfCsr(ham.ham_sparse_main_, ham.ham_sparse_second_, ket.qs, ket.qs, dim); } else { @@ -492,7 +489,7 @@ auto VectorState::GetExpectation(const Hamiltonian& ham ket.ApplyCircuit(circ_right, pr); bra.ApplyCircuit(circ_left, pr); if (ham.how_to_ == ORIGIN) { - out = qs_policy_t::ExpectationOfTerms(bra.qs, ket.qs, ham.ham_, dim); + out = qs_policy_t::ExpectationOfTerms(&(bra.qs), &(ket.qs), ham.ham_, dim); } else if (ham.how_to_ == BACKEND) { out = qs_policy_t::ExpectationOfCsr(ham.ham_sparse_main_, ham.ham_sparse_second_, bra.qs, ket.qs, dim); } else { @@ -511,7 +508,7 @@ auto VectorState::GetExpectation(const Hamiltonian& ham bra.ApplyCircuit(circ_left, pr); py_qs_data_t out; if (ham.how_to_ == ORIGIN) { - out = qs_policy_t::ExpectationOfTerms(bra.qs, ket.qs, ham.ham_, dim); + out = qs_policy_t::ExpectationOfTerms(&(bra.qs), &(ket.qs), ham.ham_, dim); } else if (ham.how_to_ == BACKEND) { out = qs_policy_t::ExpectationOfCsr(ham.ham_sparse_main_, ham.ham_sparse_second_, bra.qs, ket.qs, dim); } else { @@ -660,13 +657,13 @@ void VectorState::ApplyHamiltonian(const Hamiltonian& h } qs_data_p_t new_qs; if (ham.how_to_ == ORIGIN) { - new_qs = qs_policy_t::ApplyTerms(qs, ham.ham_, dim); + new_qs = qs_policy_t::ApplyTerms(&qs, ham.ham_, dim); } else if (ham.how_to_ == BACKEND) { new_qs = qs_policy_t::CsrDotVec(ham.ham_sparse_main_, ham.ham_sparse_second_, qs, dim); } else { new_qs = qs_policy_t::CsrDotVec(ham.ham_sparse_main_, qs, dim); } - qs_policy_t::FreeState(qs); + qs_policy_t::FreeState(&qs); qs = new_qs; } diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_condition.cpp b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_condition.cpp index dcc6322c1..251aee0ba 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_condition.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_condition.cpp @@ -26,73 +26,111 @@ namespace mindquantum::sim::vector::detail { template template -void CPUVectorPolicyBase::ConditionalBinary(qs_data_p_t src, qs_data_p_t des, index_t mask, - index_t condi, qs_data_t succ_coeff, +void CPUVectorPolicyBase::ConditionalBinary(const qs_data_p_t& src, qs_data_p_t* des_p, + index_t mask, index_t condi, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim, const binary_op& op) { // if index mask satisfied condition, multiply by success_coeff, otherwise multiply fail_coeff - THRESHOLD_OMP_FOR( - dim, DimTh, for (omp::idx_t i = 0; i < dim; i++) { - if ((i & mask) == condi) { - des[i] = op(src[i], succ_coeff); - } else { - des[i] = op(src[i], fail_coeff); - } - }) + auto& des = *des_p; + if (des == nullptr) { + des = derived::InitState(dim); + } + if (src == nullptr) { + if ((0 & mask) == condi) { + des[0] = op(src[0], succ_coeff); + } else { + des[0] = op(src[0], fail_coeff); + } + } else { + THRESHOLD_OMP_FOR( + dim, DimTh, for (omp::idx_t i = 0; i < dim; i++) { + if ((i & mask) == condi) { + des[i] = op(src[i], succ_coeff); + } else { + des[i] = op(src[i], fail_coeff); + } + }) + } } template template -void CPUVectorPolicyBase::ConditionalBinary(qs_data_p_t src, qs_data_p_t des, +void CPUVectorPolicyBase::ConditionalBinary(const qs_data_p_t& src, qs_data_p_t* des_p, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim, const binary_op& op) { // if index mask satisfied condition, multiply by success_coeff, otherwise multiply fail_coeff - THRESHOLD_OMP_FOR( - dim, DimTh, for (omp::idx_t i = 0; i < dim; i++) { - if ((i & mask) == condi) { - des[i] = op(src[i], succ_coeff); - } else { - des[i] = op(src[i], fail_coeff); - } - }) + auto& des = *des_p; + if (des == nullptr) { + des = derived::InitState(dim); + } + if (src == nullptr) { + if ((0 & mask) == condi) { + des[0] = op(src[0], succ_coeff); + } else { + des[0] = op(src[0], fail_coeff); + } + } else { + THRESHOLD_OMP_FOR( + dim, DimTh, for (omp::idx_t i = 0; i < dim; i++) { + if ((i & mask) == condi) { + des[i] = op(src[i], succ_coeff); + } else { + des[i] = op(src[i], fail_coeff); + } + }) + } } template -void CPUVectorPolicyBase::QSMulValue(qs_data_p_t src, qs_data_p_t des, qs_data_t value, +void CPUVectorPolicyBase::QSMulValue(const qs_data_p_t& src, qs_data_p_t* des_p, qs_data_t value, index_t dim) { - derived::template ConditionalBinary<0, 0>(src, des, value, 0, dim, std::multiplies()); + derived::template ConditionalBinary<0, 0>(src, des_p, value, 0, dim, std::multiplies()); } template -void CPUVectorPolicyBase::ConditionalAdd(qs_data_p_t src, qs_data_p_t des, index_t mask, +void CPUVectorPolicyBase::ConditionalAdd(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim) { - derived::template ConditionalBinary(src, des, mask, condi, succ_coeff, fail_coeff, dim, std::plus()); + derived::template ConditionalBinary(src, des_p, mask, condi, succ_coeff, fail_coeff, dim, std::plus()); } template -void CPUVectorPolicyBase::ConditionalMinus(qs_data_p_t src, qs_data_p_t des, index_t mask, - index_t condi, qs_data_t succ_coeff, +void CPUVectorPolicyBase::ConditionalMinus(const qs_data_p_t& src, qs_data_p_t* des_p, + index_t mask, index_t condi, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim) { - derived::template ConditionalBinary(src, des, mask, condi, succ_coeff, fail_coeff, dim, std::minus()); + derived::template ConditionalBinary(src, des_p, mask, condi, succ_coeff, fail_coeff, dim, std::minus()); } template -void CPUVectorPolicyBase::ConditionalMul(qs_data_p_t src, qs_data_p_t des, index_t mask, +void CPUVectorPolicyBase::ConditionalMul(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim) { - derived::template ConditionalBinary(src, des, mask, condi, succ_coeff, fail_coeff, dim, + derived::template ConditionalBinary(src, des_p, mask, condi, succ_coeff, fail_coeff, dim, std::multiplies()); } template -void CPUVectorPolicyBase::ConditionalDiv(qs_data_p_t src, qs_data_p_t des, index_t mask, +void CPUVectorPolicyBase::ConditionalDiv(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim) { - derived::template ConditionalBinary(src, des, mask, condi, succ_coeff, fail_coeff, dim, std::divides()); + derived::template ConditionalBinary(src, des_p, mask, condi, succ_coeff, fail_coeff, dim, + std::divides()); } template -auto CPUVectorPolicyBase::ConditionalCollect(qs_data_p_t qs, index_t mask, index_t condi, +auto CPUVectorPolicyBase::ConditionalCollect(const qs_data_p_t& qs, index_t mask, index_t condi, bool abs, index_t dim) -> qs_data_t { // collect amplitude with index mask satisfied condition. calc_type res_real = 0, res_imag = 0; + if (qs == nullptr) { + if (abs) { + if ((0 & mask) == condi) { + res_real += qs[0].real() * qs[0].real() + qs[0].imag() * qs[0].imag(); + } + } else { + if ((0 & mask) == condi) { + res_real += qs[0].real(); + res_imag += qs[0].imag(); + } + } + return qs_data_t(res_real, res_imag); + } if (abs) { THRESHOLD_OMP( MQ_DO_PRAGMA(omp parallel for schedule(static) reduction(+: res_real)), dim, DimTh, diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_dot_like.cpp b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_dot_like.cpp index beb41e849..8f310d519 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_dot_like.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_dot_like.cpp @@ -49,8 +49,16 @@ auto CPUVectorPolicyBase::Vdot(qs_data_p_t bra, qs_data_p_ template template -auto CPUVectorPolicyBase::ConditionVdot(qs_data_p_t bra, qs_data_p_t ket, index_t dim) +auto CPUVectorPolicyBase::ConditionVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, index_t dim) -> py_qs_data_t { + auto& bra = (*bra_p); + auto& ket = (*ket_p); + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } calc_type res_real = 0, res_imag = 0; // clang-format off THRESHOLD_OMP( @@ -66,8 +74,16 @@ auto CPUVectorPolicyBase::ConditionVdot(qs_data_p_t bra, q } template -auto CPUVectorPolicyBase::OneStateVdot(qs_data_p_t bra, qs_data_p_t ket, qbit_t obj_qubit, +auto CPUVectorPolicyBase::OneStateVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, qbit_t obj_qubit, index_t dim) -> py_qs_data_t { + auto& bra = (*bra_p); + auto& ket = (*ket_p); + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } SingleQubitGateMask mask({obj_qubit}, {}); calc_type res_real = 0, res_imag = 0; // clang-format off @@ -83,8 +99,16 @@ auto CPUVectorPolicyBase::OneStateVdot(qs_data_p_t bra, qs } template -auto CPUVectorPolicyBase::ZeroStateVdot(qs_data_p_t bra, qs_data_p_t ket, qbit_t obj_qubit, +auto CPUVectorPolicyBase::ZeroStateVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, qbit_t obj_qubit, index_t dim) -> py_qs_data_t { + auto& bra = (*bra_p); + auto& ket = (*ket_p); + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } SingleQubitGateMask mask({obj_qubit}, {}); calc_type res_real = 0, res_imag = 0; // clang-format off 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 b0f859d56..85dac5124 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,12 +44,13 @@ auto CPUVectorPolicyBase::InitState(index_t dim, bool zero } template -void CPUVectorPolicyBase::Reset(qs_data_p_t& qs, index_t dim) { - derived::FreeState(qs); +void CPUVectorPolicyBase::Reset(qs_data_p_t* qs_p, index_t dim) { + derived::FreeState(qs_p); } template -void CPUVectorPolicyBase::FreeState(qs_data_p_t& qs) { +void CPUVectorPolicyBase::FreeState(qs_data_p_t* qs_p) { + auto& qs = (*qs_p); if (qs != nullptr) { free(qs); qs = nullptr; @@ -57,7 +58,7 @@ void CPUVectorPolicyBase::FreeState(qs_data_p_t& qs) { } template -void CPUVectorPolicyBase::Display(qs_data_p_t qs, qbit_t n_qubits, qbit_t q_limit) { +void CPUVectorPolicyBase::Display(const qs_data_p_t& qs, qbit_t n_qubits, qbit_t q_limit) { if (n_qubits > q_limit) { n_qubits = q_limit; } @@ -75,7 +76,11 @@ void CPUVectorPolicyBase::Display(qs_data_p_t qs, qbit_t n } template -void CPUVectorPolicyBase::SetToZeroExcept(qs_data_p_t qs, index_t ctrl_mask, index_t dim) { +void CPUVectorPolicyBase::SetToZeroExcept(qs_data_p_t* qs_p, index_t ctrl_mask, index_t dim) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } THRESHOLD_OMP_FOR( dim, DimTh, for (omp::idx_t i = 0; i < dim; i++) { if ((i & ctrl_mask) != ctrl_mask) { @@ -96,7 +101,7 @@ auto CPUVectorPolicyBase::Copy(qs_data_p_t qs, index_t dim }; template -auto CPUVectorPolicyBase::GetQS(qs_data_p_t qs, index_t dim) -> VT { +auto CPUVectorPolicyBase::GetQS(const qs_data_p_t& qs, index_t dim) -> VT { VT out(dim); if (qs != nullptr) { THRESHOLD_OMP_FOR( @@ -108,17 +113,26 @@ auto CPUVectorPolicyBase::GetQS(qs_data_p_t qs, index_t di } template -void CPUVectorPolicyBase::SetQS(qs_data_p_t qs, const VT& qs_out, index_t dim) { +void CPUVectorPolicyBase::SetQS(qs_data_p_t* qs_p, const VT& qs_out, index_t dim) { + auto& qs = (*qs_p); if (qs_out.size() != dim) { throw std::invalid_argument("state size not match"); } + if (qs == nullptr) { + qs = derived::InitState(dim, false); + } THRESHOLD_OMP_FOR( dim, DimTh, for (omp::idx_t i = 0; i < dim; i++) { qs[i] = qs_out[i]; }) } template -auto CPUVectorPolicyBase::ApplyTerms(qs_data_p_t qs, const std::vector>& ham, - index_t dim) -> qs_data_p_t { +auto CPUVectorPolicyBase::ApplyTerms(qs_data_p_t* qs_p, + const std::vector>& ham, index_t dim) + -> qs_data_p_t { + auto& qs = (*qs_p); + if (qs == nullptr) { + qs = derived::InitState(dim); + } qs_data_p_t out = derived::InitState(dim, false); for (const auto& [pauli_string, coeff_] : ham) { auto mask = GenPauliMask(pauli_string); @@ -143,9 +157,17 @@ auto CPUVectorPolicyBase::ApplyTerms(qs_data_p_t qs, const }; template -auto CPUVectorPolicyBase::ExpectationOfTerms(qs_data_p_t bra, qs_data_p_t ket, +auto CPUVectorPolicyBase::ExpectationOfTerms(qs_data_p_t* bra_p, qs_data_p_t* ket_p, const std::vector>& ham, index_t dim) -> py_qs_data_t { + auto& bra = (*bra_p); + auto& ket = (*ket_p); + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } py_qs_data_t out = 0.0; for (const auto& [pauli_string, coeff_] : ham) { auto mask = GenPauliMask(pauli_string); diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_rot_pauli.cpp b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_rot_pauli.cpp index fbbd2e36a..a65655579 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_rot_pauli.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_rot_pauli.cpp @@ -74,7 +74,7 @@ void CPUVectorPolicyBase::ApplyRxx(qs_data_p_t qs, const q } }) if (diff) { - derived::SetToZeroExcept(qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); } } } @@ -128,7 +128,7 @@ void CPUVectorPolicyBase::ApplyRxy(qs_data_p_t qs, const q } }) if (diff) { - derived::SetToZeroExcept(qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); } } } @@ -182,7 +182,7 @@ void CPUVectorPolicyBase::ApplyRxz(qs_data_p_t qs, const q } }) if (diff) { - derived::SetToZeroExcept(qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); } } } @@ -236,7 +236,7 @@ void CPUVectorPolicyBase::ApplyRyz(qs_data_p_t qs, const q } }) if (diff) { - derived::SetToZeroExcept(qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); } } } @@ -290,7 +290,7 @@ void CPUVectorPolicyBase::ApplyRyy(qs_data_p_t qs, const q } }) if (diff) { - derived::SetToZeroExcept(qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); } } } @@ -338,7 +338,7 @@ void CPUVectorPolicyBase::ApplyRzz(qs_data_p_t qs, const q } }) if (diff) { - derived::SetToZeroExcept(qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); } } } @@ -356,7 +356,7 @@ void CPUVectorPolicyBase::ApplyRX(qs_data_p_t qs, const qb std::vector> m{{{a, 0}, {0, b}}, {{0, b}, {a, 0}}}; derived::ApplySingleQubitMatrix(qs, qs, objs[0], ctrls, m, dim); if (diff && mask.ctrl_mask) { - derived::SetToZeroExcept(qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); } } @@ -373,7 +373,7 @@ void CPUVectorPolicyBase::ApplyRY(qs_data_p_t qs, const qb std::vector> m{{{a, 0}, {-b, 0}}, {{b, 0}, {a, 0}}}; derived::ApplySingleQubitMatrix(qs, qs, objs[0], ctrls, m, dim); if (diff && mask.ctrl_mask) { - derived::SetToZeroExcept(qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); } } @@ -390,7 +390,7 @@ void CPUVectorPolicyBase::ApplyRZ(qs_data_p_t qs, const qb std::vector> m{{{a, -b}, {0, 0}}, {{0, 0}, {a, b}}}; derived::ApplySingleQubitMatrix(qs, qs, objs[0], ctrls, m, dim); if (diff && mask.ctrl_mask) { - derived::SetToZeroExcept(qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); } } diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_z_like.cpp b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_z_like.cpp index f6f4bb183..7511bc36d 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_z_like.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_z_like.cpp @@ -101,7 +101,7 @@ void CPUVectorPolicyBase::ApplyPS(qs_data_p_t qs, const qb qs[j] *= e; } }) - derived::SetToZeroExcept(qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); } } } diff --git a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_condition.cu b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_condition.cu index 1259082e1..073b0647f 100644 --- a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_condition.cu +++ b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_condition.cu @@ -27,9 +27,13 @@ namespace mindquantum::sim::vector::detail { template template -void GPUVectorPolicyBase::ConditionalBinary(qs_data_p_t src, qs_data_p_t des, +void GPUVectorPolicyBase::ConditionalBinary(const qs_data_p_t& src, qs_data_p_t* des_p, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim, const binary_op& op) { + auto& des = *des_p; + if (des == nullptr) { + des = derived::InitState(dim); + } thrust::counting_iterator i(0); thrust::for_each(i, i + dim, [=] __device__(size_t i) { if ((i & mask) == condi) { @@ -42,10 +46,14 @@ void GPUVectorPolicyBase::ConditionalBinary(qs_data_p_t sr template template -void GPUVectorPolicyBase::ConditionalBinary(qs_data_p_t src, qs_data_p_t des, index_t mask, - index_t condi, qs_data_t succ_coeff, +void GPUVectorPolicyBase::ConditionalBinary(const qs_data_p_t& src, qs_data_p_t* des_p, + index_t mask, index_t condi, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim, const binary_op& op) { + auto& des = *des_p; + if (des == nullptr) { + des = derived::InitState(dim); + } thrust::counting_iterator i(0); thrust::for_each(i, i + dim, [=] __device__(size_t i) { if ((i & mask) == condi) { @@ -57,43 +65,45 @@ void GPUVectorPolicyBase::ConditionalBinary(qs_data_p_t sr } template -void GPUVectorPolicyBase::ConditionalAdd(qs_data_p_t src, qs_data_p_t des, index_t mask, +void GPUVectorPolicyBase::ConditionalAdd(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim) { - derived::template ConditionalBinary(src, des, mask, condi, succ_coeff, fail_coeff, dim, thrust::plus()); + derived::template ConditionalBinary(src, des_p, mask, condi, succ_coeff, fail_coeff, dim, + thrust::plus()); } template -void GPUVectorPolicyBase::ConditionalMinus(qs_data_p_t src, qs_data_p_t des, index_t mask, - index_t condi, qs_data_t succ_coeff, +void GPUVectorPolicyBase::ConditionalMinus(const qs_data_p_t& src, qs_data_p_t* des_p, + index_t mask, index_t condi, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim) { - derived::template ConditionalBinary(src, des, mask, condi, succ_coeff, fail_coeff, dim, thrust::minus()); + derived::template ConditionalBinary(src, des_p, mask, condi, succ_coeff, fail_coeff, dim, + thrust::minus()); } template -void GPUVectorPolicyBase::ConditionalMul(qs_data_p_t src, qs_data_p_t des, index_t mask, +void GPUVectorPolicyBase::ConditionalMul(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim) { - derived::template ConditionalBinary(src, des, mask, condi, succ_coeff, fail_coeff, dim, + derived::template ConditionalBinary(src, des_p, mask, condi, succ_coeff, fail_coeff, dim, thrust::multiplies()); } template -void GPUVectorPolicyBase::ConditionalDiv(qs_data_p_t src, qs_data_p_t des, index_t mask, +void GPUVectorPolicyBase::ConditionalDiv(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim) { - derived::template ConditionalBinary(src, des, mask, condi, succ_coeff, fail_coeff, dim, + derived::template ConditionalBinary(src, des_p, mask, condi, succ_coeff, fail_coeff, dim, thrust::divides()); } template -void GPUVectorPolicyBase::QSMulValue(qs_data_p_t src, qs_data_p_t des, qs_data_t value, +void GPUVectorPolicyBase::QSMulValue(const qs_data_p_t& src, qs_data_p_t* des_p, qs_data_t value, index_t dim) { - derived::template ConditionalBinary<0, 0>(src, des, value, 0, dim, thrust::multiplies()); + derived::template ConditionalBinary<0, 0>(src, des_p, value, 0, dim, thrust::multiplies()); } template -auto GPUVectorPolicyBase::ConditionalCollect(qs_data_p_t qs, index_t mask, index_t condi, +auto GPUVectorPolicyBase::ConditionalCollect(const qs_data_p_t& qs, index_t mask, index_t condi, bool abs, index_t dim) -> qs_data_t { qs_data_t res = 0; thrust::counting_iterator l(0); diff --git a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_dot_like.cu b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_dot_like.cu index 2988baea3..e445451e2 100644 --- a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_dot_like.cu +++ b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_dot_like.cu @@ -27,6 +27,17 @@ namespace mindquantum::sim::vector::detail { template auto GPUVectorPolicyBase::Vdot(qs_data_p_t bra, qs_data_p_t ket, index_t dim) -> py_qs_data_t { + if (bra == nullptr && ket == nullptr) { + return 1.0; + } else if (bra == nullptr) { + py_qs_data_t out; + cudaMemcpy(&out, ket, sizeof(qs_data_t), cudaMemcpyDeviceToHost); + return out; + } else if (ket == nullptr) { + py_qs_data_t out; + cudaMemcpy(&out, bra, sizeof(qs_data_t), cudaMemcpyDeviceToHost); + return std::conj(out); + } thrust::device_ptr dev_bra(bra); thrust::device_ptr dev_ket(ket); qs_data_t res = thrust::inner_product(dev_bra, dev_bra + dim, dev_ket, qs_data_t(0, 0), thrust::plus(), @@ -36,8 +47,16 @@ auto GPUVectorPolicyBase::Vdot(qs_data_p_t bra, qs_data_p_ template template -auto GPUVectorPolicyBase::ConditionVdot(qs_data_p_t bra, qs_data_p_t ket, index_t dim) +auto GPUVectorPolicyBase::ConditionVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, index_t dim) -> py_qs_data_t { + auto& bra = (*bra_p); + auto& ket = (*ket_p); + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } thrust::counting_iterator i(0); return thrust::transform_reduce( i, i + dim, @@ -52,8 +71,16 @@ auto GPUVectorPolicyBase::ConditionVdot(qs_data_p_t bra, q } template -auto GPUVectorPolicyBase::OneStateVdot(qs_data_p_t bra, qs_data_p_t ket, qbit_t obj_qubit, +auto GPUVectorPolicyBase::OneStateVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, qbit_t obj_qubit, index_t dim) -> py_qs_data_t { + auto& bra = (*bra_p); + auto& ket = (*ket_p); + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } SingleQubitGateMask mask({obj_qubit}, {}); auto obj_high_mask = mask.obj_high_mask; auto obj_low_mask = mask.obj_low_mask; @@ -69,8 +96,16 @@ auto GPUVectorPolicyBase::OneStateVdot(qs_data_p_t bra, qs } template -auto GPUVectorPolicyBase::ZeroStateVdot(qs_data_p_t bra, qs_data_p_t ket, qbit_t obj_qubit, +auto GPUVectorPolicyBase::ZeroStateVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, qbit_t obj_qubit, index_t dim) -> py_qs_data_t { + auto& bra = (*bra_p); + auto& ket = (*ket_p); + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } SingleQubitGateMask mask({obj_qubit}, {}); auto obj_high_mask = mask.obj_high_mask; auto obj_low_mask = mask.obj_low_mask; 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 cdbbcb327..9eac1e0b4 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 @@ -40,7 +40,8 @@ auto GPUVectorPolicyBase::InitState(index_t dim, bool zero } template -void GPUVectorPolicyBase::FreeState(qs_data_p_t& qs) { +void GPUVectorPolicyBase::FreeState(qs_data_p_t* qs_p) { + auto& qs = (*qs_p); if (qs != nullptr) { cudaFree(qs); qs = nullptr; @@ -48,12 +49,12 @@ void GPUVectorPolicyBase::FreeState(qs_data_p_t& qs) { } template -void GPUVectorPolicyBase::Reset(qs_data_p_t& qs, index_t dim) { - derived::FreeState(qs); +void GPUVectorPolicyBase::Reset(qs_data_p_t* qs_p, index_t dim) { + derived::FreeState(qs_p); } template -void GPUVectorPolicyBase::Display(qs_data_p_t qs, qbit_t n_qubits, qbit_t q_limit) { +void GPUVectorPolicyBase::Display(const qs_data_p_t& qs, qbit_t n_qubits, qbit_t q_limit) { if (n_qubits > q_limit) { n_qubits = q_limit; } @@ -75,7 +76,11 @@ void GPUVectorPolicyBase::Display(qs_data_p_t qs, qbit_t n } template -void GPUVectorPolicyBase::SetToZeroExcept(qs_data_p_t qs, index_t ctrl_mask, index_t dim) { +void GPUVectorPolicyBase::SetToZeroExcept(qs_data_p_t* qs_p, index_t ctrl_mask, index_t dim) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } thrust::counting_iterator i(0); thrust::for_each(i, i + dim, [=] __device__(index_t i) { if ((i & ctrl_mask) != ctrl_mask) { @@ -85,7 +90,7 @@ void GPUVectorPolicyBase::SetToZeroExcept(qs_data_p_t qs, } template -auto GPUVectorPolicyBase::GetQS(qs_data_p_t qs, index_t dim) -> py_qs_datas_t { +auto GPUVectorPolicyBase::GetQS(const qs_data_p_t& qs, index_t dim) -> py_qs_datas_t { py_qs_datas_t out(dim); if (qs == nullptr) { out[0] = 1.0; @@ -96,17 +101,29 @@ auto GPUVectorPolicyBase::GetQS(qs_data_p_t qs, index_t di } template -void GPUVectorPolicyBase::SetQS(qs_data_p_t qs, const py_qs_datas_t& qs_out, index_t dim) { +void GPUVectorPolicyBase::SetQS(qs_data_p_t* qs_p, const py_qs_datas_t& qs_out, index_t dim) { + auto& qs = (*qs_p); if (qs_out.size() != dim) { throw std::invalid_argument("state size not match"); } + if (qs == nullptr) { + qs = derived::InitState(dim, false); + } cudaMemcpy(qs, qs_out.data(), sizeof(qs_data_t) * dim, cudaMemcpyHostToDevice); } template -auto GPUVectorPolicyBase::ExpectationOfTerms(qs_data_p_t bra, qs_data_p_t ket, +auto GPUVectorPolicyBase::ExpectationOfTerms(qs_data_p_t* bra_p, qs_data_p_t* ket_p, const std::vector>& ham, index_t dim) -> py_qs_data_t { + auto& bra = (*bra_p); + auto& ket = (*ket_p); + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } qs_data_t out = 0.0; for (const auto& [pauli_string, coeff] : ham) { auto mask = GenPauliMask(pauli_string); @@ -146,8 +163,13 @@ auto GPUVectorPolicyBase::ExpectationOfTerms(qs_data_p_t b } template -auto GPUVectorPolicyBase::ApplyTerms(qs_data_p_t qs, const std::vector>& ham, - index_t dim) -> qs_data_p_t { +auto GPUVectorPolicyBase::ApplyTerms(qs_data_p_t* qs_p, + const std::vector>& ham, index_t dim) + -> qs_data_p_t { + auto& qs = (*qs_p); + if (qs == nullptr) { + qs = derived::InitState(dim); + } qs_data_p_t out = derived::InitState(dim, false); for (const auto& [pauli_string, coeff] : ham) { auto mask = GenPauliMask(pauli_string); diff --git a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_rot_pauli.cu b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_rot_pauli.cu index a348171a7..c06934af4 100644 --- a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_rot_pauli.cu +++ b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_rot_pauli.cu @@ -37,7 +37,7 @@ void GPUVectorPolicyBase::ApplyRX(qs_data_p_t qs, const qb std::vector> m{{{a, 0}, {0, b}}, {{0, b}, {a, 0}}}; derived::ApplySingleQubitMatrix(qs, qs, objs[0], ctrls, m, dim); if (diff && mask.ctrl_mask) { - derived::SetToZeroExcept(qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); } } @@ -54,7 +54,7 @@ void GPUVectorPolicyBase::ApplyRY(qs_data_p_t qs, const qb std::vector> m{{{a, 0}, {-b, 0}}, {{b, 0}, {a, 0}}}; derived::ApplySingleQubitMatrix(qs, qs, objs[0], ctrls, m, dim); if (diff && mask.ctrl_mask) { - derived::SetToZeroExcept(qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); } } @@ -71,7 +71,7 @@ void GPUVectorPolicyBase::ApplyRZ(qs_data_p_t qs, const qb std::vector> m{{{a, -b}, {0, 0}}, {{0, 0}, {a, b}}}; derived::ApplySingleQubitMatrix(qs, qs, objs[0], ctrls, m, dim); if (diff && mask.ctrl_mask) { - derived::SetToZeroExcept(qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); } } template @@ -122,7 +122,7 @@ void GPUVectorPolicyBase::ApplyRzz(qs_data_p_t qs, const q } }); if (diff) { - derived::SetToZeroExcept(qs, ctrl_mask, dim); + derived::SetToZeroExcept(&qs, ctrl_mask, dim); } } } @@ -181,7 +181,7 @@ void GPUVectorPolicyBase::ApplyRxx(qs_data_p_t qs, const q } }); if (diff) { - derived::SetToZeroExcept(qs, ctrl_mask, dim); + derived::SetToZeroExcept(&qs, ctrl_mask, dim); } } } @@ -240,7 +240,7 @@ void GPUVectorPolicyBase::ApplyRxy(qs_data_p_t qs, const q } }); if (diff) { - derived::SetToZeroExcept(qs, ctrl_mask, dim); + derived::SetToZeroExcept(&qs, ctrl_mask, dim); } } } @@ -299,7 +299,7 @@ void GPUVectorPolicyBase::ApplyRxz(qs_data_p_t qs, const q } }); if (diff) { - derived::SetToZeroExcept(qs, ctrl_mask, dim); + derived::SetToZeroExcept(&qs, ctrl_mask, dim); } } } @@ -358,7 +358,7 @@ void GPUVectorPolicyBase::ApplyRyz(qs_data_p_t qs, const q } }); if (diff) { - derived::SetToZeroExcept(qs, ctrl_mask, dim); + derived::SetToZeroExcept(&qs, ctrl_mask, dim); } } } @@ -417,7 +417,7 @@ void GPUVectorPolicyBase::ApplyRyy(qs_data_p_t qs, const q } }); if (diff) { - derived::SetToZeroExcept(qs, ctrl_mask, dim); + derived::SetToZeroExcept(&qs, ctrl_mask, dim); } } } diff --git a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_z_like.cu b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_z_like.cu index 2a18a9560..9c104b153 100644 --- a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_z_like.cu +++ b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_z_like.cu @@ -105,7 +105,7 @@ void GPUVectorPolicyBase::ApplyPS(qs_data_p_t qs, const qb } }); } - derived::SetToZeroExcept(qs, ctrl_mask, dim); + derived::SetToZeroExcept(&qs, ctrl_mask, dim); } } } -- Gitee From f44b3e13bfbf62b4b709e0cf24ae147842d7bf0a Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Mon, 8 May 2023 11:43:23 +0800 Subject: [PATCH 6/8] const ref for expectation --- .../vector/detail/cpu_vector_policy.hpp | 56 ++--- .../vector/detail/gpu_vector_policy.cuh | 80 +++---- .../include/simulator/vector/vector_state.hpp | 42 ++-- .../include/simulator/vector/vector_state.tpp | 66 ++++-- .../cpu_vector_core_gate_expect.cpp | 197 +++++++++++++---- .../cpu_common/cpu_vector_core_policy.cpp | 8 +- .../detail/gpu/gpu_vector_core_gate_expect.cu | 202 ++++++++++++++---- .../detail/gpu/gpu_vector_core_policy.cu | 7 +- .../include/python/vector/bind_vec_state.h | 9 +- 9 files changed, 468 insertions(+), 199 deletions(-) diff --git a/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp b/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp index 2cd5adf56..92c456368 100644 --- a/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp +++ b/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp @@ -75,7 +75,7 @@ struct CPUVectorPolicyBase { static VT GetQS(const qs_data_p_t& qs, index_t dim); static void SetQS(qs_data_p_t* qs, const VT& qs_out, index_t dim); static qs_data_p_t ApplyTerms(qs_data_p_t* qs_p, const std::vector>& ham, index_t dim); - static py_qs_data_t ExpectationOfTerms(qs_data_p_t* bra_p, qs_data_p_t* ket_p, + static py_qs_data_t ExpectationOfTerms(const qs_data_p_t& bra, const qs_data_p_t& ket, const std::vector>& ham, index_t dim); static qs_data_p_t Copy(qs_data_p_t qs, index_t dim); template @@ -152,36 +152,36 @@ struct CPUVectorPolicyBase { // gate_expectation // ======================================================================================================== - static qs_data_t ExpectDiffSingleQubitMatrix(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, + static qs_data_t ExpectDiffSingleQubitMatrix(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, const qbits_t& ctrls, const VVT& m, index_t dim); - static qs_data_t ExpectDiffTwoQubitsMatrix(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, + static qs_data_t ExpectDiffTwoQubitsMatrix(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, const qbits_t& ctrls, const VVT& m, index_t dim); - static qs_data_t ExpectDiffNQubitsMatrix(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, + static qs_data_t ExpectDiffNQubitsMatrix(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, const qbits_t& ctrls, const VVT& m, index_t dim); - static qs_data_t ExpectDiffMatrixGate(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - const VVT& m, index_t dim); - static qs_data_t ExpectDiffRX(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffRY(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffRZ(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffRxx(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffRyy(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffRzz(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffRxy(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffRxz(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffRyz(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffPS(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffGP(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); + static qs_data_t ExpectDiffMatrixGate(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, const VVT& m, index_t dim); + static qs_data_t ExpectDiffRX(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffRY(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffRZ(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffRxx(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffRyy(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffRzz(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffRxy(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffRxz(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffRyz(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffPS(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffGP(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); static calc_type GroundStateOfZZs(const std::map& masks_value, qbit_t n_qubits); }; diff --git a/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh b/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh index a15a43d51..bdebbdd4a 100644 --- a/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh +++ b/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh @@ -48,25 +48,25 @@ struct GPUVectorPolicyBase { 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); template - static void ConditionalBinary(const qs_data_p_t& src, qs_data_p_t* des_p, qs_data_t succ_coeff, qs_data_t fail_coeff, - index_t dim, const binary_op& op); - template - static void ConditionalBinary(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, qs_data_t succ_coeff, + static void ConditionalBinary(const qs_data_p_t& src, qs_data_p_t* des_p, qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim, const binary_op& op); - static void ConditionalAdd(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, qs_data_t succ_coeff, - qs_data_t fail_coeff, index_t dim); - static void ConditionalMinus(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, qs_data_t succ_coeff, - qs_data_t fail_coeff, index_t dim); - static void ConditionalMul(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, qs_data_t succ_coeff, - qs_data_t fail_coeff, index_t dim); - static void ConditionalDiv(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, qs_data_t succ_coeff, - qs_data_t fail_coeff, index_t dim); + template + static void ConditionalBinary(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, + qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim, const binary_op& op); + static void ConditionalAdd(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, + qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim); + static void ConditionalMinus(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, + qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim); + static void ConditionalMul(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, + qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim); + static void ConditionalDiv(const qs_data_p_t& src, qs_data_p_t* des_p, index_t mask, index_t condi, + qs_data_t succ_coeff, qs_data_t fail_coeff, index_t dim); static void QSMulValue(const qs_data_p_t& src, qs_data_p_t* des_p, qs_data_t value, index_t dim); static qs_data_t ConditionalCollect(const qs_data_p_t& qs, index_t mask, index_t condi, bool abs, index_t dim); static py_qs_datas_t GetQS(const qs_data_p_t& qs, index_t dim); static void SetQS(qs_data_p_t* qs_p, const py_qs_datas_t& qs_out, index_t dim); static qs_data_p_t ApplyTerms(qs_data_p_t* qs_p, const std::vector>& ham, index_t dim); - static py_qs_data_t ExpectationOfTerms(qs_data_p_t* bra_p, qs_data_p_t* ket_p, + static py_qs_data_t ExpectationOfTerms(const qs_data_p_t& bra, const qs_data_p_t& ket, const std::vector>& ham, index_t dim); static qs_data_p_t Copy(qs_data_p_t qs, index_t dim); template @@ -142,37 +142,37 @@ struct GPUVectorPolicyBase { // gate_expec // ======================================================================================================== - static qs_data_t ExpectDiffSingleQubitMatrix(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, + static qs_data_t ExpectDiffSingleQubitMatrix(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, const qbits_t& ctrls, const std::vector& m, index_t dim); - static qs_data_t ExpectDiffTwoQubitsMatrix(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, + static qs_data_t ExpectDiffTwoQubitsMatrix(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, const qbits_t& ctrls, const std::vector& m, index_t dim); - static qs_data_t ExpectDiffNQubitsMatrix(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, + static qs_data_t ExpectDiffNQubitsMatrix(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, const qbits_t& ctrls, const std::vector& m, index_t dim); - static qs_data_t ExpectDiffMatrixGate(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - const std::vector& m, index_t dim); - static qs_data_t ExpectDiffRX(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffRY(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffRZ(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffRxx(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffRyy(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffRzz(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffRxy(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffRxz(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffRyz(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffPS(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); - static qs_data_t ExpectDiffGP(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, const qbits_t& ctrls, - calc_type val, index_t dim); + static qs_data_t ExpectDiffMatrixGate(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, const std::vector& m, index_t dim); + static qs_data_t ExpectDiffRX(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffRY(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffRZ(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffRxx(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffRyy(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffRzz(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffRxy(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffRxz(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffRyz(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffPS(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); + static qs_data_t ExpectDiffGP(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, + const qbits_t& ctrls, calc_type val, index_t dim); static calc_type GroundStateOfZZs(const std::map& masks_value, qbit_t n_qubits); }; diff --git a/ccsrc/include/simulator/vector/vector_state.hpp b/ccsrc/include/simulator/vector/vector_state.hpp index 2fa3c6e05..68094d881 100644 --- a/ccsrc/include/simulator/vector/vector_state.hpp +++ b/ccsrc/include/simulator/vector/vector_state.hpp @@ -116,13 +116,16 @@ class VectorState { //! calculate the expectation of differential form of parameterized gate two quantum state. That is //! - virtual tensor::Matrix ExpectDiffGate(qs_data_p_t bra, qs_data_p_t ket, const std::shared_ptr& gate, - const parameter::ParameterResolver& pr, index_t dim); - - virtual tensor::Matrix ExpectDiffU3(qs_data_p_t bra, qs_data_p_t ket, const std::shared_ptr& gate, - const parameter::ParameterResolver& pr, index_t dim); - virtual tensor::Matrix ExpectDiffFSim(qs_data_p_t bra, qs_data_p_t ket, const std::shared_ptr& gate, - const parameter::ParameterResolver& pr, index_t dim); + virtual tensor::Matrix ExpectDiffGate(const qs_data_p_t& bra, const qs_data_p_t& ket, + const std::shared_ptr& gate, + const parameter::ParameterResolver& pr, index_t dim) const; + + virtual tensor::Matrix ExpectDiffU3(const qs_data_p_t& bra, const qs_data_p_t& ket, + const std::shared_ptr& gate, const parameter::ParameterResolver& pr, + index_t dim) const; + virtual tensor::Matrix ExpectDiffFSim(const qs_data_p_t& bra, const qs_data_p_t& ket, + const std::shared_ptr& gate, + const parameter::ParameterResolver& pr, index_t dim) const; //! Apply a quantum circuit on this quantum state virtual std::map ApplyCircuit(const circuit_t& circ, const parameter::ParameterResolver& pr = parameter::ParameterResolver()); @@ -131,64 +134,65 @@ class VectorState { virtual void ApplyHamiltonian(const Hamiltonian& ham); //! Get the matrix of quantum circuit. - virtual VVT GetCircuitMatrix(const circuit_t& circ, const parameter::ParameterResolver& pr); + virtual VVT GetCircuitMatrix(const circuit_t& circ, const parameter::ParameterResolver& pr) const; //! Get expectation of given hamiltonian virtual py_qs_data_t GetExpectation(const Hamiltonian& ham, const circuit_t& circ, - const parameter::ParameterResolver& pr); + const parameter::ParameterResolver& pr) const; virtual py_qs_data_t GetExpectation(const Hamiltonian& ham, const circuit_t& circ_right, - const circuit_t& circ_left, const parameter::ParameterResolver& pr); + const circuit_t& circ_left, const parameter::ParameterResolver& pr) const; virtual py_qs_data_t GetExpectation(const Hamiltonian& ham, const circuit_t& circ_right, const circuit_t& circ_left, const derived_t& simulator_left, - const parameter::ParameterResolver& pr); + const parameter::ParameterResolver& pr) const; //! Get the expectation of hamiltonian //! Here a single hamiltonian and single parameter data are needed virtual VT GetExpectationWithGradOneOne(const Hamiltonian& ham, const circuit_t& circ, const circuit_t& herm_circ, const parameter::ParameterResolver& pr, - const MST& p_map); + const MST& p_map) const; //! Get the expectation of hamiltonian //! Here multiple hamiltonian and single parameter data are needed virtual VVT GetExpectationWithGradOneMulti( const std::vector>>& hams, const circuit_t& circ, - const circuit_t& herm_circ, const parameter::ParameterResolver& pr, const MST& p_map, int n_thread); + const circuit_t& herm_circ, const parameter::ParameterResolver& pr, const MST& p_map, + int n_thread) const; //! Get the expectation of hamiltonian //! Here multiple hamiltonian and multiple parameters are needed virtual VT> GetExpectationWithGradMultiMulti( const std::vector>>& hams, const circuit_t& circ, const circuit_t& herm_circ, const VVT& enc_data, const VT& ans_data, const VS& enc_name, - const VS& ans_name, size_t batch_threads, size_t mea_threads); + const VS& ans_name, size_t batch_threads, size_t mea_threads) const; virtual VVT GetExpectationNonHermitianWithGradOneMulti( const std::vector>>& hams, const std::vector>>& herm_hams, const circuit_t& left_circ, const circuit_t& herm_left_circ, const circuit_t& right_circ, const circuit_t& herm_right_circ, const parameter::ParameterResolver& pr, const MST& p_map, int n_thread, - const derived_t& simulator_left); + const derived_t& simulator_left) const; virtual VVT LeftSizeGradOneMulti(const std::vector>>& hams, const circuit_t& herm_left_circ, const parameter::ParameterResolver& pr, const MST& p_map, int n_thread, const derived_t& simulator_left, - const derived_t& simulator_right); + const derived_t& simulator_right) const; virtual VT> GetExpectationNonHermitianWithGradMultiMulti( const std::vector>>& hams, const std::vector>>& herm_hams, const circuit_t& left_circ, const circuit_t& herm_left_circ, const circuit_t& right_circ, const circuit_t& herm_right_circ, const VVT& enc_data, const VT& ans_data, const VS& enc_name, const VS& ans_name, - const derived_t& simulator_left, size_t batch_threads, size_t mea_threads); + const derived_t& simulator_left, size_t batch_threads, size_t mea_threads) const; virtual VT Sampling(const circuit_t& circ, const parameter::ParameterResolver& pr, size_t shots, - const MST& key_map, unsigned seed); + const MST& key_map, unsigned seed) const; template class cast_policy> - VectorState astype(unsigned seed); + VectorState astype(unsigned seed) const; protected: qs_data_p_t qs = nullptr; diff --git a/ccsrc/include/simulator/vector/vector_state.tpp b/ccsrc/include/simulator/vector/vector_state.tpp index fa19824e1..ef3f6b19b 100644 --- a/ccsrc/include/simulator/vector/vector_state.tpp +++ b/ccsrc/include/simulator/vector/vector_state.tpp @@ -464,12 +464,12 @@ void VectorState::ApplyDampingChannel(const std::shared_ptr auto VectorState::GetExpectation(const Hamiltonian& ham, const circuit_t& circ, - const parameter::ParameterResolver& pr) -> py_qs_data_t { + const parameter::ParameterResolver& pr) const -> py_qs_data_t { py_qs_data_t out; auto ket = *this; ket.ApplyCircuit(circ, pr); if (ham.how_to_ == ORIGIN) { - out = qs_policy_t::ExpectationOfTerms(&(ket.qs), &(ket.qs), ham.ham_, dim); + out = qs_policy_t::ExpectationOfTerms(ket.qs, ket.qs, ham.ham_, dim); } else if (ham.how_to_ == BACKEND) { out = qs_policy_t::ExpectationOfCsr(ham.ham_sparse_main_, ham.ham_sparse_second_, ket.qs, ket.qs, dim); } else { @@ -480,7 +480,7 @@ auto VectorState::GetExpectation(const Hamiltonian& ham template auto VectorState::GetExpectation(const Hamiltonian& ham, const circuit_t& circ_right, - const circuit_t& circ_left, const parameter::ParameterResolver& pr) + const circuit_t& circ_left, const parameter::ParameterResolver& pr) const -> py_qs_data_t { py_qs_data_t out; @@ -489,7 +489,7 @@ auto VectorState::GetExpectation(const Hamiltonian& ham ket.ApplyCircuit(circ_right, pr); bra.ApplyCircuit(circ_left, pr); if (ham.how_to_ == ORIGIN) { - out = qs_policy_t::ExpectationOfTerms(&(bra.qs), &(ket.qs), ham.ham_, dim); + out = qs_policy_t::ExpectationOfTerms(bra.qs, ket.qs, ham.ham_, dim); } else if (ham.how_to_ == BACKEND) { out = qs_policy_t::ExpectationOfCsr(ham.ham_sparse_main_, ham.ham_sparse_second_, bra.qs, ket.qs, dim); } else { @@ -501,14 +501,14 @@ auto VectorState::GetExpectation(const Hamiltonian& ham template auto VectorState::GetExpectation(const Hamiltonian& ham, const circuit_t& circ_right, const circuit_t& circ_left, const derived_t& simulator_left, - const parameter::ParameterResolver& pr) -> py_qs_data_t { + const parameter::ParameterResolver& pr) const -> py_qs_data_t { auto ket = *this; auto bra = simulator_left; ket.ApplyCircuit(circ_right, pr); bra.ApplyCircuit(circ_left, pr); py_qs_data_t out; if (ham.how_to_ == ORIGIN) { - out = qs_policy_t::ExpectationOfTerms(&(bra.qs), &(ket.qs), ham.ham_, dim); + out = qs_policy_t::ExpectationOfTerms(bra.qs, ket.qs, ham.ham_, dim); } else if (ham.how_to_ == BACKEND) { out = qs_policy_t::ExpectationOfCsr(ham.ham_sparse_main_, ham.ham_sparse_second_, bra.qs, ket.qs, dim); } else { @@ -519,14 +519,16 @@ auto VectorState::GetExpectation(const Hamiltonian& ham template template class cast_policy> -auto VectorState::astype(unsigned seed) -> VectorState { +auto VectorState::astype(unsigned seed) const -> VectorState { return VectorState(cast_policy::cast(this->qs, this->dim), this->n_qubits, seed); } template -auto VectorState::ExpectDiffGate(qs_data_p_t bra, qs_data_p_t ket, const std::shared_ptr& gate, - const parameter::ParameterResolver& pr, index_t dim) -> tensor::Matrix { +auto VectorState::ExpectDiffGate(const qs_data_p_t& bra, const qs_data_p_t& ket, + const std::shared_ptr& gate, + const parameter::ParameterResolver& pr, index_t dim) const + -> tensor::Matrix { auto id = gate->id_; auto g = static_cast(gate.get()); auto val = tensor::ops::cpu::to_vector(g->prs_[0].Combination(pr).const_value)[0]; @@ -582,8 +584,18 @@ auto VectorState::ExpectDiffGate(qs_data_p_t bra, qs_data_p_t ket, } template -auto VectorState::ExpectDiffU3(qs_data_p_t bra, qs_data_p_t ket, const std::shared_ptr& gate, - const parameter::ParameterResolver& pr, index_t dim) -> tensor::Matrix { +auto VectorState::ExpectDiffU3(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const std::shared_ptr& gate, + const parameter::ParameterResolver& pr, index_t dim) const + -> tensor::Matrix { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = qs_policy_t::InitState(dim); + } + if (ket == nullptr) { + ket = qs_policy_t::InitState(dim); + } VT grad = {0, 0, 0}; auto u3 = static_cast(gate.get()); if (u3->parameterized_) { @@ -611,8 +623,18 @@ auto VectorState::ExpectDiffU3(qs_data_p_t bra, qs_data_p_t ket, c } template -auto VectorState::ExpectDiffFSim(qs_data_p_t bra, qs_data_p_t ket, const std::shared_ptr& gate, - const parameter::ParameterResolver& pr, index_t dim) -> tensor::Matrix { +auto VectorState::ExpectDiffFSim(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const std::shared_ptr& gate, + const parameter::ParameterResolver& pr, index_t dim) const + -> tensor::Matrix { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = qs_policy_t::InitState(dim); + } + if (ket == nullptr) { + ket = qs_policy_t::InitState(dim); + } VT grad = {0, 0}; auto fsim = static_cast(gate.get()); if (fsim->parameterized_) { @@ -668,7 +690,7 @@ void VectorState::ApplyHamiltonian(const Hamiltonian& h } template -auto VectorState::GetCircuitMatrix(const circuit_t& circ, const parameter::ParameterResolver& pr) +auto VectorState::GetCircuitMatrix(const circuit_t& circ, const parameter::ParameterResolver& pr) const -> VVT { VVT> out((1UL << n_qubits), VT>((1UL << n_qubits), 0)); for (size_t i = 0; i < (1UL << n_qubits); i++) { @@ -694,7 +716,7 @@ template auto VectorState::GetExpectationWithGradOneOne(const Hamiltonian& ham, const circuit_t& circ, const circuit_t& herm_circ, const parameter::ParameterResolver& pr, - const MST& p_map) -> VT { + const MST& p_map) const -> VT { // auto timer = Timer(); // timer.Start("First part"); VT f_and_g(1 + p_map.size(), 0); @@ -728,8 +750,8 @@ auto VectorState::GetExpectationNonHermitianWithGradOneMulti( const std::vector>>& hams, const std::vector>>& herm_hams, const circuit_t& left_circ, const circuit_t& herm_left_circ, const circuit_t& right_circ, const circuit_t& herm_right_circ, - const parameter::ParameterResolver& pr, const MST& p_map, int n_thread, const derived_t& simulator_left) - -> VVT { + const parameter::ParameterResolver& pr, const MST& p_map, int n_thread, + const derived_t& simulator_left) const -> VVT { auto n_hams = hams.size(); VVT f_and_g(n_hams, VT((1 + p_map.size()), 0)); @@ -752,7 +774,7 @@ auto VectorState::LeftSizeGradOneMulti(const std::vector& p_map, int n_thread, const derived_t& simulator_left, - const derived_t& simulator_right) -> VVT { + const derived_t& simulator_right) const -> VVT { auto n_hams = hams.size(); int max_thread = 15; if (n_thread == 0) { @@ -811,7 +833,7 @@ auto VectorState::LeftSizeGradOneMulti(const std::vector auto VectorState::GetExpectationWithGradOneMulti( const std::vector>>& hams, const circuit_t& circ, const circuit_t& herm_circ, - const parameter::ParameterResolver& pr, const MST& p_map, int n_thread) -> VVT { + const parameter::ParameterResolver& pr, const MST& p_map, int n_thread) const -> VVT { auto n_hams = hams.size(); int max_thread = 15; if (n_thread == 0) { @@ -871,7 +893,7 @@ auto VectorState::GetExpectationNonHermitianWithGradMultiMulti( const std::vector>>& herm_hams, const circuit_t& left_circ, const circuit_t& herm_left_circ, const circuit_t& right_circ, const circuit_t& herm_right_circ, const VVT& enc_data, const VT& ans_data, const VS& enc_name, const VS& ans_name, - const derived_t& simulator_left, size_t batch_threads, size_t mea_threads) -> VT> { + const derived_t& simulator_left, size_t batch_threads, size_t mea_threads) const -> VT> { auto n_hams = hams.size(); auto n_prs = enc_data.size(); auto n_params = enc_name.size() + ans_name.size(); @@ -937,7 +959,7 @@ template auto VectorState::GetExpectationWithGradMultiMulti( const std::vector>>& hams, const circuit_t& circ, const circuit_t& herm_circ, const VVT& enc_data, const VT& ans_data, const VS& enc_name, const VS& ans_name, - size_t batch_threads, size_t mea_threads) -> VT> { + size_t batch_threads, size_t mea_threads) const -> VT> { auto n_hams = hams.size(); auto n_prs = enc_data.size(); auto n_params = enc_name.size() + ans_name.size(); @@ -998,7 +1020,7 @@ auto VectorState::GetExpectationWithGradMultiMulti( template VT VectorState::Sampling(const circuit_t& circ, const parameter::ParameterResolver& pr, - size_t shots, const MST& key_map, unsigned int seed) { + size_t shots, const MST& key_map, unsigned int seed) const { auto key_size = key_map.size(); VT res(shots * key_size); RndEngine rnd_eng = RndEngine(seed); diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_gate_expect.cpp b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_gate_expect.cpp index 44890e3fa..0def604fa 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_gate_expect.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_gate_expect.cpp @@ -26,10 +26,19 @@ #include "simulator/vector/detail/cpu_vector_policy.hpp" namespace mindquantum::sim::vector::detail { template -auto CPUVectorPolicyBase::ExpectDiffNQubitsMatrix(qs_data_p_t bra, qs_data_p_t ket, - const qbits_t& objs, const qbits_t& ctrls, +auto CPUVectorPolicyBase::ExpectDiffNQubitsMatrix(const qs_data_p_t& bra_out, + const qs_data_p_t& ket_out, const qbits_t& objs, + const qbits_t& ctrls, const VVT& gate, index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } size_t n_qubit = objs.size(); size_t m_dim = (1UL << n_qubit); size_t ctrl_mask = 0; @@ -69,10 +78,19 @@ auto CPUVectorPolicyBase::ExpectDiffNQubitsMatrix(qs_data_ } template -auto CPUVectorPolicyBase::ExpectDiffTwoQubitsMatrix(qs_data_p_t bra, qs_data_p_t ket, +auto CPUVectorPolicyBase::ExpectDiffTwoQubitsMatrix(const qs_data_p_t& bra_out, + const qs_data_p_t& ket_out, const qbits_t& objs, const qbits_t& ctrls, const VVT& gate, index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); calc_type res_real = 0, res_imag = 0; // clang-format off @@ -126,10 +144,19 @@ auto CPUVectorPolicyBase::ExpectDiffTwoQubitsMatrix(qs_dat }; template -auto CPUVectorPolicyBase::ExpectDiffSingleQubitMatrix(qs_data_p_t bra, qs_data_p_t ket, +auto CPUVectorPolicyBase::ExpectDiffSingleQubitMatrix(const qs_data_p_t& bra_out, + const qs_data_p_t& ket_out, const qbits_t& objs, const qbits_t& ctrls, const VVT& m, index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } SingleQubitGateMask mask(objs, ctrls); calc_type res_real = 0, res_imag = 0; if (!mask.ctrl_mask) { @@ -196,10 +223,18 @@ auto CPUVectorPolicyBase::ExpectDiffSingleQubitMatrix(qs_d }; template -auto CPUVectorPolicyBase::ExpectDiffMatrixGate(qs_data_p_t bra, qs_data_p_t ket, - const qbits_t& objs, const qbits_t& ctrls, - const VVT& m, index_t dim) - -> qs_data_t { +auto CPUVectorPolicyBase::ExpectDiffMatrixGate(const qs_data_p_t& bra_out, + const qs_data_p_t& ket_out, const qbits_t& objs, + const qbits_t& ctrls, const VVT& m, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } if (objs.size() == 1) { return derived::ExpectDiffSingleQubitMatrix(bra, ket, objs, ctrls, m, dim); } @@ -210,9 +245,17 @@ auto CPUVectorPolicyBase::ExpectDiffMatrixGate(qs_data_p_t } template -auto CPUVectorPolicyBase::ExpectDiffRX(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto CPUVectorPolicyBase::ExpectDiffRX(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } auto c = static_cast(-0.5 * std::sin(val / 2)); auto is = static_cast(0.5 * std::cos(val / 2)) * IMAGE_MI; VVT gate = {{c, is}, {is, c}}; @@ -220,9 +263,17 @@ auto CPUVectorPolicyBase::ExpectDiffRX(qs_data_p_t bra, qs }; template -auto CPUVectorPolicyBase::ExpectDiffRY(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto CPUVectorPolicyBase::ExpectDiffRY(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } calc_type c = -0.5 * std::sin(val / 2); calc_type s = 0.5 * std::cos(val / 2); VVT gate = {{c, -s}, {s, c}}; @@ -230,9 +281,17 @@ auto CPUVectorPolicyBase::ExpectDiffRY(qs_data_p_t bra, qs }; template -auto CPUVectorPolicyBase::ExpectDiffRZ(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto CPUVectorPolicyBase::ExpectDiffRZ(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } calc_type c = -0.5 * std::sin(val / 2); calc_type s = 0.5 * std::cos(val / 2); auto e0 = c + IMAGE_MI * s; @@ -242,9 +301,9 @@ auto CPUVectorPolicyBase::ExpectDiffRZ(qs_data_p_t bra, qs }; template -auto CPUVectorPolicyBase::ExpectDiffGP(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto CPUVectorPolicyBase::ExpectDiffGP(const qs_data_p_t& bra, const qs_data_p_t& ket, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { auto e = std::complex(0, -1); e *= std::exp(std::complex(0, -val)); VVT gate = {{e, 0}, {0, e}}; @@ -252,9 +311,17 @@ auto CPUVectorPolicyBase::ExpectDiffGP(qs_data_p_t bra, qs } template -auto CPUVectorPolicyBase::ExpectDiffPS(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto CPUVectorPolicyBase::ExpectDiffPS(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } SingleQubitGateMask mask(objs, ctrls); calc_type res_real = 0, res_imag = 0; auto e = -std::sin(val) + IMAGE_I * std::cos(val); @@ -290,9 +357,17 @@ auto CPUVectorPolicyBase::ExpectDiffPS(qs_data_p_t bra, qs }; template -auto CPUVectorPolicyBase::ExpectDiffRxx(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto CPUVectorPolicyBase::ExpectDiffRxx(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); auto s = static_cast(std::cos(val / 2) / 2) * IMAGE_MI; @@ -346,9 +421,17 @@ auto CPUVectorPolicyBase::ExpectDiffRxx(qs_data_p_t bra, q }; template -auto CPUVectorPolicyBase::ExpectDiffRxy(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto CPUVectorPolicyBase::ExpectDiffRxy(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); auto s = static_cast(std::cos(val / 2) / 2); @@ -402,9 +485,17 @@ auto CPUVectorPolicyBase::ExpectDiffRxy(qs_data_p_t bra, q }; template -auto CPUVectorPolicyBase::ExpectDiffRxz(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto CPUVectorPolicyBase::ExpectDiffRxz(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); auto s = static_cast(std::cos(val / 2) / 2) * IMAGE_MI; @@ -458,9 +549,17 @@ auto CPUVectorPolicyBase::ExpectDiffRxz(qs_data_p_t bra, q }; template -auto CPUVectorPolicyBase::ExpectDiffRyz(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto CPUVectorPolicyBase::ExpectDiffRyz(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); auto s = static_cast(std::cos(val / 2) / 2); @@ -514,9 +613,17 @@ auto CPUVectorPolicyBase::ExpectDiffRyz(qs_data_p_t bra, q }; template -auto CPUVectorPolicyBase::ExpectDiffRyy(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto CPUVectorPolicyBase::ExpectDiffRyy(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); auto s = static_cast(std::cos(val / 2) / 2) * IMAGE_I; @@ -570,9 +677,17 @@ auto CPUVectorPolicyBase::ExpectDiffRyy(qs_data_p_t bra, q }; template -auto CPUVectorPolicyBase::ExpectDiffRzz(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto CPUVectorPolicyBase::ExpectDiffRzz(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); 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 85dac5124..5186df297 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 @@ -11,6 +11,7 @@ // 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 #include @@ -157,11 +158,12 @@ auto CPUVectorPolicyBase::ApplyTerms(qs_data_p_t* qs_p, }; template -auto CPUVectorPolicyBase::ExpectationOfTerms(qs_data_p_t* bra_p, qs_data_p_t* ket_p, +auto CPUVectorPolicyBase::ExpectationOfTerms(const qs_data_p_t& bra_out, + const qs_data_p_t& ket_out, const std::vector>& ham, index_t dim) -> py_qs_data_t { - auto& bra = (*bra_p); - auto& ket = (*ket_p); + auto bra = bra_out; + auto ket = ket_out; if (bra == nullptr) { bra = derived::InitState(dim); } diff --git a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_gate_expect.cu b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_gate_expect.cu index e9a84fa1b..9b608a3ba 100644 --- a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_gate_expect.cu +++ b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_gate_expect.cu @@ -26,10 +26,19 @@ namespace mindquantum::sim::vector::detail { template -auto GPUVectorPolicyBase::ExpectDiffNQubitsMatrix(qs_data_p_t bra, qs_data_p_t ket, - const qbits_t& objs, const qbits_t& ctrls, +auto GPUVectorPolicyBase::ExpectDiffNQubitsMatrix(const qs_data_p_t& bra_out, + const qs_data_p_t& ket_out, const qbits_t& objs, + const qbits_t& ctrls, const std::vector& gate, index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } size_t n_qubit = objs.size(); size_t m_dim = (1UL << n_qubit); size_t ctrl_mask = 0; @@ -78,10 +87,19 @@ auto GPUVectorPolicyBase::ExpectDiffNQubitsMatrix(qs_data_ qs_data_t(0, 0), thrust::plus()); } template -auto GPUVectorPolicyBase::ExpectDiffTwoQubitsMatrix(qs_data_p_t bra, qs_data_p_t ket, +auto GPUVectorPolicyBase::ExpectDiffTwoQubitsMatrix(const qs_data_p_t& bra_out, + const qs_data_p_t& ket_out, const qbits_t& objs, const qbits_t& ctrls, const std::vector& m, index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); qs_data_t m00 = m[0][0]; qs_data_t m01 = m[0][1]; @@ -154,10 +172,19 @@ auto GPUVectorPolicyBase::ExpectDiffTwoQubitsMatrix(qs_dat } template -auto GPUVectorPolicyBase::ExpectDiffSingleQubitMatrix(qs_data_p_t bra, qs_data_p_t ket, +auto GPUVectorPolicyBase::ExpectDiffSingleQubitMatrix(const qs_data_p_t& bra_out, + const qs_data_p_t& ket_out, const qbits_t& objs, const qbits_t& ctrls, const std::vector& m, index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } SingleQubitGateMask mask(objs, ctrls); qs_data_t m00 = m[0][0]; qs_data_t m01 = m[0][1]; @@ -223,10 +250,19 @@ auto GPUVectorPolicyBase::ExpectDiffSingleQubitMatrix(qs_d } template -auto GPUVectorPolicyBase::ExpectDiffMatrixGate(qs_data_p_t bra, qs_data_p_t ket, - const qbits_t& objs, const qbits_t& ctrls, +auto GPUVectorPolicyBase::ExpectDiffMatrixGate(const qs_data_p_t& bra_out, + const qs_data_p_t& ket_out, const qbits_t& objs, + const qbits_t& ctrls, const std::vector& m, index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } if (objs.size() == 1) { return derived::ExpectDiffSingleQubitMatrix(bra, ket, objs, ctrls, m, dim); } @@ -237,9 +273,17 @@ auto GPUVectorPolicyBase::ExpectDiffMatrixGate(qs_data_p_t } template -auto GPUVectorPolicyBase::ExpectDiffRX(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto GPUVectorPolicyBase::ExpectDiffRX(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } auto c = static_cast(-0.5 * std::sin(val / 2)); auto is = static_cast(0.5 * std::cos(val / 2)) * qs_data_t(0, -1); std::vector gate = {{c, is}, {is, c}}; @@ -247,9 +291,17 @@ auto GPUVectorPolicyBase::ExpectDiffRX(qs_data_p_t bra, qs } template -auto GPUVectorPolicyBase::ExpectDiffRY(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto GPUVectorPolicyBase::ExpectDiffRY(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } SingleQubitGateMask mask(objs, ctrls); auto c = static_cast(-0.5 * std::sin(val / 2)); auto s = static_cast(0.5 * std::cos(val / 2)); @@ -258,9 +310,17 @@ auto GPUVectorPolicyBase::ExpectDiffRY(qs_data_p_t bra, qs } template -auto GPUVectorPolicyBase::ExpectDiffRZ(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto GPUVectorPolicyBase::ExpectDiffRZ(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } SingleQubitGateMask mask(objs, ctrls); auto c = static_cast(-0.5 * std::sin(val / 2)); auto s = static_cast(0.5 * std::cos(val / 2)); @@ -271,9 +331,17 @@ auto GPUVectorPolicyBase::ExpectDiffRZ(qs_data_p_t bra, qs } template -auto GPUVectorPolicyBase::ExpectDiffRxx(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto GPUVectorPolicyBase::ExpectDiffRxx(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); auto s = static_cast(std::cos(val / 2) / 2) * qs_data_t(0, -1); @@ -332,9 +400,17 @@ auto GPUVectorPolicyBase::ExpectDiffRxx(qs_data_p_t bra, q } template -auto GPUVectorPolicyBase::ExpectDiffRxy(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto GPUVectorPolicyBase::ExpectDiffRxy(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); auto s = static_cast(std::cos(val / 2) / 2); @@ -393,9 +469,17 @@ auto GPUVectorPolicyBase::ExpectDiffRxy(qs_data_p_t bra, q } template -auto GPUVectorPolicyBase::ExpectDiffRxz(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto GPUVectorPolicyBase::ExpectDiffRxz(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); auto s = static_cast(std::cos(val / 2) / 2) * qs_data_t(0, -1); @@ -454,9 +538,17 @@ auto GPUVectorPolicyBase::ExpectDiffRxz(qs_data_p_t bra, q } template -auto GPUVectorPolicyBase::ExpectDiffRyz(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto GPUVectorPolicyBase::ExpectDiffRyz(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); auto s = static_cast(std::cos(val / 2) / 2); @@ -515,9 +607,17 @@ auto GPUVectorPolicyBase::ExpectDiffRyz(qs_data_p_t bra, q } template -auto GPUVectorPolicyBase::ExpectDiffRyy(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto GPUVectorPolicyBase::ExpectDiffRyy(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); auto s = static_cast(std::cos(val / 2) / 2) * qs_data_t(0, 1); @@ -576,9 +676,17 @@ auto GPUVectorPolicyBase::ExpectDiffRyy(qs_data_p_t bra, q } template -auto GPUVectorPolicyBase::ExpectDiffRzz(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto GPUVectorPolicyBase::ExpectDiffRzz(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); auto s = static_cast(std::cos(val / 2) / 2); @@ -631,9 +739,17 @@ auto GPUVectorPolicyBase::ExpectDiffRzz(qs_data_p_t bra, q } template -auto GPUVectorPolicyBase::ExpectDiffGP(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto GPUVectorPolicyBase::ExpectDiffGP(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } SingleQubitGateMask mask(objs, ctrls); auto e = std::complex(0, -1); e *= std::exp(std::complex(0, -val)); @@ -642,9 +758,17 @@ auto GPUVectorPolicyBase::ExpectDiffGP(qs_data_p_t bra, qs } template -auto GPUVectorPolicyBase::ExpectDiffPS(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, calc_type val, index_t dim) - -> qs_data_t { +auto GPUVectorPolicyBase::ExpectDiffPS(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, calc_type val, + index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + if (bra == nullptr) { + bra = derived::InitState(dim); + } + if (ket == nullptr) { + ket = derived::InitState(dim); + } SingleQubitGateMask mask(objs, ctrls); auto e = static_cast(std::cos(val)) + qs_data_t(0, 1) * static_cast(std::sin(val)); thrust::counting_iterator l(0); 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 9eac1e0b4..79bb65927 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 @@ -113,11 +113,12 @@ void GPUVectorPolicyBase::SetQS(qs_data_p_t* qs_p, const p } template -auto GPUVectorPolicyBase::ExpectationOfTerms(qs_data_p_t* bra_p, qs_data_p_t* ket_p, +auto GPUVectorPolicyBase::ExpectationOfTerms(const qs_data_p_t& bra_out, + const qs_data_p_t& ket_out, const std::vector>& ham, index_t dim) -> py_qs_data_t { - auto& bra = (*bra_p); - auto& ket = (*ket_p); + auto bra = bra_out; + auto ket = ket_out; if (bra == nullptr) { bra = derived::InitState(dim); } 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 a94e31ee7..b938a5ebf 100644 --- a/ccsrc/python/simulator/include/python/vector/bind_vec_state.h +++ b/ccsrc/python/simulator/include/python/vector/bind_vec_state.h @@ -65,12 +65,13 @@ auto BindSim(pybind11::module& module, const std::string_view& name) { // NOLIN .def("get_expectation", pybind11::overload_cast&, const circuit_t&, const circuit_t&, const typename sim_t::derived_t&, const parameter::ParameterResolver&>( - &sim_t::GetExpectation)) + &sim_t::GetExpectation, pybind11::const_)) .def("get_expectation", pybind11::overload_cast&, const circuit_t&, const circuit_t&, - const parameter::ParameterResolver&>(&sim_t::GetExpectation)) - .def("get_expectation", pybind11::overload_cast&, const circuit_t&, - const parameter::ParameterResolver&>(&sim_t::GetExpectation)) + const parameter::ParameterResolver&>(&sim_t::GetExpectation, pybind11::const_)) + .def("get_expectation", + pybind11::overload_cast&, const circuit_t&, + const parameter::ParameterResolver&>(&sim_t::GetExpectation, pybind11::const_)) .def("get_expectation_with_grad_one_one", &sim_t::GetExpectationWithGradOneOne) .def("get_expectation_with_grad_one_multi", &sim_t::GetExpectationWithGradOneMulti) .def("get_expectation_with_grad_multi_multi", &sim_t::GetExpectationWithGradMultiMulti) -- Gitee From cd06c443f9be925cbb5ce92379b3ebdf4174278b Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Mon, 8 May 2023 15:42:21 +0800 Subject: [PATCH 7/8] dynamic allocate with applying gate. --- .whitelizard.txt | 2 +- .../detail/cpu_vector_avx_double_policy.hpp | 7 +- .../vector/detail/cpu_vector_policy.hpp | 84 +-- .../vector/detail/gpu_vector_policy.cuh | 84 +-- .../include/simulator/vector/vector_state.hpp | 2 +- .../include/simulator/vector/vector_state.tpp | 109 ++-- .../cpu_vector_core_gate_expect.cpp | 23 +- .../cpu_vector_core_matrix_gate.cpp | 18 +- .../cpu_common/cpu_vector_core_condition.cpp | 8 +- .../cpu_common/cpu_vector_core_dot_like.cpp | 132 +++-- .../cpu_vector_core_gate_expect.cpp | 136 +++-- .../cpu_vector_core_matrix_gate.cpp | 61 +- .../cpu_common/cpu_vector_core_other_gate.cpp | 8 +- .../cpu_common/cpu_vector_core_policy.cpp | 11 +- .../cpu_common/cpu_vector_core_rot_pauli.cpp | 66 ++- .../cpu_common/cpu_vector_core_swap_like.cpp | 12 +- .../cpu_common/cpu_vector_core_x_like.cpp | 14 +- .../cpu_common/cpu_vector_core_z_like.cpp | 36 +- .../detail/gpu/gpu_vector_core_condition.cu | 48 +- .../detail/gpu/gpu_vector_core_dot_like.cu | 130 +++-- .../detail/gpu/gpu_vector_core_gate_expect.cu | 547 ++++++++++-------- .../detail/gpu/gpu_vector_core_matrix_gate.cu | 61 +- .../detail/gpu/gpu_vector_core_other_gate.cu | 8 +- .../detail/gpu/gpu_vector_core_policy.cu | 22 +- .../detail/gpu/gpu_vector_core_rot_pauli.cu | 54 +- .../detail/gpu/gpu_vector_core_swap_like.cu | 12 +- .../detail/gpu/gpu_vector_core_x_like.cu | 14 +- .../detail/gpu/gpu_vector_core_z_like.cu | 36 +- 28 files changed, 1110 insertions(+), 635 deletions(-) diff --git a/.whitelizard.txt b/.whitelizard.txt index 503e7c947..49b9e4dc1 100644 --- a/.whitelizard.txt +++ b/.whitelizard.txt @@ -38,7 +38,7 @@ ccsrc/python/mqbackend/lib/terms_operators.cpp:init_terms_operators ccsrc/lib/simulator/vector/detail/runtime/cmd.cpp:mindquantum::sim::rt::cmd ccsrc/python/math/lib/bind_math.cpp:BindQubitOperator ccsrc/include/math/tensor/ops_cpu/advance_math.hpp:tensor::ops::cpu::ElementFunc - +ccsrc/lib/simulator/vector/detail/cpu_avx_double/cpu_vector_core_gate_expect.cpp:mindquantum::sim::vector::detail::CPUVectorPolicyAvxDouble::ExpectDiffSingleQubitMatrix TEST_CASE mindquantum::sim::vector::detail::VectorState::ApplyGate mindquantum::sim::vector::detail::VectorState::GetExpectationWithGradOneMulti diff --git a/ccsrc/include/simulator/vector/detail/cpu_vector_avx_double_policy.hpp b/ccsrc/include/simulator/vector/detail/cpu_vector_avx_double_policy.hpp index de70ac564..4cde4e5fe 100644 --- a/ccsrc/include/simulator/vector/detail/cpu_vector_avx_double_policy.hpp +++ b/ccsrc/include/simulator/vector/detail/cpu_vector_avx_double_policy.hpp @@ -54,9 +54,10 @@ namespace mindquantum::sim::vector::detail { struct CPUVectorPolicyAvxDouble : public CPUVectorPolicyBase { using gate_matrix_t = std::vector>>; - static void ApplySingleQubitMatrix(qs_data_p_t src, qs_data_p_t des, qbit_t obj_qubit, const qbits_t& ctrls, - const std::vector>& m, index_t dim); - static qs_data_t ExpectDiffSingleQubitMatrix(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, + static void ApplySingleQubitMatrix(const qs_data_p_t& src, qs_data_p_t* des_p, qbit_t obj_qubit, + const qbits_t& ctrls, const std::vector>& m, + index_t dim); + static qs_data_t ExpectDiffSingleQubitMatrix(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, const qbits_t& ctrls, const VVT& m, index_t dim); }; } // namespace mindquantum::sim::vector::detail diff --git a/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp b/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp index 92c456368..9eaf35a0d 100644 --- a/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp +++ b/ccsrc/include/simulator/vector/detail/cpu_vector_policy.hpp @@ -77,77 +77,79 @@ struct CPUVectorPolicyBase { static qs_data_p_t ApplyTerms(qs_data_p_t* qs_p, const std::vector>& ham, index_t dim); static py_qs_data_t ExpectationOfTerms(const qs_data_p_t& bra, const qs_data_p_t& ket, const std::vector>& ham, index_t dim); - static qs_data_p_t Copy(qs_data_p_t qs, index_t dim); + static qs_data_p_t Copy(const qs_data_p_t& qs, index_t dim); template - static py_qs_data_t ConditionVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, index_t dim); - static py_qs_data_t OneStateVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, qbit_t obj_qubit, index_t dim); - static py_qs_data_t ZeroStateVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, qbit_t obj_qubit, index_t dim); - static py_qs_data_t Vdot(qs_data_p_t bra, qs_data_p_t ket, index_t dim); - static qs_data_p_t CsrDotVec(const std::shared_ptr>& a, qs_data_p_t vec, + static py_qs_data_t ConditionVdot(const qs_data_p_t& bra, const qs_data_p_t& ket_p, index_t dim); + static py_qs_data_t OneStateVdot(const qs_data_p_t& bra, const qs_data_p_t& ket, qbit_t obj_qubit, index_t dim); + static py_qs_data_t ZeroStateVdot(const qs_data_p_t& bra, const qs_data_p_t& ket, qbit_t obj_qubit, index_t dim); + static py_qs_data_t Vdot(const qs_data_p_t& bra, const qs_data_p_t& ket, index_t dim); + static qs_data_p_t CsrDotVec(const std::shared_ptr>& a, const qs_data_p_t& vec, index_t dim); static qs_data_p_t CsrDotVec(const std::shared_ptr>& a, - const std::shared_ptr>& b, qs_data_p_t vec, + const std::shared_ptr>& b, const qs_data_p_t& vec, index_t dim); - static py_qs_data_t ExpectationOfCsr(const std::shared_ptr>& a, qs_data_p_t bra, - qs_data_p_t ket, index_t dim); static py_qs_data_t ExpectationOfCsr(const std::shared_ptr>& a, - const std::shared_ptr>& b, qs_data_p_t bra, - qs_data_p_t ket, index_t dim); + const qs_data_p_t& bra, const qs_data_p_t& ket, index_t dim); + static py_qs_data_t ExpectationOfCsr(const std::shared_ptr>& a, + const std::shared_ptr>& b, + const qs_data_p_t& bra, const qs_data_p_t& ket, index_t dim); // X like operator // ======================================================================================================== - static void ApplyXLike(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, qs_data_t v1, qs_data_t v2, + static void ApplyXLike(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, qs_data_t v1, qs_data_t v2, index_t dim); - static void ApplyX(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, index_t dim); - static void ApplyY(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, index_t dim); + static void ApplyX(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim); + static void ApplyY(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim); // Z like operator // ======================================================================================================== - static void ApplyZLike(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, qs_data_t val, index_t dim); - static void ApplyZ(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, index_t dim); + static void ApplyZLike(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, qs_data_t val, index_t dim); + static void ApplyZ(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim); // The crazy code spell check in CI do not allow apply s to name following API, even I set the filter file. - static void ApplySGate(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, index_t dim); - static void ApplyT(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, index_t dim); - static void ApplySdag(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, index_t dim); - static void ApplyTdag(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, index_t dim); - static void ApplyPS(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplySGate(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim); + static void ApplyT(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim); + static void ApplySdag(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim); + static void ApplyTdag(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim); + static void ApplyPS(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); // Single qubit operator // ======================================================================================================== - static void ApplySingleQubitMatrix(qs_data_p_t src, qs_data_p_t des, qbit_t obj_qubit, const qbits_t& ctrls, - const std::vector>& m, index_t dim); - static void ApplyTwoQubitsMatrix(qs_data_p_t src, qs_data_p_t des, const qbits_t& objs, const qbits_t& ctrls, - const std::vector>& m, index_t dim); - static void ApplyNQubitsMatrix(qs_data_p_t src, qs_data_p_t des, const qbits_t& objs, const qbits_t& ctrls, - const std::vector>& m, index_t dim); - static void ApplyMatrixGate(qs_data_p_t src, qs_data_p_t des, const qbits_t& objs, const qbits_t& ctrls, + static void ApplySingleQubitMatrix(const qs_data_p_t& src, qs_data_p_t* des_p, qbit_t obj_qubit, + const qbits_t& ctrls, const std::vector>& m, + index_t dim); + static void ApplyTwoQubitsMatrix(const qs_data_p_t& src, qs_data_p_t* des_p, const qbits_t& objs, + const qbits_t& ctrls, const std::vector>& m, + index_t dim); + static void ApplyNQubitsMatrix(const qs_data_p_t& src, qs_data_p_t* des_p, const qbits_t& objs, + const qbits_t& ctrls, const std::vector>& m, index_t dim); + static void ApplyMatrixGate(const qs_data_p_t& src, qs_data_p_t* des_p, const qbits_t& objs, const qbits_t& ctrls, const std::vector>& m, index_t dim); - static void ApplyH(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, index_t dim); - static void ApplyGP(qs_data_p_t qs, qbit_t obj_qubit, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyH(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim); + static void ApplyGP(qs_data_p_t* qs_p, qbit_t obj_qubit, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); - static void ApplyRX(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyRX(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); - static void ApplyRY(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyRY(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); - static void ApplyRZ(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyRZ(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); - static void ApplySWAP(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, index_t dim); - static void ApplyISWAP(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, bool daggered, index_t dim); - static void ApplyRxx(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplySWAP(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim); + static void ApplyISWAP(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, bool daggered, index_t dim); + static void ApplyRxx(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); - static void ApplyRyy(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyRyy(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); - static void ApplyRzz(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyRzz(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); - static void ApplyRxy(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyRxy(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); - static void ApplyRxz(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyRxz(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); - static void ApplyRyz(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyRyz(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); // gate_expectation diff --git a/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh b/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh index bdebbdd4a..b8a63f5d2 100644 --- a/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh +++ b/ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh @@ -68,76 +68,78 @@ struct GPUVectorPolicyBase { static qs_data_p_t ApplyTerms(qs_data_p_t* qs_p, const std::vector>& ham, index_t dim); static py_qs_data_t ExpectationOfTerms(const qs_data_p_t& bra, const qs_data_p_t& ket, const std::vector>& ham, index_t dim); - static qs_data_p_t Copy(qs_data_p_t qs, index_t dim); + static qs_data_p_t Copy(const qs_data_p_t& qs, index_t dim); template - static py_qs_data_t ConditionVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, index_t dim); - static py_qs_data_t OneStateVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, qbit_t obj_qubit, index_t dim); - static py_qs_data_t ZeroStateVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, qbit_t obj_qubit, index_t dim); - static py_qs_data_t Vdot(qs_data_p_t bra, qs_data_p_t ket, index_t dim); - static qs_data_p_t CsrDotVec(const std::shared_ptr>& a, qs_data_p_t vec, + static py_qs_data_t ConditionVdot(const qs_data_p_t& bra, const qs_data_p_t& ket, index_t dim); + static py_qs_data_t OneStateVdot(const qs_data_p_t& bra, const qs_data_p_t& ket, qbit_t obj_qubit, index_t dim); + static py_qs_data_t ZeroStateVdot(const qs_data_p_t& bra, const qs_data_p_t& ket, qbit_t obj_qubit, index_t dim); + static py_qs_data_t Vdot(const qs_data_p_t& bra, const qs_data_p_t& ket, index_t dim); + static qs_data_p_t CsrDotVec(const std::shared_ptr>& a, const qs_data_p_t& vec, index_t dim); static qs_data_p_t CsrDotVec(const std::shared_ptr>& a, - const std::shared_ptr>& b, qs_data_p_t vec, + const std::shared_ptr>& b, const qs_data_p_t& vec, index_t dim); - static py_qs_data_t ExpectationOfCsr(const std::shared_ptr>& a, qs_data_p_t bra, - qs_data_p_t ket, index_t dim); static py_qs_data_t ExpectationOfCsr(const std::shared_ptr>& a, - const std::shared_ptr>& b, qs_data_p_t bra, - qs_data_p_t ket, index_t dim); + const qs_data_p_t& bra, const qs_data_p_t& ket, index_t dim); + static py_qs_data_t ExpectationOfCsr(const std::shared_ptr>& a, + const std::shared_ptr>& b, + const qs_data_p_t& bra, const qs_data_p_t& ket, index_t dim); // X like operator // ======================================================================================================== - static void ApplyXLike(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, qs_data_t v1, qs_data_t v2, + static void ApplyXLike(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, qs_data_t v1, qs_data_t v2, index_t dim); - static void ApplyX(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, index_t dim); - static void ApplyY(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, index_t dim); + static void ApplyX(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim); + static void ApplyY(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim); // Z like operator // ======================================================================================================== - static void ApplyZLike(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, qs_data_t val, index_t dim); - static void ApplyZ(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, index_t dim); - static void ApplySGate(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, index_t dim); - static void ApplyT(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, index_t dim); - static void ApplySdag(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, index_t dim); - static void ApplyTdag(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, index_t dim); - static void ApplyPS(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyZLike(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, qs_data_t val, index_t dim); + static void ApplyZ(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim); + static void ApplySGate(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim); + static void ApplyT(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim); + static void ApplySdag(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim); + static void ApplyTdag(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim); + static void ApplyPS(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); // Single qubit operator // ======================================================================================================== - static void ApplySingleQubitMatrix(qs_data_p_t src, qs_data_p_t des, qbit_t obj_qubit, const qbits_t& ctrls, - const std::vector>& m, index_t dim); - static void ApplyTwoQubitsMatrix(qs_data_p_t src, qs_data_p_t des, const qbits_t& objs, const qbits_t& ctrls, - const std::vector>& m, index_t dim); - static void ApplyNQubitsMatrix(qs_data_p_t src, qs_data_p_t des, const qbits_t& objs, const qbits_t& ctrls, - const std::vector>& m, index_t dim); - static void ApplyMatrixGate(qs_data_p_t src, qs_data_p_t des, const qbits_t& objs, const qbits_t& ctrls, + static void ApplySingleQubitMatrix(const qs_data_p_t& src, qs_data_p_t* des_p, qbit_t obj_qubit, + const qbits_t& ctrls, const std::vector>& m, + index_t dim); + static void ApplyTwoQubitsMatrix(const qs_data_p_t& src, qs_data_p_t* des_p, const qbits_t& objs, + const qbits_t& ctrls, const std::vector>& m, + index_t dim); + static void ApplyNQubitsMatrix(const qs_data_p_t& src, qs_data_p_t* des_p, const qbits_t& objs, + const qbits_t& ctrls, const std::vector>& m, index_t dim); + static void ApplyMatrixGate(const qs_data_p_t& src, qs_data_p_t* des_p, const qbits_t& objs, const qbits_t& ctrls, const std::vector>& m, index_t dim); - static void ApplyH(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, index_t dim); - static void ApplyGP(qs_data_p_t qs, qbit_t obj_qubit, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyH(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim); + static void ApplyGP(qs_data_p_t* qs_p, qbit_t obj_qubit, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); - static void ApplyRX(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyRX(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); - static void ApplyRY(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyRY(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); - static void ApplyRZ(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyRZ(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); - static void ApplySWAP(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, index_t dim); - static void ApplyISWAP(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, bool daggered, index_t dim); - static void ApplyRxx(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplySWAP(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim); + static void ApplyISWAP(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, bool daggered, index_t dim); + static void ApplyRxx(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); - static void ApplyRyy(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyRyy(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); - static void ApplyRzz(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyRzz(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); - static void ApplyRxy(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyRxy(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); - static void ApplyRxz(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyRxz(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); - static void ApplyRyz(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, + static void ApplyRyz(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff = false); // gate_expec diff --git a/ccsrc/include/simulator/vector/vector_state.hpp b/ccsrc/include/simulator/vector/vector_state.hpp index 68094d881..586590f77 100644 --- a/ccsrc/include/simulator/vector/vector_state.hpp +++ b/ccsrc/include/simulator/vector/vector_state.hpp @@ -195,7 +195,7 @@ class VectorState { VectorState astype(unsigned seed) const; protected: - qs_data_p_t qs = nullptr; + qs_data_p_t qs = nullptr; // nullptr represent zero state. qbit_t n_qubits = 0; index_t dim = 0; unsigned seed = 0; diff --git a/ccsrc/include/simulator/vector/vector_state.tpp b/ccsrc/include/simulator/vector/vector_state.tpp index ef3f6b19b..c778a1b26 100644 --- a/ccsrc/include/simulator/vector/vector_state.tpp +++ b/ccsrc/include/simulator/vector/vector_state.tpp @@ -149,43 +149,40 @@ void VectorState::SetQS(const VT& qs_out) { template index_t VectorState::ApplyGate(const std::shared_ptr& gate, const parameter::ParameterResolver& pr, bool diff) { - if (this->qs == nullptr) { - this->qs = qs_policy_t::InitState(dim); - } auto id = gate->id_; switch (id) { case GateID::I: break; case GateID::X: - qs_policy_t::ApplyX(qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); + qs_policy_t::ApplyX(&qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); break; case GateID::Y: - qs_policy_t::ApplyY(qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); + qs_policy_t::ApplyY(&qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); break; case GateID::Z: - qs_policy_t::ApplyZ(qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); + qs_policy_t::ApplyZ(&qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); break; case GateID::H: - qs_policy_t::ApplyH(qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); + qs_policy_t::ApplyH(&qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); break; case GateID::S: - qs_policy_t::ApplySGate(qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); + qs_policy_t::ApplySGate(&qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); break; case GateID::Sdag: - qs_policy_t::ApplySdag(qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); + qs_policy_t::ApplySdag(&qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); break; case GateID::T: - qs_policy_t::ApplyT(qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); + qs_policy_t::ApplyT(&qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); break; case GateID::Tdag: - qs_policy_t::ApplyTdag(qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); + qs_policy_t::ApplyTdag(&qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); break; case GateID::SWAP: - qs_policy_t::ApplySWAP(qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); + qs_policy_t::ApplySWAP(&qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); break; case GateID::ISWAP: { bool daggered = static_cast(gate.get())->daggered_; - qs_policy_t::ApplyISWAP(qs, gate->obj_qubits_, gate->ctrl_qubits_, daggered, dim); + qs_policy_t::ApplyISWAP(&qs, gate->obj_qubits_, gate->ctrl_qubits_, daggered, dim); } break; case GateID::RX: { auto g = static_cast(gate.get()); @@ -193,7 +190,7 @@ index_t VectorState::ApplyGate(const std::shared_ptr& g diff = false; } auto val = tensor::ops::cpu::to_vector(g->prs_[0].Combination(pr).const_value)[0]; - qs_policy_t::ApplyRX(qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); + qs_policy_t::ApplyRX(&qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); } break; case GateID::RY: { auto g = static_cast(gate.get()); @@ -201,7 +198,7 @@ index_t VectorState::ApplyGate(const std::shared_ptr& g diff = false; } auto val = tensor::ops::cpu::to_vector(g->prs_[0].Combination(pr).const_value)[0]; - qs_policy_t::ApplyRY(qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); + qs_policy_t::ApplyRY(&qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); } break; case GateID::RZ: { auto g = static_cast(gate.get()); @@ -209,7 +206,7 @@ index_t VectorState::ApplyGate(const std::shared_ptr& g diff = false; } auto val = tensor::ops::cpu::to_vector(g->prs_[0].Combination(pr).const_value)[0]; - qs_policy_t::ApplyRZ(qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); + qs_policy_t::ApplyRZ(&qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); } break; case GateID::Rxx: { auto g = static_cast(gate.get()); @@ -217,7 +214,7 @@ index_t VectorState::ApplyGate(const std::shared_ptr& g diff = false; } auto val = tensor::ops::cpu::to_vector(g->prs_[0].Combination(pr).const_value)[0]; - qs_policy_t::ApplyRxx(qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); + qs_policy_t::ApplyRxx(&qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); } break; case GateID::Ryy: { auto g = static_cast(gate.get()); @@ -225,7 +222,7 @@ index_t VectorState::ApplyGate(const std::shared_ptr& g diff = false; } auto val = tensor::ops::cpu::to_vector(g->prs_[0].Combination(pr).const_value)[0]; - qs_policy_t::ApplyRyy(qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); + qs_policy_t::ApplyRyy(&qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); } break; case GateID::Rzz: { auto g = static_cast(gate.get()); @@ -233,7 +230,7 @@ index_t VectorState::ApplyGate(const std::shared_ptr& g diff = false; } auto val = tensor::ops::cpu::to_vector(g->prs_[0].Combination(pr).const_value)[0]; - qs_policy_t::ApplyRzz(qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); + qs_policy_t::ApplyRzz(&qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); } break; case GateID::Rxy: { auto g = static_cast(gate.get()); @@ -241,7 +238,7 @@ index_t VectorState::ApplyGate(const std::shared_ptr& g diff = false; } auto val = tensor::ops::cpu::to_vector(g->prs_[0].Combination(pr).const_value)[0]; - qs_policy_t::ApplyRxy(qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); + qs_policy_t::ApplyRxy(&qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); } break; case GateID::Rxz: { auto g = static_cast(gate.get()); @@ -249,7 +246,7 @@ index_t VectorState::ApplyGate(const std::shared_ptr& g diff = false; } auto val = tensor::ops::cpu::to_vector(g->prs_[0].Combination(pr).const_value)[0]; - qs_policy_t::ApplyRxz(qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); + qs_policy_t::ApplyRxz(&qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); } break; case GateID::Ryz: { auto g = static_cast(gate.get()); @@ -257,7 +254,7 @@ index_t VectorState::ApplyGate(const std::shared_ptr& g diff = false; } auto val = tensor::ops::cpu::to_vector(g->prs_[0].Combination(pr).const_value)[0]; - qs_policy_t::ApplyRyz(qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); + qs_policy_t::ApplyRyz(&qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); } break; case GateID::PS: { auto g = static_cast(gate.get()); @@ -265,7 +262,7 @@ index_t VectorState::ApplyGate(const std::shared_ptr& g diff = false; } auto val = tensor::ops::cpu::to_vector(g->prs_[0].Combination(pr).const_value)[0]; - qs_policy_t::ApplyPS(qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); + qs_policy_t::ApplyPS(&qs, gate->obj_qubits_, gate->ctrl_qubits_, val, dim, diff); } break; case GateID::GP: { auto g = static_cast(gate.get()); @@ -273,7 +270,7 @@ index_t VectorState::ApplyGate(const std::shared_ptr& g diff = false; } auto val = tensor::ops::cpu::to_vector(g->prs_[0].Combination(pr).const_value)[0]; - qs_policy_t::ApplyGP(qs, gate->obj_qubits_[0], gate->ctrl_qubits_, val, dim, diff); + qs_policy_t::ApplyGP(&qs, gate->obj_qubits_[0], gate->ctrl_qubits_, val, dim, diff); } break; case GateID::U3: { if (diff) { @@ -289,7 +286,7 @@ index_t VectorState::ApplyGate(const std::shared_ptr& g auto lambda = u3->lambda.Combination(pr).const_value; m = U3Matrix(theta, phi, lambda); } - qs_policy_t::ApplySingleQubitMatrix(qs, qs, gate->obj_qubits_[0], gate->ctrl_qubits_, + qs_policy_t::ApplySingleQubitMatrix(qs, &qs, gate->obj_qubits_[0], gate->ctrl_qubits_, tensor::ops::cpu::to_vector(m), dim); } break; case GateID::FSim: { @@ -305,7 +302,7 @@ index_t VectorState::ApplyGate(const std::shared_ptr& g auto phi = fsim->phi.Combination(pr).const_value; m = FSimMatrix(theta, phi); } - qs_policy_t::ApplyTwoQubitsMatrix(qs, qs, gate->obj_qubits_, gate->ctrl_qubits_, + qs_policy_t::ApplyTwoQubitsMatrix(qs, &qs, gate->obj_qubits_, gate->ctrl_qubits_, tensor::ops::cpu::to_vector(m), dim); } break; case GateID::M: @@ -333,7 +330,7 @@ index_t VectorState::ApplyGate(const std::shared_ptr& g mat = g->numba_param_diff_matrix_(val); } } - qs_policy_t::ApplyMatrixGate(qs, qs, gate->obj_qubits_, gate->ctrl_qubits_, + qs_policy_t::ApplyMatrixGate(qs, &qs, gate->obj_qubits_, gate->ctrl_qubits_, tensor::ops::cpu::to_vector(mat), dim); break; } @@ -345,9 +342,6 @@ index_t VectorState::ApplyGate(const std::shared_ptr& g template auto VectorState::ApplyMeasure(const std::shared_ptr& gate) -> index_t { - if (this->qs == nullptr) { - this->qs = qs_policy_t::InitState(dim); - } index_t one_mask = (1UL << gate->obj_qubits_[0]); auto one_amp = qs_policy_t::ConditionalCollect(qs, one_mask, one_mask, true, dim).real(); index_t collapse_mask = (static_cast(rng_() < one_amp) << gate->obj_qubits_[0]); @@ -358,9 +352,6 @@ auto VectorState::ApplyMeasure(const std::shared_ptr& g template void VectorState::ApplyChannel(const std::shared_ptr& gate) { - if (this->qs == nullptr) { - this->qs = qs_policy_t::InitState(dim); - } auto id = gate->id_; switch (id) { case GateID::PL: @@ -380,9 +371,6 @@ void VectorState::ApplyChannel(const std::shared_ptr& g template void VectorState::ApplyPauliChannel(const std::shared_ptr& gate) { - if (this->qs == nullptr) { - this->qs = qs_policy_t::InitState(dim); - } double r = static_cast(rng_()); auto g = static_cast(gate.get()); auto it = std::lower_bound(g->cumulative_probs_.begin(), g->cumulative_probs_.end(), r); @@ -393,24 +381,21 @@ void VectorState::ApplyPauliChannel(const std::shared_ptrobj_qubits_, gate->ctrl_qubits_, dim); + qs_policy_t::ApplyX(&qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); } else if (gate_index == 1) { - qs_policy_t::ApplyY(qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); + qs_policy_t::ApplyY(&qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); } else if (gate_index == 2) { - qs_policy_t::ApplyZ(qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); + qs_policy_t::ApplyZ(&qs, gate->obj_qubits_, gate->ctrl_qubits_, dim); } } template void VectorState::ApplyKrausChannel(const std::shared_ptr& gate) { - if (this->qs == nullptr) { - this->qs = qs_policy_t::InitState(dim); - } auto tmp_qs = qs_policy_t::InitState(dim); calc_type prob = 0; auto g = static_cast(gate.get()); for (size_t n_kraus = 0; n_kraus < g->kraus_operator_set_.size(); n_kraus++) { - qs_policy_t::ApplySingleQubitMatrix(qs, tmp_qs, gate->obj_qubits_[0], gate->ctrl_qubits_, + qs_policy_t::ApplySingleQubitMatrix(qs, &tmp_qs, gate->obj_qubits_[0], gate->ctrl_qubits_, tensor::ops::cpu::to_vector(g->kraus_operator_set_[n_kraus]), dim); calc_type renormal_factor_square = qs_policy_t::Vdot(tmp_qs, tmp_qs, dim).real(); @@ -428,10 +413,7 @@ void VectorState::ApplyKrausChannel(const std::shared_ptr void VectorState::ApplyDampingChannel(const std::shared_ptr& gate) { - if (this->qs == nullptr) { - this->qs = qs_policy_t::InitState(dim); - } - calc_type reduced_factor_b_square = qs_policy_t::OneStateVdot(&qs, &qs, gate->obj_qubits_[0], dim).real(); + calc_type reduced_factor_b_square = qs_policy_t::OneStateVdot(qs, qs, gate->obj_qubits_[0], dim).real(); calc_type reduced_factor_b = std::sqrt(reduced_factor_b_square); if (reduced_factor_b < 1e-8) { return; @@ -448,7 +430,7 @@ void VectorState::ApplyDampingChannel(const std::shared_ptr m({{0, 1 / reduced_factor_b}, {0, 0}}); - qs_policy_t::ApplySingleQubitMatrix(qs, tmp_qs, gate->obj_qubits_[0], gate->ctrl_qubits_, m, dim); + qs_policy_t::ApplySingleQubitMatrix(qs, &tmp_qs, gate->obj_qubits_[0], gate->ctrl_qubits_, m, dim); } else { qs_policy_t::ConditionalMul(qs, &tmp_qs, (1UL << gate->obj_qubits_[0]), 1, 1 / reduced_factor_b, 0, dim); } @@ -584,18 +566,10 @@ auto VectorState::ExpectDiffGate(const qs_data_p_t& bra, const qs_ } template -auto VectorState::ExpectDiffU3(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, +auto VectorState::ExpectDiffU3(const qs_data_p_t& bra, const qs_data_p_t& ket, const std::shared_ptr& gate, const parameter::ParameterResolver& pr, index_t dim) const -> tensor::Matrix { - auto bra = bra_out; - auto ket = ket_out; - if (bra == nullptr) { - bra = qs_policy_t::InitState(dim); - } - if (ket == nullptr) { - ket = qs_policy_t::InitState(dim); - } VT grad = {0, 0, 0}; auto u3 = static_cast(gate.get()); if (u3->parameterized_) { @@ -623,18 +597,10 @@ auto VectorState::ExpectDiffU3(const qs_data_p_t& bra_out, const q } template -auto VectorState::ExpectDiffFSim(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, +auto VectorState::ExpectDiffFSim(const qs_data_p_t& bra, const qs_data_p_t& ket, const std::shared_ptr& gate, const parameter::ParameterResolver& pr, index_t dim) const -> tensor::Matrix { - auto bra = bra_out; - auto ket = ket_out; - if (bra == nullptr) { - bra = qs_policy_t::InitState(dim); - } - if (ket == nullptr) { - ket = qs_policy_t::InitState(dim); - } VT grad = {0, 0}; auto fsim = static_cast(gate.get()); if (fsim->parameterized_) { @@ -658,9 +624,6 @@ auto VectorState::ExpectDiffFSim(const qs_data_p_t& bra_out, const template std::map VectorState::ApplyCircuit(const circuit_t& circ, const parameter::ParameterResolver& pr) { - if (this->qs == nullptr) { - this->qs = qs_policy_t::InitState(dim); - } std::map result; for (auto& g : circ) { if (g->id_ == GateID::M) { @@ -674,9 +637,6 @@ std::map VectorState::ApplyCircuit(const circuit template void VectorState::ApplyHamiltonian(const Hamiltonian& ham) { - if (this->qs == nullptr) { - this->qs = qs_policy_t::InitState(dim); - } qs_data_p_t new_qs; if (ham.how_to_ == ORIGIN) { new_qs = qs_policy_t::ApplyTerms(&qs, ham.ham_, dim); @@ -695,12 +655,9 @@ auto VectorState::GetCircuitMatrix(const circuit_t& circ, const pa VVT> out((1UL << n_qubits), VT>((1UL << n_qubits), 0)); for (size_t i = 0; i < (1UL << n_qubits); i++) { auto sim = VectorState(n_qubits, seed); - if (sim.qs == nullptr) { - sim.qs = qs_policy_t::InitState(dim); - } for (qbit_t j = 0; j < n_qubits; ++j) { if ((i >> j) & 1) { - qs_policy_t_::ApplyX(sim.qs, qbits_t({j}), qbits_t({}), sim.dim); + qs_policy_t_::ApplyX(&(sim.qs), qbits_t({j}), qbits_t({}), sim.dim); } } sim.ApplyCircuit(circ, pr); diff --git a/ccsrc/lib/simulator/vector/detail/cpu_avx_double/cpu_vector_core_gate_expect.cpp b/ccsrc/lib/simulator/vector/detail/cpu_avx_double/cpu_vector_core_gate_expect.cpp index f09044e4e..f382a5109 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_avx_double/cpu_vector_core_gate_expect.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_avx_double/cpu_vector_core_gate_expect.cpp @@ -18,9 +18,20 @@ #include "simulator/vector/detail/cpu_vector_avx_double_policy.hpp" namespace mindquantum::sim::vector::detail { -auto CPUVectorPolicyAvxDouble::ExpectDiffSingleQubitMatrix(qs_data_p_t bra, qs_data_p_t ket, const qbits_t& objs, - const qbits_t& ctrls, const VVT& m, - index_t dim) -> qs_data_t { +auto CPUVectorPolicyAvxDouble::ExpectDiffSingleQubitMatrix(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + const qbits_t& objs, const qbits_t& ctrls, + const VVT& m, index_t dim) -> qs_data_t { + auto bra = bra_out; + auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; + if (bra == nullptr) { + bra = derived::InitState(dim); + will_free_bra = true; + } + if (ket == nullptr) { + ket = derived::InitState(dim); + will_free_ket = true; + } SingleQubitGateMask mask(objs, ctrls); gate_matrix_t gate = {{m[0][0], m[0][1]}, {m[1][0], m[1][1]}}; __m256d neg = _mm256_setr_pd(1.0, -1.0, 1.0, -1.0); @@ -100,6 +111,12 @@ auto CPUVectorPolicyAvxDouble::ExpectDiffSingleQubitMatrix(qs_data_p_t bra, qs_d // clang-format on } } + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } return {res_real, res_imag}; }; } // namespace mindquantum::sim::vector::detail diff --git a/ccsrc/lib/simulator/vector/detail/cpu_avx_double/cpu_vector_core_matrix_gate.cpp b/ccsrc/lib/simulator/vector/detail/cpu_avx_double/cpu_vector_core_matrix_gate.cpp index 98081d175..ce474bd52 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_avx_double/cpu_vector_core_matrix_gate.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_avx_double/cpu_vector_core_matrix_gate.cpp @@ -13,14 +13,27 @@ // limitations under the License. #include "config/openmp.hpp" +#include "core/utils.hpp" #include "math/pr/parameter_resolver.hpp" #include "simulator/utils.hpp" #include "simulator/vector/detail/cpu_vector_avx_double_policy.hpp" namespace mindquantum::sim::vector::detail { -void CPUVectorPolicyAvxDouble::ApplySingleQubitMatrix(qs_data_p_t src, qs_data_p_t des, qbit_t obj_qubit, +void CPUVectorPolicyAvxDouble::ApplySingleQubitMatrix(const qs_data_p_t& src_out, qs_data_p_t* des_p, qbit_t obj_qubit, const qbits_t& ctrls, const std::vector>& m, index_t dim) { + auto& des = (*des_p); + if (des == nullptr) { + des = CPUVectorPolicyAvxDouble::InitState(dim); + } + qs_data_p_t src; + bool will_free = false; + if (src_out == nullptr) { + src = CPUVectorPolicyAvxDouble::InitState(dim); + will_free = true; + } else { + src = src_out; + } SingleQubitGateMask mask({obj_qubit}, ctrls); gate_matrix_t gate = {{m[0][0], m[0][1]}, {m[1][0], m[1][1]}}; __m256d neg = _mm256_setr_pd(1.0, -1.0, 1.0, -1.0); @@ -48,5 +61,8 @@ void CPUVectorPolicyAvxDouble::ApplySingleQubitMatrix(qs_data_p_t src, qs_data_p } }); } + if (will_free) { + CPUVectorPolicyAvxDouble::FreeState(&src); + } } } // namespace mindquantum::sim::vector::detail diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_condition.cpp b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_condition.cpp index 251aee0ba..3ca676bcf 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_condition.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_condition.cpp @@ -37,9 +37,9 @@ void CPUVectorPolicyBase::ConditionalBinary(const qs_data_ } if (src == nullptr) { if ((0 & mask) == condi) { - des[0] = op(src[0], succ_coeff); + des[0] = op(1.0, succ_coeff); } else { - des[0] = op(src[0], fail_coeff); + des[0] = op(1.0, fail_coeff); } } else { THRESHOLD_OMP_FOR( @@ -65,9 +65,9 @@ void CPUVectorPolicyBase::ConditionalBinary(const qs_data_ } if (src == nullptr) { if ((0 & mask) == condi) { - des[0] = op(src[0], succ_coeff); + des[0] = op(1.0, succ_coeff); } else { - des[0] = op(src[0], fail_coeff); + des[0] = op(1.0, fail_coeff); } } else { THRESHOLD_OMP_FOR( diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_dot_like.cpp b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_dot_like.cpp index 8f310d519..141945e3a 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_dot_like.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_dot_like.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 "config/openmp.hpp" #include "core/sparse/algo.hpp" @@ -27,7 +29,8 @@ namespace mindquantum::sim::vector::detail { template -auto CPUVectorPolicyBase::Vdot(qs_data_p_t bra, qs_data_p_t ket, index_t dim) -> py_qs_data_t { +auto CPUVectorPolicyBase::Vdot(const qs_data_p_t& bra, const qs_data_p_t& ket, index_t dim) + -> py_qs_data_t { if (bra == nullptr && ket == nullptr) { return 1.0; } else if (bra == nullptr) { @@ -49,15 +52,23 @@ auto CPUVectorPolicyBase::Vdot(qs_data_p_t bra, qs_data_p_ template template -auto CPUVectorPolicyBase::ConditionVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, index_t dim) - -> py_qs_data_t { - auto& bra = (*bra_p); - auto& ket = (*ket_p); - if (bra == nullptr) { - bra = derived::InitState(dim); - } - if (ket == nullptr) { - ket = derived::InitState(dim); +auto CPUVectorPolicyBase::ConditionVdot(const qs_data_p_t& bra, const qs_data_p_t& ket, + index_t dim) -> py_qs_data_t { + if (bra == nullptr && ket == nullptr) { + if ((0 & mask) == condi) { + return 1.0; + } + return 0.0; + } else if (bra == nullptr) { + if ((0 & mask) == condi) { + return ket[0]; + } + return 0.0; + } else if (ket == nullptr) { + if ((0 & mask) == condi) { + return std::conj(bra[0]); + } + return 0.0; } calc_type res_real = 0, res_imag = 0; // clang-format off @@ -74,15 +85,10 @@ auto CPUVectorPolicyBase::ConditionVdot(qs_data_p_t* bra_p } template -auto CPUVectorPolicyBase::OneStateVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, qbit_t obj_qubit, - index_t dim) -> py_qs_data_t { - auto& bra = (*bra_p); - auto& ket = (*ket_p); - if (bra == nullptr) { - bra = derived::InitState(dim); - } - if (ket == nullptr) { - ket = derived::InitState(dim); +auto CPUVectorPolicyBase::OneStateVdot(const qs_data_p_t& bra, const qs_data_p_t& ket, + qbit_t obj_qubit, index_t dim) -> py_qs_data_t { + if (bra == nullptr || ket == nullptr) { + return 0.0; } SingleQubitGateMask mask({obj_qubit}, {}); calc_type res_real = 0, res_imag = 0; @@ -99,15 +105,14 @@ auto CPUVectorPolicyBase::OneStateVdot(qs_data_p_t* bra_p, } template -auto CPUVectorPolicyBase::ZeroStateVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, qbit_t obj_qubit, - index_t dim) -> py_qs_data_t { - auto& bra = (*bra_p); - auto& ket = (*ket_p); - if (bra == nullptr) { - bra = derived::InitState(dim); - } - if (ket == nullptr) { - ket = derived::InitState(dim); +auto CPUVectorPolicyBase::ZeroStateVdot(const qs_data_p_t& bra, const qs_data_p_t& ket, + qbit_t obj_qubit, index_t dim) -> py_qs_data_t { + if (bra == nullptr && ket == nullptr) { + return 1.0; + } else if (bra == nullptr) { + return ket[0]; + } else if (ket == nullptr) { + return std::conj(bra[0]); } SingleQubitGateMask mask({obj_qubit}, {}); calc_type res_real = 0, res_imag = 0; @@ -125,44 +130,97 @@ auto CPUVectorPolicyBase::ZeroStateVdot(qs_data_p_t* bra_p template auto CPUVectorPolicyBase::CsrDotVec(const std::shared_ptr>& a, - qs_data_p_t vec, index_t dim) -> qs_data_p_t { + const qs_data_p_t& vec_out, index_t dim) -> qs_data_p_t { if (dim != a->dim_) { throw std::runtime_error("Sparse hamiltonian size not match with quantum state size."); } + auto vec = vec_out; + bool will_free = false; + if (vec == nullptr) { + vec = derived::InitState(dim); + will_free = true; + } auto out = sparse::Csr_Dot_Vec(a, reinterpret_cast(vec)); + if (will_free) { + derived::FreeState(&vec); + } return reinterpret_cast(out); } template auto CPUVectorPolicyBase::CsrDotVec(const std::shared_ptr>& a, const std::shared_ptr>& b, - qs_data_p_t vec, index_t dim) -> qs_data_p_t { + const qs_data_p_t& vec_out, index_t dim) -> qs_data_p_t { if ((dim != a->dim_) || (dim != b->dim_)) { throw std::runtime_error("Sparse hamiltonian size not match with quantum state size."); } + auto vec = vec_out; + bool will_free = false; + if (vec == nullptr) { + vec = derived::InitState(dim); + } auto out = sparse::Csr_Dot_Vec(a, b, reinterpret_cast(vec)); + if (will_free) { + derived::FreeState(&vec); + } return reinterpret_cast(out); } template auto CPUVectorPolicyBase::ExpectationOfCsr( - const std::shared_ptr>& a, qs_data_p_t bra, qs_data_p_t ket, index_t dim) - -> py_qs_data_t { + const std::shared_ptr>& a, const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + index_t dim) -> py_qs_data_t { if (dim != a->dim_) { throw std::runtime_error("Sparse hamiltonian size not match with quantum state size."); } - return sparse::ExpectationOfCsr(a, reinterpret_cast(bra), - reinterpret_cast(ket)); + auto bra = bra_out; + auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; + if (bra == nullptr) { + bra = derived::InitState(dim); + will_free_bra = true; + } + if (ket == nullptr) { + ket = derived::InitState(dim); + will_free_ket = true; + } + auto res = sparse::ExpectationOfCsr(a, reinterpret_cast(bra), + reinterpret_cast(ket)); + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } + return res; } template auto CPUVectorPolicyBase::ExpectationOfCsr( const std::shared_ptr>& a, const std::shared_ptr>& b, - qs_data_p_t bra, qs_data_p_t ket, index_t dim) -> py_qs_data_t { + const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, index_t dim) -> py_qs_data_t { if ((dim != a->dim_) || (dim != b->dim_)) { throw std::runtime_error("Sparse hamiltonian size not match with quantum state size."); } - return sparse::ExpectationOfCsr(a, b, reinterpret_cast(bra), - reinterpret_cast(ket)); + auto bra = bra_out; + auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; + if (bra == nullptr) { + bra = derived::InitState(dim); + will_free_bra = true; + } + if (ket == nullptr) { + ket = derived::InitState(dim); + will_free_ket = true; + } + auto res = sparse::ExpectationOfCsr(a, b, reinterpret_cast(bra), + reinterpret_cast(ket)); + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } + return res; } #ifdef __x86_64__ diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_gate_expect.cpp b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_gate_expect.cpp index 0def604fa..338c62f35 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_gate_expect.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_gate_expect.cpp @@ -33,11 +33,14 @@ auto CPUVectorPolicyBase::ExpectDiffNQubitsMatrix(const qs -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } size_t n_qubit = objs.size(); size_t m_dim = (1UL << n_qubit); @@ -74,6 +77,12 @@ auto CPUVectorPolicyBase::ExpectDiffNQubitsMatrix(const qs } } }) + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } return {res_real, res_imag}; } @@ -85,11 +94,14 @@ auto CPUVectorPolicyBase::ExpectDiffTwoQubitsMatrix(const -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } DoubleQubitGateMask mask(objs, ctrls); calc_type res_real = 0, res_imag = 0; @@ -140,6 +152,12 @@ auto CPUVectorPolicyBase::ExpectDiffTwoQubitsMatrix(const }) } // clang-format on + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } return {res_real, res_imag}; }; @@ -151,11 +169,14 @@ auto CPUVectorPolicyBase::ExpectDiffSingleQubitMatrix(cons -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } SingleQubitGateMask mask(objs, ctrls); calc_type res_real = 0, res_imag = 0; @@ -219,22 +240,20 @@ auto CPUVectorPolicyBase::ExpectDiffSingleQubitMatrix(cons // clang-format on } } + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } return {res_real, res_imag}; }; template -auto CPUVectorPolicyBase::ExpectDiffMatrixGate(const qs_data_p_t& bra_out, - const qs_data_p_t& ket_out, const qbits_t& objs, - const qbits_t& ctrls, const VVT& m, - index_t dim) -> qs_data_t { - auto bra = bra_out; - auto ket = ket_out; - if (bra == nullptr) { - bra = derived::InitState(dim); - } - if (ket == nullptr) { - ket = derived::InitState(dim); - } +auto CPUVectorPolicyBase::ExpectDiffMatrixGate(const qs_data_p_t& bra, const qs_data_p_t& ket, + const qbits_t& objs, const qbits_t& ctrls, + const VVT& m, index_t dim) + -> qs_data_t { if (objs.size() == 1) { return derived::ExpectDiffSingleQubitMatrix(bra, ket, objs, ctrls, m, dim); } @@ -245,17 +264,9 @@ auto CPUVectorPolicyBase::ExpectDiffMatrixGate(const qs_da } template -auto CPUVectorPolicyBase::ExpectDiffRX(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, +auto CPUVectorPolicyBase::ExpectDiffRX(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim) -> qs_data_t { - auto bra = bra_out; - auto ket = ket_out; - if (bra == nullptr) { - bra = derived::InitState(dim); - } - if (ket == nullptr) { - ket = derived::InitState(dim); - } auto c = static_cast(-0.5 * std::sin(val / 2)); auto is = static_cast(0.5 * std::cos(val / 2)) * IMAGE_MI; VVT gate = {{c, is}, {is, c}}; @@ -263,17 +274,9 @@ auto CPUVectorPolicyBase::ExpectDiffRX(const qs_data_p_t& }; template -auto CPUVectorPolicyBase::ExpectDiffRY(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, +auto CPUVectorPolicyBase::ExpectDiffRY(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim) -> qs_data_t { - auto bra = bra_out; - auto ket = ket_out; - if (bra == nullptr) { - bra = derived::InitState(dim); - } - if (ket == nullptr) { - ket = derived::InitState(dim); - } calc_type c = -0.5 * std::sin(val / 2); calc_type s = 0.5 * std::cos(val / 2); VVT gate = {{c, -s}, {s, c}}; @@ -281,17 +284,9 @@ auto CPUVectorPolicyBase::ExpectDiffRY(const qs_data_p_t& }; template -auto CPUVectorPolicyBase::ExpectDiffRZ(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, +auto CPUVectorPolicyBase::ExpectDiffRZ(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim) -> qs_data_t { - auto bra = bra_out; - auto ket = ket_out; - if (bra == nullptr) { - bra = derived::InitState(dim); - } - if (ket == nullptr) { - ket = derived::InitState(dim); - } calc_type c = -0.5 * std::sin(val / 2); calc_type s = 0.5 * std::cos(val / 2); auto e0 = c + IMAGE_MI * s; @@ -316,11 +311,14 @@ auto CPUVectorPolicyBase::ExpectDiffPS(const qs_data_p_t& index_t dim) -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } SingleQubitGateMask mask(objs, ctrls); calc_type res_real = 0, res_imag = 0; @@ -353,6 +351,12 @@ auto CPUVectorPolicyBase::ExpectDiffPS(const qs_data_p_t& }) // clang-format on } + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } return {res_real, res_imag}; }; @@ -362,11 +366,14 @@ auto CPUVectorPolicyBase::ExpectDiffRxx(const qs_data_p_t& index_t dim) -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); @@ -417,6 +424,12 @@ auto CPUVectorPolicyBase::ExpectDiffRxx(const qs_data_p_t& } }) } + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } return {res_real, res_imag}; }; @@ -426,11 +439,14 @@ auto CPUVectorPolicyBase::ExpectDiffRxy(const qs_data_p_t& index_t dim) -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); @@ -481,6 +497,12 @@ auto CPUVectorPolicyBase::ExpectDiffRxy(const qs_data_p_t& } }) } + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } return {res_real, res_imag}; }; @@ -490,11 +512,14 @@ auto CPUVectorPolicyBase::ExpectDiffRxz(const qs_data_p_t& index_t dim) -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); @@ -545,6 +570,12 @@ auto CPUVectorPolicyBase::ExpectDiffRxz(const qs_data_p_t& } }) } + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } return {res_real, res_imag}; }; @@ -554,11 +585,14 @@ auto CPUVectorPolicyBase::ExpectDiffRyz(const qs_data_p_t& index_t dim) -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); @@ -609,6 +643,12 @@ auto CPUVectorPolicyBase::ExpectDiffRyz(const qs_data_p_t& } }) } + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } return {res_real, res_imag}; }; @@ -618,11 +658,14 @@ auto CPUVectorPolicyBase::ExpectDiffRyy(const qs_data_p_t& index_t dim) -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); @@ -673,6 +716,12 @@ auto CPUVectorPolicyBase::ExpectDiffRyy(const qs_data_p_t& } }) } + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } return {res_real, res_imag}; }; @@ -682,11 +731,14 @@ auto CPUVectorPolicyBase::ExpectDiffRzz(const qs_data_p_t& index_t dim) -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } DoubleQubitGateMask mask(objs, ctrls); @@ -732,6 +784,12 @@ auto CPUVectorPolicyBase::ExpectDiffRzz(const qs_data_p_t& } }) } + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } return {res_real, res_imag}; }; #ifdef __x86_64__ diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_matrix_gate.cpp b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_matrix_gate.cpp index 9175f31df..b4b57a507 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_matrix_gate.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_matrix_gate.cpp @@ -25,10 +25,22 @@ #include "simulator/vector/detail/cpu_vector_policy.hpp" namespace mindquantum::sim::vector::detail { template -void CPUVectorPolicyBase::ApplyNQubitsMatrix(qs_data_p_t src, qs_data_p_t des, +void CPUVectorPolicyBase::ApplyNQubitsMatrix(const qs_data_p_t& src_out, qs_data_p_t* des_p, const qbits_t& objs, const qbits_t& ctrls, const std::vector>& gate, index_t dim) { + auto& des = *des_p; + if (des == nullptr) { + des = derived::InitState(dim); + } + qs_data_p_t src; + bool will_free = false; + if (src_out == nullptr) { + src = derived::InitState(dim); + will_free = true; + } else { + src = src_out; + } size_t n_qubit = objs.size(); size_t m_dim = (1UL << n_qubit); size_t ctrl_mask = 0; @@ -67,13 +79,28 @@ void CPUVectorPolicyBase::ApplyNQubitsMatrix(qs_data_p_t s } } }) + if (will_free) { + derived::FreeState(&src); + } } template -void CPUVectorPolicyBase::ApplyTwoQubitsMatrix(qs_data_p_t src, qs_data_p_t des, +void CPUVectorPolicyBase::ApplyTwoQubitsMatrix(const qs_data_p_t& src_out, qs_data_p_t* des_p, const qbits_t& objs, const qbits_t& ctrls, const std::vector>& gate, index_t dim) { + auto& des = *des_p; + if (des == nullptr) { + des = derived::InitState(dim); + } + qs_data_p_t src; + bool will_free = false; + if (src_out == nullptr) { + src = derived::InitState(dim); + will_free = true; + } else { + src = src_out; + } DoubleQubitGateMask mask(objs, ctrls); size_t mask1 = (1UL << objs[0]); size_t mask2 = (1UL << objs[1]); @@ -118,12 +145,27 @@ void CPUVectorPolicyBase::ApplyTwoQubitsMatrix(qs_data_p_t } }) } + if (will_free) { + derived::FreeState(&src); + } } template -void CPUVectorPolicyBase::ApplySingleQubitMatrix(qs_data_p_t src, qs_data_p_t des, +void CPUVectorPolicyBase::ApplySingleQubitMatrix(const qs_data_p_t& src_out, qs_data_p_t* des_p, qbit_t obj_qubit, const qbits_t& ctrls, const std::vector>& m, index_t dim) { + auto& des = (*des_p); + if (des == nullptr) { + des = derived::InitState(dim); + } + qs_data_p_t src; + bool will_free = false; + if (src_out == nullptr) { + src = derived::InitState(dim); + will_free = true; + } else { + src = src_out; + } SingleQubitGateMask mask({obj_qubit}, ctrls); if (!mask.ctrl_mask) { THRESHOLD_OMP_FOR( @@ -148,19 +190,22 @@ void CPUVectorPolicyBase::ApplySingleQubitMatrix(qs_data_p } }); } + if (will_free) { + derived::FreeState(&src); + } } template -void CPUVectorPolicyBase::ApplyMatrixGate(qs_data_p_t src, qs_data_p_t des, const qbits_t& objs, - const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyMatrixGate(const qs_data_p_t& src, qs_data_p_t* des_p, + const qbits_t& objs, const qbits_t& ctrls, const std::vector>& m, index_t dim) { if (objs.size() == 1) { - derived::ApplySingleQubitMatrix(src, des, objs[0], ctrls, m, dim); + derived::ApplySingleQubitMatrix(src, des_p, objs[0], ctrls, m, dim); } else if (objs.size() == 2) { - derived::ApplyTwoQubitsMatrix(src, des, objs, ctrls, m, dim); + derived::ApplyTwoQubitsMatrix(src, des_p, objs, ctrls, m, dim); } else { - derived::ApplyNQubitsMatrix(src, des, objs, ctrls, m, dim); + derived::ApplyNQubitsMatrix(src, des_p, objs, ctrls, m, dim); } } 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 937048191..6780531ac 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 @@ -23,18 +23,18 @@ #include "simulator/vector/detail/cpu_vector_policy.hpp" namespace mindquantum::sim::vector::detail { template -void CPUVectorPolicyBase::ApplyH(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyH(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim) { std::vector> m{{M_SQRT1_2, M_SQRT1_2}, {M_SQRT1_2, -M_SQRT1_2}}; - derived::ApplySingleQubitMatrix(qs, qs, objs[0], ctrls, m, dim); + derived::ApplySingleQubitMatrix((*qs_p), qs_p, objs[0], ctrls, m, dim); } template -void CPUVectorPolicyBase::ApplyGP(qs_data_p_t qs, qbit_t obj_qubit, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyGP(qs_data_p_t* qs_p, qbit_t obj_qubit, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { auto c = std::exp(std::complex(0, -val)); std::vector> m = {{c, 0}, {0, c}}; - derived::ApplySingleQubitMatrix(qs, qs, obj_qubit, ctrls, m, dim); + derived::ApplySingleQubitMatrix(*qs_p, qs_p, obj_qubit, ctrls, m, dim); } #ifdef __x86_64__ 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 5186df297..1a4acfa6e 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 @@ -91,7 +91,7 @@ void CPUVectorPolicyBase::SetToZeroExcept(qs_data_p_t* qs_ } template -auto CPUVectorPolicyBase::Copy(qs_data_p_t qs, index_t dim) -> qs_data_p_t { +auto CPUVectorPolicyBase::Copy(const qs_data_p_t& qs, index_t dim) -> qs_data_p_t { qs_data_p_t out = nullptr; if (qs != nullptr) { out = derived::InitState(dim, false); @@ -164,11 +164,14 @@ auto CPUVectorPolicyBase::ExpectationOfTerms(const qs_data index_t dim) -> py_qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } py_qs_data_t out = 0.0; for (const auto& [pauli_string, coeff_] : ham) { @@ -197,6 +200,12 @@ auto CPUVectorPolicyBase::ExpectationOfTerms(const qs_data // clang-format on out += py_qs_data_t(res_real, res_imag); } + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } return out; } diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_rot_pauli.cpp b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_rot_pauli.cpp index a65655579..8872af0b6 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_rot_pauli.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_rot_pauli.cpp @@ -26,8 +26,12 @@ namespace mindquantum::sim::vector::detail { constexpr int ROT_PAULI_FACTOR = 2; template -void CPUVectorPolicyBase::ApplyRxx(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyRxx(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(std::cos(val / ROT_PAULI_FACTOR)); auto s = static_cast(std::sin(val / ROT_PAULI_FACTOR)) * IMAGE_MI; @@ -74,14 +78,18 @@ void CPUVectorPolicyBase::ApplyRxx(qs_data_p_t qs, const q } }) if (diff) { - derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(qs_p, mask.ctrl_mask, dim); } } } template -void CPUVectorPolicyBase::ApplyRxy(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyRxy(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(std::cos(val / ROT_PAULI_FACTOR)); auto s = static_cast(std::sin(val / ROT_PAULI_FACTOR)); @@ -128,14 +136,18 @@ void CPUVectorPolicyBase::ApplyRxy(qs_data_p_t qs, const q } }) if (diff) { - derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(qs_p, mask.ctrl_mask, dim); } } } template -void CPUVectorPolicyBase::ApplyRxz(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyRxz(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(std::cos(val / ROT_PAULI_FACTOR)); auto s = static_cast(std::sin(val / ROT_PAULI_FACTOR)) * IMAGE_MI; @@ -182,14 +194,18 @@ void CPUVectorPolicyBase::ApplyRxz(qs_data_p_t qs, const q } }) if (diff) { - derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(qs_p, mask.ctrl_mask, dim); } } } template -void CPUVectorPolicyBase::ApplyRyz(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyRyz(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(std::cos(val / ROT_PAULI_FACTOR)); auto s = static_cast(std::sin(val / ROT_PAULI_FACTOR)); @@ -236,14 +252,18 @@ void CPUVectorPolicyBase::ApplyRyz(qs_data_p_t qs, const q } }) if (diff) { - derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(qs_p, mask.ctrl_mask, dim); } } } template -void CPUVectorPolicyBase::ApplyRyy(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyRyy(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(std::cos(val / ROT_PAULI_FACTOR)); auto s = static_cast(std::sin(val / ROT_PAULI_FACTOR)) * IMAGE_I; @@ -290,14 +310,18 @@ void CPUVectorPolicyBase::ApplyRyy(qs_data_p_t qs, const q } }) if (diff) { - derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(qs_p, mask.ctrl_mask, dim); } } } template -void CPUVectorPolicyBase::ApplyRzz(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyRzz(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(std::cos(val / ROT_PAULI_FACTOR)); auto s = static_cast(std::sin(val / ROT_PAULI_FACTOR)); @@ -338,13 +362,13 @@ void CPUVectorPolicyBase::ApplyRzz(qs_data_p_t qs, const q } }) if (diff) { - derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(qs_p, mask.ctrl_mask, dim); } } } template -void CPUVectorPolicyBase::ApplyRX(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyRX(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { SingleQubitGateMask mask(objs, ctrls); auto a = std::cos(val / ROT_PAULI_FACTOR); @@ -354,14 +378,14 @@ void CPUVectorPolicyBase::ApplyRX(qs_data_p_t qs, const qb b = -std::cos(val / ROT_PAULI_FACTOR) / ROT_PAULI_FACTOR; } std::vector> m{{{a, 0}, {0, b}}, {{0, b}, {a, 0}}}; - derived::ApplySingleQubitMatrix(qs, qs, objs[0], ctrls, m, dim); + derived::ApplySingleQubitMatrix(*qs_p, qs_p, objs[0], ctrls, m, dim); if (diff && mask.ctrl_mask) { - derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(qs_p, mask.ctrl_mask, dim); } } template -void CPUVectorPolicyBase::ApplyRY(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyRY(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { SingleQubitGateMask mask(objs, ctrls); auto a = std::cos(val / ROT_PAULI_FACTOR); @@ -371,14 +395,14 @@ void CPUVectorPolicyBase::ApplyRY(qs_data_p_t qs, const qb b = std::cos(val / ROT_PAULI_FACTOR) / ROT_PAULI_FACTOR; } std::vector> m{{{a, 0}, {-b, 0}}, {{b, 0}, {a, 0}}}; - derived::ApplySingleQubitMatrix(qs, qs, objs[0], ctrls, m, dim); + derived::ApplySingleQubitMatrix(*qs_p, qs_p, objs[0], ctrls, m, dim); if (diff && mask.ctrl_mask) { - derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(qs_p, mask.ctrl_mask, dim); } } template -void CPUVectorPolicyBase::ApplyRZ(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyRZ(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { SingleQubitGateMask mask(objs, ctrls); auto a = std::cos(val / ROT_PAULI_FACTOR); @@ -388,9 +412,9 @@ void CPUVectorPolicyBase::ApplyRZ(qs_data_p_t qs, const qb b = std::cos(val / ROT_PAULI_FACTOR) / ROT_PAULI_FACTOR; } std::vector> m{{{a, -b}, {0, 0}}, {{0, 0}, {a, b}}}; - derived::ApplySingleQubitMatrix(qs, qs, objs[0], ctrls, m, dim); + derived::ApplySingleQubitMatrix(*qs_p, qs_p, objs[0], ctrls, m, dim); if (diff && mask.ctrl_mask) { - derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(qs_p, mask.ctrl_mask, dim); } } diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_swap_like.cpp b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_swap_like.cpp index 33c0b7d2f..950b3ac74 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_swap_like.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_swap_like.cpp @@ -25,8 +25,12 @@ #include "simulator/vector/detail/cpu_vector_policy.hpp" namespace mindquantum::sim::vector::detail { template -void CPUVectorPolicyBase::ApplySWAP(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplySWAP(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); if (!mask.ctrl_mask) { THRESHOLD_OMP_FOR( @@ -58,8 +62,12 @@ void CPUVectorPolicyBase::ApplySWAP(qs_data_p_t qs, const } template -void CPUVectorPolicyBase::ApplyISWAP(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyISWAP(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, bool daggered, index_t dim) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); calc_type frac = 1.0; if (daggered) { diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_x_like.cpp b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_x_like.cpp index ff7044527..b3f0445a2 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_x_like.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_x_like.cpp @@ -25,8 +25,12 @@ #include "simulator/vector/detail/cpu_vector_policy.hpp" namespace mindquantum::sim::vector::detail { template -void CPUVectorPolicyBase::ApplyXLike(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyXLike(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, qs_data_t v1, qs_data_t v2, index_t dim) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } SingleQubitGateMask mask(objs, ctrls); if (!mask.ctrl_mask) { THRESHOLD_OMP_FOR( @@ -52,15 +56,15 @@ void CPUVectorPolicyBase::ApplyXLike(qs_data_p_t qs, const } template -void CPUVectorPolicyBase::ApplyX(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyX(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim) { - derived::ApplyXLike(qs, objs, ctrls, 1, 1, dim); + derived::ApplyXLike(qs_p, objs, ctrls, 1, 1, dim); } template -void CPUVectorPolicyBase::ApplyY(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyY(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim) { - derived::ApplyXLike(qs, objs, ctrls, IMAGE_MI, IMAGE_I, dim); + derived::ApplyXLike(qs_p, objs, ctrls, IMAGE_MI, IMAGE_I, dim); } #ifdef __x86_64__ template struct CPUVectorPolicyBase; diff --git a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_z_like.cpp b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_z_like.cpp index 7511bc36d..47dfffc72 100644 --- a/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_z_like.cpp +++ b/ccsrc/lib/simulator/vector/detail/cpu_common/cpu_vector_core_z_like.cpp @@ -25,8 +25,12 @@ #include "simulator/vector/detail/cpu_vector_policy.hpp" namespace mindquantum::sim::vector::detail { template -void CPUVectorPolicyBase::ApplyZLike(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyZLike(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, qs_data_t val, index_t dim) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } SingleQubitGateMask mask(objs, ctrls); if (!mask.ctrl_mask) { THRESHOLD_OMP_FOR( @@ -46,41 +50,45 @@ void CPUVectorPolicyBase::ApplyZLike(qs_data_p_t qs, const } template -void CPUVectorPolicyBase::ApplyZ(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyZ(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim) { - derived::ApplyZLike(qs, objs, ctrls, -1, dim); + derived::ApplyZLike(qs_p, objs, ctrls, -1, dim); } template -void CPUVectorPolicyBase::ApplySGate(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplySGate(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim) { - derived::ApplyZLike(qs, objs, ctrls, qs_data_t(0, 1), dim); + derived::ApplyZLike(qs_p, objs, ctrls, qs_data_t(0, 1), dim); } template -void CPUVectorPolicyBase::ApplySdag(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplySdag(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim) { - derived::ApplyZLike(qs, objs, ctrls, qs_data_t(0, -1), dim); + derived::ApplyZLike(qs_p, objs, ctrls, qs_data_t(0, -1), dim); } template -void CPUVectorPolicyBase::ApplyT(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyT(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim) { - derived::ApplyZLike(qs, objs, ctrls, qs_data_t(1, 1) / static_cast(std::sqrt(2.0)), dim); + derived::ApplyZLike(qs_p, objs, ctrls, qs_data_t(1, 1) / static_cast(std::sqrt(2.0)), dim); } template -void CPUVectorPolicyBase::ApplyTdag(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyTdag(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim) { - derived::ApplyZLike(qs, objs, ctrls, qs_data_t(1, -1) / static_cast(std::sqrt(2.0)), dim); + derived::ApplyZLike(qs_p, objs, ctrls, qs_data_t(1, -1) / static_cast(std::sqrt(2.0)), dim); } template -void CPUVectorPolicyBase::ApplyPS(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void CPUVectorPolicyBase::ApplyPS(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { if (!diff) { - derived::ApplyZLike(qs, objs, ctrls, qs_data_t(std::cos(val), std::sin(val)), dim); + derived::ApplyZLike(qs_p, objs, ctrls, qs_data_t(std::cos(val), std::sin(val)), dim); } else { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } SingleQubitGateMask mask(objs, ctrls); auto e = -std::sin(val) + IMAGE_I * std::cos(val); if (!mask.ctrl_mask) { @@ -101,7 +109,7 @@ void CPUVectorPolicyBase::ApplyPS(qs_data_p_t qs, const qb qs[j] *= e; } }) - derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(qs_p, mask.ctrl_mask, dim); } } } diff --git a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_condition.cu b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_condition.cu index 073b0647f..3371abbef 100644 --- a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_condition.cu +++ b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_condition.cu @@ -35,13 +35,23 @@ void GPUVectorPolicyBase::ConditionalBinary(const qs_data_ des = derived::InitState(dim); } thrust::counting_iterator i(0); - thrust::for_each(i, i + dim, [=] __device__(size_t i) { - if ((i & mask) == condi) { - des[i] = op(src[i], succ_coeff); - } else { - des[i] = op(src[i], fail_coeff); - } - }); + if (src == nullptr) { + thrust::for_each(i, i + 1, [=] __device__(size_t i) { + if ((i & mask) == condi) { + des[i] = op(1.0, succ_coeff); + } else { + des[i] = op(1.0, fail_coeff); + } + }); + } else { + thrust::for_each(i, i + dim, [=] __device__(size_t i) { + if ((i & mask) == condi) { + des[i] = op(src[i], succ_coeff); + } else { + des[i] = op(src[i], fail_coeff); + } + }); + } } template @@ -55,13 +65,23 @@ void GPUVectorPolicyBase::ConditionalBinary(const qs_data_ des = derived::InitState(dim); } thrust::counting_iterator i(0); - thrust::for_each(i, i + dim, [=] __device__(size_t i) { - if ((i & mask) == condi) { - des[i] = op(src[i], succ_coeff); - } else { - des[i] = op(src[i], fail_coeff); - } - }); + if (src == nullptr) { + thrust::for_each(i, i + 1, [=] __device__(size_t i) { + if ((i & mask) == condi) { + des[i] = op(1.0, succ_coeff); + } else { + des[i] = op(1.0, fail_coeff); + } + }); + } else { + thrust::for_each(i, i + dim, [=] __device__(size_t i) { + if ((i & mask) == condi) { + des[i] = op(src[i], succ_coeff); + } else { + des[i] = op(src[i], fail_coeff); + } + }); + } } template diff --git a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_dot_like.cu b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_dot_like.cu index e445451e2..c30817f7c 100644 --- a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_dot_like.cu +++ b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_dot_like.cu @@ -26,7 +26,8 @@ namespace mindquantum::sim::vector::detail { template -auto GPUVectorPolicyBase::Vdot(qs_data_p_t bra, qs_data_p_t ket, index_t dim) -> py_qs_data_t { +auto GPUVectorPolicyBase::Vdot(const qs_data_p_t& bra, const qs_data_p_t& ket, index_t dim) + -> py_qs_data_t { if (bra == nullptr && ket == nullptr) { return 1.0; } else if (bra == nullptr) { @@ -47,15 +48,27 @@ auto GPUVectorPolicyBase::Vdot(qs_data_p_t bra, qs_data_p_ template template -auto GPUVectorPolicyBase::ConditionVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, index_t dim) - -> py_qs_data_t { - auto& bra = (*bra_p); - auto& ket = (*ket_p); - if (bra == nullptr) { - bra = derived::InitState(dim); - } - if (ket == nullptr) { - ket = derived::InitState(dim); +auto GPUVectorPolicyBase::ConditionVdot(const qs_data_p_t& bra, const qs_data_p_t& ket, + index_t dim) -> py_qs_data_t { + if (bra == nullptr && ket == nullptr) { + if ((0 & mask) == condi) { + return 1.0; + } + return 0.0; + } else if (bra == nullptr) { + if ((0 & mask) == condi) { + py_qs_data_t out; + cudaMemcpy(&out, ket, sizeof(qs_data_t), cudaMemcpyDeviceToHost); + return out; + } + return 0.0; + } else if (ket == nullptr) { + if ((0 & mask) == condi) { + py_qs_data_t out; + cudaMemcpy(&out, bra, sizeof(qs_data_t), cudaMemcpyDeviceToHost); + return std::conj(out); + } + return 0.0; } thrust::counting_iterator i(0); return thrust::transform_reduce( @@ -71,15 +84,10 @@ auto GPUVectorPolicyBase::ConditionVdot(qs_data_p_t* bra_p } template -auto GPUVectorPolicyBase::OneStateVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, qbit_t obj_qubit, - index_t dim) -> py_qs_data_t { - auto& bra = (*bra_p); - auto& ket = (*ket_p); - if (bra == nullptr) { - bra = derived::InitState(dim); - } - if (ket == nullptr) { - ket = derived::InitState(dim); +auto GPUVectorPolicyBase::OneStateVdot(const qs_data_p_t& bra, const qs_data_p_t& ket, + qbit_t obj_qubit, index_t dim) -> py_qs_data_t { + if (bra == nullptr || ket == nullptr) { + return 0.0; } SingleQubitGateMask mask({obj_qubit}, {}); auto obj_high_mask = mask.obj_high_mask; @@ -96,15 +104,18 @@ auto GPUVectorPolicyBase::OneStateVdot(qs_data_p_t* bra_p, } template -auto GPUVectorPolicyBase::ZeroStateVdot(qs_data_p_t* bra_p, qs_data_p_t* ket_p, qbit_t obj_qubit, - index_t dim) -> py_qs_data_t { - auto& bra = (*bra_p); - auto& ket = (*ket_p); - if (bra == nullptr) { - bra = derived::InitState(dim); - } - if (ket == nullptr) { - ket = derived::InitState(dim); +auto GPUVectorPolicyBase::ZeroStateVdot(const qs_data_p_t& bra, const qs_data_p_t& ket, + qbit_t obj_qubit, index_t dim) -> py_qs_data_t { + if (bra == nullptr && ket == nullptr) { + return 1.0; + } else if (bra == nullptr) { + py_qs_data_t out; + cudaMemcpy(&out, ket, sizeof(qs_data_t), cudaMemcpyDeviceToHost); + return out; + } else if (ket == nullptr) { + py_qs_data_t out; + cudaMemcpy(&out, bra, sizeof(qs_data_t), cudaMemcpyDeviceToHost); + return std::conj(out); } SingleQubitGateMask mask({obj_qubit}, {}); auto obj_high_mask = mask.obj_high_mask; @@ -121,10 +132,16 @@ auto GPUVectorPolicyBase::ZeroStateVdot(qs_data_p_t* bra_p template auto GPUVectorPolicyBase::CsrDotVec(const std::shared_ptr>& a, - qs_data_p_t vec, index_t dim) -> qs_data_p_t { + const qs_data_p_t& vec_out, index_t dim) -> qs_data_p_t { if (dim != a->dim_) { throw std::runtime_error("Sparse hamiltonian size not match with quantum state size."); } + auto vec = vec_out; + bool will_free = false; + if (vec == nullptr) { + vec = derived::InitState(dim); + will_free = true; + } auto host = reinterpret_cast*>(malloc(dim * sizeof(std::complex))); cudaMemcpy(host, vec, sizeof(qs_data_t) * dim, cudaMemcpyDeviceToHost); auto host_res = sparse::Csr_Dot_Vec(a, reinterpret_cast(host)); @@ -137,15 +154,25 @@ auto GPUVectorPolicyBase::CsrDotVec(const std::shared_ptr< if (host_res != nullptr) { free(host_res); } + if (will_free) { + derived::FreeState(&vec); + } return out; } + template auto GPUVectorPolicyBase::CsrDotVec(const std::shared_ptr>& a, const std::shared_ptr>& b, - qs_data_p_t vec, index_t dim) -> qs_data_p_t { + const qs_data_p_t& vec_out, index_t dim) -> qs_data_p_t { if ((dim != a->dim_) || (dim != b->dim_)) { throw std::runtime_error("Sparse hamiltonian size not match with quantum state size."); } + auto vec = vec_out; + bool will_free = false; + if (vec == nullptr) { + vec = derived::InitState(dim); + will_free = true; + } auto host = reinterpret_cast*>(malloc(dim * sizeof(std::complex))); cudaMemcpy(host, vec, sizeof(qs_data_t) * dim, cudaMemcpyDeviceToHost); auto host_res = sparse::Csr_Dot_Vec(a, b, reinterpret_cast(host)); @@ -158,15 +185,29 @@ auto GPUVectorPolicyBase::CsrDotVec(const std::shared_ptr< if (host_res != nullptr) { free(host_res); } + if (will_free) { + derived::FreeState(&vec); + } return out; } template auto GPUVectorPolicyBase::ExpectationOfCsr( - const std::shared_ptr>& a, qs_data_p_t bra, qs_data_p_t ket, index_t dim) - -> py_qs_data_t { + const std::shared_ptr>& a, const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, + index_t dim) -> py_qs_data_t { if (dim != a->dim_) { throw std::runtime_error("Sparse hamiltonian size not match with quantum state size."); } + auto bra = bra_out; + auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; + if (bra == nullptr) { + bra = derived::InitState(dim); + will_free_bra = true; + } + if (ket == nullptr) { + ket = derived::InitState(dim); + will_free_ket = true; + } auto host_bra = reinterpret_cast*>(malloc(dim * sizeof(std::complex))); cudaMemcpy(host_bra, bra, sizeof(qs_data_t) * dim, cudaMemcpyDeviceToHost); auto host_ket = reinterpret_cast*>(malloc(dim * sizeof(std::complex))); @@ -179,16 +220,33 @@ auto GPUVectorPolicyBase::ExpectationOfCsr( if (host_ket != nullptr) { free(host_ket); } + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } return out; } template auto GPUVectorPolicyBase::ExpectationOfCsr( const std::shared_ptr>& a, const std::shared_ptr>& b, - qs_data_p_t bra, qs_data_p_t ket, index_t dim) -> py_qs_data_t { + const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, index_t dim) -> py_qs_data_t { if ((dim != a->dim_) || (dim != b->dim_)) { throw std::runtime_error("Sparse hamiltonian size not match with quantum state size."); } + auto bra = bra_out; + auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; + if (bra == nullptr) { + bra = derived::InitState(dim); + will_free_bra = true; + } + if (ket == nullptr) { + ket = derived::InitState(dim); + will_free_ket = true; + } auto host_bra = reinterpret_cast*>(malloc(dim * sizeof(std::complex))); cudaMemcpy(host_bra, bra, sizeof(qs_data_t) * dim, cudaMemcpyDeviceToHost); auto host_ket = reinterpret_cast*>(malloc(dim * sizeof(std::complex))); @@ -201,6 +259,12 @@ auto GPUVectorPolicyBase::ExpectationOfCsr( if (host_ket != nullptr) { free(host_ket); } + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } return out; } template struct GPUVectorPolicyBase; diff --git a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_gate_expect.cu b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_gate_expect.cu index 9b608a3ba..5d0ae578e 100644 --- a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_gate_expect.cu +++ b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_gate_expect.cu @@ -33,11 +33,14 @@ auto GPUVectorPolicyBase::ExpectDiffNQubitsMatrix(const qs index_t dim) -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } size_t n_qubit = objs.size(); size_t m_dim = (1UL << n_qubit); @@ -69,7 +72,7 @@ auto GPUVectorPolicyBase::ExpectDiffNQubitsMatrix(const qs auto device_gate_ptr = thrust::raw_pointer_cast(device_gate.data()); thrust::counting_iterator l(0); - return thrust::transform_reduce( + auto res = thrust::transform_reduce( l, l + dim, [=] __device__(size_t l) { qs_data_t res = 0; @@ -85,6 +88,13 @@ auto GPUVectorPolicyBase::ExpectDiffNQubitsMatrix(const qs return res; }, qs_data_t(0, 0), thrust::plus()); + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } + return res; } template auto GPUVectorPolicyBase::ExpectDiffTwoQubitsMatrix(const qs_data_p_t& bra_out, @@ -94,11 +104,14 @@ auto GPUVectorPolicyBase::ExpectDiffTwoQubitsMatrix(const index_t dim) -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } DoubleQubitGateMask mask(objs, ctrls); qs_data_t m00 = m[0][0]; @@ -126,8 +139,9 @@ auto GPUVectorPolicyBase::ExpectDiffTwoQubitsMatrix(const auto obj_min_mask = mask.obj_min_mask; auto obj_max_mask = mask.obj_max_mask; auto ctrl_mask = mask.ctrl_mask; + qs_data_t res = 0.0; if (!mask.ctrl_mask) { - return thrust::transform_reduce( + res = thrust::transform_reduce( l, l + dim / 4, [=] __device__(size_t l) { index_t i; @@ -146,29 +160,37 @@ auto GPUVectorPolicyBase::ExpectDiffTwoQubitsMatrix(const return this_res; }, qs_data_t(0, 0), thrust::plus()); + } else { + res = thrust::transform_reduce( + l, l + dim / 4, + [=] __device__(size_t l) { + index_t i; + SHIFT_BIT_TWO(obj_low_mask, obj_rev_low_mask, obj_high_mask, obj_rev_high_mask, l, i); + if ((i & ctrl_mask) != ctrl_mask) { + return qs_data_t(0, 0); + } + auto m = i + obj_mask; + auto j = i + obj_min_mask; + auto k = i + obj_max_mask; + auto v00 = m00 * ket[i] + m01 * ket[j] + m02 * ket[k] + m03 * ket[m]; + auto v01 = m10 * ket[i] + m11 * ket[j] + m12 * ket[k] + m13 * ket[m]; + auto v10 = m20 * ket[i] + m21 * ket[j] + m22 * ket[k] + m23 * ket[m]; + auto v11 = m30 * ket[i] + m31 * ket[j] + m32 * ket[k] + m33 * ket[m]; + auto this_res = thrust::conj(bra[i]) * v00; + this_res += thrust::conj(bra[j]) * v01; + this_res += thrust::conj(bra[k]) * v10; + this_res += thrust::conj(bra[m]) * v11; + return this_res; + }, + qs_data_t(0, 0), thrust::plus()); } - return thrust::transform_reduce( - l, l + dim / 4, - [=] __device__(size_t l) { - index_t i; - SHIFT_BIT_TWO(obj_low_mask, obj_rev_low_mask, obj_high_mask, obj_rev_high_mask, l, i); - if ((i & ctrl_mask) != ctrl_mask) { - return qs_data_t(0, 0); - } - auto m = i + obj_mask; - auto j = i + obj_min_mask; - auto k = i + obj_max_mask; - auto v00 = m00 * ket[i] + m01 * ket[j] + m02 * ket[k] + m03 * ket[m]; - auto v01 = m10 * ket[i] + m11 * ket[j] + m12 * ket[k] + m13 * ket[m]; - auto v10 = m20 * ket[i] + m21 * ket[j] + m22 * ket[k] + m23 * ket[m]; - auto v11 = m30 * ket[i] + m31 * ket[j] + m32 * ket[k] + m33 * ket[m]; - auto this_res = thrust::conj(bra[i]) * v00; - this_res += thrust::conj(bra[j]) * v01; - this_res += thrust::conj(bra[k]) * v10; - this_res += thrust::conj(bra[m]) * v11; - return this_res; - }, - qs_data_t(0, 0), thrust::plus()); + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } + return res; } template @@ -179,11 +201,14 @@ auto GPUVectorPolicyBase::ExpectDiffSingleQubitMatrix(cons index_t dim) -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } SingleQubitGateMask mask(objs, ctrls); qs_data_t m00 = m[0][0]; @@ -195,8 +220,9 @@ auto GPUVectorPolicyBase::ExpectDiffSingleQubitMatrix(cons auto obj_low_mask = mask.obj_low_mask; auto obj_mask = mask.obj_mask; auto ctrl_mask = mask.ctrl_mask; + qs_data_t res = 0.0; if (!mask.ctrl_mask) { - return thrust::transform_reduce( + res = thrust::transform_reduce( l, l + dim / 2, [=] __device__(size_t l) { auto i = ((l & obj_high_mask) << 1) + (l & obj_low_mask); @@ -220,7 +246,7 @@ auto GPUVectorPolicyBase::ExpectDiffSingleQubitMatrix(cons } auto first_high_mask = ~first_low_mask; auto second_high_mask = ~second_low_mask; - return thrust::transform_reduce( + res = thrust::transform_reduce( l, l + dim / 4, [=] __device__(size_t l) { auto i = ((l & first_high_mask) << 1) + (l & first_low_mask); @@ -232,37 +258,36 @@ auto GPUVectorPolicyBase::ExpectDiffSingleQubitMatrix(cons return this_res; }, qs_data_t(0, 0), thrust::plus()); + } else { + res = thrust::transform_reduce( + l, l + dim / 2, + [=] __device__(size_t l) { + auto i = ((l & obj_high_mask) << 1) + (l & obj_low_mask); + if ((i & ctrl_mask) != ctrl_mask) { + return qs_data_t(0, 0); + } + auto j = i + obj_mask; + auto t1 = m00 * ket[i] + m01 * ket[j]; + auto t2 = m10 * ket[i] + m11 * ket[j]; + auto this_res = thrust::conj(bra[i]) * t1 + thrust::conj(bra[j]) * t2; + return this_res; + }, + qs_data_t(0, 0), thrust::plus()); } - return thrust::transform_reduce( - l, l + dim / 2, - [=] __device__(size_t l) { - auto i = ((l & obj_high_mask) << 1) + (l & obj_low_mask); - if ((i & ctrl_mask) != ctrl_mask) { - return qs_data_t(0, 0); - } - auto j = i + obj_mask; - auto t1 = m00 * ket[i] + m01 * ket[j]; - auto t2 = m10 * ket[i] + m11 * ket[j]; - auto this_res = thrust::conj(bra[i]) * t1 + thrust::conj(bra[j]) * t2; - return this_res; - }, - qs_data_t(0, 0), thrust::plus()); + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } + return res; } template -auto GPUVectorPolicyBase::ExpectDiffMatrixGate(const qs_data_p_t& bra_out, - const qs_data_p_t& ket_out, const qbits_t& objs, - const qbits_t& ctrls, +auto GPUVectorPolicyBase::ExpectDiffMatrixGate(const qs_data_p_t& bra, const qs_data_p_t& ket, + const qbits_t& objs, const qbits_t& ctrls, const std::vector& m, index_t dim) -> qs_data_t { - auto bra = bra_out; - auto ket = ket_out; - if (bra == nullptr) { - bra = derived::InitState(dim); - } - if (ket == nullptr) { - ket = derived::InitState(dim); - } if (objs.size() == 1) { return derived::ExpectDiffSingleQubitMatrix(bra, ket, objs, ctrls, m, dim); } @@ -273,17 +298,9 @@ auto GPUVectorPolicyBase::ExpectDiffMatrixGate(const qs_da } template -auto GPUVectorPolicyBase::ExpectDiffRX(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, +auto GPUVectorPolicyBase::ExpectDiffRX(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim) -> qs_data_t { - auto bra = bra_out; - auto ket = ket_out; - if (bra == nullptr) { - bra = derived::InitState(dim); - } - if (ket == nullptr) { - ket = derived::InitState(dim); - } auto c = static_cast(-0.5 * std::sin(val / 2)); auto is = static_cast(0.5 * std::cos(val / 2)) * qs_data_t(0, -1); std::vector gate = {{c, is}, {is, c}}; @@ -291,17 +308,9 @@ auto GPUVectorPolicyBase::ExpectDiffRX(const qs_data_p_t& } template -auto GPUVectorPolicyBase::ExpectDiffRY(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, +auto GPUVectorPolicyBase::ExpectDiffRY(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim) -> qs_data_t { - auto bra = bra_out; - auto ket = ket_out; - if (bra == nullptr) { - bra = derived::InitState(dim); - } - if (ket == nullptr) { - ket = derived::InitState(dim); - } SingleQubitGateMask mask(objs, ctrls); auto c = static_cast(-0.5 * std::sin(val / 2)); auto s = static_cast(0.5 * std::cos(val / 2)); @@ -310,17 +319,9 @@ auto GPUVectorPolicyBase::ExpectDiffRY(const qs_data_p_t& } template -auto GPUVectorPolicyBase::ExpectDiffRZ(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, +auto GPUVectorPolicyBase::ExpectDiffRZ(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim) -> qs_data_t { - auto bra = bra_out; - auto ket = ket_out; - if (bra == nullptr) { - bra = derived::InitState(dim); - } - if (ket == nullptr) { - ket = derived::InitState(dim); - } SingleQubitGateMask mask(objs, ctrls); auto c = static_cast(-0.5 * std::sin(val / 2)); auto s = static_cast(0.5 * std::cos(val / 2)); @@ -336,11 +337,14 @@ auto GPUVectorPolicyBase::ExpectDiffRxx(const qs_data_p_t& index_t dim) -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); @@ -354,8 +358,9 @@ auto GPUVectorPolicyBase::ExpectDiffRxx(const qs_data_p_t& auto obj_min_mask = mask.obj_min_mask; auto obj_max_mask = mask.obj_max_mask; auto ctrl_mask = mask.ctrl_mask; + qs_data_t res = 0.0; if (!mask.ctrl_mask) { - return thrust::transform_reduce( + res = thrust::transform_reduce( l, l + dim / 4, [=] __device__(size_t l) { index_t i; @@ -374,29 +379,37 @@ auto GPUVectorPolicyBase::ExpectDiffRxx(const qs_data_p_t& return this_res; }, qs_data_t(0, 0), thrust::plus()); + } else { + res = thrust::transform_reduce( + l, l + dim / 4, + [=] __device__(size_t l) { + index_t i; + SHIFT_BIT_TWO(obj_low_mask, obj_rev_low_mask, obj_high_mask, obj_rev_high_mask, l, i); + if ((i & ctrl_mask) != ctrl_mask) { + return qs_data_t(0, 0); + } + auto m = i + obj_mask; + auto j = i + obj_min_mask; + auto k = i + obj_max_mask; + auto v00 = c * ket[i] + s * ket[m]; + auto v01 = c * ket[j] + s * ket[k]; + auto v10 = c * ket[k] + s * ket[j]; + auto v11 = c * ket[m] + s * ket[i]; + auto this_res = thrust::conj(bra[i]) * v00; + this_res += thrust::conj(bra[j]) * v01; + this_res += thrust::conj(bra[k]) * v10; + this_res += thrust::conj(bra[m]) * v11; + return this_res; + }, + qs_data_t(0, 0), thrust::plus()); } - return thrust::transform_reduce( - l, l + dim / 4, - [=] __device__(size_t l) { - index_t i; - SHIFT_BIT_TWO(obj_low_mask, obj_rev_low_mask, obj_high_mask, obj_rev_high_mask, l, i); - if ((i & ctrl_mask) != ctrl_mask) { - return qs_data_t(0, 0); - } - auto m = i + obj_mask; - auto j = i + obj_min_mask; - auto k = i + obj_max_mask; - auto v00 = c * ket[i] + s * ket[m]; - auto v01 = c * ket[j] + s * ket[k]; - auto v10 = c * ket[k] + s * ket[j]; - auto v11 = c * ket[m] + s * ket[i]; - auto this_res = thrust::conj(bra[i]) * v00; - this_res += thrust::conj(bra[j]) * v01; - this_res += thrust::conj(bra[k]) * v10; - this_res += thrust::conj(bra[m]) * v11; - return this_res; - }, - qs_data_t(0, 0), thrust::plus()); + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } + return res; } template @@ -405,11 +418,14 @@ auto GPUVectorPolicyBase::ExpectDiffRxy(const qs_data_p_t& index_t dim) -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); @@ -423,12 +439,36 @@ auto GPUVectorPolicyBase::ExpectDiffRxy(const qs_data_p_t& auto obj_min_mask = mask.obj_min_mask; auto obj_max_mask = mask.obj_max_mask; auto ctrl_mask = mask.ctrl_mask; + qs_data_t res = 0.0; if (!mask.ctrl_mask) { - return thrust::transform_reduce( + res = thrust::transform_reduce( + l, l + dim / 4, + [=] __device__(size_t l) { + index_t i; + SHIFT_BIT_TWO(obj_low_mask, obj_rev_low_mask, obj_high_mask, obj_rev_high_mask, l, i); + auto m = i + obj_mask; + auto j = i + obj_min_mask; + auto k = i + obj_max_mask; + auto v00 = c * ket[i] - s * ket[m]; + auto v01 = c * ket[j] - s * ket[k]; + auto v10 = c * ket[k] + s * ket[j]; + auto v11 = c * ket[m] + s * ket[i]; + auto this_res = thrust::conj(bra[i]) * v00; + this_res += thrust::conj(bra[j]) * v01; + this_res += thrust::conj(bra[k]) * v10; + this_res += thrust::conj(bra[m]) * v11; + return this_res; + }, + qs_data_t(0, 0), thrust::plus()); + } else { + res = thrust::transform_reduce( l, l + dim / 4, [=] __device__(size_t l) { index_t i; SHIFT_BIT_TWO(obj_low_mask, obj_rev_low_mask, obj_high_mask, obj_rev_high_mask, l, i); + if ((i & ctrl_mask) != ctrl_mask) { + return qs_data_t(0, 0); + } auto m = i + obj_mask; auto j = i + obj_min_mask; auto k = i + obj_max_mask; @@ -444,28 +484,13 @@ auto GPUVectorPolicyBase::ExpectDiffRxy(const qs_data_p_t& }, qs_data_t(0, 0), thrust::plus()); } - return thrust::transform_reduce( - l, l + dim / 4, - [=] __device__(size_t l) { - index_t i; - SHIFT_BIT_TWO(obj_low_mask, obj_rev_low_mask, obj_high_mask, obj_rev_high_mask, l, i); - if ((i & ctrl_mask) != ctrl_mask) { - return qs_data_t(0, 0); - } - auto m = i + obj_mask; - auto j = i + obj_min_mask; - auto k = i + obj_max_mask; - auto v00 = c * ket[i] - s * ket[m]; - auto v01 = c * ket[j] - s * ket[k]; - auto v10 = c * ket[k] + s * ket[j]; - auto v11 = c * ket[m] + s * ket[i]; - auto this_res = thrust::conj(bra[i]) * v00; - this_res += thrust::conj(bra[j]) * v01; - this_res += thrust::conj(bra[k]) * v10; - this_res += thrust::conj(bra[m]) * v11; - return this_res; - }, - qs_data_t(0, 0), thrust::plus()); + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } + return res; } template @@ -474,11 +499,14 @@ auto GPUVectorPolicyBase::ExpectDiffRxz(const qs_data_p_t& index_t dim) -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); @@ -492,8 +520,9 @@ auto GPUVectorPolicyBase::ExpectDiffRxz(const qs_data_p_t& auto obj_min_mask = mask.obj_min_mask; auto obj_max_mask = mask.obj_max_mask; auto ctrl_mask = mask.ctrl_mask; + qs_data_t res = 0.0; if (!mask.ctrl_mask) { - return thrust::transform_reduce( + res = thrust::transform_reduce( l, l + dim / 4, [=] __device__(size_t l) { index_t i; @@ -512,29 +541,37 @@ auto GPUVectorPolicyBase::ExpectDiffRxz(const qs_data_p_t& return this_res; }, qs_data_t(0, 0), thrust::plus()); + } else { + res = thrust::transform_reduce( + l, l + dim / 4, + [=] __device__(size_t l) { + index_t i; + SHIFT_BIT_TWO(obj_low_mask, obj_rev_low_mask, obj_high_mask, obj_rev_high_mask, l, i); + if ((i & ctrl_mask) != ctrl_mask) { + return qs_data_t(0, 0); + } + auto m = i + obj_mask; + auto j = i + obj_min_mask; + auto k = i + obj_max_mask; + auto v00 = c * ket[i] + s * ket[j]; + auto v01 = c * ket[j] + s * ket[i]; + auto v10 = c * ket[k] - s * ket[m]; + auto v11 = c * ket[m] - s * ket[k]; + auto this_res = thrust::conj(bra[i]) * v00; + this_res += thrust::conj(bra[j]) * v01; + this_res += thrust::conj(bra[k]) * v10; + this_res += thrust::conj(bra[m]) * v11; + return this_res; + }, + qs_data_t(0, 0), thrust::plus()); } - return thrust::transform_reduce( - l, l + dim / 4, - [=] __device__(size_t l) { - index_t i; - SHIFT_BIT_TWO(obj_low_mask, obj_rev_low_mask, obj_high_mask, obj_rev_high_mask, l, i); - if ((i & ctrl_mask) != ctrl_mask) { - return qs_data_t(0, 0); - } - auto m = i + obj_mask; - auto j = i + obj_min_mask; - auto k = i + obj_max_mask; - auto v00 = c * ket[i] + s * ket[j]; - auto v01 = c * ket[j] + s * ket[i]; - auto v10 = c * ket[k] - s * ket[m]; - auto v11 = c * ket[m] - s * ket[k]; - auto this_res = thrust::conj(bra[i]) * v00; - this_res += thrust::conj(bra[j]) * v01; - this_res += thrust::conj(bra[k]) * v10; - this_res += thrust::conj(bra[m]) * v11; - return this_res; - }, - qs_data_t(0, 0), thrust::plus()); + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } + return res; } template @@ -543,11 +580,14 @@ auto GPUVectorPolicyBase::ExpectDiffRyz(const qs_data_p_t& index_t dim) -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); @@ -561,8 +601,9 @@ auto GPUVectorPolicyBase::ExpectDiffRyz(const qs_data_p_t& auto obj_min_mask = mask.obj_min_mask; auto obj_max_mask = mask.obj_max_mask; auto ctrl_mask = mask.ctrl_mask; + qs_data_t res = 0.0; if (!mask.ctrl_mask) { - return thrust::transform_reduce( + res = thrust::transform_reduce( l, l + dim / 4, [=] __device__(size_t l) { index_t i; @@ -581,29 +622,37 @@ auto GPUVectorPolicyBase::ExpectDiffRyz(const qs_data_p_t& return this_res; }, qs_data_t(0, 0), thrust::plus()); + } else { + res = thrust::transform_reduce( + l, l + dim / 4, + [=] __device__(size_t l) { + index_t i; + SHIFT_BIT_TWO(obj_low_mask, obj_rev_low_mask, obj_high_mask, obj_rev_high_mask, l, i); + if ((i & ctrl_mask) != ctrl_mask) { + return qs_data_t(0, 0); + } + auto m = i + obj_mask; + auto j = i + obj_min_mask; + auto k = i + obj_max_mask; + auto v00 = c * ket[i] - s * ket[j]; + auto v01 = c * ket[j] + s * ket[i]; + auto v10 = c * ket[k] + s * ket[m]; + auto v11 = c * ket[m] - s * ket[k]; + auto this_res = thrust::conj(bra[i]) * v00; + this_res += thrust::conj(bra[j]) * v01; + this_res += thrust::conj(bra[k]) * v10; + this_res += thrust::conj(bra[m]) * v11; + return this_res; + }, + qs_data_t(0, 0), thrust::plus()); } - return thrust::transform_reduce( - l, l + dim / 4, - [=] __device__(size_t l) { - index_t i; - SHIFT_BIT_TWO(obj_low_mask, obj_rev_low_mask, obj_high_mask, obj_rev_high_mask, l, i); - if ((i & ctrl_mask) != ctrl_mask) { - return qs_data_t(0, 0); - } - auto m = i + obj_mask; - auto j = i + obj_min_mask; - auto k = i + obj_max_mask; - auto v00 = c * ket[i] - s * ket[j]; - auto v01 = c * ket[j] + s * ket[i]; - auto v10 = c * ket[k] + s * ket[m]; - auto v11 = c * ket[m] - s * ket[k]; - auto this_res = thrust::conj(bra[i]) * v00; - this_res += thrust::conj(bra[j]) * v01; - this_res += thrust::conj(bra[k]) * v10; - this_res += thrust::conj(bra[m]) * v11; - return this_res; - }, - qs_data_t(0, 0), thrust::plus()); + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } + return res; } template @@ -612,11 +661,14 @@ auto GPUVectorPolicyBase::ExpectDiffRyy(const qs_data_p_t& index_t dim) -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); @@ -630,12 +682,36 @@ auto GPUVectorPolicyBase::ExpectDiffRyy(const qs_data_p_t& auto obj_min_mask = mask.obj_min_mask; auto obj_max_mask = mask.obj_max_mask; auto ctrl_mask = mask.ctrl_mask; + qs_data_t res = 0.0; if (!mask.ctrl_mask) { - return thrust::transform_reduce( + res = thrust::transform_reduce( + l, l + dim / 4, + [=] __device__(size_t l) { + index_t i; + SHIFT_BIT_TWO(obj_low_mask, obj_rev_low_mask, obj_high_mask, obj_rev_high_mask, l, i); + auto m = i + obj_mask; + auto j = i + obj_min_mask; + auto k = i + obj_max_mask; + auto v00 = c * ket[i] + s * ket[m]; + auto v01 = c * ket[j] + s * ket[k]; + auto v10 = c * ket[k] + s * ket[j]; + auto v11 = c * ket[m] + s * ket[i]; + auto this_res = thrust::conj(bra[i]) * v00; + this_res += thrust::conj(bra[j]) * v01; + this_res += thrust::conj(bra[k]) * v10; + this_res += thrust::conj(bra[m]) * v11; + return this_res; + }, + qs_data_t(0, 0), thrust::plus()); + } else { + res = thrust::transform_reduce( l, l + dim / 4, [=] __device__(size_t l) { index_t i; SHIFT_BIT_TWO(obj_low_mask, obj_rev_low_mask, obj_high_mask, obj_rev_high_mask, l, i); + if ((i & ctrl_mask) != ctrl_mask) { + return qs_data_t(0, 0); + } auto m = i + obj_mask; auto j = i + obj_min_mask; auto k = i + obj_max_mask; @@ -651,28 +727,13 @@ auto GPUVectorPolicyBase::ExpectDiffRyy(const qs_data_p_t& }, qs_data_t(0, 0), thrust::plus()); } - return thrust::transform_reduce( - l, l + dim / 4, - [=] __device__(size_t l) { - index_t i; - SHIFT_BIT_TWO(obj_low_mask, obj_rev_low_mask, obj_high_mask, obj_rev_high_mask, l, i); - if ((i & ctrl_mask) != ctrl_mask) { - return qs_data_t(0, 0); - } - auto m = i + obj_mask; - auto j = i + obj_min_mask; - auto k = i + obj_max_mask; - auto v00 = c * ket[i] + s * ket[m]; - auto v01 = c * ket[j] + s * ket[k]; - auto v10 = c * ket[k] + s * ket[j]; - auto v11 = c * ket[m] + s * ket[i]; - auto this_res = thrust::conj(bra[i]) * v00; - this_res += thrust::conj(bra[j]) * v01; - this_res += thrust::conj(bra[k]) * v10; - this_res += thrust::conj(bra[m]) * v11; - return this_res; - }, - qs_data_t(0, 0), thrust::plus()); + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } + return res; } template @@ -681,11 +742,14 @@ auto GPUVectorPolicyBase::ExpectDiffRzz(const qs_data_p_t& index_t dim) -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } DoubleQubitGateMask mask(objs, ctrls); auto c = static_cast(-std::sin(val / 2) / 2); @@ -701,8 +765,9 @@ auto GPUVectorPolicyBase::ExpectDiffRzz(const qs_data_p_t& auto obj_min_mask = mask.obj_min_mask; auto obj_max_mask = mask.obj_max_mask; auto ctrl_mask = mask.ctrl_mask; + qs_data_t res = 0.0; if (!mask.ctrl_mask) { - return thrust::transform_reduce( + res = thrust::transform_reduce( l, l + dim / 4, [=] __device__(size_t l) { index_t i; @@ -717,39 +782,39 @@ auto GPUVectorPolicyBase::ExpectDiffRzz(const qs_data_p_t& return this_res; }, qs_data_t(0, 0), thrust::plus()); + } else { + res = thrust::transform_reduce( + l, l + dim / 4, + [=] __device__(size_t l) { + index_t i; + SHIFT_BIT_TWO(obj_low_mask, obj_rev_low_mask, obj_high_mask, obj_rev_high_mask, l, i); + if ((i & ctrl_mask) != ctrl_mask) { + return qs_data_t(0, 0); + } + auto m = i + obj_mask; + auto j = i + obj_min_mask; + auto k = i + obj_max_mask; + auto this_res = thrust::conj(bra[i]) * ket[i] * me; + this_res += thrust::conj(bra[j]) * ket[j] * e; + this_res += thrust::conj(bra[k]) * ket[k] * e; + this_res += thrust::conj(bra[m]) * ket[m] * me; + return this_res; + }, + qs_data_t(0, 0), thrust::plus()); } - return thrust::transform_reduce( - l, l + dim / 4, - [=] __device__(size_t l) { - index_t i; - SHIFT_BIT_TWO(obj_low_mask, obj_rev_low_mask, obj_high_mask, obj_rev_high_mask, l, i); - if ((i & ctrl_mask) != ctrl_mask) { - return qs_data_t(0, 0); - } - auto m = i + obj_mask; - auto j = i + obj_min_mask; - auto k = i + obj_max_mask; - auto this_res = thrust::conj(bra[i]) * ket[i] * me; - this_res += thrust::conj(bra[j]) * ket[j] * e; - this_res += thrust::conj(bra[k]) * ket[k] * e; - this_res += thrust::conj(bra[m]) * ket[m] * me; - return this_res; - }, - qs_data_t(0, 0), thrust::plus()); + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } + return res; } template -auto GPUVectorPolicyBase::ExpectDiffGP(const qs_data_p_t& bra_out, const qs_data_p_t& ket_out, +auto GPUVectorPolicyBase::ExpectDiffGP(const qs_data_p_t& bra, const qs_data_p_t& ket, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim) -> qs_data_t { - auto bra = bra_out; - auto ket = ket_out; - if (bra == nullptr) { - bra = derived::InitState(dim); - } - if (ket == nullptr) { - ket = derived::InitState(dim); - } SingleQubitGateMask mask(objs, ctrls); auto e = std::complex(0, -1); e *= std::exp(std::complex(0, -val)); @@ -763,11 +828,14 @@ auto GPUVectorPolicyBase::ExpectDiffPS(const qs_data_p_t& index_t dim) -> qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } SingleQubitGateMask mask(objs, ctrls); auto e = static_cast(std::cos(val)) + qs_data_t(0, 1) * static_cast(std::sin(val)); @@ -776,8 +844,9 @@ auto GPUVectorPolicyBase::ExpectDiffPS(const qs_data_p_t& auto obj_low_mask = mask.obj_low_mask; auto obj_mask = mask.obj_mask; auto ctrl_mask = mask.ctrl_mask; + qs_data_t res = 0.0; if (!(mask.ctrl_mask)) { - return thrust::transform_reduce( + res = thrust::transform_reduce( l, l + dim / 2, [=] __device__(size_t l) { auto i = ((l & obj_high_mask) << 1) + (l & obj_low_mask); @@ -799,7 +868,7 @@ auto GPUVectorPolicyBase::ExpectDiffPS(const qs_data_p_t& } auto first_high_mask = ~first_low_mask; auto second_high_mask = ~second_low_mask; - return thrust::transform_reduce( + res = thrust::transform_reduce( l, l + dim / 4, [=] __device__(size_t l) { auto i = ((l & first_high_mask) << 1) + (l & first_low_mask); @@ -809,19 +878,27 @@ auto GPUVectorPolicyBase::ExpectDiffPS(const qs_data_p_t& return this_res; }, qs_data_t(0, 0), thrust::plus()); + } else { + res = thrust::transform_reduce( + l, l + dim / 2, + [=] __device__(size_t l) { + auto i = ((l & obj_high_mask) << 1) + (l & obj_low_mask); + if ((i & ctrl_mask) != ctrl_mask) { + return qs_data_t(0, 0); + } + auto j = i + obj_mask; + auto this_res = thrust::conj(bra[j]) * ket[j] * e; + return this_res; + }, + qs_data_t(0, 0), thrust::plus()); } - return thrust::transform_reduce( - l, l + dim / 2, - [=] __device__(size_t l) { - auto i = ((l & obj_high_mask) << 1) + (l & obj_low_mask); - if ((i & ctrl_mask) != ctrl_mask) { - return qs_data_t(0, 0); - } - auto j = i + obj_mask; - auto this_res = thrust::conj(bra[j]) * ket[j] * e; - return this_res; - }, - qs_data_t(0, 0), thrust::plus()); + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } + return res; } template struct GPUVectorPolicyBase; diff --git a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_matrix_gate.cu b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_matrix_gate.cu index a9d1a65ca..d537990e5 100644 --- a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_matrix_gate.cu +++ b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_matrix_gate.cu @@ -25,10 +25,22 @@ #include "thrust/inner_product.h" namespace mindquantum::sim::vector::detail { template -void GPUVectorPolicyBase::ApplyNQubitsMatrix(qs_data_p_t src, qs_data_p_t des, +void GPUVectorPolicyBase::ApplyNQubitsMatrix(const qs_data_p_t& src_out, qs_data_p_t* des_p, const qbits_t& objs, const qbits_t& ctrls, const std::vector>& gate, index_t dim) { + auto& des = *des_p; + if (des == nullptr) { + des = derived::InitState(dim); + } + qs_data_p_t src; + bool will_free = false; + if (src_out == nullptr) { + src = derived::InitState(dim); + will_free = true; + } else { + src = src_out; + } size_t n_qubit = objs.size(); size_t m_dim = (1UL << n_qubit); size_t ctrl_mask = 0; @@ -76,13 +88,28 @@ void GPUVectorPolicyBase::ApplyNQubitsMatrix(qs_data_p_t s free(tmp_des); } }); + if (will_free) { + derived::FreeState(&src); + } } template -void GPUVectorPolicyBase::ApplyTwoQubitsMatrix(qs_data_p_t src, qs_data_p_t des, +void GPUVectorPolicyBase::ApplyTwoQubitsMatrix(const qs_data_p_t& src_out, qs_data_p_t* des_p, const qbits_t& objs, const qbits_t& ctrls, const std::vector>& m, index_t dim) { + auto& des = *des_p; + if (des == nullptr) { + des = derived::InitState(dim); + } + qs_data_p_t src; + bool will_free = false; + if (src_out == nullptr) { + src = derived::InitState(dim); + will_free = true; + } else { + src = src_out; + } DoubleQubitGateMask mask(objs, ctrls); qs_data_t m00 = m[0][0]; qs_data_t m01 = m[0][1]; @@ -144,12 +171,27 @@ void GPUVectorPolicyBase::ApplyTwoQubitsMatrix(qs_data_p_t } }); } + if (will_free) { + derived::FreeState(&src); + } } template -void GPUVectorPolicyBase::ApplySingleQubitMatrix(qs_data_p_t src, qs_data_p_t des, +void GPUVectorPolicyBase::ApplySingleQubitMatrix(const qs_data_p_t& src_out, qs_data_p_t* des_p, qbit_t obj_qubit, const qbits_t& ctrls, const std::vector>& m, index_t dim) { + auto& des = (*des_p); + if (des == nullptr) { + des = derived::InitState(dim); + } + qs_data_p_t src; + bool will_free = false; + if (src_out == nullptr) { + src = derived::InitState(dim); + will_free = true; + } else { + src = src_out; + } SingleQubitGateMask mask({obj_qubit}, ctrls); qs_data_t m00 = m[0][0]; qs_data_t m01 = m[0][1]; @@ -181,19 +223,22 @@ void GPUVectorPolicyBase::ApplySingleQubitMatrix(qs_data_p } }); } + if (will_free) { + derived_::FreeState(&src); + } } template -void GPUVectorPolicyBase::ApplyMatrixGate(qs_data_p_t src, qs_data_p_t des, const qbits_t& objs, - const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyMatrixGate(const qs_data_p_t& src, qs_data_p_t* des_p, + const qbits_t& objs, const qbits_t& ctrls, const std::vector>& m, index_t dim) { if (objs.size() == 1) { - derived::ApplySingleQubitMatrix(src, des, objs[0], ctrls, m, dim); + derived::ApplySingleQubitMatrix(src, des_p, objs[0], ctrls, m, dim); } else if (objs.size() == 2) { - derived::ApplyTwoQubitsMatrix(src, des, objs, ctrls, m, dim); + derived::ApplyTwoQubitsMatrix(src, des_p, objs, ctrls, m, dim); } else { - derived::ApplyNQubitsMatrix(src, des, objs, ctrls, m, dim); + derived::ApplyNQubitsMatrix(src, des_p, objs, ctrls, m, dim); } } 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 e398b86d0..cd0c758d1 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 @@ -26,18 +26,18 @@ namespace mindquantum::sim::vector::detail { template -void GPUVectorPolicyBase::ApplyH(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyH(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim) { std::vector> m{{M_SQRT1_2, M_SQRT1_2}, {M_SQRT1_2, -M_SQRT1_2}}; - derived::ApplySingleQubitMatrix(qs, qs, objs[0], ctrls, m, dim); + derived::ApplySingleQubitMatrix(*qs_p, qs_p, objs[0], ctrls, m, dim); } template -void GPUVectorPolicyBase::ApplyGP(qs_data_p_t qs, qbit_t obj_qubit, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyGP(qs_data_p_t* qs_p, qbit_t obj_qubit, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { auto c = std::exp(std::complex(0, -val)); std::vector> m = {{c, 0}, {0, c}}; - derived::ApplySingleQubitMatrix(qs, qs, obj_qubit, ctrls, m, dim); + derived::ApplySingleQubitMatrix(*qs_p, qs_p, obj_qubit, ctrls, m, dim); } template struct GPUVectorPolicyBase; 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 79bb65927..cb5925bbc 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 @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. #include +#include #include @@ -30,7 +31,10 @@ namespace mindquantum::sim::vector::detail { template auto GPUVectorPolicyBase::InitState(index_t dim, bool zero_state) -> qs_data_p_t { qs_data_p_t qs; - cudaMalloc((void**) &qs, sizeof(qs_data_t) * dim); // NOLINT + auto state = cudaMalloc((void**) &qs, sizeof(qs_data_t) * dim); // NOLINT + if (state != cudaSuccess) { + throw std::runtime_error("GPU out of memory for allocate quantum state."); + } cudaMemset(qs, 0, sizeof(qs_data_t) * dim); if (zero_state) { qs_data_t one = qs_data_t(1.0, 0.0); @@ -119,11 +123,14 @@ auto GPUVectorPolicyBase::ExpectationOfTerms(const qs_data index_t dim) -> py_qs_data_t { auto bra = bra_out; auto ket = ket_out; + bool will_free_bra = false, will_free_ket = false; if (bra == nullptr) { bra = derived::InitState(dim); + will_free_bra = true; } if (ket == nullptr) { ket = derived::InitState(dim); + will_free_ket = true; } qs_data_t out = 0.0; for (const auto& [pauli_string, coeff] : ham) { @@ -160,6 +167,12 @@ auto GPUVectorPolicyBase::ExpectationOfTerms(const qs_data }, qs_data_t(0, 0), thrust::plus()); } + if (will_free_bra) { + derived::FreeState(&bra); + } + if (will_free_ket) { + derived::FreeState(&ket); + } return out; } @@ -241,10 +254,13 @@ auto GPUVectorPolicyBase::GroundStateOfZZs(const std::map< } template -auto GPUVectorPolicyBase::Copy(qs_data_p_t qs, index_t dim) -> qs_data_p_t { +auto GPUVectorPolicyBase::Copy(const qs_data_p_t& qs, index_t dim) -> qs_data_p_t { qs_data_p_t out = nullptr; if (qs != nullptr) { - cudaMalloc((void**) &out, sizeof(qs_data_t) * dim); // NOLINT + auto state = cudaMalloc((void**) &out, sizeof(qs_data_t) * dim); // NOLINT + if (state != cudaSuccess) { + throw std::runtime_error("GPU out of memory for allocate quantum state."); + } cudaMemcpy(out, qs, sizeof(qs_data_t) * dim, cudaMemcpyDeviceToDevice); } return out; diff --git a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_rot_pauli.cu b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_rot_pauli.cu index c06934af4..5bbcc53b5 100644 --- a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_rot_pauli.cu +++ b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_rot_pauli.cu @@ -25,7 +25,7 @@ namespace mindquantum::sim::vector::detail { template -void GPUVectorPolicyBase::ApplyRX(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyRX(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { SingleQubitGateMask mask(objs, ctrls); auto a = static_cast(std::cos(val / 2)); @@ -35,14 +35,14 @@ void GPUVectorPolicyBase::ApplyRX(qs_data_p_t qs, const qb b = static_cast(-0.5 * std::cos(val / 2)); } std::vector> m{{{a, 0}, {0, b}}, {{0, b}, {a, 0}}}; - derived::ApplySingleQubitMatrix(qs, qs, objs[0], ctrls, m, dim); + derived::ApplySingleQubitMatrix(*qs_p, qs_p, objs[0], ctrls, m, dim); if (diff && mask.ctrl_mask) { - derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(qs_p, mask.ctrl_mask, dim); } } template -void GPUVectorPolicyBase::ApplyRY(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyRY(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { SingleQubitGateMask mask(objs, ctrls); auto a = static_cast(std::cos(val / 2)); @@ -52,14 +52,14 @@ void GPUVectorPolicyBase::ApplyRY(qs_data_p_t qs, const qb b = static_cast(0.5 * std::cos(val / 2)); } std::vector> m{{{a, 0}, {-b, 0}}, {{b, 0}, {a, 0}}}; - derived::ApplySingleQubitMatrix(qs, qs, objs[0], ctrls, m, dim); + derived::ApplySingleQubitMatrix(*qs_p, qs_p, objs[0], ctrls, m, dim); if (diff && mask.ctrl_mask) { - derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(qs_p, mask.ctrl_mask, dim); } } template -void GPUVectorPolicyBase::ApplyRZ(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyRZ(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { SingleQubitGateMask mask(objs, ctrls); auto a = static_cast(std::cos(val / 2)); @@ -69,14 +69,18 @@ void GPUVectorPolicyBase::ApplyRZ(qs_data_p_t qs, const qb b = static_cast(0.5 * std::cos(val / 2)); } std::vector> m{{{a, -b}, {0, 0}}, {{0, 0}, {a, b}}}; - derived::ApplySingleQubitMatrix(qs, qs, objs[0], ctrls, m, dim); + derived::ApplySingleQubitMatrix(*qs_p, qs_p, objs[0], ctrls, m, dim); if (diff && mask.ctrl_mask) { - derived::SetToZeroExcept(&qs, mask.ctrl_mask, dim); + derived::SetToZeroExcept(qs_p, mask.ctrl_mask, dim); } } template -void GPUVectorPolicyBase::ApplyRzz(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyRzz(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); thrust::counting_iterator l(0); auto obj_high_mask = mask.obj_high_mask; @@ -128,8 +132,12 @@ void GPUVectorPolicyBase::ApplyRzz(qs_data_p_t qs, const q } template -void GPUVectorPolicyBase::ApplyRxx(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyRxx(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); thrust::counting_iterator l(0); auto obj_high_mask = mask.obj_high_mask; @@ -187,8 +195,12 @@ void GPUVectorPolicyBase::ApplyRxx(qs_data_p_t qs, const q } template -void GPUVectorPolicyBase::ApplyRxy(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyRxy(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); thrust::counting_iterator l(0); auto obj_high_mask = mask.obj_high_mask; @@ -246,8 +258,12 @@ void GPUVectorPolicyBase::ApplyRxy(qs_data_p_t qs, const q } template -void GPUVectorPolicyBase::ApplyRxz(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyRxz(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); thrust::counting_iterator l(0); auto obj_high_mask = mask.obj_high_mask; @@ -305,8 +321,12 @@ void GPUVectorPolicyBase::ApplyRxz(qs_data_p_t qs, const q } template -void GPUVectorPolicyBase::ApplyRyz(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyRyz(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); thrust::counting_iterator l(0); auto obj_high_mask = mask.obj_high_mask; @@ -364,8 +384,12 @@ void GPUVectorPolicyBase::ApplyRyz(qs_data_p_t qs, const q } template -void GPUVectorPolicyBase::ApplyRyy(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyRyy(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); thrust::counting_iterator l(0); auto obj_high_mask = mask.obj_high_mask; diff --git a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_swap_like.cu b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_swap_like.cu index 86d3e04be..2ccb969c0 100644 --- a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_swap_like.cu +++ b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_swap_like.cu @@ -26,8 +26,12 @@ namespace mindquantum::sim::vector::detail { template -void GPUVectorPolicyBase::ApplySWAP(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplySWAP(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); thrust::counting_iterator l(0); auto obj_high_mask = mask.obj_high_mask; @@ -59,8 +63,12 @@ void GPUVectorPolicyBase::ApplySWAP(qs_data_p_t qs, const } template -void GPUVectorPolicyBase::ApplyISWAP(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyISWAP(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, bool daggered, index_t dim) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } DoubleQubitGateMask mask(objs, ctrls); thrust::counting_iterator l(0); auto obj_high_mask = mask.obj_high_mask; diff --git a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_x_like.cu b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_x_like.cu index 1e643da21..482f9785e 100644 --- a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_x_like.cu +++ b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_x_like.cu @@ -25,8 +25,12 @@ namespace mindquantum::sim::vector::detail { template -void GPUVectorPolicyBase::ApplyXLike(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyXLike(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, qs_data_t v1, qs_data_t v2, index_t dim) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } SingleQubitGateMask mask(objs, ctrls); thrust::counting_iterator l(0); auto obj_high_mask = mask.obj_high_mask; @@ -55,15 +59,15 @@ void GPUVectorPolicyBase::ApplyXLike(qs_data_p_t qs, const } template -void GPUVectorPolicyBase::ApplyX(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyX(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim) { - derived::ApplyXLike(qs, objs, ctrls, 1, 1, dim); + derived::ApplyXLike(qs_p, objs, ctrls, 1, 1, dim); } template -void GPUVectorPolicyBase::ApplyY(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyY(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim) { - derived::ApplyXLike(qs, objs, ctrls, qs_data_t(0, -1), qs_data_t(0, 1), dim); + derived::ApplyXLike(qs_p, objs, ctrls, qs_data_t(0, -1), qs_data_t(0, 1), dim); } template struct GPUVectorPolicyBase; diff --git a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_z_like.cu b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_z_like.cu index 9c104b153..fd82186b1 100644 --- a/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_z_like.cu +++ b/ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_z_like.cu @@ -25,8 +25,12 @@ namespace mindquantum::sim::vector::detail { template -void GPUVectorPolicyBase::ApplyZLike(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyZLike(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, qs_data_t val, index_t dim) { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } SingleQubitGateMask mask(objs, ctrls); thrust::counting_iterator l(0); auto obj_high_mask = mask.obj_high_mask; @@ -49,37 +53,41 @@ void GPUVectorPolicyBase::ApplyZLike(qs_data_p_t qs, const } template -void GPUVectorPolicyBase::ApplyZ(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyZ(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim) { - derived::ApplyZLike(qs, objs, ctrls, -1, dim); + derived::ApplyZLike(qs_p, objs, ctrls, -1, dim); } template -void GPUVectorPolicyBase::ApplySGate(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplySGate(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim) { - derived::ApplyZLike(qs, objs, ctrls, qs_data_t(0, 1), dim); + derived::ApplyZLike(qs_p, objs, ctrls, qs_data_t(0, 1), dim); } template -void GPUVectorPolicyBase::ApplySdag(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplySdag(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim) { - derived::ApplyZLike(qs, objs, ctrls, qs_data_t(0, -1), dim); + derived::ApplyZLike(qs_p, objs, ctrls, qs_data_t(0, -1), dim); } template -void GPUVectorPolicyBase::ApplyT(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyT(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim) { - derived::ApplyZLike(qs, objs, ctrls, qs_data_t(1, 1) / std::sqrt(2.0), dim); + derived::ApplyZLike(qs_p, objs, ctrls, qs_data_t(1, 1) / std::sqrt(2.0), dim); } template -void GPUVectorPolicyBase::ApplyTdag(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyTdag(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, index_t dim) { - derived::ApplyZLike(qs, objs, ctrls, qs_data_t(1, -1) / std::sqrt(2.0), dim); + derived::ApplyZLike(qs_p, objs, ctrls, qs_data_t(1, -1) / std::sqrt(2.0), dim); } template -void GPUVectorPolicyBase::ApplyPS(qs_data_p_t qs, const qbits_t& objs, const qbits_t& ctrls, +void GPUVectorPolicyBase::ApplyPS(qs_data_p_t* qs_p, const qbits_t& objs, const qbits_t& ctrls, calc_type val, index_t dim, bool diff) { if (!diff) { - derived::ApplyZLike(qs, objs, ctrls, qs_data_t(std::cos(val), std::sin(val)), dim); + derived::ApplyZLike(qs_p, objs, ctrls, qs_data_t(std::cos(val), std::sin(val)), dim); } else { + auto& qs = *qs_p; + if (qs == nullptr) { + qs = derived::InitState(dim); + } SingleQubitGateMask mask(objs, ctrls); thrust::counting_iterator l(0); auto obj_high_mask = mask.obj_high_mask; @@ -105,7 +113,7 @@ void GPUVectorPolicyBase::ApplyPS(qs_data_p_t qs, const qb } }); } - derived::SetToZeroExcept(&qs, ctrl_mask, dim); + derived::SetToZeroExcept(qs_p, ctrl_mask, dim); } } } -- Gitee From d638d688edc1505bca0979665997d143490bd6da Mon Sep 17 00:00:00 2001 From: xuxusheng Date: Mon, 8 May 2023 15:42:59 +0800 Subject: [PATCH 8/8] fix lizard --- .jenkins/check/config/whitelizard.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.jenkins/check/config/whitelizard.txt b/.jenkins/check/config/whitelizard.txt index 2e01ea1b1..1a0eb7e93 100644 --- a/.jenkins/check/config/whitelizard.txt +++ b/.jenkins/check/config/whitelizard.txt @@ -39,6 +39,7 @@ mindquantum/ccsrc/lib/simulator/vector/detail/runtime/cmd.cpp:mindquantum::sim:: mindquantum/ccsrc/include/math/tensor/ops_cpu/advance_math.hpp:tensor::ops::cpu::ElementFunc mindquantum/mindquantum/core/parameterresolver/parameterresolver.py:__init__ mindquantum/ccsrc/python/math/lib/bind_math.cpp:BindQubitOperator +ccsrc/lib/simulator/vector/detail/cpu_avx_double/cpu_vector_core_gate_expect.cpp:mindquantum::sim::vector::detail::CPUVectorPolicyAvxDouble::ExpectDiffSingleQubitMatrix TEST_CASE mindquantum::sim::vector::detail::VectorState::ApplyGate -- Gitee