4 !***********************************************************************
5 !* GNU Lesser General Public License
7 !* This file
is part of the GFDL Flexible Modeling System (FMS).
9 !* FMS
is free software: you can redistribute it and/or modify it under
10 !* the terms of the GNU Lesser General Public License as published by
11 !* the Free Software Foundation, either
version 3 of the License, or (at
12 !* your option) any later
version.
14 !* FMS
is distributed in the hope that it
will be useful, but WITHOUT
15 !* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 !* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 !* You should have
received a copy of the GNU Lesser General Public
20 !* License along with FMS. If
not, see <http:
21 !***********************************************************************
23 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
25 ! ROUTINES TO INITIALIZE/FINALIZE MPP MODULE: mpp_init, mpp_exit !
27 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
28 ! subroutine mpp_init( flags, in,
out, err, log )
29 !
integer, optional, intent(in) :: flags, in,
out, err, log
30 subroutine mpp_init( flags,localcomm )
31 integer, optional, intent(in) :: flags
32 integer, optional, intent(in) :: localcomm !
dummy here, used only in MPI
35 logical :: opened, existed
45 call START_PES(0) !the argument 0 means extract from environment variable NPES on PVP/SGI, from mpprun -
n on t3e
51 !PEsets: make defaults illegal
57 peset(:)%log2stride = -1
59 !0=
single-
PE, initialized so that count returns 1
61 allocate(
peset(0)%list(1) )
69 clock0 = mpp_clock_id(
'Total runtime', flags=MPP_CLOCK_SYNC )
71 ! Initialize mpp_datatypes
72 ! NOTE: mpp_datatypes are
not implemented in SHMEM;
this is an
empty list
77 ! Create the bytestream (default) mpp_datatype
90 if( PRESENT(flags) )then
91 debug = flags.EQ.MPP_DEBUG
95 !we use shpalloc to ensure all these are remotely accessible
96 len=0; ptr_sync = LOC(
pe) !null initialization
97 call mpp_malloc( ptr_sync,
size(TRANSFER(sync,
word)),
len )
98 len=0; ptr_status = LOC(
pe) !null initialization
100 len=0; ptr_remote = LOC(
pe) !null initialization
101 call mpp_malloc( ptr_remote,
npes*
size(TRANSFER(remote_data_loc(0),
word)),
len )
102 len=0; ptr_from = LOC(
pe) !null initialization
103 call mpp_malloc( ptr_from,
size(TRANSFER(mpp_from_pe,
word)),
len )
105 sync(:) = SHMEM_SYNC_VALUE
107 remote_data_loc(0:
npes-1) = MPP_WAIT
108 call mpp_set_stack_size(32768) !default initial value
110 call mpp_init_logfile()
114 #ifdef INTERNAL_FILE_NML 120 inquire( unit_nml,OPENED=opened )
121 if( .NOT.opened )exit
124 open(unit_nml,file=
'input.nml', iostat=io_status)
125 read(unit_nml,mpp_nml,iostat=io_status)
129 if (io_status > 0) then
130 call
mpp_error(FATAL,
'=>mpp_init: Error reading input.nml')
134 ! non-
root pe messages written to other location than stdout()
145 inquire(file=
etcfile, exist=existed)
152 !
if optional argument logunit=stdout, write messages to stdout instead.
153 !
if specifying non-defaults, you must specify
units not yet in use.
154 !
if( PRESENT(in) )then
155 ! inquire(
unit=in, opened=opened )
156 !
if( opened )call
mpp_error( FATAL, 'MPP_INIT: unable to open stdin.' )
159 !
if( PRESENT(
out) )then
160 ! inquire(
unit=
out, opened=opened )
161 !
if( opened )call
mpp_error( FATAL, 'MPP_INIT: unable to open stdout.' )
164 !
if( PRESENT(err) )then
165 ! inquire(
unit=err, opened=opened )
166 !
if( opened )call
mpp_error( FATAL, 'MPP_INIT: unable to open stderr.' )
170 !
if( PRESENT(log) )then
171 ! inquire(
unit=log, opened=opened )
172 !
if( opened .AND. log.NE.
out_unit )call
mpp_error( FATAL, 'MPP_INIT: unable to open stdlog.' )
175 !!
log_unit can be written to only from
root_pe, all others write to stdout
178 !
if( opened )call
mpp_error( FATAL, 'MPP_INIT: specified
unit for stdlog already in use.' )
189 write( logunit,'(/
a)' )'MPP
module '
190 write( logunit,'(
a,
i6)' )'MPP started with NPES=',
npes 191 write( logunit,'(
a)' )'Using SMA (shmem) library for message passing...'
192 write( logunit, '(
a,es12.4,
a,i10,
a)' ) &
194 write( logunit, '(
a,es12.4,
a,i20,
a)' ) &
200 call mpp_clock_begin(
clock0)
203 end subroutine mpp_init
205 !
####################################################################### 206 !to be called at the
end of
a run
207 subroutine mpp_exit()
209 real ::
t,
tmin, tmax, tavg, tstd
210 real ::
m, mmin, mmax, mavg, mstd, t_total
214 call mpp_set_current_pelist()
215 call mpp_clock_end(
clock0)
221 call sum_clock_data; call dump_clock_summary
224 write(
outunit,'(/
a,
i6,
a)' ) 'Tabulating mpp_clock statistics across ',
npes, ' PEs...'
226 write(
outunit,'(
a)' )' ... see mpp_clock.
out.
#### for details on individual PEs.' 227 write(
outunit,
'(/32x,a)' )
' tmin tmax tavg tstd tfrac grain pemin pemax' 229 write( logunit,
'(/37x,a)' )
'time' 235 !times between mpp_clock ticks
238 tmax =
t; call mpp_max(tmax)
239 tavg =
t; call mpp_sum(tavg); tavg = tavg/mpp_npes()
240 tstd = (
t-tavg)**2; call mpp_sum(tstd); tstd = sqrt( tstd/mpp_npes() )
248 '
tmin tmax tavg tstd mmin mmax mavg mstd mavg/tavg'
250 !messages: bytelengths and times
252 do
j = 1,MAX_EVENT_TYPES
259 mmin =
m; call mpp_min(mmin)
260 mmax =
m; call mpp_max(mmax)
261 mavg =
m; call mpp_sum(mavg); mavg = mavg/mpp_npes()
262 mstd = (
m-mavg)**2; call mpp_sum(mstd); mstd = sqrt( mstd/mpp_npes() )
266 tmax =
t; call mpp_max(tmax)
267 tavg =
t; call mpp_sum(tavg); tavg = tavg/mpp_npes()
268 tstd = (
t-tavg)**2; call mpp_sum(tstd); tstd = sqrt( tstd/mpp_npes() )
271 tmin, tmax, tavg, tstd, mmin, mmax, mavg, mstd, mavg/tavg
284 call mpp_set_current_pelist()
289 end subroutine mpp_exit
291 !
####################################################################### 292 !routine to perform symmetric allocation:
293 !
this is required on the t3e/O2k
for variables that
will be non-local arguments
294 !to
a shmem call (see man intro_shmem(3F)).
295 !newlen
is the required allocation
length for the pointer ptr
296 !
len is the current allocation (0
if unallocated)
297 subroutine mpp_malloc( ptr, newlen,
len )
303 !argument ptr
is a cray pointer, points to
a dummy argument in this routine
304 pointer( ptr,
dummy )
308 !use existing allocation
if it
is enough
309 if( newlen.LE.
len )return
311 call SHMEM_BARRIER_ALL()
312 !
if the pointer
is already allocated, deallocate
313 !
if(
len.NE.0 )call SHPDEALLC( ptr, error_8, -1 ) !BWA: error_8 instead of
error, see PV 682618 (fixed in mpt.1.3.0.1)
314 if(
len.NE.0 )call SHPDEALLC( ptr,
error, -1 )
315 !allocate new
length: assume that the array
is KIND=8
317 call SHPALLOC( ptr, newlen*words_per_long,
error, -1 )
319 call SHMEM_BARRIER_ALL()
324 write(
outunit,
'(a,i18,a,i5,a,2i8,i16)' )
'T=',
tick,
' PE=',
pe,
' MPP_MALLOC: len, newlen, ptr=',
len, newlen, ptr
327 end subroutine mpp_malloc
329 !#######################################################################
330 !
set the mpp_stack variable to be at least
n LONG words
long 331 subroutine mpp_set_stack_size(
n)
336 write(
text,
'(i8)' )
n 340 end subroutine mpp_set_stack_size
342 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
344 ! BASIC MESSAGE PASSING ROUTINE: mpp_transmit !
346 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
348 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
350 ! BASIC MESSAGE PASSING ROUTINE: mpp_transmit !
352 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
354 character(
len=*), intent(inout) :: data(:)
359 !pointer to remote data
360 character :: bdata(
length)
361 pointer( ptr, bdata )
370 if(mpp_pe() == mpp_root_pe()) then
378 call
mpp_error( FATAL, 'mpp_broadcast_text: broadcasting from invalid
PE.' )
385 write(
text, '(i8)' )words
389 if( mpp_npes().GT.1 )then
394 call mpp_sync(
pelist) !eliminate?
396 call SHMEM_UDCFLUSH !invalidate data cache
399 call mpp_sync(
pelist) !eliminate?
408 end subroutine mpp_broadcast_char
412 #define MPP_TRANSMIT_ mpp_transmit_real8 413 #undef MPP_TRANSMIT_SCALAR_ 414 #define MPP_TRANSMIT_SCALAR_ mpp_transmit_real8_scalar 415 #undef MPP_TRANSMIT_2D_ 416 #define MPP_TRANSMIT_2D_ mpp_transmit_real8_2d 417 #undef MPP_TRANSMIT_3D_ 418 #define MPP_TRANSMIT_3D_ mpp_transmit_real8_3d 419 #undef MPP_TRANSMIT_4D_ 420 #define MPP_TRANSMIT_4D_ mpp_transmit_real8_4d 421 #undef MPP_TRANSMIT_5D_ 422 #define MPP_TRANSMIT_5D_ mpp_transmit_real8_5d 424 #define MPP_RECV_ mpp_recv_real8 425 #undef MPP_RECV_SCALAR_ 426 #define MPP_RECV_SCALAR_ mpp_recv_real8_scalar 428 #define MPP_RECV_2D_ mpp_recv_real8_2d 430 #define MPP_RECV_3D_ mpp_recv_real8_3d 432 #define MPP_RECV_4D_ mpp_recv_real8_4d 434 #define MPP_RECV_5D_ mpp_recv_real8_5d 436 #define MPP_SEND_ mpp_send_real8 437 #undef MPP_SEND_SCALAR_ 438 #define MPP_SEND_SCALAR_ mpp_send_real8_scalar 440 #define MPP_SEND_2D_ mpp_send_real8_2d 442 #define MPP_SEND_3D_ mpp_send_real8_3d 444 #define MPP_SEND_4D_ mpp_send_real8_4d 446 #define MPP_SEND_5D_ mpp_send_real8_5d 447 #undef MPP_BROADCAST_ 448 #define MPP_BROADCAST_ mpp_broadcast_real8 449 #undef MPP_BROADCAST_SCALAR_ 450 #define MPP_BROADCAST_SCALAR_ mpp_broadcast_real8_scalar 451 #undef MPP_BROADCAST_2D_ 452 #define MPP_BROADCAST_2D_ mpp_broadcast_real8_2d 453 #undef MPP_BROADCAST_3D_ 454 #define MPP_BROADCAST_3D_ mpp_broadcast_real8_3d 455 #undef MPP_BROADCAST_4D_ 456 #define MPP_BROADCAST_4D_ mpp_broadcast_real8_4d 457 #undef MPP_BROADCAST_5D_ 458 #define MPP_BROADCAST_5D_ mpp_broadcast_real8_5d 460 #define MPP_TYPE_ real(DOUBLE_KIND) 461 #undef MPP_TYPE_BYTELEN_ 462 #define MPP_TYPE_BYTELEN_ 8 463 #undef SHMEM_BROADCAST_ 464 #define SHMEM_BROADCAST_ SHMEM_BROADCAST8 466 #define SHMEM_GET_ SHMEM_GET8 471 #define MPP_TRANSMIT_ mpp_transmit_cmplx8 472 #undef MPP_TRANSMIT_SCALAR_ 473 #define MPP_TRANSMIT_SCALAR_ mpp_transmit_cmplx8_scalar 474 #undef MPP_TRANSMIT_2D_ 475 #define MPP_TRANSMIT_2D_ mpp_transmit_cmplx8_2d 476 #undef MPP_TRANSMIT_3D_ 477 #define MPP_TRANSMIT_3D_ mpp_transmit_cmplx8_3d 478 #undef MPP_TRANSMIT_4D_ 479 #define MPP_TRANSMIT_4D_ mpp_transmit_cmplx8_4d 480 #undef MPP_TRANSMIT_5D_ 481 #define MPP_TRANSMIT_5D_ mpp_transmit_cmplx8_5d 483 #define MPP_RECV_ mpp_recv_cmplx8 484 #undef MPP_RECV_SCALAR_ 485 #define MPP_RECV_SCALAR_ mpp_recv_cmplx8_scalar 487 #define MPP_RECV_2D_ mpp_recv_cmplx8_2d 489 #define MPP_RECV_3D_ mpp_recv_cmplx8_3d 491 #define MPP_RECV_4D_ mpp_recv_cmplx8_4d 493 #define MPP_RECV_5D_ mpp_recv_cmplx8_5d 495 #define MPP_SEND_ mpp_send_cmplx8 496 #undef MPP_SEND_SCALAR_ 497 #define MPP_SEND_SCALAR_ mpp_send_cmplx8_scalar 499 #define MPP_SEND_2D_ mpp_send_cmplx8_2d 501 #define MPP_SEND_3D_ mpp_send_cmplx8_3d 503 #define MPP_SEND_4D_ mpp_send_cmplx8_4d 505 #define MPP_SEND_5D_ mpp_send_cmplx8_5d 506 #undef MPP_BROADCAST_ 507 #define MPP_BROADCAST_ mpp_broadcast_cmplx8 508 #undef MPP_BROADCAST_SCALAR_ 509 #define MPP_BROADCAST_SCALAR_ mpp_broadcast_cmplx8_scalar 510 #undef MPP_BROADCAST_2D_ 511 #define MPP_BROADCAST_2D_ mpp_broadcast_cmplx8_2d 512 #undef MPP_BROADCAST_3D_ 513 #define MPP_BROADCAST_3D_ mpp_broadcast_cmplx8_3d 514 #undef MPP_BROADCAST_4D_ 515 #define MPP_BROADCAST_4D_ mpp_broadcast_cmplx8_4d 516 #undef MPP_BROADCAST_5D_ 517 #define MPP_BROADCAST_5D_ mpp_broadcast_cmplx8_5d 519 #define MPP_TYPE_ complex(DOUBLE_KIND) 520 #undef MPP_TYPE_BYTELEN_ 521 #define MPP_TYPE_BYTELEN_ 16 522 #undef SHMEM_BROADCAST_ 523 #define SHMEM_BROADCAST_ SHMEM_BROADCAST8 525 #define SHMEM_GET_ SHMEM_GET128 531 #define MPP_TRANSMIT_ mpp_transmit_real4 532 #undef MPP_TRANSMIT_SCALAR_ 533 #define MPP_TRANSMIT_SCALAR_ mpp_transmit_real4_scalar 534 #undef MPP_TRANSMIT_2D_ 535 #define MPP_TRANSMIT_2D_ mpp_transmit_real4_2d 536 #undef MPP_TRANSMIT_3D_ 537 #define MPP_TRANSMIT_3D_ mpp_transmit_real4_3d 538 #undef MPP_TRANSMIT_4D_ 539 #define MPP_TRANSMIT_4D_ mpp_transmit_real4_4d 540 #undef MPP_TRANSMIT_5D_ 541 #define MPP_TRANSMIT_5D_ mpp_transmit_real4_5d 543 #define MPP_RECV_ mpp_recv_real4 544 #undef MPP_RECV_SCALAR_ 545 #define MPP_RECV_SCALAR_ mpp_recv_real4_scalar 547 #define MPP_RECV_2D_ mpp_recv_real4_2d 549 #define MPP_RECV_3D_ mpp_recv_real4_3d 551 #define MPP_RECV_4D_ mpp_recv_real4_4d 553 #define MPP_RECV_5D_ mpp_recv_real4_5d 555 #define MPP_SEND_ mpp_send_real4 556 #undef MPP_SEND_SCALAR_ 557 #define MPP_SEND_SCALAR_ mpp_send_real4_scalar 559 #define MPP_SEND_2D_ mpp_send_real4_2d 561 #define MPP_SEND_3D_ mpp_send_real4_3d 563 #define MPP_SEND_4D_ mpp_send_real4_4d 565 #define MPP_SEND_5D_ mpp_send_real4_5d 566 #undef MPP_BROADCAST_ 567 #define MPP_BROADCAST_ mpp_broadcast_real4 568 #undef MPP_BROADCAST_SCALAR_ 569 #define MPP_BROADCAST_SCALAR_ mpp_broadcast_real4_scalar 570 #undef MPP_BROADCAST_2D_ 571 #define MPP_BROADCAST_2D_ mpp_broadcast_real4_2d 572 #undef MPP_BROADCAST_3D_ 573 #define MPP_BROADCAST_3D_ mpp_broadcast_real4_3d 574 #undef MPP_BROADCAST_4D_ 575 #define MPP_BROADCAST_4D_ mpp_broadcast_real4_4d 576 #undef MPP_BROADCAST_5D_ 577 #define MPP_BROADCAST_5D_ mpp_broadcast_real4_5d 579 #define MPP_TYPE_ real(FLOAT_KIND) 580 #undef MPP_TYPE_BYTELEN_ 581 #define MPP_TYPE_BYTELEN_ 4 582 #undef SHMEM_BROADCAST_ 583 #define SHMEM_BROADCAST_ SHMEM_BROADCAST4 585 #define SHMEM_GET_ SHMEM_GET4 591 #define MPP_TRANSMIT_ mpp_transmit_cmplx4 592 #undef MPP_TRANSMIT_SCALAR_ 593 #define MPP_TRANSMIT_SCALAR_ mpp_transmit_cmplx4_scalar 594 #undef MPP_TRANSMIT_2D_ 595 #define MPP_TRANSMIT_2D_ mpp_transmit_cmplx4_2d 596 #undef MPP_TRANSMIT_3D_ 597 #define MPP_TRANSMIT_3D_ mpp_transmit_cmplx4_3d 598 #undef MPP_TRANSMIT_4D_ 599 #define MPP_TRANSMIT_4D_ mpp_transmit_cmplx4_4d 600 #undef MPP_TRANSMIT_5D_ 601 #define MPP_TRANSMIT_5D_ mpp_transmit_cmplx4_5d 603 #define MPP_RECV_ mpp_recv_cmplx4 604 #undef MPP_RECV_SCALAR_ 605 #define MPP_RECV_SCALAR_ mpp_recv_cmplx4_scalar 607 #define MPP_RECV_2D_ mpp_recv_cmplx4_2d 609 #define MPP_RECV_3D_ mpp_recv_cmplx4_3d 611 #define MPP_RECV_4D_ mpp_recv_cmplx4_4d 613 #define MPP_RECV_5D_ mpp_recv_cmplx4_5d 615 #define MPP_SEND_ mpp_send_cmplx4 616 #undef MPP_SEND_SCALAR_ 617 #define MPP_SEND_SCALAR_ mpp_send_cmplx4_scalar 619 #define MPP_SEND_2D_ mpp_send_cmplx4_2d 621 #define MPP_SEND_3D_ mpp_send_cmplx4_3d 623 #define MPP_SEND_4D_ mpp_send_cmplx4_4d 625 #define MPP_SEND_5D_ mpp_send_cmplx4_5d 626 #undef MPP_BROADCAST_ 627 #define MPP_BROADCAST_ mpp_broadcast_cmplx4 628 #undef MPP_BROADCAST_SCALAR_ 629 #define MPP_BROADCAST_SCALAR_ mpp_broadcast_cmplx4_scalar 630 #undef MPP_BROADCAST_2D_ 631 #define MPP_BROADCAST_2D_ mpp_broadcast_cmplx4_2d 632 #undef MPP_BROADCAST_3D_ 633 #define MPP_BROADCAST_3D_ mpp_broadcast_cmplx4_3d 634 #undef MPP_BROADCAST_4D_ 635 #define MPP_BROADCAST_4D_ mpp_broadcast_cmplx4_4d 636 #undef MPP_BROADCAST_5D_ 637 #define MPP_BROADCAST_5D_ mpp_broadcast_cmplx4_5d 639 #define MPP_TYPE_ complex(FLOAT_KIND) 640 #undef MPP_TYPE_BYTELEN_ 641 #define MPP_TYPE_BYTELEN_ 8 642 #undef SHMEM_BROADCAST_ 643 #define SHMEM_BROADCAST_ SHMEM_BROADCAST4 645 #define SHMEM_GET_ SHMEM_GET64 649 #ifndef no_8byte_integers 651 #define MPP_TRANSMIT_ mpp_transmit_int8 652 #undef MPP_TRANSMIT_SCALAR_ 653 #define MPP_TRANSMIT_SCALAR_ mpp_transmit_int8_scalar 654 #undef MPP_TRANSMIT_2D_ 655 #define MPP_TRANSMIT_2D_ mpp_transmit_int8_2d 656 #undef MPP_TRANSMIT_3D_ 657 #define MPP_TRANSMIT_3D_ mpp_transmit_int8_3d 658 #undef MPP_TRANSMIT_4D_ 659 #define MPP_TRANSMIT_4D_ mpp_transmit_int8_4d 660 #undef MPP_TRANSMIT_5D_ 661 #define MPP_TRANSMIT_5D_ mpp_transmit_int8_5d 663 #define MPP_RECV_ mpp_recv_int8 664 #undef MPP_RECV_SCALAR_ 665 #define MPP_RECV_SCALAR_ mpp_recv_int8_scalar 667 #define MPP_RECV_2D_ mpp_recv_int8_2d 669 #define MPP_RECV_3D_ mpp_recv_int8_3d 671 #define MPP_RECV_4D_ mpp_recv_int8_4d 673 #define MPP_RECV_5D_ mpp_recv_int8_5d 675 #define MPP_SEND_ mpp_send_int8 676 #undef MPP_SEND_SCALAR_ 677 #define MPP_SEND_SCALAR_ mpp_send_int8_scalar 679 #define MPP_SEND_2D_ mpp_send_int8_2d 681 #define MPP_SEND_3D_ mpp_send_int8_3d 683 #define MPP_SEND_4D_ mpp_send_int8_4d 685 #define MPP_SEND_5D_ mpp_send_int8_5d 686 #undef MPP_BROADCAST_ 687 #define MPP_BROADCAST_ mpp_broadcast_int8 688 #undef MPP_BROADCAST_SCALAR_ 689 #define MPP_BROADCAST_SCALAR_ mpp_broadcast_int8_scalar 690 #undef MPP_BROADCAST_2D_ 691 #define MPP_BROADCAST_2D_ mpp_broadcast_int8_2d 692 #undef MPP_BROADCAST_3D_ 693 #define MPP_BROADCAST_3D_ mpp_broadcast_int8_3d 694 #undef MPP_BROADCAST_4D_ 695 #define MPP_BROADCAST_4D_ mpp_broadcast_int8_4d 696 #undef MPP_BROADCAST_5D_ 697 #define MPP_BROADCAST_5D_ mpp_broadcast_int8_5d 699 #define MPP_TYPE_ integer(LONG_KIND) 700 #undef MPP_TYPE_BYTELEN_ 701 #define MPP_TYPE_BYTELEN_ 8 702 #undef SHMEM_BROADCAST_ 703 #define SHMEM_BROADCAST_ SHMEM_BROADCAST8 705 #define SHMEM_GET_ SHMEM_GET8 710 #define MPP_TRANSMIT_ mpp_transmit_int4 711 #undef MPP_TRANSMIT_SCALAR_ 712 #define MPP_TRANSMIT_SCALAR_ mpp_transmit_int4_scalar 713 #undef MPP_TRANSMIT_2D_ 714 #define MPP_TRANSMIT_2D_ mpp_transmit_int4_2d 715 #undef MPP_TRANSMIT_3D_ 716 #define MPP_TRANSMIT_3D_ mpp_transmit_int4_3d 717 #undef MPP_TRANSMIT_4D_ 718 #define MPP_TRANSMIT_4D_ mpp_transmit_int4_4d 719 #undef MPP_TRANSMIT_5D_ 720 #define MPP_TRANSMIT_5D_ mpp_transmit_int4_5d 722 #define MPP_RECV_ mpp_recv_int4 723 #undef MPP_RECV_SCALAR_ 724 #define MPP_RECV_SCALAR_ mpp_recv_int4_scalar 726 #define MPP_RECV_2D_ mpp_recv_int4_2d 728 #define MPP_RECV_3D_ mpp_recv_int4_3d 730 #define MPP_RECV_4D_ mpp_recv_int4_4d 732 #define MPP_RECV_5D_ mpp_recv_int4_5d 734 #define MPP_SEND_ mpp_send_int4 735 #undef MPP_SEND_SCALAR_ 736 #define MPP_SEND_SCALAR_ mpp_send_int4_scalar 738 #define MPP_SEND_2D_ mpp_send_int4_2d 740 #define MPP_SEND_3D_ mpp_send_int4_3d 742 #define MPP_SEND_4D_ mpp_send_int4_4d 744 #define MPP_SEND_5D_ mpp_send_int4_5d 745 #undef MPP_BROADCAST_ 746 #define MPP_BROADCAST_ mpp_broadcast_int4 747 #undef MPP_BROADCAST_SCALAR_ 748 #define MPP_BROADCAST_SCALAR_ mpp_broadcast_int4_scalar 749 #undef MPP_BROADCAST_2D_ 750 #define MPP_BROADCAST_2D_ mpp_broadcast_int4_2d 751 #undef MPP_BROADCAST_3D_ 752 #define MPP_BROADCAST_3D_ mpp_broadcast_int4_3d 753 #undef MPP_BROADCAST_4D_ 754 #define MPP_BROADCAST_4D_ mpp_broadcast_int4_4d 755 #undef MPP_BROADCAST_5D_ 756 #define MPP_BROADCAST_5D_ mpp_broadcast_int4_5d 758 #define MPP_TYPE_ integer(INT_KIND) 759 #undef MPP_TYPE_BYTELEN_ 760 #define MPP_TYPE_BYTELEN_ 4 761 #undef SHMEM_BROADCAST_ 762 #define SHMEM_BROADCAST_ SHMEM_BROADCAST4 764 #define SHMEM_GET_ SHMEM_GET4 767 #ifndef no_8byte_integers 769 #define MPP_TRANSMIT_ mpp_transmit_logical8 770 #undef MPP_TRANSMIT_SCALAR_ 771 #define MPP_TRANSMIT_SCALAR_ mpp_transmit_logical8_scalar 772 #undef MPP_TRANSMIT_2D_ 773 #define MPP_TRANSMIT_2D_ mpp_transmit_logical8_2d 774 #undef MPP_TRANSMIT_3D_ 775 #define MPP_TRANSMIT_3D_ mpp_transmit_logical8_3d 776 #undef MPP_TRANSMIT_4D_ 777 #define MPP_TRANSMIT_4D_ mpp_transmit_logical8_4d 778 #undef MPP_TRANSMIT_5D_ 779 #define MPP_TRANSMIT_5D_ mpp_transmit_logical8_5d 781 #define MPP_RECV_ mpp_recv_logical8 782 #undef MPP_RECV_SCALAR_ 783 #define MPP_RECV_SCALAR_ mpp_recv_logical8_scalar 785 #define MPP_RECV_2D_ mpp_recv_logical8_2d 787 #define MPP_RECV_3D_ mpp_recv_logical8_3d 789 #define MPP_RECV_4D_ mpp_recv_logical8_4d 791 #define MPP_RECV_5D_ mpp_recv_logical8_5d 793 #define MPP_SEND_ mpp_send_logical8 794 #undef MPP_SEND_SCALAR_ 795 #define MPP_SEND_SCALAR_ mpp_send_logical8_scalar 797 #define MPP_SEND_2D_ mpp_send_logical8_2d 799 #define MPP_SEND_3D_ mpp_send_logical8_3d 801 #define MPP_SEND_4D_ mpp_send_logical8_4d 803 #define MPP_SEND_5D_ mpp_send_logical8_5d 804 #undef MPP_BROADCAST_ 805 #define MPP_BROADCAST_ mpp_broadcast_logical8 806 #undef MPP_BROADCAST_SCALAR_ 807 #define MPP_BROADCAST_SCALAR_ mpp_broadcast_logical8_scalar 808 #undef MPP_BROADCAST_2D_ 809 #define MPP_BROADCAST_2D_ mpp_broadcast_logical8_2d 810 #undef MPP_BROADCAST_3D_ 811 #define MPP_BROADCAST_3D_ mpp_broadcast_logical8_3d 812 #undef MPP_BROADCAST_4D_ 813 #define MPP_BROADCAST_4D_ mpp_broadcast_logical8_4d 814 #undef MPP_BROADCAST_5D_ 815 #define MPP_BROADCAST_5D_ mpp_broadcast_logical8_5d 817 #define MPP_TYPE_ logical(LONG_KIND) 818 #undef MPP_TYPE_BYTELEN_ 819 #define MPP_TYPE_BYTELEN_ 8 820 #undef SHMEM_BROADCAST_ 821 #define SHMEM_BROADCAST_ SHMEM_BROADCAST8 823 #define SHMEM_GET_ SHMEM_GET8 828 #define MPP_TRANSMIT_ mpp_transmit_logical4 829 #undef MPP_TRANSMIT_SCALAR_ 830 #define MPP_TRANSMIT_SCALAR_ mpp_transmit_logical4_scalar 831 #undef MPP_TRANSMIT_2D_ 832 #define MPP_TRANSMIT_2D_ mpp_transmit_logical4_2d 833 #undef MPP_TRANSMIT_3D_ 834 #define MPP_TRANSMIT_3D_ mpp_transmit_logical4_3d 835 #undef MPP_TRANSMIT_4D_ 836 #define MPP_TRANSMIT_4D_ mpp_transmit_logical4_4d 837 #undef MPP_TRANSMIT_5D_ 838 #define MPP_TRANSMIT_5D_ mpp_transmit_logical4_5d 840 #define MPP_RECV_ mpp_recv_logical4 841 #undef MPP_RECV_SCALAR_ 842 #define MPP_RECV_SCALAR_ mpp_recv_logical4_scalar 844 #define MPP_RECV_2D_ mpp_recv_logical4_2d 846 #define MPP_RECV_3D_ mpp_recv_logical4_3d 848 #define MPP_RECV_4D_ mpp_recv_logical4_4d 850 #define MPP_RECV_5D_ mpp_recv_logical4_5d 852 #define MPP_SEND_ mpp_send_logical4 853 #undef MPP_SEND_SCALAR_ 854 #define MPP_SEND_SCALAR_ mpp_send_logical4_scalar 856 #define MPP_SEND_2D_ mpp_send_logical4_2d 858 #define MPP_SEND_3D_ mpp_send_logical4_3d 860 #define MPP_SEND_4D_ mpp_send_logical4_4d 862 #define MPP_SEND_5D_ mpp_send_logical4_5d 863 #undef MPP_BROADCAST_ 864 #define MPP_BROADCAST_ mpp_broadcast_logical4 865 #undef MPP_BROADCAST_SCALAR_ 866 #define MPP_BROADCAST_SCALAR_ mpp_broadcast_logical4_scalar 867 #undef MPP_BROADCAST_2D_ 868 #define MPP_BROADCAST_2D_ mpp_broadcast_logical4_2d 869 #undef MPP_BROADCAST_3D_ 870 #define MPP_BROADCAST_3D_ mpp_broadcast_logical4_3d 871 #undef MPP_BROADCAST_4D_ 872 #define MPP_BROADCAST_4D_ mpp_broadcast_logical4_4d 873 #undef MPP_BROADCAST_5D_ 874 #define MPP_BROADCAST_5D_ mpp_broadcast_logical4_5d 876 #define MPP_TYPE_ logical(INT_KIND) 877 #undef MPP_TYPE_BYTELEN_ 878 #define MPP_TYPE_BYTELEN_ 4 879 #undef SHMEM_BROADCAST_ 880 #define SHMEM_BROADCAST_ SHMEM_BROADCAST4 882 #define SHMEM_GET_ SHMEM_GET4 885 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
887 ! GLOBAL REDUCTION ROUTINES: mpp_max, mpp_sum, mpp_min !
889 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
891 #undef MPP_REDUCE_0D_ 892 #define MPP_REDUCE_0D_ mpp_max_real8_0d 893 #undef MPP_REDUCE_1D_ 894 #define MPP_REDUCE_1D_ mpp_max_real8_1d 896 #define MPP_TYPE_ real(DOUBLE_KIND) 897 #undef MPP_TYPE_BYTELEN_ 898 #define MPP_TYPE_BYTELEN_ 8 900 #define SHMEM_REDUCE_ SHMEM_REAL8_MAX_TO_ALL 904 #undef MPP_REDUCE_0D_ 905 #define MPP_REDUCE_0D_ mpp_max_real4_0d 906 #undef MPP_REDUCE_1D_ 907 #define MPP_REDUCE_1D_ mpp_max_real4_1d 909 #define MPP_TYPE_ real(FLOAT_KIND) 910 #undef MPP_TYPE_BYTELEN_ 911 #define MPP_TYPE_BYTELEN_ 4 913 #define SHMEM_REDUCE_ SHMEM_REAL4_MAX_TO_ALL 917 #ifndef no_8byte_integers 918 #undef MPP_REDUCE_0D_ 919 #define MPP_REDUCE_0D_ mpp_max_int8_0d 920 #undef MPP_REDUCE_1D_ 921 #define MPP_REDUCE_1D_ mpp_max_int8_1d 923 #define MPP_TYPE_ integer(LONG_KIND) 924 #undef MPP_TYPE_BYTELEN_ 925 #define MPP_TYPE_BYTELEN_ 8 927 #define SHMEM_REDUCE_ SHMEM_INT8_MAX_TO_ALL 931 #undef MPP_REDUCE_0D_ 932 #define MPP_REDUCE_0D_ mpp_max_int4_0d 933 #undef MPP_REDUCE_1D_ 934 #define MPP_REDUCE_1D_ mpp_max_int4_1d 936 #define MPP_TYPE_ integer(INT_KIND) 937 #undef MPP_TYPE_BYTELEN_ 938 #define MPP_TYPE_BYTELEN_ 4 940 #define SHMEM_REDUCE_ SHMEM_INT4_MAX_TO_ALL 943 #undef MPP_REDUCE_0D_ 944 #define MPP_REDUCE_0D_ mpp_min_real8_0d 945 #undef MPP_REDUCE_1D_ 946 #define MPP_REDUCE_1D_ mpp_min_real8_1d 948 #define MPP_TYPE_ real(DOUBLE_KIND) 949 #undef MPP_TYPE_BYTELEN_ 950 #define MPP_TYPE_BYTELEN_ 8 952 #define SHMEM_REDUCE_ SHMEM_REAL8_MIN_TO_ALL 956 #undef MPP_REDUCE_0D_ 957 #define MPP_REDUCE_0D_ mpp_min_real4_0d 958 #undef MPP_REDUCE_1D_ 959 #define MPP_REDUCE_1D_ mpp_min_real4_1d 961 #define MPP_TYPE_ real(FLOAT_KIND) 962 #undef MPP_TYPE_BYTELEN_ 963 #define MPP_TYPE_BYTELEN_ 4 965 #define SHMEM_REDUCE_ SHMEM_REAL4_MIN_TO_ALL 969 #ifndef no_8byte_integers 970 #undef MPP_REDUCE_0D_ 971 #define MPP_REDUCE_0D_ mpp_min_int8_0d 972 #undef MPP_REDUCE_1D_ 973 #define MPP_REDUCE_1D_ mpp_min_int8_1d 975 #define MPP_TYPE_ integer(LONG_KIND) 976 #undef MPP_TYPE_BYTELEN_ 977 #define MPP_TYPE_BYTELEN_ 8 979 #define SHMEM_REDUCE_ SHMEM_INT8_MIN_TO_ALL 983 #undef MPP_REDUCE_0D_ 984 #define MPP_REDUCE_0D_ mpp_min_int4_0d 985 #undef MPP_REDUCE_1D_ 986 #define MPP_REDUCE_1D_ mpp_min_int4_1d 988 #define MPP_TYPE_ integer(INT_KIND) 989 #undef MPP_TYPE_BYTELEN_ 990 #define MPP_TYPE_BYTELEN_ 4 992 #define SHMEM_REDUCE_ SHMEM_INT4_MIN_TO_ALL 996 #define MPP_SUM_ mpp_sum_real8 997 #undef MPP_SUM_SCALAR_ 998 #define MPP_SUM_SCALAR_ mpp_sum_real8_scalar 1000 #define MPP_SUM_2D_ mpp_sum_real8_2d 1002 #define MPP_SUM_3D_ mpp_sum_real8_3d 1004 #define MPP_SUM_4D_ mpp_sum_real8_4d 1006 #define MPP_SUM_5D_ mpp_sum_real8_5d 1008 #define MPP_TYPE_ real(DOUBLE_KIND) 1010 #define SHMEM_SUM_ SHMEM_REAL8_SUM_TO_ALL 1011 #undef MPP_TYPE_BYTELEN_ 1012 #define MPP_TYPE_BYTELEN_ 8 1017 #define MPP_SUM_ mpp_sum_cmplx8 1018 #undef MPP_SUM_SCALAR_ 1019 #define MPP_SUM_SCALAR_ mpp_sum_cmplx8_scalar 1021 #define MPP_SUM_2D_ mpp_sum_cmplx8_2d 1023 #define MPP_SUM_3D_ mpp_sum_cmplx8_3d 1025 #define MPP_SUM_4D_ mpp_sum_cmplx8_4d 1027 #define MPP_SUM_5D_ mpp_sum_cmplx8_5d 1029 #define MPP_TYPE_ complex(DOUBLE_KIND) 1031 #define SHMEM_SUM_ SHMEM_COMP8_SUM_TO_ALL 1032 #undef MPP_TYPE_BYTELEN_ 1033 #define MPP_TYPE_BYTELEN_ 16 1039 #define MPP_SUM_ mpp_sum_real4 1040 #undef MPP_SUM_SCALAR_ 1041 #define MPP_SUM_SCALAR_ mpp_sum_real4_scalar 1043 #define MPP_SUM_2D_ mpp_sum_real4_2d 1045 #define MPP_SUM_3D_ mpp_sum_real4_3d 1047 #define MPP_SUM_4D_ mpp_sum_real4_4d 1049 #define MPP_SUM_5D_ mpp_sum_real4_5d 1051 #define MPP_TYPE_ real(FLOAT_KIND) 1053 #define SHMEM_SUM_ SHMEM_REAL4_SUM_TO_ALL 1054 #undef MPP_TYPE_BYTELEN_ 1055 #define MPP_TYPE_BYTELEN_ 4 1061 #define MPP_SUM_ mpp_sum_cmplx4 1062 #undef MPP_SUM_SCALAR_ 1063 #define MPP_SUM_SCALAR_ mpp_sum_cmplx4_scalar 1065 #define MPP_SUM_2D_ mpp_sum_cmplx4_2d 1067 #define MPP_SUM_3D_ mpp_sum_cmplx4_3d 1069 #define MPP_SUM_4D_ mpp_sum_cmplx4_4d 1071 #define MPP_SUM_5D_ mpp_sum_cmplx4_5d 1073 #define MPP_TYPE_ complex(FLOAT_KIND) 1075 #define SHMEM_SUM_ SHMEM_COMP4_SUM_TO_ALL 1076 #undef MPP_TYPE_BYTELEN_ 1077 #define MPP_TYPE_BYTELEN_ 8 1081 #ifndef no_8byte_integers 1083 #define MPP_SUM_ mpp_sum_int8 1084 #undef MPP_SUM_SCALAR_ 1085 #define MPP_SUM_SCALAR_ mpp_sum_int8_scalar 1087 #define MPP_SUM_2D_ mpp_sum_int8_2d 1089 #define MPP_SUM_3D_ mpp_sum_int8_3d 1091 #define MPP_SUM_4D_ mpp_sum_int8_4d 1093 #define MPP_SUM_5D_ mpp_sum_int8_5d 1095 #define MPP_TYPE_ integer(LONG_KIND) 1097 #define SHMEM_SUM_ SHMEM_INT8_SUM_TO_ALL 1098 #undef MPP_TYPE_BYTELEN_ 1099 #define MPP_TYPE_BYTELEN_ 8 1104 #define MPP_SUM_ mpp_sum_int4 1105 #undef MPP_SUM_SCALAR_ 1106 #define MPP_SUM_SCALAR_ mpp_sum_int4_scalar 1108 #define MPP_SUM_2D_ mpp_sum_int4_2d 1110 #define MPP_SUM_3D_ mpp_sum_int4_3d 1112 #define MPP_SUM_4D_ mpp_sum_int4_4d 1114 #define MPP_SUM_5D_ mpp_sum_int4_5d 1116 #define MPP_TYPE_ integer(INT_KIND) 1118 #define SHMEM_SUM_ SHMEM_INT4_SUM_TO_ALL 1119 #undef MPP_TYPE_BYTELEN_ 1120 #define MPP_TYPE_BYTELEN_ 4 1123 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1125 ! SCATTER AND GATHER ROUTINES: mpp_alltoall !
1127 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1129 #undef MPP_ALLTOALL_ 1130 #undef MPP_ALLTOALLV_ 1132 #undef MPP_TYPE_BYTELEN_ 1134 #define MPP_ALLTOALL_ mpp_alltoall_int4 1135 #define MPP_ALLTOALLV_ mpp_alltoall_int4_v 1136 #define MPP_TYPE_ integer(INT_KIND) 1137 #define MPP_TYPE_BYTELEN_ 4 1138 #define MPI_TYPE_ MPI_INTEGER4 1141 #undef MPP_ALLTOALL_ 1142 #undef MPP_ALLTOALLV_ 1144 #undef MPP_TYPE_BYTELEN_ 1146 #define MPP_ALLTOALL_ mpp_alltoall_int8 1147 #define MPP_ALLTOALLV_ mpp_alltoall_int8_v 1148 #define MPP_TYPE_ integer(LONG_KIND) 1149 #define MPP_TYPE_BYTELEN_ 8 1150 #define MPI_TYPE_ MPI_INTEGER8 1153 #undef MPP_ALLTOALL_ 1154 #undef MPP_ALLTOALLV_ 1156 #undef MPP_TYPE_BYTELEN_ 1158 #define MPP_ALLTOALL_ mpp_alltoall_real4 1159 #define MPP_ALLTOALLV_ mpp_alltoall_real4_v 1160 #define MPP_TYPE_ real(FLOAT_KIND) 1161 #define MPP_TYPE_BYTELEN_ 4 1162 #define MPI_TYPE_ MPI_REAL4 1165 #undef MPP_ALLTOALL_ 1166 #undef MPP_ALLTOALLV_ 1168 #undef MPP_TYPE_BYTELEN_ 1170 #define MPP_ALLTOALL_ mpp_alltoall_real8 1171 #define MPP_ALLTOALLV_ mpp_alltoall_real8_v 1172 #define MPP_TYPE_ real(DOUBLE_KIND) 1173 #define MPP_TYPE_BYTELEN_ 8 1174 #define MPI_TYPE_ MPI_REAL8 1177 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1179 ! DATA TRANSFER TYPES: mpp_type_create, mpp_type_free !
1181 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1183 #define MPP_TYPE_CREATE_ mpp_type_create_int4 1184 #define MPP_TYPE_ integer(INT_KIND) 1185 #define MPI_TYPE_ MPI_INTEGER4 1188 #define MPP_TYPE_CREATE_ mpp_type_create_int8 1189 #define MPP_TYPE_ integer(LONG_KIND) 1190 #define MPI_TYPE_ MPI_INTEGER8 1193 #define MPP_TYPE_CREATE_ mpp_type_create_real4 1194 #define MPP_TYPE_ real(FLOAT_KIND) 1195 #define MPI_TYPE_ MPI_REAL4 1198 #define MPP_TYPE_CREATE_ mpp_type_create_real8 1199 #define MPP_TYPE_ real(DOUBLE_KIND) 1200 #define MPI_TYPE_ MPI_REAL8 1203 #define MPP_TYPE_CREATE_ mpp_type_create_logical4 1204 #define MPP_TYPE_ logical(INT_KIND) 1205 #define MPI_TYPE_ MPI_INTEGER4 1208 #define MPP_TYPE_CREATE_ mpp_type_create_logical8 1209 #define MPP_TYPE_ logical(LONG_KIND) 1210 #define MPI_TYPE_ MPI_INTEGER8 1213 ! Clear preprocessor flags
1216 #undef MPP_TYPE_CREATE_ 1218 subroutine mpp_type_free(dtype)
1219 type(mpp_type), pointer, intent(inout) :: dtype
1221 call
mpp_error(FATAL,
'MPP_TYPE_FREE: Unsupported for SHMEM.')
1222 end subroutine mpp_type_free
1224 !#######################################################################
1225 !these local versions are written for grouping into shmem_integer_wait
1226 subroutine shmem_int4_wait_local( ivar, cmp_value )
1228 !dir$ ATTRIBUTE FORCEINLINE shmem_int4_wait_local
1230 !dir$ INLINEALWAYS shmem_int4_wait_local
1234 call SHMEM_INT4_WAIT( ivar, cmp_value )
1236 end subroutine shmem_int4_wait_local
1238 subroutine shmem_int8_wait_local( ivar, cmp_value )
1240 !dir$ ATTRIBUTE FORCEINLINE shmem_int4_wait_local
1242 !dir$ INLINEALWAYS shmem_int4_wait_local
1246 call SHMEM_INT8_WAIT( ivar, cmp_value )
1248 end subroutine shmem_int8_wait_local
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT get_len end if return end subroutine MPP_TRANSMIT_ ! MPP_BROADCAST ! subroutine but that doesn t allow !broadcast to a subset of PEs This version will
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT get_len end if return end subroutine MPP_TRANSMIT_ ! MPP_BROADCAST ! subroutine but that doesn t allow !broadcast to a subset of PEs This version and mpp_transmit will remain !backward compatible intent(inout) i18
*f90 *************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************subroutine MPP_UPDATE_NEST_FINE_2D_(field, nest_domain, wbuffer, ebuffer, sbuffer, nbuffer, &flags, complete, position, extra_halo, name, tile_count) MPP_TYPE_, intent(in) ::field(:,:) type(nest_domain_type), intent(inout) ::nest_domain MPP_TYPE_, intent(inout) ::wbuffer(:,:) MPP_TYPE_, intent(inout) ::ebuffer(:,:) MPP_TYPE_, intent(inout) ::sbuffer(:,:) MPP_TYPE_, intent(inout) ::nbuffer(:,:) integer, intent(in), optional ::flags logical, intent(in), optional ::complete integer, intent(in), optional ::position integer, intent(in), optional ::extra_halo character(len= *), intent(in), optional ::name integer, intent(in), optional ::tile_count MPP_TYPE_ ::field3D(size(field, 1), size(field, 2), 1) MPP_TYPE_ ::wbuffer3D(size(wbuffer, 1), size(wbuffer, 2), 1) MPP_TYPE_ ::ebuffer3D(size(ebuffer, 1), size(ebuffer, 2), 1) MPP_TYPE_ ::sbuffer3D(size(sbuffer, 1), size(sbuffer, 2), 1) MPP_TYPE_ ::nbuffer3D(size(nbuffer, 1), size(nbuffer, 2), 1) pointer(ptr, field3D) pointer(ptr_w, wbuffer3D) pointer(ptr_e, ebuffer3D) pointer(ptr_s, sbuffer3D) pointer(ptr_n, nbuffer3D) ptr=LOC(field) ptr_w=LOC(wbuffer) ptr_e=LOC(ebuffer) ptr_s=LOC(sbuffer) ptr_n=LOC(nbuffer) call mpp_update_nest_fine(field3D, nest_domain, wbuffer3D, ebuffer3D, sbuffer3D, nbuffer3D, &flags, complete, position, extra_halo, name, tile_count) returnend subroutine MPP_UPDATE_NEST_FINE_2D_subroutine MPP_UPDATE_NEST_FINE_3D_(field, nest_domain, wbuffer, sbuffer, ebuffer, nbuffer, &flags, complete, position, extra_halo, name, tile_count) MPP_TYPE_, intent(in) ::field(:,:,:) type(nest_domain_type), intent(inout) ::nest_domain MPP_TYPE_, intent(inout) ::wbuffer(:,:,:) MPP_TYPE_, intent(inout) ::ebuffer(:,:,:) MPP_TYPE_, intent(inout) ::sbuffer(:,:,:) MPP_TYPE_, intent(inout) ::nbuffer(:,:,:) integer, intent(in), optional ::flags logical, intent(in), optional ::complete integer, intent(in), optional ::position integer, intent(in), optional ::extra_halo character(len= *), intent(in), optional ::name integer, intent(in), optional ::tile_count MPP_TYPE_ ::d_type type(nestSpec), pointer ::update=> set_mismatch integer ::tile update_position nbuffersz l_size integer
l_size ! loop over number of fields ke do je do i
l_size ! loop over number of fields ke do je do ie to PE
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************subroutine READ_RECORD_CORE_(unit, field, nwords, data, start, axsiz) integer, intent(in) ::unit type(fieldtype), intent(in) ::field integer, intent(in) ::nwords MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in) ::start(:), axsiz(:) integer(SHORT_KIND) ::i2vals(nwords)!rab used in conjunction with transfer intrinsic to determine size of a variable integer(KIND=1) ::one_byte(8) integer ::word_sz!#ifdef __sgi integer(INT_KIND) ::ivals(nwords) real(FLOAT_KIND) ::rvals(nwords)!#else! integer ::ivals(nwords)! real ::rvals(nwords)!#endif real(DOUBLE_KIND) ::r8vals(nwords) pointer(ptr1, i2vals) pointer(ptr2, ivals) pointer(ptr3, rvals) pointer(ptr4, r8vals) if(mpp_io_stack_size< nwords) call mpp_io_set_stack_size(nwords) call mpp_error(FATAL, 'MPP_READ currently requires use_netCDF option') end subroutine READ_RECORD_CORE_ subroutine READ_RECORD_(unit, field, nwords, data, time_level, domain, position, tile_count, start_in, axsiz_in)!routine that is finally called by all mpp_read routines to perform the read!a non-netCDF record contains:! field ID! a set of 4 coordinates(is:ie, js:je) giving the data subdomain! a timelevel and a timestamp(=NULLTIME if field is static)! 3D real data(stored as 1D)!if you are using direct access I/O, the RECL argument to OPEN must be large enough for the above!in a global direct access file, record position on PE is given by %record.!Treatment of timestamp:! We assume that static fields have been passed without a timestamp.! Here that is converted into a timestamp of NULLTIME.! For non-netCDF fields, field is treated no differently, but is written! with a timestamp of NULLTIME. There is no check in the code to prevent! the user from repeatedly writing a static field. integer, intent(in) ::unit, nwords type(fieldtype), intent(in) ::field MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in), optional ::time_level type(domain2D), intent(in), optional ::domain integer, intent(in), optional ::position, tile_count integer, intent(in), optional ::start_in(:), axsiz_in(:) integer, dimension(size(field%axes(:))) ::start, axsiz integer ::tlevel !, subdomain(4) integer ::i, error, is, ie, js, je, isg, ieg, jsg, jeg type(domain2d), pointer ::io_domain=> unit
integer(long_kind) max_ticks
integer, parameter, public long
integer current_peset_num
subroutine, public copy(self, rhs)
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT end
character(len=32) units
No description.
character(len=32) etcfile
integer, parameter, public single
l_size ! loop over number of fields ke do j
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT get_len end if return end subroutine MPP_TRANSMIT_ ! MPP_BROADCAST ! subroutine but that doesn t allow !broadcast to a subset of PEs This version and mpp_transmit will remain !backward compatible intent(inout) MPP_BROADCAST length end if MPP_BROADCAST
l_size ! loop over number of fields ke do je do ie to je n if(.NOT. d_comm%R_do_buf(list)) cycle from_pe
logical module_is_initialized
character(len=input_str_length), dimension(:), allocatable, target, public input_nml_file
character(len=128) version
l_size ! loop over number of fields ke do je do ie to is
type(communicator), dimension(:), allocatable peset
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT get_len end if return end subroutine MPP_TRANSMIT_ ! MPP_BROADCAST ! subroutine but that doesn t allow !broadcast to a subset of PEs This version and mpp_transmit will remain !backward compatible intent(inout) MPP_BROADCAST length
subroutine, private initialize
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************subroutine READ_RECORD_CORE_(unit, field, nwords, data, start, axsiz) integer, intent(in) ::unit type(fieldtype), intent(in) ::field integer, intent(in) ::nwords MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in) ::start(:), axsiz(:) integer(SHORT_KIND) ::i2vals(nwords)!rab used in conjunction with transfer intrinsic to determine size of a variable integer(KIND=1) ::one_byte(8) integer ::word_sz!#ifdef __sgi integer(INT_KIND) ::ivals(nwords) real(FLOAT_KIND) ::rvals(nwords)!#else! integer ::ivals(nwords)! real ::rvals(nwords)!#endif real(DOUBLE_KIND) ::r8vals(nwords) pointer(ptr1, i2vals) pointer(ptr2, ivals) pointer(ptr3, rvals) pointer(ptr4, r8vals) if(mpp_io_stack_size< nwords) call mpp_io_set_stack_size(nwords) call mpp_error(FATAL, 'MPP_READ currently requires use_netCDF option') end subroutine READ_RECORD_CORE_ subroutine READ_RECORD_(unit, field, nwords, data, time_level, domain, position, tile_count, start_in, axsiz_in)!routine that is finally called by all mpp_read routines to perform the read!a non-netCDF record contains:! field ID! a set of 4 coordinates(is:ie, js:je) giving the data subdomain! a timelevel and a timestamp(=NULLTIME if field is static)! 3D real data(stored as 1D)!if you are using direct access I/O, the RECL argument to OPEN must be large enough for the above!in a global direct access file, record position on PE is given by %record.!Treatment of timestamp:! We assume that static fields have been passed without a timestamp.! Here that is converted into a timestamp of NULLTIME.! For non-netCDF fields, field is treated no differently, but is written! with a timestamp of NULLTIME. There is no check in the code to prevent! the user from repeatedly writing a static field. integer, intent(in) ::unit, nwords type(fieldtype), intent(in) ::field MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in), optional ::time_level type(domain2D), intent(in), optional ::domain integer, intent(in), optional ::position, tile_count integer, intent(in), optional ::start_in(:), axsiz_in(:) integer, dimension(size(field%axes(:))) ::start, axsiz integer ::tlevel !, subdomain(4) integer ::i, error, is, ie, js, je, isg, ieg, jsg, jeg type(domain2d), pointer ::io_domain=> tlevel if(PRESENT(start_in) .AND. PRESENT(axsiz_in)) then if(size(start(! the data domain and compute domain must refer to the subdomain being passed ! In this ! since that attempts to gather all data on PE start
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT get_len end if return end subroutine MPP_TRANSMIT_ ! MPP_BROADCAST ! subroutine but that doesn t allow !broadcast to a subset of PEs This version and mpp_transmit will remain !backward compatible intent(inout) & T
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call mpp_error(FATAL, 'MPP_TRANSMIT:you cannot transmit to ANY_PE using MPI.') else if(to_pe.NE.NULL_PE) then !no other valid cases except NULL_PE call mpp_error(FATAL
integer, parameter, public down
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************subroutine READ_RECORD_CORE_(unit, field, nwords, data, start, axsiz) integer, intent(in) ::unit type(fieldtype), intent(in) ::field integer, intent(in) ::nwords MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in) ::start(:), axsiz(:) integer(SHORT_KIND) ::i2vals(nwords)!rab used in conjunction with transfer intrinsic to determine size of a variable integer(KIND=1) ::one_byte(8) integer ::word_sz!#ifdef __sgi integer(INT_KIND) ::ivals(nwords) real(FLOAT_KIND) ::rvals(nwords)!#else! integer ::ivals(nwords)! real ::rvals(nwords)!#endif real(DOUBLE_KIND) ::r8vals(nwords) pointer(ptr1, i2vals) pointer(ptr2, ivals) pointer(ptr3, rvals) pointer(ptr4, r8vals) if(mpp_io_stack_size< nwords) call mpp_io_set_stack_size(nwords) call mpp_error(FATAL, 'MPP_READ currently requires use_netCDF option') end subroutine READ_RECORD_CORE_ subroutine READ_RECORD_(unit, field, nwords, data, time_level, domain, position, tile_count, start_in, axsiz_in)!routine that is finally called by all mpp_read routines to perform the read!a non-netCDF record contains:! field ID! a set of 4 coordinates(is:ie, js:je) giving the data subdomain! a timelevel and a timestamp(=NULLTIME if field is static)! 3D real data(stored as 1D)!if you are using direct access I/O, the RECL argument to OPEN must be large enough for the above!in a global direct access file, record position on PE is given by %record.!Treatment of timestamp:! We assume that static fields have been passed without a timestamp.! Here that is converted into a timestamp of NULLTIME.! For non-netCDF fields, field is treated no differently, but is written! with a timestamp of NULLTIME. There is no check in the code to prevent! the user from repeatedly writing a static field. integer, intent(in) ::unit, nwords type(fieldtype), intent(in) ::field MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in), optional ::time_level type(domain2D), intent(in), optional ::domain integer, intent(in), optional ::position, tile_count integer, intent(in), optional ::start_in(:), axsiz_in(:) integer, dimension(size(field%axes(:))) ::start, axsiz integer ::tlevel !, subdomain(4) integer ::i, error, is, ie, js, je, isg, ieg, jsg, jeg type(domain2d), pointer ::io_domain=> id
integer current_peset_max
logical etc_unit_is_stderr
type(mpp_type_list) datatypes
character(len=32) configfile
logical function received(this, seqno)
type(field_def), target, save root
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************subroutine READ_RECORD_CORE_(unit, field, nwords, data, start, axsiz) integer, intent(in) ::unit type(fieldtype), intent(in) ::field integer, intent(in) ::nwords MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in) ::start(:), axsiz(:) integer(SHORT_KIND) ::i2vals(nwords)!rab used in conjunction with transfer intrinsic to determine size of a variable integer(KIND=1) ::one_byte(8) integer ::word_sz!#ifdef __sgi integer(INT_KIND) ::ivals(nwords) real(FLOAT_KIND) ::rvals(nwords)!#else! integer ::ivals(nwords)! real ::rvals(nwords)!#endif real(DOUBLE_KIND) ::r8vals(nwords) pointer(ptr1, i2vals) pointer(ptr2, ivals) pointer(ptr3, rvals) pointer(ptr4, r8vals) if(mpp_io_stack_size< nwords) call mpp_io_set_stack_size(nwords) call mpp_error(FATAL, 'MPP_READ currently requires use_netCDF option') end subroutine READ_RECORD_CORE_ subroutine READ_RECORD_(unit, field, nwords, data, time_level, domain, position, tile_count, start_in, axsiz_in)!routine that is finally called by all mpp_read routines to perform the read!a non-netCDF record contains:! field ID! a set of 4 coordinates(is:ie, js:je) giving the data subdomain! a timelevel and a timestamp(=NULLTIME if field is static)! 3D real data(stored as 1D)!if you are using direct access I/O, the RECL argument to OPEN must be large enough for the above!in a global direct access file, record position on PE is given by %record.!Treatment of timestamp:! We assume that static fields have been passed without a timestamp.! Here that is converted into a timestamp of NULLTIME.! For non-netCDF fields, field is treated no differently, but is written! with a timestamp of NULLTIME. There is no check in the code to prevent! the user from repeatedly writing a static field. integer, intent(in) ::unit, nwords type(fieldtype), intent(in) ::field MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in), optional ::time_level type(domain2D), intent(in), optional ::domain integer, intent(in), optional ::position, tile_count integer, intent(in), optional ::start_in(:), axsiz_in(:) integer, dimension(size(field%axes(:))) ::start, axsiz integer ::tlevel !, subdomain(4) integer ::i, error, is, ie, js, je, isg, ieg, jsg, jeg type(domain2d), pointer ::io_domain=> tlevel if(PRESENT(start_in) .AND. PRESENT(axsiz_in)) then if(size(start(! the data domain and compute domain must refer to the subdomain being passed ! In this ! since that attempts to gather all data on PE size(field%axes(:)) axsiz(i)
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT get_len end if return end subroutine MPP_TRANSMIT_ ! MPP_BROADCAST ! subroutine but that doesn t allow !broadcast to a subset of PEs This version and mpp_transmit will remain !backward compatible intent(inout) a
integer(long_kind), dimension(1) word
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT get_len end if return end subroutine MPP_TRANSMIT_ ! MPP_BROADCAST ! subroutine but that doesn t allow !broadcast to a subset of PEs This version and mpp_transmit will remain !backward compatible intent(inout) i6
real(r8), dimension(cast_m, cast_n) t
integer, dimension(:), allocatable pelist
*f90 *************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If not
integer(long_kind) ticks_per_sec
integer(long_kind) start_tick
type(mpp_type), target, public mpp_byte
type(clock), dimension(max_clocks), save clocks
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call tick
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT get_len end if return end subroutine MPP_TRANSMIT_ ! MPP_BROADCAST ! subroutine but that doesn t allow !broadcast to a subset of PEs This version and mpp_transmit will remain !backward compatible intent(inout) MPP_BROADCAST begin