3 !***********************************************************************
4 !* GNU Lesser General Public License
6 !* This file
is part of the GFDL Flexible Modeling System (FMS).
8 !* FMS
is free software: you can redistribute it and/or modify it under
9 !* the terms of the GNU Lesser General Public License as published by
10 !* the Free Software Foundation, either
version 3 of the License, or (at
11 !* your option) any later
version.
13 !* FMS
is distributed in the hope that it
will be useful, but WITHOUT
14 !* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 !* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 !* You should have
received a copy of the GNU Lesser General Public
19 !* License along with FMS. If
not, see <http:
20 !***********************************************************************
22 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
24 ! ROUTINES TO INITIALIZE/FINALIZE MPP MODULE: mpp_init, mpp_exit !
26 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
27 ! subroutine mpp_init( flags, in,
out, err, log )
28 !
integer, optional, intent(in) :: flags, in,
out, err, log
29 subroutine mpp_init( flags,localcomm )
30 integer, optional, intent(in) :: flags
31 integer, optional, intent(in) :: localcomm !
dummy here, used only in MPI
33 logical :: opened, existed
41 !PEsets: make defaults illegal
45 !0=
single-
PE, initialized so that count returns 1
47 allocate(
peset(0)%list(1) )
57 clock0 = mpp_clock_id(
'Total runtime', flags=MPP_CLOCK_SYNC )
59 ! Initialize mpp_datatypes
60 ! NOTE: mpp_datatypes
is unused in serial mode;
this is an
empty list
65 ! Create the bytestream (default) mpp_datatype
78 if( PRESENT(flags) )then
79 debug = flags.EQ.MPP_DEBUG
83 call mpp_init_logfile()
87 #ifdef INTERNAL_FILE_NML 93 inquire( unit_nml,OPENED=opened )
97 open(unit_nml,file=
'input.nml', iostat=io_status)
98 read(unit_nml,mpp_nml,iostat=io_status)
102 if (io_status > 0) then
103 call
mpp_error(FATAL,
'=>mpp_init: Error reading input.nml')
106 ! non-
root pe messages written to other location than stdout()
114 inquire(file=
etcfile, exist=existed)
120 !
if optional argument logunit=stdout, write messages to stdout instead.
121 !
if specifying non-defaults, you must specify
units not yet in use.
122 !
if( PRESENT(in) )then
123 ! inquire(
unit=in, opened=opened )
124 !
if( opened )call
mpp_error( FATAL, 'MPP_INIT: unable to open stdin.' )
127 !
if( PRESENT(
out) )then
128 ! inquire(
unit=
out, opened=opened )
129 !
if( opened )call
mpp_error( FATAL, 'MPP_INIT: unable to open stdout.' )
132 !
if( PRESENT(err) )then
133 ! inquire(
unit=err, opened=opened )
134 !
if( opened )call
mpp_error( FATAL, 'MPP_INIT: unable to open stderr.' )
138 !
if( PRESENT(log) )then
139 ! inquire(
unit=log, opened=opened )
140 !
if( opened .AND. log.NE.
out_unit )call
mpp_error( FATAL, 'MPP_INIT: unable to open stdlog.' )
143 !!
log_unit can be written to only from
root_pe, all others write to stdout
146 !
if( opened )call
mpp_error( FATAL, 'MPP_INIT: specified
unit for stdlog already in use.' )
157 write( logunit,'(/
a)' )'MPP
module '
158 write( logunit,'(
a,
i6)' )'MPP started with NPES=',
npes 159 write( logunit,'(
a)' )'Using
no library for message passing...'
160 write( logunit, '(a26,es12.4,a6,i10,a11)' ) &
162 write( logunit, '(a23,es12.4,a6,i20,a7)' ) &
166 call mpp_clock_begin(
clock0)
169 end subroutine mpp_init
171 !
####################################################################### 172 !to be called at the
end of
a run
173 subroutine mpp_exit()
175 real ::
t,
tmin, tmax, tavg, tstd
176 real ::
m, mmin, mmax, mavg, mstd, t_total
180 call mpp_set_current_pelist()
181 call mpp_clock_end(
clock0)
186 call sum_clock_data; call dump_clock_summary
189 write(
out_unit,'(/
a,
i6,
a)' ) 'Tabulating mpp_clock statistics across ',
npes, ' PEs...'
191 write(
out_unit,'(
a)' )' ... see mpp_clock.
out.
#### for details on individual PEs.' 192 write(
out_unit,
'(/32x,a)' )
' tmin tmax tavg tstd tfrac grain pemin pemax' 201 !times between mpp_clock ticks
204 tmax =
t; call mpp_max(tmax)
205 tavg =
t; call mpp_sum(tavg); tavg = tavg/mpp_npes()
206 tstd = (
t-tavg)**2; call mpp_sum(tstd); tstd = sqrt( tstd/mpp_npes() )
214 '
tmin tmax tavg tstd mmin mmax mavg mstd mavg/tavg'
217 !messages: bytelengths and times
219 do
j = 1,MAX_EVENT_TYPES
226 mmin =
m; call mpp_min(mmin)
227 mmax =
m; call mpp_max(mmax)
228 mavg =
m; call mpp_sum(mavg); mavg = mavg/mpp_npes()
229 mstd = (
m-mavg)**2; call mpp_sum(mstd); mstd = sqrt( mstd/mpp_npes() )
233 tmax =
t; call mpp_max(tmax)
234 tavg =
t; call mpp_sum(tavg); tavg = tavg/mpp_npes()
235 tstd = (
t-tavg)**2; call mpp_sum(tstd); tstd = sqrt( tstd/mpp_npes() )
238 tmin, tmax, tavg, tstd, mmin, mmax, mavg, mstd, mavg/tavg
251 call mpp_set_current_pelist()
257 end subroutine mpp_exit
259 !
####################################################################### 260 !---
dummy routine, should never been called -------------------------
261 subroutine mpp_malloc( ptr, newlen,
len )
265 pointer( ptr,
dummy )
267 call
mpp_error(FATAL,
'mpp_malloc: Should not been called when lib_SMA is not used')
270 end subroutine mpp_malloc
272 !#######################################################################
273 !
set the mpp_stack variable to be at least
n LONG words
long 274 subroutine mpp_set_stack_size(
n)
279 if( .NOT.allocated(mpp_stack) )then
280 allocate( mpp_stack(
n) )
284 write(
text,
'(i8)' )
n 288 end subroutine mpp_set_stack_size
291 character(
len=*), intent(inout) :: data(:)
297 end subroutine mpp_broadcast_char
300 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
302 ! BASIC MESSAGE PASSING ROUTINE: mpp_transmit !
304 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
307 #define MPP_TRANSMIT_ mpp_transmit_real8
308 #
undef MPP_TRANSMIT_SCALAR_
309 #define MPP_TRANSMIT_SCALAR_ mpp_transmit_real8_scalar
310 #
undef MPP_TRANSMIT_2D_
311 #define MPP_TRANSMIT_2D_ mpp_transmit_real8_2d
312 #
undef MPP_TRANSMIT_3D_
313 #define MPP_TRANSMIT_3D_ mpp_transmit_real8_3d
314 #
undef MPP_TRANSMIT_4D_
315 #define MPP_TRANSMIT_4D_ mpp_transmit_real8_4d
316 #
undef MPP_TRANSMIT_5D_
317 #define MPP_TRANSMIT_5D_ mpp_transmit_real8_5d
319 #define MPP_RECV_ mpp_recv_real8
320 #
undef MPP_RECV_SCALAR_
321 #define MPP_RECV_SCALAR_ mpp_recv_real8_scalar
323 #define MPP_RECV_2D_ mpp_recv_real8_2d
325 #define MPP_RECV_3D_ mpp_recv_real8_3d
327 #define MPP_RECV_4D_ mpp_recv_real8_4d
329 #define MPP_RECV_5D_ mpp_recv_real8_5d
331 #define MPP_SEND_ mpp_send_real8
332 #
undef MPP_SEND_SCALAR_
333 #define MPP_SEND_SCALAR_ mpp_send_real8_scalar
335 #define MPP_SEND_2D_ mpp_send_real8_2d
337 #define MPP_SEND_3D_ mpp_send_real8_3d
339 #define MPP_SEND_4D_ mpp_send_real8_4d
341 #define MPP_SEND_5D_ mpp_send_real8_5d
344 #
undef MPP_BROADCAST_SCALAR_
345 #define MPP_BROADCAST_SCALAR_ mpp_broadcast_real8_scalar
346 #
undef MPP_BROADCAST_2D_
347 #define MPP_BROADCAST_2D_ mpp_broadcast_real8_2d
348 #
undef MPP_BROADCAST_3D_
349 #define MPP_BROADCAST_3D_ mpp_broadcast_real8_3d
350 #
undef MPP_BROADCAST_4D_
351 #define MPP_BROADCAST_4D_ mpp_broadcast_real8_4d
352 #
undef MPP_BROADCAST_5D_
353 #define MPP_BROADCAST_5D_ mpp_broadcast_real8_5d
356 #
undef MPP_TYPE_BYTELEN_
357 #define MPP_TYPE_BYTELEN_ 8
360 #include <mpp_transmit_nocomm.h>
364 #define MPP_TRANSMIT_ mpp_transmit_cmplx8
365 #
undef MPP_TRANSMIT_SCALAR_
366 #define MPP_TRANSMIT_SCALAR_ mpp_transmit_cmplx8_scalar
367 #
undef MPP_TRANSMIT_2D_
368 #define MPP_TRANSMIT_2D_ mpp_transmit_cmplx8_2d
369 #
undef MPP_TRANSMIT_3D_
370 #define MPP_TRANSMIT_3D_ mpp_transmit_cmplx8_3d
371 #
undef MPP_TRANSMIT_4D_
372 #define MPP_TRANSMIT_4D_ mpp_transmit_cmplx8_4d
373 #
undef MPP_TRANSMIT_5D_
374 #define MPP_TRANSMIT_5D_ mpp_transmit_cmplx8_5d
376 #define MPP_RECV_ mpp_recv_cmplx8
377 #
undef MPP_RECV_SCALAR_
378 #define MPP_RECV_SCALAR_ mpp_recv_cmplx8_scalar
380 #define MPP_RECV_2D_ mpp_recv_cmplx8_2d
382 #define MPP_RECV_3D_ mpp_recv_cmplx8_3d
384 #define MPP_RECV_4D_ mpp_recv_cmplx8_4d
386 #define MPP_RECV_5D_ mpp_recv_cmplx8_5d
388 #define MPP_SEND_ mpp_send_cmplx8
389 #
undef MPP_SEND_SCALAR_
390 #define MPP_SEND_SCALAR_ mpp_send_cmplx8_scalar
392 #define MPP_SEND_2D_ mpp_send_cmplx8_2d
394 #define MPP_SEND_3D_ mpp_send_cmplx8_3d
396 #define MPP_SEND_4D_ mpp_send_cmplx8_4d
398 #define MPP_SEND_5D_ mpp_send_cmplx8_5d
401 #
undef MPP_BROADCAST_SCALAR_
402 #define MPP_BROADCAST_SCALAR_ mpp_broadcast_cmplx8_scalar
403 #
undef MPP_BROADCAST_2D_
404 #define MPP_BROADCAST_2D_ mpp_broadcast_cmplx8_2d
405 #
undef MPP_BROADCAST_3D_
406 #define MPP_BROADCAST_3D_ mpp_broadcast_cmplx8_3d
407 #
undef MPP_BROADCAST_4D_
408 #define MPP_BROADCAST_4D_ mpp_broadcast_cmplx8_4d
409 #
undef MPP_BROADCAST_5D_
410 #define MPP_BROADCAST_5D_ mpp_broadcast_cmplx8_5d
413 #
undef MPP_TYPE_BYTELEN_
414 #define MPP_TYPE_BYTELEN_ 16
417 #include <mpp_transmit_nocomm.h>
421 #define MPP_TRANSMIT_ mpp_transmit_real4
422 #
undef MPP_TRANSMIT_SCALAR_
423 #define MPP_TRANSMIT_SCALAR_ mpp_transmit_real4_scalar
424 #
undef MPP_TRANSMIT_2D_
425 #define MPP_TRANSMIT_2D_ mpp_transmit_real4_2d
426 #
undef MPP_TRANSMIT_3D_
427 #define MPP_TRANSMIT_3D_ mpp_transmit_real4_3d
428 #
undef MPP_TRANSMIT_4D_
429 #define MPP_TRANSMIT_4D_ mpp_transmit_real4_4d
430 #
undef MPP_TRANSMIT_5D_
431 #define MPP_TRANSMIT_5D_ mpp_transmit_real4_5d
433 #define MPP_RECV_ mpp_recv_real4
434 #
undef MPP_RECV_SCALAR_
435 #define MPP_RECV_SCALAR_ mpp_recv_real4_scalar
437 #define MPP_RECV_2D_ mpp_recv_real4_2d
439 #define MPP_RECV_3D_ mpp_recv_real4_3d
441 #define MPP_RECV_4D_ mpp_recv_real4_4d
443 #define MPP_RECV_5D_ mpp_recv_real4_5d
445 #define MPP_SEND_ mpp_send_real4
446 #
undef MPP_SEND_SCALAR_
447 #define MPP_SEND_SCALAR_ mpp_send_real4_scalar
449 #define MPP_SEND_2D_ mpp_send_real4_2d
451 #define MPP_SEND_3D_ mpp_send_real4_3d
453 #define MPP_SEND_4D_ mpp_send_real4_4d
455 #define MPP_SEND_5D_ mpp_send_real4_5d
458 #
undef MPP_BROADCAST_SCALAR_
459 #define MPP_BROADCAST_SCALAR_ mpp_broadcast_real4_scalar
460 #
undef MPP_BROADCAST_2D_
461 #define MPP_BROADCAST_2D_ mpp_broadcast_real4_2d
462 #
undef MPP_BROADCAST_3D_
463 #define MPP_BROADCAST_3D_ mpp_broadcast_real4_3d
464 #
undef MPP_BROADCAST_4D_
465 #define MPP_BROADCAST_4D_ mpp_broadcast_real4_4d
466 #
undef MPP_BROADCAST_5D_
467 #define MPP_BROADCAST_5D_ mpp_broadcast_real4_5d
470 #
undef MPP_TYPE_BYTELEN_
471 #define MPP_TYPE_BYTELEN_ 4
474 #include <mpp_transmit_nocomm.h>
478 #define MPP_TRANSMIT_ mpp_transmit_cmplx4
479 #
undef MPP_TRANSMIT_SCALAR_
480 #define MPP_TRANSMIT_SCALAR_ mpp_transmit_cmplx4_scalar
481 #
undef MPP_TRANSMIT_2D_
482 #define MPP_TRANSMIT_2D_ mpp_transmit_cmplx4_2d
483 #
undef MPP_TRANSMIT_3D_
484 #define MPP_TRANSMIT_3D_ mpp_transmit_cmplx4_3d
485 #
undef MPP_TRANSMIT_4D_
486 #define MPP_TRANSMIT_4D_ mpp_transmit_cmplx4_4d
487 #
undef MPP_TRANSMIT_5D_
488 #define MPP_TRANSMIT_5D_ mpp_transmit_cmplx4_5d
490 #define MPP_RECV_ mpp_recv_cmplx4
491 #
undef MPP_RECV_SCALAR_
492 #define MPP_RECV_SCALAR_ mpp_recv_cmplx4_scalar
494 #define MPP_RECV_2D_ mpp_recv_cmplx4_2d
496 #define MPP_RECV_3D_ mpp_recv_cmplx4_3d
498 #define MPP_RECV_4D_ mpp_recv_cmplx4_4d
500 #define MPP_RECV_5D_ mpp_recv_cmplx4_5d
502 #define MPP_SEND_ mpp_send_cmplx4
503 #
undef MPP_SEND_SCALAR_
504 #define MPP_SEND_SCALAR_ mpp_send_cmplx4_scalar
506 #define MPP_SEND_2D_ mpp_send_cmplx4_2d
508 #define MPP_SEND_3D_ mpp_send_cmplx4_3d
510 #define MPP_SEND_4D_ mpp_send_cmplx4_4d
512 #define MPP_SEND_5D_ mpp_send_cmplx4_5d
515 #
undef MPP_BROADCAST_SCALAR_
516 #define MPP_BROADCAST_SCALAR_ mpp_broadcast_cmplx4_scalar
517 #
undef MPP_BROADCAST_2D_
518 #define MPP_BROADCAST_2D_ mpp_broadcast_cmplx4_2d
519 #
undef MPP_BROADCAST_3D_
520 #define MPP_BROADCAST_3D_ mpp_broadcast_cmplx4_3d
521 #
undef MPP_BROADCAST_4D_
522 #define MPP_BROADCAST_4D_ mpp_broadcast_cmplx4_4d
523 #
undef MPP_BROADCAST_5D_
524 #define MPP_BROADCAST_5D_ mpp_broadcast_cmplx4_5d
527 #
undef MPP_TYPE_BYTELEN_
528 #define MPP_TYPE_BYTELEN_ 8
531 #include <mpp_transmit_nocomm.h>
534 #ifndef no_8byte_integers
536 #define MPP_TRANSMIT_ mpp_transmit_int8
537 #
undef MPP_TRANSMIT_SCALAR_
538 #define MPP_TRANSMIT_SCALAR_ mpp_transmit_int8_scalar
539 #
undef MPP_TRANSMIT_2D_
540 #define MPP_TRANSMIT_2D_ mpp_transmit_int8_2d
541 #
undef MPP_TRANSMIT_3D_
542 #define MPP_TRANSMIT_3D_ mpp_transmit_int8_3d
543 #
undef MPP_TRANSMIT_4D_
544 #define MPP_TRANSMIT_4D_ mpp_transmit_int8_4d
545 #
undef MPP_TRANSMIT_5D_
546 #define MPP_TRANSMIT_5D_ mpp_transmit_int8_5d
548 #define MPP_RECV_ mpp_recv_int8
549 #
undef MPP_RECV_SCALAR_
550 #define MPP_RECV_SCALAR_ mpp_recv_int8_scalar
552 #define MPP_RECV_2D_ mpp_recv_int8_2d
554 #define MPP_RECV_3D_ mpp_recv_int8_3d
556 #define MPP_RECV_4D_ mpp_recv_int8_4d
558 #define MPP_RECV_5D_ mpp_recv_int8_5d
560 #define MPP_SEND_ mpp_send_int8
561 #
undef MPP_SEND_SCALAR_
562 #define MPP_SEND_SCALAR_ mpp_send_int8_scalar
564 #define MPP_SEND_2D_ mpp_send_int8_2d
566 #define MPP_SEND_3D_ mpp_send_int8_3d
568 #define MPP_SEND_4D_ mpp_send_int8_4d
570 #define MPP_SEND_5D_ mpp_send_int8_5d
573 #
undef MPP_BROADCAST_SCALAR_
574 #define MPP_BROADCAST_SCALAR_ mpp_broadcast_int8_scalar
575 #
undef MPP_BROADCAST_2D_
576 #define MPP_BROADCAST_2D_ mpp_broadcast_int8_2d
577 #
undef MPP_BROADCAST_3D_
578 #define MPP_BROADCAST_3D_ mpp_broadcast_int8_3d
579 #
undef MPP_BROADCAST_4D_
580 #define MPP_BROADCAST_4D_ mpp_broadcast_int8_4d
581 #
undef MPP_BROADCAST_5D_
582 #define MPP_BROADCAST_5D_ mpp_broadcast_int8_5d
585 #
undef MPP_TYPE_BYTELEN_
586 #define MPP_TYPE_BYTELEN_ 8
589 #include <mpp_transmit_nocomm.h>
593 #define MPP_TRANSMIT_ mpp_transmit_int4
594 #
undef MPP_TRANSMIT_SCALAR_
595 #define MPP_TRANSMIT_SCALAR_ mpp_transmit_int4_scalar
596 #
undef MPP_TRANSMIT_2D_
597 #define MPP_TRANSMIT_2D_ mpp_transmit_int4_2d
598 #
undef MPP_TRANSMIT_3D_
599 #define MPP_TRANSMIT_3D_ mpp_transmit_int4_3d
600 #
undef MPP_TRANSMIT_4D_
601 #define MPP_TRANSMIT_4D_ mpp_transmit_int4_4d
602 #
undef MPP_TRANSMIT_5D_
603 #define MPP_TRANSMIT_5D_ mpp_transmit_int4_5d
605 #define MPP_RECV_ mpp_recv_int4
606 #
undef MPP_RECV_SCALAR_
607 #define MPP_RECV_SCALAR_ mpp_recv_int4_scalar
609 #define MPP_RECV_2D_ mpp_recv_int4_2d
611 #define MPP_RECV_3D_ mpp_recv_int4_3d
613 #define MPP_RECV_4D_ mpp_recv_int4_4d
615 #define MPP_RECV_5D_ mpp_recv_int4_5d
617 #define MPP_SEND_ mpp_send_int4
618 #
undef MPP_SEND_SCALAR_
619 #define MPP_SEND_SCALAR_ mpp_send_int4_scalar
621 #define MPP_SEND_2D_ mpp_send_int4_2d
623 #define MPP_SEND_3D_ mpp_send_int4_3d
625 #define MPP_SEND_4D_ mpp_send_int4_4d
627 #define MPP_SEND_5D_ mpp_send_int4_5d
630 #
undef MPP_BROADCAST_SCALAR_
631 #define MPP_BROADCAST_SCALAR_ mpp_broadcast_int4_scalar
632 #
undef MPP_BROADCAST_2D_
633 #define MPP_BROADCAST_2D_ mpp_broadcast_int4_2d
634 #
undef MPP_BROADCAST_3D_
635 #define MPP_BROADCAST_3D_ mpp_broadcast_int4_3d
636 #
undef MPP_BROADCAST_4D_
637 #define MPP_BROADCAST_4D_ mpp_broadcast_int4_4d
638 #
undef MPP_BROADCAST_5D_
639 #define MPP_BROADCAST_5D_ mpp_broadcast_int4_5d
642 #
undef MPP_TYPE_BYTELEN_
643 #define MPP_TYPE_BYTELEN_ 4
646 #include <mpp_transmit_nocomm.h>
648 #ifndef no_8byte_integers
650 #define MPP_TRANSMIT_ mpp_transmit_logical8
651 #
undef MPP_TRANSMIT_SCALAR_
652 #define MPP_TRANSMIT_SCALAR_ mpp_transmit_logical8_scalar
653 #
undef MPP_TRANSMIT_2D_
654 #define MPP_TRANSMIT_2D_ mpp_transmit_logical8_2d
655 #
undef MPP_TRANSMIT_3D_
656 #define MPP_TRANSMIT_3D_ mpp_transmit_logical8_3d
657 #
undef MPP_TRANSMIT_4D_
658 #define MPP_TRANSMIT_4D_ mpp_transmit_logical8_4d
659 #
undef MPP_TRANSMIT_5D_
660 #define MPP_TRANSMIT_5D_ mpp_transmit_logical8_5d
662 #define MPP_RECV_ mpp_recv_logical8
663 #
undef MPP_RECV_SCALAR_
664 #define MPP_RECV_SCALAR_ mpp_recv_logical8_scalar
666 #define MPP_RECV_2D_ mpp_recv_logical8_2d
668 #define MPP_RECV_3D_ mpp_recv_logical8_3d
670 #define MPP_RECV_4D_ mpp_recv_logical8_4d
672 #define MPP_RECV_5D_ mpp_recv_logical8_5d
674 #define MPP_SEND_ mpp_send_logical8
675 #
undef MPP_SEND_SCALAR_
676 #define MPP_SEND_SCALAR_ mpp_send_logical8_scalar
678 #define MPP_SEND_2D_ mpp_send_logical8_2d
680 #define MPP_SEND_3D_ mpp_send_logical8_3d
682 #define MPP_SEND_4D_ mpp_send_logical8_4d
684 #define MPP_SEND_5D_ mpp_send_logical8_5d
687 #
undef MPP_BROADCAST_SCALAR_
688 #define MPP_BROADCAST_SCALAR_ mpp_broadcast_logical8_scalar
689 #
undef MPP_BROADCAST_2D_
690 #define MPP_BROADCAST_2D_ mpp_broadcast_logical8_2d
691 #
undef MPP_BROADCAST_3D_
692 #define MPP_BROADCAST_3D_ mpp_broadcast_logical8_3d
693 #
undef MPP_BROADCAST_4D_
694 #define MPP_BROADCAST_4D_ mpp_broadcast_logical8_4d
695 #
undef MPP_BROADCAST_5D_
696 #define MPP_BROADCAST_5D_ mpp_broadcast_logical8_5d
699 #
undef MPP_TYPE_BYTELEN_
700 #define MPP_TYPE_BYTELEN_ 8
703 #include <mpp_transmit_nocomm.h>
707 #define MPP_TRANSMIT_ mpp_transmit_logical4
708 #
undef MPP_TRANSMIT_SCALAR_
709 #define MPP_TRANSMIT_SCALAR_ mpp_transmit_logical4_scalar
710 #
undef MPP_TRANSMIT_2D_
711 #define MPP_TRANSMIT_2D_ mpp_transmit_logical4_2d
712 #
undef MPP_TRANSMIT_3D_
713 #define MPP_TRANSMIT_3D_ mpp_transmit_logical4_3d
714 #
undef MPP_TRANSMIT_4D_
715 #define MPP_TRANSMIT_4D_ mpp_transmit_logical4_4d
716 #
undef MPP_TRANSMIT_5D_
717 #define MPP_TRANSMIT_5D_ mpp_transmit_logical4_5d
719 #define MPP_RECV_ mpp_recv_logical4
720 #
undef MPP_RECV_SCALAR_
721 #define MPP_RECV_SCALAR_ mpp_recv_logical4_scalar
723 #define MPP_RECV_2D_ mpp_recv_logical4_2d
725 #define MPP_RECV_3D_ mpp_recv_logical4_3d
727 #define MPP_RECV_4D_ mpp_recv_logical4_4d
729 #define MPP_RECV_5D_ mpp_recv_logical4_5d
731 #define MPP_SEND_ mpp_send_logical4
732 #
undef MPP_SEND_SCALAR_
733 #define MPP_SEND_SCALAR_ mpp_send_logical4_scalar
735 #define MPP_SEND_2D_ mpp_send_logical4_2d
737 #define MPP_SEND_3D_ mpp_send_logical4_3d
739 #define MPP_SEND_4D_ mpp_send_logical4_4d
741 #define MPP_SEND_5D_ mpp_send_logical4_5d
744 #
undef MPP_BROADCAST_SCALAR_
745 #define MPP_BROADCAST_SCALAR_ mpp_broadcast_logical4_scalar
746 #
undef MPP_BROADCAST_2D_
747 #define MPP_BROADCAST_2D_ mpp_broadcast_logical4_2d
748 #
undef MPP_BROADCAST_3D_
749 #define MPP_BROADCAST_3D_ mpp_broadcast_logical4_3d
750 #
undef MPP_BROADCAST_4D_
751 #define MPP_BROADCAST_4D_ mpp_broadcast_logical4_4d
752 #
undef MPP_BROADCAST_5D_
753 #define MPP_BROADCAST_5D_ mpp_broadcast_logical4_5d
756 #
undef MPP_TYPE_BYTELEN_
757 #define MPP_TYPE_BYTELEN_ 4
760 #include <mpp_transmit_nocomm.h>
762 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
764 ! GLOBAL REDUCTION ROUTINES: mpp_max, mpp_sum, mpp_min !
766 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
767 #
undef MPP_REDUCE_0D_
768 #define MPP_REDUCE_0D_ mpp_max_real8_0d
769 #
undef MPP_REDUCE_1D_
770 #define MPP_REDUCE_1D_ mpp_max_real8_1d
773 #
undef MPP_TYPE_BYTELEN_
774 #define MPP_TYPE_BYTELEN_ 8
778 #define MPI_REDUCE_ MPI_MAX
779 #include <mpp_reduce_nocomm.h>
782 #
undef MPP_REDUCE_0D_
783 #define MPP_REDUCE_0D_ mpp_max_real4_0d
784 #
undef MPP_REDUCE_1D_
785 #define MPP_REDUCE_1D_ mpp_max_real4_1d
788 #
undef MPP_TYPE_BYTELEN_
789 #define MPP_TYPE_BYTELEN_ 4
793 #define MPI_REDUCE_ MPI_MAX
794 #include <mpp_reduce_nocomm.h>
797 #ifndef no_8byte_integers
798 #
undef MPP_REDUCE_0D_
799 #define MPP_REDUCE_0D_ mpp_max_int8_0d
800 #
undef MPP_REDUCE_1D_
801 #define MPP_REDUCE_1D_ mpp_max_int8_1d
804 #
undef MPP_TYPE_BYTELEN_
805 #define MPP_TYPE_BYTELEN_ 8
809 #define MPI_REDUCE_ MPI_MAX
810 #include <mpp_reduce_nocomm.h>
813 #
undef MPP_REDUCE_0D_
814 #define MPP_REDUCE_0D_ mpp_max_int4_0d
815 #
undef MPP_REDUCE_1D_
816 #define MPP_REDUCE_1D_ mpp_max_int4_1d
819 #
undef MPP_TYPE_BYTELEN_
820 #define MPP_TYPE_BYTELEN_ 4
824 #define MPI_REDUCE_ MPI_MAX
825 #include <mpp_reduce_nocomm.h>
827 #
undef MPP_REDUCE_0D_
828 #define MPP_REDUCE_0D_ mpp_min_real8_0d
829 #
undef MPP_REDUCE_1D_
830 #define MPP_REDUCE_1D_ mpp_min_real8_1d
833 #
undef MPP_TYPE_BYTELEN_
834 #define MPP_TYPE_BYTELEN_ 8
838 #define MPI_REDUCE_ MPI_MIN
839 #include <mpp_reduce_nocomm.h>
842 #
undef MPP_REDUCE_0D_
843 #define MPP_REDUCE_0D_ mpp_min_real4_0d
844 #
undef MPP_REDUCE_1D_
845 #define MPP_REDUCE_1D_ mpp_min_real4_1d
848 #
undef MPP_TYPE_BYTELEN_
849 #define MPP_TYPE_BYTELEN_ 4
853 #define MPI_REDUCE_ MPI_MIN
854 #include <mpp_reduce_nocomm.h>
857 #ifndef no_8byte_integers
858 #
undef MPP_REDUCE_0D_
859 #define MPP_REDUCE_0D_ mpp_min_int8_0d
860 #
undef MPP_REDUCE_1D_
861 #define MPP_REDUCE_1D_ mpp_min_int8_1d
864 #
undef MPP_TYPE_BYTELEN_
865 #define MPP_TYPE_BYTELEN_ 8
869 #define MPI_REDUCE_ MPI_MIN
870 #include <mpp_reduce_nocomm.h>
873 #
undef MPP_REDUCE_0D_
874 #define MPP_REDUCE_0D_ mpp_min_int4_0d
875 #
undef MPP_REDUCE_1D_
876 #define MPP_REDUCE_1D_ mpp_min_int4_1d
879 #
undef MPP_TYPE_BYTELEN_
880 #define MPP_TYPE_BYTELEN_ 4
884 #define MPI_REDUCE_ MPI_MIN
885 #include <mpp_reduce_nocomm.h>
888 #define MPP_SUM_ mpp_sum_real8
889 #
undef MPP_SUM_SCALAR_
890 #define MPP_SUM_SCALAR_ mpp_sum_real8_scalar
892 #define MPP_SUM_2D_ mpp_sum_real8_2d
894 #define MPP_SUM_3D_ mpp_sum_real8_3d
896 #define MPP_SUM_4D_ mpp_sum_real8_4d
898 #define MPP_SUM_5D_ mpp_sum_real8_5d
903 #
undef MPP_TYPE_BYTELEN_
904 #define MPP_TYPE_BYTELEN_ 8
905 #include <mpp_sum_nocomm.h>
909 #define MPP_SUM_ mpp_sum_cmplx8
910 #
undef MPP_SUM_SCALAR_
911 #define MPP_SUM_SCALAR_ mpp_sum_cmplx8_scalar
913 #define MPP_SUM_2D_ mpp_sum_cmplx8_2d
915 #define MPP_SUM_3D_ mpp_sum_cmplx8_3d
917 #define MPP_SUM_4D_ mpp_sum_cmplx8_4d
919 #define MPP_SUM_5D_ mpp_sum_cmplx8_5d
924 #
undef MPP_TYPE_BYTELEN_
925 #define MPP_TYPE_BYTELEN_ 16
926 #include <mpp_sum_nocomm.h>
931 #define MPP_SUM_ mpp_sum_real4
932 #
undef MPP_SUM_SCALAR_
933 #define MPP_SUM_SCALAR_ mpp_sum_real4_scalar
935 #define MPP_SUM_2D_ mpp_sum_real4_2d
937 #define MPP_SUM_3D_ mpp_sum_real4_3d
939 #define MPP_SUM_4D_ mpp_sum_real4_4d
941 #define MPP_SUM_5D_ mpp_sum_real4_5d
946 #
undef MPP_TYPE_BYTELEN_
947 #define MPP_TYPE_BYTELEN_ 4
948 #include <mpp_sum_nocomm.h>
953 #define MPP_SUM_ mpp_sum_cmplx4
954 #
undef MPP_SUM_SCALAR_
955 #define MPP_SUM_SCALAR_ mpp_sum_cmplx4_scalar
957 #define MPP_SUM_2D_ mpp_sum_cmplx4_2d
959 #define MPP_SUM_3D_ mpp_sum_cmplx4_3d
961 #define MPP_SUM_4D_ mpp_sum_cmplx4_4d
963 #define MPP_SUM_5D_ mpp_sum_cmplx4_5d
968 #
undef MPP_TYPE_BYTELEN_
969 #define MPP_TYPE_BYTELEN_ 8
970 #include <mpp_sum_nocomm.h>
973 #ifndef no_8byte_integers
975 #define MPP_SUM_ mpp_sum_int8
976 #
undef MPP_SUM_SCALAR_
977 #define MPP_SUM_SCALAR_ mpp_sum_int8_scalar
979 #define MPP_SUM_2D_ mpp_sum_int8_2d
981 #define MPP_SUM_3D_ mpp_sum_int8_3d
983 #define MPP_SUM_4D_ mpp_sum_int8_4d
985 #define MPP_SUM_5D_ mpp_sum_int8_5d
990 #
undef MPP_TYPE_BYTELEN_
991 #define MPP_TYPE_BYTELEN_ 8
992 #include <mpp_sum_nocomm.h>
996 #define MPP_SUM_ mpp_sum_int4
997 #
undef MPP_SUM_SCALAR_
998 #define MPP_SUM_SCALAR_ mpp_sum_int4_scalar
1000 #define MPP_SUM_2D_ mpp_sum_int4_2d
1002 #define MPP_SUM_3D_ mpp_sum_int4_3d
1004 #define MPP_SUM_4D_ mpp_sum_int4_4d
1006 #define MPP_SUM_5D_ mpp_sum_int4_5d
1011 #
undef MPP_TYPE_BYTELEN_
1012 #define MPP_TYPE_BYTELEN_ 4
1013 #include <mpp_sum_nocomm.h>
1015 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1017 ! SCATTER AND GATHER ROUTINES: mpp_alltoall !
1019 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1021 #
undef MPP_ALLTOALL_
1022 #
undef MPP_ALLTOALLV_
1024 #
undef MPP_TYPE_BYTELEN_
1026 #define MPP_ALLTOALL_ mpp_alltoall_int4
1027 #define MPP_ALLTOALLV_ mpp_alltoall_int4_v
1029 #define MPP_TYPE_BYTELEN_ 4
1031 #include <mpp_alltoall_nocomm.h>
1033 #
undef MPP_ALLTOALL_
1034 #
undef MPP_ALLTOALLV_
1036 #
undef MPP_TYPE_BYTELEN_
1038 #define MPP_ALLTOALL_ mpp_alltoall_int8
1039 #define MPP_ALLTOALLV_ mpp_alltoall_int8_v
1041 #define MPP_TYPE_BYTELEN_ 8
1043 #include <mpp_alltoall_nocomm.h>
1045 #
undef MPP_ALLTOALL_
1046 #
undef MPP_ALLTOALLV_
1048 #
undef MPP_TYPE_BYTELEN_
1050 #define MPP_ALLTOALL_ mpp_alltoall_real4
1051 #define MPP_ALLTOALLV_ mpp_alltoall_real4_v
1053 #define MPP_TYPE_BYTELEN_ 4
1055 #include <mpp_alltoall_nocomm.h>
1057 #
undef MPP_ALLTOALL_
1058 #
undef MPP_ALLTOALLV_
1060 #
undef MPP_TYPE_BYTELEN_
1062 #define MPP_ALLTOALL_ mpp_alltoall_real8
1063 #define MPP_ALLTOALLV_ mpp_alltoall_real8_v
1065 #define MPP_TYPE_BYTELEN_ 8
1067 #include <mpp_alltoall_nocomm.h>
1069 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1071 ! DATA TRANSFER TYPES: mpp_type_create, mpp_type_free !
1073 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1078 #include <mpp_type_nocomm.h>
1083 #include <mpp_type_nocomm.h>
1088 #include <mpp_type_nocomm.h>
1093 #include <mpp_type_nocomm.h>
1098 #include <mpp_type_nocomm.h>
1103 #include <mpp_type_nocomm.h>
1105 ! Clear preprocessor flags
1110 subroutine mpp_type_free(dtype)
1111 type(mpp_type), pointer, intent(inout) :: dtype
1113 call
mpp_error(NOTE,
'MPP_TYPE_FREE: ' &
1114 'This function should not be used in serial mode.')
1116 ! For consistency with MPI, we deallocate the pointer
1119 end subroutine mpp_type_free
************************************************************************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 MPP_BROADCAST_(data, length, from_pe, pelist) !this call was originally bundled in with mpp_transmit
*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, parameter, public no
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
************************************************************************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 MPP_TYPE_
l_size ! loop over number of fields ke do j
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:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! 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
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:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! 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
************************************************************************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
************************************************************************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 MPI_TYPE_
subroutine MPP_TYPE_CREATE_(field, array_of_subsizes, array_of_starts, &dtype_out) MPP_TYPE_
integer(long_kind) ticks_per_sec
type(mpp_type), target, public mpp_byte
type(clock), dimension(max_clocks), save clocks