The Quantum Exact Simulation Toolkit v4.2.0
Loading...
Searching...
No Matches
matrices.cpp
1/** @file
2 * Unit tests of the matrices module.
3 *
4 * @author Tyson Jones
5 *
6 * @defgroup unitmatr Matrices
7 * @ingroup unittests
8 */
9
10#include "quest.h"
11
12#include <catch2/catch_test_macros.hpp>
13#include <catch2/matchers/catch_matchers_string.hpp>
14#include <catch2/generators/catch_generators_range.hpp>
15
16#include "tests/utils/qvector.hpp"
17#include "tests/utils/qmatrix.hpp"
18#include "tests/utils/cache.hpp"
19#include "tests/utils/compare.hpp"
20#include "tests/utils/convert.hpp"
21#include "tests/utils/evolve.hpp"
22#include "tests/utils/linalg.hpp"
23#include "tests/utils/lists.hpp"
24#include "tests/utils/macros.hpp"
25#include "tests/utils/random.hpp"
26
27#include <cstdlib>
28#include <algorithm>
29
30using Catch::Matchers::ContainsSubstring;
31
32
33
34/*
35 * UTILITIES
36 */
37
38#define TEST_CATEGORY \
39 LABEL_UNIT_TAG "[matrices]"
40
41
42
43/**
44 * TESTS
45 *
46 * @ingroup unitmatr
47 * @{
48 */
49
50
51TEST_CASE( "getCompMatr1", TEST_CATEGORY ) {
52
53 SECTION( LABEL_CORRECTNESS ) {
54
55 constexpr int dim = 2;
56 qmatrix ref = getRandomMatrix(dim);
57
58 SECTION( LABEL_C_INTERFACE ) {
59
60 // 2D compile-time array
61 qcomp arr[dim][dim] = {{ref[0][0], ref[0][1]}, {ref[1][0], ref[1][1]}};
62 REQUIRE_AGREE( getCompMatr1(arr), ref );
63
64 // nested pointers
65 qcomp** ptrs = (qcomp**) malloc(dim * sizeof *ptrs);
66 for (int i=0; i<dim; i++) {
67 ptrs[i] = (qcomp*) malloc(dim * sizeof **ptrs);
68 for (int j=0; j<dim; j++)
69 ptrs[i][j] = ref[i][j];
70 }
71 REQUIRE_AGREE( getCompMatr1(ptrs), ref );
72
73 // array of pointers
74 qcomp* ptrArr[dim];
75 for (int i=0; i<dim; i++)
76 ptrArr[i] = ptrs[i];
77 REQUIRE_AGREE( getCompMatr1(ptrArr), ref );
78
79 // cleanup
80 for (int i=0; i<dim; i++)
81 free(ptrs[i]);
82 free(ptrs);
83 }
84
85 SECTION( LABEL_CPP_INTERFACE ) {
86
87 // nested vectors
88 REQUIRE_AGREE( getCompMatr1(ref), ref );
89
90 // inline vectors
91 REQUIRE_AGREE( getCompMatr1({{ref[0][0],ref[0][1]},{ref[1][0],ref[1][1]}}), ref );
92 }
93 }
94
95 SECTION( LABEL_VALIDATION ) {
96
97 SECTION( "null pointer" ) {
98
99 qcomp** ptr = nullptr;
100 REQUIRE_THROWS_WITH( getCompMatr1(ptr), ContainsSubstring("was a null pointer") );
101
102 qcomp* arr[1] = {nullptr};
103 REQUIRE_THROWS_WITH( getCompMatr1(arr), ContainsSubstring("contained a null pointer") );
104 }
105
106 SECTION( "invalid dimensions" ) {
107
108 // detectable only by the C++ interface
109
110 REQUIRE_THROWS_WITH( getCompMatr1({{0,0}}), ContainsSubstring("Incompatible number of rows") );
111 REQUIRE_THROWS_WITH( getCompMatr1({{0,0},{0,0},{0,0}}), ContainsSubstring("Incompatible number of rows") );
112
113 REQUIRE_THROWS_WITH( getCompMatr1({{0,0},{0}}), ContainsSubstring("incompatible number of elements") );
114 REQUIRE_THROWS_WITH( getCompMatr1({{0,0},{0,0,0}}), ContainsSubstring("incompatible number of elements") );
115 }
116 }
117}
118
119
120TEST_CASE( "getCompMatr2", TEST_CATEGORY ) {
121
122 SECTION( LABEL_CORRECTNESS ) {
123
124 constexpr int dim = 4;
125 qmatrix ref = getRandomMatrix(dim);
126
127 SECTION( LABEL_C_INTERFACE ) {
128
129 // 2D compile-time array
130 qcomp arr[dim][dim];
131 for (int i=0; i<dim; i++)
132 for (int j=0; j<dim; j++)
133 arr[i][j] = ref[i][j];
134 REQUIRE_AGREE( getCompMatr2(arr), ref );
135
136 // nested pointers
137 qcomp** ptrs = (qcomp**) malloc(dim * sizeof *ptrs);
138 for (int i=0; i<dim; i++) {
139 ptrs[i] = (qcomp*) malloc(dim * sizeof **ptrs);
140 for (int j=0; j<dim; j++)
141 ptrs[i][j] = ref[i][j];
142 }
143 REQUIRE_AGREE( getCompMatr2(ptrs), ref );
144
145 // array of pointers
146 qcomp* ptrArr[dim];
147 for (int i=0; i<dim; i++)
148 ptrArr[i] = ptrs[i];
149 REQUIRE_AGREE( getCompMatr2(ptrArr), ref );
150
151 // cleanup
152 for (int i=0; i<dim; i++)
153 free(ptrs[i]);
154 free(ptrs);
155 }
156
157 SECTION( LABEL_CPP_INTERFACE ) {
158
159 // nested vectors
160 REQUIRE_AGREE( getCompMatr2(ref), ref );
161
162 // inline vectors
163 REQUIRE_AGREE(
165 {ref[0][0],ref[0][1],ref[0][2],ref[0][3]},
166 {ref[1][0],ref[1][1],ref[1][2],ref[1][3]},
167 {ref[2][0],ref[2][1],ref[2][2],ref[2][3]},
168 {ref[3][0],ref[3][1],ref[3][2],ref[3][3]}
169 }),
170 ref
171 );
172 }
173 }
174
175 SECTION( LABEL_VALIDATION ) {
176
177 SECTION( "null pointer" ) {
178
179 qcomp** ptr = nullptr;
180 REQUIRE_THROWS_WITH( getCompMatr2(ptr), ContainsSubstring("was a null pointer") );
181
182 qcomp* arr[1] = {nullptr};
183 REQUIRE_THROWS_WITH( getCompMatr2(arr), ContainsSubstring("contained a null pointer") );
184 }
185
186 SECTION( "invalid dimensions" ) {
187
188 // detectable only by the C++ interface
189
190 qmatrix bad1 = {{0,0,0,0}};
191 qmatrix bad2 = {{0,0,0,0},{0,0,0,0},{0,0,0,0}};
192
193 REQUIRE_THROWS_WITH( getCompMatr2(bad1), ContainsSubstring("Incompatible number of rows") );
194 REQUIRE_THROWS_WITH( getCompMatr2(bad2), ContainsSubstring("Incompatible number of rows") );
195
196 REQUIRE_THROWS_WITH( getCompMatr2({{0,0,0,0},{0},{0},{0}}), ContainsSubstring("incompatible number of elements") );
197 REQUIRE_THROWS_WITH( getCompMatr2({{0,0,0,0,0},{0},{0},{0}}), ContainsSubstring("incompatible number of elements") );
198 }
199 }
200}
201
202
203TEST_CASE( "getDiagMatr1", TEST_CATEGORY ) {
204
205 SECTION( LABEL_CORRECTNESS ) {
206
207 constexpr int dim = 2;
208 qmatrix ref = getRandomDiagonalMatrix(dim);
209
210 SECTION( LABEL_C_INTERFACE ) {
211
212 // compile-time array
213 qcomp arr[dim] = {ref[0][0], ref[1][1] };
214 REQUIRE_AGREE( getDiagMatr1(arr), ref );
215
216 // pointer
217 qvector diags = getDiagonals(ref);
218 REQUIRE_AGREE( getDiagMatr1(diags.data()), ref );
219 }
220
221 SECTION( LABEL_CPP_INTERFACE ) {
222
223 // inline vectors
224 REQUIRE_AGREE( getDiagMatr1({ref[0][0],ref[1][1]}), ref );
225 }
226 }
227
228 SECTION( LABEL_VALIDATION ) {
229
230 SECTION( "null pointer" ) {
231
232 qcomp* ptr = nullptr;
233 REQUIRE_THROWS_WITH( getDiagMatr1(ptr), ContainsSubstring("was a null pointer") );
234 }
235
236 SECTION( "invalid dimensions" ) {
237
238 // detectable only by the C++ interface
239 qvector bad1 = {0};
240 qvector bad2 = {0,0,0};
241
242 REQUIRE_THROWS_WITH( getDiagMatr1(bad1), ContainsSubstring("Incompatible number of elements") );
243 REQUIRE_THROWS_WITH( getDiagMatr1(bad2), ContainsSubstring("Incompatible number of elements") );
244 }
245 }
246}
247
248
249TEST_CASE( "getDiagMatr2", TEST_CATEGORY ) {
250
251 SECTION( LABEL_CORRECTNESS ) {
252
253 constexpr int dim = 4;
254 qmatrix ref = getRandomDiagonalMatrix(dim);
255
256 SECTION( LABEL_C_INTERFACE ) {
257
258 // compile-time array
259 qcomp arr[dim] = {ref[0][0], ref[1][1], ref[2][2], ref[3][3] };
260 REQUIRE_AGREE( getDiagMatr2(arr), ref );
261
262 // pointer
263 qvector diags = getDiagonals(ref);
264 REQUIRE_AGREE( getDiagMatr2(diags.data()), ref );
265 }
266
267 SECTION( LABEL_CPP_INTERFACE ) {
268
269 // inline vectors
270 REQUIRE_AGREE( getDiagMatr2({ref[0][0], ref[1][1], ref[2][2], ref[3][3] }), ref );
271 }
272 }
273
274 SECTION( LABEL_VALIDATION ) {
275
276 SECTION( "null pointer" ) {
277
278 qcomp* ptr = nullptr;
279 REQUIRE_THROWS_WITH( getDiagMatr2(ptr), ContainsSubstring("was a null pointer") );
280 }
281
282 SECTION( "invalid dimensions" ) {
283
284 // detectable only by the C++ interface
285 qvector bad1 = {0,0,0};
286 qvector bad2 = {0,0,0,0,0};
287
288 REQUIRE_THROWS_WITH( getDiagMatr2(bad1), ContainsSubstring("Incompatible number of elements") );
289 REQUIRE_THROWS_WITH( getDiagMatr2(bad2), ContainsSubstring("Incompatible number of elements") );
290 }
291 }
292}
293
294
295TEST_CASE( "getInlineCompMatr1", TEST_CATEGORY ) {
296
297 SECTION( LABEL_CORRECTNESS ) {
298
299 qmatrix ref = {{1,2},{3_i,4_i}};
300
301 REQUIRE_AGREE( getInlineCompMatr1({{1,2},{3_i,4_i}}), ref );
302 }
303
304 SECTION( LABEL_VALIDATION ) {
305
306 SECTION( "invalid dimensions" ) {
307
308 // detectable only by the C++ interface
309
310 REQUIRE_THROWS_WITH( getInlineCompMatr1({{0,0}}), ContainsSubstring("Incompatible number of rows") );
311 REQUIRE_THROWS_WITH( getInlineCompMatr1({{0,0},{0,0},{0,0}}), ContainsSubstring("Incompatible number of rows") );
312
313 REQUIRE_THROWS_WITH( getInlineCompMatr1({{0,0},{0}}), ContainsSubstring("incompatible number of elements") );
314 REQUIRE_THROWS_WITH( getInlineCompMatr1({{0,0},{0,0,0}}), ContainsSubstring("incompatible number of elements") );
315 }
316 }
317}
318
319
320TEST_CASE( "getInlineCompMatr2", TEST_CATEGORY ) {
321
322 SECTION( LABEL_CORRECTNESS ) {
323
324 qmatrix ref = {
325 {1,2,3,4},
326 {5_i,6_i,7_i,8_i},
327 {-1,-2,-3,-4},
328 {-1_i,-2_i,-3_i,-4_i}};
329
330 REQUIRE_AGREE(
332 {1,2,3,4},
333 {5_i,6_i,7_i,8_i},
334 {-1,-2,-3,-4},
335 {-1_i,-2_i,-3_i,-4_i}
336 }), ref );
337 }
338
339 SECTION( LABEL_VALIDATION ) {
340
341 SECTION( "invalid dimensions" ) {
342
343 // detectable only by the C++ interface
344
345 REQUIRE_THROWS_WITH( getInlineCompMatr2({{0,0,0,0}}), ContainsSubstring("Incompatible number of rows") );
346 REQUIRE_THROWS_WITH( getInlineCompMatr2({{0,0,0,0},{0,0,0,0},{0,0,0,0}}), ContainsSubstring("Incompatible number of rows") );
347
348 REQUIRE_THROWS_WITH( getInlineCompMatr2({{0,0,0,0},{0},{0},{0}}), ContainsSubstring("incompatible number of elements") );
349 REQUIRE_THROWS_WITH( getInlineCompMatr2({{0,0,0,0,0},{0},{0},{0}}), ContainsSubstring("incompatible number of elements") );
350 }
351 }
352}
353
354
355TEST_CASE( "getInlineDiagMatr1", TEST_CATEGORY ) {
356
357 SECTION( LABEL_CORRECTNESS ) {
358
359 qmatrix ref = getDiagonalMatrix({1,2_i});
360
361 REQUIRE_AGREE( getInlineDiagMatr1({1,2_i}), ref );
362 }
363
364 SECTION( LABEL_VALIDATION ) {
365
366 SECTION( "invalid dimensions" ) {
367
368 REQUIRE_THROWS_WITH( getInlineDiagMatr1({0,0,0}), ContainsSubstring("Incompatible number of elements") );
369 }
370 }
371}
372
373
374TEST_CASE( "getInlineDiagMatr2", TEST_CATEGORY ) {
375
376 SECTION( LABEL_CORRECTNESS ) {
377
378 qmatrix ref = getDiagonalMatrix({1,2_i,-3,-4_i});
379
380 REQUIRE_AGREE( getInlineDiagMatr2({1,2_i,-3,-4_i}), ref );
381 }
382
383 SECTION( LABEL_VALIDATION ) {
384
385 SECTION( "invalid dimensions" ) {
386
387 REQUIRE_THROWS_WITH( getInlineDiagMatr2({0,0,0}), ContainsSubstring("Incompatible number of elements") );
388 REQUIRE_THROWS_WITH( getInlineDiagMatr2({0,0,0,0,0}), ContainsSubstring("Incompatible number of elements") );
389 }
390 }
391}
392
393
394TEST_CASE( "createCompMatr", TEST_CATEGORY ) {
395
396 SECTION( LABEL_CORRECTNESS ) {
397
398 // inessential to link to cached Qureg sizes, but
399 // provides a nice ballpark
400 int maxNumQubits = getNumCachedQubits();
401 int numQubits = GENERATE_COPY( range(1, maxNumQubits+1) );
402 CAPTURE( numQubits );
403
404 CompMatr matr = createCompMatr(numQubits);
405 qmatrix blank = getZeroMatrix(getPow2(numQubits));
406
407 // default elements
408 REQUIRE_AGREE( matr, blank );
409
410 // fields
411 REQUIRE( matr.numQubits == numQubits );
412 REQUIRE( matr.numRows == getPow2(numQubits) );
413
414 // default properties
415 REQUIRE( *(matr.isApproxUnitary) == -1 ); // unknown
416 REQUIRE( *(matr.isApproxHermitian) == -1 ); // unknown
417 REQUIRE( *(matr.wasGpuSynced) == 0 ); // false
418
419 // pointers
420 REQUIRE( matr.cpuElems != nullptr );
421 REQUIRE( matr.cpuElemsFlat != nullptr );
422
423 if (getQuESTEnv().isGpuAccelerated)
424 REQUIRE( matr.gpuElemsFlat != nullptr );
425 else
426 REQUIRE( matr.gpuElemsFlat == nullptr );
427
428 destroyCompMatr(matr);
429 }
430
431 SECTION( LABEL_VALIDATION ) {
432
433 SECTION( "env not initialised" ) {
434
435 // impossible to test
436 SUCCEED( );
437 }
438
439 SECTION( "too few qubits" ) {
440
441 int numQubits = GENERATE( -1, 0 );
442
443 REQUIRE_THROWS_WITH( createCompMatr(numQubits), ContainsSubstring("must target one or more qubits") );
444 }
445
446 SECTION( "too many qubits" ) {
447
448 // overflows qindex in all precisions
449 REQUIRE_THROWS_WITH( createCompMatr(50), ContainsSubstring("maximum which can be addressed by the qindex type") );
450
451 // overflows size_t in single precision (and ergo also in double and quad)
452 REQUIRE_THROWS_WITH( createCompMatr(31), ContainsSubstring("necessary memory would overflow size_t") );
453
454 // no overflows, but definitely exceeds local RAM and fails to allocate; frightens address sanitizer!
455 // note the specific error message depends on the what backend the auto-deployer tried to use (e.g.
456 // GPU-accel or distributed) and whether memory-probers realised there was insufficient memory in
457 // advance or whether it proceeded to malloc() which subsequently failed
458 #ifndef SANITIZER_IS_ACTIVE
459 REQUIRE_THROWS_WITH( createCompMatr(25),
460 ContainsSubstring("failed") ||
461 ContainsSubstring("insufficient available memory") ||
462 ContainsSubstring("available GPU memory") ||
463 ContainsSubstring("exceeds the available RAM") );
464 #endif
465 }
466 }
467}
468
469
470TEST_CASE( "createDiagMatr", TEST_CATEGORY ) {
471
472 SECTION( LABEL_CORRECTNESS ) {
473
474 // inessential to link to cached Qureg sizes, but
475 // provides a nice ballpark
476 int maxNumQubits = getNumCachedQubits();
477 int numQubits = GENERATE_COPY( range(1, maxNumQubits+1) );
478 CAPTURE( numQubits );
479
480 DiagMatr matr = createDiagMatr(numQubits);
481 qmatrix blank = getZeroMatrix(getPow2(numQubits));
482
483 // default elements
484 REQUIRE_AGREE( matr, blank );
485
486 // fields
487 REQUIRE( matr.numQubits == numQubits );
488 REQUIRE( matr.numElems == getPow2(numQubits) );
489
490 // default properties
491 REQUIRE( *(matr.isApproxUnitary) == -1 ); // unknown
492 REQUIRE( *(matr.isApproxHermitian) == -1 ); // unknown
493 REQUIRE( *(matr.isApproxNonZero) == -1 ); // unknown
494 REQUIRE( *(matr.isStrictlyNonNegative) == -1 ); // unknown
495 REQUIRE( *(matr.wasGpuSynced) == 0 ); // false
496
497 // pointers
498 REQUIRE( matr.cpuElems != nullptr );
499
500 if (getQuESTEnv().isGpuAccelerated)
501 REQUIRE( matr.gpuElems != nullptr );
502 else
503 REQUIRE( matr.gpuElems == nullptr );
504
505 destroyDiagMatr(matr);
506 }
507
508 SECTION( LABEL_VALIDATION ) {
509
510 SECTION( "env not initialised" ) {
511
512 // impossible to test
513 SUCCEED( );
514 }
515
516 SECTION( "too few qubits" ) {
517
518 int numQubits = GENERATE( -1, 0 );
519
520 REQUIRE_THROWS_WITH( createDiagMatr(numQubits), ContainsSubstring("must target one or more qubits") );
521 }
522
523 SECTION( "too many qubits" ) {
524
525 // overflows qindex in all precisions
526 REQUIRE_THROWS_WITH( createDiagMatr(100), ContainsSubstring("maximum which can be addressed by the qindex type") );
527
528 // overflows size_t in single precision (and ergo also in double and quad)
529 REQUIRE_THROWS_WITH( createDiagMatr(62), ContainsSubstring("necessary memory would overflow size_t") );
530
531 // no overflows, but definitely exceeds local RAM and fails to allocate; frightens address sanitizer!
532 // note the specific error message depends on the what backend the auto-deployer tried to use (e.g.
533 // GPU-accel or distributed) and whether memory-probers realised there was insufficient memory in
534 // advance or whether it proceeded to malloc() which subsequently failed
535 #ifndef SANITIZER_IS_ACTIVE
536 REQUIRE_THROWS_WITH( createDiagMatr(50),
537 ContainsSubstring("failed") ||
538 ContainsSubstring("insufficient available memory") ||
539 ContainsSubstring("available GPU memory") ||
540 ContainsSubstring("exceeds the available RAM") );
541 #endif
542 }
543 }
544}
545
546
547TEST_CASE( "createFullStateDiagMatr", TEST_CATEGORY ) {
548
549 SECTION( LABEL_CORRECTNESS ) {
550
551 int numQubits = GENERATE_COPY( range(1, 20) );
552 CAPTURE( numQubits );
553
554 // uses auto deployment
556
557 // check state is blank
558 bool isBlank = true;
559 for (qindex i=0; i<matr.numElemsPerNode && isBlank; i++)
560 isBlank = (matr.cpuElems[i] == qcomp(0,0));
561 REQUIRE( isBlank );
562
563 // dimensions
564 REQUIRE( matr.numQubits == numQubits );
565 REQUIRE( matr.numElems == getPow2(numQubits) );
566 REQUIRE( matr.numElemsPerNode == matr.numElems / (matr.isDistributed? getQuESTEnv().numNodes : 1) );
567
568 // default properties
569 REQUIRE( *(matr.isApproxUnitary) == -1 ); // unknown
570 REQUIRE( *(matr.isApproxHermitian) == -1 ); // unknown
571 REQUIRE( *(matr.isApproxNonZero) == -1 ); // unknown
572 REQUIRE( *(matr.isStrictlyNonNegative) == -1 ); // unknown
573 REQUIRE( *(matr.wasGpuSynced) == 0 ); // false
574
575 // pointers
576 REQUIRE( matr.cpuElems != nullptr );
577
578 int gpu = matr.isGpuAccelerated;
579 if (gpu) REQUIRE( matr.gpuElems != nullptr );
580 else REQUIRE( matr.gpuElems == nullptr );
581
583 }
584
585 SECTION( LABEL_VALIDATION ) {
586
587 SECTION( "env not initialised" ) {
588
589 // impossible to test
590 SUCCEED( );
591 }
592
593 SECTION( "too few qubits" ) {
594
595 int numQubits = GENERATE( -1, 0 );
596
597 REQUIRE_THROWS_WITH( createFullStateDiagMatr(numQubits), ContainsSubstring("must target one or more qubits") );
598 }
599
600 SECTION( "too many qubits" ) {
601
602 // overflows qindex in all precisions
603 REQUIRE_THROWS_WITH( createFullStateDiagMatr(100), ContainsSubstring("maximum which can be addressed by the qindex type") );
604
605 // overflows size_t in single precision (and ergo also in double and quad)
606 REQUIRE_THROWS_WITH( createFullStateDiagMatr(62), ContainsSubstring("memory would overflow size_t") );
607
608 // no overflows, but definitely exceeds local RAM and fails to allocate; frightens address sanitizer!
609 // note the specific error message depends on the what backend the auto-deployer tried to use (e.g.
610 // GPU-accel or distributed) and whether memory-probers realised there was insufficient memory in
611 // advance or whether it proceeded to malloc() which subsequently failed
612 #ifndef SANITIZER_IS_ACTIVE
613 REQUIRE_THROWS_WITH( createFullStateDiagMatr(50),
614 ContainsSubstring("failed") ||
615 ContainsSubstring("insufficient available memory") ||
616 ContainsSubstring("available GPU memory") ||
617 ContainsSubstring("exceeds the available RAM") ||
618 ContainsSubstring("exceeds the local available RAM") );
619 #endif
620 }
621
622 // this function chooses automatic deployment,
623 // so we cannot force illegal distribution
624 }
625}
626
627
628TEST_CASE( "createCustomFullStateDiagMatr", TEST_CATEGORY ) {
629
630 SECTION( LABEL_CORRECTNESS ) {
631
632 for (auto [label, mpi, gpu, omp] : getSupportedDeployments()) {
633
634 DYNAMIC_SECTION( label ) {
635
636 int minNumQubits = std::max({1, getLog2(getQuESTEnv().numNodes)});
637 int maxNumQubits = std::min({20, minNumQubits + 1});
638 int numQubits = GENERATE_COPY( range(minNumQubits, maxNumQubits+1) );
639 CAPTURE( numQubits );
640
641 FullStateDiagMatr matr = createCustomFullStateDiagMatr(numQubits, mpi, gpu, omp);
642
643 // check state is blank
644 bool isBlank = true;
645 for (qindex i=0; i<matr.numElemsPerNode && isBlank; i++)
646 isBlank = (matr.cpuElems[i] == qcomp(0,0));
647 REQUIRE( isBlank );
648
649 // dimensions
650 REQUIRE( matr.numQubits == numQubits );
651 REQUIRE( matr.numElems == getPow2(numQubits) );
652 REQUIRE( matr.numElemsPerNode == matr.numElems / (mpi? getQuESTEnv().numNodes : 1) );
653
654 // accelerations
655 REQUIRE( matr.isDistributed == (int) (mpi && getQuESTEnv().numNodes > 1) );
656 REQUIRE( matr.isGpuAccelerated == (int) gpu );
657 REQUIRE( matr.isMultithreaded == (int) omp );
658
659 // default properties
660 REQUIRE( *(matr.isApproxUnitary) == -1 ); // unknown
661 REQUIRE( *(matr.isApproxHermitian) == -1 ); // unknown
662 REQUIRE( *(matr.isApproxNonZero) == -1 ); // unknown
663 REQUIRE( *(matr.isStrictlyNonNegative) == -1 ); // unknown
664 REQUIRE( *(matr.wasGpuSynced) == 0 ); // false
665
666 // pointers
667 REQUIRE( matr.cpuElems != nullptr );
668
669 if (gpu) REQUIRE( matr.gpuElems != nullptr );
670 else REQUIRE( matr.gpuElems == nullptr );
671
673 }
674 }
675
676 }
677
678 SECTION( LABEL_VALIDATION ) {
679
680 SECTION( "env not initialised" ) {
681
682 // impossible to test
683 SUCCEED( );
684 }
685
686 SECTION( "too few qubits" ) {
687
688 int numQubits = GENERATE( -1, 0 );
689
690 for (auto [label, mpi, gpu, omp] : getSupportedDeployments())
691 REQUIRE_THROWS_WITH( createCustomFullStateDiagMatr(numQubits, mpi,gpu,omp), ContainsSubstring("must target one or more qubits") );
692
693 if (getQuESTEnv().numNodes > 2) { // 1 node => min=1
694 int minNumQubits = getLog2(getQuESTEnv().numNodes);
695 REQUIRE_THROWS_WITH( createCustomFullStateDiagMatr(minNumQubits-1, 1,0,0), ContainsSubstring("node would contain fewer than one element") );
696 }
697 }
698
699 SECTION( "too many qubits" ) {
700
701 for (auto [label, mpi, gpu, omp] : getSupportedDeployments()) {
702
703 // overflows qindex in all precisions
704 REQUIRE_THROWS_WITH( createCustomFullStateDiagMatr(100, mpi,gpu,omp), ContainsSubstring("maximum which can be addressed by the qindex type") );
705
706 // overflows size_t in single precision (and ergo also in double and quad)
707 REQUIRE_THROWS_WITH( createCustomFullStateDiagMatr(62, mpi,gpu,omp), ContainsSubstring("memory would overflow size_t") );
708
709 // no overflows, but definitely exceeds local RAM and fails to allocate; frightens address sanitizer!
710 // note the specific error message depends on the what backend the auto-deployer tried to use (e.g.
711 // GPU-accel or distributed) and whether memory-probers realised there was insufficient memory in
712 // advance or whether it proceeded to malloc() which subsequently failed
713 #ifndef SANITIZER_IS_ACTIVE
714 REQUIRE_THROWS_WITH( createCustomFullStateDiagMatr(50, mpi,gpu,omp),
715 ContainsSubstring("failed") ||
716 ContainsSubstring("insufficient available memory") ||
717 ContainsSubstring("available GPU memory") ||
718 ContainsSubstring("exceeds the available RAM") ||
719 ContainsSubstring("exceeds the local available RAM") );
720 #endif
721 }
722 }
723
724 SECTION( "unsupported deployments" ) {
725
726 if (!getQuESTEnv().isDistributed)
727 REQUIRE_THROWS_WITH( createCustomFullStateDiagMatr(1, 1,0,0), ContainsSubstring("non-distributed QuEST environment") );
728
729 if (!getQuESTEnv().isGpuAccelerated)
730 REQUIRE_THROWS_WITH( createCustomFullStateDiagMatr(1, 0,1,0), ContainsSubstring("non-GPU-accelerated QuEST environment") );
731
732 if (!getQuESTEnv().isMultithreaded)
733 REQUIRE_THROWS_WITH( createCustomFullStateDiagMatr(1, 0,0,1), ContainsSubstring("non-multithreaded QuEST environment") );
734 }
735 }
736}
737
738
739TEST_CASE( "destroyCompMatr", TEST_CATEGORY ) {
740
741 SECTION( LABEL_CORRECTNESS ) {
742
744 REQUIRE_NOTHROW( destroyCompMatr(m) );
745 }
746
747 SECTION( LABEL_VALIDATION ) {
748
749 // sanitizer messes with default initialisation
750 #ifndef SANITIZER_IS_ACTIVE
751 SECTION( "not created" ) {
752
753 CompMatr m;
754 REQUIRE_THROWS_WITH( destroyCompMatr(m), ContainsSubstring("Invalid CompMatr") && ContainsSubstring("not created") );
755 }
756 #endif
757 }
758}
759
760
761TEST_CASE( "destroyDiagMatr", TEST_CATEGORY ) {
762
763 SECTION( LABEL_CORRECTNESS ) {
764
766 REQUIRE_NOTHROW( destroyDiagMatr(m) );
767 }
768
769 SECTION( LABEL_VALIDATION ) {
770
771 // sanitizer messes with default initialisation
772 #ifndef SANITIZER_IS_ACTIVE
773 SECTION( "not created" ) {
774
775 DiagMatr m;
776 REQUIRE_THROWS_WITH( destroyDiagMatr(m), ContainsSubstring("Invalid DiagMatr") && ContainsSubstring("not created") );
777 }
778 #endif
779 }
780}
781
782
783TEST_CASE( "destroyFullStateDiagMatr", TEST_CATEGORY ) {
784
785 SECTION( LABEL_CORRECTNESS ) {
786
788 REQUIRE_NOTHROW( destroyFullStateDiagMatr(m) );
789 }
790
791 SECTION( LABEL_VALIDATION ) {
792
793 // sanitizer messes with default initialisation
794 #ifndef SANITIZER_IS_ACTIVE
795 SECTION( "not created" ) {
796
798 REQUIRE_THROWS_WITH( destroyFullStateDiagMatr(m), ContainsSubstring("Invalid FullStateDiagMatr") );
799 }
800 #endif
801 }
802}
803
804
805TEST_CASE( "syncCompMatr", TEST_CATEGORY ) {
806
807 SECTION( LABEL_CORRECTNESS ) {
808
809 CompMatr matr = createCompMatr(5);
810
811 REQUIRE( *(matr.wasGpuSynced) == 0 );
812
813 SECTION( "overwrites GPU elements" ) {
814
815 // to test that the GPU memory was actually overwritten,
816 // we would need a custom accessor of GPU memory, requiring
817 // the tests are CUDA-compiled - no thank you mam! It is
818 // certain this function works from the other GPU tests.
819
820 SUCCEED( );
821 }
822
823 SECTION( "sets was-synced flag" ) {
824
825 *(matr.wasGpuSynced) = 0;
826
827 syncCompMatr(matr);
828 REQUIRE( *(matr.wasGpuSynced) == 1 );
829 }
830
831 SECTION( "clears numerical flags" ) {
832
833 *(matr).isApproxHermitian = 1;
834 *(matr).isApproxUnitary = 0;
835
836 syncCompMatr(matr);
837 REQUIRE( *(matr.isApproxHermitian) == -1 );
838 REQUIRE( *(matr.isApproxUnitary) == -1 );
839 }
840
841 destroyCompMatr(matr);
842 }
843
844 SECTION( LABEL_VALIDATION ) {
845
846 // sanitizer messes with default initialisation
847 #ifndef SANITIZER_IS_ACTIVE
848 SECTION( "not created" ) {
849
850 CompMatr m;
851 REQUIRE_THROWS_WITH( syncCompMatr(m), ContainsSubstring("Invalid CompMatr") && ContainsSubstring("not created") );
852 }
853 #endif
854 }
855}
856
857
858TEST_CASE( "syncDiagMatr", TEST_CATEGORY ) {
859
860 SECTION( LABEL_CORRECTNESS ) {
861
862 DiagMatr matr = createDiagMatr(5);
863 REQUIRE( *(matr.wasGpuSynced) == 0 );
864
865 SECTION( "overwrites GPU elements" ) {
866
867 // to test that the GPU memory was actually overwritten,
868 // we would need a custom accessor of GPU memory, requiring
869 // the tests are CUDA-compiled - no thank you mam! It is
870 // certain this function works from the other GPU tests.
871
872 SUCCEED( );
873 }
874
875 SECTION( "sets was-synced flag" ) {
876
877 *(matr.wasGpuSynced) = 0;
878
879 syncDiagMatr(matr);
880 REQUIRE( *(matr.wasGpuSynced) == 1 );
881 }
882
883 SECTION( "clears numerical flags" ) {
884
885 *(matr).isApproxHermitian = 1;
886 *(matr).isApproxUnitary = 0;
887 *(matr).isApproxNonZero = 1;
888 *(matr).isStrictlyNonNegative = 0;
889
890 syncDiagMatr(matr);
891 REQUIRE( *(matr.isApproxHermitian) == -1 );
892 REQUIRE( *(matr.isApproxUnitary) == -1 );
893 REQUIRE( *(matr.isApproxNonZero) == -1 );
894 REQUIRE( *(matr.isStrictlyNonNegative) == -1 );
895 }
896
897 destroyDiagMatr(matr);
898 }
899
900 SECTION( LABEL_VALIDATION ) {
901
902 // sanitizer messes with default initialisation
903 #ifndef SANITIZER_IS_ACTIVE
904 SECTION( "not created" ) {
905
906 DiagMatr m;
907 REQUIRE_THROWS_WITH( syncDiagMatr(m), ContainsSubstring("Invalid DiagMatr") && ContainsSubstring("not created") );
908 }
909 #endif
910 }
911}
912
913
914TEST_CASE( "syncFullStateDiagMatr", TEST_CATEGORY ) {
915
916 SECTION( LABEL_CORRECTNESS ) {
917
918 for (auto& [label, matrix]: getCachedFullStateDiagMatrs()) {
919
920 DYNAMIC_SECTION( label ) {
921
922 *(matrix.wasGpuSynced) = 0;
923 *(matrix).isApproxHermitian = 1;
924 *(matrix).isApproxUnitary = 0;
925 *(matrix).isApproxNonZero = 1;
926 *(matrix).isStrictlyNonNegative = 0;
927
928 syncFullStateDiagMatr(matrix);
929 REQUIRE( *(matrix.wasGpuSynced) == 1 );
930
931 REQUIRE( *(matrix.isApproxHermitian) == -1 );
932 REQUIRE( *(matrix.isApproxUnitary) == -1 );
933 REQUIRE( *(matrix.isApproxNonZero) == -1 );
934 REQUIRE( *(matrix.isStrictlyNonNegative) == -1 );
935
936 // to test that the GPU memory was actually overwritten,
937 // we would need a custom accessor of GPU memory, requiring
938 // the tests are CUDA-compiled - no thank you mam! It is
939 // certain this function works from the other GPU tests.
940 }
941 }
942 }
943
944 SECTION( LABEL_VALIDATION ) {
945
946 // sanitizer messes with default initialisation
947 #ifndef SANITIZER_IS_ACTIVE
948 SECTION( "not created" ) {
949
951 REQUIRE_THROWS_WITH( syncFullStateDiagMatr(m), ContainsSubstring("Invalid FullStateDiagMatr") );
952 }
953 #endif
954 }
955}
956
957
958TEST_CASE( "setCompMatr", TEST_CATEGORY ) {
959
960 SECTION( LABEL_CORRECTNESS ) {
961
962 int numQubits = GENERATE( range(1,6) );
963 CAPTURE( numQubits );
964
965 CompMatr matr = createCompMatr(numQubits);
966 REQUIRE( *(matr.wasGpuSynced) == 0 );
967
968 int dim = getPow2(numQubits);
969 qmatrix ref = getRandomMatrix(dim);
970
971 SECTION( LABEL_C_INTERFACE ) {
972
973 // nested pointers
974 qcomp** ptrs = (qcomp**) malloc(dim * sizeof *ptrs);
975 for (int i=0; i<dim; i++) {
976 ptrs[i] = (qcomp*) malloc(dim * sizeof **ptrs);
977 for (int j=0; j<dim; j++)
978 ptrs[i][j] = ref[i][j];
979 }
980 setCompMatr(matr, ptrs);
981 REQUIRE_AGREE( matr, ref );
982 REQUIRE( *(matr.wasGpuSynced) == 1 );
983
984 // cannot test 2D VLAs in this C++ file
985
986 // cleanup
987 for (int i=0; i<dim; i++)
988 free(ptrs[i]);
989 free(ptrs);
990 }
991
992 SECTION( LABEL_CPP_INTERFACE ) {
993
994 // nested vectors
995 setCompMatr( matr, getZeroMatrix(dim) ); // clear
996 setCompMatr( matr, ref );
997 REQUIRE_AGREE( matr, ref );
998 REQUIRE( *(matr.wasGpuSynced) == 1 );
999 }
1000
1001 destroyCompMatr(matr);
1002 }
1003
1004 SECTION( LABEL_VALIDATION ) {
1005
1006 CompMatr matr = createCompMatr(1);
1007
1008 /// @todo fails in MSVC for unknown reason
1009 #ifndef _MSC_VER
1010 // sanitizer messes with default initialisation
1011 #ifndef SANITIZER_IS_ACTIVE
1012 SECTION( "not created" ) {
1013
1014 CompMatr bad;
1015 qcomp** dummy;
1016 REQUIRE_THROWS_WITH( setCompMatr(bad, dummy), ContainsSubstring("Invalid CompMatr") && ContainsSubstring("not created") );
1017 }
1018 #endif
1019 #endif
1020
1021 SECTION( "null pointer" ) {
1022
1023 qcomp** ptr = nullptr;
1024 REQUIRE_THROWS_WITH( setCompMatr(matr, ptr), ContainsSubstring("was a null pointer") );
1025
1026 qcomp* arr[1] = {nullptr};
1027 REQUIRE_THROWS_WITH( setCompMatr(matr, arr), ContainsSubstring("contained a null pointer") );
1028 }
1029
1030 SECTION( "invalid dimensions" ) {
1031
1032 // detectable only by the C++ interface
1033
1034 REQUIRE_NOTHROW( setCompMatr(matr, {{1,2},{3,4}}) );
1035
1036 REQUIRE_THROWS_WITH( setCompMatr(matr,{{1,2}}), ContainsSubstring("Incompatible number of rows") );
1037 REQUIRE_THROWS_WITH( setCompMatr(matr, {{1,2},{3,4},{5,6}}), ContainsSubstring("Incompatible number of rows") );
1038
1039 REQUIRE_THROWS_WITH( setCompMatr(matr, {{0,0},{0}}), ContainsSubstring("incompatible number of elements") );
1040 REQUIRE_THROWS_WITH( setCompMatr(matr, {{0,0},{0,0,0}}), ContainsSubstring("incompatible number of elements") );
1041 }
1042
1043 destroyCompMatr(matr);
1044 }
1045}
1046
1047
1048TEST_CASE( "setDiagMatr", TEST_CATEGORY ) {
1049
1050 SECTION( LABEL_CORRECTNESS ) {
1051
1052 int numQubits = GENERATE( range(1,6) );
1053 CAPTURE( numQubits );
1054
1055 DiagMatr matr = createDiagMatr(numQubits);
1056 REQUIRE( *(matr.wasGpuSynced) == 0 );
1057
1058 int dim = getPow2(numQubits);
1059 qmatrix ref = getRandomDiagonalMatrix(dim);
1060
1061 SECTION( LABEL_C_INTERFACE ) {
1062
1063 // pointer
1064 qvector diags = getDiagonals(ref);
1065 setDiagMatr(matr, diags.data());
1066 REQUIRE_AGREE( matr, ref );
1067 REQUIRE( *(matr.wasGpuSynced) == 1 );
1068 }
1069
1070 SECTION( LABEL_CPP_INTERFACE ) {
1071
1072 // vector
1073 setDiagMatr(matr, getZeroVector(dim)); // clear
1074 setDiagMatr(matr, getDiagonals(ref));
1075 REQUIRE_AGREE( matr, ref );
1076 REQUIRE( *(matr.wasGpuSynced) == 1 );
1077 }
1078
1079 destroyDiagMatr(matr);
1080 }
1081
1082 SECTION( LABEL_VALIDATION ) {
1083
1084 DiagMatr matr = createDiagMatr(1);
1085
1086 // sanitizer messes with default initialisation
1087 #ifndef SANITIZER_IS_ACTIVE
1088 SECTION( "not created" ) {
1089
1090 DiagMatr bad;
1091 qcomp* dummy;
1092 REQUIRE_THROWS_WITH( setDiagMatr(bad, dummy), ContainsSubstring("Invalid DiagMatr") && ContainsSubstring("not created") );
1093 }
1094 #endif
1095
1096 SECTION( "null pointer" ) {
1097
1098 qcomp* ptr = nullptr;
1099 REQUIRE_THROWS_WITH( setDiagMatr(matr, ptr), ContainsSubstring("was a null pointer") );
1100 }
1101
1102 SECTION( "invalid dimensions" ) {
1103
1104 // detectable only by the C++ interface
1105
1106 REQUIRE_NOTHROW( setDiagMatr(matr, {1,2}) );
1107
1108 REQUIRE_THROWS_WITH( setDiagMatr(matr, {1}), ContainsSubstring("Incompatible number of elements") );
1109 REQUIRE_THROWS_WITH( setDiagMatr(matr, {1,2,3}), ContainsSubstring("Incompatible number of elements") );
1110 }
1111
1112 destroyDiagMatr(matr);
1113 }
1114}
1115
1116
1117TEST_CASE( "setInlineCompMatr", TEST_CATEGORY ) {
1118
1119 SECTION( LABEL_CORRECTNESS ) {
1120
1121 CompMatr matr = createCompMatr(1);
1122 REQUIRE( *(matr.wasGpuSynced) == 0 );
1123
1124 setInlineCompMatr( matr, 1, {{1,2},{3,4}} );
1125 REQUIRE_AGREE( matr, {{1,2},{3,4}} );
1126 REQUIRE( *(matr.wasGpuSynced) == 1 );
1127
1128 destroyCompMatr(matr);
1129 }
1130
1131 SECTION( LABEL_VALIDATION ) {
1132
1133 CompMatr matr = createCompMatr(1);
1134
1135 /// @todo fails in MSVC for unknown reason
1136 #ifndef _MSC_VER
1137 // sanitizer messes with default initialisation
1138 #ifndef SANITIZER_IS_ACTIVE
1139 SECTION( "not created" ) {
1140
1141 CompMatr bad;
1142 REQUIRE_THROWS_WITH( setInlineCompMatr(bad, 1, {{1,2},{3,4}}), ContainsSubstring("Invalid CompMatr") && ContainsSubstring("not created") );
1143 }
1144 #endif
1145 #endif
1146
1147 SECTION( "mismatching dimension" ) {
1148
1149 REQUIRE_THROWS_WITH( setInlineCompMatr(matr, 2, {{1,2},{3,4}}), ContainsSubstring("declared number of qubits") && ContainsSubstring("differs") );
1150 }
1151
1152 SECTION( "invalid dimensions" ) {
1153
1154 // detectable only by the C++ interface
1155
1156 REQUIRE_NOTHROW( setInlineCompMatr(matr, 1, {{1,2},{3,4}}) );
1157
1158 REQUIRE_THROWS_WITH( setInlineCompMatr(matr, 1, {{1,2}}), ContainsSubstring("Incompatible number of rows") );
1159 REQUIRE_THROWS_WITH( setInlineCompMatr(matr, 1, {{1,2},{3,4},{5,6}}), ContainsSubstring("Incompatible number of rows") );
1160
1161 REQUIRE_THROWS_WITH( setInlineCompMatr(matr, 1, {{1},{2}}), ContainsSubstring("One or more rows contained an incompatible number of elements") );
1162 REQUIRE_THROWS_WITH( setInlineCompMatr(matr, 1, {{1,2,3},{4,5,6}}), ContainsSubstring("One or more rows contained an incompatible number of elements") );
1163 }
1164
1165 destroyCompMatr(matr);
1166 }
1167}
1168
1169
1170TEST_CASE( "setInlineDiagMatr", TEST_CATEGORY ) {
1171
1172 SECTION( LABEL_CORRECTNESS ) {
1173
1174 DiagMatr matr = createDiagMatr(1);
1175 REQUIRE( *(matr.wasGpuSynced) == 0 );
1176
1177 setInlineDiagMatr( matr, 1, {1,2_i} );
1178 REQUIRE_AGREE( matr, {{1,0},{0,2_i}} );
1179 REQUIRE( *(matr.wasGpuSynced) == 1 );
1180
1181 destroyDiagMatr(matr);
1182 }
1183
1184 SECTION( LABEL_VALIDATION ) {
1185
1186 DiagMatr matr = createDiagMatr(1);
1187
1188 /// @todo fails in MSVC for unknown reason
1189 #ifndef _MSC_VER
1190 // sanitizer messes with default initialisation
1191 #ifndef SANITIZER_IS_ACTIVE
1192 SECTION( "not created" ) {
1193
1194 DiagMatr bad;
1195 REQUIRE_THROWS_WITH( setInlineDiagMatr(bad, 1, {1,2}), ContainsSubstring("Invalid DiagMatr") && ContainsSubstring("not created") );
1196 }
1197 #endif
1198 #endif
1199
1200 SECTION( "mismatching dimension" ) {
1201
1202 REQUIRE_THROWS_WITH( setInlineDiagMatr(matr, 2, {1,2}), ContainsSubstring("declared number of qubits") && ContainsSubstring("differs") );
1203 }
1204
1205 SECTION( "invalid dimensions" ) {
1206
1207 // detectable only by the C++ interface
1208
1209 REQUIRE_NOTHROW( setInlineDiagMatr(matr, 1, {1,2}) );
1210
1211 REQUIRE_THROWS_WITH( setInlineDiagMatr(matr, 1, {1}), ContainsSubstring("Incompatible number of elements") );
1212 REQUIRE_THROWS_WITH( setInlineDiagMatr(matr, 1, {1,2,3}), ContainsSubstring("Incompatible number of elements") );
1213 }
1214
1215 destroyDiagMatr(matr);
1216 }
1217}
1218
1219
1220TEST_CASE( "createInlineCompMatr", TEST_CATEGORY ) {
1221
1222 SECTION( LABEL_CORRECTNESS ) {
1223
1224 CompMatr matr = createInlineCompMatr(1, {{1,2},{3,4}});
1225
1226 REQUIRE_AGREE( matr, {{1,2},{3,4}} );
1227 REQUIRE( *(matr.wasGpuSynced) == 1 );
1228
1229 destroyCompMatr(matr);
1230 }
1231
1232 SECTION( LABEL_VALIDATION ) {
1233
1234 SECTION( "env not initialised" ) {
1235
1236 // impossible to test
1237 SUCCEED( );
1238 }
1239
1240 SECTION( "too few qubits" ) {
1241
1242 int numQubits = GENERATE( -1, 0 );
1243
1244 REQUIRE_THROWS_WITH( createInlineCompMatr(numQubits, {{1}}), ContainsSubstring("must target one or more qubits") );
1245 }
1246
1247 SECTION( "mismatching dimension" ) {
1248
1249 REQUIRE_THROWS_WITH( createInlineCompMatr(2, {{1,2},{3,4}}), ContainsSubstring("Incompatible number of rows") );
1250 }
1251 }
1252}
1253
1254
1255TEST_CASE( "createInlineDiagMatr", TEST_CATEGORY ) {
1256
1257 SECTION( LABEL_CORRECTNESS ) {
1258
1259 DiagMatr matr = createInlineDiagMatr(1, {1,2_i});
1260
1261 REQUIRE_AGREE( matr, {{1,0},{0,2_i}} );
1262 REQUIRE( *(matr.wasGpuSynced) == 1 );
1263
1264 destroyDiagMatr(matr);
1265 }
1266
1267 SECTION( LABEL_VALIDATION ) {
1268
1269 SECTION( "env not initialised" ) {
1270
1271 // impossible to test
1272 SUCCEED( );
1273 }
1274
1275 SECTION( "too few qubits" ) {
1276
1277 int numQubits = GENERATE( -1, 0 );
1278
1279 REQUIRE_THROWS_WITH( createInlineDiagMatr(numQubits, {1}), ContainsSubstring("must target one or more qubits") );
1280 }
1281
1282 SECTION( "mismatching dimension" ) {
1283
1284 REQUIRE_THROWS_WITH( createInlineDiagMatr(2, {1,2}), ContainsSubstring("Incompatible number of elements") );
1285 }
1286 }
1287}
1288
1289
1290/** @} (end defgroup) */
1291
1292
1293
1294/**
1295 * @todo
1296 * UNTESTED FUNCTIONS
1297 */
1298
1299
1300void setFullStateDiagMatr(FullStateDiagMatr out, qindex startInd, qcomp* in, qindex numElems);
1301void setFullStateDiagMatr(FullStateDiagMatr out, qindex startInd, std::vector<qcomp> in);
1302
1303void setInlineFullStateDiagMatr(FullStateDiagMatr matr, qindex startInd, qindex numElems, std::vector<qcomp> in);
1304
1305
1306void setDiagMatrFromMultiVarFunc(DiagMatr out, qcomp (*func)(qindex*), int* numQubitsPerVar, int numVars, int areSigned);
1307
1308void setDiagMatrFromMultiDimLists(DiagMatr out, void* lists, int* numQubitsPerDim, int numDims);
1309
1310
1312
1314
1315void setFullStateDiagMatrFromMultiVarFunc(FullStateDiagMatr out, qcomp (*func)(qindex*), int* numQubitsPerVar, int numVars, int areSigned);
1316
1317void setFullStateDiagMatrFromMultiDimLists(FullStateDiagMatr out, void* lists, int* numQubitsPerDim, int numDims);
1318
1319
1320void reportCompMatr1(CompMatr1 matrix);
1321void reportCompMatr2(CompMatr2 matrix);
1322void reportCompMatr(CompMatr matrix);
1323void reportDiagMatr1(DiagMatr1 matrix);
1324void reportDiagMatr2(DiagMatr2 matrix);
1325void reportDiagMatr(DiagMatr matrix);
QuESTEnv getQuESTEnv()
FullStateDiagMatr createCustomFullStateDiagMatr(int numQubits, int useDistrib, int useGpuAccel, int useMultithread)
Definition matrices.cpp:318
DiagMatr createInlineDiagMatr(int numQb, std::vector< qcomp > elems)
FullStateDiagMatr createFullStateDiagMatr(int numQubits)
Definition matrices.cpp:323
CompMatr createInlineCompMatr(int numQb, std::vector< std::vector< qcomp > > elems)
CompMatr createCompMatr(int numQubits)
Definition matrices.cpp:213
DiagMatr createDiagMatr(int numQubits)
Definition matrices.cpp:248
FullStateDiagMatr createFullStateDiagMatrFromPauliStrSum(PauliStrSum in)
Definition matrices.cpp:651
void destroyDiagMatr(DiagMatr matrix)
Definition matrices.cpp:399
void destroyFullStateDiagMatr(FullStateDiagMatr matrix)
Definition matrices.cpp:400
void destroyCompMatr(CompMatr matrix)
Definition matrices.cpp:398
static CompMatr2 getCompMatr2(qcomp **in)
Definition matrices.h:351
static CompMatr1 getCompMatr1(qcomp **in)
Definition matrices.h:325
static DiagMatr2 getDiagMatr2(qcomp *in)
Definition matrices.h:403
CompMatr1 getInlineCompMatr1({{ matrix }})
CompMatr2 getInlineCompMatr2({{ matrix }})
DiagMatr2 getInlineDiagMatr2({ list })
static DiagMatr1 getDiagMatr1(qcomp *in)
Definition matrices.h:378
DiagMatr1 getInlineDiagMatr1({ list })
void reportCompMatr2(CompMatr2 matrix)
Definition matrices.cpp:778
void reportDiagMatr1(DiagMatr1 matrix)
Definition matrices.cpp:780
void reportCompMatr(CompMatr matrix)
Definition matrices.cpp:779
void reportDiagMatr2(DiagMatr2 matrix)
Definition matrices.cpp:781
void reportCompMatr1(CompMatr1 matrix)
Definition matrices.cpp:777
void reportDiagMatr(DiagMatr matrix)
Definition matrices.cpp:782
void reportFullStateDiagMatr(FullStateDiagMatr matr)
Definition matrices.cpp:783
void setInlineDiagMatr(DiagMatr matr, int numQb, std::vector< qcomp > in)
void setFullStateDiagMatrFromMultiDimLists(FullStateDiagMatr out, void *lists, int *numQubitsPerDim, int numDims)
Definition matrices.cpp:723
void setDiagMatrFromMultiDimLists(DiagMatr out, void *lists, int *numQubitsPerDim, int numDims)
Definition matrices.cpp:701
void setFullStateDiagMatrFromMultiVarFunc(FullStateDiagMatr out, qcomp(*func)(qindex *), int *numQubitsPerVar, int numVars, int areSigned)
Definition matrices.cpp:687
void setInlineCompMatr(CompMatr matr, int numQb, std::vector< std::vector< qcomp > > in)
void setDiagMatr(DiagMatr out, qcomp *in)
Definition matrices.cpp:431
void setCompMatr(CompMatr matr, qcomp **vals)
Definition matrices.cpp:423
void setFullStateDiagMatr(FullStateDiagMatr out, qindex startInd, qcomp *in, qindex numElems)
Definition matrices.cpp:443
void setDiagMatrFromMultiVarFunc(DiagMatr out, qcomp(*func)(qindex *), int *numQubitsPerVar, int numVars, int areSigned)
Definition matrices.cpp:667
void setFullStateDiagMatrFromPauliStrSum(FullStateDiagMatr out, PauliStrSum in)
Definition matrices.cpp:634
void setInlineFullStateDiagMatr(FullStateDiagMatr matr, qindex startInd, qindex numElems, std::vector< qcomp > in)
void syncFullStateDiagMatr(FullStateDiagMatr matr)
Definition matrices.cpp:375
void syncDiagMatr(DiagMatr matr)
Definition matrices.cpp:374
void syncCompMatr(CompMatr matr)
Definition matrices.cpp:373
qmatrix getZeroMatrix(size_t dim)
Definition qmatrix.cpp:18
TEST_CASE("getCompMatr1", TEST_CATEGORY)
Definition matrices.cpp:51
int * wasGpuSynced
Definition matrices.h:112
int * isApproxNonZero
Definition matrices.h:170
int * isStrictlyNonNegative
Definition matrices.h:171
int * wasGpuSynced
Definition matrices.h:178