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/qvector.hpp"
17#include "tests/utils/qmatrix.hpp"
18#include "tests/utils/macros.hpp"
19#include "tests/utils/cache.hpp"
20#include "tests/utils/convert.hpp"
21#include "tests/utils/compare.hpp"
22#include "tests/utils/linalg.hpp"
23#include "tests/utils/random.hpp"
28using Catch::Matchers::ContainsSubstring;
36#define TEST_CATEGORY \
37 LABEL_UNIT_TAG "[qureg]"
51 SECTION( LABEL_CORRECTNESS ) {
53 int numQubits = GENERATE( range(1, 10) );
60 REQUIRE( qureg.numQubits == numQubits );
61 REQUIRE( qureg.isDensityMatrix == 0 );
62 REQUIRE( qureg.numAmps == getPow2(numQubits) );
63 REQUIRE( qureg.logNumAmps == getLog2(qureg.numAmps) );
64 REQUIRE( qureg.logNumAmpsPerNode == getLog2(qureg.numAmpsPerNode) );
65 REQUIRE( (qureg.isMultithreaded == 0 || qureg.isMultithreaded == 1) );
66 REQUIRE( (qureg.isGpuAccelerated == 0 || qureg.isGpuAccelerated == 1) );
67 REQUIRE( (qureg.isDistributed == 0 || qureg.isDistributed == 1) );
70 if (qureg.isDistributed) {
71 REQUIRE( qureg.rank == env.rank );
72 REQUIRE( qureg.numNodes == env.numNodes );
73 REQUIRE( qureg.logNumNodes == getLog2(env.numNodes) );
74 REQUIRE( qureg.numAmpsPerNode == qureg.numAmps / env.numNodes );
76 REQUIRE( qureg.rank == 0 );
77 REQUIRE( qureg.numNodes == 1 );
78 REQUIRE( qureg.logNumNodes == 0 );
79 REQUIRE( qureg.numAmpsPerNode == qureg.numAmps );
83 REQUIRE( qureg.cpuAmps !=
nullptr );
84 if (qureg.isGpuAccelerated)
85 REQUIRE( qureg.gpuAmps !=
nullptr );
86 if (qureg.isDistributed)
87 REQUIRE( qureg.cpuCommBuffer !=
nullptr );
88 if (qureg.isGpuAccelerated && qureg.isDistributed)
89 REQUIRE( qureg.gpuCommBuffer !=
nullptr );
94 qvector ref = getZeroVector(qureg.numAmps); ref[0] = 1;
95 REQUIRE_AGREE( qureg, ref );
100 SECTION( LABEL_VALIDATION ) {
102 SECTION(
"env not initialised" ) {
108 SECTION(
"too few qubits" ) {
110 int numQubits = GENERATE( -1, 0 );
112 REQUIRE_THROWS_WITH(
createQureg(numQubits), ContainsSubstring(
"must contain one or more qubits") );
115 SECTION(
"too many qubits" ) {
118 REQUIRE_THROWS_WITH(
createQureg(100), ContainsSubstring(
"maximum which can be addressed by the qindex type") );
121 REQUIRE_THROWS_WITH(
createQureg(62), ContainsSubstring(
"memory would overflow size_t") );
127 #ifndef SANITIZER_IS_ACTIVE
129 ContainsSubstring(
"failed") ||
130 ContainsSubstring(
"insufficient available memory") ||
131 ContainsSubstring(
"available GPU memory") ||
132 ContainsSubstring(
"RAM") );
141 SECTION( LABEL_CORRECTNESS ) {
143 int numQubits = GENERATE( range(1, 7) );
144 CAPTURE( numQubits );
150 REQUIRE( qureg.numQubits == numQubits );
151 REQUIRE( qureg.isDensityMatrix == 1 );
152 REQUIRE( qureg.numAmps == getPow2(2*numQubits) );
153 REQUIRE( qureg.logNumAmps == getLog2(qureg.numAmps) );
154 REQUIRE( qureg.logNumAmpsPerNode == getLog2(qureg.numAmpsPerNode) );
155 REQUIRE( qureg.logNumNodes == getLog2(qureg.numNodes) );
156 REQUIRE( qureg.logNumColsPerNode == getLog2(getPow2(numQubits) / qureg.numNodes) );
157 REQUIRE( qureg.numAmpsPerNode == qureg.numAmps / qureg.numNodes );
158 REQUIRE( (qureg.isMultithreaded == 0 || qureg.isMultithreaded == 1) );
159 REQUIRE( (qureg.isGpuAccelerated == 0 || qureg.isGpuAccelerated == 1) );
160 REQUIRE( (qureg.isDistributed == 0 || qureg.isDistributed == 1) );
163 if (qureg.isDistributed) {
164 REQUIRE( qureg.rank == env.rank );
165 REQUIRE( qureg.numNodes == env.numNodes );
167 REQUIRE( qureg.rank == 0 );
168 REQUIRE( qureg.numNodes == 1 );
172 REQUIRE( qureg.cpuAmps !=
nullptr );
173 if (qureg.isGpuAccelerated)
174 REQUIRE( qureg.gpuAmps !=
nullptr );
175 if (qureg.isDistributed)
176 REQUIRE( qureg.cpuCommBuffer !=
nullptr );
177 if (qureg.isGpuAccelerated && qureg.isDistributed)
178 REQUIRE( qureg.gpuCommBuffer !=
nullptr );
183 qmatrix ref =
getZeroMatrix(getPow2(numQubits)); ref[0][0] = 1;
184 REQUIRE_AGREE( qureg, ref );
189 SECTION( LABEL_VALIDATION ) {
191 SECTION(
"env not initialised" ) {
197 SECTION(
"too few qubits" ) {
199 int numQubits = GENERATE( -1, 0 );
201 REQUIRE_THROWS_WITH(
createDensityQureg(numQubits), ContainsSubstring(
"must contain one or more qubits") );
204 SECTION(
"too many qubits" ) {
210 REQUIRE_THROWS_WITH(
createDensityQureg(31), ContainsSubstring(
"memory would overflow size_t") );
216 #ifndef SANITIZER_IS_ACTIVE
218 ContainsSubstring(
"failed") ||
219 ContainsSubstring(
"insufficient available memory") ||
220 ContainsSubstring(
"available GPU memory") ||
221 ContainsSubstring(
"RAM") );
228TEST_CASE(
"createForcedQureg", TEST_CATEGORY ) {
230 SECTION( LABEL_CORRECTNESS ) {
234 int minNumQubits = std::max({1, env.isDistributed? getLog2(env.numNodes) : 1});
235 int maxNumQubits = std::min({minNumQubits + 10, 14});
236 int numQubits = GENERATE_COPY( range(minNumQubits, maxNumQubits) );
237 CAPTURE( numQubits );
242 REQUIRE( qureg.numQubits == numQubits );
243 REQUIRE( qureg.isDensityMatrix == 0 );
244 REQUIRE( qureg.numAmps == getPow2(numQubits) );
245 REQUIRE( qureg.logNumAmps == getLog2(qureg.numAmps) );
246 REQUIRE( qureg.logNumAmpsPerNode == getLog2(qureg.numAmpsPerNode) );
249 REQUIRE( qureg.numNodes == env.numNodes );
250 REQUIRE( qureg.logNumNodes == getLog2(env.numNodes) );
251 REQUIRE( qureg.isMultithreaded == env.isMultithreaded);
252 REQUIRE( qureg.isGpuAccelerated == env.isGpuAccelerated);
253 REQUIRE( (qureg.isDistributed == env.isDistributed || env.numNodes == 1) );
256 if (qureg.isDistributed) {
257 REQUIRE( qureg.rank == env.rank );
258 REQUIRE( qureg.numAmpsPerNode == qureg.numAmps / env.numNodes );
260 REQUIRE( qureg.rank == 0 );
261 REQUIRE( qureg.numAmpsPerNode == qureg.numAmps );
265 REQUIRE( qureg.cpuAmps !=
nullptr );
266 if (qureg.isGpuAccelerated)
267 REQUIRE( qureg.gpuAmps !=
nullptr );
268 if (qureg.isDistributed)
269 REQUIRE( qureg.cpuCommBuffer !=
nullptr );
270 if (qureg.isGpuAccelerated && qureg.isDistributed)
271 REQUIRE( qureg.gpuCommBuffer !=
nullptr );
274 qvector ref = getZeroVector(getPow2(numQubits)); ref[0] = 1;
275 REQUIRE_AGREE( qureg, ref );
280 SECTION( LABEL_VALIDATION ) {
282 SECTION(
"env not initialised" ) {
288 SECTION(
"too few qubits" ) {
290 REQUIRE_THROWS_WITH(
createForcedQureg(-1), ContainsSubstring(
"must contain one or more qubits") );
291 REQUIRE_THROWS_WITH(
createForcedQureg(+0), ContainsSubstring(
"must contain one or more qubits") );
295 int minNumQubits = getLog2(numNodes);
296 REQUIRE_THROWS_WITH(
createForcedQureg(minNumQubits-1), ContainsSubstring(
"each node would contain fewer than one amplitude") );
300 SECTION(
"too many qubits" ) {
303 REQUIRE_THROWS_WITH(
createForcedQureg(100), ContainsSubstring(
"maximum which can be addressed by the qindex type") );
306 REQUIRE_THROWS_WITH(
createForcedQureg(62), ContainsSubstring(
"memory would overflow size_t") );
312 #ifndef SANITIZER_IS_ACTIVE
314 ContainsSubstring(
"failed") ||
315 ContainsSubstring(
"insufficient available memory") ||
316 ContainsSubstring(
"available GPU memory") ||
317 ContainsSubstring(
"RAM") );
324TEST_CASE(
"createForcedDensityQureg", TEST_CATEGORY ) {
326 SECTION( LABEL_CORRECTNESS ) {
330 int minNumQubits = std::max({1, env.isDistributed? getLog2(env.numNodes) : 1});
331 int maxNumQubits = std::min({minNumQubits + 5, 8});
332 int numQubits = GENERATE_COPY( range(minNumQubits, maxNumQubits) );
333 CAPTURE( numQubits );
338 REQUIRE( qureg.numQubits == numQubits );
339 REQUIRE( qureg.isDensityMatrix == 1 );
340 REQUIRE( qureg.numAmps == getPow2(2*numQubits) );
341 REQUIRE( qureg.logNumAmps == getLog2(qureg.numAmps) );
342 REQUIRE( qureg.logNumAmpsPerNode == getLog2(qureg.numAmpsPerNode) );
343 REQUIRE( qureg.logNumColsPerNode == getLog2(getPow2(numQubits) / qureg.numNodes) );
346 REQUIRE( qureg.numNodes == env.numNodes );
347 REQUIRE( qureg.logNumNodes == getLog2(env.numNodes) );
348 REQUIRE( qureg.isMultithreaded == env.isMultithreaded);
349 REQUIRE( qureg.isGpuAccelerated == env.isGpuAccelerated);
350 REQUIRE( (qureg.isDistributed == env.isDistributed || env.numNodes == 1) );
353 if (qureg.isDistributed) {
354 REQUIRE( qureg.rank == env.rank );
355 REQUIRE( qureg.numAmpsPerNode == qureg.numAmps / env.numNodes );
357 REQUIRE( qureg.rank == 0 );
358 REQUIRE( qureg.numAmpsPerNode == qureg.numAmps );
362 REQUIRE( qureg.cpuAmps !=
nullptr );
363 if (qureg.isGpuAccelerated)
364 REQUIRE( qureg.gpuAmps !=
nullptr );
365 if (qureg.isDistributed)
366 REQUIRE( qureg.cpuCommBuffer !=
nullptr );
367 if (qureg.isGpuAccelerated && qureg.isDistributed)
368 REQUIRE( qureg.gpuCommBuffer !=
nullptr );
371 qmatrix ref =
getZeroMatrix(getPow2(numQubits)); ref[0][0] = 1;
372 REQUIRE_AGREE( qureg, ref );
377 SECTION( LABEL_VALIDATION ) {
379 SECTION(
"env not initialised" ) {
385 SECTION(
"too few qubits" ) {
392 int minNumQubits = getLog2(numNodes);
393 REQUIRE_THROWS_WITH(
createForcedDensityQureg(minNumQubits-1), ContainsSubstring(
"each node would contain fewer than a column") );
397 SECTION(
"too many qubits" ) {
409 #ifndef SANITIZER_IS_ACTIVE
411 ContainsSubstring(
"failed") ||
412 ContainsSubstring(
"insufficient available memory") ||
413 ContainsSubstring(
"available GPU memory") ||
414 ContainsSubstring(
"RAM") );
421TEST_CASE(
"createCustomQureg", TEST_CATEGORY ) {
423 SECTION( LABEL_CORRECTNESS ) {
427 for (
auto [deployLabel, mpi, gpu, omp] : getSupportedDeployments()) {
429 int isDenseMatr = GENERATE( 0, 1 );
431 std::string quregLabel = (isDenseMatr)? LABEL_STATEVEC : LABEL_DENSMATR;
432 std::string secLabel = quregLabel + LABEL_DELIMITER + deployLabel;
434 SECTION( secLabel ) {
436 int minNumQubits = std::max({1, mpi? getLog2(env.numNodes) : 1});
437 int maxNumQubits = std::min({minNumQubits + 3, isDenseMatr? 6 : 12});
438 int numQubits = GENERATE_COPY( range(minNumQubits, maxNumQubits) );
439 CAPTURE( numQubits );
444 REQUIRE( qureg.numQubits == numQubits );
445 REQUIRE( qureg.isDensityMatrix == isDenseMatr );
446 REQUIRE( qureg.numAmps == getPow2(numQubits * (isDenseMatr? 2:1)) );
447 REQUIRE( qureg.logNumNodes == getLog2(qureg.numNodes) );
448 REQUIRE( qureg.logNumAmps == getLog2(qureg.numAmps) );
449 REQUIRE( qureg.logNumAmpsPerNode == getLog2(qureg.numAmpsPerNode) );
450 REQUIRE( qureg.logNumColsPerNode == (isDenseMatr? getLog2(getPow2(numQubits) / qureg.numNodes) : 0) );
453 REQUIRE( qureg.isMultithreaded == omp );
454 REQUIRE( qureg.isGpuAccelerated == gpu );
455 REQUIRE( (qureg.isDistributed == mpi || env.numNodes == 1) );
459 REQUIRE( qureg.rank == env.rank );
460 REQUIRE( qureg.numNodes == env.numNodes );
461 REQUIRE( qureg.numAmpsPerNode == qureg.numAmps / env.numNodes );
463 REQUIRE( qureg.rank == 0 );
464 REQUIRE( qureg.numNodes == 1 );
465 REQUIRE( qureg.numAmpsPerNode == qureg.numAmps );
469 REQUIRE( qureg.cpuAmps !=
nullptr );
470 if (qureg.isGpuAccelerated)
471 REQUIRE( qureg.gpuAmps !=
nullptr );
472 if (qureg.isDistributed)
473 REQUIRE( qureg.cpuCommBuffer !=
nullptr );
474 if (qureg.isGpuAccelerated && qureg.isDistributed)
475 REQUIRE( qureg.gpuCommBuffer !=
nullptr );
479 qmatrix ref =
getZeroMatrix(getPow2(numQubits)); ref[0][0] = 1;
480 REQUIRE_AGREE( qureg, ref );
482 qvector ref = getZeroVector(getPow2(numQubits)); ref[0] = 1;
483 REQUIRE_AGREE( qureg, ref );
491 SECTION( LABEL_VALIDATION ) {
493 SECTION(
"env not initialised" ) {
499 SECTION(
"invalid isDensityMatrix flag" ) {
501 int isDensMatr = GENERATE( -1, 2 );
503 REQUIRE_THROWS_WITH(
createCustomQureg(10, isDensMatr, 0,0,0), ContainsSubstring(
"isDensityMatrix") );
506 SECTION(
"unsupported deployment" ) {
509 const int numQubits = 10;
510 const int isDensMatr = 0;
512 if (!env.isDistributed)
513 REQUIRE_THROWS_WITH(
createCustomQureg(numQubits,isDensMatr, 1,0,0), ContainsSubstring(
"non-distributed") );
515 if (!env.isGpuAccelerated)
516 REQUIRE_THROWS_WITH(
createCustomQureg(numQubits,isDensMatr, 0,1,0), ContainsSubstring(
"non-GPU") );
518 if (!env.isMultithreaded)
519 REQUIRE_THROWS_WITH(
createCustomQureg(numQubits,isDensMatr, 0,0,1), ContainsSubstring(
"non-multithreaded") );
522 SECTION(
"too few qubits" ) {
524 REQUIRE_THROWS_WITH(
createCustomQureg(-1, 0,0,0,0), ContainsSubstring(
"must contain one or more qubits") );
525 REQUIRE_THROWS_WITH(
createCustomQureg(+0, 0,0,0,0), ContainsSubstring(
"must contain one or more qubits") );
529 int minNumQubits = getLog2(numNodes);
531 REQUIRE_THROWS_WITH(
createCustomQureg(minNumQubits-1,0, useDistrib,0,0), ContainsSubstring(
"each node would contain fewer than one amplitude") );
535 SECTION(
"too many qubits" ) {
538 REQUIRE_THROWS_WITH(
createCustomQureg(100, 0, 0,0,0), ContainsSubstring(
"qindex") );
539 REQUIRE_THROWS_WITH(
createCustomQureg(50, 1, 0,0,0), ContainsSubstring(
"qindex") );
542 REQUIRE_THROWS_WITH(
createCustomQureg(62, 0, 0,0,0), ContainsSubstring(
"memory would overflow size_t") );
543 REQUIRE_THROWS_WITH(
createCustomQureg(31, 1, 0,0,0), ContainsSubstring(
"memory would overflow size_t") );
549 #ifndef SANITIZER_IS_ACTIVE
551 ContainsSubstring(
"failed") ||
552 ContainsSubstring(
"insufficient available memory") ||
553 ContainsSubstring(
"available GPU memory") ||
554 ContainsSubstring(
"RAM") );
556 ContainsSubstring(
"failed") ||
557 ContainsSubstring(
"insufficient available memory") ||
558 ContainsSubstring(
"available GPU memory") ||
559 ContainsSubstring(
"RAM") );
566TEST_CASE(
"createCloneQureg", TEST_CATEGORY ) {
568 SECTION( LABEL_CORRECTNESS ) {
570 auto cache = GENERATE( getCachedStatevecs(), getCachedDensmatrs() );
572 for (
auto& [label, qureg]: cache) {
578 REQUIRE( clone.isMultithreaded == qureg.isMultithreaded );
579 REQUIRE( clone.isGpuAccelerated == qureg.isGpuAccelerated );
580 REQUIRE( clone.isDistributed == qureg.isDistributed );
581 REQUIRE( clone.rank == qureg.rank );
582 REQUIRE( clone.numNodes == qureg.numNodes );
583 REQUIRE( clone.logNumNodes == qureg.logNumNodes );
584 REQUIRE( clone.isDensityMatrix == qureg.isDensityMatrix );
585 REQUIRE( clone.numQubits == qureg.numQubits );
586 REQUIRE( clone.numAmps == qureg.numAmps );
587 REQUIRE( clone.logNumAmps == qureg.logNumAmps );
588 REQUIRE( clone.numAmpsPerNode == qureg.numAmpsPerNode );
589 REQUIRE( clone.logNumAmpsPerNode == qureg.logNumAmpsPerNode );
590 REQUIRE( clone.logNumColsPerNode == qureg.logNumColsPerNode );
593 REQUIRE( clone.cpuAmps != qureg.cpuAmps );
594 if (clone.isGpuAccelerated)
595 REQUIRE( clone.gpuAmps != qureg.gpuAmps );
596 if (clone.isDistributed)
597 REQUIRE( clone.cpuCommBuffer != qureg.cpuCommBuffer );
598 if (clone.isGpuAccelerated && clone.isDistributed)
599 REQUIRE( clone.gpuCommBuffer != qureg.gpuCommBuffer );
602 REQUIRE_AGREE( clone, qureg );
612 SECTION( LABEL_CORRECTNESS ) {
618 SECTION( LABEL_VALIDATION ) {
623 #ifndef SANITIZER_IS_ACTIVE
624 SECTION(
"not created" ) {
627 REQUIRE_THROWS_WITH(
destroyQureg(qureg), ContainsSubstring(
"invalid Qureg") );
637 SECTION( LABEL_CORRECTNESS ) {
639 for (
auto& [label, qureg]: getCachedStatevecs()) {
641 qvector ref = getRefStatevec();
643 setToDebugState(ref);
645 int index = GENERATE_COPY( range(0, (
int) qureg.numAmps) );
649 REQUIRE_AGREE(
getQuregAmp(qureg, index), ref[index] );
653 SECTION( LABEL_VALIDATION ) {
658 #ifndef SANITIZER_IS_ACTIVE
659 SECTION(
"not created" ) {
662 REQUIRE_THROWS_WITH(
getQuregAmp(qureg,0), ContainsSubstring(
"invalid Qureg") );
667 SECTION(
"invalid index" ) {
669 int numQubits = GENERATE( range(1,5) );
671 int index = GENERATE_COPY( -1, getPow2(numQubits), getPow2(numQubits) + 1 );
673 REQUIRE_THROWS_WITH(
getQuregAmp(qureg,index), ContainsSubstring(
"state index") && ContainsSubstring(
"is invalid") );
678 SECTION(
"densitymatrix" ) {
682 REQUIRE_THROWS_WITH(
getQuregAmp(qureg,0), ContainsSubstring(
"received a density matrix") );
692 SECTION( LABEL_CORRECTNESS ) {
694 for (
auto& [label, qureg]: getCachedDensmatrs()) {
696 qmatrix ref = getRefDensmatr();
698 setToDebugState(ref);
700 int dim = (int) getPow2(qureg.numQubits);
704 GENERATE( range(0,100) );
712 SECTION( LABEL_VALIDATION ) {
717 #ifndef SANITIZER_IS_ACTIVE
718 SECTION(
"not created" ) {
721 REQUIRE_THROWS_WITH(
getDensityQuregAmp(qureg,0,0), ContainsSubstring(
"invalid Qureg") );
726 SECTION(
"invalid indices" ) {
728 int numQubits = GENERATE( range(1,5) );
730 qindex index = GENERATE_COPY( -1, getPow2(numQubits), getPow2(numQubits) + 1 );
738 SECTION(
"statevector" ) {
742 REQUIRE_THROWS_WITH(
getDensityQuregAmp(qureg,0,0), ContainsSubstring(
"received a statevector") );
752 SECTION( LABEL_CORRECTNESS ) {
754 for (
auto& [label, qureg]: getCachedStatevecs()) {
756 qvector ref = getRefStatevec();
758 setToDebugState(ref);
760 GENERATE( range(0,100) );
762 int numAmps =
getRandomInt(0, qureg.numAmps - startInd + 1);
764 vector<qcomp> out(numAmps);
768 REQUIRE_AGREE( out, getSublist(ref, startInd, numAmps) );
772 SECTION( LABEL_VALIDATION ) {
779 #ifndef SANITIZER_IS_ACTIVE
780 SECTION(
"not created" ) {
783 REQUIRE_THROWS_WITH(
getQuregAmps(
nullptr,bad,0,0), ContainsSubstring(
"invalid Qureg") );
788 SECTION(
"indices" ) {
790 int startInd = GENERATE_COPY( -1, qureg.numAmps, qureg.numAmps + 1 );
792 REQUIRE_THROWS_WITH(
getQuregAmps(
nullptr,qureg,startInd,0), ContainsSubstring(
"starting basis state index") );
795 SECTION(
"num amps") {
797 int numOut = GENERATE_COPY( -1, qureg.numAmps + 1 );
799 REQUIRE_THROWS_WITH(
getQuregAmps(
nullptr,qureg,0,numOut), ContainsSubstring(
"number of amplitudes") );
802 SECTION(
"subrange" ) {
806 REQUIRE_THROWS_WITH(
getQuregAmps(
nullptr,qureg, qureg.numAmps - numOut, numOut + 1), ContainsSubstring(
"implies an end index") );
816 SECTION( LABEL_CORRECTNESS ) {
818 for (
auto& [label, qureg]: getCachedDensmatrs()) {
820 qmatrix ref = getRefDensmatr();
822 setToDebugState(ref);
824 GENERATE( range(0,100) );
831 qcomp** out = (qcomp**) malloc(numRows *
sizeof *out);
832 for (
int i=0; i<numRows; i++)
833 out[i] = (qcomp*) malloc(numCols *
sizeof **out);
838 for (
int r=0; r<numRows && agrees; r++)
839 for (
int c=0; c<numCols && agrees; c++)
840 agrees = doScalarsAgree(out[r][c], ref[startRow+r][startCol+c]);
844 for (
int i=0; i<numRows; i++)
850 SECTION( LABEL_VALIDATION ) {
857 #ifndef SANITIZER_IS_ACTIVE
858 SECTION(
"not created" ) {
861 REQUIRE_THROWS_WITH(
getDensityQuregAmps(
nullptr,bad,0,0,0,0), ContainsSubstring(
"invalid Qureg") );
866 SECTION(
"indices" ) {
868 int startInd = GENERATE_COPY( -1, qureg.numAmps, qureg.numAmps + 1 );
870 REQUIRE_THROWS_WITH(
getDensityQuregAmps(
nullptr,qureg, startInd,0, 0,0), ContainsSubstring(
"Either or both of the starting row and column") );
871 REQUIRE_THROWS_WITH(
getDensityQuregAmps(
nullptr,qureg, 0,startInd, 0,0), ContainsSubstring(
"Either or both of the starting row and column") );
874 SECTION(
"num amps") {
876 int numOut = GENERATE_COPY( -1, qureg.numAmps + 1 );
878 REQUIRE_THROWS_WITH(
getDensityQuregAmps(
nullptr,qureg, 0,0, 0,numOut), ContainsSubstring(
"Either or both of the number of rows and columns") );
879 REQUIRE_THROWS_WITH(
getDensityQuregAmps(
nullptr,qureg, 0,0, numOut,0), ContainsSubstring(
"Either or both of the number of rows and columns") );
882 SECTION(
"subrange" ) {
885 int dim = getPow2(qureg.numQubits);
887 REQUIRE_THROWS_WITH(
getDensityQuregAmps(
nullptr,qureg, dim-numOut,0, numOut + 1,1), ContainsSubstring(
"combination of starting") && ContainsSubstring(
"number of rows and columns") );
888 REQUIRE_THROWS_WITH(
getDensityQuregAmps(
nullptr,qureg, 0,dim-numOut, 1,numOut + 1), ContainsSubstring(
"combination of starting") && ContainsSubstring(
"number of rows and columns") );
void initRandomPureState(Qureg qureg)
void initDebugState(Qureg qureg)
Qureg createDensityQureg(int numQubits)
Qureg createForcedQureg(int numQubits)
Qureg createForcedDensityQureg(int numQubits)
Qureg createCloneQureg(Qureg qureg)
Qureg createCustomQureg(int numQubits, int isDensMatr, int useDistrib, int useGpuAccel, int useMultithread)
Qureg createQureg(int numQubits)
void destroyQureg(Qureg qureg)
qcomp getQuregAmp(Qureg qureg, qindex index)
void getDensityQuregAmps(qcomp **outAmps, Qureg qureg, qindex startRow, qindex startCol, qindex numRows, qindex numCols)
void getQuregAmps(qcomp *outAmps, Qureg qureg, qindex startInd, qindex numAmps)
qcomp getDensityQuregAmp(Qureg qureg, qindex row, qindex column)
void reportQureg(Qureg qureg)
void reportQuregParams(Qureg qureg)
void syncQuregFromGpu(Qureg qureg)
void syncSubQuregToGpu(Qureg qureg, qindex localStartInd, qindex numLocalAmps)
void syncSubQuregFromGpu(Qureg qureg, qindex localStartInd, qindex numLocalAmps)
void syncQuregToGpu(Qureg qureg)
qmatrix getZeroMatrix(size_t dim)
int getRandomInt(int min, int maxExcl)
TEST_CASE("createQureg", TEST_CATEGORY)