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

Adding ParameterSetter interface to quantum/aqc

parent 584a9f6a
......@@ -149,7 +149,9 @@ public:
value<std::string>(), "The D-Wave SAPI URL, "
"https://qubist.dwavesys.com/sapi "
"used by default.")("dwave-solver",
value<std::string>(), "The name of the solver to run on.");
value<std::string>(), "The name of the solver to run on.")(
"dwave-solver", value<std::string>(),
"The name of the solver to use.");
return desc;
}
......
......@@ -34,6 +34,7 @@
#include "DWKernel.hpp"
#include "RuntimeOptions.hpp"
#include "AQCAcceleratorBuffer.hpp"
#include "ParameterSetter.hpp"
namespace xacc {
......@@ -128,77 +129,25 @@ std::shared_ptr<IR> DWQMICompiler::compile(const std::string& src,
// Add the embedding to the AcceleratorBuffer
aqcBuffer->setEmbedding(embedding);
auto countEdgesBetweenSubTrees = [&](std::list<int> Ti, std::list<int> Tj) -> int {
int nEdges = 0;
for (auto i : Ti) {
for (auto j : Tj) {
if (hardwareGraph->edgeExists(i, j)) {
nEdges++;
}
}
}
return nEdges;
};
auto subTreeContains = [](std::list<int> tree, int i) -> bool {
return std::find(tree.begin(), tree.end(), i) != tree.end();
};
// Setup the hardware bias values
for (auto& embKv : embedding) {
auto probVert = embKv.first;
auto hardwareMapping = embKv.second;
auto newBias = std::get<0>(problemGraph->getVertexProperties(probVert)) / hardwareMapping.size();
for (auto h : hardwareMapping) {
auto embeddedInst = std::make_shared<DWQMI>(h, h, newBias);
dwKernel->addInstruction(embeddedInst);
}
// Get the ParameterSetter
std::shared_ptr<ParameterSetter> parameterSetter;
if (runtimeOptions->exists("dwave-parameter-setter")) {
parameterSetter = ParameterSetterRegistry::instance()->create(
(*runtimeOptions)["dwave-parameter-setter"]);
} else {
parameterSetter = ParameterSetterRegistry::instance()->create(
"default");
}
for (int i = 0; i < nHardwareVerts; i++) {
for (int j = 0; j < nHardwareVerts; j++) {
if (hardwareGraph->edgeExists(i, j) && i < j && i != j) {
for (int pi = 0; pi < problemGraph->order(); pi++) {
for (int pj = 0; pj < problemGraph->order(); pj++) {
auto Ti = embedding[pi];
auto Tj = embedding[pj];
if (subTreeContains(Ti, i) && subTreeContains(Tj, j)) {
double newWeight = 0.0;
if (pi != pj) {
// If problem edge does not exist,
// Graph.getEdgeWeight retusn 0.0;
newWeight = problemGraph->getEdgeWeight(pi,
pj)
/ countEdgesBetweenSubTrees(Ti, Tj);
} else {
// ferro-magnetic coupling parameter that ensures that physical
// qubits representing one logical qubit remain highly correlated.
for (auto neighbor : problemGraph->getNeighborList(
pi)) {
newWeight += std::fabs(
problemGraph->getEdgeWeight(pi,
neighbor));
}
newWeight = std::get<0>(
problemGraph->getVertexProperties(pi))
+ newWeight - 1.0;
}
if (std::fabs(newWeight) > 1e-4) {
auto embeddedInst = std::make_shared<DWQMI>(i,
j, newWeight);
dwKernel->addInstruction(embeddedInst);
}
}
}
}
}
}
// Set the parameters
auto insts = parameterSetter->setParameters(problemGraph, hardwareGraph, embedding);
// Add the instructions to the Kernel
for (auto i : insts) {
dwKernel->addInstruction(i);
}
// Create and return the IR
auto ir = std::make_shared<DWIR>();
ir->addKernel(dwKernel);
return ir;
......
......@@ -96,7 +96,10 @@ public:
auto desc = std::make_shared<options_description>(
"D-Wave QMI Compiler Options");
desc->add_options()("dwave-embedding", value<std::string>(),
"Provide the name of the Embedding Algorithm to use during compilation.");
"Provide the name of the Embedding Algorithm to use during compilation.")(
"dwave-parameter-setter", value<std::string>(),
"Provide the name of the "
"ParameterSetter to map logical parameters to physical parameters.");
return desc;
}
......
......@@ -35,10 +35,10 @@ set (LIBRARY_NAME xacc-quantum-aqc)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ir)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/compiler)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/compiler/trivial)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/compiler/default)
file (GLOB_RECURSE HEADERS *.hpp)
file (GLOB SRC compiler/trivial/TrivialEmbeddingAlgorithm.cpp) # compiler/cmr/*.cpp)
file (GLOB SRC compiler/default/*.cpp)
add_library(${LIBRARY_NAME} SHARED ${SRC})
......
#ifndef QUANTUM_AQC_COMPILER_PARAMETERSETTER_HPP_
#define QUANTUM_AQC_COMPILER_PARAMETERSETTER_HPP_
#include "DWGraph.hpp"
#include "DWQMI.hpp"
namespace xacc {
namespace quantum {
class ParameterSetter {
public:
virtual std::list<std::shared_ptr<DWQMI>> setParameters(
std::shared_ptr<DWGraph> problemGraph,
std::shared_ptr<AcceleratorGraph> hardwareGraph,
std::map<int, std::list<int>> embedding) = 0;
virtual ~ParameterSetter() {}
};
/**
* ParameterSetter Registry is just an alias for a
* Registry of ParameterSetters.
*/
using ParameterSetterRegistry = Registry<ParameterSetter>;
/**
* RegisterParameterSetter is a convenience class for
* registering custom derived ParameterSetter classes.
*
* Creators of ParameterSetter subclasses create an instance
* of this class with their ParameterSetter subclass as the template
* parameter to register their ParameterSetter with XACC. This instance
* must be created in the CPP implementation file for the ParameterSetter
* and at global scope.
*/
template<typename T>
class RegisterParameterSetter {
public:
RegisterParameterSetter(const std::string& name) {
ParameterSetterRegistry::CreatorFunctionPtr f = std::make_shared<
ParameterSetterRegistry::CreatorFunction>([]() {
return std::make_shared<T>();
});
ParameterSetterRegistry::instance()->add(name, f);
}
};
}
}
#endif
/***********************************************************************************
* Copyright (c) 2017, 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
*
**********************************************************************************/
#include "DefaultParameterSetter.hpp"
namespace xacc {
namespace quantum {
std::list<std::shared_ptr<DWQMI>> DefaultParameterSetter::setParameters(
std::shared_ptr<DWGraph> problemGraph,
std::shared_ptr<AcceleratorGraph> hardwareGraph,
std::map<int, std::list<int>> embedding) {
std::list<std::shared_ptr<DWQMI>> instList;
auto nHardwareVerts = hardwareGraph->order();
auto nProblemVerts = problemGraph->order();
auto countEdgesBetweenSubTrees =
[&](std::list<int> Ti, std::list<int> Tj) -> int {
int nEdges = 0;
for (auto i : Ti) {
for (auto j : Tj) {
if (hardwareGraph->edgeExists(i, j)) {
nEdges++;
}
}
}
return nEdges;
};
auto subTreeContains = [](std::list<int> tree, int i) -> bool {
return std::find(tree.begin(), tree.end(), i) != tree.end();
};
// Setup the hardware bias values
for (auto& embKv : embedding) {
auto probVert = embKv.first;
auto hardwareMapping = embKv.second;
auto newBias = std::get<0>(problemGraph->getVertexProperties(probVert))
/ hardwareMapping.size();
for (auto h : hardwareMapping) {
auto embeddedInst = std::make_shared<DWQMI>(h, h, newBias);
instList.push_back(embeddedInst);
}
}
for (int i = 0; i < nHardwareVerts; i++) {
for (int j = 0; j < nHardwareVerts; j++) {
if (hardwareGraph->edgeExists(i, j) && i < j && i != j) {
for (int pi = 0; pi < nProblemVerts; pi++) {
for (int pj = 0; pj < nProblemVerts; pj++) {
auto Ti = embedding[pi];
auto Tj = embedding[pj];
if (subTreeContains(Ti, i) && subTreeContains(Tj, j)) {
double newWeight = 0.0;
if (pi != pj) {
// If problem edge does not exist,
// Graph.getEdgeWeight retusn 0.0;
newWeight = problemGraph->getEdgeWeight(pi, pj)
/ countEdgesBetweenSubTrees(Ti, Tj);
} else {
// ferro-magnetic coupling parameter that ensures that physical
// qubits representing one logical qubit remain highly correlated.
for (auto neighbor : problemGraph->getNeighborList(
pi)) {
newWeight += std::fabs(
problemGraph->getEdgeWeight(pi,
neighbor));
}
newWeight = std::get<0>(
problemGraph->getVertexProperties(pi))
+ newWeight - 1.0;
}
if (std::fabs(newWeight) > 1e-4) {
auto embeddedInst = std::make_shared<DWQMI>(i,
j, newWeight);
instList.push_back(embeddedInst);
}
}
}
}
}
}
}
return instList;
}
xacc::quantum::RegisterParameterSetter<DefaultParameterSetter> DEFPS(
"default");
}
}
/***********************************************************************************
* Copyright (c) 2017, 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
*
**********************************************************************************/
#ifndef QUANTUM_AQC_COMPILER_DefaultParameterSetter_HPP_
#define QUANTUM_AQC_COMPILER_DefaultParameterSetter_HPP_
#include "ParameterSetter.hpp"
namespace xacc {
namespace quantum {
/**
*/
class DefaultParameterSetter : public ParameterSetter {
public:
/**
* The Constructor
*/
DefaultParameterSetter() {}
/**
* The Destructor
*/
virtual ~DefaultParameterSetter() {}
virtual std::list<std::shared_ptr<DWQMI>> setParameters(
std::shared_ptr<DWGraph> problemGraph,
std::shared_ptr<AcceleratorGraph> hardwareGraph,
std::map<int, std::list<int>> embedding);
};
}
}
#endif
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