Commit 9ac4b78b authored by Nguyen, Thien's avatar Nguyen, Thien
Browse files

Fixed exp-val-z calculation for the Qpp Accelerator



Swapping the order of conditional check so that in we can further optimize for the case where there is no If statements in the circuit nor shots; in that case, calculate expectation analytically.

Also, fixed a potential bug whereby the shots count may not be reset if using the accelerator multiple times.
Signed-off-by: Nguyen, Thien's avatarThien Nguyen <nguyentm@ornl.gov>
parent 996f6bb1
......@@ -181,6 +181,8 @@ namespace quantum {
void QppAccelerator::initialize(const HeterogeneousMap& params)
{
m_visitor = std::make_shared<QppVisitor>();
// Default: no shots (unless otherwise specified)
m_shots = -1;
if (params.keyExists<int>("shots"))
{
m_shots = params.get<int>("shots");
......@@ -210,22 +212,22 @@ namespace quantum {
m_visitor->finalize();
};
// Not possible to simulate shot count by direct sampling,
// e.g. must collapse the state vector.
if(!shotCountFromFinalStateVec(compositeInstruction))
{
if (m_shots < 0)
{
runCircuit(false);
}
else
{
// Not possible to simulate shot count by direct sampling,
// e.g. must collapse the state vector.
if(!shotCountFromFinalStateVec(compositeInstruction))
{
for (int i = 0; i < m_shots; ++i)
{
runCircuit(true);
}
}
}
else
{
// Index of measure bits
......@@ -254,13 +256,19 @@ namespace quantum {
if (!measureBitIdxs.empty())
{
const auto& stateVec = m_visitor->getStateVec();
if (m_shots < 0)
{
const double expectedValueZ = QppVisitor::calcExpectationValueZ(stateVec, measureBitIdxs);
buffer->addExtraInfo("exp-val-z", expectedValueZ);
}
else
{
// Try multi-threaded execution if there are many shots.
const bool multiThreadEnabled = (m_shots > 1024);
generateMeasureBitString(buffer, measureBitIdxs, stateVec, m_shots, multiThreadEnabled);
}
m_visitor->finalize();
}
m_visitor->finalize();
}
}
......
......@@ -72,7 +72,7 @@ namespace quantum {
return m_buffer->size() - in_idx - 1;
}
double QppVisitor::calcExpectationValueZ() const
double QppVisitor::calcExpectationValueZ(const KetVectorType& in_stateVec, const std::vector<qpp::idx>& in_bits)
{
const auto hasEvenParity = [](size_t x, const std::vector<size_t>& in_qubitIndices) -> bool {
size_t count = 0;
......@@ -88,9 +88,9 @@ namespace quantum {
double result = 0.0;
for(uint64_t i = 0; i < m_stateVec.size(); ++i)
for(uint64_t i = 0; i < in_stateVec.size(); ++i)
{
result += (hasEvenParity(i, m_measureBits) ? 1.0 : -1.0) * std::norm(m_stateVec[i]);
result += (hasEvenParity(i, in_bits) ? 1.0 : -1.0) * std::norm(in_stateVec[i]);
}
return result;
......@@ -270,7 +270,7 @@ namespace quantum {
if (!m_shotsMode)
{
// Not running a shot simulation, calculate the expectation value.
const double expectedValueZ = calcExpectationValueZ();
const double expectedValueZ = calcExpectationValueZ(m_stateVec, m_measureBits);
m_buffer->addExtraInfo("exp-val-z", expectedValueZ);
}
else
......
......@@ -55,9 +55,9 @@ public:
virtual std::shared_ptr<QppVisitor> clone() { return std::make_shared<QppVisitor>(); }
const KetVectorType& getStateVec() const { return m_stateVec; }
static double calcExpectationValueZ(const KetVectorType& in_stateVec, const std::vector<qpp::idx>& in_bits);
private:
qpp::idx xaccIdxToQppIdx(size_t in_idx) const;
double calcExpectationValueZ() const;
private:
std::shared_ptr<AcceleratorBuffer> m_buffer;
std::vector<qpp::idx> m_dims;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment