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

Last change on this file since 195 was 193, checked in by ymipsl, 10 years ago

bug fix : MPI_THREAD_SINGLE was not managed, so for not multithreaded mpi stack environment, crash may occur.

YM

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