Load balance the parents (non-leafs). Assign them to the rank that has most children.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(mg_t), | intent(inout) | :: | mg |
subroutine mg_load_balance_parents(mg) type(mg_t), intent(inout) :: mg integer :: i, id, lvl integer :: c_ids(mg_num_children) integer :: c_ranks(mg_num_children) integer :: single_cpu_lvl, coarse_rank integer :: my_work(0:mg%n_cpu), i_cpu ! Up to this level, all boxes have to be on a single processor because they ! have a different size and the communication routines do not support this single_cpu_lvl = max(mg%first_normal_lvl-1, mg%lowest_lvl) do lvl = mg%highest_lvl-1, single_cpu_lvl+1, -1 my_work(:) = 0 ! Determine amount of work for the leaves do i = 1, size(mg%lvls(lvl)%leaves) id = mg%lvls(lvl)%leaves(i) i_cpu = mg%boxes(id)%rank my_work(i_cpu) = my_work(i_cpu) + 1 end do do i = 1, size(mg%lvls(lvl)%parents) id = mg%lvls(lvl)%parents(i) c_ids = mg%boxes(id)%children c_ranks = mg%boxes(c_ids)%rank i_cpu = most_popular(c_ranks, my_work, mg%n_cpu) mg%boxes(id)%rank = i_cpu my_work(i_cpu) = my_work(i_cpu) + 1 end do end do ! Determine most popular CPU for coarse grids if (single_cpu_lvl < mg%highest_lvl) then coarse_rank = most_popular(mg%boxes(mg%lvls(single_cpu_lvl+1)%ids)%rank,& my_work, mg%n_cpu) else coarse_rank = 0 end if do lvl = mg%lowest_lvl, single_cpu_lvl do i = 1, size(mg%lvls(lvl)%ids) id = mg%lvls(lvl)%ids(i) mg%boxes(id)%rank = coarse_rank end do end do do lvl = mg%lowest_lvl, mg%highest_lvl call update_lvl_info(mg, mg%lvls(lvl)) end do end subroutine mg_load_balance_parents