process will receive information for (before it can make the compute step).
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(tem_levelDesc_type), | intent(in) | :: | levelDesc |
Dimension-by-dimension level descriptor for the current level and direction. |
||
type(tem_face_descriptor_type), | intent(inout) | :: | faces |
The communication pattern you want use for the buffer. The created face descriptor. |
||
type(tem_communication_type), | intent(out) | :: | buf(2) |
The created receive buffer. Size is two, due to left and right limes of the face values. To access it use tem_left and tem_right. |
subroutine tem_build_faceRecvBuffers( levelDesc, faces, buf ) ! ------------------------------------------------------------------------- !> Dimension-by-dimension level descriptor for the current level and !! direction. type(tem_levelDesc_type), intent(in) :: levelDesc !> The communication pattern you want use for the buffer. ! type(tem_commpattern_type), intent(in) :: commPattern !> The created face descriptor. type(tem_face_descriptor_type),intent(inout) :: faces !> The created receive buffer. Size is two, due to left and right limes of !! the face values. To access it use tem_left and tem_right. type(tem_communication_type), intent(out) :: buf(2) ! -------------------------------------------------------------------------- integer :: iFace, iProc, iSide, elemPos, faceSide, tIdPos, rank, rankPos, & & elemAddPos, faceIndex logical :: wasAdded integer(kind=long_k) :: elemId ! The elements ids I will receive data for. We have to differentiate the ! left and right face of a face here. type(dyn_longArray_type) :: elemIds(2) ! The elements positions I will receive data for. We have to differentiate ! the left and right face of a face here. type(grw_intArray_type) :: elemPositions(2) ! The source ranks. type(dyn_intArray_type) :: srcRank(2) ! The position of the source ranks. type(grw_intArray_type) :: srcRankPos(2) ! -------------------------------------------------------------------------- ! Init our growing arrays. call init( me = elemIds(1) , length = 16 ) call init( me = elemIds(2) , length = 16 ) call init( me = elemPositions(1) , length = 16 ) call init( me = elemPositions(2) , length = 16 ) call init( me = srcRankPos(1) , length = 16) call init( me = srcRankPos(2) , length = 16) call init( me = srcRank(1) , length = 16 ) call init( me = srcRank(2) , length = 16 ) ! Iterate over all the faces and count the communicate faces. do iFace = 1, faces%faceList%faceId%nVals ! Check whether we will receive info of one of the adjacent elements ! of this face. faceSide = tem_isRecvFace(iFace, faces) if (faceSide /= 0) then ! Check for which adjacent element (left or right) the current rank ! will receive information about and count it. if (faceSide == tem_left) then elemPos = faces%faceList%leftElemPos%val(iFace) elemId = faces%faceList%faceId%val(iFace) ! If we receive information about the left element, we receive ! information about it's right face! faceSide = tem_right else elemPos = faces%faceList%rightElemPos%val(iFace) elemId = faces%faceList%rightElemId%val(iFace) ! If we receive information about the right element, we receive ! information about it's left face! faceSide = tem_left end if ! Get the source rank. Therefore we have a look at the level ! descriptor of the current spatial direction and level. tIdPos = PositionOfVal( me = levelDesc%elem%tId, val = elemId ) if (tIdPos <= 0) then write(*,*) 'ERROR in tem_build_faceRecvBuffers: not able to '// & & 'identify source rank for a certain face, stopping ...' call tem_abort() else rank = levelDesc%elem%sourceProc%val(tIdPos) end if ! Store element position and source proc in a dynamic array. call append( me = elemIds(faceSide), & & val = elemId, & & pos = elemAddPos, & & wasAdded = wasAdded ) if (wasAdded) then call append( me = elemPositions(faceSide), val = elemPos ) call append( me = srcRank(faceSide), val = rank, pos = rankPos ) call append( me = srcRankPos(faceSide), val = rankPos ) end if end if end do ! Now, we build the buffer for the faces (left and right values). do iSide = 1, 2 ! Init the datastructures in the buffer buf(iSide)%nProcs = srcRank(iSide)%nVals allocate(buf(iSide)%proc( srcRank(iSide)%nVals )) allocate(buf(iSide)%nElemsProc( srcRank(iSide)%nVals )) allocate(buf(iSide)%elemPos( srcRank(iSide)%nVals )) do iProc = 1, buf(iSide)%nProcs call init( me = buf(iSide)%elemPos(iProc), length = 16 ) end do ! Set the positions of the elements I will receive. do iFace = 1, elemPositions(iSide)%nVals faceIndex = elemIds(iSide)%sorted(iFace) elemPos = elemPositions(iSide)%val(faceIndex) rankPos = srcRankPos(iSide)%val(faceIndex) call append( me = buf(iSide)%elemPos(rankPos), val = elemPos ) end do ! Count the number of elements we recv from each proc. do iProc = 1, buf(iSide)%nProcs buf(iSide)%proc(iProc) = srcRank(iSide)%val(iProc) - 1 buf(iSide)%nElemsProc(iProc) = buf(iSide)%elemPos(iProc)%nVals end do end do end subroutine tem_build_faceRecvBuffers