Nature Language: funnelledHaloexchange:Each process exchanges a message with its left and right neighbour. Communication takes place by one thread inside of the parallel region.
  
CPP: int funnelledHaloexchange(int totalReps, int dataSize){\n    int repIter, i;\n\n    #pragma omp parallel default(none) \\\n    private(i,repIter) \\\n    shared(dataSize,sizeofBuffer,leftSendBuf,rightSendBuf) \\\n    shared(rightRecvBuf,leftRecvBuf,finalLeftBuf,finalRightBuf) \\\n    shared(globalIDarray,commCart,totalReps,requestArray,statusArray) \\\n    shared(leftNeighbour,rightNeighbour)\n    { \n        for (repIter=0; repIter<totalReps; repIter++){\n\n            #pragma omp for schedule(static,dataSize)\n            for (i=0; i<sizeofBuffer; i++){\n                leftSendBuf[i] = globalIDarray[myThreadID];\n                rightSendBuf[i] = globalIDarray[myThreadID];\n            }\n\n            #pragma omp master\n            {\n                MPI_Isend(leftSendBuf, sizeofBuffer, MPI_INT, leftNeighbour, \\\n                TAG, commCart, &requestArray[0]);\n\n                MPI_Isend(rightSendBuf, sizeofBuffer, MPI_INT, rightNeighbour, \\\n                TAG, commCart, &requestArray[1]);\n\n                MPI_Irecv(leftRecvBuf, sizeofBuffer, MPI_INT, leftNeighbour, \\\n                TAG, commCart, &requestArray[2]);\n\n                MPI_Irecv(rightRecvBuf, sizeofBuffer, MPI_INT, rightNeighbour, \\\n                TAG, commCart, &requestArray[3]);\n\n                MPI_Waitall(4, requestArray, statusArray);\n            }\n\n            #pragma omp barrier\n\n            #pragma omp for schedule(static,dataSize)\n            for(i=0; i<sizeofBuffer; i++){\n                finalLeftBuf[i] = leftRecvBuf[i];\n                finalRightBuf[i] = rightRecvBuf[i];\n            }\n        }\n    }\n\n    return 0;\n}",
  
Fortran: SUBROUTINE funnelledHaloexchange(totalReps, dataSize)\ninteger, intent(in) :: totalReps, dataSize\ninteger :: repIter, i\n\n!Open the parallel region\n!$OMP PARALLEL DEFAULT(NONE), &\n!$OMP PRIVATE(i,repIter), &\n!$OMP SHARED(dataSize,sizeofBuffer,leftSendBuf,rightSendBuf), &\n!$OMP SHARED(rightRecvBuf,leftRecvBuf,finalLeftBuf), &\n!$OMP SHARED(finalRightBuf,leftNeighbour,rightNeighbour), &\n!$OMP SHARED(globalIDarray,ierr,comm,status), &\n!$OMP SHARED(totalReps,requestArray,statusArray)\n\nDO repIter = 1, totalReps !loop for totalReps \n\n!Each thread writes its globalID to rightSendBuf and\n!leftSendBuf.\n!$OMP DO SCHEDULE(STATIC,dataSize)\nDO i = 1, sizeofBuffer\nleftSendBuf(i) = globalIDarray(myThreadID)\nrightSendBuf(i) = globalIDarray(myThreadID)\nEND DO\n!$OMP END DO\n!Implicit barrier here takes care of necessary synchronisation\n\n!$OMP MASTER\n!Master thread starts send of data to left and right\n!neighbours with a non-blocking send\n!..to leftNeighbour\nCALL MPI_ISend(leftSendBuf, sizeofBuffer, MPI_INTEGER, &\nleftNeighbour, tag, comm, requestArray(1), ierr)\n!..to rightNeighbour\nCALL MPI_ISend(rightSendBuf, sizeofBuffer, MPI_INTEGER, &\nrightNeighbour, tag, comm, requestArray(2), ierr)\n\n!Thread then starts receive of messages from leftNeighbour \n!and rightNeighbour.\n!Receive leftRecvBuf from leftNeighbour\nCALL MPI_IRecv(leftRecvBuf, sizeofBuffer, MPI_INTEGER, &\nleftNeighbour, tag, comm, requestArray(3), ierr)\n!Receive rightRecvBuf from rightNeighbour\nCALL MPI_IRecv(rightRecvBuf, sizeofBuffer, MPI_INTEGER, &\nrightNeighbour, tag, comm, requestArray(4), ierr)\n\n!Finish the sends and receives with an MPI_Waitall \n!on the requests.\nCALL MPI_Waitall(4, requestArray, statusArray, ierr) \n!$OMP END MASTER\n\n!Barrier to ensure master thread has completed transfer.\n!$OMP BARRIER\n\n!Each thread now reads its part of the left and right\n!received buffers.\n!$OMP DO SCHEDULE(STATIC,dataSize)\nDO i = 1, sizeofBuffer\nfinalLeftBuf(i) = leftRecvBuf(i)\nfinalRightBuf(i) = rightRecvBuf(i)\nEND DO\n!$OMP END DO\n\nEND DO !end of repetitions loop\n!$OMP END PARALLEL\nEND SUBROUTINE funnelledHaloexchange
  