Loading runtime/qrt/impls/nisq/CMakeLists.txt +4 −0 Original line number Diff line number Diff line Loading @@ -56,3 +56,7 @@ if (QCOR_BUILD_TESTS) endif() install(TARGETS ${LIBRARY_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/plugins) if (QCOR_BUILD_TESTS) add_subdirectory(tests) endif() No newline at end of file runtime/qrt/impls/nisq/nisq_qrt.cpp +31 −40 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include "xacc_internal_compiler.hpp" #include "xacc_observable.hpp" #include "xacc_service.hpp" #include "CommonGates.hpp" using namespace cppmicroservices; using namespace xacc; Loading Loading @@ -173,12 +174,14 @@ class NISQ : public ::quantum::QuantumRuntime { double pi = xacc::constants::pi; auto gateRegistry = xacc::getIRProvider("quantum"); std::string xasm_src = ""; std::vector<xacc::InstPtr> exp_insts; auto q_name = q.name(); for (auto inst : terms) { auto spinInst = inst.second; if (spinInst.isIdentity()) { continue; } // Get the individual pauli terms auto termsMap = std::get<2>(spinInst); Loading @@ -192,7 +195,7 @@ class NISQ : public ::quantum::QuantumRuntime { int largestQbitIdx = terms[terms.size() - 1].first; std::vector<std::size_t> qidxs; std::stringstream basis_front, basis_back; std::vector<xacc::InstPtr> basis_front, basis_back; for (auto &term : terms) { auto qid = term.first; Loading @@ -201,14 +204,11 @@ class NISQ : public ::quantum::QuantumRuntime { qidxs.push_back(qid); if (pop == "X") { basis_front << "H(" << q_name << "[" << qid << "]);\n"; basis_back << "H(" << q_name << "[" << qid << "]);\n"; basis_front.emplace_back(std::make_shared<xacc::quantum::Hadamard>(qid)); basis_back.emplace_back(std::make_shared<xacc::quantum::Hadamard>(qid)); } else if (pop == "Y") { basis_front << "Rx(" << q_name << "[" << qid << "], " << 1.57079362679 << ");\n"; basis_back << "Rx(" << q_name << "[" << qid << "], " << -1.57079362679 << ");\n"; basis_front.emplace_back(std::make_shared<xacc::quantum::Rx>(qid, 1.57079362679)); basis_back.emplace_back(std::make_shared<xacc::quantum::Rx>(qid, -1.57079362679)); } } Loading @@ -223,54 +223,45 @@ class NISQ : public ::quantum::QuantumRuntime { } // std::cout << "HOWDY: \n" << cnot_pairs << "\n"; std::stringstream cnot_front, cnot_back; std::vector<xacc::InstPtr> cnot_front, cnot_back; for (int i = 0; i < qidxs.size() - 1; i++) { Eigen::VectorXi pairs = cnot_pairs.col(i); auto c = pairs(0); auto t = pairs(1); cnot_front << "CNOT(" << q_name << "[" << c << "], " << q_name << "[" << t << "]);\n"; cnot_front.emplace_back(std::make_shared<xacc::quantum::CNOT>(c, t)); } for (int i = qidxs.size() - 2; i >= 0; i--) { Eigen::VectorXi pairs = cnot_pairs.col(i); auto c = pairs(0); auto t = pairs(1); cnot_back << "CNOT(" << q_name << "[" << c << "], " << q_name << "[" << t << "]);\n"; cnot_back.emplace_back(std::make_shared<xacc::quantum::CNOT>(c, t)); } xasm_src = xasm_src + "\n" + basis_front.str() + cnot_front.str(); exp_insts.insert(exp_insts.end(), std::make_move_iterator(basis_front.begin()), std::make_move_iterator(basis_front.end())); exp_insts.insert(exp_insts.end(), std::make_move_iterator(cnot_front.begin()), std::make_move_iterator(cnot_front.end())); // FIXME, we assume real coefficients, if its zero, // check that the imag part is not zero and use it if (std::fabs(std::real(spinInst.coeff())) > 1e-12) { xasm_src = xasm_src + "Rz(" + q_name + "[" + std::to_string(qidxs[qidxs.size() - 1]) + "], " + std::to_string(std::real(spinInst.coeff()) * theta) + ");\n"; exp_insts.emplace_back(std::make_shared<xacc::quantum::Rz>( qidxs[qidxs.size() - 1], std::real(spinInst.coeff()) * theta)); } else if (std::fabs(std::imag(spinInst.coeff())) > 1e-12) { xasm_src = xasm_src + "Rz(" + q_name + "[" + std::to_string(qidxs[qidxs.size() - 1]) + "], " + std::to_string(std::imag(spinInst.coeff()) * theta) + ");\n"; } xasm_src = xasm_src + cnot_back.str() + basis_back.str(); } int name_counter = 1; std::string name = "exp_tmp"; while (xacc::hasCompiled(name)) { name += std::to_string(name_counter); } xasm_src = "__qpu__ void " + name + "(qbit " + q_name + ") {\n" + xasm_src + "}"; // std::cout << "FROMQRT: " << theta << "\n" << xasm_src << "\n"; auto xasm = xacc::getCompiler("xasm"); auto tmp = xasm->compile(xasm_src)->getComposites()[0]; for (auto inst : tmp->getInstructions()) { exp_insts.emplace_back(std::make_shared<xacc::quantum::Rz>( qidxs[qidxs.size() - 1], std::imag(spinInst.coeff()) * theta)); } exp_insts.insert(exp_insts.end(), std::make_move_iterator(cnot_back.begin()), std::make_move_iterator(cnot_back.end())); exp_insts.insert(exp_insts.end(), std::make_move_iterator(basis_back.begin()), std::make_move_iterator(basis_back.end())); } for (auto& inst : exp_insts) { inst->setBufferNames(std::vector<std::string>(inst->bits().size(), q_name)); program->addInstruction(inst); } } Loading runtime/qrt/impls/nisq/tests/CMakeLists.txt 0 → 100644 +9 −0 Original line number Diff line number Diff line link_directories(${XACC_ROOT}/lib) if (NOT XACC_ROOT STREQUAL CMAKE_INSTALL_PREFIX) add_definitions(-D__internal__qcor__compile__plugin__path="${CMAKE_INSTALL_PREFIX}/plugins") endif() add_executable(NisqQrtTester NisqQrtTester.cpp) add_test(NAME qcor_NisqQrtTester COMMAND NisqQrtTester) target_include_directories(NisqQrtTester PRIVATE ${XACC_ROOT}/include/gtest) target_link_libraries(NisqQrtTester ${XACC_TEST_LIBRARIES} qcor) No newline at end of file runtime/qrt/impls/nisq/tests/NisqQrtTester.cpp 0 → 100644 +28 −0 Original line number Diff line number Diff line #include "qcor.hpp" #include <gtest/gtest.h> #include "xacc_service.hpp" TEST(NisqQrtTester, checkExpInst) { ::quantum::initialize("qpp", "empty"); const std::string obs_str = "5.907 - 2.1433 X0X1 - 2.1433 Y0Y1 + .21829 Z0 - 6.125 Z1"; auto observable = qcor::createObservable(obs_str); auto qreg = qalloc(2); qreg.setName("q"); ::quantum::exp(qreg, 1.0, observable); std::cout << "HOWDY\n" << ::quantum::qrt_impl->get_current_program()->toString() << "\n"; // Get the XACC reference implementation auto exp = std::dynamic_pointer_cast<xacc::quantum::Circuit>( xacc::getService<xacc::Instruction>("exp_i_theta")); EXPECT_TRUE(exp->expand({{ "pauli", obs_str}})); auto evaled = exp->operator()({0.5}); std::cout << "HELLO\n" << evaled->toString() << "\n"; EXPECT_EQ(evaled->toString(), ::quantum::qrt_impl->get_current_program()->toString()); } int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); auto ret = RUN_ALL_TESTS(); return ret; } Loading
runtime/qrt/impls/nisq/CMakeLists.txt +4 −0 Original line number Diff line number Diff line Loading @@ -56,3 +56,7 @@ if (QCOR_BUILD_TESTS) endif() install(TARGETS ${LIBRARY_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/plugins) if (QCOR_BUILD_TESTS) add_subdirectory(tests) endif() No newline at end of file
runtime/qrt/impls/nisq/nisq_qrt.cpp +31 −40 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include "xacc_internal_compiler.hpp" #include "xacc_observable.hpp" #include "xacc_service.hpp" #include "CommonGates.hpp" using namespace cppmicroservices; using namespace xacc; Loading Loading @@ -173,12 +174,14 @@ class NISQ : public ::quantum::QuantumRuntime { double pi = xacc::constants::pi; auto gateRegistry = xacc::getIRProvider("quantum"); std::string xasm_src = ""; std::vector<xacc::InstPtr> exp_insts; auto q_name = q.name(); for (auto inst : terms) { auto spinInst = inst.second; if (spinInst.isIdentity()) { continue; } // Get the individual pauli terms auto termsMap = std::get<2>(spinInst); Loading @@ -192,7 +195,7 @@ class NISQ : public ::quantum::QuantumRuntime { int largestQbitIdx = terms[terms.size() - 1].first; std::vector<std::size_t> qidxs; std::stringstream basis_front, basis_back; std::vector<xacc::InstPtr> basis_front, basis_back; for (auto &term : terms) { auto qid = term.first; Loading @@ -201,14 +204,11 @@ class NISQ : public ::quantum::QuantumRuntime { qidxs.push_back(qid); if (pop == "X") { basis_front << "H(" << q_name << "[" << qid << "]);\n"; basis_back << "H(" << q_name << "[" << qid << "]);\n"; basis_front.emplace_back(std::make_shared<xacc::quantum::Hadamard>(qid)); basis_back.emplace_back(std::make_shared<xacc::quantum::Hadamard>(qid)); } else if (pop == "Y") { basis_front << "Rx(" << q_name << "[" << qid << "], " << 1.57079362679 << ");\n"; basis_back << "Rx(" << q_name << "[" << qid << "], " << -1.57079362679 << ");\n"; basis_front.emplace_back(std::make_shared<xacc::quantum::Rx>(qid, 1.57079362679)); basis_back.emplace_back(std::make_shared<xacc::quantum::Rx>(qid, -1.57079362679)); } } Loading @@ -223,54 +223,45 @@ class NISQ : public ::quantum::QuantumRuntime { } // std::cout << "HOWDY: \n" << cnot_pairs << "\n"; std::stringstream cnot_front, cnot_back; std::vector<xacc::InstPtr> cnot_front, cnot_back; for (int i = 0; i < qidxs.size() - 1; i++) { Eigen::VectorXi pairs = cnot_pairs.col(i); auto c = pairs(0); auto t = pairs(1); cnot_front << "CNOT(" << q_name << "[" << c << "], " << q_name << "[" << t << "]);\n"; cnot_front.emplace_back(std::make_shared<xacc::quantum::CNOT>(c, t)); } for (int i = qidxs.size() - 2; i >= 0; i--) { Eigen::VectorXi pairs = cnot_pairs.col(i); auto c = pairs(0); auto t = pairs(1); cnot_back << "CNOT(" << q_name << "[" << c << "], " << q_name << "[" << t << "]);\n"; cnot_back.emplace_back(std::make_shared<xacc::quantum::CNOT>(c, t)); } xasm_src = xasm_src + "\n" + basis_front.str() + cnot_front.str(); exp_insts.insert(exp_insts.end(), std::make_move_iterator(basis_front.begin()), std::make_move_iterator(basis_front.end())); exp_insts.insert(exp_insts.end(), std::make_move_iterator(cnot_front.begin()), std::make_move_iterator(cnot_front.end())); // FIXME, we assume real coefficients, if its zero, // check that the imag part is not zero and use it if (std::fabs(std::real(spinInst.coeff())) > 1e-12) { xasm_src = xasm_src + "Rz(" + q_name + "[" + std::to_string(qidxs[qidxs.size() - 1]) + "], " + std::to_string(std::real(spinInst.coeff()) * theta) + ");\n"; exp_insts.emplace_back(std::make_shared<xacc::quantum::Rz>( qidxs[qidxs.size() - 1], std::real(spinInst.coeff()) * theta)); } else if (std::fabs(std::imag(spinInst.coeff())) > 1e-12) { xasm_src = xasm_src + "Rz(" + q_name + "[" + std::to_string(qidxs[qidxs.size() - 1]) + "], " + std::to_string(std::imag(spinInst.coeff()) * theta) + ");\n"; } xasm_src = xasm_src + cnot_back.str() + basis_back.str(); } int name_counter = 1; std::string name = "exp_tmp"; while (xacc::hasCompiled(name)) { name += std::to_string(name_counter); } xasm_src = "__qpu__ void " + name + "(qbit " + q_name + ") {\n" + xasm_src + "}"; // std::cout << "FROMQRT: " << theta << "\n" << xasm_src << "\n"; auto xasm = xacc::getCompiler("xasm"); auto tmp = xasm->compile(xasm_src)->getComposites()[0]; for (auto inst : tmp->getInstructions()) { exp_insts.emplace_back(std::make_shared<xacc::quantum::Rz>( qidxs[qidxs.size() - 1], std::imag(spinInst.coeff()) * theta)); } exp_insts.insert(exp_insts.end(), std::make_move_iterator(cnot_back.begin()), std::make_move_iterator(cnot_back.end())); exp_insts.insert(exp_insts.end(), std::make_move_iterator(basis_back.begin()), std::make_move_iterator(basis_back.end())); } for (auto& inst : exp_insts) { inst->setBufferNames(std::vector<std::string>(inst->bits().size(), q_name)); program->addInstruction(inst); } } Loading
runtime/qrt/impls/nisq/tests/CMakeLists.txt 0 → 100644 +9 −0 Original line number Diff line number Diff line link_directories(${XACC_ROOT}/lib) if (NOT XACC_ROOT STREQUAL CMAKE_INSTALL_PREFIX) add_definitions(-D__internal__qcor__compile__plugin__path="${CMAKE_INSTALL_PREFIX}/plugins") endif() add_executable(NisqQrtTester NisqQrtTester.cpp) add_test(NAME qcor_NisqQrtTester COMMAND NisqQrtTester) target_include_directories(NisqQrtTester PRIVATE ${XACC_ROOT}/include/gtest) target_link_libraries(NisqQrtTester ${XACC_TEST_LIBRARIES} qcor) No newline at end of file
runtime/qrt/impls/nisq/tests/NisqQrtTester.cpp 0 → 100644 +28 −0 Original line number Diff line number Diff line #include "qcor.hpp" #include <gtest/gtest.h> #include "xacc_service.hpp" TEST(NisqQrtTester, checkExpInst) { ::quantum::initialize("qpp", "empty"); const std::string obs_str = "5.907 - 2.1433 X0X1 - 2.1433 Y0Y1 + .21829 Z0 - 6.125 Z1"; auto observable = qcor::createObservable(obs_str); auto qreg = qalloc(2); qreg.setName("q"); ::quantum::exp(qreg, 1.0, observable); std::cout << "HOWDY\n" << ::quantum::qrt_impl->get_current_program()->toString() << "\n"; // Get the XACC reference implementation auto exp = std::dynamic_pointer_cast<xacc::quantum::Circuit>( xacc::getService<xacc::Instruction>("exp_i_theta")); EXPECT_TRUE(exp->expand({{ "pauli", obs_str}})); auto evaled = exp->operator()({0.5}); std::cout << "HELLO\n" << evaled->toString() << "\n"; EXPECT_EQ(evaled->toString(), ::quantum::qrt_impl->get_current_program()->toString()); } int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); auto ret = RUN_ALL_TESTS(); return ret; }