Commit 6e44e9b4 authored by Mccaskey, Alex's avatar Mccaskey, Alex

Revert "First pass at the HPC Virtualization decorator for executing a vector...

Revert "First pass at the HPC Virtualization decorator for executing a vector of CompositeInstructions across multiple available virtual QPUs"

This reverts commit 09bba284.
parent 09bba284
Pipeline #113404 passed with stage
in 73 minutes and 9 seconds
......@@ -38,6 +38,8 @@ usFunctionEmbedResources(TARGET ${LIBRARY_NAME}
manifest.json
)
message(STATUS "HELLO ${PYTHON_LIB_NAME}")
target_include_directories(${LIBRARY_NAME} PRIVATE . ${CMAKE_SOURCE_DIR}/tpls/pybind11/include ${CMAKE_BINARY_DIR})
target_link_libraries(${LIBRARY_NAME} PUBLIC xacc Python::Python)
......
......@@ -13,4 +13,3 @@
add_subdirectory(base_api)
add_subdirectory(qasm)
add_subdirectory(qst-publication)
add_subdirectory(hpc_virtualization)
# *******************************************************************************
# Copyright (c) 2019 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
# *******************************************************************************/
add_executable(tnqvm_hpc_virt tnqvm_hpc_virtualization.cpp)
target_link_libraries(tnqvm_hpc_virt PRIVATE xacc xacc-quantum-gate)
/*******************************************************************************
* Copyright (c) 2019 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
*******************************************************************************/
#include "xacc.hpp"
#include "xacc_observable.hpp"
// run this with
// $ mpirun -n N tnqvm_hpc_virtualization
// where N is the number of MPI ranks
int main(int argc, char **argv) {
xacc::Initialize(argc, argv);
// Get reference to the Accelerator
auto accelerator =
xacc::getAccelerator("tnqvm", {{"tnqvm-visitor", "exatn-mps"}});
// Decorate the accelerator with HPC Virtualization.
// This decorator assumes the provided number of input QPUs
// available to a distributed hetereogeneous system. It will
// divide the work of executing N CompositeInstructions across the
// available virtual QPUs (here tnqvm instances)
accelerator = xacc::getAcceleratorDecorator("hpc-virtualization", accelerator,
{{"n-virtual-qpus", 3}});
// Create the N=2 deuteron Hamiltonian
auto H_N_2 = xacc::quantum::getObservable(
"pauli", std::string("5.907 - 2.1433 X0X1 "
"- 2.1433 Y0Y1"
"+ .21829 Z0 - 6.125 Z1"));
auto optimizer = xacc::getOptimizer("nlopt");
// JIT map XASM Ansatz to IR
xacc::qasm(R"(
.compiler xasm
.circuit deuteron_ansatz
.parameters theta
.qbit q
X(q[0]);
Ry(q[1], theta);
CNOT(q[1],q[0]);
)");
auto ansatz = xacc::getCompiled("deuteron_ansatz");
// Get the VQE Algorithm and initialize it
auto vqe = xacc::getAlgorithm("vqe", {{"ansatz", ansatz},
{"observable", H_N_2},
{"accelerator", accelerator},
{"optimizer", optimizer}});
// Allocate some qubits and execute
auto buffer = xacc::qalloc(2);
vqe->execute(buffer);
// Print the result
auto print_predicate = buffer->hasExtraInfoKey("rank")
? ((*buffer)["rank"].as<int>() == 0)
: true;
if (print_predicate)
std::cout << "Energy: " << (*buffer)["opt-val"].as<double>() << "\n";
}
\ No newline at end of file
......@@ -150,11 +150,6 @@ void VQE::execute(const std::shared_ptr<AcceleratorBuffer> buffer) const {
accelerator->execute(tmpBuffer, fsToExec);
auto buffers = tmpBuffer->getChildren();
auto tmp_buffer_extra_info = tmpBuffer->getInformation();
for (auto& [k, v] : tmp_buffer_extra_info) {
buffer->addExtraInfo(k, v);
}
double energy = identityCoeff;
auto idBuffer = xacc::qalloc(buffer->size());
idBuffer->addExtraInfo("coefficient", identityCoeff);
......
......@@ -63,4 +63,3 @@ if(XACC_BUILD_TESTS)
add_subdirectory(tests)
endif()
add_subdirectory(hpc-virtualization)
\ No newline at end of file
# ******************************************************************************
# *
# Copyright (c) 2019 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
# ******************************************************************************
# */
find_package(MPI)
if(MPI_FOUND)
set(LIBRARY_NAME xacc-hpc-virt-decorator)
file(GLOB_RECURSE HEADERS *.hpp)
file(GLOB SRC hpc_virt_decorator.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})
set(_bundle_name xacc_hpc_virt_decorator)
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_include_directories(${LIBRARY_NAME} PUBLIC .)
target_link_libraries(${LIBRARY_NAME} PUBLIC xacc Boost::mpi)
if(APPLE)
set_target_properties(${LIBRARY_NAME}
PROPERTIES INSTALL_RPATH
"@loader_path/../lib;@loader_path")
set_target_properties(${LIBRARY_NAME}
PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
else()
set_target_properties(${LIBRARY_NAME}
PROPERTIES INSTALL_RPATH "$ORIGIN/../lib:$ORIGIN")
set_target_properties(${LIBRARY_NAME} PROPERTIES LINK_FLAGS "-shared")
endif()
install(TARGETS ${LIBRARY_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/plugins)
# Gather tests
if(XACC_BUILD_TESTS)
# add_subdirectory(tests)
endif()
endif()
/*******************************************************************************
* Copyright (c) 2019 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
*******************************************************************************/
#include "hpc_virt_decorator.hpp"
#include "InstructionIterator.hpp"
#include "Utils.hpp"
#include "xacc.hpp"
#include <boost/mpi.hpp>
#include <boost/mpi/collectives/all_gather.hpp>
#include <boost/serialization/string.hpp>
#include <mpi.h>
namespace xacc {
namespace quantum {
void HPCVirtDecorator::initialize(const HeterogeneousMap &params) {
decoratedAccelerator->initialize(params);
if (params.keyExists<int>("n-virtual-qpus")) {
n_virtual_qpus = params.get<int>("n-virtual-qpus");
}
if (!boost::mpi::environment::initialized()) {
}
}
void HPCVirtDecorator::updateConfiguration(const HeterogeneousMap &config) {
decoratedAccelerator->updateConfiguration(config);
}
void HPCVirtDecorator::execute(
std::shared_ptr<AcceleratorBuffer> buffer,
const std::shared_ptr<CompositeInstruction> function) {
if (decoratedAccelerator)
decoratedAccelerator->execute(buffer, function);
return;
}
void HPCVirtDecorator::execute(
std::shared_ptr<AcceleratorBuffer> buffer,
const std::vector<std::shared_ptr<CompositeInstruction>> functions) {
// The goal here is the following:
// Assume we have an HPC system with a set of
// compute ranks M, and we partition that set of ranks into
// communicator sub-groups, each with a dedicated virtual QPU available.
// Also we are given a vector of observable terms
// (vec of CompositeInstructions) of size N (N>>1),
// we wish to evaluate the <O> for each by partitioning
// their quantum execution across the node sub-groups.
using namespace boost;
int initialized;
MPI_Initialized(&initialized);
if (!initialized) {
MPI_Init(&xacc::argc, &xacc::argv);
}
mpi::communicator world;
// Get the rank and size in the original communicator
int world_rank = world.rank(), world_size = world.size();
if (world_size <= n_virtual_qpus) {
// just execute
decoratedAccelerator->execute(buffer, functions);
return;
}
// Get the color for this rank
int color = world_rank % n_virtual_qpus;
// Split the communicator based on the color and use the
// original rank for ordering
auto qpu_comm = world.split(color, world_rank);
// current rank now has a color to indicate which sub-comm it belongs to
// Give that sub communicator to the accelerator
void *qpu_comm_ptr = reinterpret_cast<void *>((MPI_Comm)qpu_comm);
decoratedAccelerator->updateConfiguration(
{{"mpi-communicator", qpu_comm_ptr}});
// Everybody split the CompositeInstructions vector into n_virtual_qpu
// segments
auto split_vecs = split_vector(functions, n_virtual_qpus);
// Get the segment corresponding to this color
auto my_circuits = split_vecs[color];
// Create a local buffer and execute
auto my_buffer = xacc::qalloc(buffer->size());
decoratedAccelerator->execute(my_buffer, my_circuits);
std::vector<std::string> my_child_buffer_strings;
for (auto &child : my_buffer->getChildren()) {
std::stringstream ss;
child->print(ss);
my_child_buffer_strings.push_back(ss.str());
}
qpu_comm.barrier();
// Strategy:
// Every process in a sub-communicator has the same
// children buffer data. I want each sub-group to share
// its results with the other subgroups. My thinking is
// to do an all_gather on all world ranks, all ranks will then
// have multiple copies of the data strings, so lets filter them
// out by using a std::set. Then just load the buffers and add them
// to the buffer.
// Need to distribute resultant children buffers to all ranks
std::vector<std::vector<std::string>> all_child_buffer_strings;
mpi::all_gather(world, my_child_buffer_strings, all_child_buffer_strings);
// Everyone has all copies of child buffer strings, filter them out to be
// unique
std::set<std::string> unique_buffer_strings;
for (auto &child_buffer_strings : all_child_buffer_strings) {
for (auto child_buffer_string : child_buffer_strings) {
unique_buffer_strings.insert(child_buffer_string);
}
}
// everyone add the children buffers to the incoming buffer
std::map<std::string, std::shared_ptr<AcceleratorBuffer>> name_to_buffer;
for (auto &buffer_string : unique_buffer_strings) {
auto child_buffer = xacc::qalloc(buffer->size());
std::istringstream s(buffer_string);
child_buffer->load(s);
name_to_buffer.insert({child_buffer->name(), child_buffer});
}
// buffers need to be in same order as functions coming in
for (auto &f : functions) {
buffer->appendChild(f->name(), name_to_buffer[f->name()]);
}
qpu_comm.barrier();
world.barrier();
buffer->addExtraInfo("rank", world_rank);
return;
}
void HPCVirtTearDown::tearDown() {
int finalized, initialized;
MPI_Initialized(&initialized);
if (initialized) {
MPI_Finalized(&finalized);
if (!finalized) {
MPI_Finalize();
}
}
}
} // namespace quantum
} // namespace xacc
#include "cppmicroservices/BundleActivator.h"
#include "cppmicroservices/BundleContext.h"
#include "cppmicroservices/ServiceProperties.h"
using namespace cppmicroservices;
namespace {
class US_ABI_LOCAL HPCVirtActivator : public BundleActivator {
public:
HPCVirtActivator() {}
void Start(BundleContext context) {
auto c = std::make_shared<xacc::quantum::HPCVirtDecorator>();
context.RegisterService<xacc::AcceleratorDecorator>(c);
context.RegisterService<xacc::Accelerator>(c);
context.RegisterService<xacc::TearDown>(
std::make_shared<xacc::quantum::HPCVirtTearDown>());
}
/**
*/
void Stop(BundleContext /*context*/) {}
};
} // namespace
CPPMICROSERVICES_EXPORT_BUNDLE_ACTIVATOR(HPCVirtActivator)
/*******************************************************************************
* Copyright (c) 2018 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 XACC_HPC_VIRT_DECORATOR_HPP_
#define XACC_HPC_VIRT_DECORATOR_HPP_
#include "AcceleratorDecorator.hpp"
#include "TearDown.hpp"
namespace xacc {
namespace quantum {
class HPCVirtDecorator : public AcceleratorDecorator {
protected:
std::string roErrorFile = "";
int n_virtual_qpus = 1;
public:
void initialize(const HeterogeneousMap &params = {}) override;
void updateConfiguration(const HeterogeneousMap &config) override;
const std::vector<std::string> configurationKeys() override { return {}; }
void execute(std::shared_ptr<AcceleratorBuffer> buffer,
const std::shared_ptr<CompositeInstruction> function) override;
void execute(std::shared_ptr<AcceleratorBuffer> buffer,
const std::vector<std::shared_ptr<CompositeInstruction>>
functions) override;
const std::string name() const override { return "hpc-virtualization"; }
const std::string description() const override { return ""; }
~HPCVirtDecorator() override { }
private:
template <typename T>
std::vector<std::vector<T>> split_vector(const std::vector<T> &vec,
size_t n) {
std::vector<std::vector<T>> outVec;
size_t length = vec.size() / n;
size_t remain = vec.size() % n;
size_t begin = 0;
size_t end = 0;
for (size_t i = 0; i < std::min(n, vec.size()); ++i) {
end += (remain > 0) ? (length + !!(remain--)) : length;
outVec.push_back(std::vector<T>(vec.begin() + begin, vec.begin() + end));
begin = end;
}
return outVec;
}
};
class HPCVirtTearDown : public xacc::TearDown {
public:
virtual void tearDown() override;
};
} // namespace quantum
} // namespace xacc
#endif
{
"bundle.symbolic_name" : "xacc_hpc_virt_decorator",
"bundle.activator" : true,
"bundle.name" : "XACC HPC Virtualization Decorator",
"bundle.description" : "This bundle provides the HPC Virtualization Accelerator Decorator."
}
\ No newline at end of file
......@@ -67,7 +67,7 @@ else()
endif()
set(BUILD_SHARED_LIBS FALSE)
set(BOOST_LIBS_OPTIONAL graph mpi CACHE STRING "" FORCE)
set(BOOST_LIBS_OPTIONAL graph CACHE STRING "" FORCE)
add_subdirectory(boost-cmake)
install (DIRECTORY armadillo DESTINATION ${CMAKE_INSTALL_PREFIX}/include/)
......
Subproject commit a891b51c47c4246d985984139b9b40ad7b22b103
Subproject commit c291a1622f28c7c03bd8c386bffa0ba7b03bb0a8
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