| 1406 | |
| 1407 | |
| 1408 | void mixDensityMatrixWithStatevector(qreal outProb, Qureg out, qreal inProb, Qureg in) { |
| 1409 | |
| 1410 | // we can handle 3 out of 4 possible combinations of distribution, |
| 1411 | // and accelerator.hpp will handle every combination of GPU-accel |
| 1412 | bool outDist = out.isDistributed; |
| 1413 | bool inDist = in.isDistributed; |
| 1414 | |
| 1415 | // illegal to distribute only the smaller Qureg; 'out' has no buffer space to receive it. |
| 1416 | // in theory, we could allocate a temporary receive buffer since it is merely quadratically |
| 1417 | // smaller than 'out' so will be a negligible memory overhead; but this scenario (having a |
| 1418 | // smaller distributed Qureg) is completely ludicrous and unworth supporting |
| 1419 | if (!outDist && inDist) |
| 1420 | error_mixQuregsAreLocalDensMatrAndDistribStatevec(); |
| 1421 | |
| 1422 | // both non-distributed is trivial |
| 1423 | if (!outDist && !inDist) |
| 1424 | accel_densmatr_mixQureg_subB(outProb, out, inProb, in); |
| 1425 | |
| 1426 | // both distributed requires broadcasting 'in' into every node's 'out' buffer |
| 1427 | if (outDist && inDist) { |
| 1428 | comm_combineAmpsIntoBuffer(out, in); // uses same buffer that subC() consults |
| 1429 | accel_densmatr_mixQureg_subC(outProb, out, inProb); |
| 1430 | } |
| 1431 | |
| 1432 | // only 'out' being distributed means simulation is embarrasingly parallel, |
| 1433 | // because the full 'in' is already known on every node |
| 1434 | if (outDist && !inDist) |
| 1435 | accel_densmatr_mixQureg_subD(outProb, out, inProb, in); |
| 1436 | } |
| 1437 | |
| 1438 | |
| 1439 | void localiser_densmatr_mixQureg(qreal outProb, Qureg out, qreal inProb, Qureg in) { |
no test coverage detected