Commit 6dd144dc authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

Majorly re-worked xacc package, Function is now CompositeInstruction,...


Majorly re-worked xacc package, Function is now CompositeInstruction, simplified interfaces, using heterogeneous map, updated and simplified gate ir
Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent 963da481
......@@ -93,7 +93,7 @@ add_subdirectory(tpls)
add_subdirectory(xacc)
add_subdirectory(quantum)
if(PYTHON_INCLUDE_DIR)
add_subdirectory(python)
#add_subdirectory(python)
endif()
#find_package(Clang 9.0.0)
......
# *******************************************************************************
# Copyright (c) 2017 UT-Battelle, LLC.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# and Eclipse Distribution License v.10 which accompany this distribution.
# The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
# and the Eclipse Distribution License is available at
# https://eclipse.org/org/documents/edl-v10.php
#
# Contributors:
# Alexander J. McCaskey - initial API and implementation
# *******************************************************************************/
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_BINARY_DIR}/tpls/cppmicroservices")
include(CppMicroServicesConfig)
add_subdirectory(utils)
add_subdirectory(gate)
add_subdirectory(aqc)
add_subdirectory(plugins)
file (GLOB HEADERS utils/*.hpp)
install(FILES ${HEADERS} DESTINATION include/quantum/utils)
set(LIBRARY_NAME xacc-quantum-irprovider)
file(GLOB QHEADERS *.hpp)
file(GLOB SRC
*.cpp)
# Set up dependencies to resources to track changes
usFunctionGetResourceSource(TARGET ${LIBRARY_NAME} OUT SRC)
# Generate bundle initialization code
usFunctionGenerateBundleInit(TARGET ${LIBRARY_NAME} OUT SRC)
add_library(${LIBRARY_NAME} SHARED ${SRC})
add_dependencies(${LIBRARY_NAME} antlr4_shared)
target_include_directories(${LIBRARY_NAME}
PRIVATE
gate/ir aqc/ir ${CMAKE_SOURCE_DIR}/tpls/exprtk)
set(_bundle_name xacc_quantum_irprovider)
set_target_properties(${LIBRARY_NAME}
PROPERTIES # This is required for every bundle
COMPILE_DEFINITIONS
US_BUNDLE_NAME=${_bundle_name}
# This is for convenience, used by other CMake
# functions
US_BUNDLE_NAME ${_bundle_name})
# Embed meta-data from a manifest.json file
usFunctionEmbedResources(TARGET
${LIBRARY_NAME}
WORKING_DIRECTORY
${CMAKE_CURRENT_SOURCE_DIR}
FILES
manifest.json)
target_link_libraries(${LIBRARY_NAME} PUBLIC xacc PRIVATE xacc-quantum-gate xacc-quantum-aqc)
target_compile_features(${LIBRARY_NAME}
PUBLIC
cxx_std_14
cxx_alias_templates)
if(APPLE)
set_target_properties(${LIBRARY_NAME}
PROPERTIES INSTALL_RPATH "@loader_path/../lib")
set_target_properties(${LIBRARY_NAME}
PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
else()
set_target_properties(${LIBRARY_NAME} PROPERTIES INSTALL_RPATH "$ORIGIN/../lib")
set_target_properties(${LIBRARY_NAME} PROPERTIES LINK_FLAGS "-shared")
endif()
#install(FILES ${QHEADERS} DESTINATION include/quantum/)
install(TARGETS ${LIBRARY_NAME} DESTINATION plugins)
if (XACC_BUILD_EXAMPLES)
add_subdirectory(examples)
endif()
\ No newline at end of file
add_subdirectory(ir_provider)
\ No newline at end of file
......@@ -15,15 +15,9 @@ set(LIBRARY_NAME xacc-quantum-gate)
file(GLOB_RECURSE HEADERS *.hpp)
file(GLOB SRC
*.cpp
accelerator/*.cpp
compiler/*.cpp
ir/*.cpp
ir/instructions/*.cpp
utils/*.cpp
ir/algorithms/*.cpp
ir/transformations/*.cpp
ir/parser/*.cpp
ir/parser/generated/*.cpp)
)
# Set up dependencies to resources to track changes
......@@ -33,20 +27,16 @@ usFunctionGetResourceSource(TARGET ${LIBRARY_NAME} OUT SRC)
usFunctionGenerateBundleInit(TARGET ${LIBRARY_NAME} OUT SRC)
add_library(${LIBRARY_NAME} SHARED ${SRC})
add_dependencies(${LIBRARY_NAME} antlr4_shared)
#add_dependencies(${LIBRARY_NAME} antlr4_shared)
target_include_directories(${LIBRARY_NAME}
PUBLIC utils
ir
compiler
ir/instructions
ir/algorithms
accelerator
${CMAKE_SOURCE_DIR}/tpls/rapidjson/include
#compiler
#accelerator
PRIVATE
${CMAKE_BINARY_DIR}
${CMAKE_SOURCE_DIR}/quantum/utils
${CMAKE_SOURCE_DIR}/tpls/exprtk
${CMAKE_SOURCE_DIR}/tpls/rapidjson/include
${CMAKE_SOURCE_DIR}/tpls/taocpp
${CMAKE_SOURCE_DIR}/tpls/eigen)
......@@ -74,20 +64,20 @@ target_compile_features(${LIBRARY_NAME}
cxx_alias_templates)
if(APPLE)
set_target_properties(xacc-quantum-gate
set_target_properties(${LIBRARY_NAME}
PROPERTIES INSTALL_RPATH "@loader_path")
set_target_properties(xacc-quantum-gate
set_target_properties(${LIBRARY_NAME}
PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
else()
set_target_properties(xacc-quantum-gate PROPERTIES INSTALL_RPATH "$ORIGIN")
set_target_properties(xacc-quantum-gate PROPERTIES LINK_FLAGS "-shared")
set_target_properties(${LIBRARY_NAME} PROPERTIES INSTALL_RPATH "$ORIGIN")
set_target_properties(${LIBRARY_NAME} PROPERTIES LINK_FLAGS "-shared")
endif()
add_subdirectory(observable)
add_subdirectory(compiler)
#add_subdirectory(observable)
#add_subdirectory(compiler)
add_subdirectory(ir)
add_subdirectory(utils)
add_subdirectory(accelerator)
#add_subdirectory(accelerator)
install(FILES ${HEADERS} DESTINATION include/quantum/gate)
install(TARGETS ${LIBRARY_NAME} DESTINATION lib)
......@@ -10,20 +10,20 @@
* Contributors:
* Alexander J. McCaskey - initial API and implementation
*******************************************************************************/
#include "QFT.hpp"
#include "InverseQFT.hpp"
// #include "QFT.hpp"
// #include "InverseQFT.hpp"
#include "cppmicroservices/BundleActivator.h"
#include "cppmicroservices/BundleContext.h"
#include "cppmicroservices/ServiceProperties.h"
#include "GateIRProvider.hpp"
#include "DigitalGates.hpp"
// #include "QuantumIRProvider.hpp"
#include "CommonGates.hpp"
#include "CircuitOptimizer.hpp"
// #include "CircuitOptimizer.hpp"
#include "ROErrorDecorator.hpp"
#include "ImprovedSamplingDecorator.hpp"
#include "RichExtrapDecorator.hpp"
// #include "ROErrorDecorator.hpp"
// #include "ImprovedSamplingDecorator.hpp"
// #include "RichExtrapDecorator.hpp"
#include <memory>
#include <set>
......@@ -42,32 +42,32 @@ public:
/**
*/
void Start(BundleContext context) {
auto qft = std::make_shared<xacc::quantum::QFT>();
auto iqft = std::make_shared<xacc::quantum::InverseQFT>();
// auto qft = std::make_shared<xacc::quantum::QFT>();
// auto iqft = std::make_shared<xacc::quantum::InverseQFT>();
auto giservice = std::make_shared<xacc::quantum::GateIRProvider>();
// auto giservice = std::make_shared<xacc::quantum::GateIRProvider>();
auto opt = std::make_shared<xacc::quantum::CircuitOptimizer>();
// auto opt = std::make_shared<xacc::quantum::CircuitOptimizer>();
auto roed = std::make_shared<xacc::quantum::ROErrorDecorator>();
auto impsamplingd = std::make_shared<xacc::quantum::ImprovedSamplingDecorator>();
auto richextrap = std::make_shared<xacc::quantum::RichExtrapDecorator>();
// auto roed = std::make_shared<xacc::quantum::ROErrorDecorator>();
// auto impsamplingd = std::make_shared<xacc::quantum::ImprovedSamplingDecorator>();
// auto richextrap = std::make_shared<xacc::quantum::RichExtrapDecorator>();
context.RegisterService<xacc::IRProvider>(giservice);
context.RegisterService<xacc::IRGenerator>(iqft);
context.RegisterService<xacc::IRGenerator>(qft);
// context.RegisterService<xacc::IRProvider>(giservice);
// context.RegisterService<xacc::IRGenerator>(iqft);
// context.RegisterService<xacc::IRGenerator>(qft);
context.RegisterService<xacc::IRTransformation>(opt);
context.RegisterService<xacc::OptionsProvider>(opt);
// context.RegisterService<xacc::IRTransformation>(opt);
// context.RegisterService<xacc::OptionsProvider>(opt);
context.RegisterService<xacc::AcceleratorDecorator>(roed);
context.RegisterService<xacc::Accelerator>(roed);
// context.RegisterService<xacc::AcceleratorDecorator>(roed);
// context.RegisterService<xacc::Accelerator>(roed);
context.RegisterService<xacc::AcceleratorDecorator>(richextrap);
context.RegisterService<xacc::Accelerator>(richextrap);
// context.RegisterService<xacc::AcceleratorDecorator>(richextrap);
// context.RegisterService<xacc::Accelerator>(richextrap);
context.RegisterService<xacc::AcceleratorDecorator>(impsamplingd);
context.RegisterService<xacc::Accelerator>(impsamplingd);
// context.RegisterService<xacc::AcceleratorDecorator>(impsamplingd);
// context.RegisterService<xacc::Accelerator>(impsamplingd);
auto h = std::make_shared<xacc::quantum::Hadamard>();
auto cn = std::make_shared<xacc::quantum::CNOT>();
......@@ -93,28 +93,28 @@ public:
auto crz= std::make_shared<xacc::quantum::CRZ>();
auto ch = std::make_shared<xacc::quantum::CH>();
context.RegisterService<xacc::quantum::GateInstruction>(h);
context.RegisterService<xacc::quantum::GateInstruction>(cn);
context.RegisterService<xacc::quantum::GateInstruction>(cp);
context.RegisterService<xacc::quantum::GateInstruction>(cz);
context.RegisterService<xacc::quantum::GateInstruction>(id);
context.RegisterService<xacc::quantum::GateInstruction>(m);
context.RegisterService<xacc::quantum::GateInstruction>(rx);
context.RegisterService<xacc::quantum::GateInstruction>(ry);
context.RegisterService<xacc::quantum::GateInstruction>(rz);
context.RegisterService<xacc::quantum::GateInstruction>(x);
context.RegisterService<xacc::quantum::GateInstruction>(y);
context.RegisterService<xacc::quantum::GateInstruction>(z);
context.RegisterService<xacc::quantum::GateInstruction>(sw);
context.RegisterService<xacc::quantum::GateInstruction>(u);
context.RegisterService<xacc::quantum::GateInstruction>(s);
context.RegisterService<xacc::quantum::GateInstruction>(sdg);
context.RegisterService<xacc::quantum::GateInstruction>(t);
context.RegisterService<xacc::quantum::GateInstruction>(tdg);
context.RegisterService<xacc::quantum::GateInstruction>(cy);
context.RegisterService<xacc::quantum::GateInstruction>(crz);
context.RegisterService<xacc::quantum::GateInstruction>(ch);
context.RegisterService<xacc::quantum::Gate>(h);
context.RegisterService<xacc::quantum::Gate>(cn);
context.RegisterService<xacc::quantum::Gate>(cp);
context.RegisterService<xacc::quantum::Gate>(cz);
context.RegisterService<xacc::quantum::Gate>(id);
context.RegisterService<xacc::quantum::Gate>(m);
context.RegisterService<xacc::quantum::Gate>(rx);
context.RegisterService<xacc::quantum::Gate>(ry);
context.RegisterService<xacc::quantum::Gate>(rz);
context.RegisterService<xacc::quantum::Gate>(x);
context.RegisterService<xacc::quantum::Gate>(y);
context.RegisterService<xacc::quantum::Gate>(z);
context.RegisterService<xacc::quantum::Gate>(sw);
context.RegisterService<xacc::quantum::Gate>(u);
context.RegisterService<xacc::quantum::Gate>(s);
context.RegisterService<xacc::quantum::Gate>(sdg);
context.RegisterService<xacc::quantum::Gate>(t);
context.RegisterService<xacc::quantum::Gate>(tdg);
context.RegisterService<xacc::quantum::Gate>(cy);
context.RegisterService<xacc::quantum::Gate>(crz);
context.RegisterService<xacc::quantum::Gate>(ch);
}
......
# *******************************************************************************
# Copyright (c) 2017 UT-Battelle, LLC.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# and Eclipse Distribution License v.10 which accompany this distribution.
# The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
# and the Eclipse Distribution License is available at
# https://eclipse.org/org/documents/edl-v10.php
# ******************************************************************************
# * Copyright (c) 2017 UT-Battelle, LLC. All rights reserved. This program and
# the accompanying materials are made available under the terms of the Eclipse
# Public License v1.0 and Eclipse Distribution License v.10 which accompany
# this distribution. The Eclipse Public License is available at
# http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution
# License is available at https://eclipse.org/org/documents/edl-v10.php
#
# Contributors:
# Alexander J. McCaskey - initial API and implementation
# *******************************************************************************/
# Contributors: Alexander J. McCaskey - initial API and implementation
# ******************************************************************************
# */
# Gather tests
if(XACC_BUILD_TESTS)
add_subdirectory(tests)
endif()
add_subdirectory(tests)
endif()
\ No newline at end of file
#include "Circuit.hpp"
// #include "exprtk.hpp"
// using symbol_table_t = exprtk::symbol_table<double>;
// using expression_t = exprtk::expression<double>;
// using parser_t = exprtk::parser<double>;
namespace xacc {
namespace quantum {
void Circuit::throwIfInvalidInstructionParameter(InstPtr instruction) {
if (!instruction->isComposite() && instruction->isParameterized()) {
for (int i = 0; i < instruction->nParameters(); i++) {
auto parameter = instruction->getParameter(i);
if (parameter.isVariable() &&
(std::find(variables.begin(), variables.end(),
parameter.toString()) == variables.end())) {
// First double check if we can evaluate
// this parameter to a constant, i.e. this
// variable string contains only constants
double constant;
if (parsingUtil->isConstant(parameter.toString(), constant)) {
instruction->setParameter(i, constant);
continue;
}
// symbol_table_t symbol_table;
// symbol_table.add_constants();
// expression_t expr;
// expr.register_symbol_table(symbol_table);
// parser_t parser;
// if (parser.compile(parameter.toString(), expr)) {
// auto value = expr.value();
// instruction->setParameter(i, value);
// continue;
// }
// ok, now we should check that the expression
// contains only our variables
std::vector<double> tmp(variables.size());
if (parsingUtil->validExpression(parameter.toString(), variables)) {
continue;
}
// for (int i = 0; i < variables.size(); i++) {
// symbol_table.add_variable(variables[i], tmp[i]);
// }
// expression_t expr2;
// expr2.register_symbol_table(symbol_table);
// parser_t parser2;
// if (parser2.compile(parameter.toString(), expr2)) {
// // This had only variables we know
// continue;
// }
std::stringstream ermsg;
ermsg << "\nInvalid parameterized instruction:\n" +
instruction->toString() + "\n'" + parameter.toString() +
"' not valid for this Circuit.\nValid variables are:\n[";
if (!variables.empty()) {
ermsg << variables[0];
for (int i = 1; i < variables.size(); i++) {
ermsg << "," << variables[i];
}
}
ermsg << "]\n"
<< "Please call CompositeInstruction::addVariable(variable).\n";
xacc::XACCLogger::instance()->error(ermsg.str());
throw new std::runtime_error("Invalid instruction parameter.");
}
}
}
}
std::shared_ptr<CompositeInstruction>
Circuit::operator()(const std::vector<double> &params) {
if (params.size() != variables.size()) {
xacc::XACCLogger::instance()->error(
"Invalid GateFunction evaluation: number "
"of parameters don't match. " +
std::to_string(params.size()) + ", " +
std::to_string(variables.size()));
exit(0);
}
// std::vector<double> p = params;
// symbol_table_t symbol_table;
// symbol_table.add_constants();
// std::vector<std::string> variableNames;
// std::vector<double> values;
// for (int i = 0; i < variables.size(); i++) {
// auto var = variables[i];
// variableNames.push_back(var);
// symbol_table.add_variable(var, p[i]);
// }
// auto compileExpression = [&](InstructionParameter &p) -> double {
// auto expression = mpark::get<std::string>(p);
// expression_t expr;
// expr.register_symbol_table(symbol_table);
// parser_t parser;
// parser.compile(expression, expr);
// return expr.value();
// };
auto evaluatedCircuit = std::make_shared<Circuit>("evaled_" + name());
// Walk the IR Tree, handle functions and instructions differently
for (auto inst : getInstructions()) {
if (inst->isComposite()) {
// If a Function, call this method recursively
auto evaled =
std::dynamic_pointer_cast<Circuit>(inst)->operator()(params);
evaluatedCircuit->addInstruction(evaled);
} else {
// If a concrete Gate, then check that it
// is parameterized and that it has a string parameter
if (inst->isParameterized() && inst->getParameter(0).isVariable()) {
InstructionParameter p = inst->getParameter(0);
std::stringstream s;
s << p.toString();
double val;
parsingUtil->evaluate(p.toString(), variables, params, val);
// auto val = compileExpression(p);
auto updatedInst = std::dynamic_pointer_cast<Gate>(inst)->clone();
updatedInst->setParameter(0, val);
updatedInst->setBits(inst->bits());
updatedInst->setParameter(0, val);
evaluatedCircuit->addInstruction(updatedInst);
} else {
evaluatedCircuit->addInstruction(inst);
}
}
}
return evaluatedCircuit;
}
} // namespace quantum
} // namespace xacc
\ No newline at end of file
/*******************************************************************************
* Copyright (c) 2017 UT-Battelle, LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompanies this
* distribution. The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution
*License is available at https://eclipse.org/org/documents/edl-v10.php
*
* Contributors:
* Alexander J. McCaskey - initial API and implementation
*******************************************************************************/
#ifndef QUANTUM_GATE_IR_CIRCUIT_HPP_
#define QUANTUM_GATE_IR_CIRCUIT_HPP_
#include "CompositeInstruction.hpp"
#include "Gate.hpp"
#include "InstructionIterator.hpp"
#include "Utils.hpp"
#include "expression_parsing_util.hpp"
#include "xacc_service.hpp"
#include <memory>
#include <stdexcept>
namespace xacc {
namespace quantum {
class Circuit : public CompositeInstruction,
public std::enable_shared_from_this<Circuit> {
private:
void throwIfInvalidInstructionParameter(InstPtr instruction);
void validateInstructionIndex(const std::size_t idx) {
if (idx >= instructions.size()) {
xacc::XACCLogger::instance()->error(
"\nInvalid instruction index on Circuit\n"
"CompositeInstruction:\nnInstructions() = " +
std::to_string(nInstructions()) + "\nidx = " + std::to_string(idx));
print_backtrace();
exit(0);
}
}
void validateInstructionPtr(InstPtr inst) {
if (std::find(instructions.begin(), instructions.end(), inst) !=
std::end(instructions)) {
xacc::XACCLogger::instance()->error(
"\nInvalid instruction:\nThis instruction pointer already added to "
"Circuit.");
print_backtrace();
exit(0);
}
}
void errorCircuitParameter() const {
xacc::XACCLogger::instance()->error(
"Circuit Instruction parameter API not implemented.");
print_backtrace();
exit(0);
}
protected:
std::vector<InstPtr> instructions{};
std::vector<std::string> variables{};
std::vector<std::string> _requiredKeys{};
std::string circuitName = "";
std::shared_ptr<ExpressionParsingUtil> parsingUtil;
public:
Circuit(const std::string &name)
: circuitName(name),
parsingUtil(xacc::getService<ExpressionParsingUtil>("exprtk")) {}
Circuit(const std::string &name, std::vector<std::string>& vars)
: circuitName(name), variables(vars),
parsingUtil(xacc::getService<ExpressionParsingUtil>("exprtk")) {}
Circuit(const std::string &name, std::vector<std::string>&& vars)
: circuitName(name), variables(vars),
parsingUtil(xacc::getService<ExpressionParsingUtil>("exprtk")) {}
Circuit(const Circuit &other)
: circuitName(other.circuitName), variables(other.variables),
instructions(other.instructions), parsingUtil(other.parsingUtil) {}
const std::string name() const override { return circuitName; }
const std::string description() const override { return ""; }
void mapBits(std::vector<std::size_t> bitMap) override {}
void setBits(const std::vector<std::size_t> bits) override {}
const std::vector<std::size_t> bits() override { return {}; }
const std::string toString() override {
std::string retStr = "";
for (auto i : instructions) {
if (i->isEnabled()) {
if (i->isComposite() &&
!std::dynamic_pointer_cast<CompositeInstruction>(i)
->hasChildren()) {
retStr += i->name() + "()\n";
} else {
retStr += i->toString() + "\n";
}
}
}
return retStr;
}
const InstructionParameter
getParameter(const std::size_t idx) const override {
errorCircuitParameter();
return InstructionParameter(0);
}
void setParameter(const std::size_t idx, InstructionParameter &p) override {
errorCircuitParameter();
}
std::vector<InstructionParameter> getParameters() override {
errorCircuitParameter();
return {};
}
const int nParameters() override {
errorCircuitParameter();
return 0;
}
const int nRequiredBits() const override { return 0; }
void enable() override {
for (int i = 0; i < nInstructions(); i++) {
getInstruction(i)->enable();
}
}
void disable() override {
for (int i = 0; i < nInstructions(); i++) {
getInstruction(i)->disable();
}
}
const bool isAnalog() const override {
for (int i = 0; i < instructions.size(); i++) {
auto inst = *std::next(instructions.begin(), i);
if (inst->isAnalog()) {
return true;
}
}
return false;