Commit 60596c31 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

adding setBitMap to Function, updates to get qcor working with qcs


Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent c78d130d
Pipeline #59215 passed with stages
in 10 minutes and 53 seconds
...@@ -75,6 +75,9 @@ public: ...@@ -75,6 +75,9 @@ public:
return i; return i;
} }
void setBitMap(const std::vector<int> bMap) override {}
const std::vector<int> getBitMap() override {return std::vector<int>{};}
std::list<InstPtr> getInstructions() override { return instructions; } std::list<InstPtr> getInstructions() override { return instructions; }
void removeInstruction(const int idx) override { void removeInstruction(const int idx) override {
......
...@@ -25,6 +25,7 @@ void GateFunction::mapBits(std::vector<int> bitMap) { ...@@ -25,6 +25,7 @@ void GateFunction::mapBits(std::vector<int> bitMap) {
for (auto i : instructions) { for (auto i : instructions) {
i->mapBits(bitMap); i->mapBits(bitMap);
} }
setBitMap(bitMap);
} }
void GateFunction::persist(std::ostream &outStream) { void GateFunction::persist(std::ostream &outStream) {
...@@ -74,6 +75,16 @@ void GateFunction::load(std::istream &inStream) { ...@@ -74,6 +75,16 @@ void GateFunction::load(std::istream &inStream) {
auto &kernel = doc["kernels"].GetArray()[0]; auto &kernel = doc["kernels"].GetArray()[0];
functionName = kernel["function"].GetString(); functionName = kernel["function"].GetString();
if (kernel.HasMember("bitmap")) {
auto bitMapArr = kernel["bitmap"].GetArray();
std::vector<int> bitMap;
for (int i = 0; i < bitMapArr.Size(); i++) {
bitMap.push_back(bitMapArr[i].GetInt());
}
setBitMap(bitMap);
}
auto instructionsArray = kernel["instructions"].GetArray(); auto instructionsArray = kernel["instructions"].GetArray();
for (int i = 0; i < instructionsArray.Size(); i++) { for (int i = 0; i < instructionsArray.Size(); i++) {
......
...@@ -72,6 +72,10 @@ public: ...@@ -72,6 +72,10 @@ public:
return 0; return 0;
} }
void setBitMap(const std::vector<int> bMap) override {bitMap = bMap;}
const std::vector<int> getBitMap() override {return bitMap;}
bool hasBeenBitMapped() override {return !bitMap.empty();}
void persist(std::ostream &outStream) override; void persist(std::ostream &outStream) override;
void load(std::istream &inStream) override; void load(std::istream &inStream) override;
...@@ -257,6 +261,9 @@ protected: ...@@ -257,6 +261,9 @@ protected:
std::string tag = ""; std::string tag = "";
std::map<std::string, InstructionParameter> options; std::map<std::string, InstructionParameter> options;
std::vector<int> bitMap;
}; };
} // namespace quantum } // namespace quantum
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
namespace xacc { namespace xacc {
namespace quantum { namespace quantum {
class ConditionalFunction : public virtual GateFunction { class ConditionalFunction : public GateFunction {
protected: protected:
int qbitIdx; int qbitIdx;
......
...@@ -125,17 +125,26 @@ PauliOperator::observe(std::shared_ptr<Function> function) { ...@@ -125,17 +125,26 @@ PauliOperator::observe(std::shared_ptr<Function> function) {
if (gateName == "X") { if (gateName == "X") {
auto hadamard = auto hadamard =
gateRegistry->createInstruction("H", std::vector<int>{qbit}); gateRegistry->createInstruction("H", std::vector<int>{qbit});
if (function->hasBeenBitMapped()) {
hadamard->mapBits(function->getBitMap());
}
gateFunction->addInstruction(hadamard); gateFunction->addInstruction(hadamard);
} else if (gateName == "Y") { } else if (gateName == "Y") {
auto rx = gateRegistry->createInstruction("Rx", std::vector<int>{qbit}); auto rx = gateRegistry->createInstruction("Rx", std::vector<int>{qbit});
InstructionParameter p(pi / 2.0); InstructionParameter p(pi / 2.0);
rx->setParameter(0, p); rx->setParameter(0, p);
if (function->hasBeenBitMapped()) {
rx->mapBits(function->getBitMap());
}
gateFunction->addInstruction(rx); gateFunction->addInstruction(rx);
} }
} }
if (!spinInst.isIdentity()) { if (!spinInst.isIdentity()) {
for (auto m : measurements) { for (auto m : measurements) {
if (function->hasBeenBitMapped()) {
m->mapBits(function->getBitMap());
}
gateFunction->addInstruction(m); gateFunction->addInstruction(m);
} }
} }
......
...@@ -49,6 +49,15 @@ template <class W, class B> std::string JsonVisitor<W, B>::write() { ...@@ -49,6 +49,15 @@ template <class W, class B> std::string JsonVisitor<W, B>::write() {
writer->String("function"); writer->String("function");
writer->String(f->name()); writer->String(f->name());
if (f->hasBeenBitMapped()) {
writer->String("bitmap");
writer->StartArray();
for (auto& b : f->getBitMap()) {
writer->Int(b);
}
writer->EndArray();
}
// All functions have instructions, start // All functions have instructions, start
// that array here. // that array here.
writer->String("instructions"); writer->String("instructions");
......
#include "QCSAccelerator.hpp" #include "QCSAccelerator.hpp"
#include <algorithm> #include <algorithm>
#include <pybind11/embed.h>
#include "CountGatesOfTypeVisitor.hpp" #include "CountGatesOfTypeVisitor.hpp"
#include <pybind11/numpy.h> #include <pybind11/numpy.h>
...@@ -76,7 +75,9 @@ std::shared_ptr<IR> MapToPhysical::transform(std::shared_ptr<IR> ir) { ...@@ -76,7 +75,9 @@ std::shared_ptr<IR> MapToPhysical::transform(std::shared_ptr<IR> ir) {
} }
for (auto &inst : probEdges) { for (auto &inst : probEdges) {
problemGraph->addEdge(inst.first, inst.second, 1.0); if (!problemGraph->edgeExists(inst.first, inst.second)) {
problemGraph->addEdge(inst.first, inst.second, 1.0);
}
} }
// std::cout << "\n"; // std::cout << "\n";
...@@ -93,6 +94,8 @@ std::shared_ptr<IR> MapToPhysical::transform(std::shared_ptr<IR> ir) { ...@@ -93,6 +94,8 @@ std::shared_ptr<IR> MapToPhysical::transform(std::shared_ptr<IR> ir) {
physicalMap.push_back(logical2Physical[kv.second[0]]); physicalMap.push_back(logical2Physical[kv.second[0]]);
} }
// std::cout << "Physical bits:\n";
// for (auto& b : physicalMap) std::cout << b << "\n";
function->mapBits(physicalMap); function->mapBits(physicalMap);
} }
...@@ -160,12 +163,12 @@ void QCSAccelerator::execute(std::shared_ptr<AcceleratorBuffer> buffer, ...@@ -160,12 +163,12 @@ void QCSAccelerator::execute(std::shared_ptr<AcceleratorBuffer> buffer,
quilStr = quilStr =
"DECLARE ro BIT[" + std::to_string(buffer->size()) + "]\n" + quilStr; "DECLARE ro BIT[" + std::to_string(buffer->size()) + "]\n" + quilStr;
std::shared_ptr<py::scoped_interpreter> guard;
if (!xacc::isPyApi) {
guard = std::make_shared<py::scoped_interpreter>();
}
// py::print("quil:\n", quilStr); // std::shared_ptr<pybind11::scoped_interpreter> guard;
// py::print("quil:\n", quilStr);
auto pyquil = py::module::import("pyquil"); auto pyquil = py::module::import("pyquil");
py::object get_qc = pyquil.attr("get_qc"); py::object get_qc = pyquil.attr("get_qc");
auto program = pyquil.attr("Program")(); auto program = pyquil.attr("Program")();
...@@ -173,14 +176,13 @@ void QCSAccelerator::execute(std::shared_ptr<AcceleratorBuffer> buffer, ...@@ -173,14 +176,13 @@ void QCSAccelerator::execute(std::shared_ptr<AcceleratorBuffer> buffer,
program.attr("wrap_in_numshots_loop")(shots); program.attr("wrap_in_numshots_loop")(shots);
auto qc = get_qc(backend); auto qc = get_qc(backend);
auto compiled = qc.attr("compile")(program); auto compiled = qc.attr("compile")(program);
py::array_t<int> results = qc.attr("run")(compiled); py::array_t<int> results = qc.attr("run")(compiled);
auto shape = results.request().shape; auto shape = results.request().shape;
// py::print(shape[0]); // py::print(shape[0]);
// py::print(shape[1]); // py::print(shape[1]);
//py::print(results); // py::print(results);
// py::print("QUIL\n"); // py::print("QUIL\n");
// py::print(quilStr); // py::print(quilStr);
//py::print(buffer->size()); //py::print(buffer->size());
...@@ -216,7 +218,7 @@ std::vector<std::shared_ptr<AcceleratorBuffer>> QCSAccelerator::execute( ...@@ -216,7 +218,7 @@ std::vector<std::shared_ptr<AcceleratorBuffer>> QCSAccelerator::execute(
auto tmpBuffer = createBuffer(f->name(), buffer->size()); auto tmpBuffer = createBuffer(f->name(), buffer->size());
high_resolution_clock::time_point t1 = high_resolution_clock::now(); high_resolution_clock::time_point t1 = high_resolution_clock::now();
xacc::info("Execution " + std::to_string(counter) + ": " + f->name()); // xacc::info("Execution " + std::to_string(counter) + ": " + f->name());
execute(tmpBuffer, f); execute(tmpBuffer, f);
high_resolution_clock::time_point t2 = high_resolution_clock::now(); high_resolution_clock::time_point t2 = high_resolution_clock::now();
......
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#include "CLIParser.hpp" #include "CLIParser.hpp"
#include "RemoteAccelerator.hpp" #include "RemoteAccelerator.hpp"
#include <pybind11/embed.h>
#include <dlfcn.h> #include <dlfcn.h>
#define RAPIDJSON_HAS_STDSTRING 1 #define RAPIDJSON_HAS_STDSTRING 1
...@@ -51,14 +53,14 @@ namespace quantum { ...@@ -51,14 +53,14 @@ namespace quantum {
class MapToPhysical : public xacc::IRTransformation { class MapToPhysical : public xacc::IRTransformation {
protected: protected:
std::vector<std::pair<int, int>> _edges; std::vector<std::pair<int, int>> _edges;
public: public:
MapToPhysical(std::vector<std::pair<int, int>> &edges) : _edges(edges) {} MapToPhysical(std::vector<std::pair<int, int>> &edges) : _edges(edges) {}
std::shared_ptr<IR> transform(std::shared_ptr<IR> ir) override; std::shared_ptr<IR> transform(std::shared_ptr<IR> ir) override;
bool hardwareDependent() { return true; } bool hardwareDependent() override { return true; }
const std::string name() const override { return "qcs-map-qubits"; } const std::string name() const override { return "qcs-map-qubits"; }
const std::string description() const override { return ""; } const std::string description() const override { return ""; }
}; };
/** /**
* *
*/ */
...@@ -68,6 +70,8 @@ protected: ...@@ -68,6 +70,8 @@ protected:
std::vector<std::pair<int, int>> latticeEdges; std::vector<std::pair<int, int>> latticeEdges;
Document latticeJson; Document latticeJson;
pybind11::scoped_interpreter * guard;
public: public:
QCSAccelerator() : Accelerator() {} QCSAccelerator() : Accelerator() {}
...@@ -82,10 +86,10 @@ public: ...@@ -82,10 +86,10 @@ public:
* @return * @return
*/ */
std::shared_ptr<AcceleratorBuffer> createBuffer(const std::string &varId, std::shared_ptr<AcceleratorBuffer> createBuffer(const std::string &varId,
const int size); const int size) override;
virtual std::shared_ptr<AcceleratorBuffer> std::shared_ptr<AcceleratorBuffer>
createBuffer(const std::string &varId); createBuffer(const std::string &varId) override;
void execute(std::shared_ptr<AcceleratorBuffer> buffer, void execute(std::shared_ptr<AcceleratorBuffer> buffer,
const std::shared_ptr<Function> function) override; const std::shared_ptr<Function> function) override;
...@@ -93,15 +97,15 @@ public: ...@@ -93,15 +97,15 @@ public:
execute(std::shared_ptr<AcceleratorBuffer> buffer, execute(std::shared_ptr<AcceleratorBuffer> buffer,
const std::vector<std::shared_ptr<Function>> functions) override; const std::vector<std::shared_ptr<Function>> functions) override;
virtual void initialize() { void initialize() override {
void*const libpython_handle = dlopen("libpython3.6m.so", RTLD_LAZY | RTLD_GLOBAL); void*const libpython_handle = dlopen("libpython3.6m.so", RTLD_LAZY | RTLD_GLOBAL);
if (xacc::optionExists("qcs-backend")) { if (xacc::optionExists("qcs-backend")) {
auto backend = xacc::getOption("qcs-backend"); auto backend = xacc::getOption("qcs-backend");
if (backend.find("-qvm") != std::string::npos) { if (backend.find("-qvm") != std::string::npos) {
backend.erase(backend.find("-qvm"), 4); backend.erase(backend.find("-qvm"), 4);
} }
Client client; Client client;
auto response = client.get("https://forest-server.qcs.rigetti.com", auto response = client.get("https://forest-server.qcs.rigetti.com",
"/lattices/" + backend); "/lattices/" + backend);
...@@ -119,9 +123,13 @@ public: ...@@ -119,9 +123,13 @@ public:
latticeEdges.push_back({std::stoi(split[0]), std::stoi(split[1])}); latticeEdges.push_back({std::stoi(split[0]), std::stoi(split[1])});
} }
} }
if (!xacc::isPyApi && !guard) {
guard = new pybind11::scoped_interpreter();
}
} }
std::vector<std::pair<int, int>> getAcceleratorConnectivity() { std::vector<std::pair<int, int>> getAcceleratorConnectivity() override{
if (!latticeEdges.empty()) { if (!latticeEdges.empty()) {
return latticeEdges; return latticeEdges;
} }
...@@ -133,13 +141,13 @@ public: ...@@ -133,13 +141,13 @@ public:
* @param NBits * @param NBits
* @return * @return
*/ */
virtual bool isValidBufferSize(const int NBits); bool isValidBufferSize(const int NBits) override;
/** /**
* This Accelerator models QPU Gate accelerators. * This Accelerator models QPU Gate accelerators.
* @return * @return
*/ */
virtual AcceleratorType getType() { return AcceleratorType::qpu_gate; } AcceleratorType getType() override { return AcceleratorType::qpu_gate; }
/** /**
* We have no need to transform the IR for this Accelerator, * We have no need to transform the IR for this Accelerator,
...@@ -160,20 +168,19 @@ public: ...@@ -160,20 +168,19 @@ public:
* Users can set the api-key, execution type, and number of triels * Users can set the api-key, execution type, and number of triels
* from the command line with these options. * from the command line with these options.
*/ */
virtual OptionPairs getOptions() { OptionPairs getOptions() override {
OptionPairs desc{{"qcs-shots", "Provide the number of trials to execute."}, OptionPairs desc{{"qcs-shots", "Provide the number of trials to execute."},
{"qcs-backend", ""}}; {"qcs-backend", ""}};
return desc; return desc;
} }
virtual const std::string name() const { return "qcs"; } const std::string name() const override { return "qcs"; }
const std::string description() const override { return ""; }
virtual const std::string description() const { return ""; }
/** /**
* The destructor * The destructor
*/ */
virtual ~QCSAccelerator() {} virtual ~QCSAccelerator() { delete guard;}
}; };
} // namespace quantum } // namespace quantum
......
...@@ -48,6 +48,10 @@ public: ...@@ -48,6 +48,10 @@ public:
*/ */
virtual const int nInstructions() = 0; virtual const int nInstructions() = 0;
virtual void setBitMap(const std::vector<int> bitMap) = 0;
virtual const std::vector<int> getBitMap() = 0;
virtual bool hasBeenBitMapped() {return false;}
void setBits(const std::vector<int> bits) override { void setBits(const std::vector<int> bits) override {
return; return;
} }
......
...@@ -63,6 +63,10 @@ public: ...@@ -63,6 +63,10 @@ public:
virtual const std::vector<int> bits() = 0; virtual const std::vector<int> bits() = 0;
virtual void setBits(const std::vector<int> bits) = 0; virtual void setBits(const std::vector<int> bits) = 0;
// Often times we need to map logical bits to physical bits,
// when that happens we should set hte bitMap for future reference
// virtual void setBitMap(const std::vector<int> bitMap) = 0;
/** /**
* Return this Instruction's parameter at the given index. * Return this Instruction's parameter at the given index.
* *
......
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