From 3ea5b50bf20ddb7195d9cca0ea5c1b5553fb2b73 Mon Sep 17 00:00:00 2001 From: Tyson Date: Mon, 7 Aug 2023 17:25:53 +0100 Subject: [PATCH] patched tests for MSVC This includes replicating (in a Catch2 v2 compatible way) the Catch2 patch for this Windows-specific issue: https://github.com/catchorg/Catch2/issues/2040 --- tests/catch/catch.hpp | 53 ++++++++++++++++++++++++------------- tests/test_calculations.cpp | 4 +++ tests/test_decoherence.cpp | 17 +++++++++--- tests/utilities.cpp | 18 ++++++++----- 4 files changed, 63 insertions(+), 29 deletions(-) diff --git a/tests/catch/catch.hpp b/tests/catch/catch.hpp index 4e646cfd..53d3de63 100644 --- a/tests/catch/catch.hpp +++ b/tests/catch/catch.hpp @@ -3961,7 +3961,12 @@ namespace Generators { class SingleValueGenerator final : public IGenerator { T m_value; public: - SingleValueGenerator(T&& value) : m_value(std::move(value)) {} + SingleValueGenerator(T const& value) : + m_value(value) + {} + SingleValueGenerator(T&& value) : + m_value(std::move(value)) + {} T const& get() const override { return m_value; @@ -4005,9 +4010,11 @@ namespace Generators { } }; - template - GeneratorWrapper value(T&& value) { - return GeneratorWrapper(pf::make_unique>(std::forward(value))); + template > + GeneratorWrapper value( T&& value ) { + return GeneratorWrapper( + pf::make_unique>( + std::forward( value ) ) ); } template GeneratorWrapper values(std::initializer_list values) { @@ -4019,27 +4026,36 @@ namespace Generators { std::vector> m_generators; size_t m_current = 0; - void populate(GeneratorWrapper&& generator) { - m_generators.emplace_back(std::move(generator)); + void add_generator( GeneratorWrapper&& generator ) { + m_generators.emplace_back( std::move( generator ) ); } - void populate(T&& val) { - m_generators.emplace_back(value(std::forward(val))); + void add_generator( T const& val ) { + m_generators.emplace_back( value( val ) ); } - template - void populate(U&& val) { - populate(T(std::forward(val))); + void add_generator( T&& val ) { + m_generators.emplace_back( value( std::move( val ) ) ); } - template - void populate(U&& valueOrGenerator, Gs &&... moreGenerators) { - populate(std::forward(valueOrGenerator)); - populate(std::forward(moreGenerators)...); + template + std::enable_if_t, T>::value> + add_generator( U&& val ) { + add_generator( T( std::forward( val ) ) ); + } + + template void add_generators( U&& valueOrGenerator ) { + add_generator( std::forward( valueOrGenerator ) ); + } + + template + void add_generators( U&& valueOrGenerator, Gs&&... moreGenerators ) { + add_generator( std::forward( valueOrGenerator ) ); + add_generators( std::forward( moreGenerators )... ); } public: template Generators(Gs &&... moreGenerators) { m_generators.reserve(sizeof...(Gs)); - populate(std::forward(moreGenerators)...); + add_generators(std::forward(moreGenerators)...); } T const& get() const override { @@ -4059,7 +4075,8 @@ namespace Generators { }; template - GeneratorWrapper> table( std::initializer_list::type...>> tuples ) { + GeneratorWrapper...>> + table( std::initializer_list...>> tuples ) { return values>( tuples ); } @@ -4076,7 +4093,7 @@ namespace Generators { return Generators(std::move(generator)); } template - auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators { + auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators> { return makeGenerators( value( std::forward( val ) ), std::forward( moreGenerators )... ); } template diff --git a/tests/test_calculations.cpp b/tests/test_calculations.cpp index d35cfaec..8a19b59a 100644 --- a/tests/test_calculations.cpp +++ b/tests/test_calculations.cpp @@ -1428,6 +1428,10 @@ TEST_CASE( "getNumQubits", "[calculations]" ) { } SECTION( "density-matrix" ) { + // density matrices use square as much memory; we must be careful not to seg-fault! + if (2*numQb > 25) + numQb = 13; // max size + Qureg mat = createDensityQureg(numQb, QUEST_ENV); REQUIRE( getNumQubits(mat) == numQb ); destroyQureg(mat, QUEST_ENV); diff --git a/tests/test_decoherence.cpp b/tests/test_decoherence.cpp index aad3f286..c5955b54 100644 --- a/tests/test_decoherence.cpp +++ b/tests/test_decoherence.cpp @@ -240,10 +240,15 @@ TEST_CASE( "mixMultiQubitKrausMap", "[decoherence]" ) { * and a heap overhead when numTargs >= 4 */ + // try every size (qubit wise) map int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) ); // inclusive upper bound - // note this is very expensive to try every arrangement (2 min runtime for numTargs=5 alone) - int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) ); + // previously, we tried every unique set of targets, via: + // int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) ); + // alas, this is too slow for CI, so we instead try a fixed number of random sets: + GENERATE( range(0, 10) ); + VLA(int, targs, numTargs); + setRandomTargets(targs, numTargs, NUM_QUBITS); // try the min and max number of operators, and 2 random numbers // (there are way too many to try all!) @@ -671,8 +676,12 @@ TEST_CASE( "mixNonTPMultiQubitKrausMap", "[decoherence]" ) { int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) ); // inclusive upper bound - // note this is very expensive to try every arrangement (2 min runtime for numTargs=5 alone) - int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) ); + // previously, we tried every unique set of targets, via: + // int* targs = GENERATE_COPY( sublists(range(0,NUM_QUBITS), numTargs) ); + // alas, this is too slow for CI, so we instead try a fixed number of random sets: + GENERATE( range(0, 10) ); + VLA(int, targs, numTargs); + setRandomTargets(targs, numTargs, NUM_QUBITS); // try the min and max number of operators, and 2 random numbers // (there are way too many to try all!) diff --git a/tests/utilities.cpp b/tests/utilities.cpp index 0699321b..72ae9468 100644 --- a/tests/utilities.cpp +++ b/tests/utilities.cpp @@ -386,6 +386,7 @@ QMatrix getRandomQMatrix(int dim) { // generate 2 normally-distributed random numbers via Box-Muller qreal a = rand()/(qreal) RAND_MAX; qreal b = rand()/(qreal) RAND_MAX; + if (a == 0) a = REAL_EPS; // prevent rand()=0 creation of NaN qreal r1 = sqrt(-2 * log(a)) * cos(2 * 3.14159265 * b); qreal r2 = sqrt(-2 * log(a)) * sin(2 * 3.14159265 * b); @@ -961,12 +962,15 @@ bool areEqual(Qureg qureg, QMatrix matr, qreal precision) { // DEBUG if (!ampsAgree) { - - // debug char buff[200]; - sprintf(buff, "[msg from utilities.cpp] node %d has a disagreement at (global) index %lld of (%s) + i(%s)\n", - qureg.chunkId, globalInd, REAL_STRING_FORMAT, REAL_STRING_FORMAT); - printf(buff, realDif, imagDif); + sprintf(buff, "[msg from utilities.cpp] node %d has a disagreement at %lld of (%s) + i(%s):\n\t[qureg] %s + i(%s) VS [ref] %s + i(%s)\n", + qureg.chunkId, startInd+i, + REAL_STRING_FORMAT, REAL_STRING_FORMAT, REAL_STRING_FORMAT, + REAL_STRING_FORMAT, REAL_STRING_FORMAT, REAL_STRING_FORMAT); + printf(buff, + realDif, imagDif, + qureg.stateVec.real[i], qureg.stateVec.imag[i], + real(matr[row][col]), imag(matr[row][col])); } // break loop as soon as amplitudes disagree @@ -1109,7 +1113,7 @@ QMatrix toQMatrix(Qureg qureg) { #endif // copy full state vector into a QVector - long long int dim = (1 << qureg.numQubitsRepresented); + long long int dim = (1LL << qureg.numQubitsRepresented); QMatrix matr = getZeroMatrix(dim); for (long long int n=0; n