76    type(mpi_grp_t) :: mpi_grp
 
   77    integer(int64) ::     np_global
 
   79    integer, 
allocatable        :: np_local_vec(:)
 
   80    integer(int64), 
allocatable :: istart_vec(:)
 
   85    integer(int64) :: istart
 
   86    integer, 
allocatable :: part(:)
 
  100    type(partition_t), 
intent(out) :: partition
 
  101    integer(int64),       
intent(in)  :: np_global
 
  102    type(mpi_grp_t),   
intent(in)  :: mpi_grp
 
  105    integer(int64) :: iend
 
  110    partition%mpi_grp = mpi_grp
 
  111    partition%np_global = np_global
 
  112    partition%npart = mpi_grp%size
 
  113    partition%partno = mpi_grp%rank + 1
 
  115    safe_allocate(partition%np_local_vec(1:partition%npart))
 
  116    safe_allocate(partition%istart_vec(1:partition%npart))
 
  119    do ipart = 1, partition%npart
 
  122      partition%istart_vec(ipart) = (ipart-1) * np_global/partition%npart + 1
 
  123      iend  = ipart * np_global/partition%npart
 
  124      partition%np_local_vec(ipart) = 
i8_to_i4(iend - partition%istart_vec(ipart) + 1)
 
  126    partition%istart = partition%istart_vec(partition%partno)
 
  127    partition%np_local = partition%np_local_vec(partition%partno)
 
  130    safe_allocate(partition%part(1:partition%np_local))
 
  137    type(partition_t), 
intent(inout) :: partition
 
  141    safe_deallocate_a(partition%part)
 
  148    type(partition_t), 
intent(inout) :: partition
 
  149    integer,           
intent(in)    :: part(:)
 
  153    partition%part(1:partition%np_local) = part(1:partition%np_local)
 
  165    type(partition_t), 
intent(in)  :: partition
 
  166    character(len=*),  
intent(in)  :: dir
 
  167    character(len=*),  
intent(in)  :: filename
 
  168    integer,           
intent(out) :: ierr
 
  171    character(len=MAX_PATH_LEN) :: full_filename
 
  176    full_filename = trim(dir)//
'/'//trim(filename)
 
  179    if (partition%mpi_grp%is_root()) 
then 
  181      if (err /= 0) ierr = ierr + 1
 
  183    call partition%mpi_grp%bcast(ierr, 1, mpi_integer, 0)
 
  185    assert(all(partition%part(:) > 0))
 
  194          partition%np_local, partition%part, err)
 
  196        if (err /= 0) ierr = ierr + 2
 
  210    use iso_c_binding, 
only: c_sizeof
 
  212    character(len=*),  
intent(in)    :: dir
 
  213    character(len=*),  
intent(in)    :: filename
 
  214    integer,           
intent(out)   :: ierr
 
  217    integer(int64) :: np, file_size
 
  218    integer, 
allocatable :: scounts(:)
 
  219    integer(int64), 
allocatable :: sdispls(:)
 
  220    character(len=MAX_PATH_LEN) :: full_filename
 
  225    full_filename = trim(dir)//
'/'//trim(filename)
 
  228    write(
message(1),
'(a,i8)') 
"Info: number of points in the partition (in root process) =", 
size(partition%part)
 
  234      assert(np == partition%np_global)
 
  238    call mpi_world%bcast(err, 1, mpi_integer, 0)
 
  239    call mpi_world%bcast(file_size, 1, mpi_integer8, 0)
 
  247    if (file_size - 64 /= partition%np_global * c_sizeof(int(0))) 
then 
  254    safe_allocate(scounts(1:partition%npart))
 
  255    safe_allocate(sdispls(1:partition%npart))
 
  257    scounts(:) = partition%np_local_vec(:)
 
  258    sdispls(:) = partition%istart_vec(:) - 1
 
  260    assert(sum(scounts(:)) == partition%np_global)
 
  265      partition%np_local, partition%part, err)
 
  267    if (err /= 0) ierr = ierr + 4
 
  270    if (any(partition%part(:) <= 0)) 
then 
  271      write(
message(1),
'(a)') 
'Internal error: some elements of partition are <= 0.' 
  272      write(
message(2),*) 
'filename = ', full_filename
 
  273      write(
message(3),*) 
'scounts = ', scounts(:)
 
  274      write(
message(4),*) 
'sdispls = ', sdispls(:)
 
  278    safe_deallocate_a(scounts)
 
  279    safe_deallocate_a(sdispls)
 
  287    integer(int64),       
intent(out) :: istart
 
  288    integer,           
intent(out) :: np_local
 
  292    istart = partition%istart
 
  293    np_local = partition%np_local
 
  303    integer,           
intent(out) :: part_global(:)
 
  304    integer, 
optional, 
intent(in)  :: root
 
  306    integer(int64), 
allocatable :: rdispls(:)
 
  307    integer, 
allocatable :: rcounts(:)
 
  311    safe_allocate(rdispls(1:partition%npart))
 
  312    safe_allocate(rcounts(1:partition%npart))
 
  314    rcounts(:) = partition%np_local_vec(:)
 
  315    rdispls(:) = partition%istart_vec(:) - 1
 
  317    assert(all(partition%part(1:partition%np_local) > 0))
 
  319    if (
present(root)) 
then 
  320      call partition%mpi_grp%gatherv(partition%part, partition%np_local, mpi_integer, &
 
  321        part_global, rcounts, rdispls, mpi_integer, root)
 
  323      call partition%mpi_grp%allgatherv(partition%part, partition%np_local, mpi_integer, &
 
  324        part_global, rcounts, rdispls, mpi_integer)
 
  327    if (.not. 
present(root) .or. partition%mpi_grp%is_root()) 
then 
  328      assert(all(part_global(:) > 0))
 
  332    part_global = partition%part
 
  335    safe_deallocate_a(rdispls)
 
  336    safe_deallocate_a(rcounts)
 
  348    integer,           
intent(in)  :: np
 
  349    integer(int64),       
intent(in)  :: points(:)
 
  350    integer,           
intent(out) :: partno(:)
 
  352    integer :: ip, nproc, rnp
 
  353    integer(int64), 
allocatable :: sbuffer(:), rbuffer(:)
 
  354    integer, 
allocatable :: scounts(:), rcounts(:)
 
  355    integer, 
allocatable :: sdispls(:), rdispls(:)
 
  356    integer, 
allocatable :: ipos(:), order(:)
 
  360    safe_allocate(scounts(1:partition%npart))
 
  361    safe_allocate(rcounts(1:partition%npart))
 
  362    safe_allocate(sdispls(1:partition%npart))
 
  363    safe_allocate(rdispls(1:partition%npart))
 
  371      scounts(nproc) = scounts(nproc) + 1
 
  376    call partition%mpi_grp%alltoall(scounts, 1, mpi_integer, &
 
  377      rcounts, 1, mpi_integer)
 
  382    do ip = 2, partition%npart
 
  383      sdispls(ip) = sdispls(ip-1) + scounts(ip-1)
 
  384      rdispls(ip) = rdispls(ip-1) + rcounts(ip-1)
 
  389    safe_allocate(sbuffer(1:np))
 
  390    safe_allocate(rbuffer(1:rnp))
 
  393    safe_allocate(ipos(1:partition%npart))
 
  394    safe_allocate(order(1:np))
 
  401      ipos(nproc) = ipos(nproc) + 1
 
  404      order(ip) = sdispls(nproc) + ipos(nproc)
 
  405      sbuffer(order(ip)) = points(ip) 
 
  407    safe_deallocate_a(ipos)
 
  410    call partition%mpi_grp%alltoallv(sbuffer, scounts, sdispls, mpi_integer8, &
 
  411      rbuffer, rcounts, rdispls, mpi_integer8)
 
  415      if (rbuffer(ip) == 0) cycle
 
  416      rbuffer(ip) = partition%part(rbuffer(ip) - partition%istart + 1)
 
  420    call partition%mpi_grp%alltoallv(rbuffer, rcounts, rdispls, mpi_integer8, &
 
  421      sbuffer, scounts, sdispls, mpi_integer8)
 
  425      partno(ip) = 
i8_to_i4(sbuffer(order(ip)))
 
  429    safe_deallocate_a(order)
 
  430    safe_deallocate_a(sbuffer)
 
  431    safe_deallocate_a(scounts)
 
  432    safe_deallocate_a(sdispls)
 
  433    safe_deallocate_a(rbuffer)
 
  434    safe_deallocate_a(rcounts)
 
  435    safe_deallocate_a(rdispls)
 
  443    integer(int64),       
intent(in)  :: np
 
  444    integer(int64),       
intent(in)  :: points(:)
 
  445    integer,           
intent(out) :: partno(:)
 
  447    integer(int64) :: rounds, offset, iround
 
  451    rounds = np/huge(0_int32)
 
  452    do iround = 1, rounds
 
  453      offset = (iround - 1)*huge(0_int32) + 1
 
  455        partno(offset:offset+huge(0_int32)))
 
  457    offset = rounds*huge(0_int32) + 1
 
  469    integer, 
contiguous,  
intent(inout) :: np_local_vec(:)
 
  471    integer, 
allocatable :: np_local_vec_tmp(:)
 
  476    assert(ubound(np_local_vec, 1) >= partition%npart)
 
  477    assert(partition%npart > 0)
 
  478    assert(all(partition%part(:) > 0))
 
  479    safe_allocate(np_local_vec_tmp(1:partition%npart))
 
  483    do ip = 1, partition%np_local
 
  484      np_local_vec_tmp(partition%part(ip)) = np_local_vec_tmp(partition%part(ip)) + 1
 
  488    call partition%mpi_grp%allreduce(np_local_vec_tmp, np_local_vec, partition%npart, mpi_integer, mpi_sum)
 
  489    safe_deallocate_a(np_local_vec_tmp)
 
  498    npart = partition%npart
 
  505    integer,           
intent(in) :: local_point
 
  506    part = partition%part(local_point)
 
  514    integer(int64),       
intent(in) :: global_point
 
  516    if (global_point == 0) 
then 
  517      part = partition%partno
 
  519      part = 
i8_to_i4((partition%npart*global_point - 1)/partition%np_global + 1)
 
  529    integer(int64), 
contiguous,  
intent(inout) :: rbuffer(:)
 
  530    integer,                  
intent(out)   :: np_local
 
  533    integer(int64) :: istart
 
  534    integer(int64), 
allocatable :: sdispls(:), rdispls(:), sbuffer(:)
 
  535    integer, 
allocatable :: scounts(:), rcounts(:)
 
  539    safe_allocate(sdispls(1:partition%npart))
 
  540    safe_allocate(scounts(1:partition%npart))
 
  541    safe_allocate(rcounts(1:partition%npart))
 
  544    istart = partition%istart - 1
 
  548    do ip = 1, partition%np_local
 
  549      ipart = partition%part(ip)
 
  550      scounts(ipart) = scounts(ipart) + 1
 
  555    do ipart = 2, partition%npart
 
  556      sdispls(ipart) = sdispls(ipart-1) + scounts(ipart-1)
 
  560    np_local = sum(scounts)
 
  562    safe_allocate(sbuffer(1:np_local))
 
  564      ipart = partition%part(ip)
 
  565      scounts(ipart) = scounts(ipart) + 1
 
  566      sbuffer(sdispls(ipart) + scounts(ipart)) = ip + istart
 
  570    call partition%mpi_grp%alltoall(scounts, 1, mpi_integer, &
 
  571      rcounts, 1, mpi_integer)
 
  574    np_local = sum(rcounts)
 
  575    safe_allocate(rdispls(1:partition%npart))
 
  576    assert(ubound(rbuffer, 1) >= np_local)
 
  579    do ipart = 2, partition%npart
 
  580      rdispls(ipart) = rcounts(ipart-1) + rdispls(ipart-1)
 
  584    call partition%mpi_grp%alltoallv(sbuffer, scounts, sdispls, mpi_integer8, &
 
  585      rbuffer, rcounts, rdispls, mpi_integer8)
 
  587    safe_deallocate_a(sdispls)
 
  588    safe_deallocate_a(scounts)
 
  589    safe_deallocate_a(sbuffer)
 
  590    safe_deallocate_a(rcounts)
 
  591    safe_deallocate_a(rdispls)
 
subroutine, public io_binary_get_info(fname, np, file_size, ierr)
 
subroutine, public iwrite_header(fname, np_global, ierr)
 
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
 
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
 
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
 
integer, parameter, public c_mpi_file_read
 
subroutine, public mpi_debug_in(comm, index)
 
subroutine, public mpi_debug_out(comm, index)
 
integer, parameter, public c_mpi_file_write
 
type(mpi_grp_t), public mpi_world
 
subroutine, public partition_init(partition, np_global, mpi_grp)
initialize the partition table
 
pure integer function partition_get_number(partition, global_point)
Returns the partition number for a given global index If the index is zero, return local partition.
 
pure integer function, public partition_get_npart(partition)
Returns the total number of partitions.
 
subroutine, public partition_set(partition, part)
 
subroutine partition_get_partition_number_4(partition, np, points, partno)
Given a list of global indices, return the partition number where those points are stored....
 
subroutine, public partition_get_np_local(partition, np_local_vec)
Given the partition, returns the corresponding number of local points that each partition has.
 
pure integer function, public partition_get_part(partition, local_point)
Returns the partition of the local point.
 
subroutine partition_get_partition_number_8(partition, np, points, partno)
 
subroutine, public partition_dump(partition, dir, filename, ierr)
write the partition data
 
subroutine, public partition_get_local(partition, rbuffer, np_local)
Calculates the local vector of all partitions in parallel. Local vector stores the global point indic...
 
subroutine, public partition_end(partition)
 
subroutine, public partition_load(partition, dir, filename, ierr)
read the partition data
 
subroutine, public partition_get_local_size(partition, istart, np_local)
 
subroutine, public partition_get_global(partition, part_global, root)
Returns the global partition. If root is present, the partition is gathered only in that node....
 
The partition is an array that contains the mapping between some global index and a process,...