source: codes/icosagcm/trunk/src/mpipara.F90 @ 216

Last change on this file since 216 was 216, checked in by dubos, 10 years ago

Fixed circular dependency with getin.f90

File size: 6.4 KB
Line 
1MODULE mpipara
2
3  INTEGER,SAVE :: mpi_rank
4  INTEGER,SAVE :: mpi_size
5  INTEGER,SAVE :: mpi_threading_mode
6 
7  INTEGER,SAVE :: comm_icosa
8  INTEGER,SAVE :: ierr
9  LOGICAL,SAVE :: using_mpi
10  LOGICAL,SAVE :: is_mpi_root
11 
12  INTERFACE allocate_mpi_buffer
13    MODULE PROCEDURE allocate_mpi_buffer_r2, allocate_mpi_buffer_r3,allocate_mpi_buffer_r4
14  END INTERFACE allocate_mpi_buffer
15
16  INTERFACE free_mpi_buffer
17    MODULE PROCEDURE free_mpi_buffer_r2, free_mpi_buffer_r3, free_mpi_buffer_r4
18  END INTERFACE free_mpi_buffer
19
20  PRIVATE :: getin
21
22CONTAINS
23
24  SUBROUTINE getin(name,value) ! Copied from getin.f90 to avoid circular dependency
25  USE ioipsl, ONLY : getin_=>getin
26  USE transfert_omp_mod
27  USE omp_para
28  IMPLICIT NONE
29    CHARACTER(LEN=*) :: name
30    CHARACTER(LEN=*) :: value
31
32!$OMP MASTER   
33    CALL getin_(name,value)
34    IF(is_mpi_root) PRINT *,'GETIN ',TRIM(name),' = ', TRIM(value)
35!$OMP END MASTER
36    IF (omp_in_parallel()) CALL bcast_omp(value)
37  END SUBROUTINE getin
38
39  SUBROUTINE init_mpipara
40  USE mpi_mod
41#ifdef CPP_USING_XIOS
42  USE xios
43#endif
44  IMPLICIT NONE
45    CHARACTER(LEN=256) :: required_mode_str
46    INTEGER :: required_mode
47
48    using_mpi=.FALSE.
49#ifdef CPP_USING_MPI
50    using_mpi=.TRUE. 
51#endif
52   
53    IF (using_mpi) THEN
54   
55      required_mode_str='multiple'
56      CALL getin('mpi_threading_mode',required_mode_str)
57     
58      SELECT CASE(TRIM(required_mode_str))
59        CASE ('single')
60          required_mode=MPI_THREAD_SINGLE
61        CASE ('funneled')
62          required_mode=MPI_THREAD_FUNNELED
63        CASE ('serialized')
64          required_mode=MPI_THREAD_SERIALIZED
65        CASE ('multiple')
66          required_mode=MPI_THREAD_MULTIPLE
67        CASE DEFAULT
68          PRINT*,'Bad selector for variable mpi_threading_mode  : <', TRIM(required_mode_str),  &
69                 '>  => options are <single>, <funneled>, <serialized>, <multiple>'
70          STOP
71      END SELECT
72     
73
74      IF (required_mode==MPI_THREAD_SINGLE)     PRINT*,'MPI_INIT_THREAD : MPI_SINGLE_THREAD required'
75      IF (required_mode==MPI_THREAD_FUNNELED)   PRINT*,'MPI_INIT_THREAD : MPI_THREAD_FUNNELED required'
76      IF (required_mode==MPI_THREAD_SERIALIZED) PRINT*,'MPI_INIT_THREAD : MPI_THREAD_SERIALIZED required'
77      IF (required_mode==MPI_THREAD_MULTIPLE)   PRINT*,'MPI_INIT_THREAD : MPI_THREAD_MULTIPLE required'
78
79     
80      CALL MPI_INIT_THREAD(MPI_THREAD_MULTIPLE,mpi_threading_mode,ierr)
81     
82      IF (mpi_threading_mode==MPI_THREAD_SINGLE)     PRINT*,'MPI_INIT_THREAD : MPI_SINGLE_THREAD provided'
83      IF (mpi_threading_mode==MPI_THREAD_FUNNELED)   PRINT*,'MPI_INIT_THREAD : MPI_THREAD_FUNNELED provided'
84      IF (mpi_threading_mode==MPI_THREAD_SERIALIZED) PRINT*,'MPI_INIT_THREAD : MPI_THREAD_SERIALIZED provided'
85      IF (mpi_threading_mode==MPI_THREAD_MULTIPLE)   PRINT*,'MPI_INIT_THREAD : MPI_THREAD_MULTIPLE provided'
86
87      IF (mpi_threading_mode > required_mode) mpi_threading_mode=required_mode
88
89      IF (mpi_threading_mode==MPI_THREAD_SINGLE) THEN
90         PRINT*,'MPI_INIT_THREAD : MPI_SINGLE_THREAD used : Warning : openMP is not garanted to work'
91      ENDIF
92      IF (mpi_threading_mode==MPI_THREAD_FUNNELED)   PRINT*,'MPI_INIT_THREAD : MPI_THREAD_FUNNELED used'
93      IF (mpi_threading_mode==MPI_THREAD_SERIALIZED) PRINT*,'MPI_INIT_THREAD : MPI_THREAD_SERIALIZED used'
94      IF (mpi_threading_mode==MPI_THREAD_MULTIPLE)   PRINT*,'MPI_INIT_THREAD : MPI_THREAD_MULTIPLE used'
95         
96#ifdef CPP_USING_XIOS
97      CALL xios_initialize("icosagcm",return_comm=comm_icosa)
98#else
99     comm_icosa=MPI_COMM_WORLD
100#endif
101      CALL MPI_COMM_SIZE(comm_icosa,mpi_size,ierr)
102      CALL MPI_COMM_RANK(comm_icosa,mpi_rank,ierr)
103      PRINT *, 'MPI Process ', mpi_rank, '/', mpi_size
104    ELSE
105      comm_icosa=-1
106      mpi_size=1
107      mpi_rank=0
108    ENDIF
109   
110    IF (mpi_rank==0) THEN
111      is_mpi_root=.TRUE.
112    ELSE
113      is_mpi_root=.FALSE.
114    ENDIF
115   
116  END SUBROUTINE  init_mpipara
117
118  SUBROUTINE finalize_mpipara
119  USE mpi_mod
120  IMPLICIT NONE
121   
122    IF (using_mpi) CALL MPI_FINALIZE(ierr)
123   
124   END SUBROUTINE  finalize_mpipara
125   
126
127  SUBROUTINE allocate_mpi_buffer_r2(buffer,length)
128  USE ISO_C_BINDING
129  USE mpi_mod
130  USE prec
131  IMPLICIT NONE
132    REAL(rstd), POINTER :: buffer(:)
133    INTEGER,INTENT(IN)  :: length
134
135    TYPE(C_PTR)         :: base_ptr
136    INTEGER(KIND=MPI_ADDRESS_KIND) :: size
137    INTEGER :: real_size,ierr
138   
139    CALL MPI_TYPE_EXTENT(MPI_REAL8, real_size, ierr)
140    size=length*real_size
141   
142    CALL MPI_ALLOC_MEM(size,MPI_INFO_NULL,base_ptr,ierr)
143    CALL C_F_POINTER(base_ptr, buffer, (/ length /))
144
145  END SUBROUTINE allocate_mpi_buffer_r2
146
147  SUBROUTINE free_mpi_buffer_r2(buffer)
148  USE ISO_C_BINDING
149  USE mpi_mod
150  USE prec
151  IMPLICIT NONE
152    REAL(rstd), POINTER :: buffer(:)
153
154    CALL MPI_FREE_MEM(buffer,ierr)
155
156   END SUBROUTINE free_mpi_buffer_r2
157
158  SUBROUTINE allocate_mpi_buffer_r3(buffer,length,dim3)
159  USE ISO_C_BINDING
160  USE mpi_mod
161  USE prec
162    IMPLICIT NONE
163    REAL(rstd), POINTER :: buffer(:,:)
164    INTEGER,INTENT(IN)  :: length
165    INTEGER,INTENT(IN)  :: dim3
166
167    TYPE(C_PTR)         :: base_ptr
168    INTEGER(KIND=MPI_ADDRESS_KIND) :: size
169    INTEGER :: real_size,ierr
170   
171    CALL MPI_TYPE_EXTENT(MPI_REAL8, real_size, ierr)
172    size=length*real_size*dim3
173   
174    CALL MPI_ALLOC_MEM(size,MPI_INFO_NULL,base_ptr,ierr)
175    CALL C_F_POINTER(base_ptr, buffer, (/ length,dim3 /))
176   
177  END SUBROUTINE allocate_mpi_buffer_r3
178
179  SUBROUTINE free_mpi_buffer_r3(buffer)
180  USE ISO_C_BINDING
181  USE mpi_mod
182  USE prec
183  IMPLICIT NONE
184    REAL(rstd), POINTER :: buffer(:,:)
185
186    CALL MPI_FREE_MEM(buffer,ierr)
187
188  END SUBROUTINE free_mpi_buffer_r3
189
190  SUBROUTINE allocate_mpi_buffer_r4(buffer,length,dim3,dim4)
191  USE ISO_C_BINDING
192  USE mpi_mod
193  USE prec
194  IMPLICIT NONE
195    REAL(rstd), POINTER :: buffer(:,:,:)
196    INTEGER,INTENT(IN)  :: length
197    INTEGER,INTENT(IN)  :: dim3
198    INTEGER,INTENT(IN)  :: dim4
199
200    TYPE(C_PTR)         :: base_ptr
201    INTEGER(KIND=MPI_ADDRESS_KIND) :: size
202    INTEGER :: real_size,ierr
203   
204    CALL MPI_TYPE_EXTENT(MPI_REAL8, real_size, ierr)
205    size=length*real_size*dim3*dim4
206   
207    CALL MPI_ALLOC_MEM(size,MPI_INFO_NULL,base_ptr,ierr)
208    CALL C_F_POINTER(base_ptr, buffer, (/ length, dim3, dim4 /))
209   
210   END SUBROUTINE allocate_mpi_buffer_r4
211
212  SUBROUTINE free_mpi_buffer_r4(buffer)
213  USE ISO_C_BINDING
214  USE mpi_mod
215  USE prec
216  IMPLICIT NONE
217    REAL(rstd), POINTER :: buffer(:,:,:)
218
219    CALL MPI_FREE_MEM(buffer,ierr)
220
221  END SUBROUTINE free_mpi_buffer_r4
222   
223END MODULE mpipara
Note: See TracBrowser for help on using the repository browser.