Sort fragments by size (largest first) for better load balancing Uses in-place sorting to reorder the polymers array Larger fragments (e.g., tetramers) are computed before smaller ones (e.g., dimers)
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(inout) | :: | polymers(:,:) | |||
| integer(kind=int64), | intent(in) | :: | total_fragments | |||
| integer, | intent(in) | :: | max_level |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | fragment_size | ||||
| integer(kind=int64), | private, | allocatable | :: | fragment_sizes(:) | |||
| integer(kind=int64), | private | :: | i | ||||
| integer(kind=int64), | private | :: | j | ||||
| integer, | private, | allocatable | :: | polymers_copy(:,:) | |||
| integer(kind=int_index), | private, | allocatable | :: | sort_indices(:) | |||
| integer(kind=int64), | private | :: | sorted_idx |
subroutine sort_fragments_by_size(polymers, total_fragments, max_level) !! Sort fragments by size (largest first) for better load balancing !! Uses in-place sorting to reorder the polymers array !! Larger fragments (e.g., tetramers) are computed before smaller ones (e.g., dimers) use pic_sorting, only: sort_index integer, intent(inout) :: polymers(:, :) integer(int64), intent(in) :: total_fragments integer, intent(in) :: max_level integer(int64), allocatable :: fragment_sizes(:) integer(int_index), allocatable :: sort_indices(:) integer, allocatable :: polymers_copy(:, :) integer(int64) :: i, j, sorted_idx integer :: fragment_size ! Nothing to sort if we have 1 or fewer fragments if (total_fragments <= 1) return ! Allocate arrays for sorting (0-indexed for PIC library) allocate (fragment_sizes(0:total_fragments - 1)) allocate (sort_indices(0:total_fragments - 1)) ! Calculate fragment sizes do i = 0, total_fragments - 1 fragment_size = count(polymers(i + 1, :) > 0) fragment_sizes(i) = int(fragment_size, int64) end do ! Get sort permutation in descending order (largest first) call sort_index(fragment_sizes, sort_indices, reverse=.true.) ! Reorder polymers array based on sort permutation allocate (polymers_copy(size(polymers, 1), size(polymers, 2))) polymers_copy = polymers ! Reorder: new position j gets data from original position sort_indices(j) ! NOTE: sort_indices already contains 1-indexed values, so don't add 1! do j = 0, total_fragments - 1 sorted_idx = sort_indices(j) ! Already 1-indexed! polymers(j + 1, :) = polymers_copy(sorted_idx, :) end do deallocate (polymers_copy) deallocate (fragment_sizes) deallocate (sort_indices) call logger%info("Fragments queue sorted!") end subroutine sort_fragments_by_size