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
d9e8194d
Commit
d9e8194d
authored
Jul 15, 2020
by
Nguyen, Thien Minh
Browse files
Initial set-up for some additional circuit optimization routines
Signed-off-by:
Thien Nguyen
<
nguyentm@ornl.gov
>
parent
1d385171
Changes
6
Hide whitespace changes
Inline
Side-by-side
quantum/plugins/optimizers/CMakeLists.txt
View file @
d9e8194d
...
...
@@ -13,7 +13,7 @@
set
(
LIBRARY_NAME xacc-circuit-optimizers
)
file
(
GLOB_RECURSE HEADERS *.hpp
)
file
(
GLOB SRC simple/*.cpp OptimizersActivator.cpp pulse/*.cpp
)
file
(
GLOB SRC simple/*.cpp OptimizersActivator.cpp pulse/*.cpp
gate_merge/*.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
${
CMAKE_SOURCE_DIR
}
/tpls/eigen
${
CMAKE_SOURCE_DIR
}
/tpls/exprtk
)
target_include_directories
(
${
LIBRARY_NAME
}
PUBLIC simple pulse
gate_merge
${
CMAKE_SOURCE_DIR
}
/tpls/eigen
${
CMAKE_SOURCE_DIR
}
/tpls/exprtk
)
target_link_libraries
(
${
LIBRARY_NAME
}
xacc xacc-quantum-gate
)
if
(
APPLE
)
...
...
@@ -56,5 +56,6 @@ install(TARGETS ${LIBRARY_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/plugins)
if
(
XACC_BUILD_TESTS
)
add_subdirectory
(
simple/tests
)
add_subdirectory
(
pulse/tests
)
add_subdirectory
(
gate_merge/tests
)
endif
()
quantum/plugins/optimizers/OptimizersActivator.cpp
View file @
d9e8194d
...
...
@@ -12,12 +12,12 @@
*******************************************************************************/
#include "CircuitOptimizer.hpp"
#include "default_placement.hpp"
#include "GateMergeOptimizer.hpp"
#include "PulseTransform.hpp"
#include "GateFusion.hpp"
#include "cppmicroservices/BundleActivator.h"
#include "cppmicroservices/BundleContext.h"
#include "cppmicroservices/ServiceProperties.h"
#include <memory>
#include <set>
...
...
@@ -45,6 +45,8 @@ public:
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
>
());
}
/**
...
...
quantum/plugins/optimizers/gate_merge/GateMergeOptimizer.cpp
0 → 100644
View file @
d9e8194d
#include "GateMergeOptimizer.hpp"
#include <cassert>
namespace
xacc
{
namespace
quantum
{
void
MergeSingleQubitGatesOptimizer
::
apply
(
std
::
shared_ptr
<
CompositeInstruction
>
program
,
const
std
::
shared_ptr
<
Accelerator
>
accelerator
,
const
HeterogeneousMap
&
options
)
{
std
::
set
<
size_t
>
processInstIdx
;
for
(
size_t
instIdx
=
0
;
instIdx
<
program
->
nInstructions
();
++
instIdx
)
{
const
auto
sequence
=
findSingleQubitGateSequence
(
program
,
instIdx
,
2
,
processInstIdx
);
if
(
!
sequence
.
empty
())
{
for
(
const
auto
&
instIdx
:
sequence
)
{
assert
(
!
xacc
::
container
::
contains
(
processInstIdx
,
instIdx
));
processInstIdx
.
emplace
(
instIdx
);
}
// std::cout << "Found sequence:\n";
// for (const auto& idx : sequence)
// {
// std::cout << program->getInstruction(idx)->toString() << "\n";
// }
}
}
}
std
::
vector
<
size_t
>
MergeSingleQubitGatesOptimizer
::
findSingleQubitGateSequence
(
const
std
::
shared_ptr
<
CompositeInstruction
>
in_program
,
size_t
in_startIdx
,
size_t
in_lengthLimit
,
const
std
::
set
<
size_t
>&
in_processedInstIdx
)
const
{
const
auto
nbInstructions
=
in_program
->
nInstructions
();
std
::
unordered_map
<
size_t
,
std
::
vector
<
size_t
>>
qubitToSequence
;
for
(
size_t
instIdx
=
in_startIdx
;
instIdx
<
nbInstructions
;
++
instIdx
)
{
auto
instPtr
=
in_program
->
getInstruction
(
instIdx
);
if
(
instPtr
->
bits
().
size
()
>
1
)
{
// Two-qubit gate: clear the sequence of all qubit operands.
// Returns if any sequence meets the length.
auto
&
seq1
=
qubitToSequence
[
instPtr
->
bits
()[
0
]];
auto
&
seq2
=
qubitToSequence
[
instPtr
->
bits
()[
1
]];
// Returns if a sequence has been accumulated.
if
(
seq1
.
size
()
>=
in_lengthLimit
||
seq2
.
size
()
>=
in_lengthLimit
)
{
if
(
seq1
.
size
()
>=
in_lengthLimit
&&
seq2
.
size
()
>=
in_lengthLimit
)
{
assert
(
seq1
[
0
]
!=
seq2
[
0
]);
return
(
seq1
[
0
]
<
seq2
[
0
])
?
seq1
:
seq2
;
}
return
(
seq1
.
size
()
>=
in_lengthLimit
)
?
seq1
:
seq2
;
}
seq1
.
clear
();
seq2
.
clear
();
}
else
{
if
(
instPtr
->
name
()
==
"Measure"
)
{
if
(
qubitToSequence
[
instPtr
->
bits
()[
0
]].
size
()
>=
in_lengthLimit
)
{
return
qubitToSequence
[
instPtr
->
bits
()[
0
]];
}
qubitToSequence
[
instPtr
->
bits
()[
0
]].
clear
();
}
else
{
// If this single-qubit gate has not been covered before.
if
(
!
xacc
::
container
::
contains
(
in_processedInstIdx
,
instIdx
))
{
// Single-qubit gate: accumulate the sequence.
auto
&
currentSeq
=
qubitToSequence
[
instPtr
->
bits
()[
0
]];
currentSeq
.
emplace_back
(
instIdx
);
}
}
}
}
// Handle multiple un-terminated long sequence.
size_t
minInstIdx
=
in_program
->
nInstructions
();
for
(
const
auto
&
[
qIdx
,
seq
]
:
qubitToSequence
)
{
if
(
seq
.
size
()
>=
in_lengthLimit
)
{
minInstIdx
=
(
seq
[
0
]
<
minInstIdx
)
?
seq
[
0
]
:
minInstIdx
;
}
}
for
(
const
auto
&
[
qIdx
,
seq
]
:
qubitToSequence
)
{
if
(
seq
.
size
()
>=
in_lengthLimit
&&
seq
[
0
]
==
minInstIdx
)
{
return
seq
;
}
}
return
{};
}
}
}
\ No newline at end of file
quantum/plugins/optimizers/gate_merge/GateMergeOptimizer.hpp
0 → 100644
View file @
d9e8194d
#pragma once
#include "IRTransformation.hpp"
namespace
xacc
{
namespace
quantum
{
// Merge contiguous sequence of gates (1- or 2-qubit)
// into a more efficient gate sequence.
class
MergeSingleQubitGatesOptimizer
:
public
IRTransformation
{
public:
virtual
void
apply
(
std
::
shared_ptr
<
CompositeInstruction
>
program
,
const
std
::
shared_ptr
<
Accelerator
>
accelerator
,
const
HeterogeneousMap
&
options
=
{})
override
;
virtual
const
IRTransformationType
type
()
const
override
{
return
IRTransformationType
::
Optimization
;
}
const
std
::
string
name
()
const
override
{
return
"single-qubit-gate-merging"
;
}
const
std
::
string
description
()
const
override
{
return
""
;
}
private:
std
::
vector
<
size_t
>
findSingleQubitGateSequence
(
const
std
::
shared_ptr
<
CompositeInstruction
>
in_program
,
size_t
in_startIdx
,
size_t
in_lengthLimit
,
const
std
::
set
<
size_t
>&
in_processedInstIdx
)
const
;
};
// Try to merge a block containing single and two-qubit gates
// and decompose it into a more optimized representation only if *possible*.
// e.g. only if the original block has more gates than its re-synthesized version.
// We could also define a custom target for re-write
// such as reducing the number of two-qubit gates in the block
// rather than the overall gate count.
class
MergeTwoQubitBlockOptimizer
:
public
IRTransformation
{
public:
virtual
void
apply
(
std
::
shared_ptr
<
CompositeInstruction
>
program
,
const
std
::
shared_ptr
<
Accelerator
>
accelerator
,
const
HeterogeneousMap
&
options
=
{})
override
{
/* TODO */
};
virtual
const
IRTransformationType
type
()
const
override
{
return
IRTransformationType
::
Optimization
;
}
const
std
::
string
name
()
const
override
{
return
"two-qubit-block-merging"
;
}
const
std
::
string
description
()
const
override
{
return
""
;
}
};
}
}
\ No newline at end of file
quantum/plugins/optimizers/gate_merge/tests/CMakeLists.txt
0 → 100644
View file @
d9e8194d
add_xacc_test
(
GateMerging
)
target_link_libraries
(
GateMergingTester xacc-quantum-gate
)
\ No newline at end of file
quantum/plugins/optimizers/gate_merge/tests/GateMergingTester.cpp
0 → 100644
View file @
d9e8194d
#include <gtest/gtest.h>
#include "xacc.hpp"
#include "xacc_service.hpp"
#include "IRTransformation.hpp"
TEST
(
GateMergingTester
,
checkSingleQubitSimple
)
{
auto
c
=
xacc
::
getService
<
xacc
::
Compiler
>
(
"xasm"
);
auto
f
=
c
->
compile
(
R"(__qpu__ void test1(qbit q) {
Z(q[0]);
H(q[0]);
X(q[0]);
H(q[0]);
})"
)
->
getComposites
()[
0
];
auto
opt
=
xacc
::
getService
<
xacc
::
IRTransformation
>
(
"single-qubit-gate-merging"
);
opt
->
apply
(
f
,
nullptr
);
}
TEST
(
GateMergingTester
,
checkSingleQubitStopAtTwoQubitGate
)
{
auto
c
=
xacc
::
getService
<
xacc
::
Compiler
>
(
"xasm"
);
auto
f
=
c
->
compile
(
R"(__qpu__ void test2(qbit q) {
H(q[0]);
X(q[0]);
H(q[0]);
CNOT(q[0], q[1]);
H(q[0]);
})"
)
->
getComposites
()[
0
];
auto
opt
=
xacc
::
getService
<
xacc
::
IRTransformation
>
(
"single-qubit-gate-merging"
);
opt
->
apply
(
f
,
nullptr
);
}
int
main
(
int
argc
,
char
**
argv
)
{
xacc
::
Initialize
(
argc
,
argv
);
::
testing
::
InitGoogleTest
(
&
argc
,
argv
);
auto
ret
=
RUN_ALL_TESTS
();
xacc
::
Finalize
();
return
ret
;
}
\ No newline at end of file
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