Commit 4b44bef5 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

first commit demonstrating compiler working creating a truly hybrid...


first commit demonstrating compiler working creating a truly hybrid quantum-classical executable, demonstrated with bell state circuit on local ibm accelerator
Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent d2f9e956
Pipeline #43500 passed with stages
in 2 minutes and 16 seconds
......@@ -53,18 +53,6 @@ public:
const std::shared_ptr<Function>
compile(std::shared_ptr<Function> f, std::shared_ptr<Accelerator> acc) override;
/**
* Return the command line options for this compiler
*
* @return options Description of command line options.
*/
virtual std::shared_ptr<options_description> getOptions() {
auto desc =
std::make_shared<options_description>("QCOR Compiler Options");
return desc;
}
virtual bool handleOptions(variables_map &map) { return false; }
/**
* We don't allow translations for the PyXACC Compiler.
......
......@@ -4,6 +4,7 @@
#include "XACC.hpp"
#include "qcor.hpp"
#include "clang/Basic/SourceLocation.h"
using namespace clang;
using namespace xacc;
......@@ -69,6 +70,10 @@ bool LambdaVisitor::CppToXACCIRVisitor::VisitDeclRefExpr(DeclRefExpr *expr) {
bool LambdaVisitor::CppToXACCIRVisitor::VisitIntegerLiteral(
IntegerLiteral *literal) {
bits.push_back(literal->getValue().getLimitedValue());
if (gateName == "Measure") {
InstructionParameter p(bits[0]);
parameters.push_back(p);
}
return true;
}
......@@ -128,12 +133,58 @@ bool LambdaVisitor::VisitLambdaExpr(LambdaExpr *LE) {
auto fileName = qcor::persistCompiledCircuit(function);
// write function ir to file
// Create the const char * QualType
SourceLocation sl;
QualType StrTy = ci.getASTContext().getConstantArrayType(
ci.getASTContext().adjustStringLiteralBaseType(
ci.getASTContext().CharTy.withConst()),
llvm::APInt(32, fileName.length() + 1), ArrayType::Normal, 0);
auto fnameSL = StringLiteral::Create(ci.getASTContext(), StringRef(fileName.c_str()),
StringLiteral::Ascii,
/*Pascal*/ false, StrTy, &sl, 1);
// Create New Return type for CallOperator
auto D = LE->getCallOperator()->getAsFunction();
FunctionProtoType::ExtProtoInfo fpi;
fpi.Variadic = D->isVariadic();
std::vector<QualType> ParamTypes;
llvm::ArrayRef<QualType> Args(ParamTypes);
QualType newFT = D->getASTContext().getFunctionType(StrTy, Args, fpi);
D->setType(newFT);
// Create the return statement that will return
// the string literal
auto rtrn =
ReturnStmt::Create(ci.getASTContext(), SourceLocation(), fnameSL, nullptr);
std::vector<Stmt *> svec;
svec.push_back(rtrn);
llvm::ArrayRef<Stmt *> stmts(svec);
auto cmp = CompoundStmt::Create(ci.getASTContext(), stmts, SourceLocation(),
SourceLocation());
LE->getCallOperator()->setBody(cmp);
// std::cout << "CallOperator getType().asstring(): "
// << LE->getCallOperator()->getType().getAsString() << "\n";
// std::cout << "CallOperator getType()->dump(): ";
// LE->getCallOperator()->getType()->dump();
// std::cout << "CallOperator Result Type: "
// << LE->getCallOperator()->getCallResultType().getAsString()
// << "\n";
// std::cout << "CallOperator dump(): ";
// LE->getCallOperator()->dump();
// LE->dump();
// MY GOAL... write function ir to file
// update LE body to
// [](...) {
// return qcor::loadCompiledCircuit(filename);
// }
}
// LE->getCallOperator()->getBody()
// std::cout << "DUMP AGAIN\n";
// LE->getBody()->dump();
return true;
}
......
......@@ -14,36 +14,30 @@ clang++-9 -std=c++11 -Xclang -load -Xclang compiler/clang/libqcor-ast-plugin.so
-Xclang -plugin-arg-enable-quantum -Xclang tnqvm
-Xclang -plugin-arg-enable-quantum -Xclang transform
-Xclang -plugin-arg-enable-quantum -Xclang circuit-optimizer
test.cpp
-I /root/.xacc/include/xacc -I /root/.xacc/include/cppmicroservices4
-I /home/project/qcor/runtime -L /home/project/qcor/build/runtime
-lqcor -L /root/.xacc/lib -lxacc test.cpp -o test
test.cpp looks like this
#include <stdio.h>
#include "qcor.hpp"
#include <stdio.h>
#include <string>
void foo() {
printf("hi\n");
qcor::submit([&](qcor::qpu_handler& qh){
qh.vqe([&](double t0){
X(0);
Ry(t0,0);
CX(1,0);
}, 1, 1);
});
auto future = qcor::submit([&](qcor::qpu_handler& qh){
qh.execute([&](double t0){
X(2);
Ry(t0,1);
CX(1,2);
int main() {
xacc::Initialize({"--accelerator", "local-ibm"});
auto future2 = qcor::submit([&](qcor::qpu_handler &qh) {
qh.execute([&]() {
H(0);
CX(0, 1);
Measure(0);
Measure(1);
});
});
printf("hi %d\n", future.get());
}
auto results = future2.get();
int main() {
foo();
results->print();
printf("\n");
}
\ No newline at end of file
#include "qcor.hpp"
#include "qpu_handler.hpp"
#include "AcceleratorBuffer.hpp"
#include "IRProvider.hpp"
#include "XACC.hpp"
......@@ -8,22 +10,48 @@ using namespace xacc;
namespace qcor {
const std::string persistCompiledCircuit(std::shared_ptr<Function> function) {
return "";
std::function<char()> randChar = []() -> char {
const char charset[] = "0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
const size_t max_index = (sizeof(charset) - 1);
return charset[rand() % max_index];
};
auto generateRandomString = [&](const int length = 10) -> const std::string {
std::string str(length, 0);
std::generate_n(str.begin(), length, randChar);
return str;
};
return generateRandomString();
}
std::shared_ptr<Function> loadCompiledCircuit() {
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);
return function;
}
std::future<int> submit(HandlerLambda &&totalJob) {
std::future<std::shared_ptr<AcceleratorBuffer>> submit(HandlerLambda &&totalJob) {
// Create the QPU Handler to pass to the given
// Handler HandlerLambda
qpu_handler handler;
return std::async(std::launch::async, [&] {
return std::async(std::launch::async, [&]() {
totalJob(handler);
return 1;
return handler.getResults();
});
}
......
#ifndef RUNTIME_QCOR_HPP_
#define RUNTIME_QCOR_HPP_
#include "AcceleratorBuffer.hpp"
#include <future>
#include "qpu_handler.hpp"
namespace xacc {
class Function;
class Function;
class AcceleratorBuffer;
}
using namespace xacc;
namespace qcor {
class qpu_handler;
using HandlerLambda = std::function<void(qpu_handler &)>;
// Persist the given function to file, return
......@@ -23,8 +26,11 @@ const std::string persistCompiledCircuit(std::shared_ptr<Function> function);
std::shared_ptr<Function> loadCompiledCircuit(const std::string &fileName);
// Submit an asynchronous job to the QPU
std::future<int> submit(HandlerLambda &&);
std::future<std::shared_ptr<AcceleratorBuffer>> submit(HandlerLambda &&);
} // namespace qcor
#include "qpu_handler.hpp"
#endif
#ifndef RUNTIME_QPU_HANDLER_HPP_
#define RUNTIME_QPU_HANDLER_HPP_
#include <string>
#include "XACC.hpp"
#include "qcor.hpp"
#include "Function.hpp"
#include "AcceleratorBuffer.hpp"
#include "InstructionIterator.hpp"
#include <string>
namespace qcor {
class qpu_handler {
protected:
std::shared_ptr<xacc::AcceleratorBuffer> buffer;
public:
std::shared_ptr<xacc::AcceleratorBuffer> getResults() {
return buffer;
}
template <typename QuantumKernel>
void vqe(QuantumKernel &&kernel, double observable, double optimizer) {
xacc::info("qcor executing vqe.");
xacc::info("[qcor] Executing vqe! :)");
}
template <typename QuantumKernel> void execute(QuantumKernel &&kernel) {}
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 function = kernel();
auto accelerator = xacc::getAccelerator();
buffer = accelerator->createBuffer("q", maxBitIdx);
accelerator->execute(buffer, function);
}
template <typename QuantumKernel>
void execute(const std::string &algorithm, QuantumKernel &&kernel) {}
......
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