Nature Language: funnelledPingpong:One MPI process sends single fixed length message to another MPI process. This other process then sends it back to the first process. All communication takes place within the OpenMP region for this benchmark.
  
CPP: int funnelledPingpong(int totalReps, int dataSize){\n\tint repIter, i;\n\t/* Open parallel region for threads */\n#pragma omp parallel default(none) \\\n\tprivate(i,repIter) \\\n\tshared(pingRank,pongRank,pingSendBuf,pingRecvBuf) \\\n\tshared(pongSendBuf,pongRecvBuf,finalRecvBuf,sizeofBuffer) \\\n\tshared(dataSize,globalIDarray,comm,status,totalReps,myMPIRank)\n\t{\n\tfor (repIter=0; repIter< totalReps; repIter++){\n\t\t/* All threads under MPI process with rank = pingRank\n\t\t * write to its part of the pingBuf array using a\n\t\t * parallel do directive.\n\t\t */\n\t\tif (myMPIRank == pingRank){\n#pragma omp for schedule(static,dataSize)\n\t\t\tfor (i=0; i<sizeofBuffer; i++){\n\t\t\t\tpingSendBuf[i] = globalIDarray[myThreadID];\n\t\t\t}\n/* Implicit barrier at end of for takes care of synchronisation */\n\t\t\t/*Master thread under ping process sends buffer to\n\t\t\t * MPI process with rank equal to pongRank.\n\t\t\t */\n#pragma omp master\n\t\t\t{\n\t\t\tMPI_Send(pingSendBuf, sizeofBuffer, MPI_INT, pongRank, TAG, comm);\n\t\t\t/* Master thread then waits for a message from pong process */\n\t\t\tMPI_Recv(pongRecvBuf, sizeofBuffer, MPI_INT, pongRank, TAG, \\\n\t\t\t\t\tcomm, &status);\n\t\t\t}\n/* Barrier needed to wait for master thread to complete MPI_Recv */\n#pragma omp barrier\n\t\t/*Each thread reads its part of received buffer */\n#pragma omp for schedule(static,dataSize)\n\t\tfor (i=0; i<sizeofBuffer; i++){\n\t\t\tfinalRecvBuf[i] = pongRecvBuf[i];\n\t\t}\n\t}\n\telse if (myMPIRank == pongRank){\n\t\t/* Master thread under pongRank receives the message\n\t\t * from the ping process.\n\t\t */\n#pragma omp master\n\t\t{\n\t\tMPI_Recv(pingRecvBuf, sizeofBuffer, MPI_INT, pingRank, TAG, comm, &status);\n\t\t}\n/* Barrier needed to wait on master thread */\n#pragma omp barrier\n\t\t/* Each thread under the pongRank MPI process now copies its part\n\t\t * of the received buffer to pongSendBuf.\n\t\t */\n#pragma omp for schedule(static,dataSize)\n\t\tfor (i=0; i<sizeofBuffer; i++){\n\t\t\tpongSendBuf[i] = pingRecvBuf[i];\n\t\t}\n/* Implicit barrier at end of DO */\n\t\t/* Master thread of pongRank process now sends pongSendBuf\n\t\t * to ping process.\n\t\t */\n#pragma omp master\n\t\t{\n\t\tMPI_Send(pongSendBuf, sizeofBuffer, MPI_INT, pingRank, TAG, comm);\n\t\t}\n\t}\n\t} /* end of repetitions */\n\t} /* end of parallel region */\n\treturn 0;\n}
  
Fortran: SUBROUTINE funnelledPingpong(totalReps, dataSize)\n integer, intent(in) :: totalReps, dataSize\n integer :: repIter, i\n\n !Open parallel region for threads\n!$OMP PARALLEL DEFAULT(NONE), &\n!$OMP PRIVATE(i,repIter), &\n!$OMP SHARED(pingRank,pongRank,pingSendBuf,pingRecvBuf), &\n!$OMP SHARED(pongSendBuf,pongRecvBuf,finalRecvBuf,sizeofBuffer), &\n!$OMP SHARED(dataSize,globalIDarray,comm,ierr,status), &\n!$OMP SHARED(totalReps,myMPIRank)\n\n DO repIter = 1, totalReps !loop totalRep times\n\n !All threads under MPI process with rank = pingRank\n !write to its part of the pingBuf array using a \n !PARALLEL DO directive.\n IF (myMPIRank == pingRank) THEN\n \n!$OMP DO SCHEDULE(STATIC,dataSize)\n DO i = 1,sizeofBuffer\n pingSendBuf(i) = globalIDarray(myThreadID)\n ENDDO\n!$OMP END DO\n!Implicit barrier at end of DO takes care of synchronisation here\n\n !Master thread under Ping process sends buffer \n !to MPI process with rank equal to pongRank.\n!$OMP MASTER\n CALL MPI_Send(pingSendBuf, sizeofBuffer, MPI_INTEGER,&\n pongRank, tag, comm, ierr)\n \n !Thread then waits for a message from pong process.\n CALL MPI_Recv(pongRecvBuf, sizeofBuffer, MPI_INTEGER,&\n pongRank, tag, comm, status, ierr)\n!$OMP END MASTER\n\n!Barrier needed to wait for master thread to complete MPI_Recv\n!$OMP BARRIER \n\n !Each thread reads its part of received buffer.\n !This completes the pingpong operation.\n!$OMP DO SCHEDULE(STATIC,dataSize)\n DO i = 1,sizeofBuffer\n finalRecvBuf(i) = pongRecvBuf(i)\n ENDDO\n!$OMP END DO\n\n ELSEIF (myMPIRank == pongRank) THEN\n \n !Master thread under pongRank receives the message \n !from the ping process\n!$OMP MASTER\n CALL MPI_Recv(pingRecvBuf, sizeofBuffer, MPI_INTEGER, &\n pingRank, tag, comm, status, ierr)\n!$OMP END MASTER\n\n!Barrier needed to wait on master thread\n!$OMP BARRIER\n\n !Each thread under the pongRank MPI process now copies \n !its part of the received buffer to pongSendBuf\n\n!$OMP DO SCHEDULE(STATIC,dataSize)\n DO i = 1,sizeofBuffer\n pongSendBuf(i) = pingRecvBuf(i)\n END DO\n!$OMP END DO\n!Implicit barrier at end of DO\n \n !Master thread pongRank process now sends pongSendBuf \n !to ping process.\n!$OMP MASTER\n CALL MPI_Send(pongSendBuf, sizeofBuffer, MPI_INTEGER, &\n pingRank, tag, comm, ierr)\n!$OMP END MASTER\n\n END IF\n END DO !End repetitions loop\n!$OMP END PARALLEL \n\n END SUBROUTINE funnelledPingpong
  