Commit 52aa2745 authored by Nguyen, Thien Minh's avatar Nguyen, Thien Minh
Browse files

Hook ancilla qubits to submit calls



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent fcbce46e
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
// Generate a random bit string in an obscure way...
__qpu__ void test_random(qreg q) {
  for (int i = 0; i < q.size(); ++i) {
    // Allocate qubit:
    // This qubit should be reused...
    auto anc_reg = qalloc(1);
    H(anc_reg);
    // entangle each qubit in the register
    // -> reset anc => q[i] in random 0 or 1 state
    X::ctrl(anc_reg[0], q[i]);
    Reset(anc_reg[0]);
  }
  Measure(q);
}

int main(int argc, char **argv) {
  set_shots(1024);
  auto a = qalloc(8);
  test_random(a);
  a.print();
  return 0;
}
 No newline at end of file
+1 −5
Original line number Diff line number Diff line
@@ -212,10 +212,6 @@ class xasm_single_visitor : public xasm::xasm_singleVisitor {
        ss << origText << " ";
      }
    } else {
      // std::cout << "HOWDY: " << context->getText() << "\n";
      for (const auto &expr : context->exp()) {
        std::cout << expr->getText() << "\n";
      }
      if (context->var_value &&
          context->var_value->getText().find("qalloc") != std::string::npos) {
        // std::cout << "Qalloc encountered\n";
@@ -224,7 +220,7 @@ class xasm_single_visitor : public xasm::xasm_singleVisitor {
          qalloc_ss << c->getText() << " ";
        }
        std::string qalloc_call = qalloc_ss.str();
        std::cout << qalloc_call << "\n";
        // std::cout << qalloc_call << "\n";
        const auto close_pos = qalloc_call.find_last_of(")");
        qalloc_call.insert(close_pos, ", quantum::getAncillaQubitAllocator()");
        // std::cout << "After: " << qalloc_call << "\n";
+23 −7
Original line number Diff line number Diff line
@@ -22,12 +22,12 @@ class NisqQubitAllocator : public AllocEventListener, public QubitAllocator {
public:
  static inline const std::string ANC_BUFFER_NAME = "nisq_temp_buffer";
  virtual void onAllocate(qubit *in_qubit) override {
    std::cout << "Allocate: " << (void *)in_qubit << "\n";
    // std::cout << "Allocate: " << (void *)in_qubit << "\n";
  }

  // On deallocate: don't try to deref the qubit since it may have been gone.
  virtual void onDealloc(qubit *in_qubit) override {
    std::cout << "Deallocate: " << (void *)in_qubit << "\n";
    // std::cout << "Deallocate: " << (void *)in_qubit << "\n";
    // If this qubit was allocated from this pool:
    if (xacc::container::contains(m_allocatedQubits, in_qubit)) {
      const auto qIndex = std::find(m_allocatedQubits.begin(),
@@ -44,17 +44,16 @@ public:
  }

  virtual qubit allocate() override {
    std::cout << "Allocate\n";
    if (!m_qubitPool.empty()) {
      auto recycled_qubit = m_qubitPool.back();
      m_qubitPool.pop_back();
      return recycled_qubit;
    }

    if (!m_buffer) {
      // This must be the first call.
      assert(m_allocatedQubits.empty());
      m_buffer = xacc::qalloc(1);
      m_buffer->setName(ANC_BUFFER_NAME);
    }

    // Need to allocate new qubit:
@@ -75,6 +74,8 @@ public:
  }
  static NisqQubitAllocator *g_instance;

  std::shared_ptr<xacc::AcceleratorBuffer> get_buffer() { return m_buffer; }

private:
  std::vector<qubit> m_qubitPool;
  // Track the list of qubit pointers for those
@@ -403,10 +404,19 @@ class NISQ : public ::quantum::QuantumRuntime,

  void submit(xacc::AcceleratorBuffer *buffer) override {
    // xacc::internal_compiler::execute_pass_manager();
    auto anc_allocator = NisqQubitAllocator::getInstance();
    if (anc_allocator->get_buffer() &&
        anc_allocator->get_buffer()->size() > 0) {
      std::vector<xacc::AcceleratorBuffer *> buffer_list{
          buffer, anc_allocator->get_buffer().get()};
      submit(buffer_list.data(), buffer_list.size());
    } else {
      if (__print_final_submission) {
        std::cout << "SUBMIT:\n" << program->toString() << "\n";
      }
      xacc::internal_compiler::execute(buffer, program);
    }

    clearProgram();
  }

@@ -417,6 +427,12 @@ class NISQ : public ::quantum::QuantumRuntime,
    for (int i = 0; i < nBuffers; i++) {
      ptrs.insert(buffers[i]);
    }
    // Add the kernel-allocated temporary buffer if necessary:
    auto anc_allocator = NisqQubitAllocator::getInstance();
    if (anc_allocator->get_buffer() &&
        anc_allocator->get_buffer()->size() > 0) {
      ptrs.insert(anc_allocator->get_buffer().get());
    }
    // If size is 1 here, then we only have 
    // one pointer, like in the case of qubit.results()
    if (ptrs.size() == 1) {