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)
142 safe_deallocate_a(partition%np_local_vec)
143 safe_deallocate_a(partition%istart_vec)
150 type(partition_t),
intent(inout) :: partition
151 integer,
intent(in) :: part(:)
155 partition%part(1:partition%np_local) = part(1:partition%np_local)
167 type(partition_t),
intent(in) :: partition
168 character(len=*),
intent(in) :: dir
169 character(len=*),
intent(in) :: filename
170 integer,
intent(out) :: ierr
173 character(len=MAX_PATH_LEN) :: full_filename
178 full_filename = trim(dir)//
'/'//trim(filename)
183 if (err /= 0) ierr = ierr + 1
185 call partition%mpi_grp%bcast(ierr, 1, mpi_integer, 0)
187 assert(all(partition%part(:) > 0))
196 partition%np_local, partition%part, err)
198 if (err /= 0) ierr = ierr + 2
212 use iso_c_binding,
only: c_sizeof
214 character(len=*),
intent(in) :: dir
215 character(len=*),
intent(in) :: filename
216 integer,
intent(out) :: ierr
219 integer(int64) :: np, file_size
220 integer,
allocatable :: scounts(:)
221 integer(int64),
allocatable :: sdispls(:)
222 character(len=MAX_PATH_LEN) :: full_filename
227 full_filename = trim(dir)//
'/'//trim(filename)
230 write(
message(1),
'(a,i8)')
"Info: number of points in the partition (in root process) =",
size(partition%part)
236 assert(np == partition%np_global)
240 call mpi_world%bcast(err, 1, mpi_integer, 0)
241 call mpi_world%bcast(file_size, 1, mpi_integer8, 0)
249 if (file_size - 64 /= partition%np_global * c_sizeof(int(0)))
then
256 safe_allocate(scounts(1:partition%npart))
257 safe_allocate(sdispls(1:partition%npart))
259 scounts(:) = partition%np_local_vec(:)
260 sdispls(:) = partition%istart_vec(:) - 1
262 assert(sum(scounts(:)) == partition%np_global)
267 partition%np_local, partition%part, err)
269 if (err /= 0) ierr = ierr + 4
272 if (any(partition%part(:) <= 0))
then
273 write(
message(1),
'(a)')
'Internal error: some elements of partition are <= 0.'
274 write(
message(2),*)
'filename = ', full_filename
275 write(
message(3),*)
'scounts = ', scounts(:)
276 write(
message(4),*)
'sdispls = ', sdispls(:)
280 safe_deallocate_a(scounts)
281 safe_deallocate_a(sdispls)
289 integer(int64),
intent(out) :: istart
290 integer,
intent(out) :: np_local
294 istart = partition%istart
295 np_local = partition%np_local
305 integer,
intent(out) :: part_global(:)
306 integer,
optional,
intent(in) :: root
308 integer(int64),
allocatable :: rdispls(:)
309 integer,
allocatable :: rcounts(:)
313 safe_allocate(rdispls(1:partition%npart))
314 safe_allocate(rcounts(1:partition%npart))
316 rcounts(:) = partition%np_local_vec(:)
317 rdispls(:) = partition%istart_vec(:) - 1
319 assert(all(partition%part(1:partition%np_local) > 0))
321 if (
present(root))
then
322 call partition%mpi_grp%gatherv(partition%part, partition%np_local, mpi_integer, &
323 part_global, rcounts, rdispls, mpi_integer, root)
325 call partition%mpi_grp%allgatherv(partition%part, partition%np_local, mpi_integer, &
326 part_global, rcounts, rdispls, mpi_integer)
329 if (.not.
present(root) .or. partition%mpi_grp%rank == 0)
then
330 assert(all(part_global(:) > 0))
334 part_global = partition%part
337 safe_deallocate_a(rdispls)
338 safe_deallocate_a(rcounts)
350 integer,
intent(in) :: np
351 integer(int64),
intent(in) :: points(:)
352 integer,
intent(out) :: partno(:)
354 integer :: ip, nproc, rnp
355 integer(int64),
allocatable :: sbuffer(:), rbuffer(:)
356 integer,
allocatable :: scounts(:), rcounts(:)
357 integer,
allocatable :: sdispls(:), rdispls(:)
358 integer,
allocatable :: ipos(:), order(:)
362 safe_allocate(scounts(1:partition%npart))
363 safe_allocate(rcounts(1:partition%npart))
364 safe_allocate(sdispls(1:partition%npart))
365 safe_allocate(rdispls(1:partition%npart))
373 scounts(nproc) = scounts(nproc) + 1
378 call partition%mpi_grp%alltoall(scounts, 1, mpi_integer, &
379 rcounts, 1, mpi_integer)
384 do ip = 2, partition%npart
385 sdispls(ip) = sdispls(ip-1) + scounts(ip-1)
386 rdispls(ip) = rdispls(ip-1) + rcounts(ip-1)
391 safe_allocate(sbuffer(1:np))
392 safe_allocate(rbuffer(1:rnp))
395 safe_allocate(ipos(1:partition%npart))
396 safe_allocate(order(1:np))
403 ipos(nproc) = ipos(nproc) + 1
406 order(ip) = sdispls(nproc) + ipos(nproc)
407 sbuffer(order(ip)) = points(ip)
409 safe_deallocate_a(ipos)
412 call partition%mpi_grp%alltoallv(sbuffer, scounts, sdispls, mpi_integer8, &
413 rbuffer, rcounts, rdispls, mpi_integer8)
417 if (rbuffer(ip) == 0) cycle
418 rbuffer(ip) = partition%part(rbuffer(ip) - partition%istart + 1)
422 call partition%mpi_grp%alltoallv(rbuffer, rcounts, rdispls, mpi_integer8, &
423 sbuffer, scounts, sdispls, mpi_integer8)
427 partno(ip) =
i8_to_i4(sbuffer(order(ip)))
431 safe_deallocate_a(order)
432 safe_deallocate_a(sbuffer)
433 safe_deallocate_a(scounts)
434 safe_deallocate_a(sdispls)
435 safe_deallocate_a(rbuffer)
436 safe_deallocate_a(rcounts)
437 safe_deallocate_a(rdispls)
445 integer(int64),
intent(in) :: np
446 integer(int64),
intent(in) :: points(:)
447 integer,
intent(out) :: partno(:)
449 integer(int64) :: rounds, offset, iround
453 rounds = np/huge(0_int32)
454 do iround = 1, rounds
455 offset = (iround - 1)*huge(0_int32) + 1
457 partno(offset:offset+huge(0_int32)))
459 offset = rounds*huge(0_int32) + 1
471 integer,
contiguous,
intent(inout) :: np_local_vec(:)
473 integer,
allocatable :: np_local_vec_tmp(:)
478 assert(ubound(np_local_vec, 1) >= partition%npart)
479 assert(partition%npart > 0)
480 assert(all(partition%part(:) > 0))
481 safe_allocate(np_local_vec_tmp(1:partition%npart))
485 do ip = 1, partition%np_local
486 np_local_vec_tmp(partition%part(ip)) = np_local_vec_tmp(partition%part(ip)) + 1
490 call partition%mpi_grp%allreduce(np_local_vec_tmp, np_local_vec, partition%npart, mpi_integer, mpi_sum)
491 safe_deallocate_a(np_local_vec_tmp)
500 npart = partition%npart
507 integer,
intent(in) :: local_point
508 part = partition%part(local_point)
516 integer(int64),
intent(in) :: global_point
518 if (global_point == 0)
then
519 part = partition%partno
521 part =
i8_to_i4((partition%npart*global_point - 1)/partition%np_global + 1)
531 integer(int64),
contiguous,
intent(inout) :: rbuffer(:)
532 integer,
intent(out) :: np_local
535 integer(int64) :: istart
536 integer(int64),
allocatable :: sdispls(:), rdispls(:), sbuffer(:)
537 integer,
allocatable :: scounts(:), rcounts(:)
541 safe_allocate(sdispls(1:partition%npart))
542 safe_allocate(scounts(1:partition%npart))
543 safe_allocate(rcounts(1:partition%npart))
546 istart = partition%istart - 1
550 do ip = 1, partition%np_local
551 ipart = partition%part(ip)
552 scounts(ipart) = scounts(ipart) + 1
557 do ipart = 2, partition%npart
558 sdispls(ipart) = sdispls(ipart-1) + scounts(ipart-1)
562 np_local = sum(scounts)
564 safe_allocate(sbuffer(1:np_local))
566 ipart = partition%part(ip)
567 scounts(ipart) = scounts(ipart) + 1
568 sbuffer(sdispls(ipart) + scounts(ipart)) = ip + istart
572 call partition%mpi_grp%alltoall(scounts, 1, mpi_integer, &
573 rcounts, 1, mpi_integer)
576 np_local = sum(rcounts)
577 safe_allocate(rdispls(1:partition%npart))
578 assert(ubound(rbuffer, 1) >= np_local)
581 do ipart = 2, partition%npart
582 rdispls(ipart) = rcounts(ipart-1) + rdispls(ipart-1)
586 call partition%mpi_grp%alltoallv(sbuffer, scounts, sdispls, mpi_integer8, &
587 rbuffer, rcounts, rdispls, mpi_integer8)
589 safe_deallocate_a(sdispls)
590 safe_deallocate_a(scounts)
591 safe_deallocate_a(sbuffer)
592 safe_deallocate_a(rcounts)
593 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
logical function mpi_grp_is_root(grp)
Is the current MPI process of grpcomm, root.
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,...