Commit 9b5f2d04 authored by Nguyen, Thien Minh's avatar Nguyen, Thien Minh
Browse files

QAOA WIP



- Set-up algo. parameters (initialize)

- Some initial code for kernel construction (WIP)

- Add unit test.
Signed-off-by: Nguyen, Thien Minh's avatarThien Nguyen <nguyentm@ornl.gov>
parent f71321e0
......@@ -23,7 +23,7 @@ target_include_directories(
${LIBRARY_NAME}
PUBLIC .)
target_link_libraries(${LIBRARY_NAME} PUBLIC xacc CppMicroServices)
target_link_libraries(${LIBRARY_NAME} PUBLIC xacc CppMicroServices xacc-quantum-gate)
set(_bundle_name xacc_algorithm_qaoa)
set_target_properties(${LIBRARY_NAME}
......@@ -51,8 +51,7 @@ else()
endif()
if(XACC_BUILD_TESTS)
# TODO: add tests
#add_subdirectory(tests)
add_subdirectory(tests)
endif()
install(TARGETS ${LIBRARY_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/plugins)
......@@ -11,23 +11,124 @@
* Thien Nguyen - initial API and implementation
*******************************************************************************/
#include "qaoa.hpp"
#include "xacc.hpp"
#include "xacc_service.hpp"
#include "Circuit.hpp"
#include <cassert>
namespace xacc {
namespace algorithm {
bool QAOA::initialize(const HeterogeneousMap& parameters) {
// TODO
return true;
bool QAOA::initialize(const HeterogeneousMap& parameters)
{
bool initializeOk = true;
// Hyper-parameters for QAOA:
// (1) Accelerator (QPU)
if (!parameters.pointerLikeExists<Accelerator>("accelerator"))
{
std::cout << "'accelerator' is required.\n";
// We check all required params; hence don't early return on failure.
initializeOk = false;
}
// (2) Classical optimizer
if (!parameters.pointerLikeExists<Optimizer>("optimizer"))
{
std::cout << "'optimizer' is required.\n";
initializeOk = false;
}
// (3) Number of mixing and cost function steps to use (default = 1)
m_nbSteps = 1;
if (parameters.keyExists<int>("steps"))
{
m_nbSteps = parameters.get<int>("steps");
}
// (4) Initial values for the beta parameters
m_betas.clear();
if (parameters.keyExists<std::vector<double>>("init-betas"))
{
m_betas = parameters.get<std::vector<double>>("init-betas");
}
// (5) Initial values for the gamma parameters
m_gammas.clear();
if (parameters.keyExists<std::vector<double>>("init-gammas"))
{
m_gammas = parameters.get<std::vector<double>>("init-gammas");
}
// (6) Cost Hamiltonian
if (!parameters.keyExists<std::vector<std::string>>("cost-ham"))
{
std::cout << "'cost-ham' is required.\n";
initializeOk = false;
}
// (7) Reference Hamiltonian
if (!parameters.keyExists<std::vector<std::string>>("ref-ham"))
{
std::cout << "'ref-ham' is required.\n";
initializeOk = false;
}
if (initializeOk)
{
m_refHam = parameters.get<std::vector<std::string>>("ref-ham");
m_costHam = parameters.get<std::vector<std::string>>("cost-ham");
m_qpu = parameters.getPointerLike<Accelerator>("accelerator");
m_optimizer = parameters.getPointerLike<Optimizer>("optimizer");
}
return initializeOk;
}
const std::vector<std::string> QAOA::requiredParameters() const
{
// TODO
return {};
return { "accelerator", "optimizer", "ref-ham", "cost-ham" };
}
std::shared_ptr<CompositeInstruction> QAOA::constructParameterizedKernel(const std::shared_ptr<AcceleratorBuffer>& in_buffer) const
{
auto gateRegistry = xacc::getService<xacc::IRProvider>("quantum");
const auto nbQubits = in_buffer->size();
auto qaoaKernel = gateRegistry->createComposite("qaoaKernel");
// Hadamard layer
for (size_t i = 0; i < nbQubits; ++i)
{
qaoaKernel->addInstruction(gateRegistry->createInstruction("H", { i }));
}
// Trotter layers (parameterized): mixing b/w cost and drive (reference) Hamiltonian
auto expCirc = std::dynamic_pointer_cast<xacc::quantum::Circuit>(xacc::getService<Instruction>("exp_i_theta"));
for (size_t i = 0; i < m_nbSteps; ++i)
{
for (const auto& term : m_costHam)
{
expCirc->expand({ std::make_pair("pauli", term) });
std::cout << "Term: '" << term << "': \n" << expCirc->toString() << "\n";
}
for (const auto& term : m_refHam)
{
expCirc->expand({ std::make_pair("pauli", term) });
std::cout << "Term: '" << term << "': \n" << expCirc->toString() << "\n";
}
// TODO: add the instructions from exponential circuits to the kernel:
// need to re-map the variables to make sure we capture all parameters.
}
return qaoaKernel;
}
void QAOA::execute(const std::shared_ptr<AcceleratorBuffer> buffer) const
{
// TODO
const int nbQubits = buffer->size();
auto kernel = constructParameterizedKernel(buffer);
std::cout << "Kernel: \n" << kernel->toString() << "\n\n";
}
std::vector<double> QAOA::execute(const std::shared_ptr<AcceleratorBuffer> buffer, const std::vector<double>& x)
......
......@@ -26,6 +26,18 @@ public:
const std::string name() const override { return "QAOA"; }
const std::string description() const override { return ""; }
DEFINE_ALGORITHM_CLONE(QAOA)
private:
std::shared_ptr<CompositeInstruction> constructParameterizedKernel(const std::shared_ptr<AcceleratorBuffer>& in_buffer) const;
private:
std::vector<std::string> m_refHam;
std::vector<std::string> m_costHam;
Accelerator* m_qpu;
Optimizer* m_optimizer;
int m_nbSteps;
std::vector<double> m_gammas;
std::vector<double> m_betas;
};
} // namespace algorithm
} // namespace xacc
# *******************************************************************************
# Copyright (c) 2020 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:
# Thien Nguyen - initial API and implementation
# *******************************************************************************/
include_directories(${CMAKE_BINARY_DIR})
add_xacc_test(QAOA)
target_link_libraries(QAOATester xacc)
\ No newline at end of file
/*******************************************************************************
* Copyright (c) 2020 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:
* Thien Nguyen - initial API and implementation
*******************************************************************************/
#include <gtest/gtest.h>
#include "xacc.hpp"
#include "xacc_service.hpp"
#include "Observable.hpp"
#include "Algorithm.hpp"
using namespace xacc;
TEST(QAOATester, checkSimple)
{
auto acc = xacc::getAccelerator("qpp");
auto buffer = xacc::qalloc(2);
const std::vector<std::string> costHam { "Z0 Z1" };
const std::vector<std::string> refHam { "X0 X1" };
auto optimizer = xacc::getOptimizer("nlopt");
auto qaoa = xacc::getService<Algorithm>("QAOA");
EXPECT_TRUE(
qaoa->initialize({
std::make_pair("accelerator", acc),
std::make_pair("optimizer", optimizer),
std::make_pair("cost-ham", costHam),
std::make_pair("ref-ham", refHam)
}));
qaoa->execute(buffer);
}
int main(int argc, char **argv)
{
xacc::Initialize(argc, argv);
::testing::InitGoogleTest(&argc, argv);
auto ret = RUN_ALL_TESTS();
xacc::Finalize();
return ret;
}
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