28 function mpp_redistribute_init_comm(domain_in,l_addrs_in, domain_out,l_addrs_out, &
29 isize_in,jsize_in,ksize_in,isize_out,jsize_out,ksize_out)
RESULT(d_comm)
30 type(DomainCommunicator2D),
pointer :: d_comm
31 type(domain2D),
target,
intent(in) :: domain_in
32 integer(i8_kind),
intent(in) :: l_addrs_in(:)
33 type(domain2D),
target,
intent(in) :: domain_out
34 integer(i8_kind),
intent(in) :: l_addrs_out(:)
35 integer,
intent(in) :: isize_in
36 integer,
intent(in) :: jsize_in
37 integer,
intent(in) :: ksize_in
38 integer,
intent(in) :: isize_out
39 integer,
intent(in) :: jsize_out
40 integer,
intent(in) :: ksize_out
42 integer(i8_kind) :: domain_id
44 integer :: is, ie, js, je, ke, ioff, joff, list_size
45 integer :: isc, iec, jsc, jec, mytile
46 integer :: lsize,rsize,msgsize,to_pe,from_pe
47 integer,
allocatable,
dimension(:) :: isL, jsL
48 integer(i8_kind),
allocatable,
dimension(:,:) :: slist_addr
49 character(len=8) :: text
64 if( domain_in%pe /= null_pe )ke = ksize_in
65 if( domain_out%pe /= null_pe )
then
66 if( ke /= 0 .AND. ke /= ksize_out ) &
67 call mpp_error( fatal,
'MPP_REDISTRIBUTE_INIT_COMM: mismatch between field_in and field_out.' )
70 if( ke == 0 )
call mpp_error( fatal, &
71 &
'MPP_REDISTRIBUTE_INIT_COMM: either domain_in or domain_out must be native.' )
73 if( domain_in%pe /= null_pe )
then
74 if( isize_in /= domain_in%x(1)%domain_data%size .OR. jsize_in /= domain_in%y(1)%domain_data%size ) &
75 call mpp_error( fatal,
'MPP_REDISTRIBUTE_INIT_COMM: field_in must be on data domain of domain_in.' )
77 if( domain_out%pe /= null_pe )
then
78 if( isize_out /= domain_out%x(1)%domain_data%size .OR. jsize_out /= domain_out%y(1)%domain_data%size ) &
79 call mpp_error( fatal,
'MPP_REDISTRIBUTE_INIT_COMM: field_out must be on data domain of domain_out.' )
84 list_size =
size(l_addrs_in(:))
85 if(l_addrs_out(1) > 0)
then
86 domain_id = set_domain_id(domain_out%id,ke+list_size)
88 domain_id = set_domain_id(domain_in%id,ke+list_size)
91 d_comm =>get_comm(domain_id,l_addrs_in(1),l_addrs_out(1))
93 if(d_comm%initialized)
return
95 d_comm%l_addr = l_addrs_in(1)
96 d_comm%domain_in =>domain_in
97 d_comm%Slist_size =
size(domain_out%list(:))
98 d_comm%isize_in = isize_in
99 d_comm%jsize_in = jsize_in
103 lsize = d_comm%Slist_size-1
104 allocate(d_comm%sendis(1,0:lsize), d_comm%sendie(1,0:lsize), &
105 d_comm%sendjs(1,0:lsize), d_comm%sendje(1,0:lsize), &
106 d_comm%S_msize(0:lsize),isl(0:lsize),jsl(0:lsize))
107 allocate(slist_addr(list_size,0:lsize))
108 allocate(d_comm%cto_pe(0:lsize), d_comm%S_do_buf(0:lsize))
113 d_comm%sendis=0; d_comm%sendie=0
114 d_comm%sendjs=0; d_comm%sendje=0;
116 d_comm%S_do_buf=.false.
118 ioff = domain_in%x(1)%domain_data%begin
119 joff = domain_in%y(1)%domain_data%begin
120 mytile = domain_in%tile_id(1)
122 call mpp_get_compute_domain( domain_in, isc, iec, jsc, jec )
124 m = mod( domain_out%pos+list+lsize+1, lsize+1 )
125 if( mytile .NE. domain_out%list(m)%tile_id(1) ) cycle
126 d_comm%cto_pe(list) = domain_out%list(m)%pe
127 to_pe = d_comm%cto_pe(list)
128 is = domain_out%list(m)%x(1)%compute%begin
129 ie = domain_out%list(m)%x(1)%compute%end
130 js = domain_out%list(m)%y(1)%compute%begin
131 je = domain_out%list(m)%y(1)%compute%end
132 is = max(is,isc); ie = min(ie,iec)
133 js = max(js,jsc); je = min(je,jec)
134 if( ie >= is .AND. je >= js )
then
135 d_comm%S_do_buf(list) = .true.
136 d_comm%sendis(1,list)=is; d_comm%sendie(1,list)=ie
137 d_comm%sendjs(1,list)=js; d_comm%sendje(1,list)=je
138 d_comm%S_msize(list) = (ie-is+1)*(je-js+1)*ke
139 isl(list) = is-ioff+1; jsl(list) = js-joff+1
145 d_comm%domain_out =>domain_out
146 d_comm%Rlist_size =
size(domain_in%list(:))
147 d_comm%isize_out = isize_out
148 d_comm%jsize_out = jsize_out
150 rsize = d_comm%Rlist_size-1
151 allocate(d_comm%recvis(1,0:rsize), d_comm%recvie(1,0:rsize), &
152 d_comm%recvjs(1,0:rsize), d_comm%recvje(1,0:rsize), &
153 d_comm%R_msize(0:rsize))
154 allocate(d_comm%cfrom_pe(0:rsize), d_comm%R_do_buf(0:rsize))
155 allocate(d_comm%isizeR(0:rsize), d_comm%jsizeR(0:rsize))
156 allocate(d_comm%sendisR(1,0:rsize), d_comm%sendjsR(1,0:rsize))
157 allocate(d_comm%rem_addrl(list_size,0:rsize))
158 d_comm%rem_addrl=-9999
160 d_comm%recvis=0; d_comm%recvie=0
161 d_comm%recvjs=0; d_comm%recvje=0;
163 d_comm%R_do_buf=.false.
164 d_comm%isizeR=0; d_comm%jsizeR=0
165 d_comm%sendisR=0; d_comm%sendjsR=0
167 mytile = domain_out%tile_id(1)
168 call mpp_get_compute_domain( domain_out, isc, iec, jsc, jec )
170 m = mod( domain_in%pos+rsize+1-list, rsize+1 )
171 if( mytile .NE. domain_in%list(m)%tile_id(1) ) cycle
172 d_comm%cfrom_pe(list) = domain_in%list(m)%pe
173 from_pe = d_comm%cfrom_pe(list)
174 is = domain_in%list(m)%x(1)%compute%begin
175 ie = domain_in%list(m)%x(1)%compute%end
176 js = domain_in%list(m)%y(1)%compute%begin
177 je = domain_in%list(m)%y(1)%compute%end
178 is = max(is,isc); ie = min(ie,iec)
179 js = max(js,jsc); je = min(je,jec)
180 if( ie >= is .AND. je >= js )
then
181 d_comm%R_do_buf(list) = .true.
182 d_comm%recvis(1,list)=is; d_comm%recvie(1,list)=ie
183 d_comm%recvjs(1,list)=js; d_comm%recvje(1,list)=je
184 d_comm%R_msize(list) = (ie-is+1)*(je-js+1)*ke
188 d_comm%isize_max = isize_in;
call mpp_max(d_comm%isize_max)
189 d_comm%jsize_max = jsize_in;
call mpp_max(d_comm%jsize_max)
192 msgsize = ( maxval( (/0,sum(d_comm%S_msize(:))/) ) + maxval( (/0,sum(d_comm%R_msize(:))/) ) ) * list_size
194 mpp_domains_stack_hwm = max( mpp_domains_stack_hwm, msgsize )
195 if( mpp_domains_stack_hwm.GT.mpp_domains_stack_size )
then
196 write( text,
'(i8)' )mpp_domains_stack_hwm
197 call mpp_error( fatal, &
198 &
'MPP_REDISTRIBUTE_INIT_COMM: mpp_domains_stack overflow, call mpp_domains_set_stack_size(' &
199 & //trim(text)//
') from all PEs.' )
203 DEALLOCATE(slist_addr,isl,jsl)
205 d_comm%initialized = .true.
207 end function mpp_redistribute_init_comm
211 jsize_l, ksize,l_addr2,flags, position)
RESULT(d_comm)
212 type(domaincommunicator2d),
pointer :: d_comm
213 type(domain2d),
target,
intent(in) :: domain
214 integer(i8_kind),
intent(in) :: l_addr
215 integer,
intent(in) :: isize_g
216 integer,
intent(in) :: jsize_g
217 integer,
intent(in) :: isize_l
218 integer,
intent(in) :: jsize_l
219 integer,
intent(in) :: ksize
220 integer(i8_kind),
optional,
intent(in) :: l_addr2
221 integer,
optional,
intent(in) :: flags
222 integer,
optional,
intent(in) :: position
224 integer(i8_kind) :: domain_id
225 integer :: n, lpos, rpos, list, nlist, tile_id
226 integer :: update_flags
227 logical :: xonly, yonly
228 integer :: is, ie, js, je, ioff, joff, ishift, jshift
229 integer :: lsize,msgsize,from_pe
230 integer,
allocatable,
dimension(:) :: isl, jsl
231 integer(i8_kind),
allocatable,
dimension(:,:) :: slist_addr
232 integer(i8_kind),
save ,
dimension(2) :: rem_addr
233 character(len=8) :: text
235 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_GLOBAL_FIELD: must first call mpp_domains_init.' )
236 update_flags=xupdate+yupdate; xonly = .false.; yonly = .false.
237 if(
PRESENT(flags) )
then
239 xonly = btest(flags,east)
240 yonly = btest(flags,south)
241 if( .NOT.xonly .AND. .NOT.yonly )
call mpp_error( warning, &
242 'MPP_GLOBAL_FIELD: you must have flags=XUPDATE, YUPDATE or XUPDATE+YUPDATE' )
243 if(xonly .AND. yonly)
then
244 xonly = .false.; yonly = .false.
250 if( isize_g /= (domain%x(1)%global%size+ishift) .OR. jsize_g /= (domain%y(1)%global%size+jshift) ) &
251 call mpp_error( fatal,
'MPP_GLOBAL_FIELD_INIT_COMM: incoming arrays do not match domain.' )
253 if( isize_l == (domain%x(1)%compute%size+ishift) .AND. jsize_l == (domain%y(1)%compute%size+jshift) )
then
255 ioff = -domain%x(1)%compute%begin + 1
256 joff = -domain%y(1)%compute%begin + 1
257 elseif( isize_l == (domain%x(1)%memory%size+ishift) .AND. jsize_l == (domain%y(1)%memory%size+jshift) )
then
259 ioff = -domain%x(1)%domain_data%begin + 1
260 joff = -domain%y(1)%domain_data%begin + 1
262 call mpp_error(fatal, &
263 &
'MPP_GLOBAL_FIELD_INIT_COMM: incoming field array must match either compute domain or data domain.')
267 domain_id=set_domain_id(domain%id,ksize,update_flags, position=position)
268 d_comm =>get_comm(domain_id,l_addr,l_addr2)
270 if(d_comm%initialized)
return
271 d_comm%domain => domain
272 d_comm%isize_in = isize_l; d_comm%isize_out = isize_g
273 d_comm%jsize_in = jsize_l; d_comm%jsize_out = jsize_g
275 d_comm%gf_ioff=ioff; d_comm%gf_joff=joff
279 lsize =
size(domain%x(1)%list(:))
281 allocate(d_comm%cto_pe(0:lsize-1))
284 lpos = mod(domain%x(1)%pos+lsize-list,lsize)
285 d_comm%cto_pe(list) = domain%x(1)%list(lpos)%pe
288 allocate(d_comm%cfrom_pe(0:lsize-1))
289 allocate(d_comm%recvis(1,0:lsize-1), d_comm%recvie(1,0:lsize-1), &
290 d_comm%recvjs(1,0:lsize-1), d_comm%recvje(1,0:lsize-1), &
291 d_comm%R_msize(0:lsize-1))
293 d_comm%recvis=0; d_comm%recvie=0
294 d_comm%recvjs=0; d_comm%recvje=0;
297 rpos = mod(domain%x(1)%pos+list,lsize)
298 from_pe = domain%x(1)%list(rpos)%pe
299 d_comm%cfrom_pe(list) = from_pe
300 is = domain%list(from_pe)%x(1)%compute%begin; ie = domain%list(from_pe)%x(1)%compute%end+ishift
301 js = domain%y(1)%compute%begin; je = domain%y(1)%compute%end+jshift
302 d_comm%recvis(1,list)=is; d_comm%recvie(1,list)=ie
303 d_comm%recvjs(1,list)=js; d_comm%recvje(1,list)=je
304 d_comm%R_msize(list) = (ie-is+1) * (je-js+1) * ksize
308 lsize =
size(domain%y(1)%list(:))
310 allocate(d_comm%cto_pe(0:lsize-1))
313 lpos = mod(domain%y(1)%pos+lsize-list,lsize)
314 d_comm%cto_pe(list) = domain%y(1)%list(lpos)%pe
317 allocate(d_comm%cfrom_pe(0:lsize-1))
318 allocate(d_comm%recvis(1,0:lsize-1), d_comm%recvie(1,0:lsize-1), &
319 d_comm%recvjs(1,0:lsize-1), d_comm%recvje(1,0:lsize-1), &
320 d_comm%R_msize(0:lsize-1))
322 d_comm%recvis=0; d_comm%recvie=0
323 d_comm%recvjs=0; d_comm%recvje=0;
326 rpos = mod(domain%y(1)%pos+list,lsize)
327 from_pe = domain%y(1)%list(rpos)%pe
328 d_comm%cfrom_pe(list) = from_pe
329 is = domain%x(1)%compute%begin; ie = domain%x(1)%compute%end+ishift
330 js = domain%list(from_pe)%y(1)%compute%begin; je = domain%list(from_pe)%y(1)%compute%end+jshift
331 d_comm%recvis(1,list)=is; d_comm%recvie(1,list)=ie
332 d_comm%recvjs(1,list)=js; d_comm%recvje(1,list)=je
333 d_comm%R_msize(list) = (ie-is+1) * (je-js+1) * ksize
337 nlist =
size(domain%list(:))
338 tile_id = domain%tile_id(1)
342 if( domain%list(list)%tile_id(1) .NE. tile_id ) cycle
347 allocate(d_comm%cto_pe(0:lsize-1))
351 lpos = mod(domain%pos+nlist-list,nlist)
352 if( domain%list(lpos)%tile_id(1) .NE. tile_id ) cycle
353 d_comm%cto_pe(n) = domain%list(lpos)%pe
357 allocate(d_comm%cfrom_pe(0:lsize-1))
358 allocate(d_comm%recvis(1,0:lsize-1), d_comm%recvie(1,0:lsize-1), &
359 d_comm%recvjs(1,0:lsize-1), d_comm%recvje(1,0:lsize-1), &
360 d_comm%R_msize(0:lsize-1))
362 d_comm%recvis=0; d_comm%recvie=0
363 d_comm%recvjs=0; d_comm%recvje=0;
367 rpos = mod(domain%pos+list,nlist)
368 if( domain%list(rpos)%tile_id(1) .NE. tile_id ) cycle
369 d_comm%cfrom_pe(n) = domain%list(rpos)%pe
370 is = domain%list(rpos)%x(1)%compute%begin; ie = domain%list(rpos)%x(1)%compute%end+ishift
371 js = domain%list(rpos)%y(1)%compute%begin; je = domain%list(rpos)%y(1)%compute%end+jshift
372 d_comm%recvis(1,n)=is; d_comm%recvie(1,n)=ie
373 d_comm%recvjs(1,n)=js; d_comm%recvje(1,n)=je
374 d_comm%R_msize(n) = (je-js+1) * (ie-is+1) * ksize
380 d_comm%Slist_size = lsize
381 d_comm%Rlist_size = lsize
384 allocate(d_comm%sendis(1,0:lsize-1), d_comm%sendie(1,0:lsize-1), &
385 d_comm%sendjs(1,0:lsize-1), d_comm%sendje(1,0:lsize-1), &
386 d_comm%S_msize(0:lsize-1),isl(0:lsize-1),jsl(0:lsize-1))
387 allocate(slist_addr(2,0:lsize-1))
390 d_comm%sendis=0; d_comm%sendie=0
391 d_comm%sendjs=0; d_comm%sendje=0;
394 is=domain%x(1)%compute%begin; ie=domain%x(1)%compute%end+ishift
395 js=domain%y(1)%compute%begin; je=domain%y(1)%compute%end+jshift
396 d_comm%sendis(1,list)=is; d_comm%sendie(1,list)=ie
397 d_comm%sendjs(1,list)=js; d_comm%sendje(1,list)=je
398 d_comm%S_msize(list) = (je-js+1) * (ie-is+1) * ksize
399 isl(list) = ioff+domain%x(1)%compute%begin; jsl(list) = joff+domain%y(1)%compute%begin
403 allocate(d_comm%isizeR(0:lsize-1), d_comm%jsizeR(0:lsize-1))
404 allocate(d_comm%sendisR(1,0:lsize-1), d_comm%sendjsR(1,0:lsize-1))
405 if(.not.
PRESENT(l_addr2))
then
406 allocate(d_comm%rem_addr(0:lsize-1))
407 d_comm%rem_addr=-9999
409 allocate(d_comm%rem_addrx(0:lsize-1),d_comm%rem_addry(0:lsize-1))
410 d_comm%rem_addrx=-9999; d_comm%rem_addry=-9999
412 d_comm%isizeR=0; d_comm%jsizeR=0
413 d_comm%sendisR=0; d_comm%sendjsR=0
417 msgsize = maxval( (/0,sum(d_comm%S_msize(:))/) ) + maxval( (/0,sum(d_comm%R_msize(:))/) )
419 mpp_domains_stack_hwm = max( mpp_domains_stack_hwm, msgsize )
420 if( mpp_domains_stack_hwm.GT.mpp_domains_stack_size )
then
421 write( text,
'(i8)' )mpp_domains_stack_hwm
422 call mpp_error( fatal, &
423 &
'MPP_GLOBAL_FIELD_INIT_COMM: mpp_domains_stack overflow, call mpp_domains_set_stack_size(' &
424 & //trim(text)//
') from all PEs.' )
428 DEALLOCATE(slist_addr,isl,jsl)
430 d_comm%initialized = .true.
435 subroutine mpp_redistribute_free_comm(domain_in,l_addr,domain_out,l_addr2,ksize,lsize)
438 type(domain2d),
intent(in) :: domain_in
439 integer(i8_kind),
intent(in) :: l_addr
440 type(domain2d),
intent(in) :: domain_out
441 integer(i8_kind),
intent(in) :: l_addr2
442 integer,
intent(in) :: ksize,lsize
444 integer(i8_kind) :: domain_id
447 domain_id = set_domain_id(domain_out%id,ksize+lsize)
449 domain_id = set_domain_id(domain_in%id,ksize+lsize)
451 call free_comm(domain_id,l_addr,l_addr2)
452 end subroutine mpp_redistribute_free_comm
455 subroutine mpp_global_field_free_comm(domain,l_addr,ksize,l_addr2,flags)
458 type(domain2d),
intent(in) :: domain
459 integer(i8_kind),
intent(in) :: l_addr
460 integer,
intent(in) :: ksize
461 integer(i8_kind),
optional,
intent(in) :: l_addr2
462 integer,
optional,
intent(in) :: flags
464 integer :: update_flags
465 integer(i8_kind) :: domain_id
467 update_flags=0;
if(
PRESENT(flags))update_flags=flags
468 domain_id=set_domain_id(domain%id,ksize,update_flags)
469 call free_comm(domain_id,l_addr,l_addr2)
470 end subroutine mpp_global_field_free_comm
473 subroutine free_comm(domain_id,l_addr,l_addr2)
476 integer(i8_kind),
intent(in) :: domain_id
477 integer(i8_kind),
intent(in) :: l_addr
478 integer(i8_kind),
optional,
intent(in) :: l_addr2
480 integer(i8_kind) :: dc_key,a_key
481 integer :: dc_idx,a_idx,i_idx,insert,insert_a,insert_i
482 integer :: a2_idx,insert_a2
485 i_idx = find_key(domain_id,ids_sorted(1:n_ids),insert_i)
486 a_idx = find_key(l_addr,addrs_sorted(1:a_sort_len),insert_a)
487 a_key = int(addrs_idx(a_idx),kind(i8_kind))
488 if(
PRESENT(l_addr2))
then
489 a2_idx = find_key(l_addr2,addrs2_sorted(1:a2_sort_len),insert_a2)
490 a_key = a_key + addr2_base*int(addrs2_idx(a2_idx),kind(i8_kind))
492 dc_key = domain_id_base*int(ids_idx(i_idx),kind(i8_kind)) + a_key
493 dc_idx = find_key(dc_key,dckey_sorted(1:dc_sort_len),insert)
496 call mpp_error(fatal,
'FREE_COMM: attempt to remove nonexistent domains communicator key')
498 call deallocate_comm(d_comm(dc_idx))
499 call pop_key(dckey_sorted,d_comm_idx,dc_sort_len,dc_idx)
500 call pop_key(addrs_sorted,addrs_idx,a_sort_len,a_idx)
501 if(
PRESENT(l_addr2))
call pop_key(addrs2_sorted,addrs2_idx,a2_sort_len,a2_idx)
502 end subroutine free_comm
505 function get_comm(domain_id,l_addr,l_addr2)
506 integer(i8_kind),
intent(in) :: domain_id
507 integer(i8_kind),
intent(in) :: l_addr
508 integer(i8_kind),
intent(in),
optional :: l_addr2
509 type(domaincommunicator2d),
pointer :: get_comm
511 integer(i8_kind) :: dc_key,a_key
512 integer :: i,dc_idx,a_idx,i_idx,insert,insert_a,insert_i
513 integer :: a2_idx,insert_a2
515 if(.not.
ALLOCATED(d_comm))
ALLOCATE(d_comm(max_fields))
516 i_idx = find_key(domain_id,ids_sorted(1:n_ids),insert_i)
517 a_idx = find_key(l_addr,addrs_sorted(1:a_sort_len),insert_a)
518 a_key = int(addrs_idx(a_idx),kind(i8_kind))
519 if(
PRESENT(l_addr2))
then
520 a2_idx = find_key(l_addr2,addrs2_sorted(1:a2_sort_len),insert_a2)
521 a_key = a_key + addr2_base*int(addrs2_idx(a2_idx),kind(i8_kind))
523 dc_key = domain_id_base*int(ids_idx(i_idx),kind(i8_kind)) + a_key
524 dc_idx = find_key(dc_key,dckey_sorted(1:dc_sort_len),insert)
526 get_comm =>d_comm(d_comm_idx(dc_idx))
529 if(n_ids == max_dom_ids)
then
530 call mpp_error(fatal,
'GET_COMM: Maximum number of domains exceeded')
533 i_idx = push_key(ids_sorted,ids_idx,i_sort_len,insert_i,domain_id,n_ids)
536 if(n_addrs == max_addrs)
then
537 call mpp_error(fatal,
'GET_COMM: Maximum number of memory addresses exceeded')
539 n_addrs = n_addrs + 1
540 a_idx = push_key(addrs_sorted,addrs_idx,a_sort_len,insert_a,l_addr,n_addrs)
542 if(
PRESENT(l_addr2))
then
544 if(n_addrs2 == max_addrs2)
then
545 call mpp_error(fatal,
'GET_COMM: Maximum number of 2nd memory addresses exceeded')
547 n_addrs2 = n_addrs2 + 1
548 a2_idx = push_key(addrs2_sorted,addrs2_idx,a2_sort_len,insert_a2,l_addr2,n_addrs2)
551 if(n_comm == max_fields)
then
552 call mpp_error(fatal,
'GET_COMM: Maximum number of fields exceeded')
554 a_key = int(addrs_idx(a_idx),kind(8))
555 if(
PRESENT(l_addr2))a_key = a_key + addr2_base*int(addrs2_idx(a2_idx),kind(8))
556 dc_key = domain_id_base*int(ids_idx(i_idx),kind(i8_kind)) + a_key
557 dc_idx = find_key(dc_key,dckey_sorted(1:dc_sort_len),insert)
558 if(dc_idx /= -1)
call mpp_error(fatal,
'GET_COMM: attempt to insert existing key')
560 i = push_key(dckey_sorted,d_comm_idx,dc_sort_len,insert,dc_key,n_comm)
561 d_comm_idx(insert) = n_comm
562 if(
PRESENT(l_addr2))
then
563 d_comm(n_comm)%l_addrx = l_addr
564 d_comm(n_comm)%l_addry = l_addr2
566 d_comm(n_comm)%l_addr = l_addr
568 get_comm =>d_comm(n_comm)
570 end function get_comm
573 function push_key(sorted,idx,n_idx,insert,key,ival)
574 integer(i8_kind),
intent(inout),
dimension(:) :: sorted
575 integer,
intent(inout),
dimension(-1:) :: idx
576 integer,
intent(inout) :: n_idx
577 integer,
intent(in) :: insert
578 integer(i8_kind),
intent(in) :: key
579 integer,
intent(in) :: ival
581 integer :: push_key,i
584 sorted(i+1) = sorted(i)
591 end function push_key
594 subroutine pop_key(sorted,idx,n_idx,key_idx)
595 integer(i8_kind),
intent(inout),
dimension(:) :: sorted
596 integer,
intent(inout),
dimension(-1:) :: idx
597 integer,
intent(inout) :: n_idx
598 integer,
intent(in) :: key_idx
603 sorted(i) = sorted(i+1)
606 sorted(n_idx) = -9999
609 end subroutine pop_key
612 function find_key(key,sorted,insert)
RESULT(n)
614 integer(i8_kind),
intent(in) :: key
615 integer(i8_kind),
dimension(:),
intent(in) :: sorted
616 integer,
intent(out) :: insert
617 integer :: n, n_max, n_min, n_key
620 n_key =
size(sorted(:))
625 if(key < sorted(1))
then
627 elseif(key > sorted(n_key))
then
628 insert = n_key+1;
return
631 if(key == sorted(1))
then
633 elseif(key == sorted(n_key))
then
641 if(key == sorted(n))
then
643 elseif(key > sorted(n))
then
644 if(key < sorted(n+1))
then
650 if(key > sorted(n-1))
then
656 if(n==1 .or. n==n_key)
exit
659 end function find_key
662 subroutine deallocate_comm(d_comm)
663 type(domaincommunicator2d),
intent(inout) :: d_comm
665 d_comm%domain =>null()
666 d_comm%domain_in =>null()
667 d_comm%domain_out =>null()
669 d_comm%initialized=.false.
672 d_comm%l_addrx =-9999
673 d_comm%l_addry =-9999
675 if(
allocated(d_comm%sendis) )
DEALLOCATE(d_comm%sendis);
676 if(
allocated(d_comm%sendie) )
DEALLOCATE(d_comm%sendie);
677 if(
allocated(d_comm%sendjs) )
DEALLOCATE(d_comm%sendjs);
678 if(
allocated(d_comm%sendje) )
DEALLOCATE(d_comm%sendje);
679 if(
allocated(d_comm%S_msize) )
DEALLOCATE(d_comm%S_msize);
680 if(
allocated(d_comm%S_do_buf) )
DEALLOCATE(d_comm%S_do_buf);
681 if(
allocated(d_comm%cto_pe) )
DEALLOCATE(d_comm%cto_pe);
682 if(
allocated(d_comm%recvis) )
DEALLOCATE(d_comm%recvis);
683 if(
allocated(d_comm%recvie) )
DEALLOCATE(d_comm%recvie);
684 if(
allocated(d_comm%recvjs) )
DEALLOCATE(d_comm%recvjs);
685 if(
allocated(d_comm%recvje) )
DEALLOCATE(d_comm%recvje);
686 if(
allocated(d_comm%R_msize) )
DEALLOCATE(d_comm%R_msize);
687 if(
allocated(d_comm%R_do_buf) )
DEALLOCATE(d_comm%R_do_buf);
688 if(
allocated(d_comm%cfrom_pe) )
DEALLOCATE(d_comm%cfrom_pe);
689 d_comm%Slist_size=0; d_comm%Rlist_size=0
690 d_comm%isize=0; d_comm%jsize=0; d_comm%ke=0
691 d_comm%isize_in=0; d_comm%jsize_in=0
692 d_comm%isize_out=0; d_comm%jsize_out=0
693 d_comm%isize_max=0; d_comm%jsize_max=0
694 d_comm%gf_ioff=0; d_comm%gf_joff=0
696 if(
allocated(d_comm%isizeR) )
DEALLOCATE(d_comm%isizeR);
697 if(
allocated(d_comm%jsizeR) )
DEALLOCATE(d_comm%jsizeR);
698 if(
allocated(d_comm%sendisR) )
DEALLOCATE(d_comm%sendisR);
699 if(
allocated(d_comm%sendjsR) )
DEALLOCATE(d_comm%sendjsR);
700 if(
allocated(d_comm%rem_addr) )
DEALLOCATE(d_comm%rem_addr);
701 if(
allocated(d_comm%rem_addrx) )
DEALLOCATE(d_comm%rem_addrx);
702 if(
allocated(d_comm%rem_addry) )
DEALLOCATE(d_comm%rem_addry);
703 if(
allocated(d_comm%rem_addrl) )
DEALLOCATE(d_comm%rem_addrl);
704 end subroutine deallocate_comm
707 function set_domain_id(d_id,ksize,flags,gtype, position, whalo, ehalo, shalo, nhalo)
708 integer(i8_kind),
intent(in) :: d_id
709 integer ,
intent(in) :: ksize
710 integer ,
optional,
intent(in) :: flags
711 integer ,
optional,
intent(in) :: gtype
712 integer ,
optional,
intent(in) :: position
713 integer ,
optional,
intent(in) :: whalo, ehalo, shalo, nhalo
715 integer(i8_kind) :: set_domain_id
717 set_domain_id=d_id + ke_base*int(ksize,kind(d_id))
718 if(
PRESENT(flags))set_domain_id=set_domain_id+int(flags,kind(d_id))
719 if(
PRESENT(gtype))set_domain_id=set_domain_id+gt_base*int(gtype,kind(d_id))
722 if(
present(position)) set_domain_id=set_domain_id+gt_base*int(2**position, kind(d_id))
724 if(
present(whalo))
then
726 set_domain_id=set_domain_id+gt_base*int(2**4*2**whalo, kind(d_id))
728 set_domain_id=set_domain_id-gt_base*int(2**4*2**(-whalo), kind(d_id))
731 if(
present(ehalo))
then
733 set_domain_id=set_domain_id+gt_base*int(2**4*2**ehalo, kind(d_id))
735 set_domain_id=set_domain_id-gt_base*int(2**4*2**(-ehalo), kind(d_id))
738 if(
present(shalo))
then
740 set_domain_id=set_domain_id+gt_base*int(2**4*2**shalo, kind(d_id))
742 set_domain_id=set_domain_id-gt_base*int(2**4*2**(-shalo), kind(d_id))
745 if(
present(nhalo))
then
747 set_domain_id=set_domain_id+gt_base*int(2**4*2**nhalo, kind(d_id))
749 set_domain_id=set_domain_id-gt_base*int(2**4*2**(-nhalo), kind(d_id))
752 end function set_domain_id
type(domaincommunicator2d) function, pointer mpp_global_field_init_comm(domain, l_addr, isize_g, jsize_g, isize_l, jsize_l, ksize, l_addr2, flags, position)
initializes a DomainCommunicator2D type for use in mpp_global_field
subroutine mpp_get_domain_shift(domain, ishift, jshift, position)
Returns the shift value in x and y-direction according to domain position..
subroutine mpp_sync_self(pelist, check, request, msg_size, msg_type)
This is to check if current PE's outstanding puts are complete but we can't use shmem_fence because w...