Skip to content
Snippets Groups Projects
Commit 82ccc151 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

setting up teleport to use new scaffold compiler, will soon replace old one now

parent 78aea006
No related branches found
No related tags found
No related merge requests found
......@@ -38,6 +38,8 @@ include_directories(${CMAKE_SOURCE_DIR}/quantum/gate/gateqir)
include_directories(${CMAKE_SOURCE_DIR}/quantum/gate/gateqir/instructions)
include_directories(${CMAKE_SOURCE_DIR}/quantum/gate/gateqir/functions)
link_directories(${CLANG_LIBRARY_DIRS})
add_executable(teleport_scaffold teleport_scaffold.cpp)
target_link_libraries(teleport_scaffold xacc-scaffold ${Boost_LIBRARIES} xacc-firetensor xacc-gateqir)
target_link_libraries(teleport_scaffold xacc-improved-scaffold ${CLANG_LIBS} ${LLVM_LIBS} ${Boost_LIBRARIES} xacc-firetensor xacc-gateqir dl pthread)
......@@ -56,7 +56,89 @@ ImprovedScaffoldCompiler::ImprovedScaffoldCompiler() {
std::shared_ptr<IR> ImprovedScaffoldCompiler::compile(const std::string& src,
std::shared_ptr<Accelerator> acc) {
return std::make_shared<GateQIR>();
// Set the Kernel Source code
kernelSource = src;
// Replace the __qpu__ attribute with module
if (boost::contains(kernelSource, "__qpu__")) {
kernelSource.erase(kernelSource.find("__qpu__"), 7);
kernelSource = std::string("module") + kernelSource;
}
// Make a copy, and then delete the body
// of the kernel in that copy, leaving
// just the functionDeclaration(qbit qvar) {}
auto copyOfSrc = kernelSource;
auto firstIdx = copyOfSrc.find_first_of("{");
auto lastIdx = copyOfSrc.find_last_of("}");
copyOfSrc.erase(firstIdx+1, lastIdx);
copyOfSrc = copyOfSrc + "}";
// Now we just want to get the qubit variable name,
// so lets compile the function declaration
// Create a temporary scaffold source file
std::ofstream tempSrcFile(".tmpSrcFile.scaffold");
tempSrcFile << copyOfSrc;
tempSrcFile.close();
const FileEntry *pFile = CI->getFileManager().getFile(
".tmpSrcFile.scaffold");
CI->getSourceManager().createMainFileID(pFile);
CI->getASTContext().BuiltinInfo.InitializeBuiltins(
CI->getPreprocessor().getIdentifierTable(), CI->getLangOpts());
consumer = std::make_shared<scaffold::ScaffoldASTConsumer>();
clang::ParseAST(CI->getPreprocessor(), consumer.get(), CI->getASTContext());
std::remove(".tmpSrcFile.scaffold");
// Get the Qubit variable name
auto qubitVarName = consumer->getQubitVariableName();
// Update the kernelSource with the correct
// number of qubits in this variable
auto nBits = acc->getBuffer(qubitVarName)->size();
auto searchFor = "qbit " + qubitVarName;
auto replaceWith = "qbit " + qubitVarName + "[" + std::to_string(nBits) + "]";
boost::replace_all(kernelSource, searchFor, replaceWith);
// Create a compiler all over again
CI = std::make_shared<CompilerInstance>();
CI->createDiagnostics(0, 0);
TargetOptions targetOptions;
targetOptions.Triple = llvm::sys::getDefaultTargetTriple();
TargetInfo *pTargetInfo = TargetInfo::CreateTargetInfo(CI->getDiagnostics(),
targetOptions);
CI->setTarget(pTargetInfo);
CI->createFileManager();
CI->createSourceManager(CI->getFileManager());
CI->createPreprocessor();
CI->getPreprocessorOpts().UsePredefines = false;
CI->createASTContext();
// Create a source file with all the code in it
std::ofstream tempSrcFile2(".tmpSrcFile2.scaffold");
tempSrcFile2 << kernelSource;
tempSrcFile2.close();
const FileEntry *pFile2 = CI->getFileManager().getFile(
".tmpSrcFile2.scaffold");
CI->getSourceManager().createMainFileID(pFile2);
CI->getASTContext().BuiltinInfo.InitializeBuiltins(
CI->getPreprocessor().getIdentifierTable(), CI->getLangOpts());
// Compile the code!
consumer = std::make_shared<scaffold::ScaffoldASTConsumer>();
clang::ParseAST(CI->getPreprocessor(), consumer.get(), CI->getASTContext());
// Get the IR Function representation
auto qirFunction = consumer->getFunction();
// Create a Quantum IR instance
auto qir = std::make_shared<GateQIR>();
// Give the function to the IR
qir->addKernel(qirFunction);
// Return...
return qir;
}
std::shared_ptr<IR> ImprovedScaffoldCompiler::compile(const std::string& src) {
......@@ -80,13 +162,14 @@ std::shared_ptr<IR> ImprovedScaffoldCompiler::compile(const std::string& src) {
CI->getASTContext().BuiltinInfo.InitializeBuiltins(
CI->getPreprocessor().getIdentifierTable(), CI->getLangOpts());
consumer = std::make_shared<scaffold::ScaffoldASTConsumer>();//&CI->getASTContext());
consumer = std::make_shared<scaffold::ScaffoldASTConsumer>();
clang::ParseAST(CI->getPreprocessor(), consumer.get(), CI->getASTContext());
auto qirFunction = consumer->getFunction();
auto qir = std::make_shared<GateQIR>();
std::cout << "HELLO WORLD ADDING : " << qirFunction->getName() << "\n";
qir->addKernel(qirFunction);
return qir;
......
......@@ -62,14 +62,19 @@ public:
virtual std::shared_ptr<xacc::IR> compile(const std::string& src,
std::shared_ptr<Accelerator> acc);
virtual std::shared_ptr<xacc::IR> compile(const std::string& src);
/**
*
* @param src
* @return
*/
virtual std::string getBitType() {
return "qbit";
virtual std::shared_ptr<xacc::IR> compile(const std::string& src);
/**
* Return the name of this Compiler
* @return name Compiler name
*/
virtual const std::string getName() {
return "ImprovedScaffold";
}
/**
......@@ -79,67 +84,17 @@ public:
protected:
std::string cbitVarName;
std::string qbitVarName;
std::shared_ptr<clang::CompilerInstance> CI;
std::shared_ptr<scaffold::ScaffoldASTConsumer> consumer;
/**
* Reference to potential conditional code
*/
std::vector<std::string> conditionalCodeSegments;
/**
*
* Reference to the Scaffold Clang Compiler
*/
std::vector<int> conditionalCodeSegmentActingQubits;
std::map<int, std::vector<std::string>> gateIdToParameterMap;
std::shared_ptr<clang::CompilerInstance> CI;
/**
*
* Reference to our AST Consumer, this gives us the
* compiled IR Function and the Qubit Variable Name
*/
std::map<std::string, std::string> typeToVarKernelArgs;
std::vector<std::string> orderOfArgs;
std::vector<std::string> orderedVarNames;
virtual std::vector<std::string> getKernelArgumentVariableNames() {
return orderedVarNames;
}
std::shared_ptr<scaffold::ScaffoldASTConsumer> consumer;
void kernelArgsToMap() {
auto firstParen = kernelSource.find_first_of('(');
auto secondParen = kernelSource.find_first_of(')', firstParen);
auto functionArguments = kernelSource.substr(firstParen+1, (secondParen-firstParen)-1);
int counter = 0;
if (!functionArguments.empty()) {
// First search the prototype to see if it has
// and argument that declares the accelerator bit buffer
// to use in the kernel
std::vector<std::string> splitArgs, splitTypeVar;
boost::split(splitArgs, functionArguments, boost::is_any_of(","));
std::string varName;
for (int i = 0; i < splitArgs.size(); i++) {
// split type from var name
auto s = splitArgs[i];
boost::trim(s);
boost::split(splitTypeVar, s, boost::is_any_of(" "));
auto type = splitTypeVar[0];
auto var = splitTypeVar[1];
boost::trim(type);
boost::trim(var);
typeToVarKernelArgs.insert(std::make_pair(type, var));
orderOfArgs.push_back(type);
orderedVarNames.push_back(var);
}
}
}
};
}
......
......@@ -54,10 +54,14 @@ public:
bool VisitDecl(clang::Decl *d);
bool VisitCallExpr(CallExpr * c);
bool VisitBinaryOperator(BinaryOperator *b);
auto getFunction() {
std::shared_ptr<xacc::Function> getFunction() {
return function;
}
const std::string getQubitVariableName() {
return qbitVarName;
}
virtual ~ScaffoldASTConsumer() {
}
......
......@@ -96,12 +96,10 @@ BOOST_AUTO_TEST_CASE(checkWithRzParameterized) {
auto k = gateqir->getKernel("teleport");
BOOST_VERIFY(k->nInstructions() == 1);
std::cout << "STR: \n\n" << k->toString("qreg") << "\n";
}
BOOST_AUTO_TEST_CASE(checkWithMeasurementIf) {
std::cout <<" CHECKING WITH MEASUREMNT IF\n";
const std::string src("module teleport (qbit qreg[3]) {\n"
" cbit creg[2];\n"
" // Init qubit 0 to 1\n"
......@@ -123,9 +121,6 @@ BOOST_AUTO_TEST_CASE(checkWithMeasurementIf) {
BOOST_VERIFY(gateqir->numberOfKernels() == 1);
auto k = gateqir->getKernel("teleport");
std::cout << "STR: \n\n" << k->toString("qreg") << "\n";
}
......
......@@ -64,6 +64,10 @@ public:
virtual std::shared_ptr<xacc::IR> compile(const std::string& src);
virtual const std::string getName() {
return "Scaffold";
}
/**
*
* @return
......
......@@ -98,8 +98,7 @@ public:
*/
virtual void execute(std::shared_ptr<AcceleratorBuffer> buffer,
const std::shared_ptr<Function> function) = 0;
virtual void execute(std::shared_ptr<AcceleratorBuffer> buffer,
const std::shared_ptr<IR> function) {}
/**
* Create, store, and return an AcceleratorBuffer with the given
* variable id string. This string serves as a unique identifier
......
......@@ -74,6 +74,12 @@ public:
*/
virtual std::shared_ptr<IR> compile(const std::string& src) = 0;
/**
* Return the name of this Compiler
* @return name Compiler name
*/
virtual const std::string getName() = 0;
/**
* The destructor
*/
......
......@@ -121,14 +121,12 @@ protected:
// Create the appropriate compiler
compiler = xacc::CompilerRegistry::instance()->create(compilerToRun);
std::cout << "Executing " << compiler->getName() << " compiler.\n";
// Make sure we got a valid
if (!compiler) {
XACCError("Invalid Compiler.\n");
}
// Update src with runtimeArgs...
// Execute the compilation
xaccIR = compiler->compile(src, accelerator);
......@@ -192,9 +190,9 @@ public:
std::function<void(std::shared_ptr<AcceleratorBuffer>, RuntimeArgs...)> getKernel(
const std::string& kernelName) {
return [&](std::shared_ptr<AcceleratorBuffer> buffer, RuntimeArgs... args) {
build("--compiler scaffold", args...);
build("--compiler improvedscaffold", args...);
auto fToExec = xaccIR->getKernel(kernelName);
accelerator->execute(buffer, xaccIR);
accelerator->execute(buffer, fToExec);
return;
};
}
......
......@@ -50,6 +50,10 @@ public:
}
virtual const std::string getName() {
return "Fake";
}
virtual void modifySource() {
}
......
......@@ -52,6 +52,9 @@ public:
return std::make_shared<FakeIR>();
}
virtual const std::string getName() {
return "Dummy";
}
virtual void modifySource() {
......@@ -89,93 +92,3 @@ BOOST_AUTO_TEST_CASE(checkBuildRuntimeArguments) {
auto k = prog.getKernel("teleport");
// prog.build("--compiler dummy");
}
BOOST_AUTO_TEST_CASE(checkRuntimeGateParameter) {
// Quantum Kernel executing a parameterized gate
// const std::string src("__qpu__ rotate (qbit qreg, double phi) {\n"
// " H(qreg[0]);\n"
// " Rz(qreg[0], phi);\n"
// "}\n");
//
// // Create a convenient alias for our simulator...
// using CircuitSimulator = xacc::quantum::FireTensorAccelerator<6>;
//
// // Create a reference to the 6 qubit simulation Accelerator
// auto qpu = std::make_shared<CircuitSimulator>();
//
// // Allocate 1 qubit, give them a unique identifier...
// auto qubitReg = qpu->createBuffer("qreg", 1);
// using QubitRegisterType = decltype(qubitReg);
//
// // Construct a new XACC Program
// xacc::Program quantumProgram(qpu, src);
//
// // Build the program using Scaffold comipler
// // and output the Graph Intermediate Representation
// quantumProgram.build("--compiler scaffold");
//
// // Retrieve the created kernel. It takes a
// // qubit register as input
// auto rotate = quantumProgram.getKernel<QubitRegisterType, double&>(
// "teleport");
//
// // Execute the kernel with the qubit register!
// double angle = std::acos(-1) / 4.0;
// rotate(qubitReg, angle);
//
// // Pretty print the resultant state
// qubitReg->printBufferState(std::cout);
//
// BOOST_VERIFY(std::real(qubitReg->getState()(0)) == (1.0/std::sqrt(2.0)));
// BOOST_VERIFY(std::real(qubitReg->getState()(1)) == 0.5);
// BOOST_VERIFY(std::fabs(std::imag(qubitReg->getState()(1)) - 0.5) < 1e-6);
}
BOOST_AUTO_TEST_CASE(checkTeleportScaffold) {
// Quantum Kernel executing teleportation of
// qubit state to another.
const std::string src("__qpu__ teleport (qbit qreg) {\n"
" cbit creg[2];\n"
" // Init qubit 0 to 1\n"
" X(qreg[0]);\n"
" // Now teleport...\n"
" H(qreg[1]);\n"
" CNOT(qreg[1],qreg[2]);\n"
" CNOT(qreg[0],qreg[1]);\n"
" H(qreg[0]);\n"
" creg[0] = MeasZ(qreg[0]);\n"
" creg[1] = MeasZ(qreg[1]);\n"
" if (creg[0] == 1) Z(qreg[2]);\n"
" if (creg[1] == 1) X(qreg[2]);\n"
"}\n");
xacc::Initialize();
// Create a reference to the 6 qubit simulation Accelerator
auto qpu = xacc::getAccelerator("firetensor");
// Allocate 3 qubits, give them a unique identifier...
auto qreg = qpu->createBuffer("qreg", 3);
// Construct a new XACC Program
xacc::Program quantumProgram(qpu, src);
// Retrieve the created kernel. It takes a
// qubit register as input
auto teleport = quantumProgram.getKernel("teleport");
// Execute the kernel with the qubit register!
teleport(qreg);
xacc::Finalize();
// Pretty print the resultant state
auto simqreg = std::static_pointer_cast<xacc::quantum::SimulatedQubits<10>>(qreg);
simqreg->print();
BOOST_VERIFY(std::real(simqreg->getState()(1) * simqreg->getState()(1)) == 1 ||
std::real(simqreg->getState()(5) * simqreg->getState()(5)) == 1 ||
std::real(simqreg->getState()(3) * simqreg->getState()(3)) == 1 ||
std::real(simqreg->getState()(7) * simqreg->getState()(7)) == 1);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment