21#include <PB3D_macros.h>
57 module procedure get_ser_var_complex
59 module procedure get_ser_var_real
61 module procedure get_ser_var_int
75 module procedure get_ghost_arr_3d_complex
77 module procedure get_ghost_arr_3d_real
79 module procedure get_ghost_arr_2d_complex
81 module procedure get_ghost_arr_1d_real
89 module procedure broadcast_var_real
91 module procedure broadcast_var_int
93 module procedure broadcast_var_log
95 module procedure broadcast_var_complex_arr
97 module procedure broadcast_var_real_arr
99 module procedure broadcast_var_int_arr
101 module procedure broadcast_var_log_arr
106 integer function get_ser_var_complex(var,ser_var,scatter)
result(ierr)
109 character(*),
parameter :: rout_name =
'get_ser_var'
112 complex(dp),
intent(in) :: var(:)
113 complex(dp),
allocatable,
intent(inout) :: ser_var(:)
114 logical,
intent(in),
optional :: scatter
117 character(len=max_str_ln) :: err_msg
118 integer,
allocatable :: recvcounts(:)
119 integer,
allocatable :: displs(:)
121 logical :: scatter_loc
127 scatter_loc = .false.
128 if (
present(scatter)) scatter_loc = scatter
132 if (
rank.eq.0 .or. scatter_loc)
then
136 allocate(recvcounts(0))
139 if (scatter_loc)
then
140 call mpi_allgather(
size(var),1,mpi_integer,recvcounts,1,&
141 &mpi_integer,mpi_comm_world,ierr)
143 call mpi_gather(
size(var),1,mpi_integer,recvcounts,1,&
144 &mpi_integer,0,mpi_comm_world,ierr)
146 err_msg =
'Failed to gather size of parallel variable'
150 if (
allocated(ser_var))
then
151 if (
size(ser_var).ne.sum(recvcounts))
then
153 write(*,*)
size(ser_var), sum(recvcounts)
154 err_msg =
'ser_var has wrong dimensions'
158 allocate(ser_var(sum(recvcounts)))
162 if (
rank.eq.0 .or. scatter_loc)
then
165 displs(id) = displs(id-1) + recvcounts(id-1)
169 if (scatter_loc)
then
170 call mpi_allgatherv(var,
size(var),mpi_double_complex,ser_var,&
171 &recvcounts,displs,mpi_double_complex,mpi_comm_world,ierr)
173 call mpi_gatherv(var,
size(var),mpi_double_complex,ser_var,&
174 &recvcounts,displs,mpi_double_complex,0,mpi_comm_world,ierr)
176 err_msg =
'Failed to gather parallel variable'
178 end function get_ser_var_complex
180 integer function get_ser_var_real(var,ser_var,scatter)
result(ierr)
183 character(*),
parameter :: rout_name =
'get_ser_var_real'
186 real(
dp),
intent(in) :: var(:)
187 real(
dp),
allocatable,
intent(inout) :: ser_var(:)
188 logical,
intent(in),
optional :: scatter
191 character(len=max_str_ln) :: err_msg
192 integer,
allocatable :: recvcounts(:)
193 integer,
allocatable :: displs(:)
195 logical :: scatter_loc
201 scatter_loc = .false.
202 if (
present(scatter)) scatter_loc = scatter
206 if (
rank.eq.0 .or. scatter_loc)
then
210 allocate(recvcounts(0))
213 if (scatter_loc)
then
214 call mpi_allgather(
size(var),1,mpi_integer,recvcounts,1,&
215 &mpi_integer,mpi_comm_world,ierr)
217 call mpi_gather(
size(var),1,mpi_integer,recvcounts,1,&
218 &mpi_integer,0,mpi_comm_world,ierr)
220 err_msg =
'Failed to gather size of parallel variable'
224 if (
allocated(ser_var))
then
225 if (
size(ser_var).ne.sum(recvcounts))
then
227 write(*,*)
size(ser_var), sum(recvcounts)
228 err_msg =
'ser_var has wrong dimensions'
232 allocate(ser_var(sum(recvcounts)))
236 if (
rank.eq.0 .or. scatter_loc)
then
239 displs(id) = displs(id-1) + recvcounts(id-1)
243 if (scatter_loc)
then
244 call mpi_allgatherv(var,
size(var),mpi_double_precision,ser_var,&
245 &recvcounts,displs,mpi_double_precision,mpi_comm_world,ierr)
247 call mpi_gatherv(var,
size(var),mpi_double_precision,ser_var,&
248 &recvcounts,displs,mpi_double_precision,0,mpi_comm_world,ierr)
250 err_msg =
'Failed to gather parallel variable'
252 end function get_ser_var_real
254 integer function get_ser_var_int(var,ser_var,scatter)
result(ierr)
257 character(*),
parameter :: rout_name =
'get_ser_var_int'
260 integer,
intent(in) :: var(:)
261 integer,
allocatable,
intent(inout) :: ser_var(:)
262 logical,
intent(in),
optional :: scatter
265 character(len=max_str_ln) :: err_msg
266 integer,
allocatable :: recvcounts(:)
267 integer,
allocatable :: displs(:)
269 logical :: scatter_loc
275 scatter_loc = .false.
276 if (
present(scatter)) scatter_loc = scatter
280 if (
rank.eq.0 .or. scatter_loc)
then
284 allocate(recvcounts(0))
287 if (scatter_loc)
then
288 call mpi_allgather(
size(var),1,mpi_integer,recvcounts,1,&
289 &mpi_integer,mpi_comm_world,ierr)
291 call mpi_gather(
size(var),1,mpi_integer,recvcounts,1,&
292 &mpi_integer,0,mpi_comm_world,ierr)
294 err_msg =
'Failed to gather size of parallel variable'
298 if (
allocated(ser_var))
then
299 if (
size(ser_var).ne.sum(recvcounts))
then
301 write(*,*)
size(ser_var), sum(recvcounts)
302 err_msg =
'ser_var has wrong dimensions'
306 allocate(ser_var(sum(recvcounts)))
310 if (
rank.eq.0 .or. scatter_loc)
then
313 displs(id) = displs(id-1) + recvcounts(id-1)
317 if (scatter_loc)
then
318 call mpi_allgatherv(var,
size(var),mpi_integer,ser_var,&
319 &recvcounts,displs,mpi_integer,mpi_comm_world,ierr)
321 call mpi_gatherv(var,
size(var),mpi_integer,ser_var,&
322 &recvcounts,displs,mpi_integer,0,mpi_comm_world,ierr)
324 err_msg =
'Failed to gather parallel variable'
326 end function get_ser_var_int
332 character(*),
parameter :: rout_name =
'redistribute_var'
335 real(
dp),
intent(in) :: var(:)
336 real(
dp),
intent(inout) :: dis_var(:)
337 integer,
intent(in) :: lims(2)
338 integer,
intent(in) :: lims_dis(2)
342 integer,
allocatable :: lims_tot(:,:)
343 integer,
allocatable :: lims_dis_tot(:,:)
344 integer,
allocatable :: temp_lim(:)
345 integer,
allocatable :: n_vars(:,:)
346 integer,
allocatable :: nr_sen(:)
347 integer,
allocatable :: nr_rec(:)
348 integer,
allocatable :: id_rec(:)
349 integer,
allocatable :: id_sen(:)
357 allocate(lims_dis_tot(2,
n_procs))
359 ierr =
get_ser_var(lims(id:id),temp_lim,scatter=.true.)
361 lims_tot(id,:) = temp_lim
362 ierr =
get_ser_var(lims_dis(id:id),temp_lim,scatter=.true.)
364 lims_dis_tot(id,:) = temp_lim
376 max_loc = lims_dis_tot(1,jd)
378 if (lims_tot(2,id).ge.max_loc)
then
379 n_vars(jd,id) = min(lims_tot(2,id),lims_dis_tot(2,jd)) - &
381 max_loc = max_loc + n_vars(jd,id)
399 nr_rec(id) = n_vars(
rank+1,id)
400 nr_sen(id) = n_vars(id,
rank+1)
401 id_rec(id) = sum(n_vars(
rank+1,1:id-1))
402 id_sen(id) = sum(n_vars(id,1:
rank)) + lims_dis_tot(1,id) - lims(1)
405 call mpi_alltoallv(var,nr_sen,id_sen,mpi_double_precision,&
406 &dis_var,nr_rec,id_rec,mpi_double_precision,mpi_comm_world,ierr)
421 integer function get_ghost_arr_3d_complex(arr,size_ghost)
result(ierr)
424 character(*),
parameter :: rout_name =
'get_ghost_arr_3D_complex'
427 complex(dp),
intent(inout) :: arr(:,:,:)
428 integer,
intent(in) :: size_ghost
431 integer :: n_modes(2)
433 integer :: istat(mpi_status_size)
439 n_modes = [
size(arr,1),
size(arr,2)]
440 tot_size =
size(arr,3)
445 call mpi_recv(arr(:,:,tot_size-size_ghost+1:tot_size),&
446 &size_ghost*product(n_modes),mpi_double_complex,
rank+1,&
447 &
rank+1,mpi_comm_world,istat,ierr)
448 chckerr(
'Failed to receive')
450 call mpi_send(arr(:,:,1:size_ghost),&
451 &size_ghost*product(n_modes),mpi_double_complex,
rank-1,&
452 &
rank,mpi_comm_world,ierr)
453 chckerr(
'Failed to send')
455 call mpi_sendrecv(arr(:,:,1:size_ghost),&
456 &size_ghost*product(n_modes),mpi_double_complex,
rank-1,&
457 &
rank,arr(:,:,tot_size-size_ghost+1:tot_size),&
458 &size_ghost*product(n_modes),mpi_double_complex,&
459 &
rank+1,
rank+1,mpi_comm_world,istat,ierr)
460 chckerr(
'Failed to send and receive')
463 end function get_ghost_arr_3d_complex
465 integer function get_ghost_arr_3d_real(arr,size_ghost)
result(ierr)
468 character(*),
parameter :: rout_name =
'get_ghost_arr_3D_real'
471 real(
dp),
intent(inout) :: arr(:,:,:)
472 integer,
intent(in) :: size_ghost
475 integer :: n_modes(2)
477 integer :: istat(mpi_status_size)
483 n_modes = [
size(arr,1),
size(arr,2)]
484 tot_size =
size(arr,3)
489 call mpi_recv(arr(:,:,tot_size-size_ghost+1:tot_size),&
490 &size_ghost*product(n_modes),mpi_double_precision,&
491 &
rank+1,
rank+1,mpi_comm_world,istat,ierr)
492 chckerr(
'Failed to receive')
494 call mpi_send(arr(:,:,1:size_ghost),&
495 &size_ghost*product(n_modes),mpi_double_precision,&
497 chckerr(
'Failed to send')
499 call mpi_sendrecv(arr(:,:,1:size_ghost),&
500 &size_ghost*product(n_modes),mpi_double_precision,&
502 &
rank,arr(:,:,tot_size-size_ghost+1:tot_size),&
503 &size_ghost*product(n_modes),mpi_double_precision,&
504 &
rank+1,
rank+1,mpi_comm_world,istat,ierr)
505 chckerr(
'Failed to send and receive')
508 end function get_ghost_arr_3d_real
510 integer function get_ghost_arr_2d_complex(arr,size_ghost)
result(ierr)
513 character(*),
parameter :: rout_name =
'get_ghost_arr_2D_complex'
516 complex(dp),
intent(inout) :: arr(:,:)
517 integer,
intent(in) :: size_ghost
522 integer :: istat(mpi_status_size)
528 n_modes =
size(arr,1)
529 tot_size =
size(arr,2)
534 call mpi_recv(arr(:,tot_size-size_ghost+1:tot_size),&
535 &size_ghost*n_modes,mpi_double_complex,
rank+1,&
536 &
rank+1,mpi_comm_world,istat,ierr)
537 chckerr(
'Failed to receive')
539 call mpi_send(arr(:,1:size_ghost),size_ghost*n_modes,&
540 &mpi_double_complex,
rank-1,
rank,mpi_comm_world,&
542 chckerr(
'Failed to send')
544 call mpi_sendrecv(arr(:,1:size_ghost),size_ghost*n_modes,&
546 &arr(:,tot_size-size_ghost+1:tot_size),size_ghost*n_modes,&
547 &mpi_double_complex,
rank+1,
rank+1,mpi_comm_world,&
549 chckerr(
'Failed to send and receive')
552 end function get_ghost_arr_2d_complex
554 integer function get_ghost_arr_1d_real(arr,size_ghost)
result(ierr)
557 character(*),
parameter :: rout_name =
'get_ghost_arr_1D_real'
560 real(
dp),
intent(in) :: arr(:)
561 integer,
intent(in) :: size_ghost
565 integer :: istat(mpi_status_size)
576 call mpi_recv(arr(tot_size-size_ghost+1:tot_size),&
577 &size_ghost,mpi_double_precision,
rank+1,&
578 &
rank+1,mpi_comm_world,istat,ierr)
579 chckerr(
'Failed to receive')
581 call mpi_send(arr(1:size_ghost),size_ghost,&
582 &mpi_double_precision,
rank-1,
rank,mpi_comm_world,&
584 chckerr(
'Failed to send')
586 call mpi_sendrecv(arr(1:size_ghost),size_ghost,&
588 &arr(tot_size-size_ghost+1:tot_size),size_ghost,&
589 &mpi_double_precision,
rank+1,
rank+1,&
590 &mpi_comm_world,istat,ierr)
591 chckerr(
'Failed to send and receive')
594 end function get_ghost_arr_1d_real
597 integer function broadcast_var_real(var,source)
result(ierr)
598 character(*),
parameter :: rout_name =
'broadcast_var_real'
601 real(dp),
intent(in) :: var
602 integer,
intent(in),
optional :: source
605 integer :: source_loc = 0
611 if (
present(source)) source_loc = source
613 call mpi_bcast(var,1,mpi_double_precision,source_loc,mpi_comm_world,&
615 chckerr(
'MPI broadcast failed')
616 end function broadcast_var_real
618 integer function broadcast_var_int(var,source)
result(ierr)
619 character(*),
parameter :: rout_name =
'broadcast_var_int'
622 integer,
intent(in) :: var
623 integer,
intent(in),
optional :: source
626 integer :: source_loc = 0
632 if (
present(source)) source_loc = source
634 call mpi_bcast(var,1,mpi_integer,source_loc,mpi_comm_world,ierr)
635 chckerr(
'MPI broadcast failed')
636 end function broadcast_var_int
638 integer function broadcast_var_log(var,source)
result(ierr)
639 character(*),
parameter :: rout_name =
'broadcast_var_log'
642 logical,
intent(in) :: var
643 integer,
intent(in),
optional :: source
646 integer :: source_loc = 0
652 if (
present(source)) source_loc = source
654 call mpi_bcast(var,1,mpi_logical,source_loc,mpi_comm_world,ierr)
655 chckerr(
'MPI broadcast failed')
656 end function broadcast_var_log
658 integer function broadcast_var_complex_arr(var,source)
result(ierr)
659 character(*),
parameter :: rout_name =
'broadcast_var_complex_arr'
662 complex(dp),
intent(in) :: var(:)
663 integer,
intent(in),
optional :: source
666 integer :: source_loc = 0
672 if (
present(source)) source_loc = source
674 call mpi_bcast(var,
size(var),mpi_double_complex,source_loc,&
675 &mpi_comm_world,ierr)
676 chckerr(
'MPI broadcast failed')
677 end function broadcast_var_complex_arr
679 integer function broadcast_var_real_arr(var,source)
result(ierr)
680 character(*),
parameter :: rout_name =
'broadcast_var_real_arr'
683 real(dp),
intent(in) :: var(:)
684 integer,
intent(in),
optional :: source
687 integer :: source_loc = 0
693 if (
present(source)) source_loc = source
695 call mpi_bcast(var,
size(var),mpi_double_precision,source_loc,&
696 &mpi_comm_world,ierr)
697 chckerr(
'MPI broadcast failed')
698 end function broadcast_var_real_arr
700 integer function broadcast_var_int_arr(var,source)
result(ierr)
701 character(*),
parameter :: rout_name =
'broadcast_var_int_arr'
704 integer,
intent(in) :: var(:)
705 integer,
intent(in),
optional :: source
708 integer :: source_loc = 0
714 if (
present(source)) source_loc = source
716 call mpi_bcast(var,
size(var),mpi_integer,source_loc,mpi_comm_world,ierr)
717 chckerr(
'MPI broadcast failed')
718 end function broadcast_var_int_arr
720 integer function broadcast_var_log_arr(var,source)
result(ierr)
721 character(*),
parameter :: rout_name =
'broadcast_var_log_arr'
724 logical,
intent(in) :: var(:)
725 integer,
intent(in),
optional :: source
728 integer :: source_loc = 0
734 if (
present(source)) source_loc = source
736 call mpi_bcast(var,
size(var),mpi_logical,source_loc,mpi_comm_world,ierr)
737 chckerr(
'MPI broadcast failed')
738 end function broadcast_var_log_arr
744 character(*),
parameter :: rout_name =
'wait_MPI'
750 call mpi_barrier(mpi_comm_world,ierr)
751 chckerr(
'MPI Barrier failed')
768 character(*),
parameter :: rout_name =
'lock_req_acc'
775 integer,
allocatable :: wl_loc(:)
776 integer,
allocatable :: next_nb_procs(:)
777 integer,
allocatable :: ranks_to_activate(:)
778 logical,
intent(in),
optional :: blocking
779 logical :: next_nb_proc_exists
780 logical :: direct_receipt
790 if (.not.
allocated(lock%wl))
then
792 chckerr(
'lock not intialized')
797 lock%blocking = .true.
798 if (
present(blocking)) lock%blocking = blocking
810 direct_receipt = wl_empty(wl_loc,[-2,-1,1,2])
813 if (direct_receipt)
then
816 &
'and got it right away'
820 next_nb_proc_exists = .false.
821 if (.not.lock%blocking)
then
823 next_nb_proc_exists = &
824 &.not.wl_empty(wl_loc,[-1],next_procs=next_nb_procs)
828 &
' NB proc, next NB procs found:', next_nb_procs
833 if (.not.lock%blocking .and. next_nb_proc_exists)
then
834 allocate(ranks_to_activate(
size(next_nb_procs)+1))
835 ranks_to_activate = [
rank,next_nb_procs]
837 allocate(ranks_to_activate(1))
838 ranks_to_activate =
rank
845 &
' setting status to activate:', ranks_to_activate
847 ierr =
lock_wl_change(2,.false.,lock,wl_loc,ranks=ranks_to_activate)
851 if (next_nb_proc_exists)
then
852 do id = 1,
size(next_nb_procs)
853 ierr = lock_notify(lock,next_nb_procs(id))
859 ierr = lock_get_notified(lock)
874 character(*),
parameter :: rout_name =
'lock_return_acc'
881 integer,
allocatable :: wl_loc(:)
882 integer,
allocatable :: next_procs(:)
883 integer,
allocatable :: ranks_to_activate(:)
884 logical :: next_proc_exists
885 logical :: next_proc_bl
894 if (.not.
allocated(lock%wl))
then
896 chckerr(
'lock not intialized')
910 next_proc_bl = .false.
911 next_proc_exists = .false.
912 if (lock%blocking .or. wl_empty(wl_loc,[-2]))
then
914 next_proc_exists = .not.wl_empty(wl_loc,[1],next_procs=next_procs)
915 if (next_proc_exists) next_proc_bl = .true.
918 &
' next BL procs found:', next_procs
922 if (.not. next_proc_exists)
then
923 next_proc_exists = .not.wl_empty(wl_loc,[-1],&
924 &next_procs=next_procs)
925 if (next_proc_exists) next_proc_bl = .false.
929 &
' next NB procs found:', next_procs
935 &
'but has no notification rights'
939 if (next_proc_exists)
then
941 if (next_proc_bl)
then
942 allocate(ranks_to_activate(1))
943 ranks_to_activate = next_procs(1)
945 allocate(ranks_to_activate(
size(next_procs)))
946 ranks_to_activate = next_procs
953 &
' setting status to activate:', ranks_to_activate
956 &ranks=ranks_to_activate)
960 if (next_proc_exists)
then
961 do id = 1,
size(ranks_to_activate)
962 ierr = lock_notify(lock,ranks_to_activate(id))
984 logical function wl_empty(wl,proc_type,next_procs)
988 integer,
intent(in) :: wl(:)
989 integer,
intent(in) :: proc_type(:)
990 integer,
intent(inout),
optional,
allocatable :: next_procs(:)
995 integer,
allocatable :: next_procs_loc(:)
1000 allocate(next_procs_loc(
n_procs))
1007 proc_types:
do jd = 1,
size(proc_type)
1008 if (wl(next_procs_loc(nr_np+1)+1).eq.proc_type(jd))
then
1016 if (.not.wl_empty .and.
present(next_procs))
then
1017 if (
allocated(next_procs))
deallocate(next_procs)
1018 allocate(next_procs(nr_np))
1019 next_procs = next_procs_loc(1:nr_np)
1021 end function wl_empty
1030 integer function lock_notify(lock_loc,rec_rank)
result(ierr)
1033 character(*),
parameter :: rout_name =
'lock_notify'
1037 integer,
intent(in) :: rec_rank
1047 call mpi_send(
rank+1,1,mpi_integer,rec_rank,lock_loc%wu_tag,&
1048 &mpi_comm_world,ierr)
1049 chckerr(
'Failed to send notification')
1053 &
' notified', rec_rank
1055 end function lock_notify
1062 integer function lock_get_notified(lock_loc)
result(ierr)
1063 character(*),
parameter :: rout_name =
'lock_get_notified'
1079 &
' but needs to wait for lock'
1081 call mpi_recv(dum_buf,1,mpi_integer,mpi_any_source,&
1082 &lock_loc%wu_tag,mpi_comm_world,mpi_status_ignore,ierr)
1083 chckerr(
'Failed to receive notification')
1086 &
' got notified by ',dum_buf-1
1088 end function lock_get_notified
1113 character(*),
parameter :: rout_name =
'lock_wl_change'
1116 integer,
intent(in) :: wl_action
1117 logical,
intent(in) :: blocking
1118 type(
lock_type),
intent(inout) :: lock_loc
1119 integer,
intent(inout),
allocatable :: wl(:)
1120 integer,
intent(in),
optional :: ranks(:)
1126 integer,
allocatable :: ranks_loc(:)
1127 integer(kind=MPI_ADDRESS_KIND) :: one = 1
1128 integer(kind=MPI_ADDRESS_KIND) :: disp
1132 integer(kind=8) :: window_time(2)
1140 if (.not.blocking) put_val = -put_val
1142 if (
allocated(wl))
deallocate(wl)
1146 if (.not.
present(ranks))
then
1147 allocate(ranks_loc(1))
1150 allocate(ranks_loc(
size(ranks)))
1153 n_ranks =
size(ranks_loc)
1157 if (
debug_lock)
call system_clock(window_time(1))
1159 call mpi_win_lock(mpi_lock_exclusive,0,0,lock_loc%wl_win,ierr)
1160 chckerr(
'Failed to lock window')
1173 disp = disp + ln + 1
1174 if (id.lt.n_ranks+1)
then
1175 ln = ranks_loc(id)-ranks_loc(id-1)-1
1177 ln =
n_procs-ranks_loc(id-1)-1
1183 call mpi_get(wl(int(disp)+1:int(disp)+ln),ln,mpi_integer,0,&
1184 &disp,ln,mpi_integer,lock_loc%wl_win,ierr)
1185 chckerr(
'Failed to get waiting list')
1189 if (id.lt.n_ranks+1)
then
1190 call mpi_put(put_val,1,mpi_integer,0,ranks_loc(id)*one,1,&
1191 &mpi_integer,lock_loc%wl_win,ierr)
1192 chckerr(
'Failed to add to waiting list')
1193 wl(ranks_loc(id)+1) = put_val
1198 call mpi_win_unlock(0,lock_loc%wl_win,ierr)
1199 chckerr(
'Failed to lock window')
1201 if (
debug_lock)
call system_clock(window_time(2))
1207 &trim(
r2strt(1.e-9_dp*(window_time(2)-window_time(1)))),&
1208 &
' waiting list:', wl
1216 character(len=max_str_ln) function lock_header(lock_loc)
result(header)
1223 integer(kind=8) :: clock
1224 character(len=2) :: block_char
1227 call system_clock(clock)
1230 if (lock_loc%blocking)
then
1236 header = trim(
ii2str(clock))//
' '//trim(
i2str(lock_loc%wu_tag))//
' '//&
1237 &block_char//
' '//trim(
i2str(
rank))//
'-'
Wrapper function to broadcast a single variable using MPI.
Fill the ghost regions in an array.
Gather parallel variable in serial version on group master.
Sorting with the bubble sort routine.
Numerical utilities related to giving output.
Numerical utilities related to MPI.
integer function, public redistribute_var(var, dis_var, lims, lims_dis)
Redistribute variables according to new limits.
integer, public n_waits
number of waits
integer function, public lock_wl_change(wl_action, blocking, lock_loc, wl, ranks)
Adds, removes or sets to active a rank from the waiting list for a lock and returns the lock waiting ...
integer function, public lock_req_acc(lock, blocking)
Request access to lock of a BL (blocking) or optionally a NB (non-blocking) type.
integer function, public wait_mpi()
Wait for all processes, wrapper to MPI barrier.
integer function, public lock_return_acc(lock)
Returns access to a lock.
logical, public debug_lock
print debug information about lock operations
character(len=max_str_ln) function, public lock_header(lock_loc)
Returns the header for lock debug messages.
Variables pertaining to MPI.
Numerical variables used by most other modules.
integer, parameter, public dp
double precision
real(dp), parameter, public pi
integer, public n_procs
nr. of MPI processes
integer, parameter, public max_str_ln
maximum length of strings
integer, public rank
MPI rank.
elemental character(len=max_str_ln) function, public i2str(k)
Convert an integer to string.
elemental character(len=max_str_ln) function, public r2strt(k)
Convert a real (double) to string.
elemental character(len=max_str_ln) function, public ii2str(k)
Convert an integer to string.