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

Implemented AcceleratorBuffer.load, added xacc.loadBuffer to python api



Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent 36e7df39
......@@ -3,10 +3,10 @@ import numpy as np
xacc.Initialize()
qpu = xacc.getAccelerator('tnqvm') # or ibm, rigetti, etc...
qpu = xacc.getAccelerator('local-ibm') # or ibm, rigetti, etc...
buffer = qpu.createBuffer('q',2)
@xacc.qpu(accelerator='tnqvm')
@xacc.qpu(accelerator=qpu)
def foo(buffer, theta):
X(0)
Ry(theta, 1)
......@@ -14,11 +14,14 @@ def foo(buffer, theta):
Measure(0,0)
# Execute the code on the QPU
foo(buffer, -3.1415936)
foo(buffer, -1.1415936)
print(foo.nParameters())
# Check into the results
print(buffer.getExpectationValueZ())
print(buffer) #.getExpectationValueZ())
#print(buffer.getMeasurementCounts())
newBuff = xacc.loadBuffer(str(buffer))
print('newbuff\n',newBuff)
xacc.Finalize()
\ No newline at end of file
......@@ -328,19 +328,8 @@ PYBIND11_MODULE(_pyxacc, m) {
.def("name", &xacc::AcceleratorBuffer::name, "")
.def("getAllUnique", &xacc::AcceleratorBuffer::getAllUnique,
"Return all unique information with the provided string name")
.def("__repr__",
[](const std::shared_ptr<AcceleratorBuffer> b) {
std::stringstream s;
b->print(s);
return s.str();
},
"")
.def("__str__", [](const std::shared_ptr<AcceleratorBuffer> b) {
std::stringstream s;
b->print(s);
return s.str();
},
"")
.def("__repr__", &xacc::AcceleratorBuffer::toString, "")
.def("__str__", &xacc::AcceleratorBuffer::toString, "")
.def("getChildren",
(std::vector<std::shared_ptr<AcceleratorBuffer>>(
xacc::AcceleratorBuffer::*)(const std::string, ExtraInfo)) &
......@@ -431,25 +420,26 @@ PYBIND11_MODULE(_pyxacc, m) {
xacc::getService<IRGenerator>,
py::return_value_policy::reference,
"Return the IRGenerator of given name.");
m.def("getConnectivity", [](const std::string acc) -> std::vector<std::vector<int>> {
auto a = xacc::getAccelerator(acc);
auto connectivity = a->getAcceleratorConnectivity();
std::vector<std::vector<int>> edges;
for (int i = 0; i < connectivity->order(); ++i) {
for (int j = i; j < connectivity->order(); ++j) {
if (connectivity->edgeExists(i, j)) {
edges.push_back({i,j});
}
}
}
return edges;
});
m.def("getConnectivity",
[](const std::string acc) -> std::vector<std::vector<int>> {
auto a = xacc::getAccelerator(acc);
auto connectivity = a->getAcceleratorConnectivity();
std::vector<std::vector<int>> edges;
for (int i = 0; i < connectivity->order(); ++i) {
for (int j = i; j < connectivity->order(); ++j) {
if (connectivity->edgeExists(i, j)) {
edges.push_back({i, j});
}
}
}
return edges;
});
m.def("translate", &xacc::translate,
"Translate the provided IR Function to the given language.");
m.def("setOption", [](const std::string s, InstructionParameter p) {
xacc::setOption(s, boost::lexical_cast<std::string>(p));
});
m.def("info", [](const std::string s) { xacc::info(s);}, "");
m.def("info", [](const std::string s) { xacc::info(s); }, "");
m.def("error", &xacc::error, "");
m.def("setOption", &xacc::setOption, "Set an XACC framework option.");
m.def("setOptions",
......@@ -481,7 +471,14 @@ PYBIND11_MODULE(_pyxacc, m) {
(void (*)(std::shared_ptr<AcceleratorBuffer>)) & xacc::analyzeBuffer,
"Analyze the AcceleratorBuffer to produce problem-specific results.");
m.def("Finalize", &xacc::Finalize, "Finalize the framework");
m.def("loadBuffer",
[](const std::string json) {
std::istringstream s(json);
auto buffer = std::make_shared<AcceleratorBuffer>();
buffer->load(s);
return buffer;
},
"");
m.def("compileKernel",
[](std::shared_ptr<Accelerator> acc, const std::string &src,
const std::string &compilerName = "") -> std::shared_ptr<Function> {
......
......@@ -70,7 +70,7 @@ void ToJsonVisitor::operator()(const std::vector<std::string> &i) {
}
void ToJsonVisitor::operator()(const std::map<int, std::vector<int>> &i) {
writer.StartArray();
writer.StartObject();
for (auto &kv : i) {
writer.Key(std::to_string(kv.first));
writer.StartArray();
......@@ -79,7 +79,7 @@ void ToJsonVisitor::operator()(const std::map<int, std::vector<int>> &i) {
}
writer.EndArray();
}
writer.EndArray();
writer.EndObject();
}
AcceleratorBuffer::AcceleratorBuffer(const std::string &str, const int N)
......@@ -264,7 +264,8 @@ void AcceleratorBuffer::appendMeasurement(
return;
}
void AcceleratorBuffer::appendMeasurement(const std::string measurement, const int count) {
void AcceleratorBuffer::appendMeasurement(const std::string measurement,
const int count) {
bitStringToCounts[measurement] = count;
for (int i = 0; i < count; i++)
measurements.push_back(boost::dynamic_bitset<>(measurement));
......@@ -389,9 +390,8 @@ void AcceleratorBuffer::print(std::ostream &stream) {
if (!children.empty()) {
writer.Key("Children");
writer.StartObject();
writer.StartArray();
for (auto &pair : children) {
writer.Key("child");
writer.StartObject();
writer.Key("name");
writer.String(pair.first);
......@@ -412,7 +412,7 @@ void AcceleratorBuffer::print(std::ostream &stream) {
writer.EndObject();
writer.EndObject();
}
writer.EndObject();
writer.EndArray();
}
writer.EndObject();
......@@ -420,4 +420,140 @@ void AcceleratorBuffer::print(std::ostream &stream) {
stream << buffer.GetString();
}
const std::string AcceleratorBuffer::toString() {
std::stringstream s;
print(s);
return s.str();
}
void AcceleratorBuffer::load(std::istream &stream) {
std::string json(std::istreambuf_iterator<char>(stream), {});
Document doc;
doc.Parse(json);
resetBuffer();
bufferId = doc["AcceleratorBuffer"]["name"].GetString();
nBits = doc["AcceleratorBuffer"]["size"].GetInt();
auto &topInfo = doc["AcceleratorBuffer"]["Information"];
for (auto itr = topInfo.MemberBegin(); itr != topInfo.MemberEnd(); ++itr) {
auto &value = topInfo[itr->name.GetString()];
if (value.IsInt()) {
addExtraInfo(itr->name.GetString(), value.GetInt());
} else if (value.IsDouble()) {
addExtraInfo(itr->name.GetString(), value.GetDouble());
} else if (value.IsString()) {
addExtraInfo(itr->name.GetString(), value.GetString());
} else if (value.IsArray() && !value.GetArray().Empty()) {
auto arr = value.GetArray();
auto &firstVal = arr[0];
if (firstVal.IsInt()) {
std::vector<int> childValues;
for (int i = 0; i < arr.Size(); i++)
childValues.push_back(arr[i].GetInt());
addExtraInfo(itr->name.GetString(), ExtraInfo(childValues));
} else if (firstVal.IsDouble()) {
std::vector<double> childValues;
for (int i = 0; i < arr.Size(); i++)
childValues.push_back(arr[i].GetDouble());
addExtraInfo(itr->name.GetString(), ExtraInfo(childValues));
} else if (firstVal.IsString()) {
std::vector<std::string> childValues;
for (int i = 0; i < arr.Size(); i++)
childValues.push_back(arr[i].GetString());
addExtraInfo(itr->name.GetString(), ExtraInfo(childValues));
}
} else {
// Here we have the case of an object([key:value])
if (value.IsObject()) {
std::map<int, std::vector<int>> map;
for (auto itr2 = value.MemberBegin(); itr2 != value.MemberEnd();
++itr2) {
auto keyIsInt = true;
int key;
try {
key = boost::lexical_cast<int>(itr2->name.GetString());
} catch (std::exception &e) {
keyIsInt = false;
}
if (itr2->value.IsArray() && keyIsInt) {
// we ahve a map<int,[int*]>
auto arr = itr2->value.GetArray();
std::vector<int> vec;
for (int i = 0; i < arr.Size(); i++)
vec.push_back(arr[i].GetInt());
map.insert({key, vec});
} else {
break;
}
}
addExtraInfo(itr->name.GetString(), ExtraInfo(map));
}
}
}
// FIXME Handle Measurements
auto &measures = doc["AcceleratorBuffer"]["Measurements"];
for (auto itr = measures.MemberBegin(); itr != measures.MemberEnd(); ++itr) {
appendMeasurement(itr->name.GetString(), itr->value.GetInt());
}
auto children = doc["AcceleratorBuffer"]["Children"].GetArray();
for (auto &c : children) {
auto childBuffer =
std::make_shared<AcceleratorBuffer>(c["name"].GetString(), nBits);
auto &info = c["Information"];
for (auto itr = info.MemberBegin(); itr != info.MemberEnd(); ++itr) {
auto &value = info[itr->name.GetString()];
if (value.IsInt()) {
childBuffer->addExtraInfo(itr->name.GetString(),
ExtraInfo(value.GetInt()));
} else if (value.IsDouble()) {
childBuffer->addExtraInfo(itr->name.GetString(),
ExtraInfo(value.GetDouble()));
} else if (value.IsString()) {
childBuffer->addExtraInfo(itr->name.GetString(),
ExtraInfo(value.GetString()));
} else if (value.IsArray() && !value.GetArray().Empty()) {
auto arr = value.GetArray();
auto &firstVal = arr[0];
if (firstVal.IsInt()) {
std::vector<int> childValues;
for (int i = 0; i < arr.Size(); i++)
childValues.push_back(arr[i].GetInt());
childBuffer->addExtraInfo(itr->name.GetString(),
ExtraInfo(childValues));
} else if (firstVal.IsDouble()) {
std::vector<double> childValues;
for (int i = 0; i < arr.Size(); i++)
childValues.push_back(arr[i].GetDouble());
childBuffer->addExtraInfo(itr->name.GetString(),
ExtraInfo(childValues));
} else if (firstVal.IsString()) {
std::vector<std::string> childValues;
for (int i = 0; i < arr.Size(); i++)
childValues.push_back(arr[i].GetString());
childBuffer->addExtraInfo(itr->name.GetString(),
ExtraInfo(childValues));
} else {
std::cout << "HELLO EXTRA: " << itr->name.GetString() << "\n";
}
// FIXME Handle Map<int, [int*]>
appendChild(c["name"].GetString(), childBuffer);
}
}
auto &measures = c["Measurements"];
for (auto itr = measures.MemberBegin(); itr != measures.MemberEnd();
++itr) {
childBuffer->appendMeasurement(itr->name.GetString(),
itr->value.GetInt());
}
}
}
} // namespace xacc
......@@ -21,6 +21,7 @@
#define RAPIDJSON_HAS_STDSTRING 1
#include "rapidjson/prettywriter.h"
#include "rapidjson/document.h"
using namespace rapidjson;
......@@ -103,6 +104,8 @@ protected:
std::map<std::string, ExtraInfo> info;
public:
AcceleratorBuffer() {}
/**
* The Constructor
*/
......@@ -167,8 +170,9 @@ public:
virtual void appendMeasurement(const boost::dynamic_bitset<> &measurement,
const int count);
virtual void appendMeasurement(const std::string measurement, const int count);
virtual void appendMeasurement(const std::string measurement,
const int count);
virtual double computeMeasurementProbability(const std::string &bitStr);
/**
......@@ -205,6 +209,7 @@ public:
*
*/
virtual void print();
const std::string toString();
/**
* Print information about this AcceleratorBuffer to the
......@@ -214,6 +219,8 @@ public:
*/
virtual void print(std::ostream &stream);
virtual void load(std::istream &stream);
/**
* The Destructor
*/
......
......@@ -28,17 +28,6 @@ TEST(AcceleratorBufferTester, checkGetExpectationValueZ) {
EXPECT_TRUE(std::fabs(buffer.getExpectationValueZ() + 0.00398406) < 1e-6);
// Kernel 38 Z2, 2 mapped to qubit 6
// [2017-11-29 15:01:42.752] [xacc-console] [info] Measured Qubits: 6,
// [2017-11-29 15:01:42.752] [xacc-console] [info] IBM Results:
// 0000100000000000:1 [2017-11-29 15:01:42.752] [xacc-console] [info]
// Our Results: 000000000000:1 [2017-11-29 15:01:42.752] [xacc-console]
// [info] IBM Results: 0000110000000000:7827 [2017-11-29 15:01:42.752]
// [xacc-console] [info] Our Results: 000000000000:7827 [2017-11-29
// 15:01:42.761] [xacc-console] [info] IBM Results: 0000110001000000:364
//[2017-11-29 15:01:42.761] [xacc-console] [info] Our Results:
// 000001000000:364
boost::dynamic_bitset<> m1(std::string("000000000000"));
boost::dynamic_bitset<> m2(std::string("000000000000"));
boost::dynamic_bitset<> m3(std::string("000001000000"));
......@@ -52,6 +41,120 @@ TEST(AcceleratorBufferTester, checkGetExpectationValueZ) {
EXPECT_TRUE(std::fabs(bigBuffer.getExpectationValueZ() - 0.911011) < 1e-6);
}
TEST(AcceleratorBufferTester, checkLoad) {
const std::string bufferStr = R"bufferStr({
"AcceleratorBuffer": {
"name": "q",
"size": 2,
"Information": {
"vqe-angles": [
0.5945312500000002
],
"vqe-energy": -1.7491552234943562,
"vqe-nQPU-calls": 0
},
"Measurements": {},
"Children": [
{
"name": "Z1",
"Information": {
"kernel": "Z1",
"parameters": [
0.5
]
},
"Measurements": {
"00": 323,
"01": 701
}
},
{
"name": "I",
"Information": {
"kernel": "I",
"parameters": [
0.5
]
},
"Measurements": {
"00": 323,
"01": 701
}
}
]
}
})bufferStr";
AcceleratorBuffer buffer;
std::istringstream s(bufferStr);
buffer.load(s);
EXPECT_EQ("q", buffer.name());
EXPECT_EQ(2, buffer.size());
std::stringstream ss;
buffer.print(ss);
EXPECT_EQ(ss.str(), bufferStr);
}
TEST(AcceleratorBufferTester, checkLoadDwave) {
const std::string dwaveBuffer = R"dwaveBuffer({
"AcceleratorBuffer": {
"name": "q",
"size": 2048,
"Information": {
"active-vars": [
1944,
1946,
1947,
1948,
1949,
1951
],
"analysis-results": [
3,
5
],
"embedding": {
"0": [
1948,
1947
],
"1": [
1949
],
"2": [
1946,
1951
],
"3": [
1944
]
},
"energies": [
-999.75
],
"execution-time": 0.023974,
"ir-generator": "dwave-factoring",
"num-occurrences": [
100
]
},
"Measurements": {
"010001": 100
}
}
})dwaveBuffer";
AcceleratorBuffer buffer;
std::istringstream s(dwaveBuffer);
buffer.load(s);
// EXPECT_EQ("q",buffer.name());
// EXPECT_EQ(2,buffer.size());
std::stringstream ss;
buffer.print(ss);
EXPECT_EQ(ss.str(), dwaveBuffer);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
......
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