Skip to content
This repository was archived by the owner on Oct 23, 2020. It is now read-only.

MPAS speedup of model initialisation #1350

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 36 additions & 20 deletions src/framework/mpas_dmpar.F
Original file line number Diff line number Diff line change
Expand Up @@ -1497,7 +1497,8 @@ subroutine mpas_dmpar_get_exch_list(haloLayer, ownedListField, neededListField,
type (hashtable) :: neededHash
integer :: nUniqueNeededList, threadNum
integer, dimension(:,:), pointer :: uniqueSortedNeededList

! For threading of binary search blocks
integer, dimension(:), allocatable :: karray

!
! *** NB: This code assumes that block % blockID values are local block IDs and are in the range [1, numBlocks]
Expand Down Expand Up @@ -1756,28 +1757,34 @@ subroutine mpas_dmpar_get_exch_list(haloLayer, ownedListField, neededListField,
totalSent = 0

currentProc = mod(dminfo % my_proc_id + dminfo % nprocs - i + 1, dminfo % nprocs)
allocate(karray(1:nMesgRecv))
karray = nOwnedList + 1
!$OMP parallel do default(shared) private(j)
do j=1,nMesgRecv
if (ownerListIn(j) > 0) then
k = mpas_binary_search(ownedListSorted, 2, 1, nOwnedList, ownerListIn(j))
if (k <= nOwnedList) then
iBlock = ownedBlock(ownedListSorted(2,k)) + 1
numToSend(iBlock) = numToSend(iBlock) + 1
totalSent = totalSent + 1
karray(j) = mpas_binary_search(ownedListSorted, 2, 1, nOwnedList, ownerListIn(j))
end if
end do
!$OMP end parallel do
do j=1,nMesgRecv
if (karray(j) <= nOwnedList) then
iBlock = ownedBlock(ownedListSorted(2,karray(j))) + 1
numToSend(iBlock) = numToSend(iBlock) + 1
totalSent = totalSent + 1

! recipientList(1,:) represents the index in the srcList to place this data
recipientList(1,ownedListSorted(2,k)) = numToSend(iBlock)
! recipientList(2,:) represnets the index in the buffer to place this data
recipientList(2,ownedListSorted(2,k)) = totalSent
! recipientList(1,:) represents the index in the srcList to place this data
recipientList(1,ownedListSorted(2,karray(j))) = numToSend(iBlock)
! recipientList(2,:) represnets the index in the buffer to place this data
recipientList(2,ownedListSorted(2,karray(j))) = totalSent

ownerListOut(j) = -1 * dminfo % my_proc_id
else
ownerListOut(j) = ownerListIn(j)
end if
ownerListOut(j) = -1 * dminfo % my_proc_id
else
ownerListOut(j) = ownerListIn(j)
end if
end do

deallocate(karray)

fieldCursor => ownedListField
do while (associated(fieldCursor))
iBlock = fieldCursor % block % localBlockID + 1
Expand Down Expand Up @@ -1854,15 +1861,24 @@ subroutine mpas_dmpar_get_exch_list(haloLayer, ownedListField, neededListField,

fieldCursor => neededListField
do while (associated(fieldCursor))

allocate(karray(1:fieldCursor % dimSizes(1)))
!$OMP parallel do default(shared) private(j)
do j = 1, fieldCursor % dimSizes(1)
k = mpas_binary_search(uniqueSortedNeededList, 2, 1, nUniqueNeededList, fieldCursor % array(j))
if(k <= nUniqueNeededList) then
if(ownerListIn(k) == -i) then
iBlock = fieldCursor % block % localBlockID + 1
numToRecv(iBlock) = numToRecv(iBlock) + 1
end if
karray(j) = mpas_binary_search(uniqueSortedNeededList, 2, 1, nUniqueNeededList, fieldCursor % array(j))
end do
!$OMP end parallel do
do j = 1, fieldCursor % dimSizes(1)
if(karray(j) <= nUniqueNeededList) then
if(ownerListIn(karray(j)) == -i) then
iBlock = fieldCursor % block % localBlockID + 1
numToRecv(iBlock) = numToRecv(iBlock) + 1
end if
end if
end do

deallocate(karray)

fieldCursor => fieldCursor % next
end do

Expand Down
14 changes: 11 additions & 3 deletions src/framework/mpas_sort.F
Original file line number Diff line number Diff line change
Expand Up @@ -412,10 +412,14 @@ end subroutine mpas_quicksort_2dreal!}}}
! integer function mpas_binary_search
!
!> \brief MPAS Binary search routine
!> \author Michael Duda
!> \date 03/27/13
!> \author Michael Duda, modified by Dom Heinzeller
!> \date 03/27/13, modified 05/29/17
!> \details
!> This routine performs a binary search in array for the key. It either returns the index of the key within array, or n2+1 if the key is not found.
!> This routine performs a binary search in array for the key. It either
!> returns the index of the key within array, or n2+1 if the key is not
!> found. As every binary search, it requires a sorted array to search.
!> This allows to shorten/skip the search if the key is smaller than the
!> first item in the array, or larger than the last item.
!
!-----------------------------------------------------------------------
integer function mpas_binary_search(array, d1, n1, n2, key)!{{{
Expand All @@ -429,6 +433,10 @@ integer function mpas_binary_search(array, d1, n1, n2, key)!{{{

mpas_binary_search = n2+1

if (key < array(1,n1) .or. key > array(1,n2)) then
return
end if

l = n1
u = n2
k = (l+u)/2
Expand Down
2 changes: 2 additions & 0 deletions src/framework/mpas_stream_manager.F
Original file line number Diff line number Diff line change
Expand Up @@ -5245,6 +5245,7 @@ subroutine postread_reindex(allFields, streamFields) !{{{
call mpas_quicksort(indexSpaceDim, sortedID)

! Reindex the field
!$OMP parallel do default(none) shared(outerDim, innerDim, sortedID, indexSpaceDim, int2DField) private(i,j,k)
do i = 1, outerDim
do j = 1, innerDim
k = mpas_binary_search(sortedID, 2, 1, indexSpaceDim, int2DField % array(j,i))
Expand All @@ -5255,6 +5256,7 @@ subroutine postread_reindex(allFields, streamFields) !{{{
end if
end do
end do
!$OMP end parallel do

deallocate(sortedID)
int2DField => int2DField % next
Expand Down