Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ORNL Quantum Computing Institute
xacc
Commits
809790d9
Unverified
Commit
809790d9
authored
May 21, 2021
by
Mccaskey, Alex
Committed by
GitHub
May 21, 2021
Browse files
Merge pull request #453 from tnguyen-ornl/tnguyen/port-lnn-transform
Ported nnizer transform to XACC
parents
1210455f
ed13034e
Pipeline
#146845
passed with stage
in 23 minutes and 25 seconds
Changes
6
Pipelines
4
Hide whitespace changes
Inline
Side-by-side
quantum/plugins/optimizers/CMakeLists.txt
View file @
809790d9
...
...
@@ -13,7 +13,7 @@
set
(
LIBRARY_NAME xacc-circuit-optimizers
)
file
(
GLOB_RECURSE HEADERS *.hpp
)
file
(
GLOB SRC simple/*.cpp OptimizersActivator.cpp pulse/*.cpp gate_merge/*.cpp
)
file
(
GLOB SRC simple/*.cpp OptimizersActivator.cpp pulse/*.cpp gate_merge/*.cpp
lnn_transform/*.cpp
)
# Set up dependencies to resources to track changes
usFunctionGetResourceSource
(
TARGET
${
LIBRARY_NAME
}
OUT SRC
)
...
...
@@ -39,7 +39,7 @@ usFunctionEmbedResources(TARGET ${LIBRARY_NAME}
manifest.json
)
target_include_directories
(
${
LIBRARY_NAME
}
PUBLIC simple pulse gate_merge
${
CMAKE_SOURCE_DIR
}
/tpls/eigen
${
CMAKE_SOURCE_DIR
}
/tpls/exprtk
)
target_include_directories
(
${
LIBRARY_NAME
}
PUBLIC simple pulse gate_merge
lnn_transform
${
CMAKE_SOURCE_DIR
}
/tpls/eigen
${
CMAKE_SOURCE_DIR
}
/tpls/exprtk
)
target_link_libraries
(
${
LIBRARY_NAME
}
xacc xacc-quantum-gate
)
if
(
APPLE
)
...
...
@@ -57,6 +57,7 @@ if(XACC_BUILD_TESTS)
add_subdirectory
(
simple/tests
)
add_subdirectory
(
pulse/tests
)
add_subdirectory
(
gate_merge/tests
)
add_subdirectory
(
lnn_transform/tests
)
endif
()
add_subdirectory
(
qsearch
)
\ No newline at end of file
quantum/plugins/optimizers/OptimizersActivator.cpp
View file @
809790d9
...
...
@@ -14,7 +14,8 @@
#include "default_placement.hpp"
#include "GateMergeOptimizer.hpp"
#include "PulseTransform.hpp"
#include "GateFusion.hpp"
#include "GateFusion.hpp"
#include "NearestNeighborTransform.hpp"
// #include "qsearch.hpp"
#include "cppmicroservices/BundleActivator.h"
#include "cppmicroservices/BundleContext.h"
...
...
@@ -28,40 +29,40 @@ namespace {
/**
*/
class
US_ABI_LOCAL
OptimizersActivator
:
public
BundleActivator
{
class
US_ABI_LOCAL
OptimizersActivator
:
public
BundleActivator
{
public:
OptimizersActivator
()
{}
OptimizersActivator
()
{
}
/**
*/
void
Start
(
BundleContext
context
)
{
auto
c4
=
std
::
make_shared
<
xacc
::
quantum
::
CircuitOptimizer
>
();
context
.
RegisterService
<
xacc
::
IRTransformation
>
(
c4
);
/**
*/
void
Start
(
BundleContext
context
)
{
auto
c4
=
std
::
make_shared
<
xacc
::
quantum
::
CircuitOptimizer
>
();
context
.
RegisterService
<
xacc
::
IRTransformation
>
(
c4
);
auto
c5
=
std
::
make_shared
<
xacc
::
quantum
::
DefaultPlacement
>
();
context
.
RegisterService
<
xacc
::
IRTransformation
>
(
c5
);
auto
c
5
=
std
::
make_shared
<
xacc
::
quantum
::
DefaultPlacement
>
();
context
.
RegisterService
<
xacc
::
IRTransformation
>
(
c
5
);
//
auto c
6
= std::make_shared<xacc::quantum::
QsearchOptimizer
>();
//
context.RegisterService<xacc::IRTransformation>(c
6
);
context
.
RegisterService
<
xacc
::
IRTransformation
>
(
c5
);
context
.
RegisterService
<
xacc
::
IRTransformation
>
(
std
::
make_shared
<
xacc
::
quantum
::
PulseTransform
>
());
context
.
RegisterService
<
GateFuser
>
(
std
::
make_shared
<
GateFuser
>
());
context
.
RegisterService
<
xacc
::
IRTransformation
>
(
std
::
make_shared
<
xacc
::
quantum
::
MergeSingleQubitGatesOptimizer
>
());
context
.
RegisterService
<
xacc
::
IRTransformation
>
(
std
::
make_shared
<
xacc
::
quantum
::
MergeTwoQubitBlockOptimizer
>
());
context
.
RegisterService
<
xacc
::
IRTransformation
>
(
std
::
make_shared
<
xacc
::
quantum
::
NearestNeighborTransform
>
());
}
// auto c6 = std::make_shared<xacc::quantum::QsearchOptimizer>();
// context.RegisterService<xacc::IRTransformation>(c6);
context
.
RegisterService
<
xacc
::
IRTransformation
>
(
c5
);
context
.
RegisterService
<
xacc
::
IRTransformation
>
(
std
::
make_shared
<
xacc
::
quantum
::
PulseTransform
>
());
context
.
RegisterService
<
GateFuser
>
(
std
::
make_shared
<
GateFuser
>
());
context
.
RegisterService
<
xacc
::
IRTransformation
>
(
std
::
make_shared
<
xacc
::
quantum
::
MergeSingleQubitGatesOptimizer
>
());
context
.
RegisterService
<
xacc
::
IRTransformation
>
(
std
::
make_shared
<
xacc
::
quantum
::
MergeTwoQubitBlockOptimizer
>
());
}
/**
*/
void
Stop
(
BundleContext
/*context*/
)
{
}
/**
*/
void
Stop
(
BundleContext
/*context*/
)
{}
};
}
}
// namespace
CPPMICROSERVICES_EXPORT_BUNDLE_ACTIVATOR
(
OptimizersActivator
)
quantum/plugins/optimizers/lnn_transform/NearestNeighborTransform.cpp
0 → 100644
View file @
809790d9
#include "NearestNeighborTransform.hpp"
#include "InstructionIterator.hpp"
namespace
xacc
{
namespace
quantum
{
void
NearestNeighborTransform
::
apply
(
std
::
shared_ptr
<
CompositeInstruction
>
in_program
,
const
std
::
shared_ptr
<
Accelerator
>
in_accelerator
,
const
HeterogeneousMap
&
in_options
)
{
// The option is qubit-distance (default is 1, adjacent qubits)
// any 2-qubit gates that are further than this distance are converted into
// Swap + Original Gate (at qubit distance) + Swap
// Strategy: meet in the middle:
// e.g. CNOT q0, q9; qubit-distance = 2 (max distance is next neighbor,
// e.g. CNOT q0, q2; CNOT q7, q9 are okay) then we will Swap q0->q4; q9->q6;
// then CNOT q4, q6; then Swap q4->q0 and Swap q6->q9
int
maxDistance
=
1
;
if
(
in_options
.
keyExists
<
int
>
(
"max-distance"
))
{
maxDistance
=
in_options
.
get
<
int
>
(
"max-distance"
);
}
auto
provider
=
xacc
::
getIRProvider
(
"quantum"
);
auto
flattenedProgram
=
provider
->
createComposite
(
in_program
->
name
()
+
"_Flattened"
);
InstructionIterator
it
(
in_program
);
while
(
it
.
hasNext
())
{
auto
nextInst
=
it
.
next
();
if
(
nextInst
->
isEnabled
()
&&
!
nextInst
->
isComposite
())
{
flattenedProgram
->
addInstruction
(
nextInst
->
clone
());
}
}
auto
transformedProgram
=
provider
->
createComposite
(
in_program
->
name
()
+
"_Transformed"
);
for
(
int
i
=
0
;
i
<
flattenedProgram
->
nInstructions
();
++
i
)
{
auto
inst
=
flattenedProgram
->
getInstruction
(
i
);
const
auto
exceedMaxDistance
=
[
&
maxDistance
](
int
q1
,
int
q2
)
->
bool
{
return
std
::
abs
(
q1
-
q2
)
>
maxDistance
;
};
if
(
inst
->
bits
().
size
()
==
2
&&
exceedMaxDistance
(
inst
->
bits
()[
0
],
inst
->
bits
()[
1
]))
{
const
int
origLowerIdx
=
std
::
min
({
inst
->
bits
()[
0
],
inst
->
bits
()[
1
]});
const
int
origUpperIdx
=
std
::
max
({
inst
->
bits
()[
0
],
inst
->
bits
()[
1
]});
size_t
lowerIdx
=
origLowerIdx
;
size_t
upperIdx
=
origUpperIdx
;
// Insert swaps
for
(;;
/*Break inside*/
)
{
transformedProgram
->
addInstruction
(
provider
->
createInstruction
(
"Swap"
,
{
lowerIdx
,
lowerIdx
+
1
}));
lowerIdx
++
;
if
(
!
exceedMaxDistance
(
lowerIdx
,
upperIdx
))
{
break
;
}
transformedProgram
->
addInstruction
(
provider
->
createInstruction
(
"Swap"
,
{
upperIdx
,
upperIdx
-
1
}));
upperIdx
--
;
if
(
!
exceedMaxDistance
(
lowerIdx
,
upperIdx
))
{
break
;
}
}
// Run new gate
const
bool
bitCompare
=
inst
->
bits
()[
0
]
<
inst
->
bits
()[
1
];
inst
->
setBits
(
bitCompare
?
std
::
vector
<
size_t
>
{
lowerIdx
,
upperIdx
}
:
std
::
vector
<
size_t
>
{
upperIdx
,
lowerIdx
});
transformedProgram
->
addInstruction
(
inst
);
// Insert swaps
for
(
size_t
i
=
lowerIdx
;
i
>
origLowerIdx
;
--
i
)
{
transformedProgram
->
addInstruction
(
provider
->
createInstruction
(
"Swap"
,
{
i
,
i
-
1
}));
}
for
(
size_t
i
=
upperIdx
;
i
<
origUpperIdx
;
++
i
)
{
transformedProgram
->
addInstruction
(
provider
->
createInstruction
(
"Swap"
,
{
i
,
i
+
1
}));
}
}
else
{
transformedProgram
->
addInstruction
(
inst
);
}
}
// DEBUG:
// std::cout << "After transform: \n" << transformedProgram->toString() <<
// "\n";
in_program
->
clear
();
in_program
->
addInstructions
(
transformedProgram
->
getInstructions
());
return
;
}
}
// namespace quantum
}
// namespace xacc
quantum/plugins/optimizers/lnn_transform/NearestNeighborTransform.hpp
0 → 100644
View file @
809790d9
#pragma once
#include "xacc.hpp"
#include "IRTransformation.hpp"
namespace
xacc
{
namespace
quantum
{
class
NearestNeighborTransform
:
public
IRTransformation
{
public:
NearestNeighborTransform
()
{}
void
apply
(
std
::
shared_ptr
<
CompositeInstruction
>
in_program
,
const
std
::
shared_ptr
<
Accelerator
>
in_accelerator
,
const
HeterogeneousMap
&
in_options
=
{})
override
;
const
IRTransformationType
type
()
const
override
{
return
IRTransformationType
::
Placement
;
}
const
std
::
string
name
()
const
override
{
return
"nnizer"
;
}
const
std
::
string
description
()
const
override
{
return
""
;
}
};
}
// namespace quantum
}
// namespace xacc
\ No newline at end of file
quantum/plugins/optimizers/lnn_transform/tests/CMakeLists.txt
0 → 100644
View file @
809790d9
add_xacc_test
(
NearestNeighborTransform
)
target_link_libraries
(
NearestNeighborTransformTester xacc-quantum-gate xacc-circuit-optimizers
)
\ No newline at end of file
quantum/plugins/optimizers/lnn_transform/tests/NearestNeighborTransformTester.cpp
0 → 100644
View file @
809790d9
#include <memory>
#include <gtest/gtest.h>
#include "xacc.hpp"
#include "xacc_service.hpp"
namespace
{
int
countSwap
(
const
std
::
shared_ptr
<
xacc
::
CompositeInstruction
>
in_program
)
{
int
result
=
0
;
for
(
int
i
=
0
;
i
<
in_program
->
nInstructions
();
++
i
)
{
auto
inst
=
in_program
->
getInstruction
(
i
);
if
(
inst
->
name
()
==
"Swap"
)
{
result
++
;
}
}
return
result
;
}
}
// namespace
TEST
(
NearestNeighborTransformTester
,
checkSimple
)
{
auto
c
=
xacc
::
getService
<
xacc
::
Compiler
>
(
"xasm"
);
auto
f
=
c
->
compile
(
R"(__qpu__ void test1(qbit q) {
X(q[0]);
CNOT(q[1], q[3]);
H(q[7]);
CNOT(q[6], q[7]);
CNOT(q[7], q[3]);
X(q[6]);
Swap(q[4], q[9]);
S(q[5]);
})"
)
->
getComposites
()[
0
];
auto
provider
=
xacc
::
getIRProvider
(
"quantum"
);
auto
ir
=
provider
->
createIR
();
ir
->
addComposite
(
f
);
auto
opt
=
xacc
::
getService
<
xacc
::
IRTransformation
>
(
"nnizer"
);
const
auto
nInstBefore
=
f
->
nInstructions
();
const
auto
nbSwapGateBefore
=
countSwap
(
f
);
// No option: default max distance = 1
opt
->
apply
(
f
,
nullptr
);
std
::
cout
<<
"After LNN transform:
\n
"
<<
f
->
toString
()
<<
"
\n
"
;
const
auto
nbSwapGateAfter
=
countSwap
(
f
);
const
auto
nInstAfter
=
f
->
nInstructions
();
const
auto
newSwapGateCount
=
nbSwapGateAfter
-
nbSwapGateBefore
;
EXPECT_EQ
(
nInstAfter
,
nInstBefore
+
newSwapGateCount
);
// Check that no 2-qubit gates have distance > 1
for
(
int
i
=
0
;
i
<
f
->
nInstructions
();
++
i
)
{
auto
inst
=
f
->
getInstruction
(
i
);
if
(
inst
->
bits
().
size
()
==
2
)
{
const
int
distance
=
inst
->
bits
()[
0
]
-
inst
->
bits
()[
1
];
EXPECT_EQ
(
std
::
abs
(
distance
),
1
);
}
}
}
TEST
(
NearestNeighborTransformTester
,
checkDistanceConfig
)
{
auto
c
=
xacc
::
getService
<
xacc
::
Compiler
>
(
"xasm"
);
auto
f
=
c
->
compile
(
R"(__qpu__ void test2(qbit q) {
X(q[0]);
CNOT(q[1], q[9]);
H(q[7]);
CNOT(q[3], q[1]);
})"
)
->
getComposites
()[
0
];
auto
provider
=
xacc
::
getIRProvider
(
"quantum"
);
auto
ir
=
provider
->
createIR
();
ir
->
addComposite
(
f
);
auto
opt
=
xacc
::
getService
<
xacc
::
IRTransformation
>
(
"nnizer"
);
const
auto
nInstBefore
=
f
->
nInstructions
();
const
auto
nbSwapGateBefore
=
countSwap
(
f
);
// max distance = 2
opt
->
apply
(
f
,
nullptr
,
{
std
::
make_pair
(
"max-distance"
,
2
)});
std
::
cout
<<
"After LNN transform:
\n
"
<<
f
->
toString
()
<<
"
\n
"
;
const
auto
nbSwapGateAfter
=
countSwap
(
f
);
const
auto
nInstAfter
=
f
->
nInstructions
();
const
auto
newSwapGateCount
=
nbSwapGateAfter
-
nbSwapGateBefore
;
EXPECT_EQ
(
nInstAfter
,
nInstBefore
+
newSwapGateCount
);
auto
lastInst
=
f
->
getInstruction
(
nInstAfter
-
1
);
// The last instruction is CNOT(q[3], q[1])
// (distance = 2, within the limit, hence no conversion)
EXPECT_STREQ
(
lastInst
->
name
().
c_str
(),
"CNOT"
);
EXPECT_EQ
(
lastInst
->
bits
()[
0
],
3
);
EXPECT_EQ
(
lastInst
->
bits
()[
1
],
1
);
}
int
main
(
int
argc
,
char
**
argv
)
{
xacc
::
Initialize
();
::
testing
::
InitGoogleTest
(
&
argc
,
argv
);
auto
ret
=
RUN_ALL_TESTS
();
xacc
::
Finalize
();
return
ret
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment