Commit 425d2806 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

Adding test for single term readout error post processing



Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent aebaafd3
......@@ -67,6 +67,7 @@ target_link_libraries(${LIBRARY_NAME} ${Boost_LIBRARIES} xacc ${CppUsLib})
add_subdirectory(compiler)
add_subdirectory(ir)
add_subdirectory(utils)
add_subdirectory(accelerator)
install(FILES ${HEADERS} DESTINATION include/quantum/gate)
install(TARGETS ${LIBRARY_NAME} DESTINATION lib)
......@@ -13,7 +13,7 @@
#include "QFT.hpp"
#include "InverseQFT.hpp"
#include "KernelReplacementPreprocessor.hpp"
#include "ReadoutErrorIRPreprocessor.hpp"
#include "cppmicroservices/BundleActivator.h"
#include "cppmicroservices/BundleContext.h"
#include "cppmicroservices/ServiceProperties.h"
......@@ -41,9 +41,14 @@ public:
auto iqft = std::make_shared<xacc::quantum::InverseQFT>();
auto kp =
std::make_shared<xacc::quantum::KernelReplacementPreprocessor>();
auto readout = std::make_shared<xacc::quantum::ReadoutErrorIRPreprocessor>();
context.RegisterService<xacc::Preprocessor>(kp);
context.RegisterService<xacc::IRGenerator>(iqft);
context.RegisterService<xacc::IRGenerator>(qft);
context.RegisterService<xacc::IRPreprocessor>(readout);
}
/**
......
# *******************************************************************************
# Copyright (c) 2017 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 v.10 which accompany 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
# *******************************************************************************/
# Gather tests
file (GLOB test_files tests/*.cpp)
add_tests("${test_files}" "${CMAKE_CURRENT_SOURCE_DIR}" "${Boost_LIBRARIES};xacc-quantum-gate;xacc")
......@@ -35,7 +35,7 @@ public:
}
};
class ReadoutErrorAcceleratorBufferPostprocessor : public AcceleratorBufferPostprocessor {
class ReadoutErrorAcceleratorBufferPostprocessor: public AcceleratorBufferPostprocessor {
protected:
......@@ -46,11 +46,11 @@ protected:
double exptZ(double E_Z, double p01, double p10) {
auto p_p = p01 + p10;
auto p_m = p01 - p10;
return (E_Z-p_m)/(1.0 - p_p);
return (E_Z - p_m) / (1.0 - p_p);
}
double exptZZ(double E_ZZ, double E_ZI, double E_IZ, double ap01, double ap10,
double bp01, double bp10, bool averaged = false);
double exptZZ(double E_ZZ, double E_ZI, double E_IZ, double ap01,
double ap10, double bp01, double bp10, bool averaged = false);
std::map<std::string, double> fix_assignments(
std::map<std::string, double> oldExpects,
......@@ -61,11 +61,11 @@ public:
ReadoutErrorAcceleratorBufferPostprocessor(IR& i,
std::map<std::string, std::vector<int>> sitesMap,
std::vector<std::string> orderedTerms) :
ir(i), sites(sitesMap), allTerms(
orderedTerms) {
ir(i), sites(sitesMap), allTerms(orderedTerms) {
}
virtual std::vector<std::shared_ptr<AcceleratorBuffer>> process(std::vector<std::shared_ptr<AcceleratorBuffer>> buffers);
virtual std::vector<std::shared_ptr<AcceleratorBuffer>> process(
std::vector<std::shared_ptr<AcceleratorBuffer>> buffers);
};
}
}
......
/*******************************************************************************
* Copyright (c) 2017 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
*******************************************************************************/
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE ReadoutErrorAcceleratorBufferPostprocessorTester
#include <boost/test/included/unit_test.hpp>
#include "ReadoutErrorAcceleratorBufferPostprocessor.hpp"
#include "GateQIR.hpp"
#include <boost/math/constants/constants.hpp>
#include "XACC.hpp"
#include "GateFunction.hpp"
#include "GateInstruction.hpp"
using namespace xacc;
using namespace xacc::quantum;
using Term = std::map<int, std::string>;
std::shared_ptr<IR> createXACCIR(std::unordered_map<std::string, Term> terms) {
// Create a new GateQIR to hold the spin based terms
auto newIr = std::make_shared<xacc::quantum::GateQIR>();
int counter = 0;
auto pi = boost::math::constants::pi<double>();
// Populate GateQIR now...
for (auto& inst : terms) {
Term spinInst = inst.second;
// Create a GateFunction and specify that it has
// a parameter that is the Spin Instruction coefficient
// that will help us get it to the user for their purposes.
auto gateFunction = std::make_shared<xacc::quantum::GateFunction>(
"term" + std::to_string(counter));
// Loop over all terms in the Spin Instruction
// and create instructions to run on the Gate QPU.
std::vector<std::shared_ptr<xacc::quantum::GateInstruction>> measurements;
std::vector<std::pair<int, std::string>> terms;
for (auto& kv : spinInst) {
if (kv.second != "I" && !kv.second.empty()) {
terms.push_back( { kv.first, kv.second });
}
}
for (int i = terms.size() - 1; i >= 0; i--) {
auto qbit = terms[i].first;
auto gateName = terms[i].second;
auto gateRegistry =
xacc::quantum::GateInstructionRegistry::instance();
auto meas = gateRegistry->create("Measure",
std::vector<int> { qbit });
xacc::InstructionParameter classicalIdx(qbit);
meas->setParameter(0, classicalIdx);
measurements.push_back(meas);
if (gateName == "X") {
auto hadamard = gateRegistry->create("H", std::vector<int> {
qbit });
gateFunction->addInstruction(hadamard);
} else if (gateName == "Y") {
auto rx = gateRegistry->create("Rx", std::vector<int> { qbit });
InstructionParameter p(pi / 2.0);
rx->setParameter(0, p);
gateFunction->addInstruction(rx);
}
}
for (auto m : measurements) {
gateFunction->addInstruction(m);
}
newIr->addKernel(gateFunction);
counter++;
}
return newIr;
}
class FakeTermAB : public AcceleratorBuffer {
public:
FakeTermAB(const std::string& str, const int N) : AcceleratorBuffer(str, N) {}
virtual const double getExpectationValueZ() {
return .88;
}
};
class FakeMeasureAB : public AcceleratorBuffer {
public:
FakeMeasureAB(const std::string& str, const int N) : AcceleratorBuffer(str, N) {}
virtual double computeMeasurementProbability(const std::string& bitStr) {
if (bitStr == "1") {
return .08;
} else {
return .02;
}
}
};
BOOST_AUTO_TEST_CASE(checkSimple) {
// Simple example H = X0
std::vector<std::string> orderedTerms{"Z0"};
auto gateRegistry = GateInstructionRegistry::instance();
// Construct IR for this
auto ir = createXACCIR( { { "Z0", Term { { 0, "Z" } } } });
auto f01 = std::make_shared<GateFunction>("measure0_qubit_0",
"readout-error");
auto meas01 = gateRegistry->create("Measure", std::vector<int> { 0 });
InstructionParameter p(0);
meas01->setParameter(0, p);
f01->addInstruction(meas01);
auto f10 = std::make_shared<GateFunction>("measure1_qubit_0",
"readout-error");
auto x = gateRegistry->create("X", std::vector<int> { 0 });
auto meas10 = gateRegistry->create("Measure", std::vector<int> { 0 });
InstructionParameter p2(0);
meas10->setParameter(0, p2);
f10->addInstruction(x);
f10->addInstruction(meas01);
ir->addKernel(f10);
ir->addKernel(f01);
std::cout << "IR: " << ir->getKernels().size() << "\n";
// Construct sites map
std::map<std::string, std::vector<int>> sites{{"Z0",{0}}};
auto buff = std::make_shared<FakeTermAB>("buff", 1);
auto mb1 = std::make_shared<FakeMeasureAB>("m1", 1);
auto mb2 = std::make_shared<FakeMeasureAB>("m2", 1);
std::vector<std::shared_ptr<AcceleratorBuffer>> buffers {buff, mb1, mb2};
ReadoutErrorAcceleratorBufferPostprocessor processor(*ir, sites, orderedTerms);
auto fixed = processor.process(buffers);
std::cout << "HELLO: " << fixed[0]->getExpectationValueZ() << "\n";
BOOST_VERIFY(std::fabs(fixed[0]->getExpectationValueZ() - .911111) < 1e-6);
}
......@@ -109,7 +109,6 @@ std::shared_ptr<AcceleratorBufferPostprocessor> ReadoutErrorIRPreprocessor::proc
for (auto o : extraKernelsNeeded) {
std::cout << "EXTRA: " << o << "\n";
int nKernels = ir.getKernels().size();
auto extraKernel = std::make_shared<GateFunction>(o, "readout-error-extra");
std::stringstream sg, sb;
......@@ -142,7 +141,6 @@ std::shared_ptr<AcceleratorBufferPostprocessor> ReadoutErrorIRPreprocessor::proc
int qbit = 0;
for (int i = 0; i < 2*nQubits; i+=2) {
int nKernels = ir.getKernels().size();
auto f01 = std::make_shared<GateFunction>(
"measure0_qubit_" + std::to_string(qbit), "readout-error");
auto meas01 = gateRegistry->create("Measure", std::vector<int>{qbit});
......
......@@ -107,7 +107,7 @@ public:
return;
}
double computeMeasurementProbability(const std::string& bitStr) {
virtual double computeMeasurementProbability(const std::string& bitStr) {
return (double) bitStringToCounts[bitStr] / (double)measurements.size();
}
......
......@@ -14,6 +14,7 @@
#define XACC_PROGRAM_KERNEL_HPP_
#include "Function.hpp"
#include "AcceleratorBufferPostprocessor.hpp"
namespace xacc {
......@@ -152,6 +153,7 @@ protected:
* The Accelerator to execute this Kernel on
*/
std::shared_ptr<Accelerator> accelerator;
std::vector<std::shared_ptr<AcceleratorBufferPostprocessor>> bufferPostprocessors;
public:
......@@ -161,6 +163,11 @@ public:
*/
KernelList(std::shared_ptr<Accelerator> acc) : accelerator(acc) {}
KernelList(std::shared_ptr<Accelerator> acc,
std::vector<std::shared_ptr<AcceleratorBufferPostprocessor>> postprocessors) :
accelerator(acc), bufferPostprocessors(postprocessors) {
}
/**
* Return the Accelerator this KernelList delegates to.
*/
......@@ -191,7 +198,15 @@ public:
}
}
return accelerator->execute(buffer, functions);
auto buffers = accelerator->execute(buffer, functions);
if (!bufferPostprocessors.empty()) {
for (auto p : bufferPostprocessors) {
buffers = p->process(buffers);
}
}
return buffers;
}
/**
......@@ -207,7 +222,15 @@ public:
functions.push_back(k.getIRFunction());
}
return accelerator->execute(buffer, functions);
auto buffers = accelerator->execute(buffer, functions);
if (!bufferPostprocessors.empty()) {
for (auto p : bufferPostprocessors) {
buffers = p->process(buffers);
}
}
return buffers;
}
std::vector<std::shared_ptr<AcceleratorBuffer>> execute(
......@@ -216,7 +239,16 @@ public:
for (auto k : *this) {
functions.push_back(k.getIRFunction());
}
return accelerator->execute(buffer, functions);
auto buffers = accelerator->execute(buffer, functions);
if (!bufferPostprocessors.empty()) {
for (auto p : bufferPostprocessors) {
buffers = p->process(buffers);
}
}
return buffers;
}
};
......
......@@ -77,6 +77,10 @@ void Program::build() {
xaccIR = t->transform(xaccIR);
}
for (auto irp : irpreprocessors) {
bufferPostprocessors.push_back(irp->process(*xaccIR));
}
// Write the IR to file if the user requests it
if (runtimeOptions->exists("persist-ir")) {
auto fileStr = (*runtimeOptions)["persist-ir"];
......
......@@ -28,6 +28,8 @@
#include "Preprocessor.hpp"
#include "ServiceRegistry.hpp"
#include "Kernel.hpp"
#include "IRPreprocessor.hpp"
#include "AcceleratorBufferPostprocessor.hpp"
namespace xacc {
......@@ -82,6 +84,8 @@ protected:
* to be run before Compiler execution.
*/
std::vector<std::shared_ptr<Preprocessor>> preprocessors;
std::vector<std::shared_ptr<IRPreprocessor>> irpreprocessors;
std::vector<std::shared_ptr<AcceleratorBufferPostprocessor>> bufferPostprocessors;
public:
......@@ -122,6 +126,15 @@ public:
}
}
void addIRPreprocessor(const std::string& name) {
if (ServiceRegistry::instance()->hasService<IRPreprocessor>(
name)) {
auto p = ServiceRegistry::instance()->getService<
IRPreprocessor>(name);
irpreprocessors.push_back(p);
}
}
/**
* Execute the compilation mechanism on the provided program
* source kernel code to produce XACC IR that can be executed
......@@ -166,7 +179,7 @@ public:
*/
template<typename ... RuntimeArgs>
auto getKernels() -> KernelList<RuntimeArgs...> {
KernelList<RuntimeArgs...> kernels(accelerator);
KernelList<RuntimeArgs...> kernels(accelerator, bufferPostprocessors);
if (!xaccIR) {
build();
}
......@@ -208,7 +221,7 @@ public:
* as InstructionParameters.
*/
auto getRuntimeKernels() -> KernelList<> {
KernelList<> kernels(accelerator);
KernelList<> kernels(accelerator, bufferPostprocessors);
if (!xaccIR) {
build();
}
......
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