| 1759 | |
| 1760 | |
| 1761 | void reorderReducedQureg(Qureg inQureg, Qureg outQureg, vector<int> allTargs, vector<int> suffixTargs) { |
| 1762 | |
| 1763 | /// @todo |
| 1764 | /// this function performs a sequence of SWAPs which are NOT necessarily upon disjoint qubits, |
| 1765 | /// and ergo do not commute. We still however may be able to effect this more efficiently in |
| 1766 | /// a single communicating operation rather than this sequence of SWAP gates, and might still |
| 1767 | /// even be able to use cuQuantum's distributed bit index swaps API. Check this! |
| 1768 | |
| 1769 | // determine the relative ordering of outQureg's remaining qubits |
| 1770 | auto remainingQubits = getNonTracedQubitOrder(inQureg, allTargs, suffixTargs); |
| 1771 | |
| 1772 | // perform additional swaps to re-order the remaining qubits (heuristically starting from back) |
| 1773 | for (int qubit=(int)remainingQubits.size(); qubit-- != 0; ) { |
| 1774 | |
| 1775 | // locate the next qubit which is out of its sorted position |
| 1776 | if (remainingQubits[qubit] == qubit) |
| 1777 | continue; |
| 1778 | |
| 1779 | // qubit is misplaced; locate its position among the remaining qubits |
| 1780 | int pair = 0; |
| 1781 | while (remainingQubits[pair] != qubit) |
| 1782 | pair++; |
| 1783 | |
| 1784 | // and swap it directly to its required position, triggering any communication scenario (I think) |
| 1785 | localiser_statevec_anyCtrlSwap(outQureg, {}, {}, qubit, pair); |
| 1786 | std::swap(remainingQubits[qubit], remainingQubits[pair]); |
| 1787 | } |
| 1788 | } |
| 1789 | |
| 1790 | |
| 1791 | void partialTraceOnSuffix(Qureg inQureg, Qureg outQureg, vector<int> ketTargs) { |
no test coverage detected