sort_fragments_by_size Subroutine

public subroutine sort_fragments_by_size(polymers, total_fragments, max_level)

Uses

    • pic_sorting
  • proc~~sort_fragments_by_size~~UsesGraph proc~sort_fragments_by_size sort_fragments_by_size pic_sorting pic_sorting proc~sort_fragments_by_size->pic_sorting

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)

Arguments

Type IntentOptional Attributes Name
integer, intent(inout) :: polymers(:,:)
integer(kind=int64), intent(in) :: total_fragments
integer, intent(in) :: max_level

Calls

proc~~sort_fragments_by_size~~CallsGraph proc~sort_fragments_by_size sort_fragments_by_size info info proc~sort_fragments_by_size->info sort_index sort_index proc~sort_fragments_by_size->sort_index

Called by

proc~~sort_fragments_by_size~~CalledByGraph proc~sort_fragments_by_size sort_fragments_by_size proc~run_fragmented_calculation run_fragmented_calculation proc~run_fragmented_calculation->proc~sort_fragments_by_size proc~run_calculation run_calculation proc~run_calculation->proc~run_fragmented_calculation proc~compute_energy_and_forces compute_energy_and_forces proc~compute_energy_and_forces->proc~run_calculation proc~run_multi_molecule_calculations run_multi_molecule_calculations proc~run_multi_molecule_calculations->proc~run_calculation program~main main program~main->proc~run_calculation program~main->proc~run_multi_molecule_calculations

Variables

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

Source Code

   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