Commit 37c63f22 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

committing working deuteron vqe, added qcor compiler wrapper


Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent f834800d
Pipeline #44118 passed with stages
in 2 minutes and 17 seconds
......@@ -20,6 +20,7 @@ include(CTest)
find_package(Clang 9.0.0 REQUIRED)
find_package(XACC REQUIRED)
set(CLANG_COMPILER /usr/bin/clang++-9)
if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set (CMAKE_INSTALL_PREFIX "${XACC_ROOT}" CACHE PATH "default install path" FORCE )
......@@ -35,7 +36,8 @@ include_directories(${XACC_INCLUDE_DIRS})
link_directories(${XACC_LIBRARY_DIR})
#message(STATUS "${CLANG_INCLUDE_DIRS}")
configure_file(${CMAKE_SOURCE_DIR}/scripts/qcor.in
${CMAKE_BINARY_DIR}/qcor)
macro(qcor_enable_rpath LIBNAME)
if(APPLE)
......@@ -51,3 +53,5 @@ endmacro()
add_subdirectory(runtime)
add_subdirectory(compiler)
add_subdirectory(instructions)
install(PROGRAMS ${CMAKE_BINARY_DIR}/qcor DESTINATION bin)
\ No newline at end of file
......@@ -15,3 +15,5 @@ target_include_directories(${LIBRARY_NAME}
${XACC_INCLUDE_ROOT}/cppmicroservices4)
target_link_libraries(${LIBRARY_NAME}
PUBLIC ${CLANG_LIBS} ${XACC_LIBRARIES} qcor)
install(TARGETS ${LIBRARY_NAME} DESTINATION lib)
......@@ -111,14 +111,14 @@ bool LambdaVisitor::VisitLambdaExpr(LambdaExpr *LE) {
if (isqk.isQuantumKernel()) {
// For debugging for now
std::cout << "\n\n";
q_kernel_body->dump();
// std::cout << "\n\n";
// q_kernel_body->dump();
CppToXACCIRVisitor visitor(ci.getASTContext());
visitor.TraverseStmt(LE->getBody());
auto function = visitor.getFunction();
std::cout << "\n\nXACC IR:\n" << function->toString() << "\n";
// std::cout << "\n\nXACC IR:\n" << function->toString() << "\n";
// Kick off quantum compilation
auto qcor = xacc::getCompiler("qcor");
......
......@@ -19,9 +19,9 @@ bool QCORPluginAction::ParseArgs(const CompilerInstance &ci,
xacc::Initialize(local);
}
for (auto a : args) {
xacc::info("qcor argument: " + a);
}
// for (auto a : args) {
// xacc::info("qcor argument: " + a);
// }
auto it = std::find(args.begin(), args.end(), "accelerator");
if (it != args.end()) {
......
#include "qcor.hpp"
int main() {
qcor::Initialize({"--accelerator", "local-ibm"});
auto future = qcor::submit([&](qcor::qpu_handler &qh) {
qh.execute([&]() {
H(0);
CX(0, 1);
Measure(0);
Measure(1);
});
});
// You just launched an async call,
// go do other work if necessary...
auto results = future.get();
results->print();
}
\ No newline at end of file
#include "qcor.hpp"
int main() {
qcor::Initialize({"--accelerator", "tnqvm"});
auto optimizer = qcor::getOptimizer("nlopt");
const std::string deuteronH2 =
R"deuteronH2((5.907,0) + (-2.1433,0) X0 X1 + (-2.1433,0) Y0 Y1 + (.21829,0) Z0 + (-6.125,0) Z1)deuteronH2";
PauliOperator op;
op.fromString(deuteronH2);
auto future = qcor::submit([&](qcor::qpu_handler &qh) {
qh.vqe(
[&](double t0) {
X(0);
Ry(t0, 1);
CX(1, 0);
},
op, optimizer);
});
auto results = future.get();
results->print();
}
......@@ -10,6 +10,8 @@ OptResult NLOptimizer::optimize(OptFunction &function,
auto dim = function.dimensions();
nlopt::algorithm algo = nlopt::algorithm::LN_COBYLA;
double tol = 1e-8;
int maxeval = 1000;
if (options.count("nlopt-optimizer")) {
auto optimizerAlgo = options["nlopt-optimizer"].as<std::string>();
......@@ -23,8 +25,15 @@ OptResult NLOptimizer::optimize(OptFunction &function,
}
}
nlopt::opt _opt(algo, dim);
if (options.count("nlopt-ftol")) {
tol = options["nlopt-ftol"].as<double>();
}
if (options.count("nlopt-maxeval")) {
maxeval = options["nlopt-maxeval"].as<int>();
}
nlopt::opt _opt(algo, dim);
std::function<double(const std::vector<double> &, std::vector<double> &,
void *)>
f = [&](const std::vector<double> &x, std::vector<double> &grad,
......@@ -35,7 +44,8 @@ OptResult NLOptimizer::optimize(OptFunction &function,
_opt.set_min_objective(fptr, NULL);
_opt.set_lower_bounds(std::vector<double>(dim, -3.1415926));
_opt.set_upper_bounds(std::vector<double>(dim, 3.1415926));
_opt.set_maxeval(100);
_opt.set_maxeval(maxeval);
_opt.set_ftol_rel(tol);
double optF;
std::vector<double> x(dim);
......
......@@ -4,6 +4,7 @@
#include "AcceleratorBuffer.hpp"
#include "IRProvider.hpp"
#include "XACC.hpp"
#include <regex>
using namespace xacc;
......@@ -31,25 +32,21 @@ const std::string persistCompiledCircuit(std::shared_ptr<Function> function) {
return str;
};
return generateRandomString();
auto file_name = generateRandomString();
auto persistedFunction = xacc::getCompiler("xacc-py")->translate("", function);
persistedFunction = persistedFunction.substr(7,persistedFunction.length());
xacc::appendCache(file_name, "compiled", InstructionParameter(persistedFunction), ".qcor_cache");
return file_name;
}
std::shared_ptr<Function> loadCompiledCircuit(const std::string& fileName) {
auto provider = xacc::getService<IRProvider>("gate");
auto function = provider->createFunction("tmp", {});
auto h = provider->createInstruction("H", {0});
auto cx = provider->createInstruction("CNOT", {0,1});
auto m1 = provider->createInstruction("Measure", {0}, {InstructionParameter(0)});
auto m2 = provider->createInstruction("Measure", {1}, {InstructionParameter(1)});
function->addInstruction(h);
function->addInstruction(cx);
function->addInstruction(m1);
function->addInstruction(m2);
auto cache = xacc::getCache(fileName, ".qcor_cache");
if (!cache.count("compiled")) {
xacc::error("Invalid quantum compilation cache.");
}
return function;
auto compiled = cache["compiled"].as<std::string>();
return xacc::getCompiler("xacc-py")->compile(compiled)->getKernels()[0];
}
std::future<std::shared_ptr<AcceleratorBuffer>> submit(HandlerLambda &&totalJob) {
......
#ifndef RUNTIME_QCOR_HPP_
#define RUNTIME_QCOR_HPP_
#include "AcceleratorBuffer.hpp"
#include <future>
#include "optimizer.hpp"
#include "PauliOperator.hpp"
using namespace xacc::quantum;
namespace xacc {
class Function;
......
......@@ -3,11 +3,14 @@
#include "qcor.hpp"
#include "Function.hpp"
#include "AcceleratorBuffer.hpp"
#include "Function.hpp"
#include "InstructionIterator.hpp"
#include "InstructionParameter.hpp"
#include "Observable.hpp"
#include "XACC.hpp"
#include <complex>
#include <string>
namespace qcor {
......@@ -15,49 +18,76 @@ namespace qcor {
class qpu_handler {
protected:
std::shared_ptr<xacc::AcceleratorBuffer> buffer;
public:
std::shared_ptr<xacc::AcceleratorBuffer> getResults() {
return buffer;
}
std::shared_ptr<xacc::AcceleratorBuffer> getResults() { return buffer; }
template <typename QuantumKernel>
void vqe(QuantumKernel &&kernel, double observable, std::shared_ptr<Optimizer> optimizer) {
xacc::info("[qcor] Executing vqe! :)");
xacc::info("[qcor] vqe running with " + optimizer->name() + " optimizer.");
void vqe(QuantumKernel &&kernel, xacc::Observable &observable,
std::shared_ptr<Optimizer> optimizer) {
auto function = qcor::loadCompiledCircuit(kernel());
auto nPhysicalQubits = function->nPhysicalBits();
auto accelerator = xacc::getAccelerator();
buffer = accelerator->createBuffer("q", nPhysicalQubits);
// Here we just need to make a lambda function
// to optimize that makes calls to the targeted QPU.
OptFunction f(
[&](const std::vector<double> &x) {
auto functions = observable.observe(function);
std::vector<double> coefficients;
std::vector<std::string> functionNames;
std::vector<std::shared_ptr<Function>> fsToExec;
double identityCoeff = 0.0;
for (auto &f : functions) {
functionNames.push_back(f->name());
InstructionParameter p = f->getOption("coefficient");
std::complex<double> coeff = p.as<std::complex<double>>();
if (f->nInstructions() > function->nInstructions()) {
fsToExec.push_back(f->operator()(x));
coefficients.push_back(std::real(coeff));
} else {
identityCoeff += std::real(coeff);
}
}
auto buffers = accelerator->execute(buffer, fsToExec);
double energy = identityCoeff;
for (int i = 0; i < buffers.size(); i++) {
energy += buffers[i]->getExpectationValueZ() * coefficients[i];
buffers[i]->addExtraInfo("coefficient", coefficients[i]);
buffers[i]->addExtraInfo("kernel", fsToExec[i]->name());
buffers[i]->addExtraInfo("exp-val-z", buffers[i]->getExpectationValueZ());
buffers[i]->addExtraInfo("parameters", x);
buffer->appendChild(fsToExec[i]->name(), buffers[i]);
}
xacc::info("E("+std::to_string(x[0])+") = " + std::to_string(energy));
return energy;
},
function->nParameters());
// std::cout << f({.55}) << "\n";
auto result = optimizer->optimize(f);
buffer->addExtraInfo("opt-val", ExtraInfo(result.first));
buffer->addExtraInfo("opt-params", ExtraInfo(result.second));
return;
}
template <typename QuantumKernel> void execute(QuantumKernel &&kernel) {
// xacc::info("[qcor] Executing circuit! :)");
auto function = qcor::loadCompiledCircuit(kernel());
int maxBitIdx = 0;
xacc::InstructionIterator it(function);
while (it.hasNext()) {
auto nextInst = it.next();
if (nextInst->isEnabled()) {
for (auto& i : nextInst->bits()) {
if (maxBitIdx < i) {
maxBitIdx = i;
}
}
}
}
maxBitIdx++;
auto nPhysicalQubits = function->nPhysicalBits();
// auto function = kernel();
auto accelerator = xacc::getAccelerator();
buffer = accelerator->createBuffer("q", maxBitIdx);
buffer = accelerator->createBuffer("q", nPhysicalQubits);
accelerator->execute(buffer, function);
}
......
#!/usr/bin/env python3
import argparse
import sys
import subprocess
def parse_args(args):
parser = argparse.ArgumentParser(description="QCOR Quantum-Classical C++ Compiler.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
fromfile_prefix_chars='@')
parser.add_argument(
'file', help='The quantum-classical C++ file to compile.')
parser.add_argument("-a", "--accelerator", type=str,
help="The target quantum accelerator", required=False)
parser.add_argument("-I", '--include', action='append', type=str,
help="Extra include paths to search", required=False)
parser.add_argument("-o", '--output', type=str,
help="Name of output binary", required=False)
parser.add_argument("-v", '--verbose', action='store_true',
help="Print verbose compiler output.", required=False)
opts = parser.parse_args(args)
return opts
def main(argv=None):
opts = parse_args(sys.argv[1:])
command = ["@CLANG_COMPILER@", '-std=c++11', '-Xclang', '-load', '-Xclang', '@CMAKE_INSTALL_PREFIX@/lib/libqcor-ast-plugin.so',
'-Xclang', '-add-plugin', '-Xclang', 'enable-quantum']
if opts.accelerator:
command += ['-plugin-arg-enable-quantum', '-Xclang', 'accelerator', '-Xclang',
'-plugin-arg-enable-quantum', '-Xclang', opts.accelerator]
command += ['-I', '@CMAKE_INSTALL_PREFIX@/include/xacc', '-I', '@CMAKE_INSTALL_PREFIX@/include/quantum/gate',
'-I', '@CMAKE_INSTALL_PREFIX@/include/cppmicroservices4', '-I', '@CMAKE_INSTALL_PREFIX@/include/qcor']
command += ['-L', '@CMAKE_INSTALL_PREFIX@/lib', '-lxacc',
'-lqcor', '-lCppMicroServices', '-lxacc-quantum-gate']
command += [opts.file]
if opts.output:
command += ['-o', opts.output]
if opts.verbose:
command += ['-v']
try:
result = subprocess.run(command, check=True)
except subprocess.CalledProcessError as e:
print(e.output)
print(e.returncode)
return e.returncode
return 0
if __name__ == "__main__":
sys.exit(main())
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