Commit 4fab9039 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

Fix bug in finding position in comp vector, add a few more tests


Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent 3c6df472
......@@ -32,11 +32,6 @@ std::vector<std::string> _generate_gray_code(int num_bits) {
}
}
// for (auto r : result) {
// std::cout << r << " ";
// }
// std::cout << "\n";
auto int_to_str = [&](int n) -> std::string {
const int size = sizeof(n) * 8;
std::string res;
......@@ -57,8 +52,8 @@ std::vector<std::string> _generate_gray_code(int num_bits) {
std::vector<std::string> ret;
for (auto r : result) {
// std::cout << int_to_str(r) << "\n";
ret.push_back(int_to_str(r));
// std::cout << "HI: " << ret.back() << "\n";
}
return ret;
......@@ -125,12 +120,19 @@ void _apply_mcu_graycode(std::shared_ptr<CompositeInstruction> circuit,
comp.push_back(i != j);
}
// std::cout << pattern << " " << last_pattern << " [";
// for (auto c : comp) std::cout << std::boolalpha << c << " ";
// std::cout << "], ";
int pos = -1;
auto true_itr = std::find(comp.begin(), comp.end(), true);
if (true_itr != comp.end()) {
pos = comp[std::distance(comp.begin(), true_itr)];
for (int i = 0; i < comp.size(); i++) {
if (comp[i]) {
pos = i;
break;
}
}
// std::cout << pos << "\n";
if (pos != -1) {
if (pos != lm_pos) {
circuit->addInstruction(provider->createInstruction(
......@@ -180,6 +182,12 @@ std::shared_ptr<CompositeInstruction> __gray_code_mcu_gen(
auto __lam = inst->isParameterized() ? inst->getParameter(0).as<double>()
: constants::pi;
lam = __lam * (1 / (std::pow(2, n_c - 1)));
} else if (name == "Rx" || name == "X") {
auto __theta = inst->isParameterized() ? inst->getParameter(0).as<double>()
: constants::pi;
theta = __theta * (1 / (std::pow(2, n_c - 1)));
phi = -constants::pi / 2.;
lam = constants::pi / 2.;
}
_apply_mcu_graycode(circuit, theta, phi, lam, ctrl_qubits, target_qubit);
......@@ -292,7 +300,7 @@ bool ControlledU::expand(const xacc::HeterogeneousMap &runtimeOptions) {
auto should_run_gray_mcu_synth = [ctrlU, &ctrlIdxs]() {
if (ctrlU->nInstructions() == 1) {
std::vector<std::string> allowed{"Z"};
std::vector<std::string> allowed{"X", "Rx", "Z", "Rz"};
auto inst = ctrlU->getInstruction(0);
if (xacc::container::contains(allowed, inst->name()) &&
ctrlIdxs.size() > 2) {
......@@ -323,9 +331,13 @@ bool ControlledU::expand(const xacc::HeterogeneousMap &runtimeOptions) {
}
}
for (auto iter = zero_rotation_idxs.rbegin();
iter != zero_rotation_idxs.rend(); ++iter) {
ctrlU->removeInstruction(*iter);
for (int instId = 0; instId < ctrlU->nInstructions(); ++instId) {
// Only add instructions that are not NOOPs
if (std::find(zero_rotation_idxs.begin(), zero_rotation_idxs.end(),
instId) == zero_rotation_idxs.end()) {
auto inst = ctrlU->getInstruction(instId)->clone();
addInstruction(inst);
}
}
} else {
......@@ -334,12 +346,12 @@ bool ControlledU::expand(const xacc::HeterogeneousMap &runtimeOptions) {
for (const auto &ctrlIdx : ctrlIdxs) {
ctrlU = applyControl(ctrlU, ctrlIdx);
}
}
for (int instId = 0; instId < ctrlU->nInstructions(); ++instId) {
auto inst = ctrlU->getInstruction(instId)->clone();
addInstruction(inst);
}
}
return true;
}
......
......@@ -8,73 +8,74 @@
using namespace xacc;
using namespace xacc::quantum;
TEST(ControlledGateTester, checkSimple)
{
TEST(ControlledGateTester, checkSimple) {
auto gateRegistry = xacc::getService<xacc::IRProvider>("quantum");
auto t = std::make_shared<T>(0);
auto rz = std::make_shared<Rz>(0, 3.1415);
auto u1 = std::make_shared<U1>(0, 3.1415);
auto x = std::make_shared<X>(0);
const std::vector<size_t> expectedBits { 1, 0};
const std::vector<size_t> expectedBits{1, 0};
{
std::shared_ptr<xacc::CompositeInstruction> comp = gateRegistry->createComposite("__COMPOSITE__X");
std::shared_ptr<xacc::CompositeInstruction> comp =
gateRegistry->createComposite("__COMPOSITE__X");
comp->addInstruction(x->clone());
auto ctrlKernel = std::dynamic_pointer_cast<CompositeInstruction>(xacc::getService<Instruction>("C-U"));
ctrlKernel->expand({
std::make_pair("U", comp),
std::make_pair("control-idx", 1)
});
auto ctrlKernel = std::dynamic_pointer_cast<CompositeInstruction>(
xacc::getService<Instruction>("C-U"));
ctrlKernel->expand(
{std::make_pair("U", comp), std::make_pair("control-idx", 1)});
EXPECT_EQ(ctrlKernel->nInstructions(), 1);
EXPECT_EQ(ctrlKernel->getInstruction(0)->name(), "CNOT");
EXPECT_EQ(ctrlKernel->getInstruction(0)->name(), "CNOT");
EXPECT_EQ(ctrlKernel->getInstruction(0)->bits(), expectedBits);
}
{
std::shared_ptr<xacc::CompositeInstruction> comp = gateRegistry->createComposite("__COMPOSITE__T");
std::shared_ptr<xacc::CompositeInstruction> comp =
gateRegistry->createComposite("__COMPOSITE__T");
comp->addInstruction(t->clone());
auto ctrlKernel = std::dynamic_pointer_cast<CompositeInstruction>(xacc::getService<Instruction>("C-U"));
ctrlKernel->expand({
std::make_pair("U", comp),
std::make_pair("control-idx", 1)
});
auto ctrlKernel = std::dynamic_pointer_cast<CompositeInstruction>(
xacc::getService<Instruction>("C-U"));
ctrlKernel->expand(
{std::make_pair("U", comp), std::make_pair("control-idx", 1)});
// T -> CPhase(pi/4)
EXPECT_EQ(ctrlKernel->nInstructions(), 1);
EXPECT_EQ(ctrlKernel->getInstruction(0)->name(), "CPhase");
EXPECT_NEAR(ctrlKernel->getInstruction(0)->getParameter(0).as<double>(), M_PI_4, 1e-4);
EXPECT_NEAR(ctrlKernel->getInstruction(0)->getParameter(0).as<double>(),
M_PI_4, 1e-4);
EXPECT_EQ(ctrlKernel->getInstruction(0)->bits(), expectedBits);
}
{
std::shared_ptr<xacc::CompositeInstruction> comp = gateRegistry->createComposite("__COMPOSITE__Rz");
std::shared_ptr<xacc::CompositeInstruction> comp =
gateRegistry->createComposite("__COMPOSITE__Rz");
comp->addInstruction(rz->clone());
auto ctrlKernel = std::dynamic_pointer_cast<CompositeInstruction>(xacc::getService<Instruction>("C-U"));
ctrlKernel->expand({
std::make_pair("U", comp),
std::make_pair("control-idx", 1)
});
auto ctrlKernel = std::dynamic_pointer_cast<CompositeInstruction>(
xacc::getService<Instruction>("C-U"));
ctrlKernel->expand(
{std::make_pair("U", comp), std::make_pair("control-idx", 1)});
// Rz -> CRz
EXPECT_EQ(ctrlKernel->nInstructions(), 1);
EXPECT_EQ(ctrlKernel->getInstruction(0)->name(), "CRZ");
EXPECT_EQ(ctrlKernel->getInstruction(0)->getParameter(0), rz->getParameter(0));
EXPECT_EQ(ctrlKernel->getInstruction(0)->getParameter(0),
rz->getParameter(0));
EXPECT_EQ(ctrlKernel->getInstruction(0)->bits(), expectedBits);
}
{
std::shared_ptr<xacc::CompositeInstruction> comp = gateRegistry->createComposite("__COMPOSITE__U1");
std::shared_ptr<xacc::CompositeInstruction> comp =
gateRegistry->createComposite("__COMPOSITE__U1");
comp->addInstruction(u1->clone());
auto ctrlKernel = std::dynamic_pointer_cast<CompositeInstruction>(xacc::getService<Instruction>("C-U"));
ctrlKernel->expand({
std::make_pair("U", comp),
std::make_pair("control-idx", 1)
});
auto ctrlKernel = std::dynamic_pointer_cast<CompositeInstruction>(
xacc::getService<Instruction>("C-U"));
ctrlKernel->expand(
{std::make_pair("U", comp), std::make_pair("control-idx", 1)});
// U1 -> CPhase (cU1)
EXPECT_EQ(ctrlKernel->nInstructions(), 1);
EXPECT_EQ(ctrlKernel->getInstruction(0)->name(), "CPhase");
EXPECT_EQ(ctrlKernel->getInstruction(0)->getParameter(0), u1->getParameter(0));
EXPECT_EQ(ctrlKernel->getInstruction(0)->getParameter(0),
u1->getParameter(0));
EXPECT_EQ(ctrlKernel->getInstruction(0)->bits(), expectedBits);
}
}
TEST(ControlledGateTester, checkMultipleControl)
{
TEST(ControlledGateTester, checkMultipleControl) {
auto gateRegistry = xacc::getService<xacc::IRProvider>("quantum");
auto x = std::make_shared<X>(0);
std::shared_ptr<xacc::CompositeInstruction> comp =
......@@ -87,29 +88,27 @@ TEST(ControlledGateTester, checkMultipleControl)
std::cout << "HOWDY: \n" << ccx->toString() << "\n";
// Test truth table
auto acc = xacc::getAccelerator("qpp", { std::make_pair("shots", 8192)});
auto xGate0 = gateRegistry->createInstruction("X", { 0 });
auto xGate1 = gateRegistry->createInstruction("X", { 1 });
auto xGate2 = gateRegistry->createInstruction("X", { 2 });
auto measureGate0 = gateRegistry->createInstruction("Measure", { 0 });
auto measureGate1 = gateRegistry->createInstruction("Measure", { 1 });
auto measureGate2 = gateRegistry->createInstruction("Measure", { 2 });
auto acc = xacc::getAccelerator("qpp", {std::make_pair("shots", 8192)});
auto xGate0 = gateRegistry->createInstruction("X", {0});
auto xGate1 = gateRegistry->createInstruction("X", {1});
auto xGate2 = gateRegistry->createInstruction("X", {2});
auto measureGate0 = gateRegistry->createInstruction("Measure", {0});
auto measureGate1 = gateRegistry->createInstruction("Measure", {1});
auto measureGate2 = gateRegistry->createInstruction("Measure", {2});
const auto runTestCase = [&](bool in_bit0, bool in_bit1, bool in_bit2) {
static int counter = 0;
auto composite = gateRegistry->createComposite("__TEMP_COMPOSITE__" + std::to_string(counter));
auto composite = gateRegistry->createComposite("__TEMP_COMPOSITE__" +
std::to_string(counter));
counter++;
// State prep:
if (in_bit0)
{
if (in_bit0) {
composite->addInstruction(xGate0);
}
if (in_bit1)
{
if (in_bit1) {
composite->addInstruction(xGate1);
}
if (in_bit2)
{
if (in_bit2) {
composite->addInstruction(xGate2);
}
......@@ -121,7 +120,7 @@ TEST(ControlledGateTester, checkMultipleControl)
// Add ccx
composite->addInstructions(ccx->getInstructions());
// Mesurement:
composite->addInstructions({ measureGate0, measureGate1, measureGate2 });
composite->addInstructions({measureGate0, measureGate1, measureGate2});
auto buffer = xacc::qalloc(3);
acc->execute(buffer, composite);
......@@ -131,30 +130,27 @@ TEST(ControlledGateTester, checkMultipleControl)
const auto expectedBitString = [&inputBitString]() -> std::string {
// If both control bits are 1's
// q0q1q2
if (inputBitString == "011")
{
if (inputBitString == "011") {
return "111";
}
if (inputBitString == "111")
{
if (inputBitString == "111") {
return "011";
}
// Otherwise, no changes
return inputBitString;
}();
// Check bit string
EXPECT_NEAR(buffer->computeMeasurementProbability(expectedBitString), 1.0, 0.1);
EXPECT_NEAR(buffer->computeMeasurementProbability(expectedBitString), 1.0,
0.1);
};
// 3 bits: run all test cases (8)
for (int i = 0; i < (1 << 3); ++i)
{
for (int i = 0; i < (1 << 3); ++i) {
runTestCase(i & 0x001, i & 0x002, i & 0x004);
}
}
TEST(ControlledGateTester, checkMultipleControlQregs)
{
TEST(ControlledGateTester, checkMultipleControlQregs) {
// Reference circuit (index-based)
const std::string ref_circuit_str = []() {
auto gateRegistry = xacc::getService<xacc::IRProvider>("quantum");
......@@ -200,8 +196,7 @@ TEST(ControlledGateTester, checkMultipleControlQregs)
EXPECT_EQ(ref_circuit_str, new_circ_str);
}
TEST(ControlledGateTester, checkControlSwap)
{
TEST(ControlledGateTester, checkControlSwap) {
auto gateRegistry = xacc::getService<xacc::IRProvider>("quantum");
auto swap = std::make_shared<Swap>(0, 1);
std::shared_ptr<xacc::CompositeInstruction> comp =
......@@ -215,29 +210,27 @@ TEST(ControlledGateTester, checkControlSwap)
// 2 CNOT + CCNOT (15 gates)
EXPECT_EQ(cswap->nInstructions(), 15 + 2);
// Test truth table
auto acc = xacc::getAccelerator("qpp", { std::make_pair("shots", 1024)});
auto xGate0 = gateRegistry->createInstruction("X", { 0 });
auto xGate1 = gateRegistry->createInstruction("X", { 1 });
auto xGate2 = gateRegistry->createInstruction("X", { 2 });
auto measureGate0 = gateRegistry->createInstruction("Measure", { 0 });
auto measureGate1 = gateRegistry->createInstruction("Measure", { 1 });
auto measureGate2 = gateRegistry->createInstruction("Measure", { 2 });
auto acc = xacc::getAccelerator("qpp", {std::make_pair("shots", 1024)});
auto xGate0 = gateRegistry->createInstruction("X", {0});
auto xGate1 = gateRegistry->createInstruction("X", {1});
auto xGate2 = gateRegistry->createInstruction("X", {2});
auto measureGate0 = gateRegistry->createInstruction("Measure", {0});
auto measureGate1 = gateRegistry->createInstruction("Measure", {1});
auto measureGate2 = gateRegistry->createInstruction("Measure", {2});
const auto runTestCase = [&](bool in_bit0, bool in_bit1, bool in_bit2) {
static int counter = 0;
auto composite = gateRegistry->createComposite("__TEMP_COMPOSITE__" + std::to_string(counter));
auto composite = gateRegistry->createComposite("__TEMP_COMPOSITE__" +
std::to_string(counter));
counter++;
// State prep:
if (in_bit0)
{
if (in_bit0) {
composite->addInstruction(xGate0);
}
if (in_bit1)
{
if (in_bit1) {
composite->addInstruction(xGate1);
}
if (in_bit2)
{
if (in_bit2) {
composite->addInstruction(xGate2);
}
......@@ -249,7 +242,7 @@ TEST(ControlledGateTester, checkControlSwap)
// Add cswap
composite->addInstructions(cswap->getInstructions());
// Mesurement:
composite->addInstructions({ measureGate0, measureGate1, measureGate2 });
composite->addInstructions({measureGate0, measureGate1, measureGate2});
auto buffer = xacc::qalloc(3);
acc->execute(buffer, composite);
......@@ -259,30 +252,29 @@ TEST(ControlledGateTester, checkControlSwap)
const auto expectedBitString = [&inputBitString]() -> std::string {
// If q2 is 1 and q0 and q1 are different ==> swap
// q0q1q2
if (inputBitString == "011")
{
if (inputBitString == "011") {
return "101";
}
if (inputBitString == "101")
{
if (inputBitString == "101") {
return "011";
}
// Otherwise, no changes
return inputBitString;
}();
// Check bit string
EXPECT_NEAR(buffer->computeMeasurementProbability(expectedBitString), 1.0, 0.1);
EXPECT_NEAR(buffer->computeMeasurementProbability(expectedBitString), 1.0,
0.1);
};
// 3 bits: run all test cases (8)
for (int i = 0; i < (1 << 3); ++i)
{
for (int i = 0; i < (1 << 3); ++i) {
runTestCase(i & 0x001, i & 0x002, i & 0x004);
}
}
TEST(ControlledGateTester, checkEltonBug) {
auto gateRegistry = xacc::getService<xacc::IRProvider>("quantum");
{
auto z = std::make_shared<Z>(4);
z->setBufferNames(std::vector<std::string>{"q"});
......@@ -291,31 +283,74 @@ TEST(ControlledGateTester, checkEltonBug) {
comp->addInstruction(z);
auto multi_ctrl_z = std::dynamic_pointer_cast<CompositeInstruction>(
xacc::getService<Instruction>("C-U"));
const std::vector<int> ctrl_idxs{0,1,2,3};
const std::vector<int> ctrl_idxs{0, 1, 2, 3};
multi_ctrl_z->expand({{"U", comp}, {"control-idx", ctrl_idxs}});
std::cout << "HOWDY: \n" << multi_ctrl_z->toString() << "\n";
// std::cout << "HOWDY: \n" << multi_ctrl_z->toString() << "\n";
std::cout << multi_ctrl_z->nInstructions() << "\n";
// Eigen::MatrixXcd expected = Eigen::MatrixXcd::Identity(32,32);
// expected(31,31) = -1;
// std::cout << expected << "\n";
xacc::quantum::CountGatesOfTypeVisitor<CNOT> vis(multi_ctrl_z);
xacc::quantum::CountGatesOfTypeVisitor<U> visu(multi_ctrl_z);
// QiskitImpl Reports: OrderedDict([('cx', 44), ('p', 30), ('u', 30)])
// all ours are U+CX, and we remove U(0,0,0).
// There are 8 U(0,0,0). So should have 44 CX, 60-8=52 Us
EXPECT_EQ(vis.countGates(), 44);
EXPECT_EQ(visu.countGates(), 52);
}
{
auto z = std::make_shared<Z>(6);
z->setBufferNames(std::vector<std::string>{"q"});
std::shared_ptr<xacc::CompositeInstruction> comp =
gateRegistry->createComposite("__COMPOSITE__Z");
comp->addInstruction(z);
auto multi_ctrl_z = std::dynamic_pointer_cast<CompositeInstruction>(
xacc::getService<Instruction>("C-U"));
const std::vector<int> ctrl_idxs{0, 1, 2, 3, 4, 5};
multi_ctrl_z->expand({{"U", comp}, {"control-idx", ctrl_idxs}});
// std::cout << "HOWDY: \n" << multi_ctrl_z->toString() << "\n";
std::cout << multi_ctrl_z->nInstructions() << "\n";
xacc::quantum::CountGatesOfTypeVisitor<CNOT> vis(multi_ctrl_z);
xacc::quantum::CountGatesOfTypeVisitor<U> visu(multi_ctrl_z);
// std::cout << vis.countGates() << "\n";
// OrderedDict([('cx', 188), ('p', 126), ('u', 126)])
// all ours are U+CX, and we remove U(0,0,0).
// There are 32 U(0,0,0). So should have ?? CX, 252-32=220 Us
EXPECT_EQ(vis.countGates(), 188);
EXPECT_EQ(visu.countGates(), 220);
}
{
auto x = std::make_shared<X>(6);
x->setBufferNames(std::vector<std::string>{"q"});
std::shared_ptr<xacc::CompositeInstruction> comp =
gateRegistry->createComposite("__COMPOSITE__X");
comp->addInstruction(x);
auto multi_ctrl_z = std::dynamic_pointer_cast<CompositeInstruction>(
xacc::getService<Instruction>("C-U"));
const std::vector<int> ctrl_idxs{0, 1, 2, 3, 4, 5};
multi_ctrl_z->expand({{"U", comp}, {"control-idx", ctrl_idxs}});
// std::cout << "HOWDY: \n" << multi_ctrl_z->toString() << "\n";
std::cout << multi_ctrl_z->nInstructions() << "\n";
xacc::quantum::CountGatesOfTypeVisitor<CNOT> vis(multi_ctrl_z);
xacc::quantum::CountGatesOfTypeVisitor<U> visu(multi_ctrl_z);
// std::cout << vis.countGates() << "\n";
// OrderedDict([('cx', 188), ('p', 126), ('u', 126)])
// all ours are U+CX, and we remove U(0,0,0).
// There are 32 U(0,0,0). So should have ?? CX, 252-63=220 Us
EXPECT_EQ(vis.countGates(), 188);
EXPECT_EQ(visu.countGates(), 189);
}
}
int main(int argc, char **argv)
{
int main(int argc, char **argv) {
xacc::Initialize(argc, argv);
::testing::InitGoogleTest(&argc, argv);
auto ret = RUN_ALL_TESTS();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment