provide a distribution of num_kpts k-points across mpi_size MPI ranks
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(lib_common_type), | intent(in) | :: | common_data |
library object: only the communicator type is referenced |
||
| integer, | intent(in) | :: | num_kpts |
number of k-points |
||
| integer, | intent(in) | :: | mpi_size |
number of ranks in MPI communicator |
||
| integer, | intent(inout), | allocatable | :: | dist_k(:) |
already allocated array assigned here such that dist_k(i) = rank handling kpt i size and allocation status are tested |
|
| integer, | intent(in) | :: | istdout |
destination for error messages |
||
| integer, | intent(in) | :: | istderr |
destination for error messages |
||
| integer, | intent(out) | :: | ierr |
return code, nonzero in case of error |
subroutine w90_distribute_kpts(common_data, num_kpts, mpi_size, dist_k, istdout, istderr, ierr) !! provide a distribution of num_kpts k-points across mpi_size MPI ranks ! should be called from all ranks in a parallel environment for error propagation use w90_comms, only: comms_sync_error use w90_error_base, only: w90_error_type use w90_error, only: set_error_fatal implicit none ! arguments integer, intent(in) :: num_kpts !! number of k-points integer, intent(in) :: mpi_size !! number of ranks in MPI communicator integer, intent(in) :: istdout, istderr !! destination for error messages integer, intent(inout), allocatable :: dist_k(:) !! already allocated array !! assigned here such that dist_k(i) = rank handling kpt i !! size and allocation status are tested integer, intent(out) :: ierr !! return code, nonzero in case of error type(lib_common_type), intent(in) :: common_data !! library object: only the communicator type is referenced ! local variables type(w90_error_type), allocatable :: error integer :: ctr, i, nkl ierr = 0 if (mpi_size < 1) then call set_error_fatal(error, 'Error: mpi_size < 1 in w90_distribute_kpts call.', common_data%comm) elseif (num_kpts < 1) then call set_error_fatal(error, 'Error: num_kpts < 1 in w90_distribute_kpts call.', common_data%comm) elseif (.not. allocated(dist_k)) then call set_error_fatal(error, 'Error: dist_k not allocated in w90_distribute_kpts call.', common_data%comm) elseif (size(dist_k) < num_kpts) then call set_error_fatal(error, 'Error: size(dist_k) < num_kpts in w90_distribute_kpts call.', common_data%comm) end if if (allocated(error)) then call prterr(error, ierr, istdout, istderr, common_data%comm) return end if ctr = 0 do i = 0, mpi_size - 1 nkl = num_kpts/mpi_size ! number of kpoints per rank if (mod(num_kpts, mpi_size) > i) nkl = nkl + 1 if (nkl > 0) then dist_k(ctr + 1:ctr + nkl) = i ctr = ctr + nkl end if end do end subroutine w90_distribute_kpts