Nek5000
SEM for Incompressible NS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
comm_mpi.F90
Go to the documentation of this file.
1 !---------------------------------------------------------------------
2  subroutine iniproc(intracomm)
3  use kinds, only : dp
4  use mpif, only : mpi_comm_world, mpi_double_precision, mpi_real
5  use mpif, only : mpi_tag_ub
6  use size_m, only : nid, lp, lelg
7  use parallel, only : np, wdsize, ifdblas, isize, lsize, csize, pid
8  use parallel, only : nullpid, node0, node, cr_h
9  use parallel, only : np_=>np,nekcomm,nekreal
10  implicit none
11 
12  integer :: intracomm
13  logical :: flag
14 
15  integer :: nval, ierr
16  real(DP) :: eps, oneeps
17 
18 ! call mpi_initialized(mpi_is_initialized, ierr) ! Initialize MPI
19 ! if ( mpi_is_initialized .eq. 0 ) then
20 ! call mpi_init (ierr)
21 ! endif
22 
23 ! set nek communicator
24  call init_nek_comm(intracomm)
25 
26  if(nid == 0) call printheader
27 
28 ! check upper tag size limit
29  call mpi_attr_get(mpi_comm_world,mpi_tag_ub,nval,flag,ierr)
30  if (nval < (10000+max(lp,lelg))) then
31  if(nid == 0) write(6,*) 'ABORT: MPI_TAG_UB too small!'
32  call exitt
33  endif
34 
35  IF (np > lp) THEN
36  WRITE(6,*) &
37  'ERROR: Code compiled for a max of',lp,' processors.'
38  WRITE(6,*) &
39  'Recompile with LP =',np,' or run with fewer processors.'
40  WRITE(6,*) &
41  'Aborting in routine INIPROC.'
42  call exitt
43  endif
44 
45 ! set word size for REAL
46  wdsize=4
47  eps=1.0e-12
48  oneeps = 1.0+eps
49  if (oneeps /= 1.0) then
50  wdsize=8
51  else
52  if(nid == 0) &
53  write(6,*) 'ABORT: single precision mode not supported!'
54  call exitt
55  endif
56  nekreal = mpi_real
57  if (wdsize == 8) nekreal = mpi_double_precision
58 
59  ifdblas = .false.
60  if (wdsize == 8) ifdblas = .true.
61 
62 ! set word size for INTEGER
63 ! HARDCODED since there is no secure way to detect an int overflow
64  isize = 4
65 
66 ! set word size for LOGICAL
67  lsize = 4
68 
69 ! set word size for CHARACTER
70  csize = 1
71 
72  pid = 0
73  nullpid=0
74  node0=0
75  node= nid+1
76 
77  if (nid == 0) then
78  write(6,*) 'Number of processors:',np
79  WRITE(6,*) 'REAL wdsize :',wdsize
80  WRITE(6,*) 'INTEGER wdsize :',isize
81  endif
82 
83  call crystal_setup(cr_h,nekcomm,np) ! set cr handle to new instance
84 
85  return
86  end subroutine iniproc
87 
88 !-----------------------------------------------------------------------
89  subroutine init_nek_comm(intracomm)
90  use parallel, only : nid,np,nekcomm
91  implicit none
92 
93  integer :: intracomm
94  integer, external :: mynode, numnodes
95 
96  nekcomm = intracomm
97  nid = mynode()
98  np = numnodes()
99 
100  return
101  end subroutine init_nek_comm
102 !-----------------------------------------------------------------------
104  subroutine gop( x, w, op, n)
105  use kinds, only : dp
106  use mpif, only : mpi_max, mpi_min, mpi_prod, mpi_sum
107  use ctimer, only : ifsync, icalld, tgop, ngop, etime1, dnekclock
108  use parallel, only :nid,nekcomm,nekreal
109  implicit none
110 
111  integer :: n
112  real(DP) :: x(n), w(n)
113  character(3) :: op
114 
115  integer :: ierr
116 
117  if (ifsync) call nekgsync()
118 
119 #ifndef NOTIMER
120  if (icalld == 0) then
121  tgop =0.0d0
122  ngop =0
123  icalld=1
124  endif
125  ngop = ngop + 1
126  etime1=dnekclock()
127 #endif
128 
129  if (op == '+ ') then
130  call mpi_allreduce(x,w,n,nekreal,mpi_sum ,nekcomm,ierr)
131  elseif (op == 'M ') then
132  call mpi_allreduce(x,w,n,nekreal,mpi_max ,nekcomm,ierr)
133  elseif (op == 'm ') then
134  call mpi_allreduce(x,w,n,nekreal,mpi_min ,nekcomm,ierr)
135  elseif (op == '* ') then
136  call mpi_allreduce(x,w,n,nekreal,mpi_prod,nekcomm,ierr)
137  else
138  write(6,*) nid,' OP ',op,' not supported. ABORT in GOP.'
139  call exitt
140  endif
141 
142  call copy(x,w,n)
143 
144 #ifndef NOTIMER
145  tgop =tgop +(dnekclock()-etime1)
146 #endif
147 
148  return
149  end subroutine gop
150 !-----------------------------------------------------------------------
152  subroutine igop( x, w, op, n)
153  use mpif, only : mpi_integer, mpi_max, mpi_min, mpi_prod, mpi_sum
154  use parallel, only : nid,nekcomm
155  implicit none
156 
157  integer, intent(in) :: n
158  integer, intent(inout) :: x(n), w(n)
159  character(3), intent(in) :: op
160  integer :: ierr
161 
162  if (op == '+ ') then
163  call mpi_allreduce(x,w,n,mpi_integer,mpi_sum ,nekcomm,ierr)
164  elseif (op == 'M ') then
165  call mpi_allreduce(x,w,n,mpi_integer,mpi_max ,nekcomm,ierr)
166  elseif (op == 'm ') then
167  call mpi_allreduce(x,w,n,mpi_integer,mpi_min ,nekcomm,ierr)
168  elseif (op == '* ') then
169  call mpi_allreduce(x,w,n,mpi_integer,mpi_prod,nekcomm,ierr)
170  else
171  write(6,*) nid,' OP ',op,' not supported. ABORT in igop.'
172  call exitt
173  endif
174 
175  x = w
176 
177  return
178  end subroutine igop
179 !-----------------------------------------------------------------------
181  subroutine i8gop( x, w, op, n)
182  use kinds, only : i8
183  use mpif, only : mpi_integer8, mpi_max, mpi_min, mpi_prod, mpi_sum
184  use parallel, only : nid,nekcomm
185  implicit none
186  integer :: n
187  integer(i8) :: x(n), w(n)
188  character(3) :: op
189  integer :: ierr
190 
191  if (op == '+ ') then
192  call mpi_allreduce(x,w,n,mpi_integer8,mpi_sum ,nekcomm,ierr)
193  elseif (op == 'M ') then
194  call mpi_allreduce(x,w,n,mpi_integer8,mpi_max ,nekcomm,ierr)
195  elseif (op == 'm ') then
196  call mpi_allreduce(x,w,n,mpi_integer8,mpi_min ,nekcomm,ierr)
197  elseif (op == '* ') then
198  call mpi_allreduce(x,w,n,mpi_integer8,mpi_prod,nekcomm,ierr)
199  else
200  write(6,*) nid,' OP ',op,' not supported. ABORT in igop.'
201  call exitt
202  endif
203 
204  x = w
205 
206  return
207  end subroutine i8gop
208 !-----------------------------------------------------------------------
209  subroutine csend(mtype,buf,len,jnid,jpid)
210  use kinds, only : r4
211  use mpif, only : mpi_byte
212  use parallel, only : nekcomm
213  implicit none
214  real(r4) :: buf(1)
215  integer :: mtype, len, jnid, jpid
216  integer :: ierr
217 
218  call mpi_send(buf,len,mpi_byte,jnid,mtype,nekcomm,ierr)
219 
220  return
221  end subroutine csend
222 !-----------------------------------------------------------------------
223  subroutine crecv(mtype,buf,lenm)
224  use kinds, only : r4
225  use mpif, only : mpi_any_source, mpi_byte, mpi_status_size
226  use parallel, only : nekcomm, nid
227  implicit none
228  integer :: mtype, lenm
229  real(r4) :: buf(1)
230 
231  integer :: status(mpi_status_size)
232  integer :: len, jnid, ierr
233 
234  len = lenm
235  jnid = mpi_any_source
236 
237  call mpi_recv(buf,len,mpi_byte &
238  ,jnid,mtype,nekcomm,status,ierr)
239 
240  if (len > lenm) then
241  write(6,*) nid,'long message in mpi_crecv:',len,lenm
242  call exitt
243  endif
244 
245  return
246  end subroutine crecv
247 !-----------------------------------------------------------------------
248  integer function numnodes()
249  use parallel, only : nekcomm
250  implicit none
251  integer :: ierr
252 
253  call mpi_comm_size(nekcomm, numnodes , ierr)
254 
255  return
256  end function numnodes
257 !-----------------------------------------------------------------------
258  integer function mynode()
259  use parallel, only : nekcomm
260  implicit none
261  integer :: myid, ierr
262 
263  call mpi_comm_rank(nekcomm, myid, ierr)
264  mynode = myid
265 
266  return
267  end function mynode
268 !-----------------------------------------------------------------------
270  subroutine lbcast(ifif)
271  use kinds, only : r4
272  use parallel, only : np, isize
273  implicit none
274 
275  logical :: ifif
276  integer :: item
277 
278  if (np == 1) return
279 
280  item=0
281  if (ifif) item=1
282  call bcast(real(item, kind=r4),isize)
283  ifif= .false.
284  if (item == 1) ifif= .true.
285 
286  return
287  end subroutine lbcast
288 !-----------------------------------------------------------------------
289  subroutine bcast(buf,len)
290  use kinds, only : r4
291  use mpif, only : mpi_byte
292  use parallel, only : nekcomm
293 
294  implicit none
295  real(r4) :: buf
296  integer :: len, ierr
297 
298  call mpi_bcast(buf,len,mpi_byte,0,nekcomm,ierr)
299 
300  return
301  end subroutine bcast
302 !-----------------------------------------------------------------------
303 ! Note: len in bytes
304  integer function irecv(msgtag,x,len)
305  use mpif, only : mpi_any_source, mpi_byte
306  use parallel, only : nekcomm
307  implicit none
308  integer :: msgtag, x(1), len
309  integer :: ierr, imsg
310 
311  call mpi_irecv(x,len,mpi_byte,mpi_any_source,msgtag &
312  ,nekcomm,imsg,ierr)
313  irecv = imsg
314 
315  return
316  end function irecv
317 !-----------------------------------------------------------------------
318  subroutine nekgsync()
319  use parallel, only : nekcomm
320  implicit none
321  integer :: ierr
322 
323  call mpi_barrier(nekcomm,ierr)
324 
325  return
326  end subroutine nekgsync
327 !-----------------------------------------------------------------------
328 subroutine exitti(stringi,idata)
329  use size_m, only : nid
330  use string, only : indx1
331  implicit none
332 
333  integer :: idata
334 
335  character(132) :: stringi
336  character(132) :: stringo
337  character(11) :: s11
338  integer :: len, k
339 
340  call blank(stringo,132)
341  call chcopy(stringo,stringi,132)
342  len = indx1(stringo,'$',1)
343  write(s11,11) idata
344  11 format(1x,i10)
345  call chcopy(stringo(len:len),s11,11)
346 
347  if (nid == 0) write(6,1) (stringo(k:k),k=1,len+10)
348  1 format('EXIT: ',132a1)
349 
350  call exitt
351 
352  return
353 end subroutine exitti
354 
355 !-----------------------------------------------------------------------
356 subroutine err_chk(ierr,istring)
357  use size_m, only : nid
358  use string, only : indx1
359  implicit none
360 
361  integer :: ierr
362 
363  character(*) :: istring
364  character(132) :: ostring
365  character(10) :: s10
366 
367  integer :: len, k
368  integer, external :: iglsum
369 
370  ierr = iglsum(ierr,1)
371  if(ierr == 0) return
372 
373  len = indx1(istring,'$',1)
374  call blank(ostring,132)
375  write(s10,11) ierr
376  11 format(1x,' ierr=',i3)
377 
378  call chcopy(ostring,istring,len-1)
379  call chcopy(ostring(len:len),s10,10)
380 
381  if (nid == 0) write(6,1) (ostring(k:k),k=1,len+10)
382  1 format('ERROR: ',132a1)
383 
384  call exitt
385 
386  return
387 end subroutine err_chk
388 
389 !-----------------------------------------------------------------------
390 subroutine exitt0
391  implicit none
392 
393  integer :: ierr
394 
395  write(6,*) 'Emergency exit'
396 
397  call print_stack()
398  call flush_io
399 
400  call mpi_finalize(ierr)
401 #ifdef EXTBAR
402  call exit_(0)
403 #else
404  call exit(0)
405 #endif
406 
407 
408  return
409 end subroutine exitt0
410 !-----------------------------------------------------------------------
411 subroutine exitt
412  use kinds, only : dp, i8
413  use size_m, only : nid, nx1, ny1, nz1
414  use ctimer, only : dnekclock, ttotal, etimes, ttime
415  use input, only : ifneknek
416  use parallel, only : nvtot, np
417  use tstep, only : istep
418  implicit none
419 
420 #ifdef PAPI
421  real(r4) :: papi_mflops
422 #endif
423  integer(i8) :: papi_flops
424 
425  logical :: ifopen !check for opened files
426 
427  real(DP) :: tstop, dtmp1, dtmp2, dtmp3, dgp
428  integer :: nxyz, ierr
429 
430 
431 ! Communicate unhappiness to the other session
432 ! if (ifneknek .AND. icall == 0) call happy_check(0)
433  if (ifneknek) call happy_check(0)
434 
435  call nekgsync()
436 
437  papi_flops = 0
438 #ifdef PAPI
439  call nek_flops(papi_flops,papi_mflops)
440 #endif
441 
442  tstop = dnekclock()
443  ttotal = tstop-etimes
444  nxyz = nx1*ny1*nz1
445 
446  if (nid == 0) then
447  inquire(unit=50,opened=ifopen)
448  if(ifopen) close(50)
449  dtmp1 = 0
450  dtmp2 = 0
451  dtmp3 = 0
452  if(istep > 0) then
453  dgp = nvtot
454  dgp = max(dgp,1._dp)
455  dtmp1 = np*ttime/(dgp*max(istep,1))
456  dtmp2 = ttime/max(istep,1)
457  dtmp3 = 1.*papi_flops/1e6
458  endif
459  write(6,*) ' '
460  write(6,'(A)') 'call exitt: dying ...'
461  write(6,*) ' '
462  call print_stack()
463  write(6,*) ' '
464  write(6,'(4(A,1p1e13.5,A,/))') &
465  'total elapsed time : ',ttotal, ' sec' &
466  ,'total solver time incl. I/O : ',ttime , ' sec' &
467  ,'time/timestep : ',dtmp2 , ' sec' &
468  ,'CPU seconds/timestep/gridpt : ',dtmp1 , ' sec'
469 #ifdef PAPI
470  write(6,'(2(A,1g13.5,/))') &
471  'Gflops : ',dtmp3/1000. &
472  ,'Gflops/s : ',papi_mflops/1000.
473 #endif
474  endif
475  call flush_io
476 
477  call mpi_finalize(ierr)
478 #ifdef EXTBAR
479  all exit_(0)
480 #else
481  call exit(0)
482 #endif
483  return
484 end subroutine exitt
485 !-----------------------------------------------------------------------
486 subroutine printheader
487  implicit none
488  include 'HEADER'
489 
490  return
491 end subroutine printheader
492 !-----------------------------------------------------------------------
493 integer function igl_running_sum(in)
494  use mpif, only : mpi_integer, mpi_sum
495  use parallel, only : nekcomm
496  implicit none
497  integer :: in
498  integer :: x,w,r, ierr
499 
500  x = in ! running sum
501  w = in ! working buff
502  r = 0 ! recv buff
503 
504  call mpi_scan(x,r,1,mpi_integer,mpi_sum,nekcomm,ierr)
505  igl_running_sum = r
506 
507  return
508 end function igl_running_sum
509 !-----------------------------------------------------------------------
510 subroutine msgwait(imsg)
511  use mpif, only : mpi_status_size
512  implicit none
513  integer :: status(mpi_status_size)
514  integer :: imsg, ierr
515 
516  call mpi_wait(imsg,status,ierr)
517 
518  return
519 end subroutine msgwait
subroutine msgwait(imsg)
Definition: comm_mpi.F90:510
subroutine mpi_send(data, n, datatype, iproc, itag, comm, ierror)
Definition: mpi_dummy.F90:911
subroutine bcast(buf, len)
Definition: comm_mpi.F90:289
subroutine lbcast(ifif)
Broadcast logical variable to all processors.
Definition: comm_mpi.F90:270
cleaned
Definition: tstep_mod.F90:2
#define print_stack
Definition: chelpers.c:5
Input parameters from preprocessors.
Definition: input_mod.F90:11
integer function numnodes()
Definition: comm_mpi.F90:248
subroutine mpi_recv(data, n, datatype, iproc, itag, comm, istatus, ierror)
Definition: mpi_dummy.F90:656
subroutine mpi_wait(irequest, istatus, ierror)
Definition: mpi_dummy.F90:941
subroutine mpi_scan(data1, data2, n, datatype, operation, comm, ierror)
Definition: mpi_dummy.F90:2
subroutine igop(x, w, op, n)
Global vector commutative operation.
Definition: comm_mpi.F90:152
subroutine crecv(mtype, buf, lenm)
Definition: comm_mpi.F90:223
subroutine init_nek_comm(intracomm)
Definition: comm_mpi.F90:89
integer function mynode()
Definition: comm_mpi.F90:258
void exitt()
Definition: comm_mpi.F90:411
integer function indx1(S1, S2, L2)
Definition: string_mod.F90:43
subroutine mpi_bcast(data, n, datatype, node, comm, ierror)
Definition: mpi_dummy.F90:212
subroutine mpi_irecv(data, n, datatype, iproc, itag, comm, irequest, ierror)
Definition: mpi_dummy.F90:593
subroutine mpi_barrier(comm, ierror)
Definition: mpi_dummy.F90:193
real(dp) function dnekclock()
Definition: ctimer_mod.F90:103
subroutine copy(a, b, n)
Definition: math.F90:52
subroutine mpi_finalize(ierror)
Definition: mpi_dummy.F90:532
integer function irecv(msgtag, x, len)
Definition: comm_mpi.F90:304
subroutine happy_check(iflag)
Dummy for singlmesh.
Definition: singlmesh.F90:85
subroutine printheader
Definition: comm_mpi.F90:486
subroutine nek_flops(flops, mflops)
Definition: papi.F90:1
subroutine mpi_allreduce(data1, data2, n, datatype, operation, comm, ierror)
Definition: mpi_dummy.F90:142
integer function igl_running_sum(in)
Definition: comm_mpi.F90:493
cleaned
Definition: parallel_mod.F90:2
subroutine mpi_comm_rank(comm, me, ierror)
Definition: mpi_dummy.F90:388
subroutine blank(A, N)
blank a string
Definition: math.F90:38
subroutine exitt0
Definition: comm_mpi.F90:390
subroutine nekgsync()
Definition: comm_mpi.F90:318
subroutine iniproc(intracomm)
Definition: comm_mpi.F90:2
subroutine mpi_attr_get(icomm, ikey, ival, iflag, ierr)
Definition: mpi_dummy.F90:1076
subroutine gop(x, w, op, n)
Global vector commutative operation.
Definition: comm_mpi.F90:104
Definition: mpif.F90:1
subroutine chcopy(a, b, n)
Definition: math.F90:63
subroutine mpi_comm_size(comm, nprocs, ierror)
Definition: mpi_dummy.F90:409
subroutine err_chk(ierr, istring)
Definition: comm_mpi.F90:356
subroutine flush_io
Definition: subs1.F90:890
static uint np
Definition: findpts_test.c:63
subroutine i8gop(x, w, op, n)
Global vector commutative operation.
Definition: comm_mpi.F90:181
subroutine exitti(stringi, idata)
Definition: comm_mpi.F90:328
subroutine csend(mtype, buf, len, jnid, jpid)
Definition: comm_mpi.F90:209