source: branches/ORCHIDEE_EXT/ORCHIDEE/src_parallel/data_para.f90 @ 64

Last change on this file since 64 was 64, checked in by didier.solyga, 13 years ago

Import first version of ORCHIDEE_EXT

File size: 15.8 KB
Line 
1! Definition and allocation of parallel datas.
2! Initialization of parallel or sequentiel IOs.
3! Definition of Load Balancing functions.
4
5!-
6!- $Header: /home/ssipsl/CVSREP/ORCHIDEE/src_parallel/data_para.f90,v 1.7 2010/04/06 14:31:57 ssipsl Exp $
7!-
8
9MODULE data_para
10
11!-
12  USE defprec
13  USE constantes
14  USE ioipsl
15!-
16#include "src_parallel.h"
17!-
18  INTEGER, SAVE :: mpi_size                                           !! Number of parallel processes
19  INTEGER, SAVE :: mpi_rank                                           !! my rank num
20  INTEGER, SAVE :: root_prc                                           !! rank of root proc
21  LOGICAL, SAVE :: is_root_prc                                        !! Only root proc is true
22  INTEGER, SAVE :: nbp_loc                                            !! number of local continental points
23  INTEGER, SAVE :: nbp_glo                                            !! number of global continental points
24  INTEGER,SAVE,ALLOCATABLE,DIMENSION(:) :: nbp_para_nb
25  INTEGER,SAVE,ALLOCATABLE,DIMENSION(:) :: nbp_para_begin
26  INTEGER,SAVE,ALLOCATABLE,DIMENSION(:) :: nbp_para_end
27 
28  INTEGER,SAVE :: iim_g, jjm_g                                  !! Dimension of global fields
29  ! i x j 2D points (not land points) index
30  INTEGER,SAVE,allocatable,dimension(:) :: ij_para_nb           ! Number of 2D points for each mpi_rank block
31  INTEGER,SAVE,allocatable,dimension(:) :: ij_para_begin        ! First 2D point for each mpi_rank block
32  INTEGER,SAVE,allocatable,dimension(:) :: ij_para_end          ! Last 2D point for each mpi_rank block
33  ! i 2D index
34  INTEGER,SAVE,allocatable,dimension(:) :: ii_para_begin        ! First i index of 2D point for each mpi_rank block
35  INTEGER,SAVE,allocatable,dimension(:) :: ii_para_end          ! Last i index of 2D point for each mpi_rank block
36  ! j 2D index
37  INTEGER,SAVE,allocatable,dimension(:) :: jj_para_nb           ! Number of complete j lines for each mpi_rank block
38  INTEGER,SAVE,allocatable,dimension(:) :: jj_para_begin        ! First j index of 2D point for each mpi_rank block
39  INTEGER,SAVE,allocatable,dimension(:) :: jj_para_end          ! Last j index of 2D point for each mpi_rank block
40 
41  INTEGER,SAVE :: ii_begin
42  INTEGER,SAVE :: ii_end
43  INTEGER,SAVE :: jj_begin
44  INTEGER,SAVE :: jj_end
45  INTEGER,SAVE :: jj_nb
46  INTEGER,SAVE :: ij_begin
47  INTEGER,SAVE :: ij_end
48  INTEGER,SAVE :: ij_nb
49 
50 
51  !! Global array used by stomate and sechiba
52  !-
53  !! index of land points on the 2D map
54  INTEGER(i_std),ALLOCATABLE,DIMENSION(:),SAVE   :: index_g
55  !-
56  !! indices of the 4 neighbours of each grid point (1=N, 2=E, 3=S, 4=W)
57  INTEGER(i_std),ALLOCATABLE,DIMENSION(:,:),SAVE :: neighbours_g
58  !-
59  !! resolution at each grid point in m (1=E-W, 2=N-S)
60  REAL(r_std),ALLOCATABLE,DIMENSION(:,:),SAVE    :: resolution_g 
61  REAL(r_std),ALLOCATABLE,DIMENSION(:),SAVE    :: area_g 
62  !-
63  !! Geographical coordinates
64  REAL(r_std),ALLOCATABLE,DIMENSION(:,:),SAVE    :: lalo_g
65  ! Global grid, for all process
66  REAL(r_std), ALLOCATABLE, DIMENSION(:,:), SAVE     :: lon_g, lat_g, zlev_g
67  !-
68  !! Fraction of continents
69  REAL(r_std),ALLOCATABLE,DIMENSION(:),SAVE      :: contfrac_g
70 
71  INTEGER, SAVE :: MPI_COMM_ORCH
72  INTEGER, SAVE :: MPI_REAL_ORCH
73  INTEGER, SAVE :: MPI_INT_ORCH
74  LOGICAL, SAVE :: cpl_lmdz
75 
76  INTEGER, SAVE :: orch_domain_id
77 
78CONTAINS
79 
80  SUBROUTINE init_para(cpl_lmdz_x, communicator)
81
82    IMPLICIT NONE
83   
84#ifdef CPP_PARA
85    INCLUDE 'mpif.h'
86#endif
87    LOGICAL :: cpl_lmdz_x
88    INTEGER,OPTIONAL :: communicator
89    INTEGER :: ierr
90    CHARACTER(LEN=20) :: filename
91    INTEGER :: i, div
92    CHARACTER(LEN=4) :: num
93    LOGICAL, PARAMETER :: check = .FALSE.
94
95    cpl_lmdz=cpl_lmdz_x
96     
97#ifdef CPP_PARA
98    ! Orchidee communicator :
99    IF (.NOT. cpl_lmdz) THEN
100       CALL MPI_INIT(ierr)
101       IF (ierr /= 0) THEN
102          WRITE(*,*) 'INIT_PARA : MPI_INIT failed with ',ierr
103          STOP "INIT_PARA"         
104       ENDIF
105       MPI_COMM_ORCH=MPI_COMM_WORLD
106    ELSE
107       MPI_COMM_ORCH=communicator
108    ENDIF
109         
110   
111    ! Int and real precision
112    IF (MPI_VERSION == 1) THEN
113       ! Version MPI 1.x
114       IF (i_std==i_4) THEN
115          MPI_INT_ORCH=MPI_INTEGER
116       ELSEIF (i_std==i_8) THEN
117          MPI_INT_ORCH=MPI_INTEGER
118       ELSE
119          MPI_INT_ORCH=MPI_INTEGER
120       ENDIF
121       
122       IF (r_std==r_4) THEN
123          MPI_REAL_ORCH=MPI_REAL
124       ELSEIF (r_std==r_8) THEN
125          MPI_REAL_ORCH=MPI_DOUBLE_PRECISION
126       ELSE
127          MPI_REAL_ORCH=MPI_REAL
128       ENDIF
129    ELSE
130       ! Others MPI
131       IF (i_std==i_4) THEN
132          MPI_INT_ORCH=MPI_INTEGER4
133       ELSEIF (i_std==i_8) THEN
134          MPI_INT_ORCH=MPI_INTEGER8
135       ELSE
136          MPI_INT_ORCH=MPI_INTEGER
137       ENDIF
138         
139       IF (r_std==r_4) THEN
140          MPI_REAL_ORCH=MPI_REAL4
141       ELSEIF (r_std==r_8) THEN
142          MPI_REAL_ORCH=MPI_REAL8
143       ELSE
144          MPI_REAL_ORCH=MPI_REAL
145       ENDIF
146    ENDIF
147     
148    CALL MPI_COMM_SIZE(MPI_COMM_ORCH,mpi_size,ierr)
149    IF (ierr /= 0) THEN
150       WRITE(*,*) 'INIT_PARA : MPI_COMM_SIZE failed with ',ierr
151       STOP "INIT_PARA"
152    ENDIF
153    CALL MPI_COMM_RANK(MPI_COMM_ORCH,mpi_rank,ierr)
154    IF (ierr /= 0) THEN
155       WRITE(*,*) 'INIT_PARA : MPI_COMM_RANK failed with ',ierr
156       STOP "INIT_PARA"
157    ENDIF
158     
159#else
160    mpi_rank=0
161    mpi_size=1   
162#endif
163    root_prc=0
164     
165    IF (mpi_rank==0) THEN
166       is_root_prc=.TRUE.
167    ELSE
168       is_root_prc=.FALSE.
169    ENDIF
170
171    ! Open mpi_rank outputs or select stdout
172    IF (mpi_size > 1) THEN
173       write(num,'(I4.4)') mpi_rank
174       
175       numout = 100
176       
177       filename =  'out_orchidee_'//num
178       
179       OPEN(UNIT=numout,FILE=TRIM(filename),ACTION='write',STATUS='unknown',FORM='formatted',IOSTAT=ierr) 
180       IF (ierr /= 0) THEN
181#ifdef CPP_PARA
182          CALL MPI_FINALIZE(ierr)
183#endif
184          WRITE(*,*) "Erreur can't open file ", filename
185          STOP "INIT_PARA"
186       ENDIF
187    ELSE
188       numout = 6
189    ENDIF
190
191    IF (check) THEN
192#ifdef CPP_PARA
193       WRITE(numout,*) 'version MPI ', MPI_VERSION, MPI_SUBVERSION
194       WRITE(numout,*) 'INTEGERS ',MPI_INTEGER4,MPI_INTEGER8,MPI_INTEGER,MPI_INT_ORCH
195       WRITE(numout,*) 'REALS ',MPI_REAL4,MPI_REAL8,MPI_REAL,MPI_REAL_ORCH
196#endif
197       WRITE(numout,*) 'RANK ',mpi_rank,' SIZE ',mpi_size
198       WRITE(numout,*) "Am I root process ?",is_root_prc
199       WRITE(numout,*) "Init_para : For process number ",mpi_rank, "output file = ",filename
200    ENDIF
201     
202  END SUBROUTINE init_para
203 
204  SUBROUTINE init_data_para(iim,jjm,nbpoints,index_x)
205    USE constantes
206    IMPLICIT NONE
207#ifdef CPP_PARA
208    INCLUDE 'mpif.h'
209#endif
210
211    INTEGER,INTENT(IN) :: iim
212    INTEGER,INTENT(IN) :: jjm
213    INTEGER,INTENT(IN) :: nbpoints
214    INTEGER,DIMENSION(:),INTENT(IN) :: index_x
215
216    INTEGER,ALLOCATABLE,DIMENSION(:) :: index_l
217    INTEGER,ALLOCATABLE,DIMENSION(:) :: displs
218#ifdef CPP_PARA
219    INTEGER :: ierr
220#endif 
221    INTEGER :: i
222    LOGICAL, PARAMETER :: check=.FALSE.
223
224
225    IF (check) WRITE(numout,*) 'INIT_DATA_PARA',iim,jjm,nbpoints,index_x
226    ALLOCATE(nbp_para_nb(0:mpi_size-1))
227    ALLOCATE(nbp_para_begin(0:mpi_size-1))
228    ALLOCATE(nbp_para_end(0:mpi_size-1))
229    ALLOCATE(jj_para_nb(0:mpi_size-1))
230    ALLOCATE(jj_para_begin(0:mpi_size-1))
231    ALLOCATE(jj_para_end(0:mpi_size-1))
232    ALLOCATE(ii_para_begin(0:mpi_size-1))
233    ALLOCATE(ii_para_end(0:mpi_size-1))
234    ALLOCATE(ij_para_nb(0:mpi_size-1))
235    ALLOCATE(ij_para_begin(0:mpi_size-1))
236    ALLOCATE(ij_para_end(0:mpi_size-1))
237
238    IF (cpl_lmdz) THEN
239#ifdef CPP_PARA
240       CALL MPI_GATHER(nbpoints,1,MPI_INT_ORCH,nbp_para_nb,1,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
241#else
242       nbp_para_nb(0)=nbpoints
243#endif
244
245       IF (is_root_prc) THEN
246          nbp_glo=sum(nbp_para_nb)
247          ALLOCATE(displs(0:mpi_size-1))
248          ALLOCATE(index_l(nbp_glo))
249          displs(0)=0
250          DO i=1,mpi_size-1
251             displs(i)=displs(i-1)+nbp_para_nb(i-1)
252          ENDDO
253       ENDIF
254#ifdef CPP_PARA
255       CALL MPI_BCAST(nbp_glo,1,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
256       CALL MPI_GATHERV(index_x,nbpoints,MPI_INT_ORCH,index_l,nbp_para_nb,displs,&
257            MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr) 
258#else
259       ! if not parallized, nb_glo=nbpoints=nbp_para_nb
260       IF (is_root_prc) index_l(:)=index_x(1:nbp_glo)
261#endif
262    ELSE
263       IF (is_root_prc) THEN
264          nbp_glo=nbpoints
265          ALLOCATE(index_l(nbp_glo))
266          index_l(:)=index_x(1:nbp_glo)
267          CALL Read_Load_Balance(nbpoints,nbp_para_nb)
268       ENDIF
269    ENDIF
270
271    IF (is_root_prc) THEN
272
273       IF (check) WRITE(numout,*) '==== DISTRIB ====',nbpoints,nbp_para_nb
274
275       nbp_para_begin(0)=1
276       nbp_para_end(0)=nbp_para_nb(0)
277
278       DO i=1,mpi_size-1
279          nbp_para_begin(i)=nbp_para_end(i-1)+1
280          nbp_para_end(i)=nbp_para_begin(i)+nbp_para_nb(i)-1
281       ENDDO
282
283       nbp_loc=nbp_para_nb(mpi_rank)
284
285       iim_g=iim
286       jjm_g=jjm
287
288
289       ij_para_begin(0)=1
290       ij_para_end(0)=index_l(nbp_para_end(0))
291       ij_para_nb(0)=ij_para_end(0)-ij_para_begin(0)+1
292
293       DO i=1,mpi_size-1
294          ij_para_begin(i)=ij_para_end(i-1)+1
295          ij_para_end(i)=index_l(nbp_para_end(i))
296          ij_para_nb(i)=ij_para_end(i)-ij_para_begin(i)+1
297       ENDDO
298
299       ij_para_end(mpi_size-1)=iim*jjm
300       ij_para_nb(mpi_size-1)=ij_para_end(mpi_size-1)-ij_para_begin(mpi_size-1)+1
301
302
303       DO i=0,mpi_size-1
304          jj_para_begin(i)=(ij_para_begin(i)-1)/iim + 1
305          jj_para_end(i)=(ij_para_end(i)-1)/iim + 1
306          jj_para_nb(i)=jj_para_end(i)-jj_para_begin(i)+1
307
308          ii_para_begin(i)=MOD(ij_para_begin(i)-1,iim)+1
309          ii_para_end(i)=MOD(ij_para_end(i)-1,iim)+1
310       ENDDO
311
312       IF (check) THEN
313          WRITE(numout,*) '==== DECOUP ===='
314          WRITE(numout,*) 'nbp_para_begin=',nbp_para_begin
315          WRITE(numout,*) 'nbp_para_end  =',nbp_para_end
316          WRITE(numout,*) 'nbp_loc=',nbp_loc
317
318          WRITE(numout,*) 'ij_para_begin=',ij_para_begin
319          WRITE(numout,*) 'ij_para_end=',ij_para_end
320          WRITE(numout,*) 'ij_para_nb=',ij_para_nb
321          WRITE(numout,*) 'jj_para_begin=',jj_para_begin
322          WRITE(numout,*) 'jj_para_end=',jj_para_end
323          WRITE(numout,*) 'jj_para_nb=',jj_para_nb     
324          WRITE(numout,*) 'ii_para_begin=',ii_para_begin
325          WRITE(numout,*) 'ii_para_end=',ii_para_end
326       ENDIF
327
328       !
329       !- Root need the global variables
330       !-
331       ALLOCATE(resolution_g(nbp_glo,2),area_g(nbp_glo),lalo_g(nbp_glo,2))
332       ALLOCATE(neighbours_g(nbp_glo,8),contfrac_g(nbp_glo),index_g(nbp_glo))
333       ALLOCATE(lon_g(iim_g, jjm_g), lat_g(iim_g, jjm_g), zlev_g(iim_g, jjm_g))
334
335       index_g(:)=index_l(1:nbp_glo)
336    ENDIF
337
338#ifdef CPP_PARA
339    IF (is_root_prc) WRITE(numout,*) 'nbp_para_nb =',nbp_para_nb
340    CALL MPI_BCAST(nbp_para_nb,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
341    CALL MPI_BCAST(nbp_para_begin,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
342    CALL MPI_BCAST(nbp_para_end,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
343    CALL MPI_BCAST(jj_para_nb,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
344    CALL MPI_BCAST(jj_para_begin,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
345    CALL MPI_BCAST(jj_para_end,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
346    CALL MPI_BCAST(ii_para_begin,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
347    CALL MPI_BCAST(ii_para_end,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
348    CALL MPI_BCAST(ij_para_nb,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
349    CALL MPI_BCAST(ij_para_begin,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
350    CALL MPI_BCAST(ij_para_end,mpi_size,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
351    CALL MPI_BCAST(iim_g,1,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
352    CALL MPI_BCAST(jjm_g,1,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
353    CALL MPI_BCAST(nbp_glo,1,MPI_INT_ORCH,root_prc,MPI_COMM_ORCH,ierr)
354#endif
355
356    nbp_loc=nbp_para_nb(mpi_rank)
357
358    ij_nb=ij_para_nb(mpi_rank)
359    ij_begin=ij_para_begin(mpi_rank)
360    ij_end=ij_para_end(mpi_rank)
361
362    jj_nb=jj_para_nb(mpi_rank)
363    jj_begin=jj_para_begin(mpi_rank)
364    jj_end=jj_para_end(mpi_rank)
365
366    ii_begin=ii_para_begin(mpi_rank)
367    ii_end=ii_para_end(mpi_rank)
368
369    IF (check) &
370         WRITE(numout,*) 'Init_io_para'
371    CALL Init_io_para
372
373    IF (is_root_prc ) THEN
374       DEALLOCATE(index_l)
375       IF ( cpl_lmdz) THEN
376          DEALLOCATE(displs)
377       ENDIF
378    ENDIF
379
380    IF (check) &
381         WRITE(numout,*)  'DATA PARA',nbp_loc,nbp_glo,jj_begin,jj_end,ii_begin,ii_end       
382  END SUBROUTINE init_data_para
383 
384
385  SUBROUTINE Init_io_para
386    USE ioipsl
387    IMPLICIT NONE
388   
389    INTEGER,DIMENSION(2) :: ddid
390    INTEGER,DIMENSION(2) :: dsg
391    INTEGER,DIMENSION(2) :: dsl
392    INTEGER,DIMENSION(2) :: dpf
393    INTEGER,DIMENSION(2) :: dpl
394    INTEGER,DIMENSION(2) :: dhs
395    INTEGER,DIMENSION(2) :: dhe 
396
397    ddid=(/ 1,2 /)
398    dsg=(/ iim_g, jjm_g /)
399    dsl=(/ iim_g, jj_nb /)
400    dpf=(/ 1,jj_begin /)
401    dpl=(/ iim_g, jj_end /)
402    dhs=(/ ii_begin-1,0 /)
403    if (mpi_rank==mpi_size-1) then
404      dhe=(/0,0/)
405    else
406      dhe=(/ iim_g-ii_end,0 /) 
407    endif
408   
409    call flio_dom_set(mpi_size,mpi_rank,ddid,dsg,dsl,dpf,dpl,dhs,dhe, &
410                      'APPLE',orch_domain_id)
411  END SUBROUTINE Init_io_para
412 
413  SUBROUTINE Read_Load_balance(NbPoints,Nbpoints_loc)
414
415    IMPLICIT NONE
416    INTEGER,INTENT(IN)  :: NbPoints
417    INTEGER,INTENT(OUT) :: Nbpoints_loc(0:mpi_size-1)
418#ifdef CPP_PARA 
419    INTEGER :: unit_number=10
420    CHARACTER(len=255)  :: filename='Load_balance_orchidee.dat'
421    INTEGER :: j
422#endif
423    INTEGER :: i,s,ierr
424   
425    Nbpoints_loc(:) = 0
426
427#ifdef CPP_PARA
428    OPEN(UNIT=unit_number,FILE=trim(filename),STATUS='old',FORM='formatted',IOSTAT=ierr) 
429#else
430    ierr=1
431#endif   
432    s=0
433
434#ifdef CPP_PARA 
435    IF (ierr==0) THEN
436       i=0
437       !- Reading for any balancing file (even with a bad structure)
438       DO WHILE (i < mpi_size .AND. ierr == 0) 
439          READ (unit_number,*,IOSTAT=ierr) j,Nbpoints_loc(i)
440          s=s+Nbpoints_loc(i)
441          i=i+1
442       ENDDO
443       CLOSE(unit_number)
444    ENDIF
445#endif   
446   
447    !- Correction of bad balancing file (or an empty file) => same nb of points for each procs
448    IF (ierr/=0 .OR. s/=Nbpoints) THEN
449       DO i=0,mpi_size-1
450          Nbpoints_loc(i)=Nbpoints/mpi_size
451          IF (MOD(Nbpoints,mpi_size) > i) Nbpoints_loc(i)=Nbpoints_loc(i)+1
452       ENDDO
453    ENDIF
454   
455  END SUBROUTINE Read_Load_balance
456 
457  SUBROUTINE Write_Load_balance(times)
458    IMPLICIT NONE
459    REAL,INTENT(IN) :: times
460 
461#ifdef CPP_PARA 
462    CHARACTER(len=255)  :: filename='Load_balance_orchidee.dat'
463    INTEGER :: unit_number=10
464    INTEGER :: i,ierr
465    REAL :: All_Times(0:mpi_size-1)
466    REAL :: average
467    REAL :: efficiency
468    INTEGER :: dp,S
469    INTEGER :: New_nbpoints(0:mpi_size-1)
470#endif
471   
472    WRITE(numout,*) 'time',times
473#ifndef CPP_PARA
474    RETURN
475#else
476
477    CALL MPI_GATHER(times,1,MPI_REAL_ORCH,All_times,1,MPI_REAL_ORCH,root_prc,MPI_COMM_ORCH,ierr)
478    IF (is_root_prc) WRITE(numout,*) 'ALL_times',All_times
479
480    IF (is_root_prc) THEN
481     
482       OPEN(UNIT=unit_number,FILE=trim(filename),STATUS='replace',FORM='formatted',IOSTAT=ierr)
483       
484       average=sum(All_times(:))/mpi_size
485       DO i=0,mpi_size-1
486          efficiency=All_times(i)/Nbp_para_nb(i)
487          New_nbpoints(i)=Nbp_para_nb(i)-(All_times(i)-average)/efficiency
488       ENDDO
489       
490       S=sum(new_nbpoints(:))
491       dp=nbp_glo-S
492       
493       IF ( dp > 0 ) THEN
494          DO WHILE ( dp > 0 )
495             New_nbpoints(MOD(dp,mpi_size))=New_nbpoints(MOD(dp,mpi_size))+1
496             dp=dp-1
497          ENDDO
498       ELSE
499          dp=-dp
500          DO WHILE ( dp > 0 )
501             New_nbpoints(MOD(dp,mpi_size))=New_nbpoints(MOD(dp,mpi_size))-1
502             dp=dp-1
503          ENDDO
504       ENDIF
505       
506       ! If this algorithm diverge, we use previous repartition.
507       IF ( ANY(New_nbpoints(:) .LE. 0) ) THEN
508          New_nbpoints(:)=Nbp_para_nb(:)
509       ENDIF
510       
511       DO i=0,mpi_size-1
512          WRITE(Unit_number,*) i,New_nbpoints(i)
513       ENDDO
514       CLOSE(Unit_number)
515    ENDIF
516#endif
517 
518  END SUBROUTINE Write_Load_Balance
519 
520 
521 
522END MODULE data_para
523
524#include "mpi_dummy.h"
Note: See TracBrowser for help on using the repository browser.