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
f72be235
Unverified
Commit
f72be235
authored
Dec 16, 2021
by
Thien Nguyen
Committed by
GitHub
Dec 16, 2021
Browse files
Merge pull request #497 from ausbin/feature/iontrap-1q-pass
Add one-qubit IRTransformation for ion trap backend
parents
a7559218
10a00204
Pipeline
#180823
failed with stage
in 3 minutes and 17 seconds
Changes
10
Pipelines
2
Expand all
Hide whitespace changes
Inline
Side-by-side
quantum/plugins/iontrap/CMakeLists.txt
View file @
f72be235
...
...
@@ -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 @
f72be235
...
...
@@ -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 @
f72be235
/*******************************************************************************
* 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 @
f72be235
/*******************************************************************************
* 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 @
f72be235
This diff is collapsed.
Click to expand it.
quantum/plugins/iontrap/decomp/IonTrapOptFunction.hpp
0 → 100644
View file @
f72be235
/*******************************************************************************
* 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 @
f72be235
...
...
@@ -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 @
f72be235
/*******************************************************************************
* 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 @
f72be235
/*******************************************************************************
* 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"