diff --git a/src/Simulation/Simulators/SparseSimulator/Native/SparseSimulator.h b/src/Simulation/Simulators/SparseSimulator/Native/SparseSimulator.h index aff67c6b7fd..ecdde7c5fe2 100644 --- a/src/Simulation/Simulators/SparseSimulator/Native/SparseSimulator.h +++ b/src/Simulation/Simulators/SparseSimulator/Native/SparseSimulator.h @@ -47,9 +47,18 @@ std::shared_ptr expand_wfn_helper(std::shared_ptr max_num_bits / 2) ? std::shared_ptr(new QuantumState(old_sim)): expand_wfn_helper(old_sim, nqubits); } +// Sparse simulator only stores non-zero coefficients of the quantum state. +// It has good performance only when the number of non-zero coefficients is low. +// If the number of non-zero coefficients is low, the number of qubits may be fairly large. +// Sparse simulator employs hashtable structure (by Malte Skarupke) to store non-zero coefficients. +// Keys are basis vectors represented by std::bitset<>. +// Values are non-zero amplitudes represented by std::complex. +// Zero amplitudes are simply not stored. +// Hashtable is reallocated and reconstructed on almost every gate. +// Reallocation is saved for some gates that can be performed in one round. class SparseSimulator { -public: +public: std::set operations_done; @@ -584,13 +593,16 @@ class SparseSimulator // as a phase/permutation gate // This means if an assert fails, it will fail // at some future point, not at the point of failure - #if NDEBUG + #if defined(NDEBUG) if (isAllZ) { _queued_operations.push_back(operation(OP::Assert, qubits, result)); + // In release mode we queue Z assertion and return. return; } #endif - // X or Y assertions require execution + // X or Y assertions require immediate execution. + // We also execute Z assertion immediately in debug mode + // to provide feedback at the point of failure. _execute_queued_ops(qubits, OP::PermuteLarge); _quantum_state->Assert(axes, qubits, result); } diff --git a/src/Simulation/Simulators/SparseSimulator/SparseSimulatorTests/SparseSimulatorTests.cpp b/src/Simulation/Simulators/SparseSimulator/SparseSimulatorTests/SparseSimulatorTests.cpp index c43956686e5..d3674644420 100644 --- a/src/Simulation/Simulators/SparseSimulator/SparseSimulatorTests/SparseSimulatorTests.cpp +++ b/src/Simulation/Simulators/SparseSimulator/SparseSimulatorTests/SparseSimulatorTests.cpp @@ -7,9 +7,6 @@ #include "TestHelpers.hpp" #include #include -#include // necessary for string conversions for logging -#include // necessary for string conversions for logging -#include // necessary for string conversions for logging using namespace Microsoft::VisualStudio::CppUnitTestFramework; using namespace Microsoft::Quantum::SPARSESIMULATOR; @@ -70,7 +67,7 @@ namespace SparseSimulatorTests uint64_t k = 0; qubit_label_type label1(0); qubit_label_type label2(1); - std::wstring_convert> converter; + for (i = 0; i < 500; i++){ k += i * i * i * i; uint64_t m = 0; @@ -78,7 +75,9 @@ namespace SparseSimulatorTests for (j = 0; j < 500; j++){ m += j * j * j * j; label2 = qubit_label_type(m); - Assert::AreEqual(k < m, label1 < label2, converter.from_bytes("Comparing " + std::to_string(k) + " to " + std::to_string(m) + "\n").c_str()); + wchar_t message[100]; + swprintf(message, sizeof(message)/sizeof(*message), L"Comparing %llu to %llu\n", k, m); + Assert::AreEqual(k < m, label1 < label2, message); } } }