Loading examples/qsharp/NISQ/import_kernel_utils.hpp +78 −74 Original line number Diff line number Diff line #pragma once // Helper macros to generate QCOR kernel wrapper for // external Q# kernel (compiled to QIR) #include "qir-types.hpp" #define STRINGIZE(arg) STRINGIZE1(arg) #define STRINGIZE1(arg) STRINGIZE2(arg) Loading @@ -10,27 +12,13 @@ #define CONCATENATE2(arg1, arg2) arg1##arg2 #define FOR_EACH_1(what, x, ...) what(x, 1) #define FOR_EACH_2(what, x, ...)\ what(x, 2)\ FOR_EACH_1(what, __VA_ARGS__) #define FOR_EACH_3(what, x, ...)\ what(x, 3)\ FOR_EACH_2(what, __VA_ARGS__) #define FOR_EACH_4(what, x, ...)\ what(x, 4)\ FOR_EACH_3(what, __VA_ARGS__) #define FOR_EACH_5(what, x, ...)\ what(x, 5)\ FOR_EACH_4(what, __VA_ARGS__) #define FOR_EACH_6(what, x, ...)\ what(x, 6)\ FOR_EACH_5(what, __VA_ARGS__) #define FOR_EACH_7(what, x, ...)\ what(x, 7)\ FOR_EACH_6(what, __VA_ARGS__) #define FOR_EACH_8(what, x, ...)\ what(x, 8)\ FOR_EACH_7(what, __VA_ARGS__) #define FOR_EACH_2(what, x, ...) what(x, 2) FOR_EACH_1(what, __VA_ARGS__) #define FOR_EACH_3(what, x, ...) what(x, 3) FOR_EACH_2(what, __VA_ARGS__) #define FOR_EACH_4(what, x, ...) what(x, 4) FOR_EACH_3(what, __VA_ARGS__) #define FOR_EACH_5(what, x, ...) what(x, 5) FOR_EACH_4(what, __VA_ARGS__) #define FOR_EACH_6(what, x, ...) what(x, 6) FOR_EACH_5(what, __VA_ARGS__) #define FOR_EACH_7(what, x, ...) what(x, 7) FOR_EACH_6(what, __VA_ARGS__) #define FOR_EACH_8(what, x, ...) what(x, 8) FOR_EACH_7(what, __VA_ARGS__) #define FOR_EACH_NARG(...) FOR_EACH_NARG_(__VA_ARGS__, FOR_EACH_RSEQ_N()) #define FOR_EACH_NARG_(...) FOR_EACH_ARG_N(__VA_ARGS__) Loading @@ -38,22 +26,28 @@ #define FOR_EACH_RSEQ_N() 8, 7, 6, 5, 4, 3, 2, 1, 0 #define FOR_EACH_(N, what, ...) CONCATENATE(FOR_EACH_, N)(what, __VA_ARGS__) #define FOR_EACH(what, ...) FOR_EACH_(FOR_EACH_NARG(__VA_ARGS__), what, __VA_ARGS__) #define FOR_EACH(what, ...) \ FOR_EACH_(FOR_EACH_NARG(__VA_ARGS__), what, __VA_ARGS__) #define CONSTRUCT_ARGS_LIST_(type_name, var_name) , type_name var_name #define CONSTRUCT_ARGS_LIST(type_name, counter) CONSTRUCT_ARGS_LIST_(type_name, __internal__var__##counter) #define CONSTRUCT_ARGS_LIST(type_name, counter) \ CONSTRUCT_ARGS_LIST_(type_name, __internal__var__##counter) #define CONSTRUCT_VAR_NAME_LIST(type_name, counter) , __internal__var__##counter // Macro to use to construct list of types and var names. #define ARGS_LIST_FOR_FUNC_SIGNATURE(...) FOR_EACH(CONSTRUCT_ARGS_LIST, __VA_ARGS__) #define ARGS_LIST_FOR_FUNC_INVOKE(...) FOR_EACH(CONSTRUCT_VAR_NAME_LIST, __VA_ARGS__) #define ARGS_LIST_FOR_FUNC_SIGNATURE(...) \ FOR_EACH(CONSTRUCT_ARGS_LIST, __VA_ARGS__) #define ARGS_LIST_FOR_FUNC_INVOKE(...) \ FOR_EACH(CONSTRUCT_VAR_NAME_LIST, __VA_ARGS__) #define qcor_import_qsharp_kernel(OPERATION_NAME, ...) \ extern "C" void OPERATION_NAME##__body(QReg *, __VA_ARGS__); \ class OPERATION_NAME : public qcor::QuantumKernel<class OPERATION_NAME, qreg, __VA_ARGS__> { \ extern "C" void OPERATION_NAME##__body(::Array *, __VA_ARGS__); \ class OPERATION_NAME \ : public qcor::QuantumKernel<class OPERATION_NAME, qreg, __VA_ARGS__> { \ private: \ std::deque<Qubit> m_qubits; \ ::Array *m_qubits = nullptr; \ friend class qcor::QuantumKernel<class OPERATION_NAME, qreg, __VA_ARGS__>; \ \ protected: \ void operator()(qreg q ARGS_LIST_FOR_FUNC_SIGNATURE(__VA_ARGS__)) { \ if (!parent_kernel) { \ Loading @@ -63,19 +57,30 @@ if (runtime_env == QrtType::FTQC) { \ quantum::set_current_buffer(q.results()); \ } \ QReg qReg; \ /* Convert the qreg to QIR Array of Qubits */ \ if (!m_qubits) { \ m_qubits = new ::Array(q.size()); \ for (int i = 0; i < q.size(); ++i) { \ m_qubits.push_back(i); \ qReg.emplace_back(&m_qubits.back()); \ auto qubit = Qubit::allocate(); \ int8_t *arrayPtr = (*m_qubits)[i]; \ auto qubitPtr = reinterpret_cast<Qubit **>(arrayPtr); \ *qubitPtr = qubit; \ } \ OPERATION_NAME##__body(&qReg ARGS_LIST_FOR_FUNC_INVOKE(__VA_ARGS__)); \ /* std::cout << "INVOKE:\n" << parent_kernel->toString(); */\ } \ OPERATION_NAME##__body(m_qubits ARGS_LIST_FOR_FUNC_INVOKE( \ __VA_ARGS__)); /* std::cout << "INVOKE:\n" << \ parent_kernel->toString(); */ \ } \ \ public: \ inline static const std::string kernel_name = #OPERATION_NAME; \ OPERATION_NAME(qreg q ARGS_LIST_FOR_FUNC_SIGNATURE(__VA_ARGS__)) : QuantumKernel<OPERATION_NAME, qreg, __VA_ARGS__>(q ARGS_LIST_FOR_FUNC_INVOKE(__VA_ARGS__)) {} \ OPERATION_NAME(std::shared_ptr<qcor::CompositeInstruction> _parent, qreg q ARGS_LIST_FOR_FUNC_SIGNATURE(__VA_ARGS__)) \ : QuantumKernel<OPERATION_NAME, qreg, __VA_ARGS__>(_parent, q ARGS_LIST_FOR_FUNC_INVOKE(__VA_ARGS__)) {} \ OPERATION_NAME(qreg q ARGS_LIST_FOR_FUNC_SIGNATURE(__VA_ARGS__)) \ : QuantumKernel<OPERATION_NAME, qreg, __VA_ARGS__>( \ q ARGS_LIST_FOR_FUNC_INVOKE(__VA_ARGS__)) {} \ OPERATION_NAME(std::shared_ptr<qcor::CompositeInstruction> _parent, \ qreg q ARGS_LIST_FOR_FUNC_SIGNATURE(__VA_ARGS__)) \ : QuantumKernel<OPERATION_NAME, qreg, __VA_ARGS__>( \ _parent, q ARGS_LIST_FOR_FUNC_INVOKE(__VA_ARGS__)) {} \ virtual ~OPERATION_NAME() { \ if (disable_destructor) { \ return; \ Loading @@ -98,4 +103,3 @@ // void MyQsharpKernel(qreg, double, int); // which can be used in QCOR, e.g. supporting NISQ remote submit API // and runtime pass manager, etc. examples/qsharp/NISQ/kernel_nisq_driver.cpp +4 −6 Original line number Diff line number Diff line Loading @@ -3,8 +3,6 @@ #include "qcor.hpp" #include "import_kernel_utils.hpp" using Qubit = uint64_t; using QReg = std::vector<Qubit*>; // Util pre-processor to wrap Q# operation in a QCOR QuantumKernel. qcor_import_qsharp_kernel(QCOR__TestKernel, double); Loading @@ -17,13 +15,13 @@ qcor_import_qsharp_kernel(QCOR__TestKernel, double); int main() { auto q = qalloc(3); qcor::set_verbose(true); // QCOR__TestKernel(q, 1.0); // q.print(); QCOR__TestKernel(q, 1.0); q.print(); // Integrate w/ QCOR's kernel utility... // e.g. kernel print-out... std::cout << "HELLO:\n"; QCOR__TestKernel::print_kernel(std::cout, q, M_PI/4); // std::cout << "HELLO:\n"; // QCOR__TestKernel::print_kernel(std::cout, q, M_PI/4); return 0; } No newline at end of file mlir/qir_qrt/CMakeLists.txt +3 −0 Original line number Diff line number Diff line file(GLOB SRC *.cpp) file(GLOB HEADERS qir-types.hpp qir-qrt.hpp) add_library(qir-qrt SHARED ${SRC}) #target_include_directories( Loading @@ -6,6 +8,7 @@ add_library(qir-qrt SHARED ${SRC}) # PUBLIC . ${CMAKE_SOURCE_DIR}/runtime/qrt ${XACC_ROOT}/include/cppmicroservices4 ${XACC_ROOT}/include/xacc ${XACC_ROOT}/include/qcor ${XACC_ROOT}/include/eigen ${XACC_ROOT}/include/quantum/gate) target_link_libraries(qir-qrt PRIVATE xacc::xacc qcor qrt) install (TARGETS qir-qrt DESTINATION lib) install(FILES ${HEADERS} DESTINATION include/qcor) if (QCOR_BUILD_TESTS) add_subdirectory(tests) Loading Loading
examples/qsharp/NISQ/import_kernel_utils.hpp +78 −74 Original line number Diff line number Diff line #pragma once // Helper macros to generate QCOR kernel wrapper for // external Q# kernel (compiled to QIR) #include "qir-types.hpp" #define STRINGIZE(arg) STRINGIZE1(arg) #define STRINGIZE1(arg) STRINGIZE2(arg) Loading @@ -10,27 +12,13 @@ #define CONCATENATE2(arg1, arg2) arg1##arg2 #define FOR_EACH_1(what, x, ...) what(x, 1) #define FOR_EACH_2(what, x, ...)\ what(x, 2)\ FOR_EACH_1(what, __VA_ARGS__) #define FOR_EACH_3(what, x, ...)\ what(x, 3)\ FOR_EACH_2(what, __VA_ARGS__) #define FOR_EACH_4(what, x, ...)\ what(x, 4)\ FOR_EACH_3(what, __VA_ARGS__) #define FOR_EACH_5(what, x, ...)\ what(x, 5)\ FOR_EACH_4(what, __VA_ARGS__) #define FOR_EACH_6(what, x, ...)\ what(x, 6)\ FOR_EACH_5(what, __VA_ARGS__) #define FOR_EACH_7(what, x, ...)\ what(x, 7)\ FOR_EACH_6(what, __VA_ARGS__) #define FOR_EACH_8(what, x, ...)\ what(x, 8)\ FOR_EACH_7(what, __VA_ARGS__) #define FOR_EACH_2(what, x, ...) what(x, 2) FOR_EACH_1(what, __VA_ARGS__) #define FOR_EACH_3(what, x, ...) what(x, 3) FOR_EACH_2(what, __VA_ARGS__) #define FOR_EACH_4(what, x, ...) what(x, 4) FOR_EACH_3(what, __VA_ARGS__) #define FOR_EACH_5(what, x, ...) what(x, 5) FOR_EACH_4(what, __VA_ARGS__) #define FOR_EACH_6(what, x, ...) what(x, 6) FOR_EACH_5(what, __VA_ARGS__) #define FOR_EACH_7(what, x, ...) what(x, 7) FOR_EACH_6(what, __VA_ARGS__) #define FOR_EACH_8(what, x, ...) what(x, 8) FOR_EACH_7(what, __VA_ARGS__) #define FOR_EACH_NARG(...) FOR_EACH_NARG_(__VA_ARGS__, FOR_EACH_RSEQ_N()) #define FOR_EACH_NARG_(...) FOR_EACH_ARG_N(__VA_ARGS__) Loading @@ -38,22 +26,28 @@ #define FOR_EACH_RSEQ_N() 8, 7, 6, 5, 4, 3, 2, 1, 0 #define FOR_EACH_(N, what, ...) CONCATENATE(FOR_EACH_, N)(what, __VA_ARGS__) #define FOR_EACH(what, ...) FOR_EACH_(FOR_EACH_NARG(__VA_ARGS__), what, __VA_ARGS__) #define FOR_EACH(what, ...) \ FOR_EACH_(FOR_EACH_NARG(__VA_ARGS__), what, __VA_ARGS__) #define CONSTRUCT_ARGS_LIST_(type_name, var_name) , type_name var_name #define CONSTRUCT_ARGS_LIST(type_name, counter) CONSTRUCT_ARGS_LIST_(type_name, __internal__var__##counter) #define CONSTRUCT_ARGS_LIST(type_name, counter) \ CONSTRUCT_ARGS_LIST_(type_name, __internal__var__##counter) #define CONSTRUCT_VAR_NAME_LIST(type_name, counter) , __internal__var__##counter // Macro to use to construct list of types and var names. #define ARGS_LIST_FOR_FUNC_SIGNATURE(...) FOR_EACH(CONSTRUCT_ARGS_LIST, __VA_ARGS__) #define ARGS_LIST_FOR_FUNC_INVOKE(...) FOR_EACH(CONSTRUCT_VAR_NAME_LIST, __VA_ARGS__) #define ARGS_LIST_FOR_FUNC_SIGNATURE(...) \ FOR_EACH(CONSTRUCT_ARGS_LIST, __VA_ARGS__) #define ARGS_LIST_FOR_FUNC_INVOKE(...) \ FOR_EACH(CONSTRUCT_VAR_NAME_LIST, __VA_ARGS__) #define qcor_import_qsharp_kernel(OPERATION_NAME, ...) \ extern "C" void OPERATION_NAME##__body(QReg *, __VA_ARGS__); \ class OPERATION_NAME : public qcor::QuantumKernel<class OPERATION_NAME, qreg, __VA_ARGS__> { \ extern "C" void OPERATION_NAME##__body(::Array *, __VA_ARGS__); \ class OPERATION_NAME \ : public qcor::QuantumKernel<class OPERATION_NAME, qreg, __VA_ARGS__> { \ private: \ std::deque<Qubit> m_qubits; \ ::Array *m_qubits = nullptr; \ friend class qcor::QuantumKernel<class OPERATION_NAME, qreg, __VA_ARGS__>; \ \ protected: \ void operator()(qreg q ARGS_LIST_FOR_FUNC_SIGNATURE(__VA_ARGS__)) { \ if (!parent_kernel) { \ Loading @@ -63,19 +57,30 @@ if (runtime_env == QrtType::FTQC) { \ quantum::set_current_buffer(q.results()); \ } \ QReg qReg; \ /* Convert the qreg to QIR Array of Qubits */ \ if (!m_qubits) { \ m_qubits = new ::Array(q.size()); \ for (int i = 0; i < q.size(); ++i) { \ m_qubits.push_back(i); \ qReg.emplace_back(&m_qubits.back()); \ auto qubit = Qubit::allocate(); \ int8_t *arrayPtr = (*m_qubits)[i]; \ auto qubitPtr = reinterpret_cast<Qubit **>(arrayPtr); \ *qubitPtr = qubit; \ } \ OPERATION_NAME##__body(&qReg ARGS_LIST_FOR_FUNC_INVOKE(__VA_ARGS__)); \ /* std::cout << "INVOKE:\n" << parent_kernel->toString(); */\ } \ OPERATION_NAME##__body(m_qubits ARGS_LIST_FOR_FUNC_INVOKE( \ __VA_ARGS__)); /* std::cout << "INVOKE:\n" << \ parent_kernel->toString(); */ \ } \ \ public: \ inline static const std::string kernel_name = #OPERATION_NAME; \ OPERATION_NAME(qreg q ARGS_LIST_FOR_FUNC_SIGNATURE(__VA_ARGS__)) : QuantumKernel<OPERATION_NAME, qreg, __VA_ARGS__>(q ARGS_LIST_FOR_FUNC_INVOKE(__VA_ARGS__)) {} \ OPERATION_NAME(std::shared_ptr<qcor::CompositeInstruction> _parent, qreg q ARGS_LIST_FOR_FUNC_SIGNATURE(__VA_ARGS__)) \ : QuantumKernel<OPERATION_NAME, qreg, __VA_ARGS__>(_parent, q ARGS_LIST_FOR_FUNC_INVOKE(__VA_ARGS__)) {} \ OPERATION_NAME(qreg q ARGS_LIST_FOR_FUNC_SIGNATURE(__VA_ARGS__)) \ : QuantumKernel<OPERATION_NAME, qreg, __VA_ARGS__>( \ q ARGS_LIST_FOR_FUNC_INVOKE(__VA_ARGS__)) {} \ OPERATION_NAME(std::shared_ptr<qcor::CompositeInstruction> _parent, \ qreg q ARGS_LIST_FOR_FUNC_SIGNATURE(__VA_ARGS__)) \ : QuantumKernel<OPERATION_NAME, qreg, __VA_ARGS__>( \ _parent, q ARGS_LIST_FOR_FUNC_INVOKE(__VA_ARGS__)) {} \ virtual ~OPERATION_NAME() { \ if (disable_destructor) { \ return; \ Loading @@ -98,4 +103,3 @@ // void MyQsharpKernel(qreg, double, int); // which can be used in QCOR, e.g. supporting NISQ remote submit API // and runtime pass manager, etc.
examples/qsharp/NISQ/kernel_nisq_driver.cpp +4 −6 Original line number Diff line number Diff line Loading @@ -3,8 +3,6 @@ #include "qcor.hpp" #include "import_kernel_utils.hpp" using Qubit = uint64_t; using QReg = std::vector<Qubit*>; // Util pre-processor to wrap Q# operation in a QCOR QuantumKernel. qcor_import_qsharp_kernel(QCOR__TestKernel, double); Loading @@ -17,13 +15,13 @@ qcor_import_qsharp_kernel(QCOR__TestKernel, double); int main() { auto q = qalloc(3); qcor::set_verbose(true); // QCOR__TestKernel(q, 1.0); // q.print(); QCOR__TestKernel(q, 1.0); q.print(); // Integrate w/ QCOR's kernel utility... // e.g. kernel print-out... std::cout << "HELLO:\n"; QCOR__TestKernel::print_kernel(std::cout, q, M_PI/4); // std::cout << "HELLO:\n"; // QCOR__TestKernel::print_kernel(std::cout, q, M_PI/4); return 0; } No newline at end of file
mlir/qir_qrt/CMakeLists.txt +3 −0 Original line number Diff line number Diff line file(GLOB SRC *.cpp) file(GLOB HEADERS qir-types.hpp qir-qrt.hpp) add_library(qir-qrt SHARED ${SRC}) #target_include_directories( Loading @@ -6,6 +8,7 @@ add_library(qir-qrt SHARED ${SRC}) # PUBLIC . ${CMAKE_SOURCE_DIR}/runtime/qrt ${XACC_ROOT}/include/cppmicroservices4 ${XACC_ROOT}/include/xacc ${XACC_ROOT}/include/qcor ${XACC_ROOT}/include/eigen ${XACC_ROOT}/include/quantum/gate) target_link_libraries(qir-qrt PRIVATE xacc::xacc qcor qrt) install (TARGETS qir-qrt DESTINATION lib) install(FILES ${HEADERS} DESTINATION include/qcor) if (QCOR_BUILD_TESTS) add_subdirectory(tests) Loading