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

Merge pull request #488 from ausbin/feature/gtri-plugin

Create plugin for GTRI testbed backend
parents 71abf1f8 ab6b9083
Pipeline #178098 passed with stage
in 12 minutes and 59 seconds
...@@ -18,6 +18,7 @@ add_subdirectory(algorithms) ...@@ -18,6 +18,7 @@ add_subdirectory(algorithms)
add_subdirectory(decorators) add_subdirectory(decorators)
add_subdirectory(circuits) add_subdirectory(circuits)
add_subdirectory(optimizers) add_subdirectory(optimizers)
add_subdirectory(iontrap)
add_subdirectory(ionq) add_subdirectory(ionq)
add_subdirectory(placement) add_subdirectory(placement)
#add_subdirectory(scaffold) #add_subdirectory(scaffold)
......
# *******************************************************************************
# Copyright (c) 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 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
# Austin Adams - aggressive copying and pasting for GTRI testbed
# *******************************************************************************/
set(LIBRARY_NAME xacc-iontrap)
file(GLOB SRC
*.cpp
transformations/*.cpp)
usfunctiongetresourcesource(TARGET ${LIBRARY_NAME} OUT SRC)
usfunctiongeneratebundleinit(TARGET ${LIBRARY_NAME} OUT SRC)
add_library(${LIBRARY_NAME} SHARED ${SRC})
target_include_directories(${LIBRARY_NAME}
PUBLIC .
./transformations
${CMAKE_SOURCE_DIR}/tpls/ensmallen
${CMAKE_SOURCE_DIR}/tpls/armadillo)
target_link_libraries(${LIBRARY_NAME}
PUBLIC xacc
xacc-quantum-gate
xacc-circuit-optimizers
)
if(LAPACK_FOUND)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAS_LAPACK")
target_link_libraries(${LIBRARY_NAME} PUBLIC ${LAPACK_LIBRARIES})
else()
message(STATUS "LAPACK NOT FOUND. ion trap plugin may not work.")
endif()
set(_bundle_name xacc_iontrap)
set_target_properties(${LIBRARY_NAME}
PROPERTIES COMPILE_DEFINITIONS
US_BUNDLE_NAME=${_bundle_name}
US_BUNDLE_NAME
${_bundle_name})
usfunctionembedresources(TARGET
${LIBRARY_NAME}
WORKING_DIRECTORY
${CMAKE_CURRENT_SOURCE_DIR}
FILES
manifest.json)
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()
if(XACC_BUILD_TESTS)
add_subdirectory(tests)
endif()
install(TARGETS ${LIBRARY_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/plugins)
/*******************************************************************************
* Copyright (c) 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 - aggressive copying and pasting for GTRI testbed
*******************************************************************************/
#include "cppmicroservices/BundleActivator.h"
#include "cppmicroservices/BundleContext.h"
#include "cppmicroservices/ServiceProperties.h"
#include "IonTrapTwoQubitPass.hpp"
using namespace cppmicroservices;
class US_ABI_LOCAL IonTrapActivator : public BundleActivator {
public:
IonTrapActivator() {}
void Start(BundleContext context) {
auto twoQubitPass = std::make_shared<xacc::quantum::IonTrapTwoQubitPass>();
context.RegisterService<xacc::IRTransformation>(twoQubitPass);
}
void Stop(BundleContext context) {}
};
CPPMICROSERVICES_EXPORT_BUNDLE_ACTIVATOR(IonTrapActivator)
Ion Trap Testbed Backend
========================
This is a backend that targets the quantum testbed developed by the CIPHER
[Quantum Systems Division][1] at Georgia Tech Research Institute (GTRI). The
following 2016 paper describes the testbed:
https://doi.org/10.1088/1367-2630/18/2/023048. However, due to recent hardware
upgrades, we assume that the gate beam is now tightly-focused enough for
single-ion addressing. (That is, such that the cascading scheme is no longer
necessary for single-qubit gates.) We also assume that the MS phases are 0,
meaning the native entangling gate is an XX-Ising gate. We also do not consider
the MS echo scheme described in the paper.
This is designed for modified version of the control software, which is written
in IGOR Pro and is not currently public.
Please contact Austin Adams at <aja@gatech.edu> if you have any questions about
this backend.
[1]: https://www.gtri.gatech.edu/focus-areas/quantum-computing-sensing
{
"bundle.symbolic_name" : "xacc_iontrap",
"bundle.activator" : true,
"bundle.name" : "XACC Ion Trap Testbed Accelerator",
"bundle.description" : "This bundle provides an Accelerator for an ion trap quantum testbed."
}
# *******************************************************************************
# 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 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
# Daniel Strano - adaption from Quantum++ to Qrack
# Austin Adams - adaption for GTRI testbed
# *******************************************************************************/
add_xacc_test(IonTrapTwoQubitPass)
target_link_libraries(IonTrapTwoQubitPassTester xacc-iontrap)
/*******************************************************************************
* 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
*******************************************************************************/
#include <gtest/gtest.h>
#include "xacc.hpp"
#include "xacc_service.hpp"
#include "IonTrapTwoQubitPass.hpp"
namespace {
// Give us some nice breathing room
const double ERR = 1e-4;
}
//
// Two-qubit pass tests
//
TEST(IonTrapTwoQubitPassTester, twoQubitPassDecomposesCnot)
{
auto c = xacc::getService<xacc::Compiler>("xasm");
auto ir = c->compile(R"(__qpu__ void my_bell(qbit q) {
H(q[0]);
X(q[1]);
CX(q[0],q[1]);
Measure(q[0]);
Measure(q[1]);
})")->getComposites()[0];
auto twoQubitPass = xacc::getService<xacc::IRTransformation>("iontrap-2q-pass");
xacc::quantum::IonTrapMSPhaseMap msPhases({{{0, 1}, {0.0, 0.0}}});
twoQubitPass->apply(ir, nullptr, {{"ms-phases", &msPhases}});
std::vector<std::size_t> bits0({0});
std::vector<std::size_t> bits1({1});
std::vector<std::size_t> bits01({0,1});
EXPECT_EQ(9, ir->nInstructions());
EXPECT_EQ("H", ir->getInstruction(0)->name());
EXPECT_EQ(bits0, ir->getInstruction(0)->bits());
EXPECT_EQ("X", ir->getInstruction(1)->name());
EXPECT_EQ(bits1, ir->getInstruction(1)->bits());
EXPECT_EQ("Ry", ir->getInstruction(2)->name());
EXPECT_EQ(bits0, ir->getInstruction(2)->bits());
EXPECT_NEAR(-M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(2)->getParameter(0)),
ERR);
EXPECT_EQ("XX", ir->getInstruction(3)->name());
EXPECT_EQ(bits01, ir->getInstruction(3)->bits());
EXPECT_NEAR(M_PI/4.0,
xacc::InstructionParameterToDouble(ir->getInstruction(3)->getParameter(0)),
ERR);
EXPECT_EQ("Ry", ir->getInstruction(4)->name());
EXPECT_EQ(bits0, ir->getInstruction(4)->bits());
EXPECT_NEAR(M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(4)->getParameter(0)),
ERR);
EXPECT_EQ("Rz", ir->getInstruction(5)->name());
EXPECT_EQ(bits0, ir->getInstruction(5)->bits());
EXPECT_NEAR(M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(5)->getParameter(0)),
ERR);
EXPECT_EQ("Rx", ir->getInstruction(6)->name());
EXPECT_EQ(bits1, ir->getInstruction(6)->bits());
EXPECT_NEAR(M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(6)->getParameter(0)),
ERR);
EXPECT_EQ("Measure", ir->getInstruction(7)->name());
EXPECT_EQ(bits0, ir->getInstruction(7)->bits());
EXPECT_EQ("Measure", ir->getInstruction(8)->name());
EXPECT_EQ(bits1, ir->getInstruction(8)->bits());
}
TEST(IonTrapTwoQubitPassTester, twoQubitPassDecomposesCZ)
{
auto c = xacc::getService<xacc::Compiler>("xasm");
auto ir = c->compile(R"(__qpu__ void my_cz(qbit q) {
CZ(q[1],q[0]);
})")->getComposites()[0];
auto twoQubitPass = xacc::getService<xacc::IRTransformation>("iontrap-2q-pass");
xacc::quantum::IonTrapMSPhaseMap msPhases({{{0, 1}, {0.0, 0.0}}});
twoQubitPass->apply(ir, nullptr, {{"ms-phases", &msPhases}});
std::vector<std::size_t> bits0({0});
std::vector<std::size_t> bits1({1});
std::vector<std::size_t> bits10({1,0});
EXPECT_EQ(7, ir->nInstructions());
EXPECT_EQ("H", ir->getInstruction(0)->name());
EXPECT_EQ(bits0, ir->getInstruction(0)->bits());
EXPECT_EQ("Ry", ir->getInstruction(1)->name());
EXPECT_EQ(bits1, ir->getInstruction(1)->bits());
EXPECT_NEAR(-M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(1)->getParameter(0)),
ERR);
EXPECT_EQ("XX", ir->getInstruction(2)->name());
EXPECT_EQ(bits10, ir->getInstruction(2)->bits());
EXPECT_NEAR(M_PI/4.0,
xacc::InstructionParameterToDouble(ir->getInstruction(2)->getParameter(0)),
ERR);
EXPECT_EQ("Ry", ir->getInstruction(3)->name());
EXPECT_EQ(bits1, ir->getInstruction(3)->bits());
EXPECT_NEAR(M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(3)->getParameter(0)),
ERR);
EXPECT_EQ("Rz", ir->getInstruction(4)->name());
EXPECT_EQ(bits1, ir->getInstruction(4)->bits());
EXPECT_NEAR(M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(4)->getParameter(0)),
ERR);
EXPECT_EQ("Rx", ir->getInstruction(5)->name());
EXPECT_EQ(bits0, ir->getInstruction(5)->bits());
EXPECT_NEAR(M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(5)->getParameter(0)),
ERR);
EXPECT_EQ("H", ir->getInstruction(6)->name());
EXPECT_EQ(bits0, ir->getInstruction(6)->bits());
}
TEST(IonTrapTwoQubitPassTester, twoQubitPassDecomposesSwap)
{
auto c = xacc::getService<xacc::Compiler>("xasm");
auto ir = c->compile(R"(__qpu__ void my_swap(qbit q) {
Swap(q[0],q[1]);
})")->getComposites()[0];
auto twoQubitPass = xacc::getService<xacc::IRTransformation>("iontrap-2q-pass");
xacc::quantum::IonTrapMSPhaseMap msPhases({{{0, 1}, {0.0, 0.0}}});
twoQubitPass->apply(ir, nullptr, {{"ms-phases", &msPhases}});
std::vector<std::size_t> bits0({0});
std::vector<std::size_t> bits1({1});
std::vector<std::size_t> bits01({0,1});
std::vector<std::size_t> bits10({1,0});
EXPECT_EQ(15, ir->nInstructions());
// CNOT 0,1
EXPECT_EQ("Ry", ir->getInstruction(0)->name());
EXPECT_EQ(bits0, ir->getInstruction(0)->bits());
EXPECT_NEAR(-M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(0)->getParameter(0)),
ERR);
EXPECT_EQ("XX", ir->getInstruction(1)->name());
EXPECT_EQ(bits01, ir->getInstruction(1)->bits());
EXPECT_NEAR(M_PI/4.0,
xacc::InstructionParameterToDouble(ir->getInstruction(1)->getParameter(0)),
ERR);
EXPECT_EQ("Ry", ir->getInstruction(2)->name());
EXPECT_EQ(bits0, ir->getInstruction(2)->bits());
EXPECT_NEAR(M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(2)->getParameter(0)),
ERR);
EXPECT_EQ("Rz", ir->getInstruction(3)->name());
EXPECT_EQ(bits0, ir->getInstruction(3)->bits());
EXPECT_NEAR(M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(3)->getParameter(0)),
ERR);
EXPECT_EQ("Rx", ir->getInstruction(4)->name());
EXPECT_EQ(bits1, ir->getInstruction(4)->bits());
EXPECT_NEAR(M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(4)->getParameter(0)),
ERR);
// CNOT 1,0
EXPECT_EQ("Ry", ir->getInstruction(5)->name());
EXPECT_EQ(bits1, ir->getInstruction(5)->bits());
EXPECT_NEAR(-M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(5)->getParameter(0)),
ERR);
EXPECT_EQ("XX", ir->getInstruction(6)->name());
EXPECT_EQ(bits10, ir->getInstruction(6)->bits());
EXPECT_NEAR(M_PI/4.0,
xacc::InstructionParameterToDouble(ir->getInstruction(6)->getParameter(0)),
ERR);
EXPECT_EQ("Ry", ir->getInstruction(7)->name());
EXPECT_EQ(bits1, ir->getInstruction(7)->bits());
EXPECT_NEAR(M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(7)->getParameter(0)),
ERR);
EXPECT_EQ("Rz", ir->getInstruction(8)->name());
EXPECT_EQ(bits1, ir->getInstruction(8)->bits());
EXPECT_NEAR(M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(8)->getParameter(0)),
ERR);
EXPECT_EQ("Rx", ir->getInstruction(9)->name());
EXPECT_EQ(bits0, ir->getInstruction(9)->bits());
EXPECT_NEAR(M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(9)->getParameter(0)),
ERR);
// CNOT 0,1
EXPECT_EQ("Ry", ir->getInstruction(10)->name());
EXPECT_EQ(bits0, ir->getInstruction(10)->bits());
EXPECT_NEAR(-M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(10)->getParameter(0)),
ERR);
EXPECT_EQ("XX", ir->getInstruction(11)->name());
EXPECT_EQ(bits01, ir->getInstruction(11)->bits());
EXPECT_NEAR(M_PI/4.0,
xacc::InstructionParameterToDouble(ir->getInstruction(11)->getParameter(0)),
ERR);
EXPECT_EQ("Ry", ir->getInstruction(12)->name());
EXPECT_EQ(bits0, ir->getInstruction(12)->bits());
EXPECT_NEAR(M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(12)->getParameter(0)),
ERR);
EXPECT_EQ("Rz", ir->getInstruction(13)->name());
EXPECT_EQ(bits0, ir->getInstruction(13)->bits());
EXPECT_NEAR(M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(13)->getParameter(0)),
ERR);
EXPECT_EQ("Rx", ir->getInstruction(14)->name());
EXPECT_EQ(bits1, ir->getInstruction(14)->bits());
EXPECT_NEAR(M_PI/2.0,
xacc::InstructionParameterToDouble(ir->getInstruction(14)->getParameter(0)),
ERR);
}
int main(int argc, char **argv) {
xacc::Initialize();
::testing::InitGoogleTest(&argc, argv);
const auto result = RUN_ALL_TESTS();
xacc::Finalize();
return result;
}
/*******************************************************************************
* Copyright (c) 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:
* Austin Adams - initial API and implementation
*******************************************************************************/
#include "InstructionIterator.hpp"
#include "IonTrapPassesCommon.hpp"
namespace xacc {
namespace quantum {
// Yoinked from MergeSingleQubitGatesOptimizer, except does not clone()
// instructions
void iontrapFlattenComposite(std::shared_ptr<CompositeInstruction> composite) {
std::vector<xacc::InstPtr> flatten;
InstructionIterator iter(composite);
while (iter.hasNext()) {
auto inst = iter.next();
if (!inst->isComposite()) {
// Previously, inst was clone()d here
flatten.emplace_back(inst);
}
}
composite->clear();
composite->addInstructions(flatten);
}
}
}
/*******************************************************************************
* Copyright (c) 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:
* Austin Adams - initial API and implementation
*******************************************************************************/
#ifndef QUANTUM_ACCELERATORS_IONTRAPPASSESCOMMON_HPP_
#define QUANTUM_ACCELERATORS_IONTRAPPASSESCOMMON_HPP_
#include "CompositeInstruction.hpp"
namespace xacc {
namespace quantum {
typedef std::function<void(std::vector<InstPtr>, std::vector<InstPtr>)> IonTrapLogTransformCallback;
void iontrapFlattenComposite(std::shared_ptr<CompositeInstruction> composite);
}
}
#endif
/*******************************************************************************
* Copyright (c) 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:
* Alexander J. McCaskey - initial API and implementation
* Austin Adams - adapted for GTRI testbed
*******************************************************************************/
#include "xacc.hpp"
#include "xacc_service.hpp"
#include "IonTrapTwoQubitPass.hpp"
#include "Accelerator.hpp"
namespace xacc {
namespace quantum {
//
// Two-qubit decompositions
//
std::pair<double, double> IonTrapTwoQubitPass::findMSPhases(IonTrapMSPhaseMap *msPhases, InstPtr 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]);
auto idxPair = std::make_pair(leftIdx, rightIdx);
if (!msPhases->count(idxPair)) {
xacc::error("pair " + std::to_string(leftIdx) + "," + std::to_string(rightIdx)
+ " missing from set of MS phases");
}
auto phasePair = (*msPhases)[idxPair];
double controlMSPhase = (leftIdx == cnot->bits()[0])? phasePair.first : phasePair.second;
double targetMSPhase = (rightIdx == cnot->bits()[1])? phasePair.second : phasePair.first;
return std::make_pair(controlMSPhase, targetMSPhase);
}
void IonTrapTwoQubitPass::apply(std::shared_ptr<CompositeInstruction> program,
const std::shared_ptr<Accelerator> accelerator,
const HeterogeneousMap &options) {
if (!options.keyExists<IonTrapMSPhaseMap*>("ms-phases")) {
xacc::error("IonTrapTwoQubitPass requires the ms-phases option");
return;
}
IonTrapMSPhaseMap *msPhases = options.get<IonTrapMSPhaseMap*>("ms-phases");
IonTrapLogTransformCallback logTransCallback = nullptr;
if (options.keyExists<IonTrapLogTransformCallback>("log-trans-cb")) {
logTransCallback = options.get<IonTrapLogTransformCallback>("log-trans-cb");
}
auto gateRegistry = xacc::getService<IRProvider>("quantum");
iontrapFlattenComposite(program);
for (std::size_t instIdx = 0; instIdx < program->nInstructions();) {
InstPtr inst = program->getInstruction(instIdx);
if (!inst->isEnabled()) {
instIdx++;
continue;
}
if (inst->name() == "CNOT") {
auto [controlMSPhase, targetMSPhase] = findMSPhases(msPhases, inst);
InstPtr ry1 = gateRegistry->createInstruction("Ry", {inst->bits()[0]}, {-M_PI/2.0});
InstPtr xx = gateRegistry->createInstruction("XX", inst->bits(), {M_PI/4.0});
InstPtr ry2 = gateRegistry->createInstruction("Ry", {inst->bits()[0]}, {M_PI/2.0});
InstPtr rz = gateRegistry->createInstruction("Rz", {inst->bits()[0]}, {M_PI/2.0});
InstPtr rx = gateRegistry->createInstruction("Rx", {inst->bits()[1]}, {M_PI/2.0});
std::size_t i = instIdx;
program->insertInstruction(i++, ry1);
// TODO: Note that this is kind of incorrect: really, the combination of these Rz gates
// and an MS gate is actually an XX gate (see https://doi.org/10.1088/1367-2630/18/2/023048)
// but we are surrounding an XX instruction with Rz instructions. But this will
// work for now
if (controlMSPhase) {
InstPtr msRz1 = gateRegistry->createInstruction("Rz", {inst->bits()[0]}, {controlMSPhase});
program->