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

Add array ref count



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent 97310af3
Loading
Loading
Loading
Loading
+21 −5
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@

#include <cassert>
#include <stdexcept>
#include <atomic>
// Defines implementations of QIR Opaque types

// FIXME - Qubit should be a struct that keeps track of idx
@@ -41,13 +42,15 @@ struct Array {
  Array(int64_t nbItems, int itemSizeInBytes = sizeof(int8_t *))
      : m_itemSizeInBytes(itemSizeInBytes),
        // Initialized to zero
        m_storage(nbItems * itemSizeInBytes, 0) {
        m_storage(nbItems * itemSizeInBytes, 0),
        m_refCount(1) {
    assert(m_itemSizeInBytes > 0);
  };
  // Copy
  // Copy ctor:
  // note: we copy the Storage vector, hence set ref count to 1
  Array(const Array &other)
      : m_itemSizeInBytes(other.m_itemSizeInBytes),
        m_storage(other.m_storage) {}
      : m_itemSizeInBytes(other.m_itemSizeInBytes), m_storage(other.m_storage),
        m_refCount(1) {}

  void append(const Array &other) {
    if (other.m_itemSizeInBytes != m_itemSizeInBytes) {
@@ -62,10 +65,23 @@ struct Array {
  void clear() { m_storage.clear(); }
  int64_t element_size() const { return m_itemSizeInBytes; }

  // Ref. counting:
  void add_ref() { m_refCount += 1; }
  // Release a single ref. 
  // Returns true if this Array should be deleted
  // if heap allocated (via new) 
  bool release_ref() {
    m_refCount -= 1;
    return (m_refCount == 0);
  }

  int ref_count() const { return m_refCount; }

private:
  // Must be const, i.e. changing the element size is NOT allowed.
  const int m_itemSizeInBytes;
  Storage m_storage;
  std::atomic<int> m_refCount;
};

enum Pauli : int8_t {
+31 −3
Original line number Diff line number Diff line
@@ -50,15 +50,39 @@ Array *quantum__rt__array_slice(Array *array, int32_t dim, Range range) {
}

void __quantum__rt__array_update_alias_count(Array *array, int64_t increment) {
  // TODO
  if (verbose)
    std::cout << "CALL: " << __PRETTY_FUNCTION__ << "\n";
  // Looks like alias count has no functional significance, hence ignored.
}

void __quantum__rt__array_update_reference_count(Array *aux, int64_t count) {
  // TODO
  // Spec:
  // Deallocates the array if the reference count becomes 0. 
  // The behavior is undefined if the reference count becomes negative. 
  // The call should be ignored if the given %Array* is a null pointer.  
  if (verbose)
    std::cout << "CALL: " << __PRETTY_FUNCTION__ << "\n";

  if (!aux) {
    // The call should be ignored if the given %Array* is a null pointer.
    return;
  }

  if (increment > 0) {
    for (int64_t i = 0; i < increment; ++i) {
      array->add_ref();
    }
  } else {
    for (int64_t i = 0; i < (-increment); ++i) {
      if (array->release_ref()) {
        // Deallocates the array if the reference count becomes 0. 
        if (verbose)
          std::cout << "Deallocates array.\n";
        delete array;
        return;
      }
    }
  }
}

// Returns the number of dimensions in the array.
@@ -71,6 +95,7 @@ int32_t __quantum__rt__array_get_dim(Array *array) {
int64_t __quantum__rt__array_get_size(Array *array, int32_t dim) {
  if (verbose)
    std::cout << "CALL: " << __PRETTY_FUNCTION__ << "\n";
  // We don't support multi-dimensional arrays (yet).
  return 0;
}

@@ -81,7 +106,10 @@ Array *__quantum__rt__array_copy(Array *array, bool forceNewInstance) {
  if (array && forceNewInstance) {
    return new Array(*array);
  }

  // Spec:
  // Returns the given array pointer (the first parameter), 
  // after increasing its reference count by 1. 
  array->add_ref();
  return array;
}