Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ORNL Quantum Computing Institute
xacc
Commits
10a00204
Commit
10a00204
authored
Nov 23, 2021
by
Adams, Austin Joel
Browse files
Add one-qubit IRTransformation for ion trap backend
Signed-off-by:
Austin Adams
<
aja@gatech.edu
>
parent
c3faf15a
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
quantum/plugins/iontrap/CMakeLists.txt
View file @
10a00204
...
...
@@ -15,6 +15,7 @@ set(LIBRARY_NAME xacc-iontrap)
file
(
GLOB SRC
*.cpp
decomp/*.cpp
transformations/*.cpp
)
usfunctiongetresourcesource
(
TARGET
${
LIBRARY_NAME
}
OUT SRC
)
...
...
@@ -24,6 +25,7 @@ add_library(${LIBRARY_NAME} SHARED ${SRC})
target_include_directories
(
${
LIBRARY_NAME
}
PUBLIC .
./decomp
./transformations
${
CMAKE_SOURCE_DIR
}
/tpls/ensmallen
${
CMAKE_SOURCE_DIR
}
/tpls/armadillo
)
...
...
quantum/plugins/iontrap/IonTrapActivator.cpp
View file @
10a00204
...
...
@@ -15,6 +15,7 @@
#include
"cppmicroservices/BundleActivator.h"
#include
"cppmicroservices/BundleContext.h"
#include
"cppmicroservices/ServiceProperties.h"
#include
"IonTrapOneQubitPass.hpp"
#include
"IonTrapTwoQubitPass.hpp"
using
namespace
cppmicroservices
;
...
...
@@ -26,6 +27,9 @@ public:
void
Start
(
BundleContext
context
)
{
auto
twoQubitPass
=
std
::
make_shared
<
xacc
::
quantum
::
IonTrapTwoQubitPass
>
();
context
.
RegisterService
<
xacc
::
IRTransformation
>
(
twoQubitPass
);
auto
oneQubitPass
=
std
::
make_shared
<
xacc
::
quantum
::
IonTrapOneQubitPass
>
();
context
.
RegisterService
<
xacc
::
IRTransformation
>
(
oneQubitPass
);
}
void
Stop
(
BundleContext
context
)
{}
...
...
quantum/plugins/iontrap/decomp/IonTrapDecomp.cpp
0 → 100644
View file @
10a00204
/*******************************************************************************
* 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 implementation
*******************************************************************************/
#include
<cassert>
#include
"IonTrapDecomp.hpp"
namespace
xacc
{
namespace
quantum
{
std
::
string
decompName
(
const
Decomp
decomp
)
{
switch
(
decomp
)
{
case
Decomp
::
Exact
:
return
"exact"
;
case
Decomp
::
RX
:
return
"Rx"
;
case
Decomp
::
RZ
:
return
"Rz"
;
case
Decomp
::
RZExact
:
return
"RzExact"
;
case
Decomp
::
RZRX
:
return
"RzRx"
;
case
Decomp
::
RZRZ
:
return
"RzRz"
;
default:
assert
(
0
);
return
""
;
}
}
Decomp
decompNextToTry
(
const
Decomp
decomp
)
{
switch
(
decomp
)
{
case
Decomp
::
RX
:
case
Decomp
::
RZ
:
case
Decomp
::
RZExact
:
return
Decomp
::
Exact
;
case
Decomp
::
RZRX
:
return
Decomp
::
RX
;
case
Decomp
::
RZRZ
:
return
Decomp
::
RZ
;
default:
// Exact should never call this function. If exact fails, we are
// in bad shape and should handle it differently
assert
(
0
);
return
Decomp
::
Exact
;
}
}
bool
decompShouldSkip
(
const
Decomp
decomp
,
const
int
rotations
)
{
// Rx(phi2).Rz(phi1) needs two angles. One can be 0, that's fine.
// Also, Rz(phi2).Rz(phi1) = Rz(phi2 + phi1) is really just 1 angle.
return
(
decomp
==
Decomp
::
RZRX
&&
rotations
==
1
)
||
(
decomp
==
Decomp
::
RZRZ
&&
rotations
==
2
);
}
std
::
size_t
decompFromRotationCount
(
const
Decomp
decomp
)
{
// The first 1 entry of the array of rotations is an Rz for
// Decomp::RZ{Exact,RX,RZ}, but in the case of plain
// old Decomp::{Exact,RX,RZ}, there are 0 such entries
return
decomp
!=
Decomp
::
Exact
&&
decomp
!=
Decomp
::
RX
&&
decomp
!=
Decomp
::
RZ
;
}
std
::
size_t
decompCount
(
const
Decomp
decomp
)
{
// The last 1 entry of the array of rotations is an Rx/Rz for
// Decomp::RX/RZ, but in the case of Decomp::Exact,
// there are 0 such entries
return
decomp
!=
Decomp
::
Exact
&&
decomp
!=
Decomp
::
RZExact
;
}
bool
decompShouldTrack
(
const
Decomp
decomp
)
{
// We only care about tracking Rx rotations (across XX gates)
return
decomp
==
Decomp
::
RX
||
decomp
==
Decomp
::
RZRX
;
}
arma
::
cx_mat
decompFromMat
(
const
Decomp
decomp
,
const
double
phi
)
{
const
auto
i
=
std
::
complex
<
double
>
(
0
,
1
);
if
(
decomp
==
Decomp
::
Exact
||
decomp
==
Decomp
::
RX
||
decomp
==
Decomp
::
RZ
)
{
return
arma
::
eye
<
arma
::
cx_mat
>
(
2
,
2
);
}
else
if
(
decomp
==
Decomp
::
RZExact
||
decomp
==
Decomp
::
RZRX
||
decomp
==
Decomp
::
RZRZ
)
{
// Reuse RZ rotation code from decompMat()
return
decompMat
(
Decomp
::
RZ
,
phi
);
}
else
{
assert
(
0
);
return
{};
}
}
arma
::
cx_mat
decompMat
(
const
Decomp
decomp
,
const
double
phi
)
{
const
auto
i
=
std
::
complex
<
double
>
(
0
,
1
);
if
(
decomp
==
Decomp
::
Exact
||
decomp
==
Decomp
::
RZExact
)
{
return
arma
::
eye
<
arma
::
cx_mat
>
(
2
,
2
);
}
else
if
(
decomp
==
Decomp
::
RX
||
decomp
==
Decomp
::
RZRX
)
{
arma
::
cx_mat
rx
({
std
::
cos
(
phi
/
2.0
),
-
i
*
std
::
sin
(
phi
/
2.0
),
-
i
*
std
::
sin
(
phi
/
2.0
),
std
::
cos
(
phi
/
2.0
)});
rx
.
reshape
(
2
,
2
);
return
rx
;
}
else
if
(
decomp
==
Decomp
::
RZ
||
decomp
==
Decomp
::
RZRZ
)
{
arma
::
cx_mat
rz
({
std
::
exp
(
-
i
*
phi
/
2.0
),
0
,
0
,
std
::
exp
(
i
*
phi
/
2.0
)});
rz
.
reshape
(
2
,
2
);
return
rz
;
}
else
{
assert
(
0
);
return
{};
}
}
}
// namespace quantum
}
// namespace xacc
quantum/plugins/iontrap/decomp/IonTrapDecomp.hpp
0 → 100644
View file @
10a00204
/*******************************************************************************
* 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
*******************************************************************************/
#ifndef QUANTUM_ACCELERATORS_IONTRAPDECOMP_HPP_
#define QUANTUM_ACCELERATORS_IONTRAPDECOMP_HPP_
#include
<armadillo>
namespace
xacc
{
namespace
quantum
{
enum
class
Decomp
:
int
{
Exact
,
RX
,
RZ
,
RZExact
,
RZRX
,
RZRZ
};
std
::
size_t
decompFromRotationCount
(
const
Decomp
);
arma
::
cx_mat
decompFromMat
(
const
Decomp
,
const
double
);
arma
::
cx_mat
decompMat
(
const
Decomp
,
const
double
);
std
::
size_t
decompCount
(
const
Decomp
);
Decomp
decompNextToTry
(
const
Decomp
);
bool
decompShouldSkip
(
const
Decomp
,
const
int
);
std
::
string
decompName
(
const
Decomp
);
bool
decompShouldTrack
(
const
Decomp
);
}
// namespace quantum
}
// namespace xacc
#endif
quantum/plugins/iontrap/decomp/IonTrapOptFunction.cpp
0 → 100644
View file @
10a00204
This diff is collapsed.
Click to expand it.
quantum/plugins/iontrap/decomp/IonTrapOptFunction.hpp
0 → 100644
View file @
10a00204
/*******************************************************************************
* 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
*******************************************************************************/
#ifndef QUANTUM_ACCELERATORS_IONTRAPOPTFUNCTION_HPP_
#define QUANTUM_ACCELERATORS_IONTRAPOPTFUNCTION_HPP_
#include
<armadillo>
#include
"IonTrapDecomp.hpp"
namespace
xacc
{
namespace
quantum
{
class
IonTrapOptFunction
{
public:
IonTrapOptFunction
(
Decomp
decomp
,
const
arma
::
cx_mat
&
goalUnitary
)
:
decomp
(
decomp
),
goal
(
goalUnitary
)
{}
double
Evaluate
(
const
arma
::
mat
&
phi
);
double
EvaluateWithGradient
(
const
arma
::
mat
&
phi
,
arma
::
mat
&
g
);
private:
typedef
void
(
IonTrapOptFunction
::*
NablaMethod
)(
const
arma
::
mat
&
,
arma
::
cx_mat
&
);
const
Decomp
decomp
;
const
arma
::
cx_mat
&
goal
;
std
::
complex
<
double
>
H
(
const
arma
::
mat
&
phi
);
void
nablaHExact_1
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHRx_1
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHRz_1
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHRzExact_1
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
// No nablaHRzRx_1() because Rx(phi2).Rz(phi1) needs two angles. One can be 0, that's fine
void
nablaHRzRz_1
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHExact_2
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHRx_2
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHRz_2
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHRzExact_2
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHRzRx_2
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
// No nablaHRzRz_2() because Rz(phi2).Rz(phi1) = Rz(phi2 + phi1) is really just 1 angle
void
nablaHExact_3
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHRx_3
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHRz_3
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHRzExact_3
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHRzRx_3
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHRzRz_3
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHExact_4
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHRx_4
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHRz_4
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHRzExact_4
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHRzRx_4
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
void
nablaHRzRz_4
(
const
arma
::
mat
&
phi
,
arma
::
cx_mat
&
gh
);
};
}
// namespace quantum
}
// namespace xacc
#endif
quantum/plugins/iontrap/tests/CMakeLists.txt
View file @
10a00204
...
...
@@ -13,5 +13,8 @@
# Austin Adams - adaption for GTRI testbed
# *******************************************************************************/
add_xacc_test
(
IonTrapOneQubitPass
)
target_link_libraries
(
IonTrapOneQubitPassTester xacc-iontrap
)
add_xacc_test
(
IonTrapTwoQubitPass
)
target_link_libraries
(
IonTrapTwoQubitPassTester xacc-iontrap
)
quantum/plugins/iontrap/tests/IonTrapOneQubitPassTester.cpp
0 → 100644
View file @
10a00204
/*******************************************************************************
* 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
"IonTrapOneQubitPass.hpp"
#include
"IonTrapTwoQubitPass.hpp"
namespace
{
// Give us some nice breathing room
const
double
ERR
=
1e-4
;
const
double
THRESHOLD
=
1e-3
;
}
//
// Single-qubit pass tests
//
TEST
(
IonTrapOneQubitPassTester
,
oneQubitPassExactX
)
{
auto
c
=
xacc
::
getService
<
xacc
::
Compiler
>
(
"xasm"
);
auto
ir
=
c
->
compile
(
R"(__qpu__ void my_x(qbit q) {
X(q[0]);
})"
)
->
getComposites
()[
0
];
auto
oneQubitPass
=
xacc
::
getService
<
xacc
::
IRTransformation
>
(
"iontrap-1q-pass"
);
oneQubitPass
->
apply
(
ir
,
nullptr
,
{{
"threshold"
,
THRESHOLD
},
{
"keep-trailing-gates"
,
true
},
{
"keep-rz-before-meas"
,
true
},
{
"keep-rx-before-xx"
,
true
},
{
"keep-leading-rz"
,
true
}});
std
::
vector
<
std
::
size_t
>
bits0
({
0
});
EXPECT_EQ
(
2
,
ir
->
nInstructions
());
EXPECT_EQ
(
"Rphi"
,
ir
->
getInstruction
(
0
)
->
name
());
EXPECT_EQ
(
bits0
,
ir
->
getInstruction
(
0
)
->
bits
());
EXPECT_NEAR
(
0.0
,
xacc
::
InstructionParameterToDouble
(
ir
->
getInstruction
(
0
)
->
getParameter
(
0
)),
ERR
);
EXPECT_EQ
(
"Rphi"
,
ir
->
getInstruction
(
1
)
->
name
());
EXPECT_EQ
(
bits0
,
ir
->
getInstruction
(
1
)
->
bits
());
EXPECT_NEAR
(
0.0
,
xacc
::
InstructionParameterToDouble
(
ir
->
getInstruction
(
1
)
->
getParameter
(
0
)),
ERR
);
}
TEST
(
IonTrapOneQubitPassTester
,
oneQubitPassCommuteXAroundXX
)
{
auto
c
=
xacc
::
getService
<
xacc
::
Compiler
>
(
"xasm"
);
auto
ir
=
c
->
compile
(
R"(__qpu__ void xx_x_test(qbit q) {
X(q[0]);
X(q[1]);
XX(q[0], q[1], pi/4);
X(q[0]);
X(q[1]);
})"
)
->
getComposites
()[
0
];
auto
oneQubitPass
=
xacc
::
getService
<
xacc
::
IRTransformation
>
(
"iontrap-1q-pass"
);
oneQubitPass
->
apply
(
ir
,
nullptr
,
{{
"threshold"
,
THRESHOLD
},
{
"keep-trailing-gates"
,
true
},
{
"keep-rz-before-meas"
,
true
},
{
"keep-rx-before-xx"
,
false
},
{
"keep-leading-rz"
,
true
}});
std
::
vector
<
std
::
size_t
>
bits01
({
0
,
1
});
EXPECT_EQ
(
1
,
ir
->
nInstructions
());
EXPECT_EQ
(
"XX"
,
ir
->
getInstruction
(
0
)
->
name
());
EXPECT_EQ
(
bits01
,
ir
->
getInstruction
(
0
)
->
bits
());
EXPECT_NEAR
(
M_PI
/
4
,
xacc
::
InstructionParameterToDouble
(
ir
->
getInstruction
(
0
)
->
getParameter
(
0
)),
ERR
);
}
TEST
(
IonTrapOneQubitPassTester
,
oneQubitPassUpToZ
)
{
auto
c
=
xacc
::
getService
<
xacc
::
Compiler
>
(
"xasm"
);
auto
ir
=
c
->
compile
(
R"(__qpu__ void upToZ(qbit q) {
H(q[0]);
Measure(q[0]);
})"
)
->
getComposites
()[
0
];
auto
oneQubitPass
=
xacc
::
getService
<
xacc
::
IRTransformation
>
(
"iontrap-1q-pass"
);
oneQubitPass
->
apply
(
ir
,
nullptr
,
{{
"threshold"
,
THRESHOLD
},
{
"keep-trailing-gates"
,
true
},
{
"keep-rz-before-meas"
,
false
},
{
"keep-rx-before-xx"
,
true
},
{
"keep-leading-rz"
,
true
}});
std
::
vector
<
std
::
size_t
>
bits0
({
0
});
EXPECT_EQ
(
2
,
ir
->
nInstructions
());
EXPECT_EQ
(
"Rphi"
,
ir
->
getInstruction
(
0
)
->
name
());
EXPECT_EQ
(
bits0
,
ir
->
getInstruction
(
0
)
->
bits
());
EXPECT_NEAR
(
-
M_PI
/
2
,
xacc
::
InstructionParameterToDouble
(
ir
->
getInstruction
(
0
)
->
getParameter
(
0
)),
ERR
);
EXPECT_EQ
(
"Measure"
,
ir
->
getInstruction
(
1
)
->
name
());
EXPECT_EQ
(
bits0
,
ir
->
getInstruction
(
1
)
->
bits
());
}
TEST
(
IonTrapOneQubitPassTester
,
oneQubitPassFromZ
)
{
auto
c
=
xacc
::
getService
<
xacc
::
Compiler
>
(
"xasm"
);
auto
ir
=
c
->
compile
(
R"(__qpu__ void fromZ(qbit q) {
H(q[0]);
})"
)
->
getComposites
()[
0
];
auto
oneQubitPass
=
xacc
::
getService
<
xacc
::
IRTransformation
>
(
"iontrap-1q-pass"
);
oneQubitPass
->
apply
(
ir
,
nullptr
,
{{
"threshold"
,
THRESHOLD
},
{
"keep-trailing-gates"
,
true
},
{
"keep-rz-before-meas"
,
true
},
{
"keep-rx-before-xx"
,
true
},
{
"keep-leading-rz"
,
false
}});
std
::
vector
<
std
::
size_t
>
bits0
({
0
});
EXPECT_EQ
(
1
,
ir
->
nInstructions
());
EXPECT_EQ
(
"Rphi"
,
ir
->
getInstruction
(
0
)
->
name
());
EXPECT_EQ
(
bits0
,
ir
->
getInstruction
(
0
)
->
bits
());
EXPECT_NEAR
(
M_PI
/
2
,
xacc
::
InstructionParameterToDouble
(
ir
->
getInstruction
(
0
)
->
getParameter
(
0
)),
ERR
);
}
TEST
(
IonTrapOneQubitPassTester
,
oneQubitPassFromZtoX
)
{
auto
c
=
xacc
::
getService
<
xacc
::
Compiler
>
(
"xasm"
);
auto
ir
=
c
->
compile
(
R"(__qpu__ void fromZtoX(qbit q) {
Y(q[0]);
XX(q[0], q[1], pi/4);
})"
)
->
getComposites
()[
0
];
auto
oneQubitPass
=
xacc
::
getService
<
xacc
::
IRTransformation
>
(
"iontrap-1q-pass"
);
oneQubitPass
->
apply
(
ir
,
nullptr
,
{{
"threshold"
,
THRESHOLD
},
{
"keep-trailing-gates"
,
true
},
{
"keep-rz-before-meas"
,
true
},
{
"keep-rx-before-xx"
,
false
},
{
"keep-leading-rz"
,
false
}});
std
::
vector
<
std
::
size_t
>
bits0
({
0
});
std
::
vector
<
std
::
size_t
>
bits01
({
0
,
1
});
EXPECT_EQ
(
3
,
ir
->
nInstructions
());
EXPECT_EQ
(
"XX"
,
ir
->
getInstruction
(
0
)
->
name
());
EXPECT_EQ
(
bits01
,
ir
->
getInstruction
(
0
)
->
bits
());
EXPECT_NEAR
(
M_PI
/
4
,
xacc
::
InstructionParameterToDouble
(
ir
->
getInstruction
(
0
)
->
getParameter
(
0
)),
ERR
);
EXPECT_EQ
(
"Rphi"
,
ir
->
getInstruction
(
1
)
->
name
());
EXPECT_EQ
(
bits0
,
ir
->
getInstruction
(
1
)
->
bits
());
EXPECT_NEAR
(
0
,
xacc
::
InstructionParameterToDouble
(
ir
->
getInstruction
(
1
)
->
getParameter
(
0
)),
ERR
);
EXPECT_EQ
(
"Rphi"
,
ir
->
getInstruction
(
2
)
->
name
());
EXPECT_EQ
(
bits0
,
ir
->
getInstruction
(
2
)
->
bits
());
EXPECT_NEAR
(
0
,
xacc
::
InstructionParameterToDouble
(
ir
->
getInstruction
(
2
)
->
getParameter
(
0
)),
ERR
);
}
TEST
(
IonTrapOneQubitPassTester
,
oneQubitPassFromZtoZ
)
{
auto
c
=
xacc
::
getService
<
xacc
::
Compiler
>
(
"xasm"
);
auto
ir
=
c
->
compile
(
R"(__qpu__ void fromZtoZ(qbit q) {
Z(q[0]);
})"
)
->
getComposites
()[
0
];
auto
oneQubitPass
=
xacc
::
getService
<
xacc
::
IRTransformation
>
(
"iontrap-1q-pass"
);
oneQubitPass
->
apply
(
ir
,
nullptr
,
{{
"threshold"
,
THRESHOLD
},
{
"keep-trailing-gates"
,
true
},
{
"keep-rz-before-meas"
,
false
},
{
"keep-rx-before-xx"
,
true
},
{
"keep-leading-rz"
,
false
}});
std
::
vector
<
std
::
size_t
>
bits0
({
0
});
EXPECT_EQ
(
0
,
ir
->
nInstructions
());
}
TEST
(
IonTrapOneQubitPassTester
,
oneQubitPassTrailingGates
)
{
auto
c
=
xacc
::
getService
<
xacc
::
Compiler
>
(
"xasm"
);
auto
ir
=
c
->
compile
(
R"(__qpu__ void fromZtoZ(qbit q) {
XX(q[0], q[1], pi/4);
X(q[1]);
Y(q[0]);
Measure(q[0]);
})"
)
->
getComposites
()[
0
];
auto
oneQubitPass
=
xacc
::
getService
<
xacc
::
IRTransformation
>
(
"iontrap-1q-pass"
);
oneQubitPass
->
apply
(
ir
,
nullptr
,
{{
"threshold"
,
THRESHOLD
},
{
"keep-trailing-gates"
,
false
},
{
"keep-rz-before-meas"
,
true
},
{
"keep-rx-before-xx"
,
true
},
{
"keep-leading-rz"
,
true
}});
std
::
vector
<
std
::
size_t
>
bits0
({
0
});
std
::
vector
<
std
::
size_t
>
bits01
({
0
,
1
});
EXPECT_EQ
(
4
,
ir
->
nInstructions
());
EXPECT_EQ
(
"XX"
,
ir
->
getInstruction
(
0
)
->
name
());
EXPECT_EQ
(
bits01
,
ir
->
getInstruction
(
0
)
->
bits
());
EXPECT_NEAR
(
M_PI
/
4
,
xacc
::
InstructionParameterToDouble
(
ir
->
getInstruction
(
0
)
->
getParameter
(
0
)),
ERR
);
EXPECT_EQ
(
"Rphi"
,
ir
->
getInstruction
(
1
)
->
name
());
EXPECT_EQ
(
bits0
,
ir
->
getInstruction
(
1
)
->
bits
());
EXPECT_NEAR
(
M_PI
/
2
,
xacc
::
InstructionParameterToDouble
(
ir
->
getInstruction
(
1
)
->
getParameter
(
0
)),
ERR
);
EXPECT_EQ
(
"Rphi"
,
ir
->
getInstruction
(
2
)
->
name
());
EXPECT_EQ
(
bits0
,
ir
->
getInstruction
(
2
)
->
bits
());
EXPECT_NEAR
(
M_PI
/
2
,
xacc
::
InstructionParameterToDouble
(
ir
->
getInstruction
(
2
)
->
getParameter
(
0
)),
ERR
);
EXPECT_EQ
(
"Measure"
,
ir
->
getInstruction
(
3
)
->
name
());
EXPECT_EQ
(
bits0
,
ir
->
getInstruction
(
3
)
->
bits
());
}
TEST
(
IonTrapOneQubitPassTester
,
oneQubitPassIdentity
)
{
auto
c
=
xacc
::
getService
<
xacc
::
Compiler
>
(
"xasm"
);
auto
ir
=
c
->
compile
(
R"(__qpu__ void identityTest(qbit q) {
X(q[0]);
XX(q[0], q[1], pi/4);
X(q[0]);
H(q[1]);
H(q[1]);
})"
)
->
getComposites
()[
0
];
auto
oneQubitPass
=
xacc
::
getService
<
xacc
::
IRTransformation
>
(
"iontrap-1q-pass"
);
oneQubitPass
->
apply
(
ir
,
nullptr
,
{{
"threshold"
,
THRESHOLD
},
{
"keep-trailing-gates"
,
true
},
{
"keep-rz-before-meas"
,
true
},
{
"keep-rx-before-xx"
,
false
},
{
"keep-leading-rz"
,
true
}});
std
::
vector
<
std
::
size_t
>
bits01
({
0
,
1
});
EXPECT_EQ
(
1
,
ir
->
nInstructions
());
EXPECT_EQ
(
"XX"
,
ir
->
getInstruction
(
0
)
->
name
());
EXPECT_EQ
(
bits01
,
ir
->
getInstruction
(
0
)
->
bits
());
EXPECT_NEAR
(
M_PI
/
4
,
xacc
::
InstructionParameterToDouble
(
ir
->
getInstruction
(
0
)
->
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
;
}
quantum/plugins/iontrap/transformations/IonTrapOneQubitPass.cpp
0 → 100644
View file @
10a00204
/*******************************************************************************
* 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
<limits>
#include
"xacc.hpp"
#include
"xacc_service.hpp"
#include
<ensmallen.hpp>
#include
"IonTrapOneQubitPass.hpp"
#include
"IonTrapOptFunction.hpp"
#include
"Accelerator.hpp"
#include
"CommonGates.hpp"
#include
"GateFusion.hpp"