| 497 | |
| 498 | |
| 499 | void localiser_statevec_getAmps(qcomp* outAmps, Qureg qureg, qindex globalStartInd, qindex globalNumAmps) { |
| 500 | |
| 501 | // we do not assert state-vec, since the density matrix routine re-uses this function |
| 502 | |
| 503 | // when not distributed, all nodes merely perform direct local overwrite and finish |
| 504 | if (!qureg.isDistributed) { |
| 505 | accel_statevec_getAmps_sub(outAmps, qureg, globalStartInd, globalNumAmps); |
| 506 | return; |
| 507 | } |
| 508 | |
| 509 | // when distributed, each node will broadcast their overlap (which may be zero) with the global range |
| 510 | int myRank = comm_getRank(); |
| 511 | int numNodes = comm_getNumNodes(); |
| 512 | |
| 513 | // which they first overwrite into their local copies of out (may involve a GPU-to-CPU copy) |
| 514 | if (util_areAnyVectorElemsWithinNode(myRank, qureg.numAmpsPerNode, globalStartInd, globalNumAmps)) { |
| 515 | auto localInds = util_getLocalIndRangeOfVectorElemsWithinNode(myRank, qureg.numAmpsPerNode, globalStartInd, globalNumAmps); |
| 516 | accel_statevec_getAmps_sub(&outAmps[localInds.localDuplicStartInd], qureg, localInds.localDistribStartInd, localInds.numElems); |
| 517 | } |
| 518 | |
| 519 | // determine the overlap with each node (i.e. which amps, if any, they contribute) |
| 520 | vector<qindex> globalRecvInds(numNodes); |
| 521 | vector<qindex> localSendInds (numNodes); |
| 522 | vector<qindex> numAmpsPerRank(numNodes, 0); // default = zero contributed amps |
| 523 | |
| 524 | for (int sendRank=0; sendRank<numNodes; sendRank++) { |
| 525 | |
| 526 | if (!util_areAnyVectorElemsWithinNode(sendRank, qureg.numAmpsPerNode, globalStartInd, globalNumAmps)) |
| 527 | continue; |
| 528 | |
| 529 | auto inds = util_getLocalIndRangeOfVectorElemsWithinNode(sendRank, qureg.numAmpsPerNode, globalStartInd, globalNumAmps); |
| 530 | globalRecvInds[sendRank] = inds.localDuplicStartInd; |
| 531 | localSendInds [sendRank] = inds.localDistribStartInd; |
| 532 | numAmpsPerRank[sendRank] = inds.numElems; |
| 533 | } |
| 534 | |
| 535 | // contributor nodes broadcast, all nodes receive, so that every node populates 'outAmps' fully |
| 536 | comm_combineSubArrays(outAmps, globalRecvInds, localSendInds, numAmpsPerRank); |
| 537 | } |
| 538 | |
| 539 | |
| 540 | void localiser_densmatr_getAmps(qcomp** outAmps, Qureg qureg, qindex startRow, qindex startCol, qindex numRows, qindex numCols) { |
no test coverage detected