ComIn 0.5.1
ICON Community Interface
Loading...
Searching...
No Matches
yaxt_fortran_plugin.F90
Go to the documentation of this file.
1! --------------------------------------------------------------------
2!> Example plugin for the ICON Community Interface (ComIn)
3! using the YAXT library to gather one ICON variable (temperature) on
4! task zero to calculate the global average near surface temperature.
5!
6! @authors 08/2021 :: ICON Community Interface <icon@dwd.de>
7!
8! Note that in order to demonstrate ComIn's language interoperability,
9! a similar plugin has been implemented in C, see the subdirectory
10! "yaxt_c".
11! --------------------------------------------------------------------
13
14 USE iso_c_binding, ONLY : c_int
16 , comin_var_get &
18 , t_comin_var_handle &
19 , comin_descrdata_get_domain &
20 , t_comin_descrdata_domain &
21 , comin_descrdata_get_global &
22 , t_comin_descrdata_global &
23 , t_comin_setup_version_info &
25 , ep_secondary_constructor &
26 , ep_destructor &
27 , ep_atm_write_output_before &
28 , comin_flag_read &
29 , comin_parallel_get_host_mpi_rank &
31 , comin_parallel_get_plugin_mpi_comm &
33 , t_comin_plugin_info &
34 , comin_current_get_plugin_info &
37 , comin_error_check, comin_print_info &
38 , comin_print_debug
39 USE yaxt, ONLY: xt_redist, xi => xt_int_kind
40
41 IMPLICIT NONE
42
43 CHARACTER(LEN=*), PARAMETER :: pluginname = "yaxt_fortran_plugin"
44
45 !> working precision (will be compared to ComIn's and ICON's)
46 INTEGER, PARAMETER :: wp = selected_real_kind(12,307)
47 TYPE(t_comin_setup_version_info) :: version
48
49 TYPE(t_comin_var_handle) :: temp ! temperature
50 INTEGER :: rank
51 CHARACTER(LEN=:), ALLOCATABLE :: units
52
53 !> access descriptive data structures
54 TYPE(t_comin_descrdata_domain) :: p_patch
55 TYPE(t_comin_descrdata_global) :: p_global
56
57 !> yaxt related variables
58 TYPE(xt_redist) :: yaxt_redist
59
60 CHARACTER(LEN=120) :: text
61
62CONTAINS
63
64 ! --------------------------------------------------------------------
65 ! ComIn primary constructor.
66 ! --------------------------------------------------------------------
67 SUBROUTINE comin_main() BIND(C)
68
69 USE yaxt, ONLY: xt_initialize, xt_idxlist, xt_idxlist_delete &
70 , xt_xmap, xt_xmap_delete, xt_idxstripes_new, xt_idxvec_new &
71 , xt_stripe, xt_idxempty_new, xt_xmap_all2all_new &
72 , xt_redist_p2p_new, xt_initialized
73 USE mpi, ONLY: mpi_double_precision
74
75 CHARACTER(LEN=*), PARAMETER :: substr = 'comin_main (yaxt_fortran_plugin)'
76 TYPE(t_comin_plugin_info) :: this_plugin
77 INTEGER :: p_all_comm ! communicator of all ICON tasks
78 TYPE(xt_idxlist) :: src_idxlist, tgt_idxlist
79 TYPE(xt_xmap) :: xmap
80 INTEGER(kind=xi), DIMENSION(:), ALLOCATABLE :: idxvec, idxmap
81 INTEGER, POINTER :: glb_index(:)
82 INTEGER :: k
83
84 !> get the rank of the current process and say hello to the world
85 rank = comin_parallel_get_host_mpi_rank()
86 CALL comin_print_info("setup")
87
88 !> check, if the ComIn library version is compatible
90 IF (version%version_no_major > 1) THEN
91 CALL comin_plugin_finish(substr, "incompatible ComIn library version!")
92 END IF
93
94 !> check plugin id
95 CALL comin_current_get_plugin_info(this_plugin)
96 WRITE (text,'(a,a,a,i4)') " plugin " &
97 , trim(this_plugin%name), " has id: ", this_plugin%id
98 CALL comin_print_info(text)
99
100 !> add requests for additional ICON variables
101 ! not applicable for this example
102
103 !> register callbacks
104 CALL comin_callback_register(ep_secondary_constructor &
106 CALL comin_callback_register(ep_atm_write_output_before &
108 CALL comin_callback_register(ep_destructor &
110
111 !> get descriptive data structures
112 p_patch = comin_descrdata_get_domain(1)
113 p_global = comin_descrdata_get_global()
114
115 !> setup yaxt
116 p_all_comm = comin_parallel_get_plugin_mpi_comm()
117 IF (.NOT. xt_initialized()) THEN
118 CALL comin_print_info("Initialize yaxt...")
119 CALL xt_initialize(p_all_comm)
120 ENDIF
121
122 !> construct yaxt variables ...
123 ! ... get halo info using decomp_domain :-
124 ! ... 0=core, 1=shared edge with owned, 2=shared vertex with owned, <0: undefined
125 idxmap = reshape(p_patch%cells%get_decomp_domain() &
126 , (/ SIZE(p_patch%cells%get_decomp_domain()) /))
127 ! ... get local ids of all core cells
128 idxvec = int(pack( [(k,k=1,p_patch%cells%get_ncells())], idxmap == 0 ), xi)
129 ! ... convert local ids to global ids
130 glb_index => p_patch%cells%get_glb_index()
131 idxvec = glb_index(idxvec)
132 ! ... generate idxlist for all core cells
133 src_idxlist = xt_idxvec_new(idxvec)
134
135 IF (rank == 0) THEN
136 tgt_idxlist = xt_idxstripes_new( &
137 (/ xt_stripe(1, 1, p_patch%cells%get_ncells_global()) /))
138 ELSE
139 ! ... empty on all other pe
140 tgt_idxlist = xt_idxempty_new()
141 ENDIF
142
143 ! ... create exchange map ...
144 xmap = xt_xmap_all2all_new(src_idxlist, tgt_idxlist, p_all_comm)
145
146 ! ... create redistribution instance for DP ...
147 yaxt_redist = xt_redist_p2p_new(xmap, mpi_double_precision)
148
149 ! ... clean up
150 CALL xt_xmap_delete(xmap)
151 CALL xt_idxlist_delete(src_idxlist)
152 CALL xt_idxlist_delete(tgt_idxlist)
153 DEALLOCATE(idxvec)
154 DEALLOCATE(idxmap)
155
156 END SUBROUTINE comin_main
157
158 ! --------------------------------------------------------------------
159 ! ComIn secondary constructor.
160 ! --------------------------------------------------------------------
161 SUBROUTINE yaxt_fortran_constructor() BIND(C)
162
163 USE yaxt, ONLY: xt_idxlist, xt_idxlist_delete &
164 , xt_xmap, xt_xmap_delete &
165 , xt_redist
166
167 CHARACTER(LEN=*), PARAMETER :: substr = 'yaxt_fortran_constructor (yaxt_fortran_plugin)'
168 TYPE(t_comin_var_descriptor) :: var_desc
169
170 CALL comin_print_info("secondary constructor")
171
172 CALL comin_print_info("request temperature")
173 var_desc = t_comin_var_descriptor('temp', 1)
174 CALL comin_var_get([ep_atm_write_output_before], &
175 var_desc, comin_flag_read, temp)
176
177 CALL comin_metadata_get(var_desc, 'units', units)
178
179 END SUBROUTINE yaxt_fortran_constructor
180
181 ! --------------------------------------------------------------------
182 ! ComIn callback function.
183 ! --------------------------------------------------------------------
184 SUBROUTINE yaxt_fortran_gather() BIND(C)
185
186 USE yaxt, ONLY: xt_redist_s_exchange1
187 USE iso_c_binding, ONLY: c_loc
188
189 CHARACTER(LEN=*), PARAMETER :: substr = 'yaxt_fortran_gather (yaxt_fortran_plugin)'
190 TYPE(t_comin_plugin_info) :: this_plugin
191 INTEGER :: domain_id
192 REAL(kind=wp), DIMENSION(:,:), POINTER :: src
193 REAL(kind=wp), DIMENSION(:,:,:), POINTER :: src3d
194 REAL(kind=wp), DIMENSION(:), POINTER :: tgt, area
195
196 CALL comin_print_info("callback before output")
197
198 !> check plugin id
199 CALL comin_current_get_plugin_info(this_plugin)
200
201 domain_id = comin_current_get_domain_id()
202 IF (domain_id == comin_domain_outside_loop) THEN
203 CALL comin_print_debug("currently not in domain loop")
204 ELSE
205 WRITE(text,'(a,a,i0)') "currently on domain ", domain_id
206 CALL comin_print_debug(text)
207 END IF
208
209 !> reset pointers
210 NULLIFY(src, src3d, tgt, area)
211
212 CALL temp%to_3d(src3d)
213
214 !> extract near surface temperature
215 ALLOCATE(src(p_global%get_nproma(), p_patch%cells%get_nblks()))
216 src(:,:) = src3d(:,p_patch%get_nlev(),:)
217
218 !> allocate local space to gather global information
219 ALLOCATE(tgt(p_patch%cells%get_ncells_global()))
220 ALLOCATE(area(p_patch%cells%get_ncells_global()))
221
222 !> gather information in rank zero
223 CALL xt_redist_s_exchange1(yaxt_redist, c_loc(src), c_loc(tgt))
224 CALL xt_redist_s_exchange1(yaxt_redist, c_loc(p_patch%cells%get_area()) &
225 , c_loc(area) )
226
227 IF (rank == 0) &
228 WRITE(0,*) substr, ': global average temperature is ' &
229 , sum(tgt*area)/sum(area), trim(units)
230
231 !> clean up memory
232 DEALLOCATE(src)
233 DEALLOCATE(tgt)
234 DEALLOCATE(area)
235
236 END SUBROUTINE yaxt_fortran_gather
237
238 ! --------------------------------------------------------------------
239 ! ComIn callback function.
240 ! --------------------------------------------------------------------
241 SUBROUTINE yaxt_fortran_destructor() BIND(C)
242
243 USE yaxt, ONLY: xt_finalize, xt_redist_delete
244
245 CALL comin_print_info("destructor")
246
247 !> free yaxt related memory
248 CALL xt_redist_delete(yaxt_redist)
249
250 !> finalize yaxt
251 CALL xt_finalize()
252
253 END SUBROUTINE yaxt_fortran_destructor
254
255END MODULE yaxt_fortran_plugin
void comin_plugin_finish(const char *routine, const char *text)
void comin_error_check()
const T * comin_metadata_get(t_comin_var_descriptor descriptor, const char *key)
void comin_setup_get_version(unsigned int *major, unsigned int *minor, unsigned int *patch)
int comin_current_get_domain_id()
integer, parameter, public comin_domain_outside_loop
Return value of comin_current_get_domain_id if there is currently no domain loop.
void comin_callback_register(t_comin_entry_point entry_point, t_comin_callback_function fct_ptr)
Example plugin for the ICON Community Interface (ComIn)
character(len= *), parameter pluginname
integer, parameter wp
working precision (will be compared to ComIn's and ICON's)
character(len=:), allocatable units
type(t_comin_var_handle) temp
type(t_comin_descrdata_domain) p_patch
access descriptive data structures
type(t_comin_descrdata_global) p_global
type(t_comin_setup_version_info) version
subroutine yaxt_fortran_constructor()
character(len=120) text
void comin_main()