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(:)
206 subroutine par_vec_init(mpi_grp, np_global, idx, stencil, space, partition, pv, namespace)
207 type(mpi_grp_t),
intent(in) :: mpi_grp
209 integer(int64),
intent(in) :: np_global
210 type(index_t),
intent(in) :: idx
211 type(stencil_t),
intent(in) :: stencil
212 class(space_t),
intent(in) :: space
213 type(partition_t),
intent(in) :: partition
214 type(par_vec_t),
intent(inout) :: pv
215 type(namespace_t),
intent(in) :: namespace
221 integer(int64) :: gip, index
222 integer :: ip, jp, jj, inode
223 integer :: p1(space%dim)
226 integer(int64),
allocatable :: boundary_inv(:), ghost_inv(:)
228 character(len=6) :: filenum
231 integer :: idir, ipart, itmp
232 integer(int64) :: tmp
233 integer,
allocatable :: points(:), part_ghost(:), part_ghost_tmp(:)
234 integer(int64),
allocatable :: indices(:), ghost_tmp(:)
243 pv%rank = mpi_grp%rank
244 pv%partno = pv%rank + 1
247 pv%np_global = np_global
251 safe_allocate(pv%np_local_vec(1:npart))
252 safe_allocate(pv%xlocal_vec(1:npart))
253 safe_allocate(pv%ghost_rcounts(1:npart))
254 safe_allocate(pv%ghost_scounts(1:npart))
259 pv%np_local = pv%np_local_vec(pv%partno)
266 pv%xlocal_vec(inode) = pv%xlocal_vec(inode - 1) + pv%np_local_vec(inode - 1)
268 pv%xlocal = pv%xlocal_vec(pv%partno)
270 safe_allocate(pv%local(pv%xlocal:pv%xlocal + pv%np_local - 1))
277 do ip = 1, pv%np_local
278 call lihash_insert(pv%global, pv%local(pv%xlocal + ip - 1), ip)
286 safe_allocate(boundary_inv(1:pv%np_local))
287 safe_allocate(ghost_inv(1:pv%np_local))
290 do gip = pv%xlocal, pv%xlocal + pv%np_local - 1
294 do jj = 1, stencil%size
302 if (index > np_global)
then
305 pv%np_bndry = pv%np_bndry + 1
307 if (pv%np_bndry >= ubound(boundary_inv, 1))
call make_array_larger(boundary_inv, pv%np_bndry*2)
308 boundary_inv(pv%np_bndry) = index
312 pv%np_ghost = pv%np_ghost + 1
314 if (pv%np_ghost >= ubound(ghost_inv, 1))
call make_array_larger(ghost_inv, pv%np_ghost*2)
315 ghost_inv(pv%np_ghost) = index
320 safe_allocate(pv%bndry(1:pv%np_bndry))
321 do ip = 1, pv%np_bndry
322 pv%bndry(ip) = boundary_inv(ip)
326 safe_allocate(ghost_tmp(1:pv%np_ghost))
327 do ip = 1, pv%np_ghost
328 ghost_tmp(ip) = ghost_inv(ip)
332 safe_deallocate_a(ghost_inv)
333 safe_deallocate_a(boundary_inv)
335 safe_allocate(part_ghost_tmp(1:pv%np_ghost))
337 ghost_tmp, part_ghost_tmp)
340 pv%ghost_rcounts(:) = 0
341 do ip = 1, pv%np_ghost
342 ipart = part_ghost_tmp(ip)
343 pv%ghost_rcounts(ipart) = pv%ghost_rcounts(ipart)+1
345 assert(sum(pv%ghost_rcounts) == pv%np_ghost)
347 safe_allocate(pv%ghost_rdispls(1:pv%npart))
348 pv%ghost_rdispls(1) = 0
349 do ipart = 2, pv%npart
350 pv%ghost_rdispls(ipart) = pv%ghost_rdispls(ipart - 1) + pv%ghost_rcounts(ipart - 1)
354 safe_allocate(pv%ghost(1:pv%np_ghost))
355 safe_allocate(part_ghost(1:pv%np_ghost))
356 safe_allocate(points(1:pv%npart))
358 do ip = 1, pv%np_ghost
359 ipart = part_ghost_tmp(ip)
360 points(ipart) = points(ipart)+1
362 jp = pv%ghost_rdispls(ipart) + points(ipart)
363 pv%ghost(jp) = ghost_tmp(ip)
364 part_ghost(jp) = part_ghost_tmp(ip)
366 safe_deallocate_a(points)
367 safe_deallocate_a(ghost_tmp)
368 safe_deallocate_a(part_ghost_tmp)
370 call pv%mpi_grp%alltoall(pv%ghost_rcounts, 1, mpi_integer, &
371 pv%ghost_scounts, 1, mpi_integer)
373 safe_allocate(pv%ghost_sdispls(1:pv%npart))
375 pv%ghost_sdispls(1) = 0
376 do ipart = 2, pv%npart
377 pv%ghost_sdispls(ipart) = pv%ghost_sdispls(ipart - 1) + pv%ghost_scounts(ipart - 1)
379 pv%ghost_scount = sum(pv%ghost_scounts)
381 safe_allocate(pv%ghost_recvmap(1:pv%np_ghost))
382 safe_allocate(points(1:pv%npart))
384 do ip = 1, pv%np_ghost
385 ipart = part_ghost(ip)
386 points(ipart) = points(ipart) + 1
387 pv%ghost_recvmap(ip) = pv%ghost_rdispls(ipart) + points(ipart)
389 safe_deallocate_a(points)
391 safe_allocate(indices(1:pv%np_ghost))
392 do ip = 1, pv%np_ghost
393 indices(pv%ghost_recvmap(ip)) = pv%ghost(ip)
395 safe_allocate(pv%ghost_sendmap(1:pv%ghost_scount))
396 safe_allocate(ghost_tmp(1:pv%ghost_scount))
397 call pv%mpi_grp%alltoallv(indices, pv%ghost_rcounts, pv%ghost_rdispls, mpi_integer8, &
398 ghost_tmp, pv%ghost_scounts, pv%ghost_sdispls, mpi_integer8)
399 do ip = 1, pv%ghost_scount
403 pv%ghost_sendmap(ip) = jp
405 safe_deallocate_a(indices)
406 safe_deallocate_a(ghost_tmp)
421 call io_mkdir(
'debug/mesh_partition', namespace, parents=.
true.)
423 write(filenum,
'(i6.6)') pv%partno
424 iunit =
io_open(
'debug/mesh_partition/ghost_points.'//filenum, namespace, action=
'write')
425 do ip = 1, pv%np_ghost
427 write(iunit,
'(99i8)') pv%ghost(ip), (p1(idir), idir = 1, space%dim)
436 do ip = 1, pv%np_ghost
437 call lihash_insert(pv%global, pv%ghost(ip), ip + pv%np_local)
440 do ip = 1, pv%np_bndry
441 call lihash_insert(pv%global, pv%bndry(ip), ip + pv%np_local + pv%np_ghost)
444 safe_deallocate_a(part_ghost)
450 integer :: ip, nn, direction
451 integer(int64) :: ipg
452 integer :: bsize(space%dim), order, point(space%dim), number_of_blocks(space%dim)
453 integer(int64),
allocatable :: reorder_indices(:)
454 integer(int64),
allocatable :: reordered(:)
455 integer,
allocatable :: global_indices(:)
457 logical :: increase_with_dimension
458 integer,
parameter :: &
480 call parse_variable(namespace,
'MeshLocalOrder', order_blocks, order)
482 if (space%dim == 1)
then
501 call parse_variable(namespace,
'MeshLocalBlockDirection', 1, direction)
502 increase_with_dimension = direction == 1
503 if (direction /= 1 .and. direction /= 2)
then
510 case (order_blocks, order_cube)
511 if (order == order_cube)
then
512 bsize(1:space%dim) = idx%nr(2, 1:space%dim) - idx%nr(1, 1:space%dim) + 1
525 if (
conf%target_states_block_size < 16)
then
526 bsize(1) = 80 * 4 / abs(
conf%target_states_block_size)
527 if (space%dim > 1) bsize(2) = 4
528 if (space%dim > 2) bsize(3:) = 10
530 bsize(1) = max(4 * 16 / abs(
conf%target_states_block_size), 1)
531 if (space%dim > 1) bsize(2) = 15
532 if (space%dim > 2) bsize(3:) = 15
535 if (
parse_block(namespace,
'MeshLocalBlockSize', blk) == 0)
then
537 if (nn /= space%dim)
then
538 message(1) =
"Error: number of entries in MeshLocalBlockSize must match the umber of dimensions."
547 number_of_blocks(1:space%dim) = idx%ll(1:space%dim)/bsize(1:space%dim) + 1
550 safe_allocate(reorder_indices(1:pv%np_local))
551 safe_allocate(global_indices(1:pv%np_local))
552 do ip = 1, pv%np_local
553 ipg = pv%local(ip + pv%xlocal - 1)
555 point = point + idx%offset + idx%enlarge
556 reorder_indices(ip) =
get_blocked_index(space%dim, point, bsize, number_of_blocks, increase_with_dimension)
559 call sort(reorder_indices, global_indices)
560 safe_deallocate_a(reorder_indices)
563 safe_allocate(reordered(1:pv%np_local))
564 do ip = 1, pv%np_local
565 reordered(ip) = pv%local(global_indices(ip) + pv%xlocal - 1)
567 safe_deallocate_a(global_indices)
570 do ip = 1, pv%np_local
571 pv%local(ip + pv%xlocal - 1) = reordered(ip)
573 safe_deallocate_a(reordered)
579 do ip = 1, pv%np_local
580 call lihash_insert(pv%global, pv%local(pv%xlocal + ip - 1), ip)
588 integer,
allocatable :: part_local(:)
592 safe_allocate(part_local(1:pv%np_local))
593 safe_allocate(indices(1:pv%np_local))
594 do ip = 1, pv%np_local
595 indices(ip) = pv%xlocal + ip - 1
599 safe_deallocate_a(indices)
601 safe_allocate(pv%send_count(1:npart))
602 safe_allocate(pv%recv_count(1:npart))
603 safe_allocate(pv%send_disp(1:npart))
604 safe_allocate(pv%recv_disp(1:npart))
607 do ip = 1, pv%np_local
608 ipart = part_local(ip)
609 pv%send_count(ipart) = pv%send_count(ipart) + 1
613 pv%send_disp(ipart) = pv%send_disp(ipart - 1) + pv%send_count(ipart - 1)
616 call pv%mpi_grp%alltoall(pv%send_count, 1, mpi_integer, &
617 pv%recv_count, 1, mpi_integer)
621 pv%recv_disp(ipart) = pv%recv_disp(ipart - 1) + pv%recv_count(ipart - 1)
625 safe_allocate(pv%sendmap(1:pv%np_local))
626 safe_allocate(points(1:pv%npart))
628 do ip = 1, pv%np_local
629 ipart = part_local(ip)
630 points(ipart) = points(ipart) + 1
631 pv%sendmap(ip) = pv%send_disp(ipart) + points(ipart)
633 safe_deallocate_a(points)
635 safe_allocate(indices(1:pv%np_local))
636 do ip = 1, pv%np_local
637 indices(pv%sendmap(ip)) = pv%xlocal + ip - 1
639 safe_allocate(pv%recvmap(1:sum(pv%recv_count)))
640 call pv%mpi_grp%alltoallv(indices, pv%send_count, pv%send_disp, mpi_integer8, &
641 pv%recvmap, pv%recv_count, pv%recv_disp, mpi_integer8)
642 do ip = 1, sum(pv%recv_count)
646 pv%recvmap(ip) = index
648 safe_deallocate_a(indices)
661 safe_deallocate_a(pv%ghost_rdispls)
662 safe_deallocate_a(pv%ghost_sdispls)
663 safe_deallocate_a(pv%ghost_rcounts)
664 safe_deallocate_a(pv%ghost_scounts)
665 safe_deallocate_a(pv%ghost_sendpos)
666 safe_deallocate_a(pv%ghost_recvmap)
667 safe_deallocate_a(pv%ghost_sendmap)
668 safe_deallocate_a(pv%send_disp)
669 safe_deallocate_a(pv%recv_disp)
670 safe_deallocate_a(pv%np_local_vec)
671 safe_deallocate_a(pv%xlocal_vec)
672 safe_deallocate_a(pv%local)
673 safe_deallocate_a(pv%send_count)
674 safe_deallocate_a(pv%recv_count)
675 safe_deallocate_a(pv%sendmap)
676 safe_deallocate_a(pv%recvmap)
677 safe_deallocate_a(pv%bndry)
678 safe_deallocate_a(pv%ghost)
696 integer(int64),
intent(in) :: ipg
703 if (pv%npart > 1)
then
708 assert(ipg < huge(ip))
717 integer,
intent(in) :: ip
721 if (pv%npart == 1)
then
724 if (ip <= pv%np_local)
then
725 ipg = pv%local(pv%xlocal + ip - 1)
726 else if (ip <= pv%np_local + pv%np_ghost)
then
727 ipg = pv%ghost(ip - pv%np_local)
728 else if (ip <= pv%np_local + pv%np_ghost + pv%np_bndry)
then
729 ipg = pv%bndry(ip - pv%np_local - pv%np_ghost)
740 integer,
intent(in) :: root
741 integer(int64),
allocatable,
intent(inout) :: local_vec(:)
743 integer(int64),
allocatable :: xlocal_tmp(:)
747 safe_allocate(xlocal_tmp(1:pv%npart))
748 xlocal_tmp(:) = pv%xlocal_vec(:) - 1
750 call pv%mpi_grp%gatherv(pv%local(pv%xlocal:), pv%np_local, mpi_integer8, &
751 local_vec, pv%np_local_vec, xlocal_tmp, mpi_integer8, root)
752 safe_deallocate_a(xlocal_tmp)
758#include "complex.F90"
759#include "par_vec_inc.F90"
763#include "par_vec_inc.F90"
766#include "integer.F90"
767#include "par_vec_inc.F90"
771#include "par_vec_inc.F90"
774#include "complex32.F90"
775#include "par_vec_inc.F90"
This is the common interface to a sorting routine. It performs the shell algorithm,...
subroutine, public accel_free_buffer(this, async)
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)
MPI_THREAD_FUNNELED allows for calls to MPI from an OMP region if the thread is the team master.
Some general things and nomenclature:
subroutine cpar_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, 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 spar_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 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 spar_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 gather_local_vec(pv, root, local_vec)
subroutine cpar_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 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 cpar_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_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 spar_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 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), parameter, 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()