Loading mlir/qir_qrt/CMakeLists.txt +5 −1 Original line number Diff line number Diff line Loading @@ -5,3 +5,7 @@ add_library(qir-qrt SHARED qir-qrt.cpp) # 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) if (QCOR_BUILD_TESTS) add_subdirectory(tests) endif() No newline at end of file mlir/qir_qrt/qir-qrt.cpp +30 −28 Original line number Diff line number Diff line Loading @@ -145,52 +145,52 @@ void __quantum__rt__set_external_qreg(qreg* q) { } void __quantum__qis__cnot(Qubit* src, Qubit* tgt) { std::size_t src_copy = reinterpret_cast<std::size_t>(src); std::size_t tgt_copy = reinterpret_cast<std::size_t>(tgt); std::size_t src_copy = src->id; std::size_t tgt_copy = tgt->id; if (verbose) printf("[qir-qrt] Applying CX %lu, %lu\n", src_copy, tgt_copy); ::quantum::cnot({"q", src_copy}, {"q", tgt_copy}); } void __quantum__qis__h(Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying H %lu\n", qcopy); ::quantum::h({"q", qcopy}); } void __quantum__qis__s(Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying S %lu\n", qcopy); ::quantum::s({"q", qcopy}); } void __quantum__qis__sdg(Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying Sdg %lu\n", qcopy); ::quantum::sdg({"q", qcopy}); } void __quantum__qis__t(Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying T %lu\n", qcopy); ::quantum::t({"q", qcopy}); } void __quantum__qis__tdg(Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying Tdg %lu\n", qcopy); ::quantum::tdg({"q", qcopy}); } void __quantum__qis__x(Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying X %lu\n", qcopy); ::quantum::x({"q", qcopy}); } void __quantum__qis__y(Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying Y %lu\n", qcopy); ::quantum::y({"q", qcopy}); } void __quantum__qis__z(Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying Z %lu\n", qcopy); ::quantum::z({"q", qcopy}); } Loading @@ -202,34 +202,32 @@ void __quantum__qis__reset(Qubit* q) { } void __quantum__qis__rx(double x, Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying Rx(%f) %lu\n", x, qcopy); ::quantum::rx({"q", qcopy}, x); } void __quantum__qis__ry(double x, Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying Ry(%f) %lu\n", x, qcopy); ::quantum::ry({"q", qcopy}, x); } void __quantum__qis__rz(double x, Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying Rz(%f) %lu\n", x, qcopy); ::quantum::rz({"q", qcopy}, x); } void __quantum__qis__u3(double theta, double phi, double lambda, Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); if (verbose) printf("[qir-qrt] Applying U3(%f, %f, %f) %lu\n", theta, phi, lambda, qcopy); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying U3(%f, %f, %f) %lu\n", theta, phi, lambda, qcopy); ::quantum::u3({"q", qcopy}, theta, phi, lambda); } Result* __quantum__qis__mz(Qubit* q) { if (verbose) printf("[qir-qrt] Measuring qubit %lu\n", reinterpret_cast<std::size_t>(q)); std::size_t qcopy = reinterpret_cast<std::size_t>(q); printf("[qir-qrt] Measuring qubit %lu\n", q->id); std::size_t qcopy = q->id; if (!qbits) { qbits = std::make_shared<xacc::AcceleratorBuffer>(allocated_qbits); Loading @@ -247,9 +245,12 @@ Array* __quantum__rt__qubit_allocate_array(uint64_t size) { auto new_array = std::make_unique<Array>(size); for (uint64_t i = 0; i < size; i++) { auto qubit = new uint64_t; // Qubit("q", i); *qubit = i; (*new_array)[i] = reinterpret_cast<int8_t*>(qubit); auto qubit = new Qubit(i); int8_t *arrayPtr = (*new_array)[i]; // Sequence: Cast to arrayPtr to Qubit** auto qubitPtr = reinterpret_cast<Qubit **>(arrayPtr); // Then save the qubit *pointer* to the location. *qubitPtr = qubit; } allocated_qbits = size; Loading @@ -266,10 +267,9 @@ Array* __quantum__rt__qubit_allocate_array(uint64_t size) { int8_t* __quantum__rt__array_get_element_ptr_1d(Array* q, uint64_t idx) { Array &arr = *q; int8_t *ptr = arr[idx]; Qubit* qq = reinterpret_cast<Qubit*>(ptr); // Don't deref the underlying type since we don't know what it points to. if (verbose) printf("[qir-qrt] Returning qubit array element %lu, idx=%lu.\n", *qq, idx); printf("[qir-qrt] Returning array element at idx=%lu.\n", idx); return ptr; } Loading @@ -282,7 +282,9 @@ void __quantum__rt__qubit_release_array(Array* q) { printf("[qir-qrt] deallocating the qubit array of size %lu\n", array_size); for (int k = 0; k < array_size; k++) { delete (*array_ptr)[k]; int8_t *arrayPtr = (*array_ptr)[k]; Qubit *qubitPtr = *(reinterpret_cast<Qubit **>(arrayPtr)); delete qubitPtr; } array_ptr->clear(); } Loading mlir/qir_qrt/qir-qrt.hpp +1 −8 Original line number Diff line number Diff line #include <memory> #include <vector> #include "qalloc.hpp" #include "qir-types.hpp" extern "C" { // FIXME - Qubit should be a struct that keeps track of idx // qreg name, array it comes from, and associated accelerator buffer using Qubit = uint64_t; using Result = bool; using Array = std::vector<int8_t*>; using TupleHeader = int *; using qreg = xacc::internal_compiler::qreg; extern Result ResultZero; Loading mlir/qir_qrt/qir-types.hpp 0 → 100644 +43 −0 Original line number Diff line number Diff line #include <cassert> // Defines implementations of QIR Opaque types // FIXME - Qubit should be a struct that keeps track of idx // qreg name, array it comes from, and associated accelerator buffer // Make this a struct now so that we can upgrade the API later // more easily. struct Qubit { uint64_t id; operator int() const { return id; } Qubit(uint64_t idVal) : id(idVal) {} }; using Result = bool; struct Array { // Vector of bytes using Storage = std::vector<int8_t>; int8_t *getItemPointer(int64_t index) { assert(index >= 0); assert(static_cast<uint64_t>(index * m_itemSizeInBytes) < m_storage.size()); return &m_storage.at(index * m_itemSizeInBytes); } int8_t *operator[](int64_t index) { return getItemPointer(index); } // Ctors // Default items are pointers. Array(int64_t nbItems, int itemSizeInBytes = sizeof(int8_t *)) : m_itemSizeInBytes(itemSizeInBytes), // Initialized to zero m_storage(nbItems * itemSizeInBytes, 0) { assert(m_itemSizeInBytes > 0); }; int64_t size() { return m_storage.size() / m_itemSizeInBytes; } void clear() { m_storage.clear(); } private: // Must be const, i.e. changing the element size is NOT allowed. const int m_itemSizeInBytes; Storage m_storage; }; using TupleHeader = int *; mlir/qir_qrt/tests/CMakeLists.txt 0 → 100644 +8 −0 Original line number Diff line number Diff line link_directories(${XACC_ROOT}/lib) add_executable(QirQrtTester QirQrtTester.cpp) add_test(NAME qcor_QirQrtTester COMMAND QirQrtTester) target_include_directories(QirQrtTester PRIVATE . .. ${CMAKE_BINARY_DIR} ${XACC_ROOT}/include/gtest) target_link_libraries(QirQrtTester ${XACC_TEST_LIBRARIES} xacc::xacc qir-qrt qrt) # Test compile a QASM -> QIR lowering add_test(NAME mlir_qrt_compile COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/bell_qasm.qasm) No newline at end of file Loading
mlir/qir_qrt/CMakeLists.txt +5 −1 Original line number Diff line number Diff line Loading @@ -5,3 +5,7 @@ add_library(qir-qrt SHARED qir-qrt.cpp) # 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) if (QCOR_BUILD_TESTS) add_subdirectory(tests) endif() No newline at end of file
mlir/qir_qrt/qir-qrt.cpp +30 −28 Original line number Diff line number Diff line Loading @@ -145,52 +145,52 @@ void __quantum__rt__set_external_qreg(qreg* q) { } void __quantum__qis__cnot(Qubit* src, Qubit* tgt) { std::size_t src_copy = reinterpret_cast<std::size_t>(src); std::size_t tgt_copy = reinterpret_cast<std::size_t>(tgt); std::size_t src_copy = src->id; std::size_t tgt_copy = tgt->id; if (verbose) printf("[qir-qrt] Applying CX %lu, %lu\n", src_copy, tgt_copy); ::quantum::cnot({"q", src_copy}, {"q", tgt_copy}); } void __quantum__qis__h(Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying H %lu\n", qcopy); ::quantum::h({"q", qcopy}); } void __quantum__qis__s(Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying S %lu\n", qcopy); ::quantum::s({"q", qcopy}); } void __quantum__qis__sdg(Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying Sdg %lu\n", qcopy); ::quantum::sdg({"q", qcopy}); } void __quantum__qis__t(Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying T %lu\n", qcopy); ::quantum::t({"q", qcopy}); } void __quantum__qis__tdg(Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying Tdg %lu\n", qcopy); ::quantum::tdg({"q", qcopy}); } void __quantum__qis__x(Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying X %lu\n", qcopy); ::quantum::x({"q", qcopy}); } void __quantum__qis__y(Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying Y %lu\n", qcopy); ::quantum::y({"q", qcopy}); } void __quantum__qis__z(Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying Z %lu\n", qcopy); ::quantum::z({"q", qcopy}); } Loading @@ -202,34 +202,32 @@ void __quantum__qis__reset(Qubit* q) { } void __quantum__qis__rx(double x, Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying Rx(%f) %lu\n", x, qcopy); ::quantum::rx({"q", qcopy}, x); } void __quantum__qis__ry(double x, Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying Ry(%f) %lu\n", x, qcopy); ::quantum::ry({"q", qcopy}, x); } void __quantum__qis__rz(double x, Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying Rz(%f) %lu\n", x, qcopy); ::quantum::rz({"q", qcopy}, x); } void __quantum__qis__u3(double theta, double phi, double lambda, Qubit* q) { std::size_t qcopy = reinterpret_cast<std::size_t>(q); if (verbose) printf("[qir-qrt] Applying U3(%f, %f, %f) %lu\n", theta, phi, lambda, qcopy); std::size_t qcopy = q->id; if (verbose) printf("[qir-qrt] Applying U3(%f, %f, %f) %lu\n", theta, phi, lambda, qcopy); ::quantum::u3({"q", qcopy}, theta, phi, lambda); } Result* __quantum__qis__mz(Qubit* q) { if (verbose) printf("[qir-qrt] Measuring qubit %lu\n", reinterpret_cast<std::size_t>(q)); std::size_t qcopy = reinterpret_cast<std::size_t>(q); printf("[qir-qrt] Measuring qubit %lu\n", q->id); std::size_t qcopy = q->id; if (!qbits) { qbits = std::make_shared<xacc::AcceleratorBuffer>(allocated_qbits); Loading @@ -247,9 +245,12 @@ Array* __quantum__rt__qubit_allocate_array(uint64_t size) { auto new_array = std::make_unique<Array>(size); for (uint64_t i = 0; i < size; i++) { auto qubit = new uint64_t; // Qubit("q", i); *qubit = i; (*new_array)[i] = reinterpret_cast<int8_t*>(qubit); auto qubit = new Qubit(i); int8_t *arrayPtr = (*new_array)[i]; // Sequence: Cast to arrayPtr to Qubit** auto qubitPtr = reinterpret_cast<Qubit **>(arrayPtr); // Then save the qubit *pointer* to the location. *qubitPtr = qubit; } allocated_qbits = size; Loading @@ -266,10 +267,9 @@ Array* __quantum__rt__qubit_allocate_array(uint64_t size) { int8_t* __quantum__rt__array_get_element_ptr_1d(Array* q, uint64_t idx) { Array &arr = *q; int8_t *ptr = arr[idx]; Qubit* qq = reinterpret_cast<Qubit*>(ptr); // Don't deref the underlying type since we don't know what it points to. if (verbose) printf("[qir-qrt] Returning qubit array element %lu, idx=%lu.\n", *qq, idx); printf("[qir-qrt] Returning array element at idx=%lu.\n", idx); return ptr; } Loading @@ -282,7 +282,9 @@ void __quantum__rt__qubit_release_array(Array* q) { printf("[qir-qrt] deallocating the qubit array of size %lu\n", array_size); for (int k = 0; k < array_size; k++) { delete (*array_ptr)[k]; int8_t *arrayPtr = (*array_ptr)[k]; Qubit *qubitPtr = *(reinterpret_cast<Qubit **>(arrayPtr)); delete qubitPtr; } array_ptr->clear(); } Loading
mlir/qir_qrt/qir-qrt.hpp +1 −8 Original line number Diff line number Diff line #include <memory> #include <vector> #include "qalloc.hpp" #include "qir-types.hpp" extern "C" { // FIXME - Qubit should be a struct that keeps track of idx // qreg name, array it comes from, and associated accelerator buffer using Qubit = uint64_t; using Result = bool; using Array = std::vector<int8_t*>; using TupleHeader = int *; using qreg = xacc::internal_compiler::qreg; extern Result ResultZero; Loading
mlir/qir_qrt/qir-types.hpp 0 → 100644 +43 −0 Original line number Diff line number Diff line #include <cassert> // Defines implementations of QIR Opaque types // FIXME - Qubit should be a struct that keeps track of idx // qreg name, array it comes from, and associated accelerator buffer // Make this a struct now so that we can upgrade the API later // more easily. struct Qubit { uint64_t id; operator int() const { return id; } Qubit(uint64_t idVal) : id(idVal) {} }; using Result = bool; struct Array { // Vector of bytes using Storage = std::vector<int8_t>; int8_t *getItemPointer(int64_t index) { assert(index >= 0); assert(static_cast<uint64_t>(index * m_itemSizeInBytes) < m_storage.size()); return &m_storage.at(index * m_itemSizeInBytes); } int8_t *operator[](int64_t index) { return getItemPointer(index); } // Ctors // Default items are pointers. Array(int64_t nbItems, int itemSizeInBytes = sizeof(int8_t *)) : m_itemSizeInBytes(itemSizeInBytes), // Initialized to zero m_storage(nbItems * itemSizeInBytes, 0) { assert(m_itemSizeInBytes > 0); }; int64_t size() { return m_storage.size() / m_itemSizeInBytes; } void clear() { m_storage.clear(); } private: // Must be const, i.e. changing the element size is NOT allowed. const int m_itemSizeInBytes; Storage m_storage; }; using TupleHeader = int *;
mlir/qir_qrt/tests/CMakeLists.txt 0 → 100644 +8 −0 Original line number Diff line number Diff line link_directories(${XACC_ROOT}/lib) add_executable(QirQrtTester QirQrtTester.cpp) add_test(NAME qcor_QirQrtTester COMMAND QirQrtTester) target_include_directories(QirQrtTester PRIVATE . .. ${CMAKE_BINARY_DIR} ${XACC_ROOT}/include/gtest) target_link_libraries(QirQrtTester ${XACC_TEST_LIBRARIES} xacc::xacc qir-qrt qrt) # Test compile a QASM -> QIR lowering add_test(NAME mlir_qrt_compile COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/bell_qasm.qasm) No newline at end of file