50 long long int innerMask = 1LL << targetQubit;
53 long long int thisTask;
54 long long int thisPattern;
55 long long int totMask = innerMask|outerMask;
58 # pragma omp parallel \
60 shared (innerMask,outerMask,totMask,qureg,retain) \
61 private (thisTask,thisPattern)
65 # pragma omp for schedule (static)
67 for (thisTask=0; thisTask<numTasks; thisTask++){
69 if ((thisPattern==innerMask) || (thisPattern==outerMask)){
80 qreal retain=1-dephase;
85 qreal retain=1-dephase;
88 long long int innerMaskQubit1 = 1LL << qubit1;
90 long long int innerMaskQubit2 = 1LL << qubit2;
92 long long int totMaskQubit1 = innerMaskQubit1|outerMaskQubit1;
93 long long int totMaskQubit2 = innerMaskQubit2|outerMaskQubit2;
95 long long int thisTask;
96 long long int thisPatternQubit1, thisPatternQubit2;
99 # pragma omp parallel \
101 shared (innerMaskQubit1,outerMaskQubit1,totMaskQubit1,innerMaskQubit2,outerMaskQubit2, \
102 totMaskQubit2,qureg,retain) \
103 private (thisTask,thisPatternQubit1,thisPatternQubit2)
107 # pragma omp for schedule (static)
109 for (thisTask=0; thisTask<numTasks; thisTask++){
114 if ( (thisPatternQubit1==innerMaskQubit1) || (thisPatternQubit1==outerMaskQubit1) ||
115 (thisPatternQubit2==innerMaskQubit2) || (thisPatternQubit2==outerMaskQubit2) ){
126 qreal retain=1-depolLevel;
129 long long int innerMask = 1LL << targetQubit;
131 long long int totMask = innerMask|outerMask;
133 long long int thisTask;
134 long long int partner;
135 long long int thisPattern;
137 qreal realAv, imagAv;
140 # pragma omp parallel \
142 shared (innerMask,outerMask,totMask,qureg,retain,depolLevel) \
143 private (thisTask,partner,thisPattern,realAv,imagAv)
147 # pragma omp for schedule (static)
149 for (thisTask=0; thisTask<numTasks; thisTask++){
151 if ((thisPattern==innerMask) || (thisPattern==outerMask)){
157 if ((thisTask&totMask)==0){
159 partner = thisTask | totMask;
160 realAv = (qureg.
stateVec.real[thisTask] + qureg.
stateVec.real[partner]) /2 ;
161 imagAv = (qureg.
stateVec.imag[thisTask] + qureg.
stateVec.imag[partner]) /2 ;
163 qureg.
stateVec.real[thisTask] = retain*qureg.
stateVec.real[thisTask] + depolLevel*realAv;
164 qureg.
stateVec.imag[thisTask] = retain*qureg.
stateVec.imag[thisTask] + depolLevel*imagAv;
166 qureg.
stateVec.real[partner] = retain*qureg.
stateVec.real[partner] + depolLevel*realAv;
167 qureg.
stateVec.imag[partner] = retain*qureg.
stateVec.imag[partner] + depolLevel*imagAv;
175 qreal retain=1-damping;
176 qreal dephase=sqrt(retain);
179 long long int innerMask = 1LL << targetQubit;
181 long long int totMask = innerMask|outerMask;
183 long long int thisTask;
184 long long int partner;
185 long long int thisPattern;
190 # pragma omp parallel \
192 shared (innerMask,outerMask,totMask,qureg,retain,damping,dephase) \
193 private (thisTask,partner,thisPattern)
197 # pragma omp for schedule (static)
199 for (thisTask=0; thisTask<numTasks; thisTask++){
201 if ((thisPattern==innerMask) || (thisPattern==outerMask)){
207 if ((thisTask&totMask)==0){
209 partner = thisTask | totMask;
232 long long int sizeInnerBlock, sizeInnerHalfBlock;
233 long long int sizeOuterColumn, sizeOuterHalfColumn;
234 long long int thisInnerBlock,
237 thisIndexInOuterColumn,
238 thisIndexInInnerBlock;
241 long long int thisTask;
245 sizeInnerHalfBlock = 1LL << targetQubit;
246 sizeInnerBlock = 2LL * sizeInnerHalfBlock;
248 sizeOuterHalfColumn = sizeOuterColumn >> 1;
251 # pragma omp parallel \
253 shared (sizeInnerBlock,sizeInnerHalfBlock,sizeOuterColumn,sizeOuterHalfColumn,qureg,depolLevel) \
254 private (thisTask,thisInnerBlock,thisOuterColumn,thisIndex,thisIndexInOuterColumn, \
255 thisIndexInInnerBlock,outerBit)
259 # pragma omp for schedule (static)
266 for (thisTask=0; thisTask<numTasks; thisTask++) {
269 thisOuterColumn = thisTask / sizeOuterHalfColumn;
270 thisIndexInOuterColumn = thisTask&(sizeOuterHalfColumn-1);
271 thisInnerBlock = thisIndexInOuterColumn/sizeInnerHalfBlock;
273 thisIndexInInnerBlock = thisTask&(sizeInnerHalfBlock-1);
274 thisIndex = thisOuterColumn*sizeOuterColumn + thisInnerBlock*sizeInnerBlock
275 + thisIndexInInnerBlock;
280 thisIndex += outerBit*(sizeInnerHalfBlock);
290 qureg.
stateVec.real[thisIndex] = (1-depolLevel)*qureg.
stateVec.real[thisIndex] +
293 qureg.
stateVec.imag[thisIndex] = (1-depolLevel)*qureg.
stateVec.imag[thisIndex] +
300 qreal retain=1-damping;
301 qreal dephase=sqrt(1-damping);
308 long long int sizeInnerBlock, sizeInnerHalfBlock;
309 long long int sizeOuterColumn, sizeOuterHalfColumn;
310 long long int thisInnerBlock,
313 thisIndexInOuterColumn,
314 thisIndexInInnerBlock;
318 long long int thisTask;
322 sizeInnerHalfBlock = 1LL << targetQubit;
323 sizeInnerBlock = 2LL * sizeInnerHalfBlock;
325 sizeOuterHalfColumn = sizeOuterColumn >> 1;
328 # pragma omp parallel \
330 shared (sizeInnerBlock,sizeInnerHalfBlock,sizeOuterColumn,sizeOuterHalfColumn,qureg,damping, retain, dephase) \
331 private (thisTask,thisInnerBlock,thisOuterColumn,thisIndex,thisIndexInOuterColumn, \
332 thisIndexInInnerBlock,outerBit, stateBit)
336 # pragma omp for schedule (static)
343 for (thisTask=0; thisTask<numTasks; thisTask++) {
346 thisOuterColumn = thisTask / sizeOuterHalfColumn;
347 thisIndexInOuterColumn = thisTask&(sizeOuterHalfColumn-1);
348 thisInnerBlock = thisIndexInOuterColumn/sizeInnerHalfBlock;
350 thisIndexInInnerBlock = thisTask&(sizeInnerHalfBlock-1);
351 thisIndex = thisOuterColumn*sizeOuterColumn + thisInnerBlock*sizeInnerBlock
352 + thisIndexInInnerBlock;
357 thisIndex += outerBit*(sizeInnerHalfBlock);
387 long long int innerMaskQubit1 = 1LL << qubit1;
389 long long int totMaskQubit1 = innerMaskQubit1 | outerMaskQubit1;
390 long long int innerMaskQubit2 = 1LL << qubit2;
392 long long int totMaskQubit2 = innerMaskQubit2 | outerMaskQubit2;
394 long long int thisTask;
395 long long int partner;
396 long long int thisPatternQubit1, thisPatternQubit2;
398 qreal real00, imag00;
401 # pragma omp parallel \
403 shared (totMaskQubit1,totMaskQubit2,qureg,delta,gamma) \
404 private (thisTask,partner,thisPatternQubit1,thisPatternQubit2,real00,imag00)
409 # pragma omp for schedule (static)
412 for (thisTask=0; thisTask<numTasks; thisTask++){
415 if ((thisPatternQubit1==0) && ((thisPatternQubit2==0)
416 || (thisPatternQubit2==totMaskQubit2))){
418 partner = thisTask | totMaskQubit1;
419 real00 = qureg.
stateVec.real[thisTask];
420 imag00 = qureg.
stateVec.imag[thisTask];
423 + delta*qureg.
stateVec.real[partner];
425 + delta*qureg.
stateVec.imag[partner];
433 # pragma omp for schedule (static)
436 for (thisTask=0; thisTask<numTasks; thisTask++){
439 if ((thisPatternQubit2==0) && ((thisPatternQubit1==0)
440 || (thisPatternQubit1==totMaskQubit1))){
442 partner = thisTask | totMaskQubit2;
443 real00 = qureg.
stateVec.real[thisTask];
444 imag00 = qureg.
stateVec.imag[thisTask];
447 + delta*qureg.
stateVec.real[partner];
449 + delta*qureg.
stateVec.imag[partner];
458 # pragma omp for schedule (static)
461 for (thisTask=0; thisTask<numTasks; thisTask++){
464 if ((thisPatternQubit2==0) && ((thisPatternQubit1==0)
465 || (thisPatternQubit1==totMaskQubit1))){
467 partner = thisTask | totMaskQubit2;
468 partner = partner ^ totMaskQubit1;
469 real00 = qureg.
stateVec.real[thisTask];
470 imag00 = qureg.
stateVec.imag[thisTask];
473 + delta*qureg.
stateVec.real[partner]);
475 + delta*qureg.
stateVec.imag[partner]);
489 long long int innerMaskQubit1 = 1LL << qubit1;
491 long long int totMaskQubit1 = innerMaskQubit1 | outerMaskQubit1;
492 long long int innerMaskQubit2 = 1LL << qubit2;
494 long long int totMaskQubit2 = innerMaskQubit2 | outerMaskQubit2;
499 long long int thisTask;
500 long long int partner;
501 long long int thisPatternQubit1, thisPatternQubit2;
503 qreal real00, imag00;
506 # pragma omp parallel \
508 shared (totMaskQubit1,totMaskQubit2,qureg,delta) \
509 private (thisTask,partner,thisPatternQubit1,thisPatternQubit2,real00,imag00)
514 # pragma omp for schedule (static)
517 for (thisTask=0; thisTask<numTasks; thisTask ++){
520 if ((thisPatternQubit1==0) && ((thisPatternQubit2==0)
521 || (thisPatternQubit2==totMaskQubit2))){
523 partner = thisTask | totMaskQubit1;
524 real00 = qureg.
stateVec.real[thisTask];
525 imag00 = qureg.
stateVec.imag[thisTask];
528 + delta*qureg.
stateVec.real[partner];
530 + delta*qureg.
stateVec.imag[partner];
543 long long int sizeInnerBlockQ1, sizeInnerHalfBlockQ1;
544 long long int sizeInnerBlockQ2, sizeInnerHalfBlockQ2, sizeInnerQuarterBlockQ2;
545 long long int sizeOuterColumn, sizeOuterQuarterColumn;
546 long long int thisInnerBlockQ2,
549 thisIndexInOuterColumn,
550 thisIndexInInnerBlockQ1,
551 thisIndexInInnerBlockQ2,
552 thisInnerBlockQ1InInnerBlockQ2;
553 int outerBitQ1, outerBitQ2;
555 long long int thisTask;
559 sizeInnerHalfBlockQ1 = 1LL << targetQubit;
560 sizeInnerHalfBlockQ2 = 1LL << qubit2;
561 sizeInnerQuarterBlockQ2 = sizeInnerHalfBlockQ2 >> 1;
562 sizeInnerBlockQ2 = sizeInnerHalfBlockQ2 << 1;
563 sizeInnerBlockQ1 = 2LL * sizeInnerHalfBlockQ1;
565 sizeOuterQuarterColumn = sizeOuterColumn >> 2;
568 # pragma omp parallel \
570 shared (sizeInnerBlockQ1,sizeInnerHalfBlockQ1,sizeInnerBlockQ2,sizeInnerHalfBlockQ2,sizeInnerQuarterBlockQ2,\
571 sizeOuterColumn,sizeOuterQuarterColumn,qureg,delta,gamma) \
572 private (thisTask,thisInnerBlockQ2,thisInnerBlockQ1InInnerBlockQ2, \
573 thisOuterColumn,thisIndex,thisIndexInOuterColumn, \
574 thisIndexInInnerBlockQ1,thisIndexInInnerBlockQ2,outerBitQ1,outerBitQ2)
578 # pragma omp for schedule (static)
585 for (thisTask=0; thisTask<numTasks; thisTask++) {
588 thisOuterColumn = thisTask / sizeOuterQuarterColumn;
590 thisIndexInOuterColumn = thisTask&(sizeOuterQuarterColumn-1);
591 thisInnerBlockQ2 = thisIndexInOuterColumn / sizeInnerQuarterBlockQ2;
593 thisIndexInInnerBlockQ2 = thisTask&(sizeInnerQuarterBlockQ2-1);
594 thisInnerBlockQ1InInnerBlockQ2 = thisIndexInInnerBlockQ2 / sizeInnerHalfBlockQ1;
596 thisIndexInInnerBlockQ1 = thisTask&(sizeInnerHalfBlockQ1-1);
599 thisIndex = thisOuterColumn*sizeOuterColumn + thisInnerBlockQ2*sizeInnerBlockQ2
600 + thisInnerBlockQ1InInnerBlockQ2*sizeInnerBlockQ1 + thisIndexInInnerBlockQ1;
606 thisIndex += outerBitQ1*(sizeInnerHalfBlockQ1);
612 thisIndex += outerBitQ2*(sizeInnerQuarterBlockQ2<<1);
634 long long int sizeInnerBlockQ1, sizeInnerHalfBlockQ1;
635 long long int sizeInnerBlockQ2, sizeInnerHalfBlockQ2, sizeInnerQuarterBlockQ2;
636 long long int sizeOuterColumn, sizeOuterQuarterColumn;
637 long long int thisInnerBlockQ2,
640 thisIndexInPairVector,
641 thisIndexInOuterColumn,
642 thisIndexInInnerBlockQ1,
643 thisIndexInInnerBlockQ2,
644 thisInnerBlockQ1InInnerBlockQ2;
645 int outerBitQ1, outerBitQ2;
647 long long int thisTask;
651 sizeInnerHalfBlockQ1 = 1LL << targetQubit;
652 sizeInnerHalfBlockQ2 = 1LL << qubit2;
653 sizeInnerQuarterBlockQ2 = sizeInnerHalfBlockQ2 >> 1;
654 sizeInnerBlockQ2 = sizeInnerHalfBlockQ2 << 1;
655 sizeInnerBlockQ1 = 2LL * sizeInnerHalfBlockQ1;
657 sizeOuterQuarterColumn = sizeOuterColumn >> 2;
661 # pragma omp parallel \
663 shared (sizeInnerBlockQ1,sizeInnerHalfBlockQ1,sizeInnerBlockQ2,sizeInnerHalfBlockQ2,sizeInnerQuarterBlockQ2,\
664 sizeOuterColumn,sizeOuterQuarterColumn,qureg,delta,gamma) \
665 private (thisTask,thisInnerBlockQ2,thisInnerBlockQ1InInnerBlockQ2, \
666 thisOuterColumn,thisIndex,thisIndexInPairVector,thisIndexInOuterColumn, \
667 thisIndexInInnerBlockQ1,thisIndexInInnerBlockQ2,outerBitQ1,outerBitQ2)
671 # pragma omp for schedule (static)
679 for (thisTask=0; thisTask<numTasks; thisTask++) {
682 thisOuterColumn = thisTask / sizeOuterQuarterColumn;
684 thisIndexInOuterColumn = thisTask&(sizeOuterQuarterColumn-1);
685 thisInnerBlockQ2 = thisIndexInOuterColumn / sizeInnerQuarterBlockQ2;
687 thisIndexInInnerBlockQ2 = thisTask&(sizeInnerQuarterBlockQ2-1);
688 thisInnerBlockQ1InInnerBlockQ2 = thisIndexInInnerBlockQ2 / sizeInnerHalfBlockQ1;
690 thisIndexInInnerBlockQ1 = thisTask&(sizeInnerHalfBlockQ1-1);
693 thisIndex = thisOuterColumn*sizeOuterColumn + thisInnerBlockQ2*sizeInnerBlockQ2
694 + thisInnerBlockQ1InInnerBlockQ2*sizeInnerBlockQ1 + thisIndexInInnerBlockQ1;
700 thisIndex += outerBitQ1*(sizeInnerHalfBlockQ1);
704 thisIndexInPairVector = thisTask + (1-outerBitQ1)*sizeInnerHalfBlockQ1*sizeOuterQuarterColumn -
705 outerBitQ1*sizeInnerHalfBlockQ1*sizeOuterQuarterColumn;
711 thisIndex += outerBitQ2*(sizeInnerQuarterBlockQ2<<1);
736 # pragma omp parallel for schedule (static)
738 for (i=startInd; i < startInd+numAmps; i++) {
746 # pragma omp parallel for schedule (static)
748 for (i=startInd; i < startInd+numAmps; i++) {
755 long long int startAmpInd,
long long int numAmps,
long long int blockSize
757 long long int numDubBlocks = numAmps / (2*blockSize);
758 long long int blockStartInd;
761 long long int dubBlockInd;
763 # pragma omp parallel for schedule (static) private (blockStartInd)
765 for (dubBlockInd=0; dubBlockInd < numDubBlocks; dubBlockInd++) {
766 blockStartInd = startAmpInd + dubBlockInd*2*blockSize;
768 zeroSomeAmps( qureg, blockStartInd + blockSize, blockSize);
771 long long int dubBlockInd;
773 # pragma omp parallel for schedule (static) private (blockStartInd)
775 for (dubBlockInd=0; dubBlockInd < numDubBlocks; dubBlockInd++) {
776 blockStartInd = startAmpInd + dubBlockInd*2*blockSize;
791 long long int innerBlockSize = (1LL << measureQubit);
797 long long int globalStartInd = qureg.
chunkId * locNumAmps;
798 int innerBit =
extractBit(measureQubit, globalStartInd);
802 if (locNumAmps <= outerBlockSize) {
805 if (outerBit != outcome)
809 if (locNumAmps <= innerBlockSize) {
812 if (innerBit != outcome)
821 qureg, totalStateProb, innerBit==outcome, 0, qureg.
numAmpsPerChunk, innerBlockSize);
825 long long int numOuterDoubleBlocks = locNumAmps / (2*outerBlockSize);
826 long long int firstBlockInd;
831 if (outerBit == outcome) {
833 for (
long long int outerDubBlockInd = 0; outerDubBlockInd < numOuterDoubleBlocks; outerDubBlockInd++) {
834 firstBlockInd = outerDubBlockInd*2*outerBlockSize;
838 qureg, totalStateProb, innerBit==outcome,
839 firstBlockInd, outerBlockSize, innerBlockSize);
842 zeroSomeAmps(qureg, firstBlockInd + outerBlockSize, outerBlockSize);
847 for (
long long int outerDubBlockInd = 0; outerDubBlockInd < numOuterDoubleBlocks; outerDubBlockInd++) {
848 firstBlockInd = outerDubBlockInd*2*outerBlockSize;
853 qureg, totalStateProb, innerBit==outcome,
854 firstBlockInd + outerBlockSize, outerBlockSize, innerBlockSize);
871 # pragma omp parallel \
872 shared (vecRe, vecIm, numAmps) \
874 reduction ( +:trace )
878 # pragma omp for schedule (static)
880 for (index=0LL; index<numAmps; index++) {
882 trace += vecRe[index]*vecRe[index] + vecIm[index]*vecIm[index];
902 # pragma omp parallel \
904 shared (combineVecRe,combineVecIm,otherVecRe,otherVecIm, otherProb, numAmps) \
909 # pragma omp for schedule (static)
911 for (index=0; index < numAmps; index++) {
912 combineVecRe[index] *= 1-otherProb;
913 combineVecIm[index] *= 1-otherProb;
915 combineVecRe[index] += otherProb * otherVecRe[index];
916 combineVecIm[index] += otherProb * otherVecIm[index];
936 # pragma omp parallel \
937 shared (aRe,aIm, bRe,bIm, numAmps) \
938 private (index,difRe,difIm) \
939 reduction ( +:trace )
943 # pragma omp for schedule (static)
945 for (index=0LL; index<numAmps; index++) {
947 difRe = aRe[index] - bRe[index];
948 difIm = aIm[index] - bIm[index];
949 trace += difRe*difRe + difIm*difIm;
970 # pragma omp parallel \
971 shared (aRe,aIm, bRe,bIm, numAmps) \
973 reduction ( +:trace )
977 # pragma omp for schedule (static)
979 for (index=0LL; index<numAmps; index++) {
980 trace += aRe[index]*bRe[index] + aIm[index]*bIm[index];
1020 qreal densElemRe, densElemIm;
1021 qreal prefacRe, prefacIm;
1022 qreal rowSumRe, rowSumIm;
1023 qreal vecElemRe, vecElemIm;
1026 qreal globalSumRe = 0;
1029 # pragma omp parallel \
1030 shared (vecRe,vecIm,densRe,densIm, dim,colsPerNode,startCol) \
1031 private (row,col, prefacRe,prefacIm, rowSumRe,rowSumIm, densElemRe,densElemIm, vecElemRe,vecElemIm) \
1032 reduction ( +:globalSumRe )
1036 # pragma omp for schedule (static)
1039 for (row=0; row < dim; row++) {
1042 prefacRe = vecRe[row];
1043 prefacIm = - vecIm[row];
1049 for (col=0; col < colsPerNode; col++) {
1052 densElemRe = densRe[row + dim*col];
1053 densElemIm = densIm[row + dim*col];
1056 vecElemRe = vecRe[startCol + col];
1057 vecElemIm = vecIm[startCol + col];
1059 rowSumRe += densElemRe*vecElemRe - densElemIm*vecElemIm;
1060 rowSumIm += densElemRe*vecElemIm + densElemIm*vecElemRe;
1063 globalSumRe += rowSumRe*prefacRe - rowSumIm*prefacIm;
1072 qreal innerProdReal = 0;
1073 qreal innerProdImag = 0;
1075 long long int index;
1082 qreal braRe, braIm, ketRe, ketIm;
1085 # pragma omp parallel \
1086 shared (braVecReal, braVecImag, ketVecReal, ketVecImag, numAmps) \
1087 private (index, braRe, braIm, ketRe, ketIm) \
1088 reduction ( +:innerProdReal, innerProdImag )
1092 # pragma omp for schedule (static)
1094 for (index=0; index < numAmps; index++) {
1095 braRe = braVecReal[index];
1096 braIm = braVecImag[index];
1097 ketRe = ketVecReal[index];
1098 ketIm = ketVecImag[index];
1101 innerProdReal += braRe*ketRe + braIm*ketIm;
1102 innerProdImag += braRe*ketIm - braIm*ketRe;
1107 innerProd.
real = innerProdReal;
1108 innerProd.
imag = innerProdImag;
1124 long long int index;
1126 # pragma omp parallel \
1128 shared (densityNumElems, densityReal, densityImag) \
1133 # pragma omp for schedule (static)
1135 for (index=0; index<densityNumElems; index++) {
1136 densityReal[index] = 0.0;
1137 densityImag[index] = 0.0;
1143 long long int densityInd = (densityDim + 1)*stateInd;
1146 if (qureg.
chunkId == densityInd / densityNumElems){
1147 densityReal[densityInd % densityNumElems] = 1.0;
1148 densityImag[densityInd % densityNumElems] = 0.0;
1163 long long int index;
1167 # pragma omp parallel \
1169 shared (chunkSize, densityReal, densityImag, probFactor) \
1174 # pragma omp for schedule (static)
1176 for (index=0; index<chunkSize; index++) {
1177 densityReal[index] = probFactor;
1178 densityImag[index] = 0.0;
1200 long long int col, row, index;
1203 qreal ketRe, ketIm, braRe, braIm;
1206 # pragma omp parallel \
1208 shared (colOffset, colsPerNode,rowsPerNode, vecRe,vecIm,densRe,densIm) \
1209 private (col,row, ketRe,ketIm,braRe,braIm, index)
1213 # pragma omp for schedule (static)
1216 for (col=0; col < colsPerNode; col++) {
1219 for (row=0; row < rowsPerNode; row++) {
1224 braRe = vecRe[col + colOffset];
1225 braIm = - vecIm[col + colOffset];
1228 index = row + col*rowsPerNode;
1229 densRe[index] = ketRe*braRe - ketIm*braIm;
1230 densIm[index] = ketRe*braIm + ketIm*braRe;
1243 long long int localEndInd = localStartInd + numAmps;
1249 if (localStartInd < 0)
1256 long long int index;
1261 # pragma omp parallel \
1263 shared (localStartInd,localEndInd, vecRe,vecIm, reals,imags, offset) \
1268 # pragma omp for schedule (static)
1271 for (index=localStartInd; index < localEndInd; index++) {
1272 vecRe[index] = reals[index + offset];
1273 vecIm[index] = imags[index + offset];
1280 long long int numAmps = 1LL << numQubits;
1281 long long int numAmpsPerRank = numAmps/env.
numRanks;
1283 if (numAmpsPerRank > SIZE_MAX) {
1284 printf(
"Could not allocate memory (cannot fit numAmps into size_t)!");
1285 exit (EXIT_FAILURE);
1288 size_t arrSize = (size_t) (numAmpsPerRank *
sizeof(*(qureg->
stateVec.real)));
1289 qureg->
stateVec.real = malloc(arrSize);
1290 qureg->
stateVec.imag = malloc(arrSize);
1297 && numAmpsPerRank ) {
1298 printf(
"Could not allocate memory!");
1299 exit (EXIT_FAILURE);
1303 && numAmpsPerRank ) {
1304 printf(
"Could not allocate memory!");
1305 exit (EXIT_FAILURE);
1335 long long int index;
1338 for (rank=0; rank<qureg.
numChunks; rank++){
1341 printf(
"Reporting state from rank %d [\n", qureg.
chunkId);
1342 printf(
"real, imag\n");
1343 }
else if (rank==0) {
1344 printf(
"Reporting state [\n");
1345 printf(
"real, imag\n");
1350 printf(REAL_STRING_FORMAT
", " REAL_STRING_FORMAT
"\n", qureg.
stateVec.real[index], qureg.
stateVec.imag[index]);
1352 if (reportRank || rank==qureg.
numChunks-1) printf(
"]\n");
1356 }
else printf(
"Error: reportStateToScreen will not print output for systems of more than 5 qubits.\n");
1361 numThreads=omp_get_max_threads();
1368 long long int stateVecSize;
1369 long long int index;
1380 # pragma omp parallel \
1382 shared (stateVecSize, stateVecReal, stateVecImag) \
1387 # pragma omp for schedule (static)
1389 for (index=0; index<stateVecSize; index++) {
1390 stateVecReal[index] = 0.0;
1391 stateVecImag[index] = 0.0;
1408 long long int chunkSize, stateVecSize;
1409 long long int index;
1413 stateVecSize = chunkSize*qureg.
numChunks;
1414 qreal normFactor = 1.0/sqrt((
qreal)stateVecSize);
1422 # pragma omp parallel \
1424 shared (chunkSize, stateVecReal, stateVecImag, normFactor) \
1429 # pragma omp for schedule (static)
1431 for (index=0; index<chunkSize; index++) {
1432 stateVecReal[index] = normFactor;
1433 stateVecImag[index] = 0.0;
1440 long long int stateVecSize;
1441 long long int index;
1452 # pragma omp parallel \
1454 shared (stateVecSize, stateVecReal, stateVecImag) \
1459 # pragma omp for schedule (static)
1461 for (index=0; index<stateVecSize; index++) {
1462 stateVecReal[index] = 0.0;
1463 stateVecImag[index] = 0.0;
1468 if (qureg.
chunkId == stateInd/stateVecSize){
1469 stateVecReal[stateInd % stateVecSize] = 1.0;
1470 stateVecImag[stateInd % stateVecSize] = 0.0;
1477 long long int stateVecSize;
1478 long long int index;
1491 # pragma omp parallel \
1493 shared (stateVecSize, targetStateVecReal, targetStateVecImag, copyStateVecReal, copyStateVecImag) \
1498 # pragma omp for schedule (static)
1500 for (index=0; index<stateVecSize; index++) {
1501 targetStateVecReal[index] = copyStateVecReal[index];
1502 targetStateVecImag[index] = copyStateVecImag[index];
1515 long long int chunkSize, stateVecSize;
1516 long long int index;
1518 const long long int chunkId=qureg->
chunkId;
1522 stateVecSize = chunkSize*qureg->
numChunks;
1523 qreal normFactor = 1.0/sqrt((
qreal)stateVecSize/2.0);
1531 # pragma omp parallel \
1533 shared (chunkSize, stateVecReal, stateVecImag, normFactor, qubitId, outcome) \
1534 private (index, bit)
1538 # pragma omp for schedule (static)
1540 for (index=0; index<chunkSize; index++) {
1541 bit =
extractBit(qubitId, index+chunkId*chunkSize);
1543 stateVecReal[index] = normFactor;
1544 stateVecImag[index] = 0.0;
1546 stateVecReal[index] = 0.0;
1547 stateVecImag[index] = 0.0;
1561 long long int chunkSize;
1562 long long int index;
1563 long long int indexOffset;
1572 indexOffset = chunkSize * qureg.
chunkId;
1576 # pragma omp parallel \
1578 shared (chunkSize, stateVecReal, stateVecImag, indexOffset) \
1583 # pragma omp for schedule (static)
1585 for (index=0; index<chunkSize; index++) {
1586 stateVecReal[index] = ((indexOffset + index)*2.0)/10.0;
1587 stateVecImag[index] = ((indexOffset + index)*2.0+1.0)/10.0;
1594 long long int chunkSize, stateVecSize;
1595 long long int indexInChunk, totalIndex;
1598 stateVecSize = chunkSize*qureg->
numChunks;
1606 for (
int rank=0; rank<(qureg->
numChunks); rank++){
1608 fp = fopen(filename,
"r");
1614 indexInChunk = 0; totalIndex = 0;
1615 while (fgets(line,
sizeof(
char)*200, fp) != NULL && totalIndex<stateVecSize){
1617 int chunkId = (int) (totalIndex/chunkSize);
1620 sscanf(line,
"%f, %f", &(stateVecReal[indexInChunk]),
1621 &(stateVecImag[indexInChunk]));
1622 # elif QuEST_PREC==2
1623 sscanf(line,
"%lf, %lf", &(stateVecReal[indexInChunk]),
1624 &(stateVecImag[indexInChunk]));
1625 # elif QuEST_PREC==4
1626 sscanf(line,
"%Lf, %Lf", &(stateVecReal[indexInChunk]),
1627 &(stateVecImag[indexInChunk]));
1647 for (
long long int i=0; i<chunkSize; i++){
1649 if (diff>precision)
return 0;
1651 if (diff>precision)
return 0;
1658 long long int sizeBlock, sizeHalfBlock;
1659 long long int thisBlock,
1662 qreal stateRealUp,stateRealLo,stateImagUp,stateImagLo;
1663 long long int thisTask;
1667 sizeHalfBlock = 1LL << targetQubit;
1668 sizeBlock = 2LL * sizeHalfBlock;
1677 # pragma omp parallel \
1679 shared (sizeBlock,sizeHalfBlock, stateVecReal,stateVecImag, alphaReal,alphaImag, betaReal,betaImag) \
1680 private (thisTask,thisBlock ,indexUp,indexLo, stateRealUp,stateImagUp,stateRealLo,stateImagLo)
1684 # pragma omp for schedule (static)
1686 for (thisTask=0; thisTask<numTasks; thisTask++) {
1688 thisBlock = thisTask / sizeHalfBlock;
1689 indexUp = thisBlock*sizeBlock + thisTask%sizeHalfBlock;
1690 indexLo = indexUp + sizeHalfBlock;
1693 stateRealUp = stateVecReal[indexUp];
1694 stateImagUp = stateVecImag[indexUp];
1696 stateRealLo = stateVecReal[indexLo];
1697 stateImagLo = stateVecImag[indexLo];
1700 stateVecReal[indexUp] = alphaReal*stateRealUp - alphaImag*stateImagUp
1701 - betaReal*stateRealLo - betaImag*stateImagLo;
1702 stateVecImag[indexUp] = alphaReal*stateImagUp + alphaImag*stateRealUp
1703 - betaReal*stateImagLo + betaImag*stateRealLo;
1706 stateVecReal[indexLo] = betaReal*stateRealUp - betaImag*stateImagUp
1707 + alphaReal*stateRealLo + alphaImag*stateImagLo;
1708 stateVecImag[indexLo] = betaReal*stateImagUp + betaImag*stateRealUp
1709 + alphaReal*stateImagLo - alphaImag*stateRealLo;
1725 long long int thisTask;
1726 long long int thisGlobalInd00;
1727 long long int ind00, ind01, ind10, ind11;
1728 qreal re00, re01, re10, re11;
1729 qreal im00, im01, im10, im11;
1732 # pragma omp parallel \
1734 shared (reVec,imVec,globalIndStart,numTasks,ctrlMask,u) \
1735 private (thisTask, thisGlobalInd00, ind00,ind01,ind10,ind11, re00,re01,re10,re11, im00,im01,im10,im11)
1739 # pragma omp for schedule (static)
1741 for (thisTask=0; thisTask<numTasks; thisTask++) {
1747 thisGlobalInd00 = ind00 + globalIndStart;
1748 if (ctrlMask && ((ctrlMask & thisGlobalInd00) != ctrlMask))
1757 re00 = reVec[ind00]; im00 = imVec[ind00];
1758 re01 = reVec[ind01]; im01 = imVec[ind01];
1759 re10 = reVec[ind10]; im10 = imVec[ind10];
1760 re11 = reVec[ind11]; im11 = imVec[ind11];
1764 u.
real[0][0]*re00 - u.
imag[0][0]*im00 +
1765 u.
real[0][1]*re01 - u.
imag[0][1]*im01 +
1766 u.
real[0][2]*re10 - u.
imag[0][2]*im10 +
1767 u.
real[0][3]*re11 - u.
imag[0][3]*im11;
1769 u.
imag[0][0]*re00 + u.
real[0][0]*im00 +
1770 u.
imag[0][1]*re01 + u.
real[0][1]*im01 +
1771 u.
imag[0][2]*re10 + u.
real[0][2]*im10 +
1772 u.
imag[0][3]*re11 + u.
real[0][3]*im11;
1775 u.
real[1][0]*re00 - u.
imag[1][0]*im00 +
1776 u.
real[1][1]*re01 - u.
imag[1][1]*im01 +
1777 u.
real[1][2]*re10 - u.
imag[1][2]*im10 +
1778 u.
real[1][3]*re11 - u.
imag[1][3]*im11;
1780 u.
imag[1][0]*re00 + u.
real[1][0]*im00 +
1781 u.
imag[1][1]*re01 + u.
real[1][1]*im01 +
1782 u.
imag[1][2]*re10 + u.
real[1][2]*im10 +
1783 u.
imag[1][3]*re11 + u.
real[1][3]*im11;
1786 u.
real[2][0]*re00 - u.
imag[2][0]*im00 +
1787 u.
real[2][1]*re01 - u.
imag[2][1]*im01 +
1788 u.
real[2][2]*re10 - u.
imag[2][2]*im10 +
1789 u.
real[2][3]*re11 - u.
imag[2][3]*im11;
1791 u.
imag[2][0]*re00 + u.
real[2][0]*im00 +
1792 u.
imag[2][1]*re01 + u.
real[2][1]*im01 +
1793 u.
imag[2][2]*re10 + u.
real[2][2]*im10 +
1794 u.
imag[2][3]*re11 + u.
real[2][3]*im11;
1797 u.
real[3][0]*re00 - u.
imag[3][0]*im00 +
1798 u.
real[3][1]*re01 - u.
imag[3][1]*im01 +
1799 u.
real[3][2]*re10 - u.
imag[3][2]*im10 +
1800 u.
real[3][3]*re11 - u.
imag[3][3]*im11;
1802 u.
imag[3][0]*re00 + u.
real[3][0]*im00 +
1803 u.
imag[3][1]*re01 + u.
real[3][1]*im01 +
1804 u.
imag[3][2]*re10 + u.
real[3][2]*im10 +
1805 u.
imag[3][3]*re11 + u.
real[3][3]*im11;
1811 return *(
int*)a - *(
int*)b;
1821 long long int numTargAmps = 1 << u.
numQubits;
1826 long long int thisTask;
1827 long long int thisInd00;
1828 long long int thisGlobalInd00;
1831 qreal reElem, imElem;
1835 long long int ampInds[numTargAmps];
1836 qreal reAmps[numTargAmps];
1837 qreal imAmps[numTargAmps];
1841 int sortedTargs[numTargs];
1842 for (
int t=0; t < numTargs; t++)
1843 sortedTargs[t] = targs[t];
1844 qsort(sortedTargs, numTargs,
sizeof(
int),
qsortComp);
1847 # pragma omp parallel \
1849 shared (reVec,imVec, numTasks,numTargAmps,globalIndStart, ctrlMask,targs,sortedTargs,u) \
1850 private (thisTask,thisInd00,thisGlobalInd00,ind,i,t,r,c,reElem,imElem, ampInds,reAmps,imAmps)
1854 # pragma omp for schedule (static)
1856 for (thisTask=0; thisTask<numTasks; thisTask++) {
1859 thisInd00 = thisTask;
1860 for (t=0; t < numTargs; t++)
1864 thisGlobalInd00 = thisInd00 + globalIndStart;
1865 if (ctrlMask && ((ctrlMask & thisGlobalInd00) != ctrlMask))
1869 for (i=0; i < numTargAmps; i++) {
1873 for (t=0; t < numTargs; t++)
1879 reAmps [i] = reVec[ind];
1880 imAmps [i] = imVec[ind];
1884 for (r=0; r < numTargAmps; r++) {
1889 for (c=0; c < numTargAmps; c++) {
1890 reElem = u.
real[r][c];
1891 imElem = u.
imag[r][c];
1892 reVec[ind] += reAmps[c]*reElem - imAmps[c]*imElem;
1893 imVec[ind] += reAmps[c]*imElem + imAmps[c]*reElem;
1902 long long int sizeBlock, sizeHalfBlock;
1903 long long int thisBlock,
1906 qreal stateRealUp,stateRealLo,stateImagUp,stateImagLo;
1907 long long int thisTask;
1911 sizeHalfBlock = 1LL << targetQubit;
1912 sizeBlock = 2LL * sizeHalfBlock;
1919 # pragma omp parallel \
1921 shared (sizeBlock,sizeHalfBlock, stateVecReal,stateVecImag, u) \
1922 private (thisTask,thisBlock ,indexUp,indexLo, stateRealUp,stateImagUp,stateRealLo,stateImagLo)
1926 # pragma omp for schedule (static)
1928 for (thisTask=0; thisTask<numTasks; thisTask++) {
1930 thisBlock = thisTask / sizeHalfBlock;
1931 indexUp = thisBlock*sizeBlock + thisTask%sizeHalfBlock;
1932 indexLo = indexUp + sizeHalfBlock;
1935 stateRealUp = stateVecReal[indexUp];
1936 stateImagUp = stateVecImag[indexUp];
1938 stateRealLo = stateVecReal[indexLo];
1939 stateImagLo = stateVecImag[indexLo];
1943 stateVecReal[indexUp] = u.
real[0][0]*stateRealUp - u.
imag[0][0]*stateImagUp
1944 + u.
real[0][1]*stateRealLo - u.
imag[0][1]*stateImagLo;
1945 stateVecImag[indexUp] = u.
real[0][0]*stateImagUp + u.
imag[0][0]*stateRealUp
1946 + u.
real[0][1]*stateImagLo + u.
imag[0][1]*stateRealLo;
1949 stateVecReal[indexLo] = u.
real[1][0]*stateRealUp - u.
imag[1][0]*stateImagUp
1950 + u.
real[1][1]*stateRealLo - u.
imag[1][1]*stateImagLo;
1951 stateVecImag[indexLo] = u.
real[1][0]*stateImagUp + u.
imag[1][0]*stateRealUp
1952 + u.
real[1][1]*stateImagLo + u.
imag[1][1]*stateRealLo;
1971 ComplexArray stateVecUp,
1972 ComplexArray stateVecLo,
1973 ComplexArray stateVecOut)
1976 qreal stateRealUp,stateRealLo,stateImagUp,stateImagLo;
1977 long long int thisTask;
1982 qreal *stateVecRealUp=stateVecUp.real, *stateVecImagUp=stateVecUp.imag;
1983 qreal *stateVecRealLo=stateVecLo.real, *stateVecImagLo=stateVecLo.imag;
1984 qreal *stateVecRealOut=stateVecOut.real, *stateVecImagOut=stateVecOut.imag;
1987 # pragma omp parallel \
1989 shared (stateVecRealUp,stateVecImagUp,stateVecRealLo,stateVecImagLo,stateVecRealOut,stateVecImagOut, \
1990 rot1Real,rot1Imag, rot2Real,rot2Imag) \
1991 private (thisTask,stateRealUp,stateImagUp,stateRealLo,stateImagLo)
1995 # pragma omp for schedule (static)
1997 for (thisTask=0; thisTask<numTasks; thisTask++) {
1999 stateRealUp = stateVecRealUp[thisTask];
2000 stateImagUp = stateVecImagUp[thisTask];
2002 stateRealLo = stateVecRealLo[thisTask];
2003 stateImagLo = stateVecImagLo[thisTask];
2006 stateVecRealOut[thisTask] = rot1Real*stateRealUp - rot1Imag*stateImagUp + rot2Real*stateRealLo + rot2Imag*stateImagLo;
2007 stateVecImagOut[thisTask] = rot1Real*stateImagUp + rot1Imag*stateRealUp + rot2Real*stateImagLo - rot2Imag*stateRealLo;
2026 ComplexArray stateVecUp,
2027 ComplexArray stateVecLo,
2028 ComplexArray stateVecOut)
2031 qreal stateRealUp,stateRealLo,stateImagUp,stateImagLo;
2032 long long int thisTask;
2037 qreal *stateVecRealUp=stateVecUp.real, *stateVecImagUp=stateVecUp.imag;
2038 qreal *stateVecRealLo=stateVecLo.real, *stateVecImagLo=stateVecLo.imag;
2039 qreal *stateVecRealOut=stateVecOut.real, *stateVecImagOut=stateVecOut.imag;
2043 # pragma omp parallel \
2045 shared (stateVecRealUp,stateVecImagUp,stateVecRealLo,stateVecImagLo,stateVecRealOut,stateVecImagOut, \
2046 rot1Real, rot1Imag, rot2Real, rot2Imag) \
2047 private (thisTask,stateRealUp,stateImagUp,stateRealLo,stateImagLo)
2051 # pragma omp for schedule (static)
2053 for (thisTask=0; thisTask<numTasks; thisTask++) {
2055 stateRealUp = stateVecRealUp[thisTask];
2056 stateImagUp = stateVecImagUp[thisTask];
2058 stateRealLo = stateVecRealLo[thisTask];
2059 stateImagLo = stateVecImagLo[thisTask];
2061 stateVecRealOut[thisTask] = rot1Real*stateRealUp - rot1Imag*stateImagUp
2062 + rot2Real*stateRealLo - rot2Imag*stateImagLo;
2063 stateVecImagOut[thisTask] = rot1Real*stateImagUp + rot1Imag*stateRealUp
2064 + rot2Real*stateImagLo + rot2Imag*stateRealLo;
2072 long long int sizeBlock, sizeHalfBlock;
2073 long long int thisBlock,
2076 qreal stateRealUp,stateRealLo,stateImagUp,stateImagLo;
2077 long long int thisTask;
2080 const long long int chunkId=qureg.
chunkId;
2085 sizeHalfBlock = 1LL << targetQubit;
2086 sizeBlock = 2LL * sizeHalfBlock;
2095 # pragma omp parallel \
2097 shared (sizeBlock,sizeHalfBlock, stateVecReal,stateVecImag, alphaReal,alphaImag, betaReal,betaImag) \
2098 private (thisTask,thisBlock ,indexUp,indexLo, stateRealUp,stateImagUp,stateRealLo,stateImagLo,controlBit)
2102 # pragma omp for schedule (static)
2104 for (thisTask=0; thisTask<numTasks; thisTask++) {
2106 thisBlock = thisTask / sizeHalfBlock;
2107 indexUp = thisBlock*sizeBlock + thisTask%sizeHalfBlock;
2108 indexLo = indexUp + sizeHalfBlock;
2110 controlBit =
extractBit (controlQubit, indexUp+chunkId*chunkSize);
2113 stateRealUp = stateVecReal[indexUp];
2114 stateImagUp = stateVecImag[indexUp];
2116 stateRealLo = stateVecReal[indexLo];
2117 stateImagLo = stateVecImag[indexLo];
2120 stateVecReal[indexUp] = alphaReal*stateRealUp - alphaImag*stateImagUp
2121 - betaReal*stateRealLo - betaImag*stateImagLo;
2122 stateVecImag[indexUp] = alphaReal*stateImagUp + alphaImag*stateRealUp
2123 - betaReal*stateImagLo + betaImag*stateRealLo;
2126 stateVecReal[indexLo] = betaReal*stateRealUp - betaImag*stateImagUp
2127 + alphaReal*stateRealLo + alphaImag*stateImagLo;
2128 stateVecImag[indexLo] = betaReal*stateImagUp + betaImag*stateRealUp
2129 + alphaReal*stateImagLo - alphaImag*stateRealLo;
2141 Qureg qureg,
const int targetQubit,
2142 long long int ctrlQubitsMask,
long long int ctrlFlipMask,
2145 long long int sizeBlock, sizeHalfBlock;
2146 long long int thisBlock,
2149 qreal stateRealUp,stateRealLo,stateImagUp,stateImagLo;
2150 long long int thisTask;
2153 const long long int chunkId=qureg.
chunkId;
2156 sizeHalfBlock = 1LL << targetQubit;
2157 sizeBlock = 2LL * sizeHalfBlock;
2164 # pragma omp parallel \
2166 shared (sizeBlock,sizeHalfBlock, stateVecReal,stateVecImag, u, ctrlQubitsMask,ctrlFlipMask) \
2167 private (thisTask,thisBlock, indexUp,indexLo, stateRealUp,stateImagUp,stateRealLo,stateImagLo)
2171 # pragma omp for schedule (static)
2173 for (thisTask=0; thisTask<numTasks; thisTask++) {
2175 thisBlock = thisTask / sizeHalfBlock;
2176 indexUp = thisBlock*sizeBlock + thisTask%sizeHalfBlock;
2177 indexLo = indexUp + sizeHalfBlock;
2182 if (ctrlQubitsMask == (ctrlQubitsMask & ((indexUp+chunkId*chunkSize) ^ ctrlFlipMask))) {
2184 stateRealUp = stateVecReal[indexUp];
2185 stateImagUp = stateVecImag[indexUp];
2187 stateRealLo = stateVecReal[indexLo];
2188 stateImagLo = stateVecImag[indexLo];
2191 stateVecReal[indexUp] = u.
real[0][0]*stateRealUp - u.
imag[0][0]*stateImagUp
2192 + u.
real[0][1]*stateRealLo - u.
imag[0][1]*stateImagLo;
2193 stateVecImag[indexUp] = u.
real[0][0]*stateImagUp + u.
imag[0][0]*stateRealUp
2194 + u.
real[0][1]*stateImagLo + u.
imag[0][1]*stateRealLo;
2197 stateVecReal[indexLo] = u.
real[1][0]*stateRealUp - u.
imag[1][0]*stateImagUp
2198 + u.
real[1][1]*stateRealLo - u.
imag[1][1]*stateImagLo;
2199 stateVecImag[indexLo] = u.
real[1][0]*stateImagUp + u.
imag[1][0]*stateRealUp
2200 + u.
real[1][1]*stateImagLo + u.
imag[1][1]*stateRealLo;
2210 long long int sizeBlock, sizeHalfBlock;
2211 long long int thisBlock,
2214 qreal stateRealUp,stateRealLo,stateImagUp,stateImagLo;
2215 long long int thisTask;
2218 const long long int chunkId=qureg.
chunkId;
2223 sizeHalfBlock = 1LL << targetQubit;
2224 sizeBlock = 2LL * sizeHalfBlock;
2231 # pragma omp parallel \
2233 shared (sizeBlock,sizeHalfBlock, stateVecReal,stateVecImag, u) \
2234 private (thisTask,thisBlock ,indexUp,indexLo, stateRealUp,stateImagUp,stateRealLo,stateImagLo,controlBit)
2238 # pragma omp for schedule (static)
2240 for (thisTask=0; thisTask<numTasks; thisTask++) {
2242 thisBlock = thisTask / sizeHalfBlock;
2243 indexUp = thisBlock*sizeBlock + thisTask%sizeHalfBlock;
2244 indexLo = indexUp + sizeHalfBlock;
2246 controlBit =
extractBit (controlQubit, indexUp+chunkId*chunkSize);
2249 stateRealUp = stateVecReal[indexUp];
2250 stateImagUp = stateVecImag[indexUp];
2252 stateRealLo = stateVecReal[indexLo];
2253 stateImagLo = stateVecImag[indexLo];
2257 stateVecReal[indexUp] = u.
real[0][0]*stateRealUp - u.
imag[0][0]*stateImagUp
2258 + u.
real[0][1]*stateRealLo - u.
imag[0][1]*stateImagLo;
2259 stateVecImag[indexUp] = u.
real[0][0]*stateImagUp + u.
imag[0][0]*stateRealUp
2260 + u.
real[0][1]*stateImagLo + u.
imag[0][1]*stateRealLo;
2263 stateVecReal[indexLo] = u.
real[1][0]*stateRealUp - u.
imag[1][0]*stateImagUp
2264 + u.
real[1][1]*stateRealLo - u.
imag[1][1]*stateImagLo;
2265 stateVecImag[indexLo] = u.
real[1][0]*stateImagUp + u.
imag[1][0]*stateRealUp
2266 + u.
real[1][1]*stateImagLo + u.
imag[1][1]*stateRealLo;
2287 ComplexArray stateVecUp,
2288 ComplexArray stateVecLo,
2289 ComplexArray stateVecOut)
2292 qreal stateRealUp,stateRealLo,stateImagUp,stateImagLo;
2293 long long int thisTask;
2296 const long long int chunkId=qureg.
chunkId;
2302 qreal *stateVecRealUp=stateVecUp.real, *stateVecImagUp=stateVecUp.imag;
2303 qreal *stateVecRealLo=stateVecLo.real, *stateVecImagLo=stateVecLo.imag;
2304 qreal *stateVecRealOut=stateVecOut.real, *stateVecImagOut=stateVecOut.imag;
2307 # pragma omp parallel \
2309 shared (stateVecRealUp,stateVecImagUp,stateVecRealLo,stateVecImagLo,stateVecRealOut,stateVecImagOut, \
2310 rot1Real,rot1Imag, rot2Real,rot2Imag) \
2311 private (thisTask,stateRealUp,stateImagUp,stateRealLo,stateImagLo,controlBit)
2315 # pragma omp for schedule (static)
2317 for (thisTask=0; thisTask<numTasks; thisTask++) {
2318 controlBit =
extractBit (controlQubit, thisTask+chunkId*chunkSize);
2321 stateRealUp = stateVecRealUp[thisTask];
2322 stateImagUp = stateVecImagUp[thisTask];
2324 stateRealLo = stateVecRealLo[thisTask];
2325 stateImagLo = stateVecImagLo[thisTask];
2328 stateVecRealOut[thisTask] = rot1Real*stateRealUp - rot1Imag*stateImagUp + rot2Real*stateRealLo + rot2Imag*stateImagLo;
2329 stateVecImagOut[thisTask] = rot1Real*stateImagUp + rot1Imag*stateRealUp + rot2Real*stateImagLo - rot2Imag*stateRealLo;
2349 ComplexArray stateVecUp,
2350 ComplexArray stateVecLo,
2351 ComplexArray stateVecOut)
2354 qreal stateRealUp,stateRealLo,stateImagUp,stateImagLo;
2355 long long int thisTask;
2358 const long long int chunkId=qureg.
chunkId;
2364 qreal *stateVecRealUp=stateVecUp.real, *stateVecImagUp=stateVecUp.imag;
2365 qreal *stateVecRealLo=stateVecLo.real, *stateVecImagLo=stateVecLo.imag;
2366 qreal *stateVecRealOut=stateVecOut.real, *stateVecImagOut=stateVecOut.imag;
2369 # pragma omp parallel \
2371 shared (stateVecRealUp,stateVecImagUp,stateVecRealLo,stateVecImagLo,stateVecRealOut,stateVecImagOut, \
2372 rot1Real,rot1Imag, rot2Real,rot2Imag) \
2373 private (thisTask,stateRealUp,stateImagUp,stateRealLo,stateImagLo,controlBit)
2377 # pragma omp for schedule (static)
2379 for (thisTask=0; thisTask<numTasks; thisTask++) {
2380 controlBit =
extractBit (controlQubit, thisTask+chunkId*chunkSize);
2383 stateRealUp = stateVecRealUp[thisTask];
2384 stateImagUp = stateVecImagUp[thisTask];
2386 stateRealLo = stateVecRealLo[thisTask];
2387 stateImagLo = stateVecImagLo[thisTask];
2389 stateVecRealOut[thisTask] = rot1Real*stateRealUp - rot1Imag*stateImagUp
2390 + rot2Real*stateRealLo - rot2Imag*stateImagLo;
2391 stateVecImagOut[thisTask] = rot1Real*stateImagUp + rot1Imag*stateRealUp
2392 + rot2Real*stateImagLo + rot2Imag*stateRealLo;
2415 const int targetQubit,
2416 long long int ctrlQubitsMask,
long long int ctrlFlipMask,
2418 ComplexArray stateVecUp,
2419 ComplexArray stateVecLo,
2420 ComplexArray stateVecOut)
2423 qreal stateRealUp,stateRealLo,stateImagUp,stateImagLo;
2424 long long int thisTask;
2427 const long long int chunkId=qureg.
chunkId;
2431 qreal *stateVecRealUp=stateVecUp.real, *stateVecImagUp=stateVecUp.imag;
2432 qreal *stateVecRealLo=stateVecLo.real, *stateVecImagLo=stateVecLo.imag;
2433 qreal *stateVecRealOut=stateVecOut.real, *stateVecImagOut=stateVecOut.imag;
2436 # pragma omp parallel \
2438 shared (stateVecRealUp,stateVecImagUp,stateVecRealLo,stateVecImagLo,stateVecRealOut,stateVecImagOut, \
2439 rot1Real,rot1Imag, rot2Real,rot2Imag, ctrlQubitsMask,ctrlFlipMask) \
2440 private (thisTask,stateRealUp,stateImagUp,stateRealLo,stateImagLo)
2444 # pragma omp for schedule (static)
2446 for (thisTask=0; thisTask<numTasks; thisTask++) {
2447 if (ctrlQubitsMask == (ctrlQubitsMask & ((thisTask+chunkId*chunkSize) ^ ctrlFlipMask))) {
2449 stateRealUp = stateVecRealUp[thisTask];
2450 stateImagUp = stateVecImagUp[thisTask];
2452 stateRealLo = stateVecRealLo[thisTask];
2453 stateImagLo = stateVecImagLo[thisTask];
2455 stateVecRealOut[thisTask] = rot1Real*stateRealUp - rot1Imag*stateImagUp
2456 + rot2Real*stateRealLo - rot2Imag*stateImagLo;
2457 stateVecImagOut[thisTask] = rot1Real*stateImagUp + rot1Imag*stateRealUp
2458 + rot2Real*stateImagLo + rot2Imag*stateRealLo;
2466 long long int sizeBlock, sizeHalfBlock;
2467 long long int thisBlock,
2470 qreal stateRealUp,stateImagUp;
2471 long long int thisTask;
2475 sizeHalfBlock = 1LL << targetQubit;
2476 sizeBlock = 2LL * sizeHalfBlock;
2483 # pragma omp parallel \
2485 shared (sizeBlock,sizeHalfBlock, stateVecReal,stateVecImag) \
2486 private (thisTask,thisBlock ,indexUp,indexLo, stateRealUp,stateImagUp)
2490 # pragma omp for schedule (static)
2492 for (thisTask=0; thisTask<numTasks; thisTask++) {
2493 thisBlock = thisTask / sizeHalfBlock;
2494 indexUp = thisBlock*sizeBlock + thisTask%sizeHalfBlock;
2495 indexLo = indexUp + sizeHalfBlock;
2497 stateRealUp = stateVecReal[indexUp];
2498 stateImagUp = stateVecImag[indexUp];
2500 stateVecReal[indexUp] = stateVecReal[indexLo];
2501 stateVecImag[indexUp] = stateVecImag[indexLo];
2503 stateVecReal[indexLo] = stateRealUp;
2504 stateVecImag[indexLo] = stateImagUp;
2523 ComplexArray stateVecIn,
2524 ComplexArray stateVecOut)
2527 long long int thisTask;
2530 qreal *stateVecRealIn=stateVecIn.real, *stateVecImagIn=stateVecIn.imag;
2531 qreal *stateVecRealOut=stateVecOut.real, *stateVecImagOut=stateVecOut.imag;
2534 # pragma omp parallel \
2536 shared (stateVecRealIn,stateVecImagIn,stateVecRealOut,stateVecImagOut) \
2541 # pragma omp for schedule (static)
2543 for (thisTask=0; thisTask<numTasks; thisTask++) {
2544 stateVecRealOut[thisTask] = stateVecRealIn[thisTask];
2545 stateVecImagOut[thisTask] = stateVecImagIn[thisTask];
2552 long long int sizeBlock, sizeHalfBlock;
2553 long long int thisBlock,
2556 qreal stateRealUp,stateImagUp;
2557 long long int thisTask;
2560 const long long int chunkId=qureg.
chunkId;
2565 sizeHalfBlock = 1LL << targetQubit;
2566 sizeBlock = 2LL * sizeHalfBlock;
2573 # pragma omp parallel \
2575 shared (sizeBlock,sizeHalfBlock, stateVecReal,stateVecImag) \
2576 private (thisTask,thisBlock ,indexUp,indexLo, stateRealUp,stateImagUp,controlBit)
2580 # pragma omp for schedule (static)
2582 for (thisTask=0; thisTask<numTasks; thisTask++) {
2583 thisBlock = thisTask / sizeHalfBlock;
2584 indexUp = thisBlock*sizeBlock + thisTask%sizeHalfBlock;
2585 indexLo = indexUp + sizeHalfBlock;
2587 controlBit =
extractBit(controlQubit, indexUp+chunkId*chunkSize);
2589 stateRealUp = stateVecReal[indexUp];
2590 stateImagUp = stateVecImag[indexUp];
2592 stateVecReal[indexUp] = stateVecReal[indexLo];
2593 stateVecImag[indexUp] = stateVecImag[indexLo];
2595 stateVecReal[indexLo] = stateRealUp;
2596 stateVecImag[indexLo] = stateImagUp;
2613 ComplexArray stateVecIn,
2614 ComplexArray stateVecOut)
2617 long long int thisTask;
2620 const long long int chunkId=qureg.
chunkId;
2624 qreal *stateVecRealIn=stateVecIn.real, *stateVecImagIn=stateVecIn.imag;
2625 qreal *stateVecRealOut=stateVecOut.real, *stateVecImagOut=stateVecOut.imag;
2628 # pragma omp parallel \
2630 shared (stateVecRealIn,stateVecImagIn,stateVecRealOut,stateVecImagOut) \
2631 private (thisTask,controlBit)
2635 # pragma omp for schedule (static)
2637 for (thisTask=0; thisTask<numTasks; thisTask++) {
2638 controlBit =
extractBit (controlQubit, thisTask+chunkId*chunkSize);
2640 stateVecRealOut[thisTask] = stateVecRealIn[thisTask];
2641 stateVecImagOut[thisTask] = stateVecImagIn[thisTask];
2649 long long int sizeBlock, sizeHalfBlock;
2650 long long int thisBlock,
2653 qreal stateRealUp,stateImagUp;
2654 long long int thisTask;
2658 sizeHalfBlock = 1LL << targetQubit;
2659 sizeBlock = 2LL * sizeHalfBlock;
2666 # pragma omp parallel \
2668 shared (sizeBlock,sizeHalfBlock, stateVecReal,stateVecImag) \
2669 private (thisTask,thisBlock ,indexUp,indexLo, stateRealUp,stateImagUp)
2673 # pragma omp for schedule (static)
2675 for (thisTask=0; thisTask<numTasks; thisTask++) {
2676 thisBlock = thisTask / sizeHalfBlock;
2677 indexUp = thisBlock*sizeBlock + thisTask%sizeHalfBlock;
2678 indexLo = indexUp + sizeHalfBlock;
2680 stateRealUp = stateVecReal[indexUp];
2681 stateImagUp = stateVecImag[indexUp];
2683 stateVecReal[indexUp] = conjFac * stateVecImag[indexLo];
2684 stateVecImag[indexUp] = conjFac * -stateVecReal[indexLo];
2685 stateVecReal[indexLo] = conjFac * -stateImagUp;
2686 stateVecImag[indexLo] = conjFac * stateRealUp;
2705 ComplexArray stateVecIn,
2706 ComplexArray stateVecOut,
2707 int updateUpper,
const int conjFac)
2710 long long int thisTask;
2713 qreal *stateVecRealIn=stateVecIn.real, *stateVecImagIn=stateVecIn.imag;
2714 qreal *stateVecRealOut=stateVecOut.real, *stateVecImagOut=stateVecOut.imag;
2716 int realSign=1, imagSign=1;
2717 if (updateUpper) imagSign=-1;
2721 # pragma omp parallel \
2723 shared (stateVecRealIn,stateVecImagIn,stateVecRealOut,stateVecImagOut,realSign,imagSign) \
2728 # pragma omp for schedule (static)
2730 for (thisTask=0; thisTask<numTasks; thisTask++) {
2731 stateVecRealOut[thisTask] = conjFac * realSign * stateVecImagIn[thisTask];
2732 stateVecImagOut[thisTask] = conjFac * imagSign * stateVecRealIn[thisTask];
2742 long long int sizeBlock, sizeHalfBlock;
2743 long long int thisBlock,
2746 qreal stateRealUp,stateImagUp;
2747 long long int thisTask;
2750 const long long int chunkId=qureg.
chunkId;
2755 sizeHalfBlock = 1LL << targetQubit;
2756 sizeBlock = 2LL * sizeHalfBlock;
2763 # pragma omp parallel \
2765 shared (sizeBlock,sizeHalfBlock, stateVecReal,stateVecImag) \
2766 private (thisTask,thisBlock ,indexUp,indexLo, stateRealUp,stateImagUp,controlBit)
2770 # pragma omp for schedule (static)
2772 for (thisTask=0; thisTask<numTasks; thisTask++) {
2773 thisBlock = thisTask / sizeHalfBlock;
2774 indexUp = thisBlock*sizeBlock + thisTask%sizeHalfBlock;
2775 indexLo = indexUp + sizeHalfBlock;
2777 controlBit =
extractBit(controlQubit, indexUp+chunkId*chunkSize);
2779 stateRealUp = stateVecReal[indexUp];
2780 stateImagUp = stateVecImag[indexUp];
2783 stateVecReal[indexUp] = conjFac * stateVecImag[indexLo];
2784 stateVecImag[indexUp] = conjFac * -stateVecReal[indexLo];
2785 stateVecReal[indexLo] = conjFac * -stateImagUp;
2786 stateVecImag[indexLo] = conjFac * stateRealUp;
2794 ComplexArray stateVecIn,
2795 ComplexArray stateVecOut,
const int conjFac)
2798 long long int thisTask;
2801 const long long int chunkId=qureg.
chunkId;
2805 qreal *stateVecRealIn=stateVecIn.real, *stateVecImagIn=stateVecIn.imag;
2806 qreal *stateVecRealOut=stateVecOut.real, *stateVecImagOut=stateVecOut.imag;
2809 # pragma omp parallel \
2811 shared (stateVecRealIn,stateVecImagIn,stateVecRealOut,stateVecImagOut) \
2812 private (thisTask,controlBit)
2816 # pragma omp for schedule (static)
2818 for (thisTask=0; thisTask<numTasks; thisTask++) {
2819 controlBit =
extractBit (controlQubit, thisTask+chunkId*chunkSize);
2821 stateVecRealOut[thisTask] = conjFac * stateVecImagIn[thisTask];
2822 stateVecImagOut[thisTask] = conjFac * -stateVecRealIn[thisTask];
2836 long long int sizeBlock, sizeHalfBlock;
2837 long long int thisBlock,
2840 qreal stateRealUp,stateRealLo,stateImagUp,stateImagLo;
2841 long long int thisTask;
2845 sizeHalfBlock = 1LL << targetQubit;
2846 sizeBlock = 2LL * sizeHalfBlock;
2852 qreal recRoot2 = 1.0/sqrt(2);
2855 # pragma omp parallel \
2857 shared (sizeBlock,sizeHalfBlock, stateVecReal,stateVecImag, recRoot2) \
2858 private (thisTask,thisBlock ,indexUp,indexLo, stateRealUp,stateImagUp,stateRealLo,stateImagLo)
2862 # pragma omp for schedule (static)
2864 for (thisTask=0; thisTask<numTasks; thisTask++) {
2865 thisBlock = thisTask / sizeHalfBlock;
2866 indexUp = thisBlock*sizeBlock + thisTask%sizeHalfBlock;
2867 indexLo = indexUp + sizeHalfBlock;
2869 stateRealUp = stateVecReal[indexUp];
2870 stateImagUp = stateVecImag[indexUp];
2872 stateRealLo = stateVecReal[indexLo];
2873 stateImagLo = stateVecImag[indexLo];
2875 stateVecReal[indexUp] = recRoot2*(stateRealUp + stateRealLo);
2876 stateVecImag[indexUp] = recRoot2*(stateImagUp + stateImagLo);
2878 stateVecReal[indexLo] = recRoot2*(stateRealUp - stateRealLo);
2879 stateVecImag[indexLo] = recRoot2*(stateImagUp - stateImagLo);
2895 ComplexArray stateVecUp,
2896 ComplexArray stateVecLo,
2897 ComplexArray stateVecOut,
2901 qreal stateRealUp,stateRealLo,stateImagUp,stateImagLo;
2902 long long int thisTask;
2906 if (updateUpper) sign=1;
2909 qreal recRoot2 = 1.0/sqrt(2);
2911 qreal *stateVecRealUp=stateVecUp.real, *stateVecImagUp=stateVecUp.imag;
2912 qreal *stateVecRealLo=stateVecLo.real, *stateVecImagLo=stateVecLo.imag;
2913 qreal *stateVecRealOut=stateVecOut.real, *stateVecImagOut=stateVecOut.imag;
2916 # pragma omp parallel \
2918 shared (stateVecRealUp,stateVecImagUp,stateVecRealLo,stateVecImagLo,stateVecRealOut,stateVecImagOut, \
2920 private (thisTask,stateRealUp,stateImagUp,stateRealLo,stateImagLo)
2924 # pragma omp for schedule (static)
2926 for (thisTask=0; thisTask<numTasks; thisTask++) {
2928 stateRealUp = stateVecRealUp[thisTask];
2929 stateImagUp = stateVecImagUp[thisTask];
2931 stateRealLo = stateVecRealLo[thisTask];
2932 stateImagLo = stateVecImagLo[thisTask];
2934 stateVecRealOut[thisTask] = recRoot2*(stateRealUp + sign*stateRealLo);
2935 stateVecImagOut[thisTask] = recRoot2*(stateImagUp + sign*stateImagLo);
2942 long long int index;
2943 long long int stateVecSize;
2947 const long long int chunkId=qureg.
chunkId;
2954 qreal stateRealLo, stateImagLo;
2959 # pragma omp parallel for \
2961 shared (stateVecSize, stateVecReal,stateVecImag ) \
2962 private (index,targetBit,stateRealLo,stateImagLo) \
2965 for (index=0; index<stateVecSize; index++) {
2968 targetBit =
extractBit (targetQubit, index+chunkId*chunkSize);
2971 stateRealLo = stateVecReal[index];
2972 stateImagLo = stateVecImag[index];
2974 stateVecReal[index] = cosAngle*stateRealLo - sinAngle*stateImagLo;
2975 stateVecImag[index] = sinAngle*stateRealLo + cosAngle*stateImagLo;
2982 long long int index;
2983 long long int stateVecSize;
2987 const long long int chunkId=qureg.
chunkId;
2994 qreal stateRealLo, stateImagLo;
2995 const qreal cosAngle = cos(angle);
2996 const qreal sinAngle = sin(angle);
2999 # pragma omp parallel for \
3001 shared (stateVecSize, stateVecReal,stateVecImag ) \
3002 private (index,bit1,bit2,stateRealLo,stateImagLo) \
3005 for (index=0; index<stateVecSize; index++) {
3006 bit1 =
extractBit (idQubit1, index+chunkId*chunkSize);
3007 bit2 =
extractBit (idQubit2, index+chunkId*chunkSize);
3010 stateRealLo = stateVecReal[index];
3011 stateImagLo = stateVecImag[index];
3013 stateVecReal[index] = cosAngle*stateRealLo - sinAngle*stateImagLo;
3014 stateVecImag[index] = sinAngle*stateRealLo + cosAngle*stateImagLo;
3021 long long int index;
3022 long long int stateVecSize;
3025 const long long int chunkId=qureg.
chunkId;
3027 long long int mask =
getQubitBitMask(controlQubits, numControlQubits);
3033 qreal stateRealLo, stateImagLo;
3034 const qreal cosAngle = cos(angle);
3035 const qreal sinAngle = sin(angle);
3038 # pragma omp parallel \
3040 shared (stateVecSize, stateVecReal, stateVecImag, mask) \
3041 private (index, stateRealLo, stateImagLo)
3045 # pragma omp for schedule (static)
3047 for (index=0; index<stateVecSize; index++) {
3048 if (mask == (mask & (index+chunkId*chunkSize)) ){
3050 stateRealLo = stateVecReal[index];
3051 stateImagLo = stateVecImag[index];
3053 stateVecReal[index] = cosAngle*stateRealLo - sinAngle*stateImagLo;
3054 stateVecImag[index] = sinAngle*stateRealLo + cosAngle*stateImagLo;
3064 mask = mask & (mask-1);
3071 long long int index;
3072 long long int stateVecSize;
3075 const long long int chunkId=qureg.
chunkId;
3081 qreal stateReal, stateImag;
3082 const qreal cosAngle = cos(angle/2.0);
3083 const qreal sinAngle = sin(angle/2.0);
3090 # pragma omp parallel \
3092 shared (stateVecSize, stateVecReal, stateVecImag, mask) \
3093 private (index, fac, stateReal, stateImag)
3097 # pragma omp for schedule (static)
3099 for (index=0; index<stateVecSize; index++) {
3100 stateReal = stateVecReal[index];
3101 stateImag = stateVecImag[index];
3105 stateVecReal[index] = cosAngle*stateReal + fac * sinAngle*stateImag;
3106 stateVecImag[index] = - fac * sinAngle*stateReal + cosAngle*stateImag;
3116 long long int diagSpacing = 1LL + densityDim;
3117 long long int maxNumDiagsPerChunk = 1 + localNumAmps / diagSpacing;
3118 long long int numPrevDiags = (qureg.
chunkId>0)? 1+(qureg.
chunkId*localNumAmps)/diagSpacing : 0;
3119 long long int globalIndNextDiag = diagSpacing * numPrevDiags;
3120 long long int localIndNextDiag = globalIndNextDiag % localNumAmps;
3123 long long int numDiagsInThisChunk = maxNumDiagsPerChunk;
3124 if (localIndNextDiag + (numDiagsInThisChunk-1)*diagSpacing >= localNumAmps)
3125 numDiagsInThisChunk -= 1;
3127 long long int visitedDiags;
3128 long long int basisStateInd;
3129 long long int index;
3135 # pragma omp parallel \
3136 shared (localIndNextDiag, numPrevDiags, diagSpacing, stateVecReal, numDiagsInThisChunk) \
3137 private (visitedDiags, basisStateInd, index) \
3138 reduction ( +:zeroProb )
3142 # pragma omp for schedule (static)
3145 for (visitedDiags = 0; visitedDiags < numDiagsInThisChunk; visitedDiags++) {
3147 basisStateInd = numPrevDiags + visitedDiags;
3148 index = localIndNextDiag + diagSpacing * visitedDiags;
3150 if (
extractBit(measureQubit, basisStateInd) == 0)
3151 zeroProb += stateVecReal[index];
3167 const int measureQubit)
3170 long long int sizeBlock,
3173 long long int thisBlock,
3176 qreal totalProbability;
3178 long long int thisTask;
3184 sizeHalfBlock = 1LL << (measureQubit);
3186 sizeBlock = 2LL * sizeHalfBlock;
3189 totalProbability = 0.0;
3195 # pragma omp parallel \
3196 shared (numTasks,sizeBlock,sizeHalfBlock, stateVecReal,stateVecImag) \
3197 private (thisTask,thisBlock,index) \
3198 reduction ( +:totalProbability )
3202 # pragma omp for schedule (static)
3204 for (thisTask=0; thisTask<numTasks; thisTask++) {
3205 thisBlock = thisTask / sizeHalfBlock;
3206 index = thisBlock*sizeBlock + thisTask%sizeHalfBlock;
3208 totalProbability += stateVecReal[index]*stateVecReal[index]
3209 + stateVecImag[index]*stateVecImag[index];
3212 return totalProbability;
3224 qreal totalProbability;
3226 long long int thisTask;
3234 totalProbability = 0.0;
3240 # pragma omp parallel \
3241 shared (numTasks,stateVecReal,stateVecImag) \
3242 private (thisTask) \
3243 reduction ( +:totalProbability )
3247 # pragma omp for schedule (static)
3249 for (thisTask=0; thisTask<numTasks; thisTask++) {
3250 totalProbability += stateVecReal[thisTask]*stateVecReal[thisTask]
3251 + stateVecImag[thisTask]*stateVecImag[thisTask];
3255 return totalProbability;
3262 long long int index;
3263 long long int stateVecSize;
3267 const long long int chunkId=qureg.
chunkId;
3275 # pragma omp parallel for \
3277 shared (stateVecSize, stateVecReal,stateVecImag ) \
3278 private (index,bit1,bit2) \
3281 for (index=0; index<stateVecSize; index++) {
3282 bit1 =
extractBit (idQubit1, index+chunkId*chunkSize);
3283 bit2 =
extractBit (idQubit2, index+chunkId*chunkSize);
3285 stateVecReal [index] = - stateVecReal [index];
3286 stateVecImag [index] = - stateVecImag [index];
3293 long long int index;
3294 long long int stateVecSize;
3297 const long long int chunkId=qureg.
chunkId;
3299 long long int mask =
getQubitBitMask(controlQubits, numControlQubits);
3306 # pragma omp parallel \
3308 shared (stateVecSize, stateVecReal,stateVecImag, mask ) \
3313 # pragma omp for schedule (static)
3315 for (index=0; index<stateVecSize; index++) {
3316 if (mask == (mask & (index+chunkId*chunkSize)) ){
3317 stateVecReal [index] = - stateVecReal [index];
3318 stateVecImag [index] = - stateVecImag [index];
3343 long long int sizeBlock,
3346 long long int thisBlock,
3351 long long int thisTask;
3358 sizeHalfBlock = 1LL << (measureQubit);
3360 sizeBlock = 2LL * sizeHalfBlock;
3362 renorm=1/sqrt(totalProbability);
3368 # pragma omp parallel \
3370 shared (numTasks,sizeBlock,sizeHalfBlock, stateVecReal,stateVecImag,renorm,outcome) \
3371 private (thisTask,thisBlock,index)
3377 # pragma omp for schedule (static)
3379 for (thisTask=0; thisTask<numTasks; thisTask++) {
3380 thisBlock = thisTask / sizeHalfBlock;
3381 index = thisBlock*sizeBlock + thisTask%sizeHalfBlock;
3382 stateVecReal[index]=stateVecReal[index]*renorm;
3383 stateVecImag[index]=stateVecImag[index]*renorm;
3385 stateVecReal[index+sizeHalfBlock]=0;
3386 stateVecImag[index+sizeHalfBlock]=0;
3391 # pragma omp for schedule (static)
3393 for (thisTask=0; thisTask<numTasks; thisTask++) {
3394 thisBlock = thisTask / sizeHalfBlock;
3395 index = thisBlock*sizeBlock + thisTask%sizeHalfBlock;
3396 stateVecReal[index]=0;
3397 stateVecImag[index]=0;
3399 stateVecReal[index+sizeHalfBlock]=stateVecReal[index+sizeHalfBlock]*renorm;
3400 stateVecImag[index+sizeHalfBlock]=stateVecImag[index+sizeHalfBlock]*renorm;
3425 long long int thisTask;
3428 qreal renorm=1/sqrt(totalProbability);
3434 # pragma omp parallel \
3435 shared (numTasks,stateVecReal,stateVecImag) \
3440 # pragma omp for schedule (static)
3442 for (thisTask=0; thisTask<numTasks; thisTask++) {
3443 stateVecReal[thisTask] = stateVecReal[thisTask]*renorm;
3444 stateVecImag[thisTask] = stateVecImag[thisTask]*renorm;
3464 long long int thisTask;
3475 # pragma omp parallel \
3476 shared (numTasks,stateVecReal,stateVecImag) \
3481 # pragma omp for schedule (static)
3483 for (thisTask=0; thisTask<numTasks; thisTask++) {
3484 stateVecReal[thisTask] = 0;
3485 stateVecImag[thisTask] = 0;
3503 long long int thisTask;
3504 long long int ind00, ind01, ind10;
3509 # pragma omp parallel \
3511 shared (reVec,imVec,numTasks,qb1,qb2) \
3512 private (thisTask, ind00,ind01,ind10, re01,re10, im01,im10)
3516 # pragma omp for schedule (static)
3518 for (thisTask=0; thisTask<numTasks; thisTask++) {
3525 re01 = reVec[ind01]; im01 = imVec[ind01];
3526 re10 = reVec[ind10]; im10 = imVec[ind10];
3529 reVec[ind01] = re10; reVec[ind10] = re01;
3530 imVec[ind01] = im10; imVec[ind10] = im01;
3548 long long int globalStartInd = qureg.
chunkId * numLocalAmps;
3549 long long int pairGlobalStartInd = pairRank * numLocalAmps;
3551 long long int localInd, globalInd;
3552 long long int pairLocalInd, pairGlobalInd;
3555 # pragma omp parallel \
3557 shared (reVec,imVec,rePairVec,imPairVec,numLocalAmps,globalStartInd,pairGlobalStartInd,qb1,qb2) \
3558 private (localInd,globalInd, pairLocalInd,pairGlobalInd)
3562 # pragma omp for schedule (static)
3564 for (localInd=0; localInd < numLocalAmps; localInd++) {
3566 globalInd = globalStartInd + localInd;
3570 pairLocalInd = pairGlobalInd - pairGlobalStartInd;
3572 reVec[localInd] = rePairVec[pairLocalInd];
3573 imVec[localInd] = imPairVec[pairLocalInd];
3597 qreal re1,im1, re2,im2, reOut,imOut;
3598 long long int index;
3601 # pragma omp parallel \
3602 shared (vecRe1,vecIm1, vecRe2,vecIm2, vecReOut,vecImOut, facRe1,facIm1,facRe2,facIm2, numAmps) \
3603 private (index, re1,im1, re2,im2, reOut,imOut)
3607 # pragma omp for schedule (static)
3609 for (index=0LL; index<numAmps; index++) {
3610 re1 = vecRe1[index]; im1 = vecIm1[index];
3611 re2 = vecRe2[index]; im2 = vecIm2[index];
3612 reOut = vecReOut[index];
3613 imOut = vecImOut[index];
3615 vecReOut[index] = (facReOut*reOut - facImOut*imOut) + (facRe1*re1 - facIm1*im1) + (facRe2*re2 - facIm2*im2);
3616 vecImOut[index] = (facReOut*imOut + facImOut*reOut) + (facRe1*im1 + facIm1*re1) + (facRe2*im2 + facIm2*re2);