From d8c9a08250c59b6308c0b2a2efbd03dcfa17ea7f Mon Sep 17 00:00:00 2001
From: mbuchberger1967 <mail@markusbuchberger.de>
Date: Sun, 25 Jul 2021 09:38:15 +0000
Subject: [PATCH 1/5] fixed bug in ctor QubitRegister(Type *state)

---
 .gitignore                   |  2 ++
 include/alignedallocator.hpp | 23 +++++++++++++++++------
 include/qureg.hpp            | 22 +++++++++++-----------
 src/qureg_init.cpp           | 18 ++++++++++++++++++
 4 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/.gitignore b/.gitignore
index b6658a0c..df1396af 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,5 @@ docs/build
 venv
 docs/source/doxyoutput
 docs/source/api
+**/build/**
+**/bin/**
diff --git a/include/alignedallocator.hpp b/include/alignedallocator.hpp
index 810af991..ab2823ff 100644
--- a/include/alignedallocator.hpp
+++ b/include/alignedallocator.hpp
@@ -48,6 +48,8 @@ namespace iqs {
 template <typename T, unsigned int Alignment>
 class AlignedAllocator
 {
+ private:
+  T* memory_pointer;
  public:
 
   typedef T* pointer;
@@ -65,11 +67,13 @@ class AlignedAllocator
   };
 
   AlignedAllocator() noexcept {}
-  AlignedAllocator(AlignedAllocator const&) noexcept {}
+  AlignedAllocator(T* memory_ptr) noexcept { memory_pointer = memory_ptr; }
+  AlignedAllocator(AlignedAllocator const& other) noexcept { memory_pointer = other.memory_pointer; }
 
   template <typename U>
-  AlignedAllocator(AlignedAllocator<U, Alignment> const&) noexcept
+  AlignedAllocator(AlignedAllocator<U, Alignment> const& other) noexcept
   {
+    memory_pointer = other.memory_pointer;
   }
 
   pointer allocate(size_type n)
@@ -78,13 +82,18 @@ class AlignedAllocator
 
     static_assert(isPowerOf2(Alignment), "Alignment not a power of 2");
 
+    if ( memory_pointer != nullptr ) {
+      p = reinterpret_cast<pointer>(memory_pointer);
+    }
+    else {
 #ifdef _WIN32
-    p = reinterpret_cast<pointer>(_aligned_malloc(n * sizeof(T), Alignment));
-    if (p == 0) throw std::bad_alloc();
+      p = reinterpret_cast<pointer>(_aligned_malloc(n * sizeof(T), Alignment));
+      if (p == 0) throw std::bad_alloc();
 #else
-    if (posix_memalign(reinterpret_cast<void**>(&p), Alignment, n * sizeof(T)))
-      throw std::bad_alloc();
+      if (posix_memalign(reinterpret_cast<void**>(&p), Alignment, n * sizeof(T)))
+        throw std::bad_alloc();
 #endif
+    }
     return p;
   }
 
@@ -92,8 +101,10 @@ class AlignedAllocator
   {
 #ifdef _WIN32
     _aligned_free(p);
+//    std::cout << "_aligned_free: " << p << std::endl;
 #else
     std::free(p);
+//    std::cout << "std::free: " << p << std::endl;
 #endif
   }
 
diff --git a/include/qureg.hpp b/include/qureg.hpp
index 36a7737b..385211b6 100644
--- a/include/qureg.hpp
+++ b/include/qureg.hpp
@@ -375,22 +375,22 @@ class QubitRegister
   {assert(rng_ptr_); rng_ptr_->SetSeedStreamPtrs(seed); }
 
   // Members
-  std::size_t num_qubits;
+  std::size_t num_qubits = 0;
   std::vector<Type, iqs::AlignedAllocator<Type, 256>> state_storage;
-  Type *state;
-  Permutation *qubit_permutation;
-  Timer *timer;
-  GateCounter *gate_counter;	// Count how many gates acted on given program qubits.
-  std::size_t llc_watermarkbit;
-  bool imported_state;
-  bool specialize;
+  Type *state = nullptr;
+  Permutation *qubit_permutation = nullptr;
+  Timer *timer = nullptr;
+  GateCounter *gate_counter = nullptr;	// Count how many gates acted on given program qubits.
+  std::size_t llc_watermarkbit = 0;
+  bool imported_state = false;
+  bool specialize = false;
   bool specialize2 = false;
   // Related to the simulation of quantum channels:
   BaseType overall_sign_of_channels = 1;
 
   // temporary buffer for fusion
-  bool fusion;
-  unsigned log2llc;
+  bool fusion = false;
+  unsigned log2llc = 0;
   std::vector<std::tuple<std::string, TM2x2<Type>, unsigned, unsigned>> fwindow;
 
   // set option of printing more info.
@@ -413,7 +413,7 @@ class QubitRegister
 };
 
 template <typename Type>
-bool QubitRegister<Type>::do_print_extra_info = false;
+bool QubitRegister<Type>::do_print_extra_info = true;
 
 template <typename Type>
 using BaseType = typename QubitRegister<Type>::BaseType;
diff --git a/src/qureg_init.cpp b/src/qureg_init.cpp
index e6320eaf..1cef21a9 100644
--- a/src/qureg_init.cpp
+++ b/src/qureg_init.cpp
@@ -194,9 +194,27 @@ template <class Type>
 QubitRegister<Type>::QubitRegister(std::size_t new_num_qubits, Type *state, 
                                    std::size_t tmp_spacesize_)
 {
+  unsigned myrank=0, nprocs=1, num_ranks_per_node=1;
+  myrank = iqs::mpi::Environment::GetStateRank();
+  nprocs = iqs::mpi::Environment::GetStateSize();
+  num_ranks_per_node = iqs::mpi::Environment::GetNumRanksPerNode();
+
   imported_state = true;
   Initialize(new_num_qubits, tmp_spacesize_);
+
+#ifdef USE_MM_MALLOC
   this->state = state;
+#else
+  // create a temporary vector to use AlignedAllocator with prepared memory block
+  std::vector<Type, iqs::AlignedAllocator<Type, 256>> tmp_storage(0, iqs::AlignedAllocator<Type, 256>(state));
+
+  std::size_t num_amplitudes = (nprocs == 1) ? LocalSize() : (LocalSize() + TmpSize());
+  tmp_storage.resize(num_amplitudes);
+
+  // move that memory block into our state_storage
+  state_storage = std::move(tmp_storage);
+  this->state = &state_storage[0];
+#endif
 }
 
 

From 328a43d594ed7f086446508ad3a889f3180b25c4 Mon Sep 17 00:00:00 2001
From: mbuchberger1967 <mail@markusbuchberger.de>
Date: Sun, 25 Jul 2021 11:51:39 +0200
Subject: [PATCH 2/5] init memory_pointer

---
 include/alignedallocator.hpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/alignedallocator.hpp b/include/alignedallocator.hpp
index ab2823ff..30a45d93 100644
--- a/include/alignedallocator.hpp
+++ b/include/alignedallocator.hpp
@@ -49,7 +49,7 @@ template <typename T, unsigned int Alignment>
 class AlignedAllocator
 {
  private:
-  T* memory_pointer;
+  T* memory_pointer = nullptr_t;
  public:
 
   typedef T* pointer;

From d4bfae432ff751d6e339edb6364e81860a1b8d55 Mon Sep 17 00:00:00 2001
From: mbuchberger1967 <mail@markusbuchberger.de>
Date: Sun, 25 Jul 2021 09:54:52 +0000
Subject: [PATCH 3/5] init memory_pointer

---
 include/alignedallocator.hpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/alignedallocator.hpp b/include/alignedallocator.hpp
index 30a45d93..09c2fb32 100644
--- a/include/alignedallocator.hpp
+++ b/include/alignedallocator.hpp
@@ -49,7 +49,7 @@ template <typename T, unsigned int Alignment>
 class AlignedAllocator
 {
  private:
-  T* memory_pointer = nullptr_t;
+  T const* memory_pointer = nullptr;
  public:
 
   typedef T* pointer;

From ee443a043a06c82e32b25bced048082bc015ca7e Mon Sep 17 00:00:00 2001
From: mbuchberger1967 <mail@markusbuchberger.de>
Date: Sun, 25 Jul 2021 10:04:14 +0000
Subject: [PATCH 4/5] fixed const error

---
 include/alignedallocator.hpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/alignedallocator.hpp b/include/alignedallocator.hpp
index 09c2fb32..f88175a8 100644
--- a/include/alignedallocator.hpp
+++ b/include/alignedallocator.hpp
@@ -49,7 +49,7 @@ template <typename T, unsigned int Alignment>
 class AlignedAllocator
 {
  private:
-  T const* memory_pointer = nullptr;
+  T* memory_pointer = nullptr;
  public:
 
   typedef T* pointer;

From e6ab3d191c21537d61c90bf0b3cc921fb7b0e131 Mon Sep 17 00:00:00 2001
From: mbuchberger1967 <mail@markusbuchberger.de>
Date: Sun, 25 Jul 2021 10:17:48 +0000
Subject: [PATCH 5/5] reset do_print_extra_info = false

---
 include/qureg.hpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/qureg.hpp b/include/qureg.hpp
index 385211b6..10ec3453 100644
--- a/include/qureg.hpp
+++ b/include/qureg.hpp
@@ -413,7 +413,7 @@ class QubitRegister
 };
 
 template <typename Type>
-bool QubitRegister<Type>::do_print_extra_info = true;
+bool QubitRegister<Type>::do_print_extra_info = false;
 
 template <typename Type>
 using BaseType = typename QubitRegister<Type>::BaseType;
