Loading mlir/parsers/qasm3/examples/qpe.qasm +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ for i in [0:n_counting] { } // Run inverse QFT iqf2 counting; iqft counting; // Now lets measure the counting qubits bit c[n_counting]; Loading runtime/kernel/quantum_kernel.hpp +103 −96 Original line number Diff line number Diff line Loading @@ -343,98 +343,6 @@ class QuantumKernel { virtual ~QuantumKernel() {} }; template <typename... Args> using callable_function_ptr = void (*)(std::shared_ptr<xacc::CompositeInstruction>, Args...); template <typename... Args> class KernelSignature { protected: callable_function_ptr<Args...> &function_pointer; public: KernelSignature(callable_function_ptr<Args...> &&f) : function_pointer(f) {} // Ctor from raw void* funtion pointer. // IMPORTANT: since function_pointer is kept as a *reference*, // we must keep a reference to the original f_ptr void* as well. KernelSignature(void *&f_ptr) : function_pointer((callable_function_ptr<Args...> &)f_ptr) {} void operator()(std::shared_ptr<xacc::CompositeInstruction> ir, Args... args) { function_pointer(ir, args...); } void ctrl(std::shared_ptr<xacc::CompositeInstruction> ir, int ctrl_qbit, Args... args) { auto tempKernel = qcor::__internal__::create_composite("temp_control"); function_pointer(tempKernel, args...); auto ctrlKernel = qcor::__internal__::create_ctrl_u(); ctrlKernel->expand({ std::make_pair("U", tempKernel), std::make_pair("control-idx", ctrl_qbit), }); for (int instId = 0; instId < ctrlKernel->nInstructions(); ++instId) { ir->addInstruction(ctrlKernel->getInstruction(instId)->clone()); } ::quantum::set_current_program(ir); } void ctrl(std::shared_ptr<xacc::CompositeInstruction> ir, qubit ctrl_qbit, Args... args) { int ctrl_bit = (int)ctrl_qbit.second; ctrl(ir, ctrl_bit, args...); } void adjoint(std::shared_ptr<CompositeInstruction> ir, Args... args) { auto tempKernel = qcor::__internal__::create_composite("temp_adjoint"); function_pointer(tempKernel, args...); // get the instructions auto instructions = tempKernel->getInstructions(); std::shared_ptr<CompositeInstruction> program = tempKernel; // Assert that we don't have measurement if (!std::all_of( instructions.cbegin(), instructions.cend(), [](const auto &inst) { return inst->name() != "Measure"; })) { error( "Unable to create Adjoint for kernels that have Measure operations."); } auto provider = qcor::__internal__::get_provider(); for (int i = 0; i < instructions.size(); i++) { auto inst = tempKernel->getInstruction(i); // Parametric gates: if (inst->name() == "Rx" || inst->name() == "Ry" || inst->name() == "Rz" || inst->name() == "CPHASE" || inst->name() == "U1" || inst->name() == "CRZ") { inst->setParameter(0, -inst->getParameter(0).template as<double>()); } // Handles T and S gates, etc... => T -> Tdg else if (inst->name() == "T") { auto tdg = provider->createInstruction("Tdg", inst->bits()); program->replaceInstruction(i, tdg); } else if (inst->name() == "S") { auto sdg = provider->createInstruction("Sdg", inst->bits()); program->replaceInstruction(i, sdg); } } // We update/replace instructions in the derived.parent_kernel composite, // hence collecting these new instructions and reversing the sequence. auto new_instructions = tempKernel->getInstructions(); std::reverse(new_instructions.begin(), new_instructions.end()); // add the instructions to the current parent kernel ir->addInstructions(new_instructions); ::quantum::set_current_program(ir); } }; // We use the following to enable ctrl operations on our single // qubit gates, X::ctrl(), Z::ctrl(), H::ctrl(), etc.... template <typename Derived> Loading @@ -456,7 +364,15 @@ using OneQubitKernel = QuantumKernel<Derived, qubit>; if (runtime_env == QrtType::FTQC) { \ quantum::set_current_buffer(q.results()); \ } \ bool cached_is_compute_section = \ ::quantum::qrt_impl->isComputeSection(); \ if (cached_is_compute_section) { \ ::quantum::qrt_impl->__end_mark_segment_as_compute(); \ } \ ::quantum::QRTNAME(q); \ if (cached_is_compute_section) { \ ::quantum::qrt_impl->__begin_mark_segment_as_compute(); \ } \ return; \ } \ virtual ~CLASSNAME() {} \ Loading Loading @@ -487,7 +403,6 @@ ONE_QUBIT_KERNEL_CTRL_ENABLER(Sdg, sdg) template <typename... CaptureArgs> class _qpu_lambda { private: // Private inner class for getting the type // of a capture variable as a string at runtime class TupleToTypeArgString { Loading Loading @@ -596,4 +511,96 @@ class _qpu_lambda { #define qpu_lambda(EXPR, ...) _qpu_lambda(#EXPR, #__VA_ARGS__, ##__VA_ARGS__) template <typename... Args> using callable_function_ptr = void (*)(std::shared_ptr<xacc::CompositeInstruction>, Args...); template <typename... Args> class KernelSignature { protected: callable_function_ptr<Args...> &function_pointer; public: KernelSignature(callable_function_ptr<Args...> &&f) : function_pointer(f) {} // Ctor from raw void* funtion pointer. // IMPORTANT: since function_pointer is kept as a *reference*, // we must keep a reference to the original f_ptr void* as well. KernelSignature(void *&f_ptr) : function_pointer((callable_function_ptr<Args...> &)f_ptr) {} void operator()(std::shared_ptr<xacc::CompositeInstruction> ir, Args... args) { function_pointer(ir, args...); } void ctrl(std::shared_ptr<xacc::CompositeInstruction> ir, int ctrl_qbit, Args... args) { auto tempKernel = qcor::__internal__::create_composite("temp_control"); function_pointer(tempKernel, args...); auto ctrlKernel = qcor::__internal__::create_ctrl_u(); ctrlKernel->expand({ std::make_pair("U", tempKernel), std::make_pair("control-idx", ctrl_qbit), }); for (int instId = 0; instId < ctrlKernel->nInstructions(); ++instId) { ir->addInstruction(ctrlKernel->getInstruction(instId)->clone()); } ::quantum::set_current_program(ir); } void ctrl(std::shared_ptr<xacc::CompositeInstruction> ir, qubit ctrl_qbit, Args... args) { int ctrl_bit = (int)ctrl_qbit.second; ctrl(ir, ctrl_bit, args...); } void adjoint(std::shared_ptr<CompositeInstruction> ir, Args... args) { auto tempKernel = qcor::__internal__::create_composite("temp_adjoint"); function_pointer(tempKernel, args...); // get the instructions auto instructions = tempKernel->getInstructions(); std::shared_ptr<CompositeInstruction> program = tempKernel; // Assert that we don't have measurement if (!std::all_of( instructions.cbegin(), instructions.cend(), [](const auto &inst) { return inst->name() != "Measure"; })) { error( "Unable to create Adjoint for kernels that have Measure operations."); } auto provider = qcor::__internal__::get_provider(); for (int i = 0; i < instructions.size(); i++) { auto inst = tempKernel->getInstruction(i); // Parametric gates: if (inst->name() == "Rx" || inst->name() == "Ry" || inst->name() == "Rz" || inst->name() == "CPHASE" || inst->name() == "U1" || inst->name() == "CRZ") { inst->setParameter(0, -inst->getParameter(0).template as<double>()); } // Handles T and S gates, etc... => T -> Tdg else if (inst->name() == "T") { auto tdg = provider->createInstruction("Tdg", inst->bits()); program->replaceInstruction(i, tdg); } else if (inst->name() == "S") { auto sdg = provider->createInstruction("Sdg", inst->bits()); program->replaceInstruction(i, sdg); } } // We update/replace instructions in the derived.parent_kernel composite, // hence collecting these new instructions and reversing the sequence. auto new_instructions = tempKernel->getInstructions(); std::reverse(new_instructions.begin(), new_instructions.end()); // add the instructions to the current parent kernel ir->addInstructions(new_instructions); ::quantum::set_current_program(ir); } }; } // namespace qcor runtime/qrt/impls/ftqc/ftqc_qrt.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ class FTQC : public quantum::QuantumRuntime { void __begin_mark_segment_as_compute() override { mark_as_compute = true; } void __end_mark_segment_as_compute() override { mark_as_compute = false; } bool isComputeSection() override { return mark_as_compute; } const std::string name() const override { return "ftqc"; } const std::string description() const override { return ""; } Loading runtime/qrt/impls/nisq/nisq_qrt.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,9 @@ class NISQ : public ::quantum::QuantumRuntime, void __begin_mark_segment_as_compute() override { mark_as_compute = true; } void __end_mark_segment_as_compute() override { mark_as_compute = false; } bool isComputeSection() override { return mark_as_compute; } void h(const qubit &qidx) override { one_qubit_inst("H", qidx); } void x(const qubit &qidx) override { one_qubit_inst("X", qidx); } Loading runtime/qrt/qrt.hpp +2 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ public: virtual void initialize(const std::string kernel_name) = 0; virtual void __begin_mark_segment_as_compute() = 0; virtual void __end_mark_segment_as_compute() = 0; virtual bool isComputeSection() = 0; virtual void h(const qubit &qidx) = 0; virtual void x(const qubit &qidx) = 0; Loading Loading
mlir/parsers/qasm3/examples/qpe.qasm +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ for i in [0:n_counting] { } // Run inverse QFT iqf2 counting; iqft counting; // Now lets measure the counting qubits bit c[n_counting]; Loading
runtime/kernel/quantum_kernel.hpp +103 −96 Original line number Diff line number Diff line Loading @@ -343,98 +343,6 @@ class QuantumKernel { virtual ~QuantumKernel() {} }; template <typename... Args> using callable_function_ptr = void (*)(std::shared_ptr<xacc::CompositeInstruction>, Args...); template <typename... Args> class KernelSignature { protected: callable_function_ptr<Args...> &function_pointer; public: KernelSignature(callable_function_ptr<Args...> &&f) : function_pointer(f) {} // Ctor from raw void* funtion pointer. // IMPORTANT: since function_pointer is kept as a *reference*, // we must keep a reference to the original f_ptr void* as well. KernelSignature(void *&f_ptr) : function_pointer((callable_function_ptr<Args...> &)f_ptr) {} void operator()(std::shared_ptr<xacc::CompositeInstruction> ir, Args... args) { function_pointer(ir, args...); } void ctrl(std::shared_ptr<xacc::CompositeInstruction> ir, int ctrl_qbit, Args... args) { auto tempKernel = qcor::__internal__::create_composite("temp_control"); function_pointer(tempKernel, args...); auto ctrlKernel = qcor::__internal__::create_ctrl_u(); ctrlKernel->expand({ std::make_pair("U", tempKernel), std::make_pair("control-idx", ctrl_qbit), }); for (int instId = 0; instId < ctrlKernel->nInstructions(); ++instId) { ir->addInstruction(ctrlKernel->getInstruction(instId)->clone()); } ::quantum::set_current_program(ir); } void ctrl(std::shared_ptr<xacc::CompositeInstruction> ir, qubit ctrl_qbit, Args... args) { int ctrl_bit = (int)ctrl_qbit.second; ctrl(ir, ctrl_bit, args...); } void adjoint(std::shared_ptr<CompositeInstruction> ir, Args... args) { auto tempKernel = qcor::__internal__::create_composite("temp_adjoint"); function_pointer(tempKernel, args...); // get the instructions auto instructions = tempKernel->getInstructions(); std::shared_ptr<CompositeInstruction> program = tempKernel; // Assert that we don't have measurement if (!std::all_of( instructions.cbegin(), instructions.cend(), [](const auto &inst) { return inst->name() != "Measure"; })) { error( "Unable to create Adjoint for kernels that have Measure operations."); } auto provider = qcor::__internal__::get_provider(); for (int i = 0; i < instructions.size(); i++) { auto inst = tempKernel->getInstruction(i); // Parametric gates: if (inst->name() == "Rx" || inst->name() == "Ry" || inst->name() == "Rz" || inst->name() == "CPHASE" || inst->name() == "U1" || inst->name() == "CRZ") { inst->setParameter(0, -inst->getParameter(0).template as<double>()); } // Handles T and S gates, etc... => T -> Tdg else if (inst->name() == "T") { auto tdg = provider->createInstruction("Tdg", inst->bits()); program->replaceInstruction(i, tdg); } else if (inst->name() == "S") { auto sdg = provider->createInstruction("Sdg", inst->bits()); program->replaceInstruction(i, sdg); } } // We update/replace instructions in the derived.parent_kernel composite, // hence collecting these new instructions and reversing the sequence. auto new_instructions = tempKernel->getInstructions(); std::reverse(new_instructions.begin(), new_instructions.end()); // add the instructions to the current parent kernel ir->addInstructions(new_instructions); ::quantum::set_current_program(ir); } }; // We use the following to enable ctrl operations on our single // qubit gates, X::ctrl(), Z::ctrl(), H::ctrl(), etc.... template <typename Derived> Loading @@ -456,7 +364,15 @@ using OneQubitKernel = QuantumKernel<Derived, qubit>; if (runtime_env == QrtType::FTQC) { \ quantum::set_current_buffer(q.results()); \ } \ bool cached_is_compute_section = \ ::quantum::qrt_impl->isComputeSection(); \ if (cached_is_compute_section) { \ ::quantum::qrt_impl->__end_mark_segment_as_compute(); \ } \ ::quantum::QRTNAME(q); \ if (cached_is_compute_section) { \ ::quantum::qrt_impl->__begin_mark_segment_as_compute(); \ } \ return; \ } \ virtual ~CLASSNAME() {} \ Loading Loading @@ -487,7 +403,6 @@ ONE_QUBIT_KERNEL_CTRL_ENABLER(Sdg, sdg) template <typename... CaptureArgs> class _qpu_lambda { private: // Private inner class for getting the type // of a capture variable as a string at runtime class TupleToTypeArgString { Loading Loading @@ -596,4 +511,96 @@ class _qpu_lambda { #define qpu_lambda(EXPR, ...) _qpu_lambda(#EXPR, #__VA_ARGS__, ##__VA_ARGS__) template <typename... Args> using callable_function_ptr = void (*)(std::shared_ptr<xacc::CompositeInstruction>, Args...); template <typename... Args> class KernelSignature { protected: callable_function_ptr<Args...> &function_pointer; public: KernelSignature(callable_function_ptr<Args...> &&f) : function_pointer(f) {} // Ctor from raw void* funtion pointer. // IMPORTANT: since function_pointer is kept as a *reference*, // we must keep a reference to the original f_ptr void* as well. KernelSignature(void *&f_ptr) : function_pointer((callable_function_ptr<Args...> &)f_ptr) {} void operator()(std::shared_ptr<xacc::CompositeInstruction> ir, Args... args) { function_pointer(ir, args...); } void ctrl(std::shared_ptr<xacc::CompositeInstruction> ir, int ctrl_qbit, Args... args) { auto tempKernel = qcor::__internal__::create_composite("temp_control"); function_pointer(tempKernel, args...); auto ctrlKernel = qcor::__internal__::create_ctrl_u(); ctrlKernel->expand({ std::make_pair("U", tempKernel), std::make_pair("control-idx", ctrl_qbit), }); for (int instId = 0; instId < ctrlKernel->nInstructions(); ++instId) { ir->addInstruction(ctrlKernel->getInstruction(instId)->clone()); } ::quantum::set_current_program(ir); } void ctrl(std::shared_ptr<xacc::CompositeInstruction> ir, qubit ctrl_qbit, Args... args) { int ctrl_bit = (int)ctrl_qbit.second; ctrl(ir, ctrl_bit, args...); } void adjoint(std::shared_ptr<CompositeInstruction> ir, Args... args) { auto tempKernel = qcor::__internal__::create_composite("temp_adjoint"); function_pointer(tempKernel, args...); // get the instructions auto instructions = tempKernel->getInstructions(); std::shared_ptr<CompositeInstruction> program = tempKernel; // Assert that we don't have measurement if (!std::all_of( instructions.cbegin(), instructions.cend(), [](const auto &inst) { return inst->name() != "Measure"; })) { error( "Unable to create Adjoint for kernels that have Measure operations."); } auto provider = qcor::__internal__::get_provider(); for (int i = 0; i < instructions.size(); i++) { auto inst = tempKernel->getInstruction(i); // Parametric gates: if (inst->name() == "Rx" || inst->name() == "Ry" || inst->name() == "Rz" || inst->name() == "CPHASE" || inst->name() == "U1" || inst->name() == "CRZ") { inst->setParameter(0, -inst->getParameter(0).template as<double>()); } // Handles T and S gates, etc... => T -> Tdg else if (inst->name() == "T") { auto tdg = provider->createInstruction("Tdg", inst->bits()); program->replaceInstruction(i, tdg); } else if (inst->name() == "S") { auto sdg = provider->createInstruction("Sdg", inst->bits()); program->replaceInstruction(i, sdg); } } // We update/replace instructions in the derived.parent_kernel composite, // hence collecting these new instructions and reversing the sequence. auto new_instructions = tempKernel->getInstructions(); std::reverse(new_instructions.begin(), new_instructions.end()); // add the instructions to the current parent kernel ir->addInstructions(new_instructions); ::quantum::set_current_program(ir); } }; } // namespace qcor
runtime/qrt/impls/ftqc/ftqc_qrt.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ class FTQC : public quantum::QuantumRuntime { void __begin_mark_segment_as_compute() override { mark_as_compute = true; } void __end_mark_segment_as_compute() override { mark_as_compute = false; } bool isComputeSection() override { return mark_as_compute; } const std::string name() const override { return "ftqc"; } const std::string description() const override { return ""; } Loading
runtime/qrt/impls/nisq/nisq_qrt.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,9 @@ class NISQ : public ::quantum::QuantumRuntime, void __begin_mark_segment_as_compute() override { mark_as_compute = true; } void __end_mark_segment_as_compute() override { mark_as_compute = false; } bool isComputeSection() override { return mark_as_compute; } void h(const qubit &qidx) override { one_qubit_inst("H", qidx); } void x(const qubit &qidx) override { one_qubit_inst("X", qidx); } Loading
runtime/qrt/qrt.hpp +2 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ public: virtual void initialize(const std::string kernel_name) = 0; virtual void __begin_mark_segment_as_compute() = 0; virtual void __end_mark_segment_as_compute() = 0; virtual bool isComputeSection() = 0; virtual void h(const qubit &qidx) = 0; virtual void x(const qubit &qidx) = 0; Loading