KTH framework for Nek5000 toolboxes; testing version  0.0.1
dprocmap.f
Go to the documentation of this file.
1 #ifdef DPROCMAP
2 c-----------------------------------------------------------------------
3 c
4 c gllnid and gllel are stored as a distributed array ordered by
5 c the global element index. Access is provided by two
6 c functions gllnid() and gllel(). Each ranks holds a local cache
7 c for its local and some remote elements.
8 c
9 c-----------------------------------------------------------------------
10  subroutine dprocmapinit()
11 
12  include 'mpif.h'
13  include 'SIZE'
14  include 'PARALLEL'
15  include 'DPROCMAP'
16 
17  common /nekmpi/ nid_,np_,nekcomm,nekgroup,nekreal
18 
19  integer disp_unit
20  integer*8 wsize
21 
22 #ifdef MPI
23  disp_unit = isize
24  wsize = disp_unit*size(dprocmapwin)
25  call mpi_win_create(dprocmapwin,
26  $ wsize,
27  $ disp_unit,
28  $ mpi_info_null,
29  $ nekcomm,dprocmaph,ierr)
30 
31  if (ierr .ne. 0 ) call exitti('MPI_Win_allocate failed!$',0)
32 #endif
33 
34  dprocmapcache = .true.
35 
36  return
37  end
38 c-----------------------------------------------------------------------
39  subroutine dprocmapput(ibuf,lbuf,ioff,ieg)
40 
41  include 'mpif.h'
42  include 'SIZE'
43  include 'PARALLEL'
44  include 'DPROCMAP'
45 
46  integer ibuf(lbuf)
47  integer*8 disp
48 
49  if (lbuf.lt.1 .or. lbuf.gt.2)
50  $ call exitti('invalid lbuf!',lbuf)
51 
52 #ifdef MPI
53  call dprocmapfind(iloc,nids,ieg)
54  disp = 2*(iloc-1) + ioff
55 
56  call mpi_win_lock(mpi_lock_exclusive,nids,0,dprocmaph,ierr)
57  call mpi_put(ibuf,lbuf,mpi_integer,nids,disp,lbuf,mpi_integer,
58  $ dprocmaph,ierr)
59  call mpi_win_unlock(nids,dprocmaph,ierr)
60 #else
61  call icopy(dprocmapwin(2*(ieg-1) + ioff + 1),ibuf,lbuf)
62 #endif
63 
64  return
65  end
66 c-----------------------------------------------------------------------
67  subroutine dprocmapget(ibuf,ieg)
68 
69  include 'mpif.h'
70  include 'SIZE'
71  include 'PARALLEL'
72  include 'DPROCMAP'
73 
74  integer ibuf(2)
75 
76  integer*8 disp
77 
78  ! local cache
79  parameter(lcr = lelt) ! remote elements
80  parameter(lc = lelt+lcr+8-mod(lelt+lcr,8)) ! multiple of 8
81  integer cache(lc,3)
82  save cache
83 
84  save icalld
85  data icalld /0/
86 
87  save iran
88  parameter(im = 6075, ia = 106, ic = 1283)
89 
90  if (icalld .eq. 0) then
91  call ifill(cache,-1,size(cache))
92  icalld = 1
93  endif
94 
95  ii = lsearch_ur(cache(1,3),lc,ieg)
96  if (ii.gt.lc) call exitti('lsearch_ur returns invalid index$',ii)
97  if (ii.gt.0 .and. ii.ne.lelt+lcr) then ! cache hit
98 c write(6,*) nid, 'cache hit ', 'ieg:', ieg
99  ibuf(1) = cache(ii,1)
100  ibuf(2) = cache(ii,2)
101  else
102 #ifdef MPI
103  call dprocmapfind(il,nidt,ieg)
104  disp = 2*(il-1)
105  call mpi_win_lock(mpi_lock_shared,nidt,0,dprocmaph,ierr)
106  call mpi_get(ibuf,2,mpi_integer,nidt,disp,2,mpi_integer,
107  $ dprocmaph,ierr)
108  call mpi_win_unlock(nidt,dprocmaph,ierr)
109 #else
110  call icopy(ibuf,dprocmapwin(2*(ieg-1) + 1),2)
111 #endif
112  if (dprocmapcache) then
113  if (ibuf(2).eq.nid) then
114  ii = ibuf(1)
115  else
116  iran = mod(iran*ia+ic,im)
117  ii = lelt + (lcr*iran)/im + 1 ! randomize array location
118  endif
119  cache(ii,1) = ibuf(1)
120  cache(ii,2) = ibuf(2)
121  cache(ii,3) = ieg
122  endif
123  endif
124 
125  return
126  end
127 c-----------------------------------------------------------------------
128  subroutine dprocmapfind(il,nids,ieg)
129 
130  include 'SIZE'
131  include 'PARALLEL'
132 
133  nstar = nelgt/np
134  nids = (ieg-1)/nstar
135  il = ieg - nids * nstar
136  if (ieg .gt. np*nstar) then
137  nids = mod(ieg,np) - 1
138  il = nstar + 1
139  endif
140 
141  return
142  end
143 c-----------------------------------------------------------------------
144  integer function lsearch_ur(a,n,k)
145 
146  integer a(n), n, k
147  parameter(lvec = 8) ! unroll factor
148 
149  lsearch_ur = 0
150  do i = 1,n,lvec
151  do j = 0,lvec-1
152  if (a(i+j).eq.k) lsearch_ur = i + j
153  enddo
154  if (lsearch_ur.gt.0) goto 10
155  enddo
156 
157 10 continue
158  end
159 c-----------------------------------------------------------------------
160  integer function gllnid(ieg)
161 
162  include 'mpif.h'
163 
164  integer iegl, nidl
165  save iegl, nidl
166  data iegl, nidl /0,0/
167 
168  integer ibuf(2)
169 
170  if (ieg.eq.iegl) then
171  ibuf(2) = nidl
172  goto 100
173  endif
174  call dprocmapget(ibuf,ieg)
175 
176  100 iegl = ieg
177  nidl = ibuf(2)
178  gllnid = ibuf(2)
179 
180  end
181 c-----------------------------------------------------------------------
182  integer function gllel(ieg)
183 
184  include 'mpif.h'
185 
186  integer iegl, iell
187  save iegl, iell
188  data iegl, iell /0,0/
189 
190  integer ibuf(2)
191 
192  if (ieg.eq.iegl) then
193  ibuf(1) = iell
194  goto 100
195  endif
196  call dprocmapget(ibuf,ieg)
197 
198  100 iegl = ieg
199  iell = ibuf(1)
200  gllel = ibuf(1)
201 
202  end
203 #endif
subroutine exitti(stringi, idata)
Definition: comm_mpi.f:535
subroutine dprocmapget(ibuf, ieg)
Definition: dprocmap.f:68
integer function lsearch_ur(a, n, k)
Definition: dprocmap.f:145
subroutine dprocmapfind(il, nids, ieg)
Definition: dprocmap.f:129
integer function gllel(ieg)
Definition: dprocmap.f:183
subroutine dprocmapinit()
Definition: dprocmap.f:11
integer function gllnid(ieg)
Definition: dprocmap.f:161
subroutine dprocmapput(ibuf, lbuf, ioff, ieg)
Definition: dprocmap.f:40
subroutine ifill(ia, ib, n)
Definition: math.f:252
subroutine icopy(a, b, n)
Definition: math.f:289