Find the remote partitions holding data on a given path
Using a binary search over the processes first and last elements.
Is the element in question a local or remote element? To look up a certain element by its treeID in the distributed list of elements, it is sufficient to know the splitting positions of all chunks. That is, the first and last treeID of each partition. With a binary search over the splitting positions any requested element can then be identified to be either outside the computational domain at all, or inside of one or several known partitions.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer, | intent(out) | :: | depProc |
List of partitions |
||
integer, | intent(out) | :: | nDepProcs |
Number of partitions |
||
type(tem_path_type), | intent(in) | :: | elemPath |
Element to look up |
||
integer, | intent(in) | :: | p_lb |
Left interval bound to search in |
||
integer, | intent(in) | :: | p_ub |
Right interval bound to search in |
||
type(tem_path_type), | intent(in) | :: | PathFirst(:) |
Left partition bounds |
||
type(tem_path_type), | intent(in) | :: | PathLast(:) |
Right partition bounds |
subroutine tem_find_depProc_globSearch( depProc, nDepProcs, elemPath, p_lb, & & p_ub, PathFirst, PathLast) ! -------------------------------------------------------------------- ! !> List of partitions integer, intent(out) :: depProc !> Number of partitions integer, intent(out) :: nDepProcs !> Element to look up type(tem_path_type), intent(in) :: elemPath !> Left partition bounds type(tem_path_type), intent(in) :: PathFirst(:) !> Right partition bounds type(tem_path_type), intent(in) :: PathLast(:) !> Left interval bound to search in integer, intent(in) :: p_lb !> Right interval bound to search in integer, intent(in) :: p_ub ! -------------------------------------------------------------------- ! integer :: lb, ub integer :: foundProc, lastProc integer :: curProc integer :: pComp ! -------------------------------------------------------------------- ! lb = p_lb ub = p_ub ! Find the partition, to which elemPath is definitely right of ! the first element. do curProc = (lb + ub) / 2 if( curProc <= 0 ) then ! Element not found on any proc foundProc = 0 exit end if pComp = tem_PathComparison(elemPath, PathFirst(curProc)) if (pComp > 0) then ! The first element of curProc is smaller than elemPath, therefore ! we do not have to search left of curProc. Can we even go to curProc+1? if (tem_PathComparison(elemPath, PathLast(curProc)) > 0) then ! The search element is not in the partition curProc at all, continue ! search with new lower bound of curProc+1. lb = min(curProc + 1, p_ub) else ! The left element is smaller than the search element and the right ! one is larger or equal to it, thus we found the first partition, ! which contains information on the element. foundProc = curProc exit end if else ! The first element of curProc is larger or equal to elemPath, thus ! we can restrict our search interval up to this partition. ub = curProc ! It is OK to not decrease the interval further here, as we always ! round down to find the middle, thus, if by this step we set ! ub = lb+1, the next iteration will test a new element, as we get ! curProc = (lb + lb + 1) / 2 = lb. end if if (ub <= lb) then ! Interval of size 0, found the first process to hold information on ! the element in neighpath. ! The lower bound was tested strictly, thus it is safe to set the first ! process to the lower bound here and exit. foundProc = lb pComp = tem_PathComparison(elemPath, PathFirst(foundProc)) ! element is below lower bound of process 1. ! Therefor no process is holding the element if ( lb == 1 .and. pComp < 0 ) foundProc = 0 ! element is below lower bound of process and the element is bigger ! than upper bound of previous process. -> element doesn't exist if ( ub == lb .and. pComp < 0 ) foundProc = 0 exit end if end do ! Now linearly search for the last process spanned by the searched element. ! Usually this is just the single partition identified above or more lastProc = foundProc if (lastProc > 0) then if (lastProc < p_ub) then ! Found process that is not the last one, check whether we span ! more than this one (it might just be the first partition with that ! element). nDepProcs = 1 depProc = lastProc do if (lastProc == p_ub) exit if (tem_PathComparison(elemPath, PathLast(lastProc)) < 0) exit if (tem_PathComparison(elemPath, PathFirst(lastProc+1)) < 0) exit lastProc = lastProc + 1 nDepProcs = nDepProcs + 1 end do else ! Last process, there can not be any more processes that would contain ! this element. Check whether this element actually is found in this ! last process. if (tem_PathComparison(elemPath, PathLast(lastProc)) <= 0) then ! Element is found on this process, return it accordingly. nDepProcs = 1 depProc = lastProc else ! Element not found on last process, nowhere in all processes to be ! found, return accordingly 0 processes. nDepProcs = 0 depProc = 0 end if end if else ! Element is left of first process in given list, so no process contains ! it ... nDepProcs = 0 depProc = 0 end if end subroutine tem_find_depProc_globSearch