123 integer,
allocatable :: ghost_sendpos(:)
125 integer,
allocatable :: ghost_rdispls(:)
126 integer,
allocatable :: ghost_sdispls(:)
127 integer,
allocatable :: ghost_rcounts(:)
128 integer,
allocatable :: ghost_scounts(:)
129 integer :: ghost_scount
130 integer,
allocatable :: ghost_sendmap(:)
131 integer,
allocatable :: ghost_recvmap(:)
132 type(accel_mem_t) :: buff_sendmap
133 type(accel_mem_t) :: buff_recvmap
136 type(mpi_grp_t) :: mpi_grp
138 integer(int64) :: np_global
140 integer,
allocatable :: np_local_vec(:)
144 integer(int64),
allocatable,
private :: xlocal_vec(:)
148 integer(int64) :: xlocal
151 integer(int64),
allocatable,
private :: local(:)
153 integer,
allocatable :: recv_count(:)
154 integer,
allocatable :: send_count(:)
156 integer,
allocatable :: recv_disp(:)
157 integer,
allocatable :: send_disp(:)
158 integer(int64),
allocatable:: sendmap(:)
159 integer(int64),
allocatable:: recvmap(:)
163 integer(int64),
allocatable,
private :: bndry(:)
165 type(lihash_t),
private :: global
168 integer(int64),
allocatable,
private :: ghost(:)
200 subroutine par_vec_init(mpi_grp, np_global, idx, stencil, space, partition, pv, namespace)
201 type(mpi_grp_t),
intent(in) :: mpi_grp
203 integer(int64),
intent(in) :: np_global
204 type(index_t),
intent(in) :: idx
205 type(stencil_t),
intent(in) :: stencil
206 class(space_t),
intent(in) :: space
207 type(partition_t),
intent(in) :: partition
208 type(par_vec_t),
intent(inout) :: pv
209 type(namespace_t),
intent(in) :: namespace
215 integer(int64) :: gip, index
216 integer :: ip, jp, jj, inode
217 integer :: p1(space%dim)
220 integer(int64),
allocatable :: boundary_inv(:), ghost_inv(:)
222 character(len=6) :: filenum
225 integer :: idir, ipart, itmp
226 integer(int64) :: tmp
227 integer,
allocatable :: points(:), part_ghost(:), part_ghost_tmp(:)
228 integer(int64),
allocatable :: indices(:), ghost_tmp(:)
237 pv%rank = mpi_grp%rank
238 pv%partno = pv%rank + 1
241 pv%np_global = np_global
245 safe_allocate(pv%np_local_vec(1:npart))
246 safe_allocate(pv%xlocal_vec(1:npart))
247 safe_allocate(pv%ghost_rcounts(1:npart))
248 safe_allocate(pv%ghost_scounts(1:npart))
253 pv%np_local = pv%np_local_vec(pv%partno)
260 pv%xlocal_vec(inode) = pv%xlocal_vec(inode - 1) + pv%np_local_vec(inode - 1)
262 pv%xlocal = pv%xlocal_vec(pv%partno)
264 safe_allocate(pv%local(pv%xlocal:pv%xlocal + pv%np_local - 1))
271 do ip = 1, pv%np_local
272 call lihash_insert(pv%global, pv%local(pv%xlocal + ip - 1), ip)
280 safe_allocate(boundary_inv(1:pv%np_local))
281 safe_allocate(ghost_inv(1:pv%np_local))
284 do gip = pv%xlocal, pv%xlocal + pv%np_local - 1
288 do jj = 1, stencil%size
296 if (index > np_global)
then
299 pv%np_bndry = pv%np_bndry + 1
301 if (pv%np_bndry >= ubound(boundary_inv, 1))
call make_array_larger(boundary_inv, pv%np_bndry*2)
302 boundary_inv(pv%np_bndry) = index
306 pv%np_ghost = pv%np_ghost + 1
308 if (pv%np_ghost >= ubound(ghost_inv, 1))
call make_array_larger(ghost_inv, pv%np_ghost*2)
309 ghost_inv(pv%np_ghost) = index
314 safe_allocate(pv%bndry(1:pv%np_bndry))
315 do ip = 1, pv%np_bndry
316 pv%bndry(ip) = boundary_inv(ip)
320 safe_allocate(ghost_tmp(1:pv%np_ghost))
321 do ip = 1, pv%np_ghost
322 ghost_tmp(ip) = ghost_inv(ip)
326 safe_deallocate_a(ghost_inv)
327 safe_deallocate_a(boundary_inv)
329 safe_allocate(part_ghost_tmp(1:pv%np_ghost))
331 ghost_tmp, part_ghost_tmp)
334 pv%ghost_rcounts(:) = 0
335 do ip = 1, pv%np_ghost
336 ipart = part_ghost_tmp(ip)
337 pv%ghost_rcounts(ipart) = pv%ghost_rcounts(ipart)+1
339 assert(sum(pv%ghost_rcounts) == pv%np_ghost)
341 safe_allocate(pv%ghost_rdispls(1:pv%npart))
342 pv%ghost_rdispls(1) = 0
343 do ipart = 2, pv%npart
344 pv%ghost_rdispls(ipart) = pv%ghost_rdispls(ipart - 1) + pv%ghost_rcounts(ipart - 1)
348 safe_allocate(pv%ghost(1:pv%np_ghost))
349 safe_allocate(part_ghost(1:pv%np_ghost))
350 safe_allocate(points(1:pv%npart))
352 do ip = 1, pv%np_ghost
353 ipart = part_ghost_tmp(ip)
354 points(ipart) = points(ipart)+1
356 jp = pv%ghost_rdispls(ipart) + points(ipart)
357 pv%ghost(jp) = ghost_tmp(ip)
358 part_ghost(jp) = part_ghost_tmp(ip)
360 safe_deallocate_a(points)
361 safe_deallocate_a(ghost_tmp)
362 safe_deallocate_a(part_ghost_tmp)
364 call pv%mpi_grp%alltoall(pv%ghost_rcounts, 1, mpi_integer, &
365 pv%ghost_scounts, 1, mpi_integer)
367 safe_allocate(pv%ghost_sdispls(1:pv%npart))
369 pv%ghost_sdispls(1) = 0
370 do ipart = 2, pv%npart
371 pv%ghost_sdispls(ipart) = pv%ghost_sdispls(ipart - 1) + pv%ghost_scounts(ipart - 1)
373 pv%ghost_scount = sum(pv%ghost_scounts)
375 safe_allocate(pv%ghost_recvmap(1:pv%np_ghost))
376 safe_allocate(points(1:pv%npart))
378 do ip = 1, pv%np_ghost
379 ipart = part_ghost(ip)
380 points(ipart) = points(ipart) + 1
381 pv%ghost_recvmap(ip) = pv%ghost_rdispls(ipart) + points(ipart)
383 safe_deallocate_a(points)
385 safe_allocate(indices(1:pv%np_ghost))
386 do ip = 1, pv%np_ghost
387 indices(pv%ghost_recvmap(ip)) = pv%ghost(ip)
389 safe_allocate(pv%ghost_sendmap(1:pv%ghost_scount))
390 safe_allocate(ghost_tmp(1:pv%ghost_scount))
391 call pv%mpi_grp%alltoallv(indices, pv%ghost_rcounts, pv%ghost_rdispls, mpi_integer8, &
392 ghost_tmp, pv%ghost_scounts, pv%ghost_sdispls, mpi_integer8)
393 do ip = 1, pv%ghost_scount
397 pv%ghost_sendmap(ip) = jp
399 safe_deallocate_a(indices)
400 safe_deallocate_a(ghost_tmp)
415 call io_mkdir(
'debug/mesh_partition', namespace, parents=.
true.)
417 write(filenum,
'(i6.6)') pv%partno
418 iunit =
io_open(
'debug/mesh_partition/ghost_points.'//filenum, namespace, action=
'write')
419 do ip = 1, pv%np_ghost
421 write(iunit,
'(99i8)') pv%ghost(ip), (p1(idir), idir = 1, space%dim)
430 do ip = 1, pv%np_ghost
431 call lihash_insert(pv%global, pv%ghost(ip), ip + pv%np_local)
434 do ip = 1, pv%np_bndry
435 call lihash_insert(pv%global, pv%bndry(ip), ip + pv%np_local + pv%np_ghost)
438 safe_deallocate_a(part_ghost)
444 integer :: ip, nn, direction
445 integer(int64) :: ipg
446 integer :: bsize(space%dim), order, point(space%dim), number_of_blocks(space%dim)
447 integer(int64),
allocatable :: reorder_indices(:)
448 integer(int64),
allocatable :: reordered(:)
449 integer,
allocatable :: global_indices(:)
451 logical :: increase_with_dimension
452 integer,
parameter :: &
474 call parse_variable(namespace,
'MeshLocalOrder', order_blocks, order)
476 if (space%dim == 1)
then
495 call parse_variable(namespace,
'MeshLocalBlockDirection', 1, direction)
496 increase_with_dimension = direction == 1
497 if (direction /= 1 .and. direction /= 2)
then
504 case (order_blocks, order_cube)
505 if (order == order_cube)
then
506 bsize(1:space%dim) = idx%nr(2, 1:space%dim) - idx%nr(1, 1:space%dim) + 1
519 if (
conf%target_states_block_size < 16)
then
520 bsize(1) = 80 * 4 / abs(
conf%target_states_block_size)
521 if (space%dim > 1) bsize(2) = 4
522 if (space%dim > 2) bsize(3:) = 10
524 bsize(1) = max(4 * 16 / abs(
conf%target_states_block_size), 1)
525 if (space%dim > 1) bsize(2) = 15
526 if (space%dim > 2) bsize(3:) = 15
529 if (
parse_block(namespace,
'MeshLocalBlockSize', blk) == 0)
then
531 if (nn /= space%dim)
then
532 message(1) =
"Error: number of entries in MeshLocalBlockSize must match the umber of dimensions."
541 number_of_blocks(1:space%dim) = idx%ll(1:space%dim)/bsize(1:space%dim) + 1
544 safe_allocate(reorder_indices(1:pv%np_local))
545 safe_allocate(global_indices(1:pv%np_local))
546 do ip = 1, pv%np_local
547 ipg = pv%local(ip + pv%xlocal - 1)
549 point = point + idx%offset + idx%enlarge
550 reorder_indices(ip) =
get_blocked_index(space%dim, point, bsize, number_of_blocks, increase_with_dimension)
553 call sort(reorder_indices, global_indices)
554 safe_deallocate_a(reorder_indices)
557 safe_allocate(reordered(1:pv%np_local))
558 do ip = 1, pv%np_local
559 reordered(ip) = pv%local(global_indices(ip) + pv%xlocal - 1)
561 safe_deallocate_a(global_indices)
564 do ip = 1, pv%np_local
565 pv%local(ip + pv%xlocal - 1) = reordered(ip)
567 safe_deallocate_a(reordered)
573 do ip = 1, pv%np_local
574 call lihash_insert(pv%global, pv%local(pv%xlocal + ip - 1), ip)
582 integer,
allocatable :: part_local(:)
586 safe_allocate(part_local(1:pv%np_local))
587 safe_allocate(indices(1:pv%np_local))
588 do ip = 1, pv%np_local
589 indices(ip) = pv%xlocal + ip - 1
593 safe_deallocate_a(indices)
595 safe_allocate(pv%send_count(1:npart))
596 safe_allocate(pv%recv_count(1:npart))
597 safe_allocate(pv%send_disp(1:npart))
598 safe_allocate(pv%recv_disp(1:npart))
601 do ip = 1, pv%np_local
602 ipart = part_local(ip)
603 pv%send_count(ipart) = pv%send_count(ipart) + 1
607 pv%send_disp(ipart) = pv%send_disp(ipart - 1) + pv%send_count(ipart - 1)
610 call pv%mpi_grp%alltoall(pv%send_count, 1, mpi_integer, &
611 pv%recv_count, 1, mpi_integer)
615 pv%recv_disp(ipart) = pv%recv_disp(ipart - 1) + pv%recv_count(ipart - 1)
619 safe_allocate(pv%sendmap(1:pv%np_local))
620 safe_allocate(points(1:pv%npart))
622 do ip = 1, pv%np_local
623 ipart = part_local(ip)
624 points(ipart) = points(ipart) + 1
625 pv%sendmap(ip) = pv%send_disp(ipart) + points(ipart)
627 safe_deallocate_a(points)
629 safe_allocate(indices(1:pv%np_local))
630 do ip = 1, pv%np_local
631 indices(pv%sendmap(ip)) = pv%xlocal + ip - 1
633 safe_allocate(pv%recvmap(1:sum(pv%recv_count)))
634 call pv%mpi_grp%alltoallv(indices, pv%send_count, pv%send_disp, mpi_integer8, &
635 pv%recvmap, pv%recv_count, pv%recv_disp, mpi_integer8)
636 do ip = 1, sum(pv%recv_count)
640 pv%recvmap(ip) = index
642 safe_deallocate_a(indices)
655 safe_deallocate_a(pv%ghost_rdispls)
656 safe_deallocate_a(pv%ghost_sdispls)
657 safe_deallocate_a(pv%ghost_rcounts)
658 safe_deallocate_a(pv%ghost_scounts)
659 safe_deallocate_a(pv%ghost_sendpos)
660 safe_deallocate_a(pv%ghost_recvmap)
661 safe_deallocate_a(pv%ghost_sendmap)
662 safe_deallocate_a(pv%send_disp)
663 safe_deallocate_a(pv%recv_disp)
664 safe_deallocate_a(pv%np_local_vec)
665 safe_deallocate_a(pv%xlocal_vec)
666 safe_deallocate_a(pv%local)
667 safe_deallocate_a(pv%send_count)
668 safe_deallocate_a(pv%recv_count)
669 safe_deallocate_a(pv%sendmap)
670 safe_deallocate_a(pv%recvmap)
671 safe_deallocate_a(pv%bndry)
672 safe_deallocate_a(pv%ghost)
690 integer(int64),
intent(in) :: ipg
697 if (pv%npart > 1)
then
702 assert(ipg < huge(ip))
711 integer,
intent(in) :: ip
715 if (pv%npart == 1)
then
718 if (ip <= pv%np_local)
then
719 ipg = pv%local(pv%xlocal + ip - 1)
720 else if (ip <= pv%np_local + pv%np_ghost)
then
721 ipg = pv%ghost(ip - pv%np_local)
722 else if (ip <= pv%np_local + pv%np_ghost + pv%np_bndry)
then
723 ipg = pv%bndry(ip - pv%np_local - pv%np_ghost)
734 integer,
intent(in) :: root
735 integer(int64),
allocatable,
intent(inout) :: local_vec(:)
737 integer(int64),
allocatable :: xlocal_tmp(:)
741 safe_allocate(xlocal_tmp(1:pv%npart))
742 xlocal_tmp = pv%xlocal_vec - 1
744 call pv%mpi_grp%gatherv(pv%local(pv%xlocal:), pv%np_local, mpi_integer8, &
745 local_vec, pv%np_local_vec, xlocal_tmp, mpi_integer8, root)
746 safe_deallocate_a(xlocal_tmp)
752#include "complex.F90"
753#include "par_vec_inc.F90"
757#include "par_vec_inc.F90"
760#include "integer.F90"
761#include "par_vec_inc.F90"
This is the common interface to a sorting routine. It performs the shell algorithm,...
subroutine, public accel_release_buffer(this)
pure logical function, public accel_is_enabled()
integer, parameter, public accel_mem_read_only
type(debug_t), save, public debug
type(conf_t), public conf
Global instance of Octopus configuration.
This module implements a simple hash table for non-negative integer keys and integer values.
integer function, public lihash_lookup(h, key, found)
Look up a value in the hash table h. If found is present, it indicates if key could be found in the t...
subroutine, public lihash_insert(h, key, val)
Insert a (key, val) pair into the hash table h.
subroutine, public lihash_end(h)
Free a hash table.
subroutine, public lihash_init(h)
Initialize a hash table h.
This module implements the index, used for the mesh points.
integer(int64) function, public get_blocked_index(dim, point, bsize, number_of_blocks, increase_with_dimensions)
subroutine, public index_spatial_to_point(idx, dim, ispatial, point)
subroutine, public index_to_coords(idx, ip, ix)
Given a global point index, this function returns the set of integer coordinates of the point.
integer(int64) function, public index_from_coords(idx, ix)
This function takes care of the boundary conditions for a given vector of integer coordinates it retu...
subroutine, public io_close(iunit, grp)
subroutine, public io_mkdir(fname, namespace, parents)
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
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_input_error(namespace, var, details, row, column)
subroutine mpi_grp_copy(mpi_grp_out, mpi_grp_in)
Some general things and nomenclature:
subroutine, public par_vec_end(pv)
Deallocate memory used by pv.
integer function, public par_vec_global2local(pv, ipg)
Returns local number of global point ip on the local node If the result is zero, the point is not ava...
subroutine ipar_vec_scatter(pv, root, v_local, v)
Generally: Xpar_vec_gather and Xpar_vec_scatter only consider inner points. Xpar_vec_scatter_bndry ta...
subroutine dpar_vec_allgather(pv, v, v_local)
Like Xpar_vec_gather but the result is gathered on all nodes, i. e. v has to be a properly allocated ...
subroutine zpar_vec_scatter(pv, root, v_local, v)
Generally: Xpar_vec_gather and Xpar_vec_scatter only consider inner points. Xpar_vec_scatter_bndry ta...
subroutine dpar_vec_scatter(pv, root, v_local, v)
Generally: Xpar_vec_gather and Xpar_vec_scatter only consider inner points. Xpar_vec_scatter_bndry ta...
integer(int64) function, public par_vec_local2global(pv, ip)
Returns global index of local point ip.
subroutine, public par_vec_init(mpi_grp, np_global, idx, stencil, space, partition, pv, namespace)
Initializes a par_vec_type object (parallel vector).
subroutine ipar_vec_gather(pv, root, v_local, v)
Reverse operation of Xpar_vec_scatter. All v_locals from the nodes are packed together into v on node...
subroutine zpar_vec_gather(pv, root, v_local, v)
Reverse operation of Xpar_vec_scatter. All v_locals from the nodes are packed together into v on node...
subroutine gather_local_vec(pv, root, local_vec)
subroutine dpar_vec_gather(pv, root, v_local, v)
Reverse operation of Xpar_vec_scatter. All v_locals from the nodes are packed together into v on node...
subroutine zpar_vec_allgather(pv, v, v_local)
Like Xpar_vec_gather but the result is gathered on all nodes, i. e. v has to be a properly allocated ...
subroutine ipar_vec_allgather(pv, v, v_local)
Like Xpar_vec_gather but the result is gathered on all nodes, i. e. v has to be a properly allocated ...
integer function, public parse_block(namespace, name, blk, check_varinfo_)
subroutine, public partition_get_np_local(partition, np_local_vec)
Given the partition, returns the corresponding number of local points that each partition has.
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...
This module is intended to contain "only mathematical" functions and procedures.
This module defines stencils used in Octopus.
type(type_t), public type_integer
This module is intended to contain simple general-purpose utility functions and procedures.
subroutine, public make_array_larger(array, new_size)
subroutine init_mpi_alltoall()
subroutine reorder_points()