Loading examples/placement/simplePlacement.cpp 0 → 100644 +44 −0 Original line number Diff line number Diff line #include <qalloc> // Create a multi-qubit entangled state __qpu__ void entangleQubits(qreg q) { H(q[0]); for (int i = 1; i < q.size(); i++) { CX(q[0],q[i]); } for (int i = 0; i < q.size(); i++) { Measure(q[i]); } } // Example: using ibmq_ourense or ibmqx2 (5 qubits) which has // the following connectivity graph: // 1 // / | // / | // 0 -- 1 -- 2 / | // | / | // 3 0 -- 2 -- 3 // | | / // 4 | / // | / // | / // 4 // Compile: qcor -qpu aer:ibmq_ourense simplePlacement.cpp // Compile: qcor -qpu aer:ibmqx2 simplePlacement.cpp // Make sure to have a valid ~/.ibm_config file. // Example: // key: YOUR_API_KEY // hub:ibm-q // group:open // project:main // url: https://quantumexperience.ng.bluemix.net int main() { // This circuit requires 4 qubits. auto q = qalloc(4); entangleQubits(q); // Expect: ~50-50 for "0000" and "1111" // (plus some variations due to noise) q.print(); } handlers/qcor_syntax_handler.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -207,8 +207,8 @@ public: } OS << ");\n"; OS << "if (optimize_only) {\n"; OS << "xacc::internal_compiler::execute_pass_manager();\n"; OS << "if (optimize_only) {\n"; OS << "return;\n"; OS << "}\n"; Loading runtime/qcor.hpp +6 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,12 @@ public: #endif #ifdef __internal__qcor__compile__opt__passes xacc::internal_compiler::__user_opt_passes = __internal__qcor__compile__opt__passes; #endif #ifdef __internal__qcor__compile__placement__name xacc::internal_compiler::__placement_name = __internal__qcor__compile__placement__name; #endif #ifdef __internal__qcor__compile__qubit__map xacc::internal_compiler::__qubit_map = xacc::internal_compiler::parse_qubit_map(__internal__qcor__compile__qubit__map); #endif } }; Loading runtime/qrt/pass_manager.cpp +34 −1 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ #include "InstructionIterator.hpp" #include "xacc.hpp" #include "xacc_service.hpp" #include "xacc_internal_compiler.hpp" #include <iomanip> #include <numeric> namespace { Loading Loading @@ -41,7 +42,9 @@ printGateCountComparison(const std::unordered_map<std::string, int> &before, namespace qcor { namespace internal { PassManager::PassManager(int level) : m_level(level) {} PassManager::PassManager(int level, const std::vector<int> &qubitMap, const std::string &placementName) : m_level(level), m_qubitMap(qubitMap), m_placement(placementName) {} PassStat PassManager::runPass(const std::string &passName, std::shared_ptr<xacc::CompositeInstruction> program) { PassStat stat; Loading Loading @@ -91,6 +94,36 @@ std::vector<PassStat> PassManager::optimize( return passData; } void PassManager::applyPlacement(std::shared_ptr<xacc::CompositeInstruction> program) const { const std::string placementName = [&]() -> std::string { // If the qubit-map was provided, always use default-placement if (!m_qubitMap.empty()) { return "default-placement"; } // Use the specified placement if any. // Note: placement will only be activated if the accelerator // has a connectivity graph. return m_placement.empty() ? DEFAULT_PLACEMENT : m_placement; }(); if (!xacc::hasService<xacc::IRTransformation>(placementName) && !xacc::hasContributedService<xacc::IRTransformation>(placementName)) { // Graciously ignores services which cannot be located. return; } auto irt = xacc::getIRTransformation(placementName); if (irt->type() == xacc::IRTransformationType::Placement && xacc::internal_compiler::qpu && !xacc::internal_compiler::qpu->getConnectivity().empty()) { if (placementName == "default-placement") { irt->apply(program, xacc::internal_compiler::qpu, {{"qubit-map", m_qubitMap}}); } else { irt->apply(program, xacc::internal_compiler::qpu); } } } std::unordered_map<std::string, int> PassStat::countGates( const std::shared_ptr<xacc::CompositeInstruction> &program) { std::unordered_map<std::string, int> gateCount; Loading runtime/qrt/pass_manager.hpp +10 −1 Original line number Diff line number Diff line Loading @@ -26,9 +26,14 @@ struct PassStat { class PassManager { public: PassManager(int level); PassManager(int level, const std::vector<int> &qubitMap = {}, const std::string &placementName = ""); // Static helper to run an optimization pass static PassStat runPass(const std::string &passName, std::shared_ptr<xacc::CompositeInstruction> program); // Default placement strategy static constexpr const char *DEFAULT_PLACEMENT = "swap-shortest-path"; // Apply placement void applyPlacement(std::shared_ptr<xacc::CompositeInstruction> program) const; // Optimizes the input program. // Returns the full statistics about all the passes that have been executed. std::vector<PassStat> Loading Loading @@ -59,7 +64,11 @@ public: "circuit-optimizer", }; private: // Circuit optimization level int m_level; // Placement config. std::vector<int> m_qubitMap; std::string m_placement; }; } // namespace internal } // namespace qcor No newline at end of file Loading
examples/placement/simplePlacement.cpp 0 → 100644 +44 −0 Original line number Diff line number Diff line #include <qalloc> // Create a multi-qubit entangled state __qpu__ void entangleQubits(qreg q) { H(q[0]); for (int i = 1; i < q.size(); i++) { CX(q[0],q[i]); } for (int i = 0; i < q.size(); i++) { Measure(q[i]); } } // Example: using ibmq_ourense or ibmqx2 (5 qubits) which has // the following connectivity graph: // 1 // / | // / | // 0 -- 1 -- 2 / | // | / | // 3 0 -- 2 -- 3 // | | / // 4 | / // | / // | / // 4 // Compile: qcor -qpu aer:ibmq_ourense simplePlacement.cpp // Compile: qcor -qpu aer:ibmqx2 simplePlacement.cpp // Make sure to have a valid ~/.ibm_config file. // Example: // key: YOUR_API_KEY // hub:ibm-q // group:open // project:main // url: https://quantumexperience.ng.bluemix.net int main() { // This circuit requires 4 qubits. auto q = qalloc(4); entangleQubits(q); // Expect: ~50-50 for "0000" and "1111" // (plus some variations due to noise) q.print(); }
handlers/qcor_syntax_handler.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -207,8 +207,8 @@ public: } OS << ");\n"; OS << "if (optimize_only) {\n"; OS << "xacc::internal_compiler::execute_pass_manager();\n"; OS << "if (optimize_only) {\n"; OS << "return;\n"; OS << "}\n"; Loading
runtime/qcor.hpp +6 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,12 @@ public: #endif #ifdef __internal__qcor__compile__opt__passes xacc::internal_compiler::__user_opt_passes = __internal__qcor__compile__opt__passes; #endif #ifdef __internal__qcor__compile__placement__name xacc::internal_compiler::__placement_name = __internal__qcor__compile__placement__name; #endif #ifdef __internal__qcor__compile__qubit__map xacc::internal_compiler::__qubit_map = xacc::internal_compiler::parse_qubit_map(__internal__qcor__compile__qubit__map); #endif } }; Loading
runtime/qrt/pass_manager.cpp +34 −1 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ #include "InstructionIterator.hpp" #include "xacc.hpp" #include "xacc_service.hpp" #include "xacc_internal_compiler.hpp" #include <iomanip> #include <numeric> namespace { Loading Loading @@ -41,7 +42,9 @@ printGateCountComparison(const std::unordered_map<std::string, int> &before, namespace qcor { namespace internal { PassManager::PassManager(int level) : m_level(level) {} PassManager::PassManager(int level, const std::vector<int> &qubitMap, const std::string &placementName) : m_level(level), m_qubitMap(qubitMap), m_placement(placementName) {} PassStat PassManager::runPass(const std::string &passName, std::shared_ptr<xacc::CompositeInstruction> program) { PassStat stat; Loading Loading @@ -91,6 +94,36 @@ std::vector<PassStat> PassManager::optimize( return passData; } void PassManager::applyPlacement(std::shared_ptr<xacc::CompositeInstruction> program) const { const std::string placementName = [&]() -> std::string { // If the qubit-map was provided, always use default-placement if (!m_qubitMap.empty()) { return "default-placement"; } // Use the specified placement if any. // Note: placement will only be activated if the accelerator // has a connectivity graph. return m_placement.empty() ? DEFAULT_PLACEMENT : m_placement; }(); if (!xacc::hasService<xacc::IRTransformation>(placementName) && !xacc::hasContributedService<xacc::IRTransformation>(placementName)) { // Graciously ignores services which cannot be located. return; } auto irt = xacc::getIRTransformation(placementName); if (irt->type() == xacc::IRTransformationType::Placement && xacc::internal_compiler::qpu && !xacc::internal_compiler::qpu->getConnectivity().empty()) { if (placementName == "default-placement") { irt->apply(program, xacc::internal_compiler::qpu, {{"qubit-map", m_qubitMap}}); } else { irt->apply(program, xacc::internal_compiler::qpu); } } } std::unordered_map<std::string, int> PassStat::countGates( const std::shared_ptr<xacc::CompositeInstruction> &program) { std::unordered_map<std::string, int> gateCount; Loading
runtime/qrt/pass_manager.hpp +10 −1 Original line number Diff line number Diff line Loading @@ -26,9 +26,14 @@ struct PassStat { class PassManager { public: PassManager(int level); PassManager(int level, const std::vector<int> &qubitMap = {}, const std::string &placementName = ""); // Static helper to run an optimization pass static PassStat runPass(const std::string &passName, std::shared_ptr<xacc::CompositeInstruction> program); // Default placement strategy static constexpr const char *DEFAULT_PLACEMENT = "swap-shortest-path"; // Apply placement void applyPlacement(std::shared_ptr<xacc::CompositeInstruction> program) const; // Optimizes the input program. // Returns the full statistics about all the passes that have been executed. std::vector<PassStat> Loading Loading @@ -59,7 +64,11 @@ public: "circuit-optimizer", }; private: // Circuit optimization level int m_level; // Placement config. std::vector<int> m_qubitMap; std::string m_placement; }; } // namespace internal } // namespace qcor No newline at end of file