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

Updating to c++17, heterogeneousmap now uses std::any internally. updated xacc...


Updating to c++17, heterogeneousmap now uses std::any internally. updated xacc internal compiler api to work with shared_ptrs.
Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent e33afcda
......@@ -95,7 +95,7 @@ std::shared_ptr<Graph> AnnealingProgram::toGraph() {
auto bits = inst->bits();
if (bits[0] == bits[1]) {
auto p = inst->getParameter(0);
graph->getVertexProperties(bits[0]).get_mutable<double>("bias") = xacc::InstructionParameterToDouble(p);//p.as<double>();
graph->getVertexProperties(bits[0]).insert("bias", xacc::InstructionParameterToDouble(p));//p.as<double>();
} else {
graph->addEdge(bits[0], bits[1], xacc::InstructionParameterToDouble(inst->getParameter(0)));
}
......
......@@ -278,13 +278,13 @@ TEST(GateTester, checkGenerateGraph) {
std::string expected = R"expected(digraph G {
node [shape=box style=filled]
0 [label="id=0;name=InitialState;bits=[0,1,2]"];
1 [label="id=1;name=H;bits=[1]"];
2 [label="id=2;name=CNOT;bits=[1,2]"];
3 [label="id=3;name=CNOT;bits=[0,1]"];
4 [label="id=4;name=H;bits=[0]"];
5 [label="id=5;name=Rz;bits=[2]"];
6 [label="id=6;name=FinalState;bits=[0,1,2]"];
0 [label="bits=[0,1,2];id=0;name=InitialState"];
1 [label="bits=[1];id=1;name=H"];
2 [label="bits=[1,2];id=2;name=CNOT"];
3 [label="bits=[0,1];id=3;name=CNOT"];
4 [label="bits=[0];id=4;name=H"];
5 [label="bits=[2];id=5;name=Rz"];
6 [label="bits=[0,1,2];id=6;name=FinalState"];
0->1 ;
0->2 ;
0->3 ;
......
......@@ -185,7 +185,7 @@ PauliOperator::observe(std::shared_ptr<CompositeInstruction> function) {
auto gateRegistry = xacc::getService<IRProvider>("quantum");
std::vector<std::shared_ptr<CompositeInstruction>> observed;
int counter = 0;
auto pi = 3.141592653589793238;
auto pi = xacc::constants::pi;
// Populate GateQIR now...
for (auto &inst : terms) {
......@@ -737,7 +737,6 @@ void PauliOperator::fromXACCIR(std::shared_ptr<IR> ir) {
std::map<int, std::string> pauliTerm;
for (auto inst : kernel->getInstructions()) {
bool seen = false;
if (!inst->isComposite()) {
if (inst->name() == "H") {
......
......@@ -342,7 +342,7 @@ public:
};
} // namespace quantum
template const quantum::PauliOperator &
template const quantum::PauliOperator
HeterogeneousMap::get<quantum::PauliOperator>(const std::string key) const;
} // namespace xacc
......
......@@ -26,19 +26,18 @@ bool VQE::initialize(const HeterogeneousMap &parameters) {
if (!parameters.pointerLikeExists<Observable>("observable")) {
std::cout << "Obs was false\n";
return false;
} else if (!parameters.pointerLikeExists<CompositeInstruction>(
"ansatz")) {
} else if (!parameters.pointerLikeExists<CompositeInstruction>("ansatz")) {
std::cout << "Ansatz was false\n";
return false;
} else if (!parameters.pointerLikeExists<Accelerator>(
"accelerator")) {
} else if (!parameters.pointerLikeExists<Accelerator>("accelerator")) {
std::cout << "Acc was false\n";
return false;
}
observable = parameters.getPointerLike<Observable>("observable");
optimizer = parameters.getPointerLike<Optimizer>("optimizer");
if (parameters.pointerLikeExists<Optimizer>("optimizer")) {
optimizer = parameters.getPointerLike<Optimizer>("optimizer");
}
accelerator = parameters.getPointerLike<Accelerator>("accelerator");
kernel = parameters.getPointerLike<CompositeInstruction>("ansatz");
......@@ -51,6 +50,11 @@ const std::vector<std::string> VQE::requiredParameters() const {
void VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer) const {
if (!optimizer) {
xacc::error("VQE Algorithm Error - Optimizer was null. Please provide a "
"valid Optimizer.");
}
auto kernels = observable->observe(xacc::as_shared_ptr(kernel));
// Here we just need to make a lambda kernel
......@@ -95,7 +99,7 @@ void VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer) const {
idBuffer->addExtraInfo("parameters", x);
idBuffer->addExtraInfo("exp-val-z", 1.0);
if (accelerator->name() == "ro-error")
idBuffer->addExtraInfo("ro-fixed-exp-val-z", 1.0);
idBuffer->addExtraInfo("ro-fixed-exp-val-z", 1.0);
buffer->appendChild("I", idBuffer);
if (buffers[0]->hasExtraInfoKey(
......@@ -118,7 +122,7 @@ void VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer) const {
}
std::stringstream ss;
ss << "E(" << ( !x.empty() ? std::to_string(x[0]) : "");
ss << "E(" << (!x.empty() ? std::to_string(x[0]) : "");
for (int i = 1; i < x.size(); i++)
ss << "," << x[i];
ss << ") = " << std::setprecision(12) << energy;
......@@ -137,6 +141,7 @@ void VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer) const {
std::vector<double>
VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer,
const std::vector<double> &x) {
auto kernels = observable->observe(xacc::as_shared_ptr(kernel));
std::vector<double> coefficients;
std::vector<std::string> kernelNames;
......@@ -198,7 +203,7 @@ VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer,
std::stringstream ss;
ss << "E(" << ( !x.empty() ? std::to_string(x[0]) : "");
ss << "E(" << (!x.empty() ? std::to_string(x[0]) : "");
for (int i = 1; i < x.size(); i++)
ss << "," << x[i];
ss << ") = " << std::setprecision(12) << energy;
......
......@@ -589,9 +589,9 @@ void XASMListener::enterOptionsType(xasmParser::OptionsTypeContext *ctx) {
if (currentOptions.stringExists(key)) {
bool isConstChar = currentOptions.keyExists<const char *>(key);
if (isConstChar) {
currentOptions.get_mutable<const char *>(key) = valStr.c_str();
currentOptions.insert(key, valStr.c_str());
} else {
currentOptions.get_mutable<std::string>(key) = valStr;
currentOptions.insert(key,valStr);
}
} else {
......
......@@ -102,7 +102,7 @@ endif()
target_compile_features(xacc
PUBLIC
cxx_std_14
cxx_std_17
cxx_alias_templates)
if(APPLE)
set_target_properties(xacc PROPERTIES INSTALL_RPATH "@loader_path")
......
......@@ -9,8 +9,8 @@
namespace xacc {
namespace internal_compiler {
Accelerator *qpu = nullptr;
CompositeInstruction *lastCompiled = nullptr;
std::shared_ptr<Accelerator> qpu = nullptr;
std::shared_ptr<CompositeInstruction> lastCompiled = nullptr;
bool __execute = true;
std::vector<HeterogeneousMap> current_runtime_arguments = {};
......@@ -19,11 +19,9 @@ void compiler_InitializeXACC(const char *qpu_backend) {
if (!xacc::isInitialized()) {
xacc::Initialize();
xacc::external::load_external_language_plugins();
auto at_exit = []() {
xacc::Finalize();
};
auto at_exit = []() { xacc::Finalize(); };
atexit(at_exit);
}
}
setAccelerator(qpu_backend);
}
......@@ -31,9 +29,7 @@ void compiler_InitializeXACC(const char *qpu_backend, int shots) {
if (!xacc::isInitialized()) {
xacc::Initialize();
xacc::external::load_external_language_plugins();
auto at_exit = []() {
xacc::Finalize();
};
auto at_exit = []() { xacc::Finalize(); };
atexit(at_exit);
}
......@@ -43,62 +39,53 @@ void compiler_InitializeXACC(const char *qpu_backend, int shots) {
void setAccelerator(const char *qpu_backend) {
if (qpu) {
if (qpu_backend != qpu->name()) {
qpu = xacc::getAccelerator(qpu_backend).get();
qpu = xacc::getAccelerator(qpu_backend);
}
} else {
qpu = xacc::getAccelerator(qpu_backend).get();
qpu = xacc::getAccelerator(qpu_backend);
}
}
void setAccelerator(const char *qpu_backend, int shots) {
if (qpu) {
if (qpu_backend != qpu->name()) {
qpu = xacc::getAccelerator(qpu_backend, {std::make_pair("shots", shots)})
.get();
qpu = xacc::getAccelerator(qpu_backend, {std::make_pair("shots", shots)});
}
} else {
qpu = xacc::getAccelerator(qpu_backend, {std::make_pair("shots", shots)})
.get();
qpu = xacc::getAccelerator(qpu_backend, {std::make_pair("shots", shots)});
}
}
Accelerator *get_qpu() { return qpu; }
std::shared_ptr<Accelerator> get_qpu() { return qpu; }
CompositeInstruction *getLastCompiled() { return lastCompiled; }
std::shared_ptr<CompositeInstruction> getLastCompiled() { return lastCompiled; }
// Map kernel source string representing a single
// kernel function to a single CompositeInstruction (src to IR)
CompositeInstruction *compile(const char *compiler_name,
const char *kernel_src) {
auto qpu_as_shared =
std::shared_ptr<Accelerator>(qpu, xacc::empty_delete<Accelerator>());
std::shared_ptr<CompositeInstruction> compile(const char *compiler_name,
const char *kernel_src) {
auto compiler = xacc::getCompiler(compiler_name);
auto IR = compiler->compile(kernel_src, qpu_as_shared);
auto IR = compiler->compile(kernel_src, qpu);
auto program = IR->getComposites()[0];
lastCompiled = program.get();
return program.get();
lastCompiled = program;
return program;
}
CompositeInstruction *getCompiled(const char *kernel_name) {
return xacc::hasCompiled(kernel_name) ? xacc::getCompiled(kernel_name).get()
std::shared_ptr<CompositeInstruction> getCompiled(const char *kernel_name) {
return xacc::hasCompiled(kernel_name) ? xacc::getCompiled(kernel_name)
: nullptr;
}
// Run quantum compilation routines on IR
void optimize(CompositeInstruction *program, const OptLevel opt) {
void optimize(std::shared_ptr<CompositeInstruction> program,
const OptLevel opt) {
xacc::info("[InternalCompiler] Pre-optimization, circuit has " +
std::to_string(program->nInstructions()) + " instructions.");
// We don't own this ptr, so create shared_ptr with empty deleter
auto as_shared = std::shared_ptr<CompositeInstruction>(
program, xacc::empty_delete<CompositeInstruction>());
auto qpu_as_shared =
std::shared_ptr<Accelerator>(qpu, xacc::empty_delete<Accelerator>());
if (opt == DEFAULT) {
auto optimizer = xacc::getIRTransformation("circuit-optimizer");
optimizer->apply(as_shared, qpu_as_shared);
optimizer->apply(program, qpu);
} else {
xacc::error("Other Optimization Levels not yet supported.");
}
......@@ -108,41 +95,31 @@ void optimize(CompositeInstruction *program, const OptLevel opt) {
}
void execute(AcceleratorBuffer *buffer,
std::vector<CompositeInstruction *> programs) {
std::vector<std::shared_ptr<CompositeInstruction>> ps_vec;
for (auto &p : programs) {
if (p->name() != "I") {
ps_vec.push_back(xacc::as_shared_ptr(p));
}
}
std::vector<std::shared_ptr<CompositeInstruction>> programs) {
qpu->execute(xacc::as_shared_ptr(buffer), ps_vec);
qpu->execute(xacc::as_shared_ptr(buffer), programs);
}
// Execute on the specified QPU, persisting results to
// the provided buffer.
void execute(AcceleratorBuffer *buffer, CompositeInstruction *program,
void execute(AcceleratorBuffer *buffer,
std::shared_ptr<CompositeInstruction> program,
double *parameters) {
std::shared_ptr<CompositeInstruction> program_as_shared;
if (parameters) {
std::vector<double> values(parameters, parameters + program->nVariables());
program_as_shared = program->operator()(values);
} else {
// We don't own this ptr, so create shared_ptr with empty deleter
program_as_shared = std::shared_ptr<CompositeInstruction>(
program, xacc::empty_delete<CompositeInstruction>());
program = program->operator()(values);
}
auto buffer_as_shared = std::shared_ptr<AcceleratorBuffer>(
buffer, xacc::empty_delete<AcceleratorBuffer>());
qpu->execute(buffer_as_shared, program_as_shared);
qpu->execute(buffer_as_shared, program);
}
void execute(AcceleratorBuffer **buffers, const int nBuffers,
CompositeInstruction *program, double *parameters) {
std::shared_ptr<CompositeInstruction> program,
double *parameters) {
// Should take vector of buffers, and we collapse them
// into a single unified buffer for execution, then set the
......@@ -153,14 +130,10 @@ void execute(AcceleratorBuffer **buffers, const int nBuffers,
for (auto &a : bvec)
buffer_names.push_back(a->name());
// We don't own this ptr, so create shared_ptr with empty deleter
auto program_as_shared = std::shared_ptr<CompositeInstruction>(
program, xacc::empty_delete<CompositeInstruction>());
// Do we have any unknown ancilla bits?
std::vector<std::string> possible_extra_buffers;
int possible_size = -1;
InstructionIterator it(program_as_shared);
InstructionIterator it(program);
while (it.hasNext()) {
auto &next = *it.next();
auto bnames = next.getBufferNames();
......@@ -176,7 +149,7 @@ void execute(AcceleratorBuffer **buffers, const int nBuffers,
for (auto &possible_buffer : possible_extra_buffers) {
std::set<std::size_t> sizes;
InstructionIterator it2(program_as_shared);
InstructionIterator it2(program);
while (it2.hasNext()) {
auto &next = *it2.next();
for (auto &bit : next.bits()) {
......@@ -216,7 +189,7 @@ void execute(AcceleratorBuffer **buffers, const int nBuffers,
// Update Program bit indices based on new global
// qubit register
InstructionIterator iter(program_as_shared);
InstructionIterator iter(program);
while (iter.hasNext()) {
auto &next = *iter.next();
std::vector<std::size_t> newBits;
......@@ -237,7 +210,7 @@ void execute(AcceleratorBuffer **buffers, const int nBuffers,
}
std::vector<std::size_t> measure_idxs;
InstructionIterator iter2(program_as_shared);
InstructionIterator iter2(program);
while (iter2.hasNext()) {
auto &next = *iter2.next();
if (next.name() == "Measure") {
......
......@@ -14,6 +14,7 @@
#define XACC_XACC_INTERNAL_COMPILER_HPP_
#include <vector>
#include <memory>
namespace xacc {
class CompositeInstruction;
......@@ -21,8 +22,8 @@ class AcceleratorBuffer;
class Accelerator;
namespace internal_compiler {
extern Accelerator *qpu;
extern CompositeInstruction *lastCompiled;
extern std::shared_ptr<Accelerator> qpu;
extern std::shared_ptr<CompositeInstruction> lastCompiled;
extern bool __execute;
enum OptLevel { DEFAULT, LEVEL1, LEVEL2, LEVEL3 };
......@@ -32,28 +33,28 @@ void compiler_InitializeXACC(const char *qpu_backend, int shots);
void setAccelerator(const char *qpu_backend);
void setAccelerator(const char *qpu_backend, int shots);
Accelerator *get_qpu();
std::shared_ptr<Accelerator> get_qpu();
void __set_verbose(bool verbose);
// Map kernel source string representing a single
// kernel function to a single CompositeInstruction (src to IR)
CompositeInstruction *compile(const char *compiler_name,
std::shared_ptr<CompositeInstruction> compile(const char *compiler_name,
const char *kernel_src);
CompositeInstruction *getLastCompiled();
CompositeInstruction *getCompiled(const char *kernel_name);
std::shared_ptr<CompositeInstruction> getLastCompiled();
std::shared_ptr<CompositeInstruction> getCompiled(const char *kernel_name);
// Run quantum compilation routines on IR
void optimize(CompositeInstruction *program, const OptLevel opt = DEFAULT);
void optimize(std::shared_ptr<CompositeInstruction> program, const OptLevel opt = DEFAULT);
// Execute on the specified QPU, persisting results to
// the provided buffer.
void execute(AcceleratorBuffer *buffer, std::vector<CompositeInstruction*> programs);
void execute(AcceleratorBuffer *buffer, CompositeInstruction *program,
void execute(AcceleratorBuffer *buffer, std::vector<std::shared_ptr<CompositeInstruction>> programs);
void execute(AcceleratorBuffer *buffer, std::shared_ptr<CompositeInstruction> program,
double *parameters = nullptr);
void execute(AcceleratorBuffer **buffers, const int nBuffers,
CompositeInstruction *program, double *parameters = nullptr);
std::shared_ptr<CompositeInstruction> program, double *parameters = nullptr);
} // namespace internal_compiler
} // namespace xacc
......
......@@ -79,14 +79,14 @@ protected:
// Take the concrete value and set it on the
// correct argument.
template <typename T> void updateArgs(T &value) {
if (arguments[_internal_counter]->runtimeValue.keyExists<T>(
INTERNAL_ARGUMENT_VALUE_KEY)) {
arguments[_internal_counter]->runtimeValue.get_mutable<T>(
INTERNAL_ARGUMENT_VALUE_KEY) = value;
} else {
// if (arguments[_internal_counter]->runtimeValue.keyExists<T>(
// INTERNAL_ARGUMENT_VALUE_KEY)) {
// arguments[_internal_counter]->runtimeValue.get_mutable<T>(
// INTERNAL_ARGUMENT_VALUE_KEY) = value;
// } else {
arguments[_internal_counter]->runtimeValue.insert(
INTERNAL_ARGUMENT_VALUE_KEY, value);
}
// }
_internal_counter++;
}
......
......@@ -52,10 +52,10 @@ TEST(DirectedGraphTester, checkConstruction) {
EXPECT_EQ(0.0 , graph.getVertexProperties(0).get<double>("bias"));
EXPECT_EQ(0.0 , graph.getVertexProperties(1).get<double>("bias"));
graph.getVertexProperties(0).get_mutable<double>("bias") = 3.3;
graph.getVertexProperties(0).insert("bias",3.3);
EXPECT_EQ(3.3, graph.getVertexProperties(0).get<double>("bias"));
graph.getVertexProperties(1).get_mutable<double>("bias") = 33.3;
graph.getVertexProperties(1).insert("bias", 33.3);
EXPECT_EQ(33.3 , graph.getVertexProperties(1).get<double>("bias"));
auto n = graph.getNeighborList(0);
......
......@@ -51,9 +51,9 @@ TEST(UndirectedGraphTester, checkConstruction) {
// Verify that we can set vertex bias values
EXPECT_EQ(0.0 , graph.getVertexProperties(0).get<double>("bias"));//.as<double>());
EXPECT_EQ(0.0 , graph.getVertexProperties(1).get<double>( "bias"));//as<double>());
graph.getVertexProperties(0).get_mutable<double>("bias") = 3.3;
graph.getVertexProperties(0).insert("bias", 3.3);
EXPECT_EQ(3.3 , graph.getVertexProperties(0).get<double>("bias"));//.as<double>());
graph.getVertexProperties(1).get_mutable<double>("bias") = 33.3;
graph.getVertexProperties(1).insert("bias", 33.3);
EXPECT_EQ(33.3 , graph.getVertexProperties(1).get<double>("bias"));
// graph.setVertexProperty(1, "bias", 33.3);
// EXPECT_EQ(33.3 , graph.getVertexProperty(1, "bias").as<double>());
......
......@@ -10,6 +10,7 @@
* Contributors:
* Alexander J. McCaskey - initial API and implementation
*******************************************************************************/
#include "CompositeInstruction.hpp"
#include "heterogeneous.hpp"
#include <gtest/gtest.h>
#include <stdexcept>
......@@ -17,11 +18,10 @@
#include "Algorithm.hpp"
#include "xacc_service.hpp"
class print_visitor : public xacc::visitor_base<int,double> {
class print_visitor : public xacc::visitor_base<int, double> {
public:
template<typename T>
void operator()(const std::string& s, const T& t) {
std::cout << s<< ": "<< t << "\n";
template <typename T> void operator()(const std::string &s, const T &t) {
std::cout << s << ": " << t << "\n";
}
};
......@@ -75,37 +75,46 @@ TEST(HeterogeneousMapTester, checkSimple) {
xacc::HeterogeneousMap cc;
EXPECT_ANY_THROW(cc.get_with_throw<int>("intkey"));
EXPECT_EQ("f",
m3.getPointerLike<xacc::CompositeInstruction>("function")->name());
EXPECT_TRUE(m3.pointerLikeExists<xacc::CompositeInstruction>("function"));
m3.insert("doublekey", 222.222);
EXPECT_EQ(222.222, m3.get<double>("doublekey"));
xacc::HeterogeneousMap m4({std::pair<std::string, double>{"doublekey", 2.0},
std::pair<std::string, int>{"intkey", 22}});
m4.print<int, double>(std::cout);
}
TEST(HeterogeneousMapTester, checkVQE) {
using namespace xacc;
class TestObservable : public xacc::Observable {
public:
std::vector<std::shared_ptr<CompositeInstruction>>
observe(std::shared_ptr<CompositeInstruction> CompositeInstruction) override {
return {};
}
const std::string toString() override { return ""; }
void fromString(const std::string str) override {}
const int nBits() override { return 0; }
const std::string name() const override { return "test"; }
const std::string description() const override { return ""; }
void fromOptions(const HeterogeneousMap& options) override {}
};
std::shared_ptr<Observable> observable = std::make_shared<TestObservable>();
xacc::HeterogeneousMap options;
using namespace xacc;
class TestObservable : public xacc::Observable {
public:
std::vector<std::shared_ptr<CompositeInstruction>> observe(
std::shared_ptr<CompositeInstruction> CompositeInstruction) override {
return {};
}
const std::string toString() override { return ""; }
void fromString(const std::string str) override {}
const int nBits() override { return 0; }
const std::string name() const override { return "test"; }
const std::string description() const override { return ""; }
void fromOptions(const HeterogeneousMap &options) override {}
};
std::shared_ptr<Observable> observable = std::make_shared<TestObservable>();
xacc::HeterogeneousMap options;
auto provider = xacc::getIRProvider("quantum");
auto function = provider->createComposite("f", {});
options.insert("observable", observable);
options.insert("ansatz", function);
auto vqe = xacc::getService<Algorithm>("vqe");
options.insert("observable", observable);
options.insert("ansatz", function);
auto vqe = xacc::getService<Algorithm>("vqe");
vqe->initialize(options);
vqe->initialize(options);
}
int main(int argc, char **argv) {
xacc::Initialize();
......
......@@ -21,10 +21,12 @@
#include <iostream>
#include <experimental/type_traits>
// mpark variant
#include "variant.hpp"
#include "Utils.hpp"
#include <complex>
#include <any>
namespace xacc {
......@@ -48,12 +50,7 @@ public:
HeterogeneousMap &operator=(const HeterogeneousMap &_other) {
clear();
clear_functions = _other.clear_functions;
copy_functions = _other.copy_functions;
size_functions = _other.size_functions;
for (auto &&copy_function : copy_functions) {
copy_function(_other, *this);
}
items = _other.items;
return *this;
}
......@@ -80,45 +77,25 @@ public:
}
template <class T> void insert(const std::string key, const T &_t) {
// don't have it yet, so create functions for printing, copying, moving, and
// destroying
if (items<T>.find(this) == std::end(items<T>)) {
clear_functions.emplace_back(
[](HeterogeneousMap &_c) { items<T>.erase(&_c); });
// if someone copies me, they need to call each copy_function and pass
// themself
copy_functions.emplace_back(