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..f88175a8 100644 --- a/include/alignedallocator.hpp +++ b/include/alignedallocator.hpp @@ -48,6 +48,8 @@ namespace iqs { template class AlignedAllocator { + private: + T* memory_pointer = nullptr; 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 - AlignedAllocator(AlignedAllocator const&) noexcept + AlignedAllocator(AlignedAllocator 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(memory_pointer); + } + else { #ifdef _WIN32 - p = reinterpret_cast(_aligned_malloc(n * sizeof(T), Alignment)); - if (p == 0) throw std::bad_alloc(); + p = reinterpret_cast(_aligned_malloc(n * sizeof(T), Alignment)); + if (p == 0) throw std::bad_alloc(); #else - if (posix_memalign(reinterpret_cast(&p), Alignment, n * sizeof(T))) - throw std::bad_alloc(); + if (posix_memalign(reinterpret_cast(&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..10ec3453 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> 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, unsigned, unsigned>> fwindow; // set option of printing more info. 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 QubitRegister::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> tmp_storage(0, iqs::AlignedAllocator(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 }