Loading handlers/qcor_syntax_handler.cpp +7 −1 Original line number Diff line number Diff line Loading @@ -152,6 +152,12 @@ void QCORSyntaxHandler::GetReplacement( "qcor::__internal__::create_composite(kernel_name);\n"; OS << "}\n"; OS << "quantum::set_current_program(parent_kernel);\n"; // Set the buffer in FTQC mode so that following QRT calls (in new_src) are // executed on that buffer. OS << "if (runtime_env == QrtType::FTQC) {\n"; // We only support one buffer in FTQC mode atm. OS << "quantum::set_current_buffer(" << bufferNames[0] << ".results());\n"; OS << "}\n"; OS << new_src << "\n"; OS << "}\n"; Loading Loading @@ -213,7 +219,7 @@ void QCORSyntaxHandler::GetReplacement( OS << "return;\n"; OS << "}\n"; OS << "if (is_callable) {\n"; OS << "if (is_callable && (runtime_env == QrtType::NISQ)) {\n"; if (bufferNames.size() > 1) { OS << "xacc::AcceleratorBuffer * buffers[" << bufferNames.size() << "] = {"; OS << bufferNames[0] << ".results()"; Loading runtime/kernel/quantum_kernel.hpp +2 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,8 @@ public: // Flag to indicate we only want to // run the pass manager and not execute bool optimize_only = false; enum class QrtType { NISQ, FTQC }; QrtType runtime_env = QrtType::NISQ; // Default constructor, takes quantum kernel function arguments QuantumKernel(Args... args) : args_tuple(std::forward_as_tuple(args...)) {} Loading runtime/qrt/impls/ftqc/ftqc_qrt.cpp +72 −40 Original line number Diff line number Diff line Loading @@ -15,41 +15,44 @@ using namespace cppmicroservices; namespace qcor { class FTQC : public quantum::QuantumRuntime { public: virtual void initialize(const std::string kernel_name) override { /* TODO */ virtual void initialize(const std::string kernel_name) override { provider = xacc::getIRProvider("quantum"); qpu = xacc::internal_compiler::qpu; } const std::string name() const override { return "ftqc"; } const std::string description() const override { return ""; } virtual void h(const qubit &qidx) override { /* TODO */ } virtual void x(const qubit &qidx) override { /* TODO */ } virtual void y(const qubit &qidx) override { /* TODO */ } virtual void z(const qubit &qidx) override { /* TODO */ } virtual void t(const qubit &qidx) override { /* TODO */ } virtual void tdg(const qubit &qidx) override { /* TODO */ } virtual void s(const qubit &qidx) override { /* TODO */ } virtual void sdg(const qubit &qidx) override { /* TODO */ virtual void h(const qubit &qidx) override { applyGate("H", {qidx.second}); } virtual void x(const qubit &qidx) override { applyGate("X", {qidx.second}); } virtual void y(const qubit &qidx) override { applyGate("Y", {qidx.second}); } virtual void z(const qubit &qidx) override { applyGate("Z", {qidx.second}); } virtual void t(const qubit &qidx) override { applyGate("T", {qidx.second}); } virtual void tdg(const qubit &qidx) override { applyGate("Tdg", {qidx.second}); } virtual void s(const qubit &qidx) override { applyGate("S", {qidx.second}); } virtual void sdg(const qubit &qidx) override { applyGate("Sdg", {qidx.second}); } // Common single-qubit, parameterized instructions virtual void rx(const qubit &qidx, const double theta) override { /* TODO */ virtual void rx(const qubit &qidx, const double theta) override { applyGate("Rx", {qidx.second}, {theta}); } virtual void ry(const qubit &qidx, const double theta) override { /* TODO */ virtual void ry(const qubit &qidx, const double theta) override { applyGate("Ry", {qidx.second}, {theta}); } virtual void rz(const qubit &qidx, const double theta) override { /* TODO */ virtual void rz(const qubit &qidx, const double theta) override { applyGate("Rz", {qidx.second}, {theta}); } // U1(theta) gate virtual void u1(const qubit &qidx, const double theta) override { /* TODO */ virtual void u1(const qubit &qidx, const double theta) override { applyGate("U1", {qidx.second}, {theta}); } virtual void u3(const qubit &qidx, const double theta, const double phi, const double lambda) override { /* TODO */ const double lambda) override { applyGate("U", {qidx.second}, {theta, phi, lambda}); } // Measure-Z Loading @@ -57,28 +60,30 @@ public: } // Common two-qubit gates. virtual void cnot(const qubit &src_idx, const qubit &tgt_idx) override { /* TODO */ virtual void cnot(const qubit &src_idx, const qubit &tgt_idx) override { applyGate("CNOT", {src_idx.second, tgt_idx.second}); } virtual void cy(const qubit &src_idx, const qubit &tgt_idx) override { /* TODO */ virtual void cy(const qubit &src_idx, const qubit &tgt_idx) override { applyGate("CY", {src_idx.second, tgt_idx.second}); } virtual void cz(const qubit &src_idx, const qubit &tgt_idx) override { /* TODO */ virtual void cz(const qubit &src_idx, const qubit &tgt_idx) override { applyGate("CZ", {src_idx.second, tgt_idx.second}); } virtual void ch(const qubit &src_idx, const qubit &tgt_idx) override { /* TODO */ virtual void ch(const qubit &src_idx, const qubit &tgt_idx) override { applyGate("CH", {src_idx.second, tgt_idx.second}); } virtual void swap(const qubit &src_idx, const qubit &tgt_idx) override { /* TODO */ virtual void swap(const qubit &src_idx, const qubit &tgt_idx) override { applyGate("Swap", {src_idx.second, tgt_idx.second}); } // Common parameterized 2 qubit gates. virtual void cphase(const qubit &src_idx, const qubit &tgt_idx, const double theta) override { /* TODO */ const double theta) override { applyGate("CPhase", {src_idx.second, tgt_idx.second}, {theta}); } virtual void crz(const qubit &src_idx, const qubit &tgt_idx, const double theta) override { /* TODO */ const double theta) override { applyGate("CRZ", {src_idx.second, tgt_idx.second}, {theta}); } // exponential of i * theta * H, where H is an Observable pointer Loading @@ -92,22 +97,49 @@ public: std::shared_ptr<xacc::Observable> H) override { /* TODO */ } // Submission API. Submit the constructed CompositeInstruction operating // on the provided AcceleratorBuffer(s) (note qreg wraps an AcceleratorBuffer) virtual void submit(xacc::AcceleratorBuffer *buffer) override { /* TODO */ // Submission API: sanity check that we don't call these API's. // e.g. catch high-level code gen errors. virtual void submit(xacc::AcceleratorBuffer *buffer) override { throw std::runtime_error("FTQC runtime doesn't support submit API."); } virtual void submit(xacc::AcceleratorBuffer **buffers, const int nBuffers) override { /* TODO */ const int nBuffers) override { throw std::runtime_error("FTQC runtime doesn't support submit API."); } // Some getters for the qcor runtime library. virtual void set_current_program( std::shared_ptr<xacc::CompositeInstruction> p) override { /* TODO */ virtual void set_current_program(std::shared_ptr<xacc::CompositeInstruction> p) override { // Nothing to do } virtual std::shared_ptr<xacc::CompositeInstruction> get_current_program() override { /* TODO */ get_current_program() override { return nullptr; } void set_current_buffer(xacc::AcceleratorBuffer *buffer) override { qReg = xacc::as_shared_ptr(buffer); } private: // Notes: all gate parameters must be resolved (to double) for FT-QRT // execution. void applyGate(const std::string &gateName, const std::vector<size_t> &bits, const std::vector<double> ¶ms = {}) { std::vector<xacc::InstructionParameter> instParams; for (const auto &val : params) { instParams.emplace_back(val); } auto gateInst = provider->createInstruction(gateName, bits, instParams); qpu->apply(qReg, gateInst); } private: std::shared_ptr<xacc::IRProvider> provider; std::shared_ptr<xacc::Accelerator> qpu; // TODO: eventually, we may want to support an arbitrary number of qubit // registers when the FTQC backend can support it. std::shared_ptr<xacc::AcceleratorBuffer> qReg; }; } // namespace qcor Loading runtime/qrt/impls/nisq/nisq_qrt.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -259,6 +259,11 @@ public: if (program && provider) program = provider->createComposite(program->name()); } void set_current_buffer(xacc::AcceleratorBuffer* buffer) override { // Nothing to do: the NISQ runtime doesn't keep track of runtime buffer info. } const std::string name() const override { return "nisq"; } const std::string description() const override { return ""; } }; Loading runtime/qrt/qrt.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -179,4 +179,8 @@ void set_current_program(std::shared_ptr<xacc::CompositeInstruction> p) { qrt_impl->set_current_program(p); } void set_current_buffer(xacc::AcceleratorBuffer* buffer) { qrt_impl->set_current_buffer(buffer); } } // namespace quantum No newline at end of file Loading
handlers/qcor_syntax_handler.cpp +7 −1 Original line number Diff line number Diff line Loading @@ -152,6 +152,12 @@ void QCORSyntaxHandler::GetReplacement( "qcor::__internal__::create_composite(kernel_name);\n"; OS << "}\n"; OS << "quantum::set_current_program(parent_kernel);\n"; // Set the buffer in FTQC mode so that following QRT calls (in new_src) are // executed on that buffer. OS << "if (runtime_env == QrtType::FTQC) {\n"; // We only support one buffer in FTQC mode atm. OS << "quantum::set_current_buffer(" << bufferNames[0] << ".results());\n"; OS << "}\n"; OS << new_src << "\n"; OS << "}\n"; Loading Loading @@ -213,7 +219,7 @@ void QCORSyntaxHandler::GetReplacement( OS << "return;\n"; OS << "}\n"; OS << "if (is_callable) {\n"; OS << "if (is_callable && (runtime_env == QrtType::NISQ)) {\n"; if (bufferNames.size() > 1) { OS << "xacc::AcceleratorBuffer * buffers[" << bufferNames.size() << "] = {"; OS << bufferNames[0] << ".results()"; Loading
runtime/kernel/quantum_kernel.hpp +2 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,8 @@ public: // Flag to indicate we only want to // run the pass manager and not execute bool optimize_only = false; enum class QrtType { NISQ, FTQC }; QrtType runtime_env = QrtType::NISQ; // Default constructor, takes quantum kernel function arguments QuantumKernel(Args... args) : args_tuple(std::forward_as_tuple(args...)) {} Loading
runtime/qrt/impls/ftqc/ftqc_qrt.cpp +72 −40 Original line number Diff line number Diff line Loading @@ -15,41 +15,44 @@ using namespace cppmicroservices; namespace qcor { class FTQC : public quantum::QuantumRuntime { public: virtual void initialize(const std::string kernel_name) override { /* TODO */ virtual void initialize(const std::string kernel_name) override { provider = xacc::getIRProvider("quantum"); qpu = xacc::internal_compiler::qpu; } const std::string name() const override { return "ftqc"; } const std::string description() const override { return ""; } virtual void h(const qubit &qidx) override { /* TODO */ } virtual void x(const qubit &qidx) override { /* TODO */ } virtual void y(const qubit &qidx) override { /* TODO */ } virtual void z(const qubit &qidx) override { /* TODO */ } virtual void t(const qubit &qidx) override { /* TODO */ } virtual void tdg(const qubit &qidx) override { /* TODO */ } virtual void s(const qubit &qidx) override { /* TODO */ } virtual void sdg(const qubit &qidx) override { /* TODO */ virtual void h(const qubit &qidx) override { applyGate("H", {qidx.second}); } virtual void x(const qubit &qidx) override { applyGate("X", {qidx.second}); } virtual void y(const qubit &qidx) override { applyGate("Y", {qidx.second}); } virtual void z(const qubit &qidx) override { applyGate("Z", {qidx.second}); } virtual void t(const qubit &qidx) override { applyGate("T", {qidx.second}); } virtual void tdg(const qubit &qidx) override { applyGate("Tdg", {qidx.second}); } virtual void s(const qubit &qidx) override { applyGate("S", {qidx.second}); } virtual void sdg(const qubit &qidx) override { applyGate("Sdg", {qidx.second}); } // Common single-qubit, parameterized instructions virtual void rx(const qubit &qidx, const double theta) override { /* TODO */ virtual void rx(const qubit &qidx, const double theta) override { applyGate("Rx", {qidx.second}, {theta}); } virtual void ry(const qubit &qidx, const double theta) override { /* TODO */ virtual void ry(const qubit &qidx, const double theta) override { applyGate("Ry", {qidx.second}, {theta}); } virtual void rz(const qubit &qidx, const double theta) override { /* TODO */ virtual void rz(const qubit &qidx, const double theta) override { applyGate("Rz", {qidx.second}, {theta}); } // U1(theta) gate virtual void u1(const qubit &qidx, const double theta) override { /* TODO */ virtual void u1(const qubit &qidx, const double theta) override { applyGate("U1", {qidx.second}, {theta}); } virtual void u3(const qubit &qidx, const double theta, const double phi, const double lambda) override { /* TODO */ const double lambda) override { applyGate("U", {qidx.second}, {theta, phi, lambda}); } // Measure-Z Loading @@ -57,28 +60,30 @@ public: } // Common two-qubit gates. virtual void cnot(const qubit &src_idx, const qubit &tgt_idx) override { /* TODO */ virtual void cnot(const qubit &src_idx, const qubit &tgt_idx) override { applyGate("CNOT", {src_idx.second, tgt_idx.second}); } virtual void cy(const qubit &src_idx, const qubit &tgt_idx) override { /* TODO */ virtual void cy(const qubit &src_idx, const qubit &tgt_idx) override { applyGate("CY", {src_idx.second, tgt_idx.second}); } virtual void cz(const qubit &src_idx, const qubit &tgt_idx) override { /* TODO */ virtual void cz(const qubit &src_idx, const qubit &tgt_idx) override { applyGate("CZ", {src_idx.second, tgt_idx.second}); } virtual void ch(const qubit &src_idx, const qubit &tgt_idx) override { /* TODO */ virtual void ch(const qubit &src_idx, const qubit &tgt_idx) override { applyGate("CH", {src_idx.second, tgt_idx.second}); } virtual void swap(const qubit &src_idx, const qubit &tgt_idx) override { /* TODO */ virtual void swap(const qubit &src_idx, const qubit &tgt_idx) override { applyGate("Swap", {src_idx.second, tgt_idx.second}); } // Common parameterized 2 qubit gates. virtual void cphase(const qubit &src_idx, const qubit &tgt_idx, const double theta) override { /* TODO */ const double theta) override { applyGate("CPhase", {src_idx.second, tgt_idx.second}, {theta}); } virtual void crz(const qubit &src_idx, const qubit &tgt_idx, const double theta) override { /* TODO */ const double theta) override { applyGate("CRZ", {src_idx.second, tgt_idx.second}, {theta}); } // exponential of i * theta * H, where H is an Observable pointer Loading @@ -92,22 +97,49 @@ public: std::shared_ptr<xacc::Observable> H) override { /* TODO */ } // Submission API. Submit the constructed CompositeInstruction operating // on the provided AcceleratorBuffer(s) (note qreg wraps an AcceleratorBuffer) virtual void submit(xacc::AcceleratorBuffer *buffer) override { /* TODO */ // Submission API: sanity check that we don't call these API's. // e.g. catch high-level code gen errors. virtual void submit(xacc::AcceleratorBuffer *buffer) override { throw std::runtime_error("FTQC runtime doesn't support submit API."); } virtual void submit(xacc::AcceleratorBuffer **buffers, const int nBuffers) override { /* TODO */ const int nBuffers) override { throw std::runtime_error("FTQC runtime doesn't support submit API."); } // Some getters for the qcor runtime library. virtual void set_current_program( std::shared_ptr<xacc::CompositeInstruction> p) override { /* TODO */ virtual void set_current_program(std::shared_ptr<xacc::CompositeInstruction> p) override { // Nothing to do } virtual std::shared_ptr<xacc::CompositeInstruction> get_current_program() override { /* TODO */ get_current_program() override { return nullptr; } void set_current_buffer(xacc::AcceleratorBuffer *buffer) override { qReg = xacc::as_shared_ptr(buffer); } private: // Notes: all gate parameters must be resolved (to double) for FT-QRT // execution. void applyGate(const std::string &gateName, const std::vector<size_t> &bits, const std::vector<double> ¶ms = {}) { std::vector<xacc::InstructionParameter> instParams; for (const auto &val : params) { instParams.emplace_back(val); } auto gateInst = provider->createInstruction(gateName, bits, instParams); qpu->apply(qReg, gateInst); } private: std::shared_ptr<xacc::IRProvider> provider; std::shared_ptr<xacc::Accelerator> qpu; // TODO: eventually, we may want to support an arbitrary number of qubit // registers when the FTQC backend can support it. std::shared_ptr<xacc::AcceleratorBuffer> qReg; }; } // namespace qcor Loading
runtime/qrt/impls/nisq/nisq_qrt.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -259,6 +259,11 @@ public: if (program && provider) program = provider->createComposite(program->name()); } void set_current_buffer(xacc::AcceleratorBuffer* buffer) override { // Nothing to do: the NISQ runtime doesn't keep track of runtime buffer info. } const std::string name() const override { return "nisq"; } const std::string description() const override { return ""; } }; Loading
runtime/qrt/qrt.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -179,4 +179,8 @@ void set_current_program(std::shared_ptr<xacc::CompositeInstruction> p) { qrt_impl->set_current_program(p); } void set_current_buffer(xacc::AcceleratorBuffer* buffer) { qrt_impl->set_current_buffer(buffer); } } // namespace quantum No newline at end of file