Commit a956bf3a authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

Adding ImprovedSamplingDecorator (#79)



Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent 5e662501
#include "ImprovedSamplingDecorator.hpp"
#include "InstructionIterator.hpp"
#include "XACC.hpp"
namespace xacc {
namespace quantum {
void ImprovedSamplingDecorator::execute(
std::shared_ptr<AcceleratorBuffer> buffer,
const std::shared_ptr<Function> function) {
if (!decoratedAccelerator) {
xacc::error("Cannot run the ImprovedSamplingDecorator without a delegate "
"Accelerator.");
}
if (!xacc::optionExists("sampler-n-execs")) {
xacc::error("Cannot find sampler-n-execs option. Skipping "
"ImprovedSamplingDecorator.");
return;
}
// Get the number of extra runs to execute
auto nRuns = std::stoi(xacc::getOption("sampler-n-execs"));
// Execute the first one.
decoratedAccelerator->execute(buffer, function);
auto counts = buffer->getMeasurementCounts();
for (int i = 1; i < nRuns; i++) {
auto cloned = buffer->clone();
cloned->clearMeasurements();
decoratedAccelerator->execute(cloned, function);
auto clonedCounts = cloned->getMeasurementCounts();
// Aggregate results...
counts = std::accumulate(counts.begin(), counts.end(), clonedCounts,
[](std::map<std::string, int> &m,
const std::pair<std::string, int> &p) {
return (m[p.first] += p.second, m);
});
// Set on the return buffer;
buffer->setMeasurements(counts);
}
return;
}
std::vector<std::shared_ptr<AcceleratorBuffer>>
ImprovedSamplingDecorator::execute(
std::shared_ptr<AcceleratorBuffer> buffer,
const std::vector<std::shared_ptr<Function>> functions) {
std::vector<std::shared_ptr<AcceleratorBuffer>> buffers;
if (!decoratedAccelerator) {
xacc::error("Cannot run the ImprovedSamplingDecorator without a delegate "
"Accelerator.");
}
if (!xacc::optionExists("sampler-n-execs")) {
xacc::error("Cannot find sampler-n-execs option. Skipping "
"ImprovedSamplingDecorator.");
}
auto nRuns = std::stoi(xacc::getOption("sampler-n-execs"));
buffers = decoratedAccelerator->execute(buffer, functions);
std::map<std::string, std::map<std::string, int>> childrenCounts;
for (auto &b : buffers) {
childrenCounts.insert({b->name(), b->getMeasurementCounts()});
}
for (int i = 1; i < nRuns; i++) {
buffers = decoratedAccelerator->execute(buffer, functions);
for (auto &b : buffers) {
auto newCounts = b->getMeasurementCounts();
childrenCounts[b->name()] =
std::accumulate(childrenCounts[b->name()].begin(),
childrenCounts[b->name()].end(), newCounts,
[](std::map<std::string, int> &m,
const std::pair<std::string, int> &p) {
return (m[p.first] += p.second, m);
});
b->setMeasurements(childrenCounts[b->name()]);
}
}
return buffers;
}
} // namespace quantum
} // namespace xacc
\ No newline at end of file
/*******************************************************************************
* Copyright (c) 2018 UT-Battelle, LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompanies this
* distribution. The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution
*License is available at https://eclipse.org/org/documents/edl-v10.php
*
* Contributors:
* Alexander J. McCaskey - initial API and implementation
*******************************************************************************/
#ifndef XACC_IMPROVEDSAMPLINGDECORATOR_HPP_
#define XACC_IMPROVEDSAMPLINGDECORATOR_HPP_
#include "AcceleratorDecorator.hpp"
namespace xacc {
namespace quantum {
class ImprovedSamplingDecorator : public AcceleratorDecorator {
public:
void execute(std::shared_ptr<AcceleratorBuffer> buffer,
const std::shared_ptr<Function> function) override;
std::vector<std::shared_ptr<AcceleratorBuffer>>
execute(std::shared_ptr<AcceleratorBuffer> buffer,
const std::vector<std::shared_ptr<Function>> functions) override;
const std::string name() const override { return "improved-sampling"; }
const std::string description() const override { return ""; }
virtual std::shared_ptr<options_description> getOptions() {
auto desc = std::make_shared<options_description>();
desc->add_options()("sampler-n-execs", value<std::string>(), "");
return desc;
}
~ImprovedSamplingDecorator() override {}
};
} // namespace quantum
} // namespace xacc
#endif
#add_xacc_test(ReadoutErrorAcceleratorBufferPostprocessor)
add_xacc_test(ImprovedSamplingDecorator)
\ No newline at end of file
/*******************************************************************************
* Copyright (c) 2018 UT-Battelle, LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompanies this
* distribution. The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution
*License is available at https://eclipse.org/org/documents/edl-v10.php
*
* Contributors:
* Alexander J. McCaskey - initial API and implementation
*******************************************************************************/
#include <gtest/gtest.h>
#include "XACC.hpp"
#include "ImprovedSamplingDecorator.hpp"
using namespace xacc;
using namespace xacc::quantum;
TEST(ImprovedSamplingDecoratorTester, checkSimple) {
int shots = 8192;
int nExecs = 4;
if (xacc::hasAccelerator("local-ibm")) {
auto acc = xacc::getAccelerator("local-ibm");
auto buffer = acc->createBuffer("buffer", 2);
auto compiler = xacc::getService<xacc::Compiler>("xacc-py");
const std::string src = R"src(def f(buffer):
H(0)
Measure(0,0)
)src";
auto ir = compiler->compile(src, acc);
auto f = ir->getKernel("f");
ImprovedSamplingDecorator decorator;
decorator.setDecorated(acc);
xacc::setOption("ibm-shots", std::to_string(shots));
xacc::setOption("sampler-n-execs", std::to_string(nExecs));
decorator.execute(buffer, f);
int nshots = 0;
auto counts = buffer->getMeasurementCounts();
buffer->print();
for (auto &kv : counts) {
nshots += kv.second;
}
EXPECT_EQ(nshots, nExecs * shots);
}
}
TEST(ImprovedSamplingDecoratorTester, checkMultiple) {
int shots = 8192;
int nExecs = 2;
if (xacc::hasAccelerator("local-ibm")) {
auto acc = xacc::getAccelerator("local-ibm");
auto buffer = acc->createBuffer("buffer", 2);
auto compiler = xacc::getService<xacc::Compiler>("xacc-py");
const std::string src = R"src(def f(buffer):
H(0)
Measure(0,0)
)src";
const std::string src2 = R"src(def g(buffer):
H(0)
Measure(0,0)
)src";
auto ir = compiler->compile(src, acc);
auto ir2 = compiler->compile(src2, acc);
auto f = ir->getKernel("f");
auto g = ir2->getKernel("g");
ImprovedSamplingDecorator decorator;
decorator.setDecorated(acc);
xacc::setOption("ibm-shots", std::to_string(shots));
xacc::setOption("sampler-n-execs", std::to_string(nExecs));
auto buffers = decorator.execute(buffer, {f, g});
for (auto &b : buffers) {
int nshots = 0;
auto counts = b->getMeasurementCounts();
b->print();
for (auto &kv : counts) {
nshots += kv.second;
}
EXPECT_EQ(nshots, nExecs * shots);
}
}
}
int main(int argc, char **argv) {
xacc::Initialize();
::testing::InitGoogleTest(&argc, argv);
auto ret = RUN_ALL_TESTS();
xacc::Finalize();
return ret;
}
......@@ -285,6 +285,15 @@ AcceleratorBuffer::computeMeasurementProbability(const std::string &bitStr) {
return (double)bitStringToCounts[bitStr] / (double)measurements.size();
}
std::shared_ptr<AcceleratorBuffer> AcceleratorBuffer::clone() {
std::stringstream s;
print(s);
std::istringstream is(s.str());
auto cloned = std::make_shared<AcceleratorBuffer>();
cloned->load(is);
return cloned;
}
/**
* Compute and return the expectation value with respect
* to the Pauli-Z operator. Here we provide a base implementation
......
......@@ -131,6 +131,8 @@ public:
ExtraInfo getInformation(const std::string name);
std::map<std::string, ExtraInfo> getInformation();
std::shared_ptr<AcceleratorBuffer> clone();
/**
* Return all children with ExtraInfo infoName equal
* to the given ExtraInfo i.
......@@ -204,7 +206,20 @@ public:
virtual const std::vector<std::string> getMeasurementStrings();
virtual std::map<std::string, int> getMeasurementCounts();
virtual void clearMeasurements() {
measurements.clear();
bitStringToCounts.clear();
}
virtual void setMeasurements(std::map<std::string, int> counts) {
clearMeasurements();
bitStringToCounts = counts;
for (auto& kv : counts) {
for (int i = 0; i < kv.second; i++)
measurements.push_back(boost::dynamic_bitset<>(kv.first));
}
}
/**
* Print information about this AcceleratorBuffer to standard out.
*
......
Supports Markdown
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