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

Starting on Preprocessor and KernelReplacementPreprocessor

parent db56699f
......@@ -31,6 +31,7 @@
#include <regex>
#include "GateQIR.hpp"
#include "ScaffoldCompiler.hpp"
#include "ScaffoldIRToSrcVisitor.hpp"
using namespace clang;
......@@ -159,10 +160,18 @@ std::shared_ptr<IR> ScaffoldCompiler::compile(const std::string& src) {
}
const std::string ScaffoldCompiler::translate(std::shared_ptr<Function> function) {
std::string srcString = "";
auto visitor = std::make_shared<ScaffoldIRToSrcVisitor>("");
InstructionIterator it(function);
while (it.hasNext()) {
// Get the next node in the tree
auto nextInst = it.next();
if (nextInst->isEnabled()) {
nextInst->accept(visitor);
}
}
return srcString;
return visitor->getScaffoldString();
}
......
......@@ -32,6 +32,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/utils)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ir)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ir/instructions)
add_subdirectory(compiler)
add_subdirectory(ir)
add_subdirectory(utils)
......
#***********************************************************************************
# Copyright (c) 2016, UT-Battelle
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the xacc nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Contributors:
# Initial API and implementation - Alex McCaskey
#
#**********************************************************************************/
set (PACKAGE_NAME "Quantum XACC Gate Compiler Runtime")
set (PACKAGE_DESCIPTION "Quantum XACC Gate Compiler Utilities")
set (LIBRARY_NAME xacc-gate-compiler)
file (GLOB HEADERS *.hpp)
file (GLOB SRC *.cpp)
add_library(${LIBRARY_NAME} SHARED ${SRC})
install(FILES ${HEADERS} DESTINATION include/quantum/gate)
install(TARGETS ${LIBRARY_NAME} DESTINATION lib)
# Gather tests
file (GLOB test_files tests/*.cpp)
add_tests("${test_files}" "${CMAKE_CURRENT_SOURCE_DIR}" "${Boost_LIBRARIES};xacc-gate-ir;xacc-gate-compiler")
#include "KernelReplacementPreprocessor.hpp"
namespace xacc {
namespace quantum {
KernelReplacementPreprocessor::KernelReplacementPreprocessor() {}
const std::string KernelReplacementPreprocessor::process(const std::string& source,
std::shared_ptr<Compiler> compiler,
std::shared_ptr<Accelerator> accelerator) {
std::cout << "Running Kernel Replacement Preprocessor.\n";
return source;
}
}
}
#ifndef XACC_COMPILER_KERNELREPLACEMENTPREPROCESSOR_HPP_
#define XACC_COMPILER_KERNELREPLACEMENTPREPROCESSOR_HPP_
#include "Preprocessor.hpp"
#include "Utils.hpp"
namespace xacc {
namespace quantum {
class KernelReplacementPreprocessor : public xacc::Preprocessor {
public:
KernelReplacementPreprocessor();
/**
* This method is to be implemented by subclasses to take in a
* kernel source string and process it in an isomorphic manner, and
* returns the processed source code.
*
* @param src The unprocessed kernel source code
* @param compiler The compiler being used to compile the code
* @param accelerator The Accelerator this code will be run on
*
* @return processedSrc The processed kernel source code
*/
virtual const std::string process(const std::string& source,
std::shared_ptr<Compiler> compiler,
std::shared_ptr<Accelerator> accelerator);
/**
* Return the name of this Preprocessor
* @return name Preprocessor name
*/
virtual const std::string getName() {
return "kernel-replacement";
}
/**
* Register this Preprocessor with the framework.
*/
static void registerPreprocessor() {
std::cout << "REGISTERING PreProcessor\n";
xacc::RegisterPreprocessor<xacc::quantum::KernelReplacementPreprocessor> KernelReplacement(
"kernel-replacement");
}
virtual ~KernelReplacementPreprocessor() {}
};
// Create an alias to search for.
RegisterPreprocessor(xacc::quantum::KernelReplacementPreprocessor)
}
}
#endif
/***********************************************************************************
* Copyright (c) 2016, UT-Battelle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the xacc nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
* Initial API and implementation - Alex McCaskey
*
**********************************************************************************/
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE KernelReplacementPPTester
#include <boost/test/included/unit_test.hpp>
#include "KernelReplacementPreprocessor.hpp"
using namespace xacc::quantum;
BOOST_AUTO_TEST_CASE(checkSimple) {
}
......@@ -120,6 +120,11 @@ public:
getInstruction(idx), replacingInst);
}
virtual void insertInstruction(const int idx, InstPtr newInst) {
auto iter = std::next(instructions.begin(), idx);
instructions.insert(iter, newInst);
}
/**
* Return the name of this function
* @return
......
......@@ -38,6 +38,7 @@
#include "Accelerator.hpp"
#include "CLIParser.hpp"
#include "Program.hpp"
#include "Preprocessor.hpp"
namespace xacc {
......@@ -53,17 +54,19 @@ auto tmpInitConsole = spdlog::stdout_logger_mt("xacc-console");
void Initialize(int argc, char** argv) {
XACCInfo("[xacc] Initializing XACC Framework");
// Parse any user-supplied command line options
CLIParser parser(argc, argv);
parser.parse();
// Get reference to our compiler and accelerator registries
auto compilerRegistry = xacc::CompilerRegistry::instance();
auto acceleratorRegistry = xacc::AcceleratorRegistry::instance();
auto preprocessorRegistry = xacc::PreprocessorRegistry::instance();
// Parse any user-supplied command line options
CLIParser parser(argc, argv);
parser.parse();
// Check that we have some
auto s = compilerRegistry->size();
auto a = acceleratorRegistry->size();
auto ps = preprocessorRegistry->size();
if (s == 0) XACCError("There are no Compiler instances available. Exiting.");
if (a == 0) XACCError("There are no Accelerator instances available. Exiting.");
......@@ -73,7 +76,13 @@ void Initialize(int argc, char** argv) {
XACCInfo(
"[xacc::accelerator] XACC has " + std::to_string(a) + " Accelerator"
+ ((s == 0 || s == 1) ? "" : "s") + " available.");
XACCInfo(
"[xacc::preprocessor] XACC has " + std::to_string(ps) + " Preprocessor"
+ ((ps == 0 || ps == 1) ? "" : "s") + " available.");
for (auto x : preprocessorRegistry->getRegisteredIds()) {
std::cout << "HEY WORLD " << x << "\n";
}
// We're good if we make it here, so indicate that we've been
// initialized
xacc::xaccFrameworkInitialized = true;
......@@ -105,6 +114,7 @@ void Finalize() {
"\n[xacc::accelerator] Cleaning up Accelerator Registry.");
xacc::CompilerRegistry::instance()->destroy();
xacc::AcceleratorRegistry::instance()->destroy();
xacc::PreprocessorRegistry::instance()->destroy();
xacc::xaccFrameworkInitialized = false;
}
}
......
......@@ -129,6 +129,19 @@ public:
}
}
/**
* Return all allocated AcceleratorBuffer variable names.
*
* @return varNames The buffer variable names
*/
virtual std::vector<std::string> getAllocatedBufferNames() {
std::vector<std::string> names;
for (auto b : allocatedBuffers) {
names.push_back(b.first);
}
return names;
}
/**
* Return true if this Accelerator can allocated
* NBits number of bits.
......
#ifndef XACC_COMPILER_PREPROCESSOR_HPP_
#define XACC_COMPILER_PREPROCESSOR_HPP_
#include "Compiler.hpp"
namespace xacc {
/**
*
*/
class Preprocessor : public OptionsProvider {
public:
Preprocessor() {}
/**
* This method is to be implemented by subclasses to take in a
* kernel source string and process it in an isomorphic manner, and
* returns the processed source code.
*
* @param src The unprocessed kernel source code
* @param compiler The compiler being used to compile the code
* @param accelerator The Accelerator this code will be run on
*
* @return processedSrc The processed kernel source code
*/
virtual const std::string process(const std::string& source,
std::shared_ptr<Compiler> compiler,
std::shared_ptr<Accelerator> accelerator) = 0;
/**
* Return the name of this Preprocessor
*
* @return name The name of this preprocessor
*/
virtual const std::string getName() = 0;
/**
* Return an empty options_description, this is for
* subclasses to implement.
*/
virtual std::shared_ptr<options_description> getOptions() {
return std::make_shared<options_description>();
}
~Preprocessor() {}
};
/**
* Preprocessor Registry is just an alias for a
* Registry of Preprocessors.
*/
using PreprocessorRegistry = Registry<Preprocessor>;
/**
* RegisterPreprocessor is a convenience class for
* registering custom derived Preprocessor classes.
*
* Creators of Preprocessor subclasses create an instance
* of this class with their Preprocessor subclass as the template
* parameter to register their Preprocessor with XACC. This instance
* must be created in the CPP implementation file for the Preprocessor
* and at global scope.
*/
template<typename T>
class RegisterPreprocessor {
public:
RegisterPreprocessor(const std::string& name) {
PreprocessorRegistry::instance()->add(name,
(std::function<std::shared_ptr<xacc::Preprocessor>()>) ([]() {
std::cout << "I AM TRYING TO CREATE THIS THING\n";
return std::make_shared<T>();
}));
}
};
#define RegisterPreprocessor(TYPE) BOOST_DLL_ALIAS(TYPE::registerPreprocessor, registerPreprocessor)
}
#endif
......@@ -82,6 +82,16 @@ public:
*/
virtual void replaceInstruction(const int idx, InstPtr newInst) = 0;
/**
* Insert a new Instruction at the given index. All previous
* instructions are pushed back, ie their new indices are
* currentIndex + 1.
*
* @param idx The index where the new instruction should be inserted
* @param newInst The new Instruction to insert.
*/
virtual void insertInstruction(const int idx, InstPtr newInst) = 0;
/**
* Add an Instruction to this Function.
*
......
......@@ -43,6 +43,7 @@
#include "Compiler.hpp"
#include "Accelerator.hpp"
#include "RuntimeOptions.hpp"
#include "Preprocessor.hpp"
namespace xacc {
......@@ -57,6 +58,21 @@ std::vector<IRTransformation> getAcceleratorIndependentTransformations(
return transformations;
}
std::vector<std::shared_ptr<Preprocessor>> getDefaultPreprocessors(AcceleratorType accType) {
std::vector<std::shared_ptr<Preprocessor>> preprocessors;
auto ppRegistry = PreprocessorRegistry::instance();
std::cout << "We have " << ppRegistry->size() << " preprocessors\n";
for (auto s : ppRegistry->getRegisteredIds()) {
std::cout << "HI: " << s << "\n";
}
if (accType == AcceleratorType::qpu_gate) {
preprocessors.push_back(
ppRegistry->create("kernel-replacement"));
}
return preprocessors;
}
/**
* The Program is the main entrypoint for the XACC
* API. Users with accelerator kernels must construct a
......@@ -114,6 +130,16 @@ protected:
XACCError("Invalid Compiler.\n");
}
// Before compiling, run any preprocessors
auto ppRegistry = PreprocessorRegistry::instance();
auto pp = ppRegistry->create("kernel-replacement");
src = pp->process(src, compiler, accelerator);
// auto defaultPPs = getDefaultPreprocessors(accelerator->getType());
// for (auto preprocessor : defaultPPs) {
// src = preprocessor->process(src, compiler, accelerator);
// }
XACCInfo("Executing "+ compiler->getName() + " compiler.");
// Execute the compilation
......
......@@ -37,6 +37,7 @@
#include <boost/program_options.hpp>
#include "RuntimeOptions.hpp"
#include "xacc_config.hpp"
#include "Preprocessor.hpp"
using namespace boost::program_options;
......@@ -84,6 +85,8 @@ public:
// Get a reference to the RuntimeOptions
auto runtimeOptions = RuntimeOptions::instance();
auto inst = PreprocessorRegistry::instance();
// Create a base options_description, we will add
// to this with all OptionsProviders
auto compilerOptions = std::make_shared<options_description>(
......@@ -135,6 +138,14 @@ public:
dll::load_mode::append_decorations);
regFunc();
}
if (lib.has("registerPreprocessor")) {
typedef void (RegisterPreprocessor)();
auto regFunc = boost::dll::import_alias<
RegisterPreprocessor>(p,
"registerPreprocessor",
dll::load_mode::append_decorations);
regFunc();
}
}
}
}
......
......@@ -75,7 +75,8 @@ public:
XACCInfo(id + " already exists in Registry. Ignoring and retaining previous Registry entry");
return true;
}
bool s = registry.insert(std::make_pair(id, f)).second;
std::cout << "ADDING " << id << " to registry\n";
bool s = registry.insert(std::make_pair(id, std::move(f))).second;
if (!s) {
XACCError("Could not add " + id + " to the Registry.");
} else {
......@@ -93,6 +94,7 @@ public:
std::shared_ptr<T> create(const std::string& id, TArgs... args) {
auto search = registry.find(id);
if (search != registry.end()) {
std::cout << "Creating " << id << ".\n";
return registry[id](args...);
} else {
XACCError("Invalid Registry map id string - " + id);
......
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