Skip to content

Commit

Permalink
improve measure
Browse files Browse the repository at this point in the history
  • Loading branch information
donghufeng committed Jan 25, 2024
1 parent eb306d5 commit 314d921
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 8 deletions.
2 changes: 2 additions & 0 deletions ccsrc/include/simulator/vector/detail/cpu_vector_policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ struct CPUVectorPolicyBase {
static py_qs_data_t ExpectationOfCsr(const std::shared_ptr<sparse::CsrHdMatrix<calc_type>>& a,
const std::shared_ptr<sparse::CsrHdMatrix<calc_type>>& b,
const qs_data_p_t& bra, const qs_data_p_t& ket, index_t dim);
static VT<calc_type> GetCumulativeProbs(const qs_data_p_t& qs_p, index_t dim);
static VT<unsigned> LowerBound(const VT<calc_type>& cum_prob, const VT<calc_type>& sampled_probs);
// X like operator
// ========================================================================================================

Expand Down
2 changes: 2 additions & 0 deletions ccsrc/include/simulator/vector/detail/gpu_vector_policy.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ struct GPUVectorPolicyBase {
static py_qs_data_t ExpectationOfCsr(const std::shared_ptr<sparse::CsrHdMatrix<calc_type>>& a,
const std::shared_ptr<sparse::CsrHdMatrix<calc_type>>& b,
const qs_data_p_t& bra, const qs_data_p_t& ket, index_t dim);
static VT<calc_type> GetCumulativeProbs(const qs_data_p_t& qs_p, index_t dim);
static VT<unsigned> LowerBound(const VT<calc_type>& cum_prob, const VT<calc_type>& sampled_probs);
// X like operator
// ========================================================================================================

Expand Down
26 changes: 21 additions & 5 deletions ccsrc/include/simulator/vector/vector_state.tpp
Original file line number Diff line number Diff line change
Expand Up @@ -1303,21 +1303,37 @@ VT<unsigned> VectorState<qs_policy_t_>::SamplingMeasurementEndingWithoutNoise(co
auto sim = derived_t(n_qubits, static_cast<unsigned>(rng()), qs);

VT<int> already_measured(this->n_qubits, 0);
circuit_t mea_circ;

VT<int> m_qids;
circuit_t other_circ;
for (auto& g : circ) {
if (g->GetID() == GateID::M) {
auto m_qid = g->GetObjQubits()[0];
if (already_measured[m_qid] != 0) {
throw std::runtime_error("Quantum circuit is not a measurement ending circuit.");
}
already_measured[m_qid] = 1;
mea_circ.push_back(g);
m_qids.push_back(m_qid);
} else {
sim.ApplyGate(g, pr, false);
other_circ.push_back(g);
}
}
sim.ApplyCircuit(other_circ, pr);

auto cum_prob = qs_policy_t_::GetCumulativeProbs(sim.qs, dim);
VT<calc_type> sampled_probs(shots);
for (size_t i = 0; i < shots; ++i) {
sampled_probs[i] = static_cast<calc_type>(sim.rng_());
}
std::sort(sampled_probs.begin(), sampled_probs.end());
auto res = qs_policy_t_::LowerBound(cum_prob, sampled_probs);
VT<unsigned> out;
// Measure all qubits and filter actually measurement qubit.
for (auto r : res) {
for (auto i : m_qids) {
out.push_back((r >> i) & 1);
}
}
return sim.Sampling(mea_circ, pr, shots, key_map, seed);
return out;
}
} // namespace mindquantum::sim::vector::detail

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,16 @@
* limitations under the License.
*/
#include <cstddef>
#include <cstdlib>
#include <execution>
#include <limits>
#include <numeric>
#include <stdexcept>

#include "config/details/macros.h"
#include "config/openmp.h"
#include "config/type_promotion.h"
#include "core/mq_base_types.h"
#include "core/utils.h"
#include "math/pr/parameter_resolver.h"
#include "simulator/utils.h"
Expand Down Expand Up @@ -281,6 +285,56 @@ auto CPUVectorPolicyBase<derived_, calc_type>::GroundStateOfZZs(const std::map<i
return result;
}

template <typename T>
void ShowVec(const std::vector<T>& a) {
for (auto i : a) {
std::cout << i << ", ";
}
std::cout << std::endl;
}

template <typename derived_, typename calc_type>
VT<calc_type> CPUVectorPolicyBase<derived_, calc_type>::GetCumulativeProbs(const qs_data_p_t& qs_out, index_t dim) {
auto qs = qs_out;
bool will_free = false;
if (qs == nullptr) {
qs = derived_::InitState(dim);
will_free = true;
}
VT<calc_type> prob(dim);
// Can be optimized by parallel prefix sum algorithm.
prob[0] = qs[0].real() * qs[0].real() + qs[0].imag() * qs[0].imag();
for (size_t i = 1; i < dim; ++i) {
prob[i] = qs[i].real() * qs[i].real() + qs[i].imag() * qs[i].imag() + prob[i - 1];
}

prob[dim - 1] = 1.0;
if (will_free) {
free(qs);
}
return prob;
}

template <typename derived_, typename calc_type>
VT<unsigned> CPUVectorPolicyBase<derived_, calc_type>::LowerBound(const VT<calc_type>& cum_prob,
const VT<calc_type>& sampled_probs) {
size_t samp_size = sampled_probs.size();
VT<unsigned> out(samp_size);
size_t samp_idx = 0, dist_idx = 0;
while (true) {
if (samp_idx >= samp_size) {
break;
}
if (sampled_probs[samp_idx] < cum_prob[dist_idx]) {
out[samp_idx] = dist_idx;
samp_idx += 1;
} else {
dist_idx += 1;
}
}
return out;
}

#ifdef __x86_64__
template struct CPUVectorPolicyBase<CPUVectorPolicyAvxFloat, float>;
template struct CPUVectorPolicyBase<CPUVectorPolicyAvxDouble, double>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -931,7 +931,6 @@ auto GPUVectorPolicyBase<derived_, calc_type_>::ExpectDiffGivens(const qs_data_p
auto obj_rev_high_mask = mask.obj_rev_high_mask;
auto obj_low_mask = mask.obj_low_mask;
auto obj_rev_low_mask = mask.obj_rev_low_mask;
auto obj_mask = mask.obj_mask;
auto obj_min_mask = mask.obj_min_mask;
auto obj_max_mask = mask.obj_max_mask;
auto ctrl_mask = mask.ctrl_mask;
Expand Down
49 changes: 49 additions & 0 deletions ccsrc/lib/simulator/vector/detail/gpu/gpu_vector_core_policy.cu
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <limits>
#include <stdexcept>

#include <thrust/host_vector.h>
#include <thrust/transform_reduce.h>

#include "config/openmp.h"
Expand Down Expand Up @@ -334,6 +335,54 @@ auto GPUVectorPolicyBase<derived_, calc_type_>::Copy(const qs_data_p_t& qs, inde
return out;
};

template <typename derived_, typename calc_type>
VT<calc_type> GPUVectorPolicyBase<derived_, calc_type>::GetCumulativeProbs(const qs_data_p_t& qs_out, index_t dim) {
auto qs = qs_out;
bool will_free = false;
if (qs == nullptr) {
qs = derived_::InitState(dim);
will_free = true;
}
calc_type* prob;
auto state = cudaMalloc((void**) &prob, sizeof(calc_type) * dim); // NOLINT
if (state != cudaSuccess) {
throw std::runtime_error("Malloc GPU memory failed: " + std::string(cudaGetErrorName(state)) + ", "
+ cudaGetErrorString(state));
}
thrust::counting_iterator<index_t> i(0);
thrust::for_each(
i, i + dim, [=] __device__(index_t i) { prob[i] = qs[i].real() * qs[i].real() + qs[i].imag() * qs[i].imag(); });
thrust::device_ptr<calc_type> prob_ptr(prob);
thrust::inclusive_scan(thrust::device, prob, prob + dim, prob);
if (will_free) {
derived::FreeState(&qs);
}
VT<calc_type> out(dim);
thrust::copy(prob_ptr, prob_ptr + dim, out.begin());
cudaFree(prob);
return out;
}

template <typename derived_, typename calc_type>
VT<unsigned> GPUVectorPolicyBase<derived_, calc_type>::LowerBound(const VT<calc_type>& cum_prob,
const VT<calc_type>& sampled_probs) {
size_t samp_size = sampled_probs.size();
VT<unsigned> out(samp_size);
size_t samp_idx = 0, dist_idx = 0;
while (true) {
if (samp_idx >= samp_size) {
break;
}
if (sampled_probs[samp_idx] < cum_prob[dist_idx]) {
out[samp_idx] = dist_idx;
samp_idx += 1;
} else {
dist_idx += 1;
}
}
return out;
}

template struct GPUVectorPolicyBase<GPUVectorPolicyFloat, float>;
template struct GPUVectorPolicyBase<GPUVectorPolicyDouble, double>;

Expand Down
2 changes: 1 addition & 1 deletion mindquantum/core/circuit/circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,7 @@ def is_measure_end(self):
high[idx] += 1
if isinstance(gate, mq_gates.Measure):
m_idx = gate.obj_qubits[0]
if high[m_idx] != self.all_qubits.map[m_idx]:
if high[m_idx] != circ.all_qubits.map[m_idx]:
return False
return True

Expand Down
2 changes: 1 addition & 1 deletion tests/st/test_io/test_svg.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def test_measure_svg():
res = sim.sampling(circ, shots=100, seed=42)
text = res.svg()._repr_svg_().split('bar') # pylint: disable=protected-access
text = "bar".join([text[0]] + ['"'.join(i.split('"')[1:]) for i in text[1:]])
len_text_exp = 9257
len_text_exp = 9258
assert len(text) == len_text_exp


Expand Down

0 comments on commit 314d921

Please sign in to comment.