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

adding dw decorate that delegates to legacy sapi code from dwave


Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent f65ecb78
Pipeline #83064 passed with stage
in 4 minutes and 9 seconds
......@@ -16,3 +16,6 @@
[submodule "xacc/optimizer/nlopt-optimizers/nlopt"]
path = xacc/optimizer/nlopt-optimizers/nlopt
url = https://github.com/stevengj/nlopt
[submodule "quantum/plugins/dwave/tpls/legacy-sapi-clients"]
path = quantum/plugins/dwave/tpls/legacy-sapi-clients
url = https://github.com/ornl-qci/legacy-sapi-clients
......@@ -42,7 +42,7 @@ usFunctionEmbedResources(TARGET ${LIBRARY_NAME}
target_include_directories(${LIBRARY_NAME} PRIVATE . generated
${CMAKE_SOURCE_DIR}/tpls/antlr/runtime/src)
target_link_libraries(${LIBRARY_NAME} PUBLIC xacc ${ANTLR_LIB})
target_link_libraries(${LIBRARY_NAME} PUBLIC xacc xacc-quantum-gate xacc-quantum-annealing ${ANTLR_LIB})
if(APPLE)
set_target_properties(${LIBRARY_NAME} PROPERTIES INSTALL_RPATH "@loader_path/../lib")
......
......@@ -17,7 +17,9 @@
#include "expression_parsing_util.hpp"
#include "pyxasm_listener.hpp"
#include "Circuit.hpp"
#include "AnnealingProgram.hpp"
#include <memory>
#include <regex>
using namespace pyxasm;
......@@ -47,6 +49,11 @@ void PyXASMListener::enterInstruction(pyxasmParser::InstructionContext *ctx) {
instructionName = "CNOT";
} else if (instructionName == "MEASURE") {
instructionName = "Measure";
} else if (instructionName == "dwqmi") {
auto isCircuit = std::dynamic_pointer_cast<quantum::Circuit>(function);
if (isCircuit) {
function = irProvider->createComposite(function->name(), function->getVariables(), "anneal");
}
}
auto nRequiredBits = irProvider->getNRequiredBits(instructionName);
......@@ -114,6 +121,10 @@ void PyXASMListener::enterInstruction(pyxasmParser::InstructionContext *ctx) {
std::dynamic_pointer_cast<CompositeInstruction>(tmpInst)->addVariable(params[p].toString());
}
}
if (std::dynamic_pointer_cast<quantum::AnnealingProgram>(tmpInst) && std::dynamic_pointer_cast<quantum::Circuit>(function)) {
function = irProvider->createComposite(function->name(), function->getVariables(), "anneal");
}
}
function->addInstruction(tmpInst);
function->expand(options);
......
......@@ -11,11 +11,7 @@ H 0.000000 0.0 0.0
H 0.0 0.0 .7474
symmetry c1
'''
fo = [0, 1, 2, 3, 4, 10, 11, 12, 13, 14]
ao = [5, 9, 15, 19]
H = xacc.getObservable('psi4', {'basis': 'sto-3g', 'geometry': geom})#,
# 'frozen-spin-orbitals': fo, 'active-spin-orbitals': ao})
H = xacc.getObservable('psi4', {'basis': 'sto-3g', 'geometry': geom})
@xacc.qpu(algo='vqe', accelerator=qpu, observable=H)
def ansatz(q, x):
......
......@@ -52,6 +52,8 @@ class DwaveNealAccelerator(xacc.Accelerator):
counts = Counter(counts_list)
buffer.setMeasurements(counts)
buffer.addExtraInfo('unique-configurations', unique_config_to_energy)
gstate = min(unique_config_to_energy, key=unique_config_to_energy.get)
buffer.addExtraInfo('ground_state', gstate)
......
......@@ -12,6 +12,7 @@ class Psi4Observable(xacc.Observable):
def __init__(self):
xacc.Observable.__init__(self)
self.observable = None
self.asPauli = None
def toString(self):
return self.observable.toString()
......@@ -25,6 +26,9 @@ class Psi4Observable(xacc.Observable):
def name(self):
return 'psi4'
def __iter__(self):
return self.asPauli.__iter__()
def fromOptions(self, inputParams):
import numpy as np
import psi4
......@@ -209,4 +213,5 @@ class Psi4Observable(xacc.Observable):
if abs(Hamiltonian_fc_2body_tmp[p,q,r,ss]) > 1e-12:
f_str += pos_or_neg(Hamiltonian_fc_2body_tmp[p,q,r,ss]) + str(abs(Hamiltonian_fc_2body_tmp[p,q,r,ss])) + ' ' + str(p) + '^ ' + str(q) + '^ ' + str(r) + ' ' + str(ss)
self.observable = xacc.getObservable('fermion', f_str)
self.asPauli = xacc.transformToPauli('jw', self.observable)
......@@ -15,6 +15,7 @@
#include "FermionOperator.hpp"
#include "xacc_service.hpp"
#include "py_heterogeneous_map.hpp"
#include "ObservableTransform.hpp"
using namespace xacc::quantum;
......@@ -103,7 +104,9 @@ void bind_observable(py::module &m) {
return std::make_shared<PauliOperator>();
}
});
m.def("transformToPauli", [](const std::string type, std::shared_ptr<Observable> obs) {
return std::dynamic_pointer_cast<PauliOperator>(xacc::getService<ObservableTransform>(type)->transform(obs));
});
m.def("getObservable",
[](const std::string &type,
const PyHeterogeneousMap &options) -> std::shared_ptr<Observable> {
......@@ -125,7 +128,7 @@ void bind_observable(py::module &m) {
t->fromOptions(m);
return t;
});
m.def("getObservable",
[](const std::string &type) -> std::shared_ptr<Observable> {
std::shared_ptr<Observable> t;
......
......@@ -10,6 +10,8 @@
# Contributors:
# Alexander J. McCaskey - initial API and implementation
# *******************************************************************************/
add_subdirectory(tpls/legacy-sapi-clients/c-client)
set(LIBRARY_NAME xacc-dwave)
set(ANTLR_LIB ${CMAKE_SOURCE_DIR}/dist/libantlr4-runtime.so)
......@@ -21,6 +23,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-format-security")
file(GLOB SRC
accelerator/DWAccelerator.cpp
accelerator/DWDecorator.cpp
DWaveActivator.cpp
embedding/CMREmbedding.cpp
generators/rbm.cpp)
......@@ -37,6 +40,10 @@ target_include_directories(${LIBRARY_NAME}
embedding
generators
embedding/minorminer/include
tpls/legacy-sapi-clients/c-client/include
tpls/legacy-sapi-clients/find-embedding/include
tpls/legacy-sapi-clients/c-client/include
tpls/legacy-sapi-clients/remote/include
${CMAKE_SOURCE_DIR}/tpls/rapidjson/include
${CMAKE_SOURCE_DIR}/tpls/antlr/runtime/src)
......@@ -44,7 +51,7 @@ target_include_directories(${LIBRARY_NAME}
target_link_libraries(${LIBRARY_NAME}
PUBLIC xacc
xacc-quantum-annealing
${ANTLR_LIB}
${ANTLR_LIB} dwave_sapi
)
set(_bundle_name xacc_dwave)
......
......@@ -11,6 +11,8 @@
* Alexander J. McCaskey - initial API and implementation
*******************************************************************************/
#include "DWAccelerator.hpp"
#include "DWDecorator.hpp"
// #include "DWQMICompiler.hpp"
#include "rbm.hpp"
#include "CMREmbedding.hpp"
......@@ -38,6 +40,9 @@ public:
void Start(BundleContext context) {
auto acc = std::make_shared<xacc::quantum::DWAccelerator>();
context.RegisterService<xacc::Accelerator>(acc);
auto accd = std::make_shared<xacc::quantum::DWDecorator>();
context.RegisterService<xacc::Accelerator>(accd);
// context.RegisterService<xacc::OptionsProvider>(acc);
auto rbm = std::make_shared<xacc::dwave::RBM>();
......
......@@ -25,13 +25,11 @@
#include "rapidjson/prettywriter.h"
using namespace rapidjson;
namespace xacc {
namespace quantum {
namespace quantum {
void DWAccelerator::initialize(const HeterogeneousMap &params) {
searchAPIKey(apiKey, url);
updateConfiguration(params);
if (xacc::optionExists("dwave-skip-initialization")) {
......@@ -97,7 +95,8 @@ const std::string DWAccelerator::processInput(
splitLines = xacc::split(newKernel->toString(), '\n');
auto nQMILines = splitLines.size();
std::string jsonStr = "", solverName = "DW_2000Q_VFYC_2_1",
solveType = "ising", trials = std::to_string(shots), annealTime = "20";
solveType = "ising", trials = std::to_string(shots),
annealTime = "20";
auto solver = availableSolvers[solverName];
......@@ -110,20 +109,19 @@ const std::string DWAccelerator::processInput(
jsonStr += ", \"auto_scale\" : true } }]";
jsonStr = std::regex_replace(jsonStr, std::regex("\n"), "\\n");
// std::cout << "sending: " << jsonStr << "\n";
// std::cout << "sending: " << jsonStr << "\n";
return jsonStr;
}
void DWAccelerator::processResponse(std::shared_ptr<AcceleratorBuffer> buffer,
const std::string &response) {
bool jobCompleted = false;
Document doc;
// Parse the json string
doc.Parse(response);
// std::cout << response << "\n";
// std::cout << response << "\n";
// Get the JobID
std::string jobId = std::string(doc[0]["id"].GetString());
......@@ -152,7 +150,7 @@ void DWAccelerator::processResponse(std::shared_ptr<AcceleratorBuffer> buffer,
// xacc::info(msg);
}
// std::cout << msg << "\n";
std::cout << msg << "\n";
// We've completed, so let's get
// teh results.
doc.Parse(msg);
......@@ -161,6 +159,11 @@ void DWAccelerator::processResponse(std::shared_ptr<AcceleratorBuffer> buffer,
std::vector<int> numOccurrences, active_vars;
auto energyArray = doc["answer"]["energies"].GetArray();
auto numOccArray = doc["answer"]["num_occurrences"].GetArray();
auto activeVarsSize = doc["answer"]["active_variables"].GetArray().Size();
auto activeVars = doc["answer"]["active_variables"].GetArray();
for (int i = 0; i < activeVarsSize; i++) {
active_vars.push_back(activeVars[i].GetInt());
}
double minEnergy = std::numeric_limits<double>::max();
int idx = 0;
for (int i = 0; i < energyArray.Size(); i++) {
......@@ -171,36 +174,32 @@ void DWAccelerator::processResponse(std::shared_ptr<AcceleratorBuffer> buffer,
idx = i;
}
}
auto num_vars = doc["answer"]["num_variables"].GetInt();
buffer->addExtraInfo("num_vars", num_vars);
buffer->addExtraInfo("ground_energy", ExtraInfo(minEnergy));
auto solutionsStrEncoded =
std::string(doc["answer"]["solutions"].GetString());
auto decoded = base64_decode(solutionsStrEncoded);
// xacc::info("DECODED: " + decoded);
std::string bitStr = "";
std::stringstream ss;
for (std::size_t i = 0; i < decoded.size(); ++i) {
ss << std::bitset<8>(decoded.c_str()[i]);
}
bitStr = ss.str();
auto activeVarsSize = doc["answer"]["active_variables"].GetArray().Size();
auto activeVars = doc["answer"]["active_variables"].GetArray();
for (int i = 0; i < activeVarsSize; i++) {
active_vars.push_back(activeVars[i].GetInt());
}
int start = 0;
for (auto &count : numOccurrences) {
auto solution = bitStr.substr(start, activeVarsSize);
buffer->appendMeasurement(solution, count);
if (start == 0) {
buffer->addExtraInfo("ground_state", ExtraInfo(solution));
}
start += activeVarsSize;
}
// auto decodedTest = decodeSolutions(solutionsStrEncoded, energyArray.Size(),
// num_vars, active_vars, -1);
// auto decoded = base64_decode(solutionsStrEncoded);
// std::cout << "DECODED SIZE: " << decodedTest.size() << "\n";
// std::vector<std::vector<char>> bitStrings;
// for (auto j = 0; j < energies.size(); j++) {
// // std::stringstream sss;
// auto first = decodedTest.begin() + j * num_vars;
// auto last = decodedTest.begin() + j * num_vars + num_vars;
// std::vector<char> sub(first, last);
// bitStrings.push_back(sub);
// // for (int i = 0; i < sub.size(); i++) {
// // sss << static_cast<int>(sub[i]);
// // }
// // auto bs = sss.str();
// // buffer->appendMeasurement(bs, numOccurrences[j]);
// }
buffer->addExtraInfo("solutions", solutionsStrEncoded);
// FIXME CHECK WE HAVE total_real_time
auto &timing = doc["answer"]["timing"];
if (timing.HasMember("total_real_time")) {
......
......@@ -18,6 +18,8 @@
#include "DWQMI.hpp"
#include "RemoteAccelerator.hpp"
#include "dwave_sapi.h"
using namespace xacc;
namespace xacc {
......@@ -45,7 +47,7 @@ public:
std::vector<std::pair<int, int>> getConnectivity() override;
const std::string getSignature() override {return "dwave"+backend;}
const std::string getSignature() override { return "dwave-internal" + backend; }
const std::string processInput(
std::shared_ptr<AcceleratorBuffer> buffer,
......@@ -84,7 +86,7 @@ public:
return {"shots", "backend"};
}
const std::string name() const override { return "dwave"; }
const std::string name() const override { return "dwave-internal"; }
const std::string description() const override {
return "The D-Wave Accelerator executes Ising Hamiltonian parameters "
......@@ -101,6 +103,10 @@ protected:
std::string url;
std::map<std::string, DWSolver> availableSolvers;
sapi_Connection *connection = nullptr;
sapi_Solver *solver = nullptr;
const sapi_SolverProperties *solver_properties = nullptr;
void searchAPIKey(std::string &key, std::string &url);
void findApiKeyInFile(std::string &key, std::string &url,
const std::string &p);
......
#include "DWDecorator.hpp"
#include "EmbeddingAlgorithm.hpp"
#include "xacc.hpp"
#include <algorithm>
#include "AnnealingProgram.hpp"
#include "dwave_sapi.h"
namespace {
namespace base64 {
const unsigned int ign = 0x100;
const unsigned int bad = 0x101;
const unsigned int pad = 0x102;
const unsigned int decode[128] = {
/* 0 */ bad,
bad,
bad,
bad,
bad,
bad,
bad,
bad,
bad,
bad,
ign,
bad,
bad,
ign,
bad,
bad,
/* 16 */ bad,
bad,
bad,
bad,
bad,
bad,
bad,
bad,
bad,
bad,
bad,
bad,
bad,
bad,
bad,
bad,
/* 32 */ bad,
bad,
bad,
bad,
bad,
bad,
bad,
bad,
bad,
bad,
bad,
62,
bad,
bad,
bad,
63,
/* 48 */ 52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
bad,
bad,
bad,
pad,
bad,
bad,
/* 64 */ bad,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
/* 80 */ 15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
bad,
bad,
bad,
bad,
bad,
/* 96 */ bad,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
/* 112 */ 41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
bad,
bad,
bad,
bad,
bad,
};
const int decodeSize = sizeof(decode) / sizeof(decode[0]);
const int blockSize = 4;
const int encodedBits = 6;
const int minPaddingIndex = 2;
const auto encode =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const auto padChar = '=';
} // namespace base64
} // namespace
std::string encodeBase64(const void *vdata, size_t len) {
auto data = static_cast<const unsigned char *>(vdata);
// if (len > (std::string::npos - 1) / 4 * 3) xaccthrow
// std::length_error("sapiremote::encodeBase64");
auto b64size = (len + 2) / 3 * 4;
auto b64 = std::string(b64size, '\0');
auto out = b64.begin();
auto numFullBlocks = len / 3;
for (auto i = 0u; i < numFullBlocks; ++i) {
unsigned block = (static_cast<unsigned int>(data[0]) << 16) |
(static_cast<unsigned int>(data[1]) << 8) | data[2];
*out++ = base64::encode[(block >> 18) & 0x3f];
*out++ = base64::encode[(block >> 12) & 0x3f];
*out++ = base64::encode[(block >> 6) & 0x3f];
*out++ = base64::encode[block & 0x3f];
data += 3;
}
switch (len % 3) {
case 0:
break;
case 1: {
unsigned block = (static_cast<unsigned int>(data[0]) << 16);
;
*out++ = base64::encode[(block >> 18) & 0x3f];
*out++ = base64::encode[(block >> 12) & 0x3f];
*out++ = base64::padChar;
*out++ = base64::padChar;
} break;
case 2: {
unsigned block = (static_cast<unsigned int>(data[0]) << 16) |
(static_cast<unsigned int>(data[1]) << 8);
*out++ = base64::encode[(block >> 18) & 0x3f];
*out++ = base64::encode[(block >> 12) & 0x3f];
*out++ = base64::encode[(block >> 6) & 0x3f];
*out++ = base64::padChar;
} break;
}
return b64;
}
std::vector<unsigned char> decodeBase64(const std::string &b64data) {
std::vector<unsigned char> data;
data.reserve(b64data.size() * 3 / 4);
auto byteIndex = 0;
auto padding = 0;
auto finished = false;
unsigned int block = 0;
for (char c : b64data) {
// if (c < 0 || c >= base64::decodeSize) xacc::error("base 64
// exception");//throw Base64Exception();
auto d = base64::decode[c];
if (d == base64::ign)
continue;
if (finished)
xacc::error("base 64 exception");
switch (d) {
case base64::bad:
xacc::error("base 64 exception");
case base64::pad:
if (padding == 0 && byteIndex < base64::minPaddingIndex)
xacc::error("base 64 exception");
block <<= base64::encodedBits;
++padding;
++byteIndex;
break;
default:
if (padding)
xacc::error("base 64 exception");
block = (block << base64::encodedBits) | d;
++byteIndex;
break;
}
if (byteIndex == base64::blockSize) {
data.push_back(static_cast<unsigned char>(block >> 16));
if (padding < 2)
data.push_back(static_cast<unsigned char>((block >> 8) & 0xff));
if (padding < 1)
data.push_back(static_cast<unsigned char>(block & 0xff));
finished = padding > 0;
byteIndex = 0;
block = 0;
}
}
if (byteIndex != 0)
xacc::error("base 64 exception");
return data;
}
std::vector<char> decodeSolutions(const std::string &answer, size_t numSols,
int numVars, std::vector<int> activeVars,
char zero) {
auto solBits = decodeBase64(answer);
// auto activeVars = decodeBinary<int>(answer, answerkeys::activeVars);