New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
obs_mpp.F90 in branches/UKMO/r6232_obs_oper_update/NEMOGCM/NEMO/OPA_SRC/OBS – NEMO

source: branches/UKMO/r6232_obs_oper_update/NEMOGCM/NEMO/OPA_SRC/OBS/obs_mpp.F90 @ 11202

Last change on this file since 11202 was 11202, checked in by jcastill, 5 years ago

Copy of branch branches/UKMO/dev_r5518_obs_oper_update@11130 without namelist_ref changes to allow merging with coupling and biogeochemistry branches

  • Property svn:keywords set to Id
File size: 16.9 KB
RevLine 
[2128]1MODULE obs_mpp
2   !!======================================================================
3   !!                       ***  MODULE obs_mpp  ***
4   !! Observation diagnostics: Various MPP support routines
5   !!======================================================================
[2335]6   !! History :  2.0  ! 2006-03  (K. Mogensen)  Original code
7   !!             -   ! 2006-05  (K. Mogensen)  Reformatted
8   !!             -   ! 2008-01  (K. Mogensen)  add mpp_global_max
[11202]9   !!            3.6  ! 2015-01  (J. Waters) obs_mpp_find_obs_proc
10   !!                            rewritten to avoid global arrays
[2128]11   !!----------------------------------------------------------------------
[2335]12#  define mpivar mpi_double_precision
13   !!----------------------------------------------------------------------
14   !! obs_mpp_bcast_integer : Broadcast an integer array from a processor to all processors
15   !! obs_mpp_max_integer   : Find maximum on all processors of each value in an integer on all processors
[11202]16   !! obs_mpp_find_obs_proc : Find processors which should hold the observations, avoiding global arrays
[2128]17   !! obs_mpp_sum_integers  : Sum an integer array from all processors
18   !! obs_mpp_sum_integer   : Sum an integer from all processors
19   !!----------------------------------------------------------------------
[2335]20   USE dom_oce, ONLY :   nproc, mig, mjg   ! Ocean space and time domain variables
21   USE mpp_map, ONLY :   mppmap
[2128]22   USE in_out_manager
23#if defined key_mpp_mpi
[2335]24   USE lib_mpp, ONLY :   mpi_comm_opa      ! MPP library
[2128]25#endif
26   IMPLICIT NONE
27   PRIVATE
28
[2335]29   PUBLIC obs_mpp_bcast_integer, & !: Broadcast an integer array from a proc to all procs
30      &   obs_mpp_max_integer,   & !: Find maximum across processors in an integer array
31      &   obs_mpp_find_obs_proc, & !: Find processors which should hold the observations
32      &   obs_mpp_sum_integers,  & !: Sum an integer array from all processors
33      &   obs_mpp_sum_integer,   & !: Sum an integer from all processors
[2128]34      &   mpp_alltoall_int,      &
35      &   mpp_alltoallv_int,     &
36      &   mpp_alltoallv_real,    &
37      &   mpp_global_max
38
[2287]39   !!----------------------------------------------------------------------
40   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
41   !! $Id$
[2335]42   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
[2287]43   !!----------------------------------------------------------------------
[2128]44CONTAINS
45
[2335]46   SUBROUTINE obs_mpp_bcast_integer( kvals, kno, kroot )
[2128]47      !!----------------------------------------------------------------------
48      !!               ***  ROUTINE obs_mpp_bcast_integer ***
49      !!         
50      !! ** Purpose : Send array kvals to all processors
51      !!
52      !! ** Method  : MPI broadcast
53      !!
54      !! ** Action  : This does only work for MPI.
55      !!              MPI_COMM_OPA needs to be replace for OASIS4.!
56      !!
57      !! References : http://www.mpi-forum.org
[2335]58      !!----------------------------------------------------------------------
59      INTEGER                , INTENT(in   ) ::   kno     ! Number of elements in array
60      INTEGER                , INTENT(in   ) ::   kroot   ! Processor to send data
61      INTEGER, DIMENSION(kno), INTENT(inout) ::   kvals   ! Array to send on kroot, receive for non-kroot
[2513]62      !
[2128]63#if defined key_mpp_mpi
[2513]64      !
[2363]65      INTEGER :: ierr 
[2513]66      !
[2249]67INCLUDE 'mpif.h'
[2335]68      !!----------------------------------------------------------------------
[2128]69
70      ! Call the MPI library to broadcast data
[2335]71      CALL mpi_bcast( kvals, kno, mpi_integer,  &
[2128]72         &            kroot, mpi_comm_opa, ierr )
[2335]73#else
74      ! no MPI: empty routine
[2128]75#endif
[2335]76      !
77   END SUBROUTINE obs_mpp_bcast_integer
[2128]78
[2335]79 
[2128]80   SUBROUTINE obs_mpp_max_integer( kvals, kno )
81      !!----------------------------------------------------------------------
82      !!               ***  ROUTINE obs_mpp_bcast_integer ***
83      !!         
84      !! ** Purpose : Find maximum across processors in an integer array.
85      !!
86      !! ** Method  : MPI all reduce.
87      !!
88      !! ** Action  : This does only work for MPI.
89      !!              It does not work for SHMEM.
90      !!              MPI_COMM_OPA needs to be replace for OASIS4.!
91      !!
92      !! References : http://www.mpi-forum.org
[2335]93      !!----------------------------------------------------------------------
94      INTEGER                , INTENT(in   ) ::   kno     ! Number of elements in array
95      INTEGER, DIMENSION(kno), INTENT(inout) ::   kvals   ! Array to send on kroot, receive for non-kroot 
[2513]96      !
[2128]97#if defined key_mpp_mpi
[2513]98      !
[2363]99      INTEGER :: ierr 
[11202]100      INTEGER, DIMENSION(:), ALLOCATABLE ::   ivals
[2513]101      !
[2249]102INCLUDE 'mpif.h'
[2335]103      !!----------------------------------------------------------------------
[2128]104
[11202]105      ALLOCATE( ivals(kno) )
106
[2128]107      ! Call the MPI library to find the maximum across processors
[2335]108      CALL mpi_allreduce( kvals, ivals, kno, mpi_integer,   &
[2128]109         &                mpi_max, mpi_comm_opa, ierr )
110      kvals(:) = ivals(:)
[11202]111
112      DEALLOCATE( ivals )
[2335]113#else
114      ! no MPI: empty routine
[2128]115#endif
116   END SUBROUTINE obs_mpp_max_integer
117
[2335]118
[11202]119   SUBROUTINE obs_mpp_find_obs_proc( kobsp,kno )
[2128]120      !!----------------------------------------------------------------------
[11202]121      !!               ***  ROUTINE obs_mpp_find_obs_proc  ***
122      !!         
123      !! ** Purpose : From the array kobsp containing the results of the
[2128]124      !!              grid search on each processor the processor return a
125      !!              decision of which processors should hold the observation.
126      !!
[11202]127      !! ** Method  : Synchronize the processor number for each obs using
128      !!              obs_mpp_max_integer. If an observation exists on two
129      !!              processors it will be allocated to the lower numbered
130      !!              processor.
[2128]131      !!
[11202]132      !! ** Action  : This does only work for MPI.
[2128]133      !!              It does not work for SHMEM.
134      !!
135      !! References : http://www.mpi-forum.org
[2335]136      !!----------------------------------------------------------------------
137      INTEGER                , INTENT(in   ) ::   kno
138      INTEGER, DIMENSION(kno), INTENT(inout) ::   kobsp
[2513]139      !
[2128]140#if defined key_mpp_mpi
[2513]141      !
[11202]142      !
143      INTEGER :: ji, isum
144      INTEGER, DIMENSION(:), ALLOCATABLE ::   iobsp
[2335]145      !!
[11202]146      !!
[2128]147
[11202]148      ALLOCATE( iobsp(kno) )
149
150      iobsp(:)=kobsp(:)
151
152      WHERE( iobsp(:) == -1 )
153         iobsp(:) = 9999999
154      END WHERE
155
156      iobsp(:)=-1*iobsp(:)
157
158      CALL obs_mpp_max_integer( iobsp, kno )
159
160      kobsp(:)=-1*iobsp(:)
161
162      isum=0
[2128]163      DO ji = 1, kno
[11202]164         IF ( kobsp(ji) == 9999999 ) THEN
165            isum=isum+1
166            kobsp(ji)=-1
[2128]167         ENDIF
[11202]168      ENDDO
[2128]169
170
[11202]171      IF ( isum > 0 ) THEN
172         IF (lwp) WRITE(numout,*) isum, ' observations failed the grid search.'
173         IF (lwp) WRITE(numout,*)'If ln_grid_search_lookup=.TRUE., try reducing grid_search_res'
174      ENDIF
175
[2128]176      DEALLOCATE( iobsp )
[11202]177
[2335]178#else
179      ! no MPI: empty routine
[11202]180#endif     
181     
[2128]182   END SUBROUTINE obs_mpp_find_obs_proc
183
[2335]184
[2128]185   SUBROUTINE obs_mpp_sum_integers( kvalsin, kvalsout, kno )
186      !!----------------------------------------------------------------------
187      !!               ***  ROUTINE obs_mpp_sum_integers ***
188      !!         
189      !! ** Purpose : Sum an integer array.
190      !!
191      !! ** Method  : MPI all reduce.
192      !!
193      !! ** Action  : This does only work for MPI.
194      !!              It does not work for SHMEM.
195      !!
196      !! References : http://www.mpi-forum.org
[2335]197      !!----------------------------------------------------------------------
198      INTEGER                , INTENT(in   ) :: kno
199      INTEGER, DIMENSION(kno), INTENT(in   ) ::   kvalsin
200      INTEGER, DIMENSION(kno), INTENT(  out) ::   kvalsout
[2513]201      !
[2128]202#if defined key_mpp_mpi
[2513]203      !
[2128]204      INTEGER :: ierr
[2513]205      !
[2249]206INCLUDE 'mpif.h'
[2335]207      !!----------------------------------------------------------------------
208      !
[2128]209      !-----------------------------------------------------------------------
210      ! Call the MPI library to find the sum across processors
211      !-----------------------------------------------------------------------
212      CALL mpi_allreduce( kvalsin, kvalsout, kno, mpi_integer, &
213         &                mpi_sum, mpi_comm_opa, ierr )
214#else
215      !-----------------------------------------------------------------------
216      ! For no-MPP just return input values
217      !-----------------------------------------------------------------------
218      kvalsout(:) = kvalsin(:)
219#endif
[2335]220      !
[2128]221   END SUBROUTINE obs_mpp_sum_integers
222
[2335]223
[2128]224   SUBROUTINE obs_mpp_sum_integer( kvalin, kvalout )
225      !!----------------------------------------------------------------------
226      !!               ***  ROUTINE obs_mpp_sum_integers ***
227      !!         
228      !! ** Purpose : Sum a single integer
229      !!
230      !! ** Method  : MPI all reduce.
231      !!
232      !! ** Action  : This does only work for MPI.
233      !!              It does not work for SHMEM.
234      !!
235      !! References : http://www.mpi-forum.org
[2335]236      !!----------------------------------------------------------------------
237      INTEGER, INTENT(in   ) ::   kvalin
238      INTEGER, INTENT(  out) ::   kvalout
[2513]239      !
[2128]240#if defined key_mpp_mpi
[2513]241      !
[2128]242      INTEGER :: ierr
[2513]243      !
[2249]244INCLUDE 'mpif.h'
[2335]245      !!----------------------------------------------------------------------
246      !
[2128]247      !-----------------------------------------------------------------------
248      ! Call the MPI library to find the sum across processors
249      !-----------------------------------------------------------------------
[2335]250      CALL mpi_allreduce( kvalin, kvalout, 1, mpi_integer,   &
[2128]251         &                mpi_sum, mpi_comm_opa, ierr )
252#else
253      !-----------------------------------------------------------------------
254      ! For no-MPP just return input values
255      !-----------------------------------------------------------------------
256      kvalout = kvalin
257#endif
[2335]258      !
[2128]259   END SUBROUTINE obs_mpp_sum_integer
260
[2335]261
[2128]262   SUBROUTINE mpp_global_max( pval )
263      !!----------------------------------------------------------------------
264      !!               ***  ROUTINE mpp_global_or ***
265      !!         
266      !! ** Purpose : Get the maximum value across processors for a global
267      !!              real array
268      !!
269      !! ** Method  : MPI allreduce
270      !!
271      !! ** Action  : This does only work for MPI.
272      !!              It does not work for SHMEM.
273      !!
274      !! References : http://www.mpi-forum.org
[2335]275      !!----------------------------------------------------------------------
276      REAL(KIND=wp), DIMENSION(jpiglo,jpjglo), INTENT(inout) ::   pval
[2513]277      !
[2128]278      INTEGER :: ierr
[2513]279      !
[2128]280#if defined key_mpp_mpi
[2513]281      !
[2249]282INCLUDE 'mpif.h'
[2335]283      REAL(KIND=wp), DIMENSION(:,:), ALLOCATABLE ::   zcp
284      !!----------------------------------------------------------------------
[2128]285
286      ! Copy data for input to MPI
287
288      ALLOCATE( &
289         & zcp(jpiglo,jpjglo) &
290         & )
291      zcp(:,:) = pval(:,:)
292
293      ! Call the MPI library to find the coast lines globally
294
295      CALL mpi_allreduce( zcp, pval, jpiglo*jpjglo, mpivar, &
296         &                mpi_max, mpi_comm_opa, ierr )
297
298      DEALLOCATE( &
299         & zcp &
300         & )
301
[2335]302#else
303      ! no MPI: empty routine
[2128]304#endif
[2335]305      !
[2128]306   END SUBROUTINE mpp_global_max
307
[2335]308
[2128]309   SUBROUTINE mpp_alltoall_int( kno, kvalsin, kvalsout )
310      !!----------------------------------------------------------------------
311      !!               ***  ROUTINE mpp_allgatherv ***
312      !!         
313      !! ** Purpose : all to all.
314      !!
315      !! ** Method  : MPI alltoall
316      !!
317      !! ** Action  : This does only work for MPI.
318      !!              It does not work for SHMEM.
319      !!
320      !! References : http://www.mpi-forum.org
[2335]321      !!----------------------------------------------------------------------
322      INTEGER                      , INTENT(in   ) ::   kno
323      INTEGER, DIMENSION(kno*jpnij), INTENT(in   ) ::   kvalsin
324      INTEGER, DIMENSION(kno*jpnij), INTENT(  out) ::   kvalsout
[2128]325      !!
326      INTEGER :: ierr
[2513]327      !
[2128]328#if defined key_mpp_mpi
[2513]329      !
[2249]330INCLUDE 'mpif.h'
[2128]331      !-----------------------------------------------------------------------
332      ! Call the MPI library to do the all to all operation of the data
333      !-----------------------------------------------------------------------
334      CALL mpi_alltoall( kvalsin,  kno, mpi_integer, &
335         &               kvalsout, kno, mpi_integer, &
336         &               mpi_comm_opa, ierr )
337#else
338      !-----------------------------------------------------------------------
339      ! For no-MPP just return input values
340      !-----------------------------------------------------------------------
341      kvalsout = kvalsin
342#endif
[2335]343      !
[2128]344   END SUBROUTINE mpp_alltoall_int
345
[2335]346
347   SUBROUTINE mpp_alltoallv_int( kvalsin, knoin , kinv , kvalsout,   &
348      &                                   knoout, koutv )
[2128]349      !!----------------------------------------------------------------------
350      !!               ***  ROUTINE mpp_alltoallv_int ***
351      !!         
352      !! ** Purpose : all to all (integer version).
353      !!
354      !! ** Method  : MPI alltoall
355      !!
356      !! ** Action  : This does only work for MPI.
357      !!              It does not work for SHMEM.
358      !!
359      !! References : http://www.mpi-forum.org
[2335]360      !!----------------------------------------------------------------------
361      INTEGER                   , INTENT(in) :: knoin
362      INTEGER                   , INTENT(in) :: knoout
363      INTEGER, DIMENSION(jpnij)                 ::   kinv, koutv
364      INTEGER, DIMENSION(knoin) , INTENT(in   ) ::   kvalsin
365      INTEGER, DIMENSION(knoout), INTENT(  out) ::   kvalsout
[2128]366      !!
367      INTEGER :: ierr
368      INTEGER :: jproc
[2513]369      !
[2128]370#if defined key_mpp_mpi
[2513]371      !
[2249]372INCLUDE 'mpif.h'
[2335]373      INTEGER, DIMENSION(jpnij) ::   irdsp, isdsp
[2128]374      !-----------------------------------------------------------------------
375      ! Compute displacements
376      !-----------------------------------------------------------------------
377      irdsp(1) = 0
378      isdsp(1) = 0
379      DO jproc = 2, jpnij
380         isdsp(jproc) = isdsp(jproc-1) + kinv(jproc-1)
381         irdsp(jproc) = irdsp(jproc-1) + koutv(jproc-1)
382      END DO
383      !-----------------------------------------------------------------------
384      ! Call the MPI library to do the all to all operation of the data
385      !-----------------------------------------------------------------------
386      CALL mpi_alltoallv( kvalsin,  kinv,  isdsp, mpi_integer, &
387         &                kvalsout, koutv, irdsp, mpi_integer, &
388         &                mpi_comm_opa, ierr )
389#else
390      !-----------------------------------------------------------------------
391      ! For no-MPP just return input values
392      !-----------------------------------------------------------------------
393      kvalsout = kvalsin
394#endif
[2335]395      !
[2128]396   END SUBROUTINE mpp_alltoallv_int
397
[2335]398
399   SUBROUTINE mpp_alltoallv_real( pvalsin, knoin , kinv , pvalsout,   &
400      &                                    knoout, koutv )
[2128]401      !!----------------------------------------------------------------------
402      !!               ***  ROUTINE mpp_alltoallv_real ***
403      !!         
404      !! ** Purpose : all to all (integer version).
405      !!
406      !! ** Method  : MPI alltoall
407      !!
408      !! ** Action  : This does only work for MPI.
409      !!              It does not work for SHMEM.
410      !!
411      !! References : http://www.mpi-forum.org
[2335]412      !!----------------------------------------------------------------------
413      INTEGER                    , INTENT(in   ) :: knoin
414      INTEGER                    , INTENT(in   ) :: knoout
415      INTEGER , DIMENSION(jpnij)                 ::   kinv, koutv
416      REAL(wp), DIMENSION(knoin) , INTENT(in   ) ::   pvalsin
417      REAL(wp), DIMENSION(knoout), INTENT(  out) ::   pvalsout
[2128]418      !!
419      INTEGER :: ierr
420      INTEGER :: jproc
[2513]421      !
[2128]422#if defined key_mpp_mpi
[2513]423      !
[2249]424INCLUDE 'mpif.h'
[2335]425      INTEGER, DIMENSION(jpnij) ::   irdsp, isdsp
426      !!----------------------------------------------------------------------
427      !
[2128]428      !-----------------------------------------------------------------------
429      ! Compute displacements
430      !-----------------------------------------------------------------------
431      irdsp(1) = 0
432      isdsp(1) = 0
433      DO jproc = 2, jpnij
434         isdsp(jproc) = isdsp(jproc-1) + kinv(jproc-1)
435         irdsp(jproc) = irdsp(jproc-1) + koutv(jproc-1)
436      END DO
437      !-----------------------------------------------------------------------
438      ! Call the MPI library to do the all to all operation of the data
439      !-----------------------------------------------------------------------
440      CALL mpi_alltoallv( pvalsin,  kinv,  isdsp, mpivar, &
441         &                pvalsout, koutv, irdsp, mpivar, &
442         &                mpi_comm_opa, ierr )
443#else
444      !-----------------------------------------------------------------------
445      ! For no-MPP just return input values
446      !-----------------------------------------------------------------------
447      pvalsout = pvalsin
448#endif
[2335]449      !
[2128]450   END SUBROUTINE mpp_alltoallv_real
451
[2335]452   !!======================================================================
[2128]453END MODULE obs_mpp
Note: See TracBrowser for help on using the repository browser.