10#include "quest/include/quest.h"
12#include <catch2/catch_test_macros.hpp>
13#include <catch2/matchers/catch_matchers_string.hpp>
14#include <catch2/generators/catch_generators_range.hpp>
16#include "tests/utils/macros.hpp"
17#include "tests/utils/cache.hpp"
18#include "tests/utils/convert.hpp"
19#include "tests/utils/compare.hpp"
20#include "tests/utils/random.hpp"
27using Catch::Matchers::ContainsSubstring;
36#define TEST_CATEGORY \
37 LABEL_UNIT_TAG "[debug]"
65TEST_CASE(
"setMaxNumReportedSigFigs", TEST_CATEGORY ) {
67 SECTION( LABEL_CORRECTNESS ) {
69 qcomp scalar =
getQcomp(0.12345, 0.12345);
71 vector<std::string> refs = {
82 for (
size_t numSigFigs=1; numSigFigs<=refs.size(); numSigFigs++) {
87 std::stringstream buffer;
88 std::streambuf * old = std::cout.rdbuf(buffer.rdbuf());
91 std::string out = buffer.str();
93 std::string ref = refs[numSigFigs-1];
95 CAPTURE( numSigFigs, ref );
96 REQUIRE( out == ref );
100 SECTION( LABEL_VALIDATION ) {
102 SECTION(
"number" ) {
104 int num = GENERATE( -1, 0 );
115TEST_CASE(
"setNumReportedNewlines", TEST_CATEGORY ) {
117 SECTION( LABEL_CORRECTNESS ) {
119 for (
int numNewlines=0; numNewlines<3; numNewlines++) {
124 std::stringstream buffer;
125 std::streambuf * old = std::cout.rdbuf(buffer.rdbuf());
127 std::cout.rdbuf(old);
128 std::string out = buffer.str();
130 std::string ref =
"x" + std::string(numNewlines,
'\n');
132 CAPTURE( numNewlines, ref );
133 REQUIRE( out == ref );
137 SECTION( LABEL_VALIDATION ) {
139 SECTION(
"number" ) {
141 REQUIRE_THROWS_WITH(
setNumReportedNewlines(-1), ContainsSubstring(
"Cannot generally be less than zero") );
144 SECTION(
"multine number" ) {
148 REQUIRE_THROWS_WITH(
reportQuESTEnv(), ContainsSubstring(
"zero") && ContainsSubstring(
"not permitted when calling multi-line") );
159 SECTION( LABEL_CORRECTNESS ) {
164 for (
auto& [label, qureg]: getCachedDensmatrs()) {
166 DYNAMIC_SECTION( label ) {
168 SECTION(
"same seed consistency" ) {
170 unsigned seeds[] = {123, 543, 755};
171 const int numSeeds = 3;
172 const int numMixedStates = 10;
173 const int numReps = 5;
180 qmatrix ref = getMatrix(qureg);
183 vector<int> outcomes(qureg.numQubits);
184 for (
int i=0; i<qureg.numQubits; i++)
188 for (
int r=0; r<numReps; r++) {
195 REQUIRE_AGREE( qureg, ref);
198 for (
int i=0; i<qureg.numQubits; i++)
203 SECTION(
"different key inconsistency" ) {
205 unsigned seeds[] = {123, 543, 755};
206 const int numSeeds = 3;
207 const int ampInd = 0;
215 int i = GENERATE_COPY( range(0,numSeeds) );
216 seeds[i] = 987654321;
222 REQUIRE( amp1 != amp2 );
228 SECTION( LABEL_VALIDATION ) {
230 SECTION(
"env not initialised" ) {
236 SECTION(
"number of seeds" ) {
238 int numSeeds = GENERATE( -1, 0 );
240 REQUIRE_THROWS_WITH(
setSeeds(
nullptr, numSeeds), ContainsSubstring(
"Invalid number of random seeds") );
251TEST_CASE(
"setSeedsToDefault", TEST_CATEGORY ) {
253 SECTION( LABEL_CORRECTNESS ) {
258 for (
auto& [label, qureg]: getCachedDensmatrs()) {
260 DYNAMIC_SECTION( label ) {
262 SECTION(
"different key inconsistency" ) {
264 const int ampInd = 0;
277 REQUIRE( amp1 != amp2 );
283 SECTION( LABEL_VALIDATION ) {
285 SECTION(
"env not initialised" ) {
299 SECTION( LABEL_CORRECTNESS ) {
301 SECTION(
"can be called immediately" ) {
306 vector<unsigned> out(numSeeds);
308 REQUIRE_NOTHROW(
getSeeds(out.data()) );
311 SECTION(
"correct output" ) {
313 GENERATE( range(0,10) );
317 vector<unsigned> in(numSeeds);
318 for (
int i=0; i<numSeeds; i++)
325 vector<unsigned> out(numSeeds);
327 for (
int i=0; i<numSeeds; i++)
328 REQUIRE( in[i] == out[i] );
332 SECTION( LABEL_VALIDATION ) {
334 SECTION(
"env not initialised" ) {
346TEST_CASE(
"getNumSeeds", TEST_CATEGORY ) {
348 SECTION( LABEL_CORRECTNESS ) {
350 SECTION(
"can be called immediately" ) {
355 SECTION(
"correct output" ) {
357 GENERATE( range(0,10) );
361 vector<unsigned> in(numSeeds);
362 for (
int i=0; i<numSeeds; i++)
373 SECTION( LABEL_VALIDATION ) {
375 SECTION(
"env not initialised" ) {
387TEST_CASE(
"setValidationOn", TEST_CATEGORY ) {
389 SECTION( LABEL_CORRECTNESS ) {
392 for (
int i=0; i<3; i++)
396 REQUIRE_THROWS(
setSeeds(
nullptr, -99) );
399 SECTION( LABEL_VALIDATION ) {
407TEST_CASE(
"setValidationOff", TEST_CATEGORY ) {
409 SECTION( LABEL_CORRECTNESS ) {
412 for (
int i=0; i<3; i++)
429 SECTION( LABEL_VALIDATION ) {
442 SECTION( LABEL_CORRECTNESS ) {
444 SECTION(
"affects validation" ) {
448 SECTION(
"unitarity" ) {
478 SECTION(
"affects struct fields" ) {
480 SECTION(
"CompMatr" ) {
483 *(m.isApproxUnitary) = 1;
484 *(m.isApproxHermitian) = 1;
487 REQUIRE( *(m.isApproxUnitary) == -1 );
488 REQUIRE( *(m.isApproxHermitian) == -1 );
493 SECTION(
"DiagMatr" ) {
496 *(m.isApproxUnitary) = 1;
497 *(m.isApproxHermitian) = 0;
501 REQUIRE( *(m.isApproxUnitary) == -1 );
502 REQUIRE( *(m.isApproxHermitian) == -1 );
508 SECTION(
"FullStateDiagMatr" ) {
511 *(m.isApproxUnitary) = 1;
512 *(m.isApproxHermitian) = 0;
513 *(m.isApproxNonZero) = 1;
516 REQUIRE( *(m.isApproxUnitary) == -1 );
517 REQUIRE( *(m.isApproxHermitian) == -1 );
518 REQUIRE( *(m.isApproxNonZero) == -1 );
523 SECTION(
"KrausMap" ) {
526 *(k.isApproxCPTP) = 1;
529 REQUIRE( *(k.isApproxCPTP) == -1 );
536 SECTION( LABEL_VALIDATION ) {
538 SECTION(
"negative epsilon" ) {
540 qreal eps = GENERATE( -0.5, -1, -100 );
551TEST_CASE(
"getValidationEpsilon", TEST_CATEGORY ) {
553 SECTION( LABEL_CORRECTNESS ) {
556 for (
int i=0; i<3; i++)
559 GENERATE( range(0,10) );
568 SECTION( LABEL_VALIDATION ) {
579TEST_CASE(
"setValidationEpsilonToDefault", TEST_CATEGORY ) {
581 SECTION( LABEL_CORRECTNESS ) {
583 SECTION(
"always safe to call" ) {
585 for (
int i=0; i<3; i++)
589 SECTION(
"affects validation" ) {
609 SECTION(
"affects struct fields" ) {
611 SECTION(
"CompMatr" ) {
614 *(m.isApproxUnitary) = 1;
615 *(m.isApproxHermitian) = 1;
618 REQUIRE( *(m.isApproxUnitary) == -1 );
619 REQUIRE( *(m.isApproxHermitian) == -1 );
624 SECTION(
"DiagMatr" ) {
627 *(m.isApproxUnitary) = 1;
628 *(m.isApproxHermitian) = 0;
632 REQUIRE( *(m.isApproxUnitary) == -1 );
633 REQUIRE( *(m.isApproxHermitian) == -1 );
639 SECTION(
"FullStateDiagMatr" ) {
642 *(m.isApproxUnitary) = 1;
643 *(m.isApproxHermitian) = 0;
644 *(m.isApproxNonZero) = 1;
647 REQUIRE( *(m.isApproxUnitary) == -1 );
648 REQUIRE( *(m.isApproxHermitian) == -1 );
649 REQUIRE( *(m.isApproxNonZero) == -1 );
654 SECTION(
"KrausMap" ) {
657 *(k.isApproxCPTP) = 1;
660 REQUIRE( *(k.isApproxCPTP) == -1 );
667 SECTION( LABEL_VALIDATION ) {
669 SECTION( LABEL_VALIDATION ) {
681TEST_CASE(
"getGpuCacheSize", TEST_CATEGORY ) {
683 SECTION( LABEL_CORRECTNESS ) {
692 bool usingCuQuantum = std::string(envStr).find(
"cuQuantum=0") == std::string::npos;
695 if (
getQuESTEnv().isGpuAccelerated && !usingCuQuantum) {
700 for (qindex i=0; i<matr.numRows; i++)
701 matr.cpuElems[i][i] = 1;
707 int targs[] = {0,1,2,3,4,5};
708 int ctrls[] = {6,7,8,9};
709 qindex cacheSize = 0;
711 for (
int numCtrls=4; numCtrls>=0; numCtrls--) {
720 CAPTURE( cacheSize, newSize );
721 REQUIRE( newSize >= cacheSize );
731 SECTION( LABEL_VALIDATION ) {
KrausMap createKrausMap(int numQubits, int numOperators)
void destroyKrausMap(KrausMap map)
void getEnvironmentString(char str[200])
void setMaxNumReportedItems(qindex numRows, qindex numCols)
void setMaxNumReportedSigFigs(int numSigFigs)
void setNumReportedNewlines(int numNewlines)
std::vector< unsigned > getSeeds()
void setSeeds(unsigned *seeds, int numSeeds)
void setValidationEpsilonToDefault()
qreal getValidationEpsilon()
void setValidationEpsilon(qreal eps)
void initRandomPureState(Qureg qureg)
void initRandomMixedState(Qureg qureg, qindex numPureStates)
FullStateDiagMatr createFullStateDiagMatr(int numQubits)
CompMatr createCompMatr(int numQubits)
DiagMatr createDiagMatr(int numQubits)
void destroyDiagMatr(DiagMatr matrix)
void destroyFullStateDiagMatr(FullStateDiagMatr matrix)
void destroyCompMatr(CompMatr matrix)
static CompMatr1 getCompMatr1(qcomp **in)
void syncCompMatr(CompMatr matr)
void applyCompMatr1(Qureg qureg, int target, CompMatr1 matrix)
void applyMultiControlledCompMatr(Qureg qureg, int *controls, int numControls, int *targets, int numTargets, CompMatr matr)
int applyQubitMeasurement(Qureg qureg, int target)
Qureg createCustomQureg(int numQubits, int isDensMatr, int useDistrib, int useGpuAccel, int useMultithread)
Qureg createQureg(int numQubits)
void destroyQureg(Qureg qureg)
qcomp getDensityQuregAmp(Qureg qureg, qindex row, qindex column)
qreal getRandomReal(qreal min, qreal maxExcl)
int getRandomInt(int min, int maxExcl)
void reportStr(const char *str)
static qcomp getQcomp(qreal re, qreal im)
void reportScalar(const char *label, qcomp num)
TEST_CASE("setInputErrorHandler", TEST_CATEGORY)