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 NEMO/trunk/src/OCE/OBS – NEMO

source: NEMO/trunk/src/OCE/OBS/obs_mpp.F90 @ 14275

Last change on this file since 14275 was 14275, checked in by smasson, 3 years ago

trunk: suppress nproc ( = mpprank = narea-1)

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