Skip to content

Commit

Permalink
patched tests for MSVC
Browse files Browse the repository at this point in the history
This includes replicating (in a Catch2 v2 compatible way) the Catch2 patch for this Windows-specific issue:
catchorg/Catch2#2040
  • Loading branch information
TysonRayJones committed Aug 7, 2023
1 parent 7b26f4f commit 3ea5b50
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 29 deletions.
53 changes: 35 additions & 18 deletions tests/catch/catch.hpp
Expand Up @@ -3961,7 +3961,12 @@ namespace Generators {
class SingleValueGenerator final : public IGenerator<T> {
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;
Expand Down Expand Up @@ -4005,9 +4010,11 @@ namespace Generators {
}
};

template <typename T>
GeneratorWrapper<T> value(T&& value) {
return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));
template <typename T, typename DecayedT = std::decay_t<T>>
GeneratorWrapper<DecayedT> value( T&& value ) {
return GeneratorWrapper<DecayedT>(
pf::make_unique<SingleValueGenerator<DecayedT>>(
std::forward<T>( value ) ) );
}
template <typename T>
GeneratorWrapper<T> values(std::initializer_list<T> values) {
Expand All @@ -4019,27 +4026,36 @@ namespace Generators {
std::vector<GeneratorWrapper<T>> m_generators;
size_t m_current = 0;

void populate(GeneratorWrapper<T>&& generator) {
m_generators.emplace_back(std::move(generator));
void add_generator( GeneratorWrapper<T>&& generator ) {
m_generators.emplace_back( std::move( generator ) );
}
void populate(T&& val) {
m_generators.emplace_back(value(std::forward<T>(val)));
void add_generator( T const& val ) {
m_generators.emplace_back( value( val ) );
}
template<typename U>
void populate(U&& val) {
populate(T(std::forward<U>(val)));
void add_generator( T&& val ) {
m_generators.emplace_back( value( std::move( val ) ) );
}
template<typename U, typename... Gs>
void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {
populate(std::forward<U>(valueOrGenerator));
populate(std::forward<Gs>(moreGenerators)...);
template <typename U>
std::enable_if_t<!std::is_same<std::decay_t<U>, T>::value>
add_generator( U&& val ) {
add_generator( T( std::forward<U>( val ) ) );
}

template <typename U> void add_generators( U&& valueOrGenerator ) {
add_generator( std::forward<U>( valueOrGenerator ) );
}

template <typename U, typename... Gs>
void add_generators( U&& valueOrGenerator, Gs&&... moreGenerators ) {
add_generator( std::forward<U>( valueOrGenerator ) );
add_generators( std::forward<Gs>( moreGenerators )... );
}

public:
template <typename... Gs>
Generators(Gs &&... moreGenerators) {
m_generators.reserve(sizeof...(Gs));
populate(std::forward<Gs>(moreGenerators)...);
add_generators(std::forward<Gs>(moreGenerators)...);
}

T const& get() const override {
Expand All @@ -4059,7 +4075,8 @@ namespace Generators {
};

template<typename... Ts>
GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) {
GeneratorWrapper<std::tuple<std::decay_t<Ts>...>>
table( std::initializer_list<std::tuple<std::decay_t<Ts>...>> tuples ) {
return values<std::tuple<Ts...>>( tuples );
}

Expand All @@ -4076,7 +4093,7 @@ namespace Generators {
return Generators<T>(std::move(generator));
}
template<typename T, typename... Gs>
auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<T> {
auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<std::decay_t<T>> {
return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
}
template<typename T, typename U, typename... Gs>
Expand Down
4 changes: 4 additions & 0 deletions tests/test_calculations.cpp
Expand Up @@ -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);
Expand Down
17 changes: 13 additions & 4 deletions tests/test_decoherence.cpp
Expand Up @@ -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!)
Expand Down Expand Up @@ -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!)
Expand Down
18 changes: 11 additions & 7 deletions tests/utilities.cpp
Expand Up @@ -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);

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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<qureg.numAmpsTotal; n++)
matr[n%dim][n/dim] = qcomp(fullRe[n], fullIm[n]);
Expand Down Expand Up @@ -1232,7 +1236,7 @@ void toQureg(Qureg qureg, QVector vec) {
}
void toQureg(Qureg qureg, QMatrix mat) {
DEMAND( qureg.isDensityMatrix );
DEMAND( (1 << qureg.numQubitsRepresented) == (long long int) mat.size() );
DEMAND( (1LL << qureg.numQubitsRepresented) == (long long int) mat.size() );

syncQuESTEnv(QUEST_ENV);

Expand Down

0 comments on commit 3ea5b50

Please sign in to comment.