(git:ccc2433)
cp_fm_pool_types.F
Go to the documentation of this file.
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 pool for for elements that are retained and released
10 !> \par History
11 !> 08.2002 created [fawzi]
12 !> \author Fawzi Mohamed
13 ! **************************************************************************************************
17  cp_fm_struct_type
18  USE cp_fm_types, ONLY: cp_fm_create, &
19  cp_fm_p_type, &
20  cp_fm_release, &
21  cp_fm_type
27  cp_sll_fm_type
28  USE cp_log_handling, ONLY: cp_to_string
29 #include "../base/base_uses.f90"
30 
31  IMPLICIT NONE
32  PRIVATE
33 
34  LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .true.
35  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cp_fm_pool_types'
36 
37  PUBLIC :: cp_fm_pool_type, cp_fm_pool_p_type
38  PUBLIC :: fm_pool_create, fm_pool_retain, &
42  PUBLIC :: fm_pools_dealloc, &
43  fm_pools_create_fm_vect, &
44  fm_pools_give_back_fm_vect
45 !***
46 
47 ! **************************************************************************************************
48 !> \brief represent a pool of elements with the same structure
49 !> \param ref_count reference count (see /cp2k/doc/ReferenceCounting.html)
50 !> \param el_struct the structure of the elements stored in this pool
51 !> \param cache linked list with the elements in the pool
52 !> \par History
53 !> 08.2002 created [fawzi]
54 !> \author Fawzi Mohamed
55 ! **************************************************************************************************
56  TYPE cp_fm_pool_type
57  PRIVATE
58  INTEGER :: ref_count = -1
59  TYPE(cp_fm_struct_type), POINTER :: el_struct => null()
60  TYPE(cp_sll_fm_type), POINTER :: cache => null()
61  END TYPE cp_fm_pool_type
62 
63 ! **************************************************************************************************
64 !> \brief to create arrays of pools
65 !> \param pool the pool
66 !> \par History
67 !> 08.2002 created [fawzi]
68 !> \author Fawzi Mohamed
69 ! **************************************************************************************************
70  TYPE cp_fm_pool_p_type
71  TYPE(cp_fm_pool_type), POINTER :: pool => null()
72  END TYPE cp_fm_pool_p_type
73 
74  INTERFACE fm_pools_create_fm_vect
75  MODULE PROCEDURE fm_pools_create_fm_m1_p_type_pointer
76  MODULE PROCEDURE fm_pools_create_fm_m1_p_type_alloc
77  MODULE PROCEDURE fm_pools_create_fm_m1_array_pointer
78  MODULE PROCEDURE fm_pools_create_fm_m1_array_alloc
79  END INTERFACE
80 
81  INTERFACE fm_pools_give_back_fm_vect
82  MODULE PROCEDURE fm_pools_give_back_fm_m1_p_type_pointer
83  MODULE PROCEDURE fm_pools_give_back_fm_m1_p_type_alloc
84  MODULE PROCEDURE fm_pools_give_back_fm_m1_array_pointer
85  MODULE PROCEDURE fm_pools_give_back_fm_m1_array_alloc
86  END INTERFACE
87 
88 CONTAINS
89 
90 ! **************************************************************************************************
91 !> \brief creates a pool of elements
92 !> \param pool the pool to create
93 !> \param el_struct the structure of the elements that are stored in
94 !> this pool
95 !> \par History
96 !> 08.2002 created [fawzi]
97 !> \author Fawzi Mohamed
98 ! **************************************************************************************************
99  SUBROUTINE fm_pool_create(pool, el_struct)
100  TYPE(cp_fm_pool_type), POINTER :: pool
101  TYPE(cp_fm_struct_type), TARGET :: el_struct
102 
103  ALLOCATE (pool)
104  pool%el_struct => el_struct
105  CALL cp_fm_struct_retain(pool%el_struct)
106  pool%ref_count = 1
107 
108  END SUBROUTINE fm_pool_create
109 
110 ! **************************************************************************************************
111 !> \brief retains the pool (see cp2k/doc/ReferenceCounting.html)
112 !> \param pool the pool to retain
113 !> \par History
114 !> 08.2002 created [fawzi]
115 !> \author Fawzi Mohamed
116 ! **************************************************************************************************
117  SUBROUTINE fm_pool_retain(pool)
118  TYPE(cp_fm_pool_type), INTENT(INOUT) :: pool
119 
120  cpassert(pool%ref_count > 0)
121 
122  pool%ref_count = pool%ref_count + 1
123  END SUBROUTINE fm_pool_retain
124 
125 ! **************************************************************************************************
126 !> \brief deallocates all the cached elements
127 !> \param pool the pool to flush
128 !> \par History
129 !> 08.2002 created [fawzi]
130 !> \author Fawzi Mohamed
131 ! **************************************************************************************************
132  SUBROUTINE fm_pool_flush_cache(pool)
133  TYPE(cp_fm_pool_type), INTENT(IN) :: pool
134 
135  TYPE(cp_fm_type), POINTER :: el_att
136  TYPE(cp_sll_fm_type), POINTER :: iterator
137 
138  iterator => pool%cache
139  DO
140  IF (.NOT. cp_sll_fm_next(iterator, el_att=el_att)) EXIT
141  CALL cp_fm_release(el_att)
142  DEALLOCATE (el_att)
143  NULLIFY (el_att)
144  END DO
145  CALL cp_sll_fm_dealloc(pool%cache)
146  END SUBROUTINE fm_pool_flush_cache
147 
148 ! **************************************************************************************************
149 !> \brief releases the given pool (see cp2k/doc/ReferenceCounting.html)
150 !> \param pool the pool to release
151 !> \par History
152 !> 08.2002 created [fawzi]
153 !> \author Fawzi Mohamed
154 ! **************************************************************************************************
155  SUBROUTINE fm_pool_release(pool)
156  TYPE(cp_fm_pool_type), POINTER :: pool
157 
158  IF (ASSOCIATED(pool)) THEN
159  cpassert(pool%ref_count > 0)
160  pool%ref_count = pool%ref_count - 1
161  IF (pool%ref_count == 0) THEN
162  pool%ref_count = 1
163  CALL fm_pool_flush_cache(pool)
164  CALL cp_fm_struct_release(pool%el_struct)
165  pool%ref_count = 0
166 
167  DEALLOCATE (pool)
168  END IF
169  END IF
170  NULLIFY (pool)
171  END SUBROUTINE fm_pool_release
172 
173 ! **************************************************************************************************
174 !> \brief returns an element, allocating it if none is in the pool
175 !> \param pool the pool from where you get the element
176 !> \param element will contain the new element
177 !>\param name the name for the new matrix (optional)
178 !> \param name ...
179 !> \par History
180 !> 08.2002 created [fawzi]
181 !> \author Fawzi Mohamed
182 ! **************************************************************************************************
183  SUBROUTINE fm_pool_create_fm(pool, element, &
184  name)
185  TYPE(cp_fm_pool_type), INTENT(IN) :: pool
186  TYPE(cp_fm_type), INTENT(OUT) :: element
187  CHARACTER(len=*), INTENT(in), OPTIONAL :: name
188 
189  TYPE(cp_fm_type), POINTER :: el
190 
191  NULLIFY (el)
192  IF (ASSOCIATED(pool%cache)) THEN
193  el => cp_sll_fm_get_first_el(pool%cache)
194  CALL cp_sll_fm_rm_first_el(pool%cache)
195  END IF
196  IF (ASSOCIATED(el)) THEN
197  element = el
198  DEALLOCATE (el)
199  ELSE
200  CALL cp_fm_create(element, matrix_struct=pool%el_struct)
201  END IF
202 
203  IF (PRESENT(name)) THEN
204  element%name = name
205  ELSE
206  element%name = "tmp"
207  END IF
208 
209  END SUBROUTINE fm_pool_create_fm
210 
211 ! **************************************************************************************************
212 !> \brief returns the element to the pool
213 !> \param pool the pool where to cache the element
214 !> \param element the element to give back
215 !> \par History
216 !> 08.2002 created [fawzi]
217 !> \author Fawzi Mohamed
218 !> \note
219 !> transfers the ownership of the element to the pool
220 !> (it is as if you had called cp_fm_release)
221 !> Accept give_backs of non associated elements?
222 ! **************************************************************************************************
223  SUBROUTINE fm_pool_give_back_fm(pool, element)
224  TYPE(cp_fm_pool_type), INTENT(IN) :: pool
225  TYPE(cp_fm_type), INTENT(INOUT) :: element
226 
227  IF (.NOT. ASSOCIATED(pool%el_struct, element%matrix_struct)) THEN
228  CALL cp_fm_release(element)
229  ELSE
230  block
231  TYPE(cp_fm_type), POINTER :: el
232  ALLOCATE (el)
233  el = element
234  CALL cp_sll_fm_insert_el(pool%cache, el=el)
235  NULLIFY (element%matrix_struct, element%local_data, element%local_data_sp)
236  END block
237  END IF
238  END SUBROUTINE fm_pool_give_back_fm
239 
240 ! **************************************************************************************************
241 !> \brief returns the structure of the elements in this pool
242 !> \param pool the pool you are interested in
243 !> \return ...
244 !> \par History
245 !> 05.2002 created [fawzi]
246 !> \author Fawzi Mohamed
247 ! **************************************************************************************************
248  FUNCTION fm_pool_get_el_struct(pool) RESULT(res)
249  TYPE(cp_fm_pool_type), INTENT(IN) :: pool
250  TYPE(cp_fm_struct_type), POINTER :: res
251 
252  res => pool%el_struct
253  END FUNCTION fm_pool_get_el_struct
254 
255 !================== pools ================
256 
257 ! **************************************************************************************************
258 !> \brief shallow copy of an array of pools (retains each pool)
259 !> \param source_pools the pools to copy
260 !> \param target_pools will contains the new pools
261 !> \par History
262 !> 11.2002 created [fawzi]
263 !> \author Fawzi Mohamed
264 ! **************************************************************************************************
265  SUBROUTINE fm_pools_copy(source_pools, target_pools)
266  TYPE(cp_fm_pool_p_type), DIMENSION(:), POINTER :: source_pools, target_pools
267 
268  INTEGER :: i
269 
270  cpassert(ASSOCIATED(source_pools))
271  ALLOCATE (target_pools(SIZE(source_pools)))
272  DO i = 1, SIZE(source_pools)
273  target_pools(i)%pool => source_pools(i)%pool
274  CALL fm_pool_retain(source_pools(i)%pool)
275  END DO
276  END SUBROUTINE fm_pools_copy
277 
278 ! **************************************************************************************************
279 !> \brief deallocate an array of pools (releasing each pool)
280 !> \param pools the pools to release
281 !> \par History
282 !> 11.2002 created [fawzi]
283 !> \author Fawzi Mohamed
284 ! **************************************************************************************************
285  SUBROUTINE fm_pools_dealloc(pools)
286  TYPE(cp_fm_pool_p_type), DIMENSION(:), POINTER :: pools
287 
288  INTEGER :: i
289 
290  IF (ASSOCIATED(pools)) THEN
291  DO i = 1, SIZE(pools)
292  CALL fm_pool_release(pools(i)%pool)
293  END DO
294  DEALLOCATE (pools)
295  END IF
296  END SUBROUTINE fm_pools_dealloc
297 
298 
299 ! **************************************************************************************************
300 !> \brief Returns a vector with an element from each pool
301 !> \param pools the pools to create the elements from
302 !> \param elements will contain the vector of elements
303 !> \param name the name for the new matrixes (optional)
304 !> \par History
305 !> 09.2002 created [fawzi]
306 !> \author Fawzi Mohamed
307 ! **************************************************************************************************
308  SUBROUTINE fm_pools_create_fm_m1_array_alloc (pools, elements, &
309  name)
310  TYPE(cp_fm_pool_p_type), DIMENSION(:), INTENT(IN) :: pools
311  TYPE(cp_fm_type), DIMENSION(:), ALLOCATABLE :: elements
312  CHARACTER(len=*), INTENT(in), OPTIONAL :: name
313 
314  INTEGER :: i
315  TYPE(cp_fm_pool_type), POINTER :: pool
316 
317  NULLIFY (pool)
318 
319  ALLOCATE (elements(SIZE(pools)))
320  DO i = 1, SIZE(pools)
321  pool => pools(i)%pool
322  IF (PRESENT(name)) THEN
323  CALL fm_pool_create_fm(pool, elements(i) , &
324  name=name//"-"//adjustl(cp_to_string(i)))
325  ELSE
326  CALL fm_pool_create_fm(pool, elements(i) )
327  END IF
328 
329  END DO
330 
331  END SUBROUTINE fm_pools_create_fm_m1_array_alloc
332 
333 ! **************************************************************************************************
334 !> \brief returns a vector to the pools. The vector is deallocated
335 !> (like cp_fm_vect_dealloc)
336 !> \param pools the pool where to give back the vector
337 !> \param elements the vector of elements to give back
338 !> \par History
339 !> 09.2002 created [fawzi]
340 !> \author Fawzi Mohamed
341 !> \note
342 !> accept unassociated vect?
343 ! **************************************************************************************************
344  SUBROUTINE fm_pools_give_back_fm_m1_array_alloc (pools, elements)
345  TYPE(cp_fm_pool_p_type), DIMENSION(:), INTENT(IN) :: pools
346  TYPE(cp_fm_type), DIMENSION(:), ALLOCATABLE :: elements
347 
348  INTEGER :: i
349 
350  IF (ALLOCATED (elements)) THEN
351  cpassert(SIZE(pools) == SIZE(elements))
352  DO i = 1, SIZE(pools)
353  CALL fm_pool_give_back_fm(pools(i)%pool, &
354  elements(i) )
355  END DO
356  DEALLOCATE (elements)
357  END IF
358  END SUBROUTINE fm_pools_give_back_fm_m1_array_alloc
359 ! **************************************************************************************************
360 !> \brief Returns a vector with an element from each pool
361 !> \param pools the pools to create the elements from
362 !> \param elements will contain the vector of elements
363 !> \param name the name for the new matrixes (optional)
364 !> \par History
365 !> 09.2002 created [fawzi]
366 !> \author Fawzi Mohamed
367 ! **************************************************************************************************
368  SUBROUTINE fm_pools_create_fm_m1_array_pointer (pools, elements, &
369  name)
370  TYPE(cp_fm_pool_p_type), DIMENSION(:), INTENT(IN) :: pools
371  TYPE(cp_fm_type), DIMENSION(:), POINTER :: elements
372  CHARACTER(len=*), INTENT(in), OPTIONAL :: name
373 
374  INTEGER :: i
375  TYPE(cp_fm_pool_type), POINTER :: pool
376 
377  NULLIFY (pool)
378 
379  ALLOCATE (elements(SIZE(pools)))
380  DO i = 1, SIZE(pools)
381  pool => pools(i)%pool
382  IF (PRESENT(name)) THEN
383  CALL fm_pool_create_fm(pool, elements(i) , &
384  name=name//"-"//adjustl(cp_to_string(i)))
385  ELSE
386  CALL fm_pool_create_fm(pool, elements(i) )
387  END IF
388 
389  END DO
390 
391  END SUBROUTINE fm_pools_create_fm_m1_array_pointer
392 
393 ! **************************************************************************************************
394 !> \brief returns a vector to the pools. The vector is deallocated
395 !> (like cp_fm_vect_dealloc)
396 !> \param pools the pool where to give back the vector
397 !> \param elements the vector of elements to give back
398 !> \par History
399 !> 09.2002 created [fawzi]
400 !> \author Fawzi Mohamed
401 !> \note
402 !> accept unassociated vect?
403 ! **************************************************************************************************
404  SUBROUTINE fm_pools_give_back_fm_m1_array_pointer (pools, elements)
405  TYPE(cp_fm_pool_p_type), DIMENSION(:), INTENT(IN) :: pools
406  TYPE(cp_fm_type), DIMENSION(:), POINTER :: elements
407 
408  INTEGER :: i
409 
410  IF (ASSOCIATED (elements)) THEN
411  cpassert(SIZE(pools) == SIZE(elements))
412  DO i = 1, SIZE(pools)
413  CALL fm_pool_give_back_fm(pools(i)%pool, &
414  elements(i) )
415  END DO
416  DEALLOCATE (elements)
417  NULLIFY (elements)
418  END IF
419  END SUBROUTINE fm_pools_give_back_fm_m1_array_pointer
420 ! **************************************************************************************************
421 !> \brief Returns a vector with an element from each pool
422 !> \param pools the pools to create the elements from
423 !> \param elements will contain the vector of elements
424 !> \param name the name for the new matrixes (optional)
425 !> \par History
426 !> 09.2002 created [fawzi]
427 !> \author Fawzi Mohamed
428 ! **************************************************************************************************
429  SUBROUTINE fm_pools_create_fm_m1_p_type_alloc (pools, elements, &
430  name)
431  TYPE(cp_fm_pool_p_type), DIMENSION(:), INTENT(IN) :: pools
432  TYPE(cp_fm_p_type), DIMENSION(:), ALLOCATABLE :: elements
433  CHARACTER(len=*), INTENT(in), OPTIONAL :: name
434 
435  INTEGER :: i
436  TYPE(cp_fm_pool_type), POINTER :: pool
437 
438  NULLIFY (pool)
439 
440  ALLOCATE (elements(SIZE(pools)))
441  DO i = 1, SIZE(pools)
442  pool => pools(i)%pool
443  ALLOCATE (elements(i)%matrix)
444  IF (PRESENT(name)) THEN
445  CALL fm_pool_create_fm(pool, elements(i) %matrix, &
446  name=name//"-"//adjustl(cp_to_string(i)))
447  ELSE
448  CALL fm_pool_create_fm(pool, elements(i) %matrix)
449  END IF
450 
451  END DO
452 
453  END SUBROUTINE fm_pools_create_fm_m1_p_type_alloc
454 
455 ! **************************************************************************************************
456 !> \brief returns a vector to the pools. The vector is deallocated
457 !> (like cp_fm_vect_dealloc)
458 !> \param pools the pool where to give back the vector
459 !> \param elements the vector of elements to give back
460 !> \par History
461 !> 09.2002 created [fawzi]
462 !> \author Fawzi Mohamed
463 !> \note
464 !> accept unassociated vect?
465 ! **************************************************************************************************
466  SUBROUTINE fm_pools_give_back_fm_m1_p_type_alloc (pools, elements)
467  TYPE(cp_fm_pool_p_type), DIMENSION(:), INTENT(IN) :: pools
468  TYPE(cp_fm_p_type), DIMENSION(:), ALLOCATABLE :: elements
469 
470  INTEGER :: i
471 
472  IF (ALLOCATED (elements)) THEN
473  cpassert(SIZE(pools) == SIZE(elements))
474  DO i = 1, SIZE(pools)
475  CALL fm_pool_give_back_fm(pools(i)%pool, &
476  elements(i) %matrix)
477  DEALLOCATE (elements(i)%matrix)
478  END DO
479  DEALLOCATE (elements)
480  END IF
481  END SUBROUTINE fm_pools_give_back_fm_m1_p_type_alloc
482 ! **************************************************************************************************
483 !> \brief Returns a vector with an element from each pool
484 !> \param pools the pools to create the elements from
485 !> \param elements will contain the vector of elements
486 !> \param name the name for the new matrixes (optional)
487 !> \par History
488 !> 09.2002 created [fawzi]
489 !> \author Fawzi Mohamed
490 ! **************************************************************************************************
491  SUBROUTINE fm_pools_create_fm_m1_p_type_pointer (pools, elements, &
492  name)
493  TYPE(cp_fm_pool_p_type), DIMENSION(:), INTENT(IN) :: pools
494  TYPE(cp_fm_p_type), DIMENSION(:), POINTER :: elements
495  CHARACTER(len=*), INTENT(in), OPTIONAL :: name
496 
497  INTEGER :: i
498  TYPE(cp_fm_pool_type), POINTER :: pool
499 
500  NULLIFY (pool)
501 
502  ALLOCATE (elements(SIZE(pools)))
503  DO i = 1, SIZE(pools)
504  pool => pools(i)%pool
505  ALLOCATE (elements(i)%matrix)
506  IF (PRESENT(name)) THEN
507  CALL fm_pool_create_fm(pool, elements(i) %matrix, &
508  name=name//"-"//adjustl(cp_to_string(i)))
509  ELSE
510  CALL fm_pool_create_fm(pool, elements(i) %matrix)
511  END IF
512 
513  END DO
514 
515  END SUBROUTINE fm_pools_create_fm_m1_p_type_pointer
516 
517 ! **************************************************************************************************
518 !> \brief returns a vector to the pools. The vector is deallocated
519 !> (like cp_fm_vect_dealloc)
520 !> \param pools the pool where to give back the vector
521 !> \param elements the vector of elements to give back
522 !> \par History
523 !> 09.2002 created [fawzi]
524 !> \author Fawzi Mohamed
525 !> \note
526 !> accept unassociated vect?
527 ! **************************************************************************************************
528  SUBROUTINE fm_pools_give_back_fm_m1_p_type_pointer (pools, elements)
529  TYPE(cp_fm_pool_p_type), DIMENSION(:), INTENT(IN) :: pools
530  TYPE(cp_fm_p_type), DIMENSION(:), POINTER :: elements
531 
532  INTEGER :: i
533 
534  IF (ASSOCIATED (elements)) THEN
535  cpassert(SIZE(pools) == SIZE(elements))
536  DO i = 1, SIZE(pools)
537  CALL fm_pool_give_back_fm(pools(i)%pool, &
538  elements(i) %matrix)
539  DEALLOCATE (elements(i)%matrix)
540  END DO
541  DEALLOCATE (elements)
542  NULLIFY (elements)
543  END IF
544  END SUBROUTINE fm_pools_give_back_fm_m1_p_type_pointer
545 
546 END MODULE cp_fm_pool_types
pool for for elements that are retained and released
subroutine, public fm_pool_create_fm(pool, element, name)
returns an element, allocating it if none is in the pool
subroutine, public fm_pool_create(pool, el_struct)
creates a pool of elements
subroutine, public fm_pool_release(pool)
releases the given pool (see cp2k/doc/ReferenceCounting.html)
subroutine, public fm_pool_give_back_fm(pool, element)
returns the element to the pool
subroutine, public fm_pool_retain(pool)
retains the pool (see cp2k/doc/ReferenceCounting.html)
subroutine, public fm_pools_dealloc(pools)
deallocate an array of pools (releasing each pool)
type(cp_fm_struct_type) function, pointer, public fm_pool_get_el_struct(pool)
returns the structure of the elements in this pool
represent the structure of a full matrix
Definition: cp_fm_struct.F:14
subroutine, public cp_fm_struct_retain(fmstruct)
retains a full matrix structure
Definition: cp_fm_struct.F:306
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
Definition: cp_fm_struct.F:320
represent a full matrix distributed on many processors
Definition: cp_fm_types.F:15
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
Definition: cp_fm_types.F:167
subroutine, public cp_sll_fm_insert_el(sll, el)
insert an element at the beginning of the list
logical function, public cp_sll_fm_next(iterator, el_att)
returns true if the actual element is valid (i.e. iterator ont at end) moves the iterator to the next...
type(cp_fm_type) function, pointer, public cp_sll_fm_get_first_el(sll)
returns the first element stored in the list
subroutine, public cp_sll_fm_dealloc(sll)
deallocates the singly linked list starting at sll. Does not work if loops are present!
subroutine, public cp_sll_fm_rm_first_el(sll)
remove the first element of the linked list
various routines to log and control the output. The idea is that decisions about where to log should ...