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

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

Add new openMP parallelism based on distribution of domains on threads. There is no more limitation of number of threads by MPI process.

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)     PRINT*,'MPI_INIT_THREAD : MPI_SINGLE_THREAD used'
74      IF (mpi_threading_mode==MPI_THREAD_FUNNELED)   PRINT*,'MPI_INIT_THREAD : MPI_THREAD_FUNNELED used'
75      IF (mpi_threading_mode==MPI_THREAD_SERIALIZED) PRINT*,'MPI_INIT_THREAD : MPI_THREAD_SERIALIZED used'
76      IF (mpi_threading_mode==MPI_THREAD_MULTIPLE)   PRINT*,'MPI_INIT_THREAD : MPI_THREAD_MULTIPLE used'
77         
78#ifdef CPP_USING_XIOS
79      CALL xios_initialize("icosagcm",return_comm=comm_icosa)
80#else
81     comm_icosa=MPI_COMM_WORLD
82#endif
83      CALL MPI_COMM_SIZE(comm_icosa,mpi_size,ierr)
84      CALL MPI_COMM_RANK(comm_icosa,mpi_rank,ierr)
85      PRINT *, 'MPI Process ', mpi_rank, '/', mpi_size
86    ELSE
87      comm_icosa=-1
88      mpi_size=1
89      mpi_rank=0
90    ENDIF
91   
92    IF (mpi_rank==0) THEN
93      is_mpi_root=.TRUE.
94    ELSE
95      is_mpi_root=.FALSE.
96    ENDIF
97   
98  END SUBROUTINE  init_mpipara
99
100  SUBROUTINE finalize_mpipara
101  USE mpi_mod
102  IMPLICIT NONE
103   
104    IF (using_mpi) CALL MPI_FINALIZE(ierr)
105   
106   END SUBROUTINE  finalize_mpipara
107   
108
109  SUBROUTINE allocate_mpi_buffer_r2(buffer,length)
110  USE ISO_C_BINDING
111  USE mpi_mod
112  USE prec
113  IMPLICIT NONE
114    REAL(rstd), POINTER :: buffer(:)
115    INTEGER,INTENT(IN)  :: length
116
117    TYPE(C_PTR)         :: base_ptr
118    INTEGER(KIND=MPI_ADDRESS_KIND) :: size
119    INTEGER :: real_size,ierr
120   
121    CALL MPI_TYPE_EXTENT(MPI_REAL8, real_size, ierr)
122    size=length*real_size
123   
124    CALL MPI_ALLOC_MEM(size,MPI_INFO_NULL,base_ptr,ierr)
125    CALL C_F_POINTER(base_ptr, buffer, (/ length /))
126
127  END SUBROUTINE allocate_mpi_buffer_r2
128
129  SUBROUTINE free_mpi_buffer_r2(buffer)
130  USE ISO_C_BINDING
131  USE mpi_mod
132  USE prec
133  IMPLICIT NONE
134    REAL(rstd), POINTER :: buffer(:)
135
136    CALL MPI_FREE_MEM(buffer,ierr)
137
138   END SUBROUTINE free_mpi_buffer_r2
139
140  SUBROUTINE allocate_mpi_buffer_r3(buffer,length,dim3)
141  USE ISO_C_BINDING
142  USE mpi_mod
143  USE prec
144    IMPLICIT NONE
145    REAL(rstd), POINTER :: buffer(:,:)
146    INTEGER,INTENT(IN)  :: length
147    INTEGER,INTENT(IN)  :: dim3
148
149    TYPE(C_PTR)         :: base_ptr
150    INTEGER(KIND=MPI_ADDRESS_KIND) :: size
151    INTEGER :: real_size,ierr
152   
153    CALL MPI_TYPE_EXTENT(MPI_REAL8, real_size, ierr)
154    size=length*real_size*dim3
155   
156    CALL MPI_ALLOC_MEM(size,MPI_INFO_NULL,base_ptr,ierr)
157    CALL C_F_POINTER(base_ptr, buffer, (/ length,dim3 /))
158   
159  END SUBROUTINE allocate_mpi_buffer_r3
160
161  SUBROUTINE free_mpi_buffer_r3(buffer)
162  USE ISO_C_BINDING
163  USE mpi_mod
164  USE prec
165  IMPLICIT NONE
166    REAL(rstd), POINTER :: buffer(:,:)
167
168    CALL MPI_FREE_MEM(buffer,ierr)
169
170  END SUBROUTINE free_mpi_buffer_r3
171
172  SUBROUTINE allocate_mpi_buffer_r4(buffer,length,dim3,dim4)
173  USE ISO_C_BINDING
174  USE mpi_mod
175  USE prec
176  IMPLICIT NONE
177    REAL(rstd), POINTER :: buffer(:,:,:)
178    INTEGER,INTENT(IN)  :: length
179    INTEGER,INTENT(IN)  :: dim3
180    INTEGER,INTENT(IN)  :: dim4
181
182    TYPE(C_PTR)         :: base_ptr
183    INTEGER(KIND=MPI_ADDRESS_KIND) :: size
184    INTEGER :: real_size,ierr
185   
186    CALL MPI_TYPE_EXTENT(MPI_REAL8, real_size, ierr)
187    size=length*real_size*dim3*dim4
188   
189    CALL MPI_ALLOC_MEM(size,MPI_INFO_NULL,base_ptr,ierr)
190    CALL C_F_POINTER(base_ptr, buffer, (/ length, dim3, dim4 /))
191   
192   END SUBROUTINE allocate_mpi_buffer_r4
193
194  SUBROUTINE free_mpi_buffer_r4(buffer)
195  USE ISO_C_BINDING
196  USE mpi_mod
197  USE prec
198  IMPLICIT NONE
199    REAL(rstd), POINTER :: buffer(:,:,:)
200
201    CALL MPI_FREE_MEM(buffer,ierr)
202
203  END SUBROUTINE free_mpi_buffer_r4
204   
205END MODULE mpipara
Note: See TracBrowser for help on using the repository browser.