Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief Manages a pool of grids (to be used for example as tmp objects),
10 : !> but can also be used to instantiate grids that are never given back.
11 : !>
12 : !> Multigrid pools are just an array of pw_pools
13 : !> \note
14 : !> The pool could also work without pointers (doing = each time),
15 : !> but I find it *very* ugly.
16 : !>
17 : !> The pool could be integrated into pw_grid_type, I don't know if
18 : !> it would be a good or bad idea (but would add a circular dependence
19 : !> between pw and pw_grid types).
20 : !> \par History
21 : !> 08.2002 created [fawzi]
22 : !> \author Fawzi Mohamed
23 : ! **************************************************************************************************
24 : MODULE pw_pool_types
25 : #:include 'pw_types.fypp'
26 : #:for kind in pw_kinds
27 : USE cp_linked_list_pw, ONLY: cp_sll_${kind[1:]}$_${kind[0]}$_dealloc, cp_sll_${kind[1:]}$_${kind[0]}$_get_first_el, &
28 : cp_sll_${kind[1:]}$_${kind[0]}$_get_length, &
29 : cp_sll_${kind[1:]}$_${kind[0]}$_insert_el, cp_sll_${kind[1:]}$_${kind[0]}$_next, &
30 : cp_sll_${kind[1:]}$_${kind[0]}$_rm_first_el, cp_sll_${kind[1:]}$_${kind[0]}$_type
31 : #:endfor
32 : USE kinds, ONLY: dp
33 : USE pw_grid_types, ONLY: pw_grid_type
34 : USE pw_grids, ONLY: pw_grid_compare, &
35 : pw_grid_release, &
36 : pw_grid_retain
37 : #:for space in pw_spaces
38 : #:for kind in pw_kinds
39 : USE pw_types, ONLY: pw_${kind}$_${space}$_type
40 : #:endfor
41 : #:endfor
42 : #include "../base/base_uses.f90"
43 :
44 : IMPLICIT NONE
45 : PRIVATE
46 :
47 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'pw_pool_types'
48 : INTEGER, PARAMETER :: default_max_cache = 75, max_max_cache = 150
49 :
50 : PUBLIC :: pw_pool_type, pw_pool_p_type
51 : PUBLIC :: pw_pool_create, pw_pool_release
52 : PUBLIC :: pw_pools_copy, pw_pools_dealloc, &
53 : pw_pools_create_pws, pw_pools_give_back_pws
54 :
55 : ! **************************************************************************************************
56 : !> \brief Manages a pool of grids (to be used for example as tmp objects),
57 : !> but can also be used to instantiate grids that are never given back.
58 : !> \param ref_count reference count (see /cp2k/doc/ReferenceCounting.html)
59 : !> \param real 1d_array, c1d_array, complex3d_array: liked list with
60 : !> the cached grids of the corresponding type
61 : !> \note
62 : !> As of now I would like replace the linked lists by arrays
63 : !> (no annoying list elements that are allocated would show up when
64 : !> tracking leaks) [fawzi]
65 : !> \par History
66 : !> 08.2002 created [fawzi]
67 : !> \author Fawzi Mohamed
68 : ! **************************************************************************************************
69 : TYPE pw_pool_type
70 : INTEGER :: ref_count = 0, max_cache = 0
71 : TYPE(pw_grid_type), POINTER :: pw_grid => NULL()
72 : #:for kind in pw_kinds
73 : TYPE(cp_sll_${kind[1:]}$_${kind[0]}$_type), POINTER :: ${kind}$_array => NULL()
74 : #:endfor
75 : CONTAINS
76 : PROCEDURE, PUBLIC, NON_OVERRIDABLE :: retain => pw_pool_retain
77 : #:for space in pw_spaces
78 : #:for i, kind in enumerate(pw_kinds)
79 : PROCEDURE, PUBLIC, NON_OVERRIDABLE :: pw_pool_create_pw_${kind}$_${space}$
80 : GENERIC, PUBLIC :: create_pw => pw_pool_create_pw_${kind}$_${space}$
81 : PROCEDURE, PUBLIC, NON_OVERRIDABLE :: pw_pool_give_back_pw_${kind}$_${space}$
82 : GENERIC, PUBLIC :: give_back_pw => pw_pool_give_back_pw_${kind}$_${space}$
83 : #:endfor
84 : #:endfor
85 : PROCEDURE, PUBLIC, NON_OVERRIDABLE :: create_cr3d => pw_pool_create_cr3d
86 : PROCEDURE, PUBLIC, NON_OVERRIDABLE :: give_back_cr3d => pw_pool_give_back_cr3d
87 : END TYPE pw_pool_type
88 :
89 : ! **************************************************************************************************
90 : !> \brief to create arrays of pools
91 : !> \param pool the pool
92 : !> \par History
93 : !> 08.2002 created [fawzi]
94 : !> \author Fawzi Mohamed
95 : ! **************************************************************************************************
96 : TYPE pw_pool_p_type
97 : TYPE(pw_pool_type), POINTER :: pool => NULL()
98 : END TYPE pw_pool_p_type
99 :
100 : INTERFACE pw_pools_create_pws
101 : #:for space in pw_spaces
102 : #:for kind in pw_kinds
103 : MODULE PROCEDURE pw_pools_create_pws_${kind}$_${space}$
104 : #:endfor
105 : #:endfor
106 : END INTERFACE
107 :
108 : INTERFACE pw_pools_give_back_pws
109 : #:for space in pw_spaces
110 : #:for kind in pw_kinds
111 : MODULE PROCEDURE pw_pools_give_back_pws_${kind}$_${space}$
112 : #:endfor
113 : #:endfor
114 : END INTERFACE
115 :
116 : CONTAINS
117 :
118 : ! **************************************************************************************************
119 : !> \brief creates a pool for pw
120 : !> \param pool the pool to create
121 : !> \param pw_grid the grid that is used to create the pw
122 : !> \param max_cache ...
123 : !> \par History
124 : !> 08.2002 created [fawzi]
125 : !> \author Fawzi Mohamed
126 : ! **************************************************************************************************
127 93521 : SUBROUTINE pw_pool_create(pool, pw_grid, max_cache)
128 : TYPE(pw_pool_type), POINTER :: pool
129 : TYPE(pw_grid_type), POINTER :: pw_grid
130 : INTEGER, OPTIONAL :: max_cache
131 :
132 93521 : ALLOCATE (pool)
133 93521 : pool%pw_grid => pw_grid
134 93521 : CALL pw_grid_retain(pw_grid)
135 93521 : pool%ref_count = 1
136 93521 : pool%max_cache = default_max_cache
137 93521 : IF (PRESENT(max_cache)) pool%max_cache = max_cache
138 93521 : pool%max_cache = MIN(max_max_cache, pool%max_cache)
139 93521 : END SUBROUTINE pw_pool_create
140 :
141 : ! **************************************************************************************************
142 : !> \brief retains the pool (see cp2k/doc/ReferenceCounting.html)
143 : !> \param pool the pool to retain
144 : !> \par History
145 : !> 08.2002 created [fawzi]
146 : !> \author Fawzi Mohamed
147 : ! **************************************************************************************************
148 193129 : SUBROUTINE pw_pool_retain(pool)
149 : CLASS(pw_pool_type), INTENT(INOUT) :: pool
150 :
151 193129 : CPASSERT(pool%ref_count > 0)
152 :
153 193129 : pool%ref_count = pool%ref_count + 1
154 193129 : END SUBROUTINE pw_pool_retain
155 :
156 : ! **************************************************************************************************
157 : !> \brief deallocates all the cached grids
158 : !> \param pool the pool to flush
159 : !> \par History
160 : !> 08.2002 created [fawzi]
161 : !> \author Fawzi Mohamed
162 : ! **************************************************************************************************
163 93521 : SUBROUTINE pw_pool_flush_cache(pool)
164 : TYPE(pw_pool_type), INTENT(INOUT) :: pool
165 :
166 : #:for kind, type in zip(pw_kinds, pw_types)
167 93521 : ${type}$, CONTIGUOUS, POINTER :: ${kind}$_att
168 : TYPE(cp_sll_${kind[1:]}$_${kind[0]}$_type), POINTER :: ${kind}$_iterator
169 : #:endfor
170 :
171 : #:for kind in pw_kinds
172 374084 : NULLIFY (${kind}$_iterator, ${kind}$_att)
173 280563 : ${kind}$_iterator => pool%${kind}$_array
174 324737 : DO
175 698821 : IF (.NOT. cp_sll_${kind[1:]}$_${kind[0]}$_next(${kind}$_iterator, el_att=${kind}$_att)) EXIT
176 324737 : DEALLOCATE (${kind}$_att)
177 : END DO
178 374084 : CALL cp_sll_${kind[1:]}$_${kind[0]}$_dealloc(pool%${kind}$_array)
179 : #:endfor
180 :
181 93521 : END SUBROUTINE pw_pool_flush_cache
182 :
183 : ! **************************************************************************************************
184 : !> \brief releases the given pool (see cp2k/doc/ReferenceCounting.html)
185 : !> \param pool the pool to release
186 : !> \par History
187 : !> 08.2002 created [fawzi]
188 : !> \author Fawzi Mohamed
189 : ! **************************************************************************************************
190 307477 : SUBROUTINE pw_pool_release(pool)
191 : TYPE(pw_pool_type), POINTER :: pool
192 :
193 307477 : IF (ASSOCIATED(pool)) THEN
194 286650 : CPASSERT(pool%ref_count > 0)
195 286650 : pool%ref_count = pool%ref_count - 1
196 286650 : IF (pool%ref_count == 0) THEN
197 93521 : CALL pw_pool_flush_cache(pool)
198 93521 : CALL pw_grid_release(pool%pw_grid)
199 :
200 93521 : DEALLOCATE (pool)
201 : END IF
202 : END IF
203 307477 : NULLIFY (pool)
204 307477 : END SUBROUTINE pw_pool_release
205 :
206 : #:for kind, type in zip(pw_kinds, pw_types)
207 : ! **************************************************************************************************
208 : !> \brief tries to pop an element from the given list (no error on failure)
209 : !> \param list the list to pop
210 : !> \return ...
211 : !> \par History
212 : !> 08.2002 created [fawzi]
213 : !> \author Fawzi Mohamed
214 : !> \note
215 : !> private function
216 : ! **************************************************************************************************
217 6598111 : FUNCTION try_pop_${kind}$ (list) RESULT(res)
218 : TYPE(cp_sll_${kind[1:]}$_${kind[0]}$_type), POINTER :: list
219 : ${type}$, CONTIGUOUS, POINTER :: res
220 :
221 6598111 : IF (ASSOCIATED(list)) THEN
222 6215923 : res => cp_sll_${kind[1:]}$_${kind[0]}$_get_first_el(list)
223 6215923 : CALL cp_sll_${kind[1:]}$_${kind[0]}$_rm_first_el(list)
224 : ELSE
225 382188 : NULLIFY (res)
226 : END IF
227 6598111 : END FUNCTION try_pop_${kind}$
228 :
229 : #:for space in pw_spaces
230 : ! **************************************************************************************************
231 : !> \brief returns a pw, allocating it if none is in the pool
232 : !> \param pool the pool from where you get the pw
233 : !> \param pw will contain the new pw
234 : !> \par History
235 : !> 08.2002 created [fawzi]
236 : !> \author Fawzi Mohamed
237 : ! **************************************************************************************************
238 6598111 : SUBROUTINE pw_pool_create_pw_${kind}$_${space}$ (pool, pw)
239 : CLASS(pw_pool_type), INTENT(IN) :: pool
240 : TYPE(pw_${kind}$_${space}$_type), INTENT(OUT) :: pw
241 :
242 : CHARACTER(len=*), PARAMETER :: routineN = 'pw_pool_create_pw'
243 :
244 : INTEGER :: handle
245 6598111 : ${type}$, CONTIGUOUS, POINTER :: array_ptr
246 :
247 6598111 : CALL timeset(routineN, handle)
248 6598111 : NULLIFY (array_ptr)
249 :
250 6598111 : array_ptr => try_pop_${kind}$ (pool%${kind}$_array)
251 6598111 : CALL pw%create(pool%pw_grid, array_ptr=array_ptr)
252 :
253 6598111 : CALL timestop(handle)
254 :
255 6598111 : END SUBROUTINE pw_pool_create_pw_${kind}$_${space}$
256 :
257 : ! **************************************************************************************************
258 : !> \brief returns the pw to the pool
259 : !> \param pool the pool where to reintegrate the pw
260 : !> \param pw the pw to give back
261 : !> \par History
262 : !> 08.2002 created [fawzi]
263 : !> \author Fawzi Mohamed
264 : ! **************************************************************************************************
265 7168471 : SUBROUTINE pw_pool_give_back_pw_${kind}$_${space}$ (pool, pw)
266 : CLASS(pw_pool_type), INTENT(IN) :: pool
267 : TYPE(pw_${kind}$_${space}$_type), INTENT(INOUT) :: pw
268 :
269 : CHARACTER(len=*), PARAMETER :: routineN = 'pw_pool_give_back_pw'
270 :
271 : INTEGER :: handle
272 :
273 7168471 : CALL timeset(routineN, handle)
274 7168471 : IF (ASSOCIATED(pw%pw_grid)) THEN
275 6820529 : IF (pw_grid_compare(pw%pw_grid, pool%pw_grid)) THEN
276 6820525 : IF (ASSOCIATED(pw%array)) THEN
277 6347473 : IF (cp_sll_${kind[1:]}$_${kind[0]}$_get_length(pool%${kind}$_array) < pool%max_cache) THEN
278 6347473 : CALL cp_sll_${kind[1:]}$_${kind[0]}$_insert_el(pool%${kind}$_array, el=pw%array)
279 6347473 : NULLIFY (pw%array)
280 : ELSE IF (max_max_cache >= 0) THEN
281 0 : CPWARN("hit max_cache")
282 : END IF
283 : END IF
284 : END IF
285 : END IF
286 7168471 : CALL pw%release()
287 7168471 : CALL timestop(handle)
288 7168471 : END SUBROUTINE pw_pool_give_back_pw_${kind}$_${space}$
289 :
290 : ! **************************************************************************************************
291 : !> \brief creates a multigrid structure
292 : !> \param pools the multigrid pool (i.e. an array of pw_pool)
293 : !> \param pws the multigrid of coefficent you want to initialize
294 : !> \par History
295 : !> 07.2004 created [fawzi]
296 : !> \author Fawzi Mohamed
297 : ! **************************************************************************************************
298 935290 : SUBROUTINE pw_pools_create_pws_${kind}$_${space}$ (pools, pws)
299 : TYPE(pw_pool_p_type), DIMENSION(:), INTENT(IN) :: pools
300 : TYPE(pw_${kind}$_${space}$_type), ALLOCATABLE, DIMENSION(:), &
301 : INTENT(OUT) :: pws
302 :
303 : INTEGER :: i
304 :
305 6513282 : ALLOCATE (pws(SIZE(pools)))
306 4642702 : DO i = 1, SIZE(pools)
307 4642702 : CALL pw_pool_create_pw_${kind}$_${space}$ (pools(i)%pool, pws(i))
308 : END DO
309 935290 : END SUBROUTINE pw_pools_create_pws_${kind}$_${space}$
310 :
311 : ! **************************************************************************************************
312 : !> \brief returns the pw part of the coefficients into the pools
313 : !> \param pools the pools that will cache the pws %pw
314 : !> \param pws the coefficients to give back
315 : !> \par History
316 : !> 08.2002 created [fawzi]
317 : !> \author Fawzi Mohamed
318 : ! **************************************************************************************************
319 935290 : SUBROUTINE pw_pools_give_back_pws_${kind}$_${space}$ (pools, pws)
320 : TYPE(pw_pool_p_type), DIMENSION(:), INTENT(IN) :: pools
321 : TYPE(pw_${kind}$_${space}$_type), ALLOCATABLE, DIMENSION(:), &
322 : INTENT(INOUT) :: pws
323 :
324 : INTEGER :: i
325 :
326 935290 : CPASSERT(SIZE(pws) == SIZE(pools))
327 4642702 : DO i = 1, SIZE(pools)
328 4642702 : CALL pw_pool_give_back_pw_${kind}$_${space}$ (pools(i)%pool, pws(i))
329 : END DO
330 935290 : DEALLOCATE (pws)
331 935290 : END SUBROUTINE pw_pools_give_back_pws_${kind}$_${space}$
332 : #:endfor
333 : #:endfor
334 :
335 : ! **************************************************************************************************
336 : !> \brief returns a 3d real array of coefficients as the one used by pw with
337 : !> REALDATA3D, allocating it if none is present in the pool
338 : !> \param pw_pool the pool that caches the cr3d
339 : !> \param cr3d the pointer that will contain the array
340 : !> \par History
341 : !> 11.2003 created [fawzi]
342 : !> \author fawzi
343 : ! **************************************************************************************************
344 697563 : SUBROUTINE pw_pool_create_cr3d(pw_pool, cr3d)
345 : CLASS(pw_pool_type), INTENT(IN) :: pw_pool
346 : REAL(kind=dp), DIMENSION(:, :, :), POINTER :: cr3d
347 :
348 697563 : IF (ASSOCIATED(pw_pool%r3d_array)) THEN
349 419132 : cr3d => cp_sll_3d_r_get_first_el(pw_pool%r3d_array)
350 419132 : CALL cp_sll_3d_r_rm_first_el(pw_pool%r3d_array)
351 : END IF
352 697563 : IF (.NOT. ASSOCIATED(cr3d)) THEN
353 : ALLOCATE (cr3d(pw_pool%pw_grid%bounds_local(1, 1):pw_pool%pw_grid%bounds_local(2, 1), &
354 : pw_pool%pw_grid%bounds_local(1, 2):pw_pool%pw_grid%bounds_local(2, 2), &
355 1392155 : pw_pool%pw_grid%bounds_local(1, 3):pw_pool%pw_grid%bounds_local(2, 3)))
356 : END IF
357 697563 : END SUBROUTINE pw_pool_create_cr3d
358 :
359 : ! **************************************************************************************************
360 : !> \brief returns a 3d real array of coefficients as the one used by pw with
361 : !> REALDATA3D, allocating it if none is present in the pool
362 : !> \param pw_pool the pool that caches the cr3d
363 : !> \param cr3d the pointer that will contain the array
364 : !> \par History
365 : !> 11.2003 created [fawzi]
366 : !> \author fawzi
367 : ! **************************************************************************************************
368 4627916 : SUBROUTINE pw_pool_give_back_cr3d(pw_pool, cr3d)
369 : CLASS(pw_pool_type), INTENT(IN) :: pw_pool
370 : REAL(kind=dp), CONTIGUOUS, DIMENSION(:, :, :), &
371 : POINTER :: cr3d
372 :
373 : LOGICAL :: compatible
374 :
375 4627916 : IF (ASSOCIATED(cr3d)) THEN
376 : compatible = ALL(MERGE(pw_pool%pw_grid%bounds_local(1, :) == LBOUND(cr3d) .AND. &
377 : pw_pool%pw_grid%bounds_local(2, :) == UBOUND(cr3d), &
378 : pw_pool%pw_grid%bounds_local(2, :) < pw_pool%pw_grid%bounds_local(1, :), &
379 6735553 : UBOUND(cr3d) >= LBOUND(cr3d)))
380 612323 : IF (compatible) THEN
381 612323 : IF (cp_sll_3d_r_get_length(pw_pool%r3d_array) < pw_pool%max_cache) THEN
382 612319 : CALL cp_sll_3d_r_insert_el(pw_pool%r3d_array, el=cr3d)
383 : ELSE
384 4 : CPWARN_IF(max_max_cache >= 0, "hit max_cache")
385 4 : DEALLOCATE (cr3d)
386 : END IF
387 : ELSE
388 0 : DEALLOCATE (cr3d)
389 : END IF
390 : END IF
391 4627916 : NULLIFY (cr3d)
392 4627916 : END SUBROUTINE pw_pool_give_back_cr3d
393 :
394 : ! **************************************************************************************************
395 : !> \brief copies a multigrid pool, the underlying pools are shared
396 : !> \param source_pools the pools to copy
397 : !> \param target_pools will hold the copy of the pools
398 : !> \par History
399 : !> 08.2002 created [fawzi]
400 : !> \author Fawzi Mohamed
401 : ! **************************************************************************************************
402 11120 : SUBROUTINE pw_pools_copy(source_pools, target_pools)
403 : TYPE(pw_pool_p_type), DIMENSION(:), INTENT(IN) :: source_pools
404 : TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: target_pools
405 :
406 : INTEGER :: i
407 :
408 64208 : ALLOCATE (target_pools(SIZE(source_pools)))
409 41968 : DO i = 1, SIZE(source_pools)
410 30848 : target_pools(i)%pool => source_pools(i)%pool
411 41968 : CALL source_pools(i)%pool%retain()
412 : END DO
413 11120 : END SUBROUTINE pw_pools_copy
414 :
415 : ! **************************************************************************************************
416 : !> \brief deallocates the given pools (releasing each of the underlying
417 : !> pools)
418 : !> \param pools the pols to deallocate
419 : !> \par History
420 : !> 08.2002 created [fawzi]
421 : !> \author Fawzi Mohamed
422 : ! **************************************************************************************************
423 38090 : SUBROUTINE pw_pools_dealloc(pools)
424 : TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pools
425 :
426 : INTEGER :: i
427 :
428 38090 : IF (ASSOCIATED(pools)) THEN
429 80496 : DO i = 1, SIZE(pools)
430 80496 : CALL pw_pool_release(pools(i)%pool)
431 : END DO
432 20140 : DEALLOCATE (pools)
433 : END IF
434 38090 : NULLIFY (pools)
435 38090 : END SUBROUTINE pw_pools_dealloc
436 :
437 0 : END MODULE pw_pool_types
|