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/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
128 REQUIRE_THROWS_WITH(
createQureg(50), ContainsSubstring(
"failed") || ContainsSubstring(
"insufficient available memory") || ContainsSubstring(
"available GPU memory") );
137 SECTION( LABEL_CORRECTNESS ) {
139 int numQubits = GENERATE( range(1, 7) );
140 CAPTURE( numQubits );
146 REQUIRE( qureg.numQubits == numQubits );
147 REQUIRE( qureg.isDensityMatrix == 1 );
148 REQUIRE( qureg.numAmps == getPow2(2*numQubits) );
149 REQUIRE( qureg.logNumAmps == getLog2(qureg.numAmps) );
150 REQUIRE( qureg.logNumAmpsPerNode == getLog2(qureg.numAmpsPerNode) );
151 REQUIRE( qureg.logNumNodes == getLog2(qureg.numNodes) );
152 REQUIRE( qureg.logNumColsPerNode == getLog2(getPow2(numQubits) / qureg.numNodes) );
153 REQUIRE( qureg.numAmpsPerNode == qureg.numAmps / qureg.numNodes );
154 REQUIRE( (qureg.isMultithreaded == 0 || qureg.isMultithreaded == 1) );
155 REQUIRE( (qureg.isGpuAccelerated == 0 || qureg.isGpuAccelerated == 1) );
156 REQUIRE( (qureg.isDistributed == 0 || qureg.isDistributed == 1) );
159 if (qureg.isDistributed) {
160 REQUIRE( qureg.rank == env.rank );
161 REQUIRE( qureg.numNodes == env.numNodes );
163 REQUIRE( qureg.rank == 0 );
164 REQUIRE( qureg.numNodes == 1 );
168 REQUIRE( qureg.cpuAmps !=
nullptr );
169 if (qureg.isGpuAccelerated)
170 REQUIRE( qureg.gpuAmps !=
nullptr );
171 if (qureg.isDistributed)
172 REQUIRE( qureg.cpuCommBuffer !=
nullptr );
173 if (qureg.isGpuAccelerated && qureg.isDistributed)
174 REQUIRE( qureg.gpuCommBuffer !=
nullptr );
179 qmatrix ref =
getZeroMatrix(getPow2(numQubits)); ref[0][0] = 1;
180 REQUIRE_AGREE( qureg, ref );
185 SECTION( LABEL_VALIDATION ) {
187 SECTION(
"env not initialised" ) {
193 SECTION(
"too few qubits" ) {
195 int numQubits = GENERATE( -1, 0 );
197 REQUIRE_THROWS_WITH(
createDensityQureg(numQubits), ContainsSubstring(
"must contain one or more qubits") );
200 SECTION(
"too many qubits" ) {
206 REQUIRE_THROWS_WITH(
createDensityQureg(31), ContainsSubstring(
"memory would overflow size_t") );
212 #ifndef SANITIZER_IS_ACTIVE
213 REQUIRE_THROWS_WITH(
createDensityQureg(25), ContainsSubstring(
"failed") || ContainsSubstring(
"insufficient available memory") || ContainsSubstring(
"available GPU memory") );
220TEST_CASE(
"createForcedQureg", TEST_CATEGORY ) {
222 SECTION( LABEL_CORRECTNESS ) {
226 int minNumQubits = std::max({1, env.isDistributed? getLog2(env.numNodes) : 1});
227 int maxNumQubits = std::min({minNumQubits + 10, 14});
228 int numQubits = GENERATE_COPY( range(minNumQubits, maxNumQubits) );
229 CAPTURE( numQubits );
234 REQUIRE( qureg.numQubits == numQubits );
235 REQUIRE( qureg.isDensityMatrix == 0 );
236 REQUIRE( qureg.numAmps == getPow2(numQubits) );
237 REQUIRE( qureg.logNumAmps == getLog2(qureg.numAmps) );
238 REQUIRE( qureg.logNumAmpsPerNode == getLog2(qureg.numAmpsPerNode) );
241 REQUIRE( qureg.numNodes == env.numNodes );
242 REQUIRE( qureg.logNumNodes == getLog2(env.numNodes) );
243 REQUIRE( qureg.isMultithreaded == env.isMultithreaded);
244 REQUIRE( qureg.isGpuAccelerated == env.isGpuAccelerated);
245 REQUIRE( (qureg.isDistributed == env.isDistributed || env.numNodes == 1) );
248 if (qureg.isDistributed) {
249 REQUIRE( qureg.rank == env.rank );
250 REQUIRE( qureg.numAmpsPerNode == qureg.numAmps / env.numNodes );
252 REQUIRE( qureg.rank == 0 );
253 REQUIRE( qureg.numAmpsPerNode == qureg.numAmps );
257 REQUIRE( qureg.cpuAmps !=
nullptr );
258 if (qureg.isGpuAccelerated)
259 REQUIRE( qureg.gpuAmps !=
nullptr );
260 if (qureg.isDistributed)
261 REQUIRE( qureg.cpuCommBuffer !=
nullptr );
262 if (qureg.isGpuAccelerated && qureg.isDistributed)
263 REQUIRE( qureg.gpuCommBuffer !=
nullptr );
266 qvector ref = getZeroVector(getPow2(numQubits)); ref[0] = 1;
267 REQUIRE_AGREE( qureg, ref );
272 SECTION( LABEL_VALIDATION ) {
274 SECTION(
"env not initialised" ) {
280 SECTION(
"too few qubits" ) {
282 REQUIRE_THROWS_WITH(
createForcedQureg(-1), ContainsSubstring(
"must contain one or more qubits") );
283 REQUIRE_THROWS_WITH(
createForcedQureg(+0), ContainsSubstring(
"must contain one or more qubits") );
287 int minNumQubits = getLog2(numNodes);
288 REQUIRE_THROWS_WITH(
createForcedQureg(minNumQubits-1), ContainsSubstring(
"each node would contain fewer than one amplitude") );
292 SECTION(
"too many qubits" ) {
295 REQUIRE_THROWS_WITH(
createForcedQureg(100), ContainsSubstring(
"maximum which can be addressed by the qindex type") );
298 REQUIRE_THROWS_WITH(
createForcedQureg(62), ContainsSubstring(
"memory would overflow size_t") );
304 #ifndef SANITIZER_IS_ACTIVE
305 REQUIRE_THROWS_WITH(
createForcedQureg(50), ContainsSubstring(
"failed") || ContainsSubstring(
"insufficient available memory") || ContainsSubstring(
"available GPU memory") );
312TEST_CASE(
"createForcedDensityQureg", TEST_CATEGORY ) {
314 SECTION( LABEL_CORRECTNESS ) {
318 int minNumQubits = std::max({1, env.isDistributed? getLog2(env.numNodes) : 1});
319 int maxNumQubits = std::min({minNumQubits + 5, 8});
320 int numQubits = GENERATE_COPY( range(minNumQubits, maxNumQubits) );
321 CAPTURE( numQubits );
326 REQUIRE( qureg.numQubits == numQubits );
327 REQUIRE( qureg.isDensityMatrix == 1 );
328 REQUIRE( qureg.numAmps == getPow2(2*numQubits) );
329 REQUIRE( qureg.logNumAmps == getLog2(qureg.numAmps) );
330 REQUIRE( qureg.logNumAmpsPerNode == getLog2(qureg.numAmpsPerNode) );
331 REQUIRE( qureg.logNumColsPerNode == getLog2(getPow2(numQubits) / qureg.numNodes) );
334 REQUIRE( qureg.numNodes == env.numNodes );
335 REQUIRE( qureg.logNumNodes == getLog2(env.numNodes) );
336 REQUIRE( qureg.isMultithreaded == env.isMultithreaded);
337 REQUIRE( qureg.isGpuAccelerated == env.isGpuAccelerated);
338 REQUIRE( (qureg.isDistributed == env.isDistributed || env.numNodes == 1) );
341 if (qureg.isDistributed) {
342 REQUIRE( qureg.rank == env.rank );
343 REQUIRE( qureg.numAmpsPerNode == qureg.numAmps / env.numNodes );
345 REQUIRE( qureg.rank == 0 );
346 REQUIRE( qureg.numAmpsPerNode == qureg.numAmps );
350 REQUIRE( qureg.cpuAmps !=
nullptr );
351 if (qureg.isGpuAccelerated)
352 REQUIRE( qureg.gpuAmps !=
nullptr );
353 if (qureg.isDistributed)
354 REQUIRE( qureg.cpuCommBuffer !=
nullptr );
355 if (qureg.isGpuAccelerated && qureg.isDistributed)
356 REQUIRE( qureg.gpuCommBuffer !=
nullptr );
359 qmatrix ref =
getZeroMatrix(getPow2(numQubits)); ref[0][0] = 1;
360 REQUIRE_AGREE( qureg, ref );
365 SECTION( LABEL_VALIDATION ) {
367 SECTION(
"env not initialised" ) {
373 SECTION(
"too few qubits" ) {
380 int minNumQubits = getLog2(numNodes);
381 REQUIRE_THROWS_WITH(
createForcedDensityQureg(minNumQubits-1), ContainsSubstring(
"each node would contain fewer than a column") );
385 SECTION(
"too many qubits" ) {
397 #ifndef SANITIZER_IS_ACTIVE
398 REQUIRE_THROWS_WITH(
createForcedDensityQureg(25), ContainsSubstring(
"failed") || ContainsSubstring(
"insufficient available memory") || ContainsSubstring(
"available GPU memory") );
405TEST_CASE(
"createCustomQureg", TEST_CATEGORY ) {
407 SECTION( LABEL_CORRECTNESS ) {
411 for (
auto [deployLabel, mpi, gpu, omp] : getSupportedDeployments()) {
413 int isDenseMatr = GENERATE( 0, 1 );
415 std::string quregLabel = (isDenseMatr)? LABEL_STATEVEC : LABEL_DENSMATR;
416 std::string secLabel = quregLabel + LABEL_DELIMITER + deployLabel;
418 SECTION( secLabel ) {
420 int minNumQubits = std::max({1, mpi? getLog2(env.numNodes) : 1});
421 int maxNumQubits = std::min({minNumQubits + 3, isDenseMatr? 6 : 12});
422 int numQubits = GENERATE_COPY( range(minNumQubits, maxNumQubits) );
423 CAPTURE( numQubits );
428 REQUIRE( qureg.numQubits == numQubits );
429 REQUIRE( qureg.isDensityMatrix == isDenseMatr );
430 REQUIRE( qureg.numAmps == getPow2(numQubits * (isDenseMatr? 2:1)) );
431 REQUIRE( qureg.logNumNodes == getLog2(qureg.numNodes) );
432 REQUIRE( qureg.logNumAmps == getLog2(qureg.numAmps) );
433 REQUIRE( qureg.logNumAmpsPerNode == getLog2(qureg.numAmpsPerNode) );
434 REQUIRE( qureg.logNumColsPerNode == (isDenseMatr? getLog2(getPow2(numQubits) / qureg.numNodes) : 0) );
437 REQUIRE( qureg.isMultithreaded == omp );
438 REQUIRE( qureg.isGpuAccelerated == gpu );
439 REQUIRE( (qureg.isDistributed == mpi || env.numNodes == 1) );
443 REQUIRE( qureg.rank == env.rank );
444 REQUIRE( qureg.numNodes == env.numNodes );
445 REQUIRE( qureg.numAmpsPerNode == qureg.numAmps / env.numNodes );
447 REQUIRE( qureg.rank == 0 );
448 REQUIRE( qureg.numNodes == 1 );
449 REQUIRE( qureg.numAmpsPerNode == qureg.numAmps );
453 REQUIRE( qureg.cpuAmps !=
nullptr );
454 if (qureg.isGpuAccelerated)
455 REQUIRE( qureg.gpuAmps !=
nullptr );
456 if (qureg.isDistributed)
457 REQUIRE( qureg.cpuCommBuffer !=
nullptr );
458 if (qureg.isGpuAccelerated && qureg.isDistributed)
459 REQUIRE( qureg.gpuCommBuffer !=
nullptr );
463 qmatrix ref =
getZeroMatrix(getPow2(numQubits)); ref[0][0] = 1;
464 REQUIRE_AGREE( qureg, ref );
466 qvector ref = getZeroVector(getPow2(numQubits)); ref[0] = 1;
467 REQUIRE_AGREE( qureg, ref );
475 SECTION( LABEL_VALIDATION ) {
477 SECTION(
"env not initialised" ) {
483 SECTION(
"invalid isDensityMatrix flag" ) {
485 int isDensMatr = GENERATE( -1, 2 );
487 REQUIRE_THROWS_WITH(
createCustomQureg(10, isDensMatr, 0,0,0), ContainsSubstring(
"isDensityMatrix") );
490 SECTION(
"unsupported deployment" ) {
493 const int numQubits = 10;
494 const int isDensMatr = 0;
496 if (!env.isDistributed)
497 REQUIRE_THROWS_WITH(
createCustomQureg(numQubits,isDensMatr, 1,0,0), ContainsSubstring(
"non-distributed") );
499 if (!env.isGpuAccelerated)
500 REQUIRE_THROWS_WITH(
createCustomQureg(numQubits,isDensMatr, 0,1,0), ContainsSubstring(
"non-GPU") );
502 if (!env.isMultithreaded)
503 REQUIRE_THROWS_WITH(
createCustomQureg(numQubits,isDensMatr, 0,0,1), ContainsSubstring(
"non-multithreaded") );
506 SECTION(
"too few qubits" ) {
508 REQUIRE_THROWS_WITH(
createCustomQureg(-1, 0,0,0,0), ContainsSubstring(
"must contain one or more qubits") );
509 REQUIRE_THROWS_WITH(
createCustomQureg(+0, 0,0,0,0), ContainsSubstring(
"must contain one or more qubits") );
513 int minNumQubits = getLog2(numNodes);
515 REQUIRE_THROWS_WITH(
createCustomQureg(minNumQubits-1,0, useDistrib,0,0), ContainsSubstring(
"each node would contain fewer than one amplitude") );
519 SECTION(
"too many qubits" ) {
522 REQUIRE_THROWS_WITH(
createCustomQureg(100, 0, 0,0,0), ContainsSubstring(
"qindex") );
523 REQUIRE_THROWS_WITH(
createCustomQureg(50, 1, 0,0,0), ContainsSubstring(
"qindex") );
526 REQUIRE_THROWS_WITH(
createCustomQureg(62, 0, 0,0,0), ContainsSubstring(
"memory would overflow size_t") );
527 REQUIRE_THROWS_WITH(
createCustomQureg(31, 1, 0,0,0), ContainsSubstring(
"memory would overflow size_t") );
533 #ifndef SANITIZER_IS_ACTIVE
534 REQUIRE_THROWS_WITH(
createCustomQureg(50, 0, 0,0,0), ContainsSubstring(
"failed") || ContainsSubstring(
"insufficient available memory") || ContainsSubstring(
"available GPU memory") );
535 REQUIRE_THROWS_WITH(
createCustomQureg(25, 1, 0,0,0), ContainsSubstring(
"failed") || ContainsSubstring(
"insufficient available memory") || ContainsSubstring(
"available GPU memory") );
542TEST_CASE(
"createCloneQureg", TEST_CATEGORY ) {
544 SECTION( LABEL_CORRECTNESS ) {
546 auto cache = GENERATE( getCachedStatevecs(), getCachedDensmatrs() );
548 for (
auto& [label, qureg]: cache) {
554 REQUIRE( clone.isMultithreaded == qureg.isMultithreaded );
555 REQUIRE( clone.isGpuAccelerated == qureg.isGpuAccelerated );
556 REQUIRE( clone.isDistributed == qureg.isDistributed );
557 REQUIRE( clone.rank == qureg.rank );
558 REQUIRE( clone.numNodes == qureg.numNodes );
559 REQUIRE( clone.logNumNodes == qureg.logNumNodes );
560 REQUIRE( clone.isDensityMatrix == qureg.isDensityMatrix );
561 REQUIRE( clone.numQubits == qureg.numQubits );
562 REQUIRE( clone.numAmps == qureg.numAmps );
563 REQUIRE( clone.logNumAmps == qureg.logNumAmps );
564 REQUIRE( clone.numAmpsPerNode == qureg.numAmpsPerNode );
565 REQUIRE( clone.logNumAmpsPerNode == qureg.logNumAmpsPerNode );
566 REQUIRE( clone.logNumColsPerNode == qureg.logNumColsPerNode );
569 REQUIRE( clone.cpuAmps != qureg.cpuAmps );
570 if (clone.isGpuAccelerated)
571 REQUIRE( clone.gpuAmps != qureg.gpuAmps );
572 if (clone.isDistributed)
573 REQUIRE( clone.cpuCommBuffer != qureg.cpuCommBuffer );
574 if (clone.isGpuAccelerated && clone.isDistributed)
575 REQUIRE( clone.gpuCommBuffer != qureg.gpuCommBuffer );
578 REQUIRE_AGREE( clone, qureg );
588 SECTION( LABEL_CORRECTNESS ) {
594 SECTION( LABEL_VALIDATION ) {
599 #ifndef SANITIZER_IS_ACTIVE
600 SECTION(
"not created" ) {
603 REQUIRE_THROWS_WITH(
destroyQureg(qureg), ContainsSubstring(
"invalid Qureg") );
613 SECTION( LABEL_CORRECTNESS ) {
615 for (
auto& [label, qureg]: getCachedStatevecs()) {
617 qvector ref = getRefStatevec();
619 setToDebugState(ref);
621 int index = GENERATE_COPY( range(0, (
int) qureg.numAmps) );
625 REQUIRE_AGREE(
getQuregAmp(qureg, index), ref[index] );
629 SECTION( LABEL_VALIDATION ) {
634 #ifndef SANITIZER_IS_ACTIVE
635 SECTION(
"not created" ) {
638 REQUIRE_THROWS_WITH(
getQuregAmp(qureg,0), ContainsSubstring(
"invalid Qureg") );
643 SECTION(
"invalid index" ) {
645 int numQubits = GENERATE( range(1,5) );
647 int index = GENERATE_COPY( -1, getPow2(numQubits), getPow2(numQubits) + 1 );
649 REQUIRE_THROWS_WITH(
getQuregAmp(qureg,index), ContainsSubstring(
"state index") && ContainsSubstring(
"is invalid") );
654 SECTION(
"densitymatrix" ) {
658 REQUIRE_THROWS_WITH(
getQuregAmp(qureg,0), ContainsSubstring(
"received a density matrix") );
668 SECTION( LABEL_CORRECTNESS ) {
670 for (
auto& [label, qureg]: getCachedDensmatrs()) {
672 qmatrix ref = getRefDensmatr();
674 setToDebugState(ref);
676 int dim = (int) getPow2(qureg.numQubits);
680 GENERATE( range(0,100) );
688 SECTION( LABEL_VALIDATION ) {
693 #ifndef SANITIZER_IS_ACTIVE
694 SECTION(
"not created" ) {
697 REQUIRE_THROWS_WITH(
getDensityQuregAmp(qureg,0,0), ContainsSubstring(
"invalid Qureg") );
702 SECTION(
"invalid indices" ) {
704 int numQubits = GENERATE( range(1,5) );
706 qindex index = GENERATE_COPY( -1, getPow2(numQubits), getPow2(numQubits) + 1 );
714 SECTION(
"statevector" ) {
718 REQUIRE_THROWS_WITH(
getDensityQuregAmp(qureg,0,0), ContainsSubstring(
"received a statevector") );
728 SECTION( LABEL_CORRECTNESS ) {
730 for (
auto& [label, qureg]: getCachedStatevecs()) {
732 qvector ref = getRefStatevec();
734 setToDebugState(ref);
736 GENERATE( range(0,100) );
738 int numAmps =
getRandomInt(0, qureg.numAmps - startInd + 1);
740 vector<qcomp> out(numAmps);
744 REQUIRE_AGREE( out, getSublist(ref, startInd, numAmps) );
748 SECTION( LABEL_VALIDATION ) {
755 #ifndef SANITIZER_IS_ACTIVE
756 SECTION(
"not created" ) {
759 REQUIRE_THROWS_WITH(
getQuregAmps(
nullptr,bad,0,0), ContainsSubstring(
"invalid Qureg") );
764 SECTION(
"indices" ) {
766 int startInd = GENERATE_COPY( -1, qureg.numAmps, qureg.numAmps + 1 );
768 REQUIRE_THROWS_WITH(
getQuregAmps(
nullptr,qureg,startInd,0), ContainsSubstring(
"starting basis state index") );
771 SECTION(
"num amps") {
773 int numOut = GENERATE_COPY( -1, qureg.numAmps + 1 );
775 REQUIRE_THROWS_WITH(
getQuregAmps(
nullptr,qureg,0,numOut), ContainsSubstring(
"number of amplitudes") );
778 SECTION(
"subrange" ) {
782 REQUIRE_THROWS_WITH(
getQuregAmps(
nullptr,qureg, qureg.numAmps - numOut, numOut + 1), ContainsSubstring(
"implies an end index") );
792 SECTION( LABEL_CORRECTNESS ) {
794 for (
auto& [label, qureg]: getCachedDensmatrs()) {
796 qmatrix ref = getRefDensmatr();
798 setToDebugState(ref);
800 GENERATE( range(0,100) );
807 qcomp** out = (qcomp**) malloc(numRows *
sizeof *out);
808 for (
int i=0; i<numRows; i++)
809 out[i] = (qcomp*) malloc(numCols *
sizeof **out);
814 for (
int r=0; r<numRows && agrees; r++)
815 for (
int c=0; c<numCols && agrees; c++)
816 agrees = doScalarsAgree(out[r][c], ref[startRow+r][startCol+c]);
820 for (
int i=0; i<numRows; i++)
826 SECTION( LABEL_VALIDATION ) {
833 #ifndef SANITIZER_IS_ACTIVE
834 SECTION(
"not created" ) {
837 REQUIRE_THROWS_WITH(
getDensityQuregAmps(
nullptr,bad,0,0,0,0), ContainsSubstring(
"invalid Qureg") );
842 SECTION(
"indices" ) {
844 int startInd = GENERATE_COPY( -1, qureg.numAmps, qureg.numAmps + 1 );
846 REQUIRE_THROWS_WITH(
getDensityQuregAmps(
nullptr,qureg, startInd,0, 0,0), ContainsSubstring(
"Either or both of the starting row and column") );
847 REQUIRE_THROWS_WITH(
getDensityQuregAmps(
nullptr,qureg, 0,startInd, 0,0), ContainsSubstring(
"Either or both of the starting row and column") );
850 SECTION(
"num amps") {
852 int numOut = GENERATE_COPY( -1, qureg.numAmps + 1 );
854 REQUIRE_THROWS_WITH(
getDensityQuregAmps(
nullptr,qureg, 0,0, 0,numOut), ContainsSubstring(
"Either or both of the number of rows and columns") );
855 REQUIRE_THROWS_WITH(
getDensityQuregAmps(
nullptr,qureg, 0,0, numOut,0), ContainsSubstring(
"Either or both of the number of rows and columns") );
858 SECTION(
"subrange" ) {
861 int dim = getPow2(qureg.numQubits);
863 REQUIRE_THROWS_WITH(
getDensityQuregAmps(
nullptr,qureg, dim-numOut,0, numOut + 1,1), ContainsSubstring(
"combination of starting") && ContainsSubstring(
"number of rows and columns") );
864 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)