405 {
406
407 SECTION( LABEL_CORRECTNESS ) {
408
410
411 for (auto [deployLabel, mpi, gpu, omp] : getSupportedDeployments()) {
412
413 int isDenseMatr = GENERATE( 0, 1 );
414
415 std::string quregLabel = (isDenseMatr)? LABEL_STATEVEC : LABEL_DENSMATR;
416 std::string secLabel = quregLabel + LABEL_DELIMITER + deployLabel;
417
418 SECTION( secLabel ) {
419
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 );
424
426
427
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) );
435
436
437 REQUIRE( qureg.isMultithreaded == omp );
438 REQUIRE( qureg.isGpuAccelerated == gpu );
439 REQUIRE( (qureg.isDistributed == mpi || env.numNodes == 1) );
440
441
442 if (mpi) {
443 REQUIRE( qureg.rank == env.rank );
444 REQUIRE( qureg.numNodes == env.numNodes );
445 REQUIRE( qureg.numAmpsPerNode == qureg.numAmps / env.numNodes );
446 } else {
447 REQUIRE( qureg.rank == 0 );
448 REQUIRE( qureg.numNodes == 1 );
449 REQUIRE( qureg.numAmpsPerNode == qureg.numAmps );
450 }
451
452
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 );
460
461
462 if (isDenseMatr) {
463 qmatrix ref =
getZeroMatrix(getPow2(numQubits)); ref[0][0] = 1;
464 REQUIRE_AGREE( qureg, ref );
465 } else {
466 qvector ref = getZeroVector(getPow2(numQubits)); ref[0] = 1;
467 REQUIRE_AGREE( qureg, ref );
468 }
469
471 }
472 }
473 }
474
475 SECTION( LABEL_VALIDATION ) {
476
477 SECTION( "env not initialised" ) {
478
479
480 SUCCEED( );
481 }
482
483 SECTION( "invalid isDensityMatrix flag" ) {
484
485 int isDensMatr = GENERATE( -1, 2 );
486
487 REQUIRE_THROWS_WITH(
createCustomQureg(10, isDensMatr, 0,0,0), ContainsSubstring(
"isDensityMatrix") );
488 }
489
490 SECTION( "unsupported deployment" ) {
491
493 const int numQubits = 10;
494 const int isDensMatr = 0;
495
496 if (!env.isDistributed)
497 REQUIRE_THROWS_WITH(
createCustomQureg(numQubits,isDensMatr, 1,0,0), ContainsSubstring(
"non-distributed") );
498
499 if (!env.isGpuAccelerated)
500 REQUIRE_THROWS_WITH(
createCustomQureg(numQubits,isDensMatr, 0,1,0), ContainsSubstring(
"non-GPU") );
501
502 if (!env.isMultithreaded)
503 REQUIRE_THROWS_WITH(
createCustomQureg(numQubits,isDensMatr, 0,0,1), ContainsSubstring(
"non-multithreaded") );
504 }
505
506 SECTION( "too few qubits" ) {
507
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") );
510
512 if (numNodes > 2) {
513 int minNumQubits = getLog2(numNodes);
514 int useDistrib = 1;
515 REQUIRE_THROWS_WITH(
createCustomQureg(minNumQubits-1,0, useDistrib,0,0), ContainsSubstring(
"each node would contain fewer than one amplitude") );
516 }
517 }
518
519 SECTION( "too many qubits" ) {
520
521
522 REQUIRE_THROWS_WITH(
createCustomQureg(100, 0, 0,0,0), ContainsSubstring(
"qindex") );
523 REQUIRE_THROWS_WITH(
createCustomQureg(50, 1, 0,0,0), ContainsSubstring(
"qindex") );
524
525
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") );
528
529
530
531
532
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") );
536 #endif
537 }
538 }
539}
Qureg createCustomQureg(int numQubits, int isDensMatr, int useDistrib, int useGpuAccel, int useMultithread)
qmatrix getZeroMatrix(size_t dim)