Unverified Commit 46d11bc1 authored by Thien Nguyen's avatar Thien Nguyen Committed by GitHub
Browse files

Merge pull request #508 from ausbin/feature/iontrap-accelerator

Add ion trap accelerator
parents 335b9a9e cbbd7a1f
Pipeline #185140 passed with stage
in 19 minutes and 3 seconds
......@@ -15,6 +15,7 @@ set(LIBRARY_NAME xacc-iontrap)
file(GLOB SRC
*.cpp
accelerator/*.cpp
decomp/*.cpp
transformations/*.cpp)
......@@ -25,6 +26,7 @@ add_library(${LIBRARY_NAME} SHARED ${SRC})
target_include_directories(${LIBRARY_NAME}
PUBLIC .
./accelerator
./decomp
./transformations
${CMAKE_SOURCE_DIR}/tpls/ensmallen
......
......@@ -15,6 +15,7 @@
#include "cppmicroservices/BundleActivator.h"
#include "cppmicroservices/BundleContext.h"
#include "cppmicroservices/ServiceProperties.h"
#include "IonTrapAccelerator.hpp"
#include "IonTrapOneQubitPass.hpp"
#include "IonTrapTwoQubitPass.hpp"
......@@ -25,6 +26,9 @@ public:
IonTrapActivator() {}
void Start(BundleContext context) {
auto acc = std::make_shared<xacc::quantum::IonTrapAccelerator>();
context.RegisterService<xacc::Accelerator>(acc);
auto twoQubitPass = std::make_shared<xacc::quantum::IonTrapTwoQubitPass>();
context.RegisterService<xacc::IRTransformation>(twoQubitPass);
......
This diff is collapsed.
/*******************************************************************************
* Copyright (c) 2019-2021 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
* Daniel Strano - adaption from Quantum++ to Qrack
* Austin Adams - adaption for GTRI testbed
*******************************************************************************/
#ifndef QUANTUM_ACCELERATORS_IONTRAPACCELERATOR_HPP_
#define QUANTUM_ACCELERATORS_IONTRAPACCELERATOR_HPP_
#include "xacc.hpp"
#include "IonTrapOneQubitPass.hpp"
#include "IonTrapTwoQubitPass.hpp"
#include "IonTrapQasmVisitor.hpp"
#include "IonTrapPassesCommon.hpp"
// On Linux, use inotify to check for result files. On other operating
// systems, use polling instead
#ifdef __linux__
#define IONTRAP_USE_INOTIFY
#endif
namespace xacc {
namespace quantum {
class IonTrapAccelerator : public Accelerator {
public:
// Identifiable interface impls
virtual const std::string name() const override { return "iontrap"; }
virtual const std::string description() const override { return "XACC Accelerator targetting the IonTrap general-purpose quantum testbed"; }
// Accelerator interface impls
virtual void initialize(const HeterogeneousMap& params = {}) override;
virtual void updateConfiguration(const HeterogeneousMap& config) override;
virtual const std::vector<std::string> configurationKeys() override;
virtual BitOrder getBitOrder() override { return BitOrder::LSB; }
virtual std::vector<std::pair<int, int>> getConnectivity() override;
virtual void execute(std::shared_ptr<AcceleratorBuffer> buffer, const std::shared_ptr<CompositeInstruction> compositeInstruction) override;
virtual void execute(std::shared_ptr<AcceleratorBuffer> buffer, const std::vector<std::shared_ptr<CompositeInstruction>> compositeInstructions) override;
private:
static constexpr double RESULT_CHECK_INTERVAL_SEC = 1;
std::string inputExt;
bool adjacentIonCouplingsOnly;
bool serializedSeq;
bool keepTempFiles;
bool emitQasm;
bool keepTrailingGates;
bool keepRzBeforeMeas;
bool keepRxBeforeXX;
bool keepLeadingRz;
double threshold;
std::size_t numQubits;
IonTrapCouplingMap couplingMap;
IonTrapMSPhaseMap msPhases;
std::string watchdir;
std::string logTransformsPath;
void readConfig();
std::map<std::string, std::string> readConfigKeys();
void compileToNativeGatesAndLogTransforms(std::shared_ptr<CompositeInstruction>);
void compileToNativeGates(std::shared_ptr<CompositeInstruction>, IonTrapLogTransformCallback);
#ifdef IONTRAP_USE_INOTIFY
int getInotifyFd(std::string);
void waitForResultFileInotify(int, std::string &);
#else
void waitForResultFile(std::string &);
#endif
std::vector<InstPtr> findOpTableRow(const std::shared_ptr<CompositeInstruction>,
std::size_t &);
void writeOpTable(const std::shared_ptr<CompositeInstruction>, std::ostream &);
void writeInput(std::shared_ptr<AcceleratorBuffer>,
const std::shared_ptr<CompositeInstruction>,
const std::string &,
std::multimap<std::size_t, std::size_t> &);
double calcExpZ(std::vector<std::complex<double>> &,
std::multimap<std::size_t, std::size_t> &);
void readResult(std::shared_ptr<AcceleratorBuffer>, const std::string &,
std::multimap<std::size_t, std::size_t> &);
std::string randomChars();
};
}}
#endif
/*******************************************************************************
* Copyright (c) 2019-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
* Daniel Strano - adaption from Quantum++ to Qrack
* Austin Adams - adaption for GTRI testbed
*******************************************************************************/
#include "IonTrapQasmVisitor.hpp"
#include "xacc.hpp"
namespace xacc {
namespace quantum {
void IonTrapQasmVisitor::writeHeader() {
for (int i = 0; i < nQubits; i++) {
qasmFile << "\tqubit q" << i << "\r\n";
}
qasmFile << "\r\n";
}
void IonTrapQasmVisitor::visit(Hadamard &h) {
qasmFile << "\tH q" << h.bits()[0] << "\r\n";
}
void IonTrapQasmVisitor::visit(CNOT &cnot) {
std::size_t leftIdx = std::min(cnot.bits()[0], cnot.bits()[1]);
std::size_t rightIdx = std::max(cnot.bits()[0], cnot.bits()[1]);
if (!couplingMap.count(std::make_pair(leftIdx, rightIdx))) {
xacc::error("CNOT on non-adjacent qubits " + std::to_string(leftIdx)
+ "," + std::to_string(rightIdx));
return;
}
qasmFile << "\tCNOT q" << cnot.bits()[0] << ",q" << cnot.bits()[1] << "\r\n";
}
void IonTrapQasmVisitor::visit(Rz &rz) {
double theta = rz.getParameter(0).as<double>();
qasmFile << "\tRZ(" << theta << ") q" << rz.bits()[0] << "\r\n";
}
void IonTrapQasmVisitor::visit(Ry &ry) {
double theta = ry.getParameter(0).as<double>();
S s(ry.bits()[0]);
Rx rx(ry.bits()[0], theta);
Sdg sdg(ry.bits()[0]);
// Ry(theta) = S.Rx(theta).Sdg
visit(sdg);
visit(rx);
visit(s);
}
void IonTrapQasmVisitor::visit(Rx &rx) {
double theta = rx.getParameter(0).as<double>();
Hadamard h1(rx.bits()[0]);
Rz rz(rx.bits()[0], theta);
Hadamard h2(rx.bits()[0]);
// RX(theta) = e^(-i*theta/2) H.RZ(theta).H
visit(h1);
visit(rz);
visit(h2);
}
void IonTrapQasmVisitor::visit(X &x) {
qasmFile << "\tX q" << x.bits()[0] << "\r\n";
}
void IonTrapQasmVisitor::visit(Y &y) {
qasmFile << "\tY q" << y.bits()[0] << "\r\n";
}
void IonTrapQasmVisitor::visit(Z &z) {
qasmFile << "\tZ q" << z.bits()[0] << "\r\n";
}
void IonTrapQasmVisitor::visit(CRZ &crz) {
xacc::warning("CRZ not implemented on IonTrap backend");
}
// From IonQ backend
void IonTrapQasmVisitor::visit(CH &ch) {
Hadamard h1(ch.bits()[1]);
Sdg sdg(ch.bits()[1]);
CNOT cn1(ch.bits());
Hadamard h2(ch.bits()[1]);
T t1(ch.bits()[1]);
CNOT cn2(ch.bits());
T t2(ch.bits()[1]);
Hadamard h3(ch.bits()[1]);
S s1(ch.bits()[1]);
X x(ch.bits()[1]);
S s2(ch.bits()[0]);
visit(h1);
visit(sdg);
visit(cn1);
visit(h2);
visit(t1);
visit(cn2);
visit(t2);
visit(h3);
visit(s1);
visit(x);
visit(s2);
}
void IonTrapQasmVisitor::visit(S &s) {
qasmFile << "\tS q" << s.bits()[0] << "\r\n";
}
void IonTrapQasmVisitor::visit(Sdg &sdg) {
qasmFile << "\tS! q" << sdg.bits()[0] << "\r\n";
}
void IonTrapQasmVisitor::visit(T &t) {
qasmFile << "\tT q" << t.bits()[0] << "\r\n";
}
void IonTrapQasmVisitor::visit(Tdg &tdg) {
qasmFile << "\tT! q" << tdg.bits()[0] << "\r\n";
}
void IonTrapQasmVisitor::visit(CPhase &cphase) {
// TODO: implement me
xacc::warning("CPhase not implemented on IonTrap backend");
}
void IonTrapQasmVisitor::visit(Identity &i) {
qasmFile << "\tI q" << i.bits()[0] << "\r\n";
}
void IonTrapQasmVisitor::visit(U &u) {
double theta = u.getParameter(0).as<double>();
double phi = u.getParameter(1).as<double>();
double lambda = u.getParameter(2).as<double>();
Rz rz1(u.bits()[0], phi);
Rx rx1(u.bits()[0], -xacc::constants::pi/2);
Rz rz2(u.bits()[0], theta);
Rx rx2(u.bits()[0], xacc::constants::pi/2);
Rz rz3(u.bits()[0], lambda);
// Per https://qiskit.org/documentation/stubs/qiskit.circuit.library.U3Gate.html,
// U(theta,pi,lambda) = Rz(phi).Rx(-pi/2).Rz(theta).Rx(pi/2).Rz(lambda)
visit(rz3);
visit(rx2);
visit(rz2);
visit(rx1);
visit(rz1);
}
void IonTrapQasmVisitor::visit(iSwap &in_iSwapGate) {
xacc::warning("iSWAP not implemented on IonTrap backend");
}
void IonTrapQasmVisitor::visit(fSim &in_fsimGate) {
xacc::warning("fSim not implemented on IonTrap backend");
}
void IonTrapQasmVisitor::visit(IfStmt &ifStmt) {
xacc::warning("if statement not implemented on IonTrap backend");
}
void IonTrapQasmVisitor::visit(Measure &meas) {
// This should've been handled beforehand in IonTrapAccelerator
xacc::error("Measure instruction reached IonTrapQasmVisitor!");
}
}}
/*******************************************************************************
* Copyright (c) 2019-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
* Daniel Strano - adaption from Quantum++ to Qrack
* Austin Adams - adaption for GTRI testbed
*******************************************************************************/
#ifndef QUANTUM_ACCELERATORS_IONTRAPQASMVISITOR_HPP_
#define QUANTUM_ACCELERATORS_IONTRAPQASMVISITOR_HPP_
#include "Identifiable.hpp"
#include "AllGateVisitor.hpp"
#include "AcceleratorBuffer.hpp"
#include "OptionsProvider.hpp"
using namespace xacc;
namespace xacc {
namespace quantum {
typedef std::set<std::pair<std::size_t, std::size_t>> IonTrapCouplingMap;
class IonTrapQasmVisitor : public AllGateVisitor, public OptionsProvider, public xacc::Cloneable<IonTrapQasmVisitor> {
public:
IonTrapQasmVisitor(std::size_t nQubits_, IonTrapCouplingMap &couplingMap_, std::ostream &qasmFile_) : nQubits(nQubits_), couplingMap(couplingMap_), qasmFile(qasmFile_) {}
void writeHeader();
void visit(Hadamard& h) override;
void visit(CNOT& cnot) override;
void visit(Rz& rz) override;
void visit(Ry& ry) override;
void visit(Rx& rx) override;
void visit(X& x) override;
void visit(Y& y) override;
void visit(Z& z) override;
void visit(CRZ& crz) override;
void visit(CH& ch) override;
void visit(S& s) override;
void visit(Sdg& sdg) override;
void visit(T& t) override;
void visit(Tdg& tdg) override;
void visit(CPhase& cphase) override;
void visit(Identity& i) override;
void visit(U& u) override;
void visit(iSwap& in_iSwapGate) override;
void visit(fSim& in_fsimGate) override;
void visit(IfStmt& ifStmt) override;
void visit(Measure &meas) override;
virtual std::shared_ptr<IonTrapQasmVisitor> clone() { return std::make_shared<IonTrapQasmVisitor>(nQubits, couplingMap, qasmFile); }
private:
std::size_t nQubits;
IonTrapCouplingMap &couplingMap;
std::ostream &qasmFile;
};
}}
#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