LCOV - code coverage report
Current view: top level - src - qs_fb_matrix_data_types.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:d1f8d1b) Lines: 78 106 73.6 %
Date: 2024-11-29 06:42:44 Functions: 8 12 66.7 %

          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             : MODULE qs_fb_matrix_data_types
       9             : 
      10             :    USE kinds,                           ONLY: dp,&
      11             :                                               int_8
      12             :    USE qs_fb_buffer_types,              ONLY: fb_buffer_add,&
      13             :                                               fb_buffer_create,&
      14             :                                               fb_buffer_d_obj,&
      15             :                                               fb_buffer_get,&
      16             :                                               fb_buffer_has_data,&
      17             :                                               fb_buffer_nullify,&
      18             :                                               fb_buffer_release,&
      19             :                                               fb_buffer_replace
      20             :    USE qs_fb_hash_table_types,          ONLY: fb_hash_table_add,&
      21             :                                               fb_hash_table_create,&
      22             :                                               fb_hash_table_get,&
      23             :                                               fb_hash_table_has_data,&
      24             :                                               fb_hash_table_nullify,&
      25             :                                               fb_hash_table_obj,&
      26             :                                               fb_hash_table_release
      27             : #include "./base/base_uses.f90"
      28             : 
      29             :    IMPLICIT NONE
      30             : 
      31             :    PRIVATE
      32             : 
      33             :    ! public types
      34             :    PUBLIC :: fb_matrix_data_obj
      35             : 
      36             :    ! public methods
      37             :    !API
      38             :    PUBLIC :: fb_matrix_data_add, &
      39             :              fb_matrix_data_create, &
      40             :              fb_matrix_data_get, &
      41             :              fb_matrix_data_has_data, &
      42             :              fb_matrix_data_nullify, &
      43             :              fb_matrix_data_release
      44             : 
      45             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_fb_matrix_data_types'
      46             : 
      47             :    ! Parameters related to automatic resizing of matrix_data:
      48             :    INTEGER, PARAMETER, PRIVATE :: EXPAND_FACTOR = 2
      49             : 
      50             : ! **************************************************************************************************
      51             : !> \brief data type for storing a list of matrix blocks
      52             : !> \param nmax      : maximum number of blocks can be stored
      53             : !> \param nblks     : number of blocks currently stored
      54             : !> \param nencode   : integer used to encode global block coordinate (row, col)
      55             : !>                    into a single combined integer
      56             : !> \param ind       : hash table maping the global combined index of the blocks
      57             : !>                    to the location in the data area
      58             : !> \param blks      : data area, well the matrix elements are actuaally stored
      59             : !> \param lds       : leading dimensions of each block
      60             : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
      61             : ! **************************************************************************************************
      62             :    TYPE fb_matrix_data_data
      63             :       INTEGER :: nmax = -1
      64             :       INTEGER :: nblks = -1
      65             :       INTEGER :: nencode = -1
      66             :       TYPE(fb_hash_table_obj) :: ind = fb_hash_table_obj()
      67             :       TYPE(fb_buffer_d_obj) :: blks = fb_buffer_d_obj()
      68             :       INTEGER, DIMENSION(:), POINTER :: lds => NULL()
      69             :    END TYPE fb_matrix_data_data
      70             : 
      71             : ! **************************************************************************************************
      72             : !> \brief the object container which allows for the creation of an array
      73             : !>        of pointers to fb_matrix_data objects
      74             : !> \param obj : pointer to the fb_matrix_data object
      75             : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
      76             : ! **************************************************************************************************
      77             :    TYPE fb_matrix_data_obj
      78             :       TYPE(fb_matrix_data_data), POINTER, PRIVATE :: obj => NULL()
      79             :    END TYPE fb_matrix_data_obj
      80             : 
      81             : CONTAINS
      82             : 
      83             : ! **************************************************************************************************
      84             : !> \brief Add a matrix block to a fb_matrix_data object
      85             : !> \param matrix_data : the fb_matrix_data object
      86             : !> \param row         : block row index of the matrix block
      87             : !> \param col         : block col index of the matrix block
      88             : !> \param blk         : the matrix block to add
      89             : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
      90             : ! **************************************************************************************************
      91        1664 :    SUBROUTINE fb_matrix_data_add(matrix_data, row, col, blk)
      92             :       TYPE(fb_matrix_data_obj), INTENT(INOUT)            :: matrix_data
      93             :       INTEGER, INTENT(IN)                                :: row, col
      94             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: blk
      95             : 
      96             :       INTEGER                                            :: existing_ii, ii, ncols, nrows, old_nblks
      97             :       INTEGER(KIND=int_8)                                :: pair_ind
      98        1664 :       INTEGER, DIMENSION(:), POINTER                     :: new_lds
      99             :       LOGICAL                                            :: check_ok, found
     100             : 
     101        1664 :       check_ok = fb_matrix_data_has_data(matrix_data)
     102           0 :       CPASSERT(check_ok)
     103        1664 :       NULLIFY (new_lds)
     104        1664 :       nrows = SIZE(blk, 1)
     105        1664 :       ncols = SIZE(blk, 2)
     106             :       ! first check if the block already exists in matrix_data
     107        1664 :       pair_ind = fb_matrix_data_encode_pair(row, col, matrix_data%obj%nencode)
     108        1664 :       CALL fb_hash_table_get(matrix_data%obj%ind, pair_ind, existing_ii, found)
     109        1664 :       IF (found) THEN
     110           0 :          CALL fb_buffer_replace(matrix_data%obj%blks, existing_ii, RESHAPE(blk, (/nrows*ncols/)))
     111             :       ELSE
     112        1664 :          old_nblks = matrix_data%obj%nblks
     113        1664 :          matrix_data%obj%nblks = old_nblks + 1
     114        1664 :          ii = matrix_data%obj%nblks
     115             :          ! resize lds if necessary
     116        1664 :          IF (SIZE(matrix_data%obj%lds) .LT. ii) THEN
     117         720 :             ALLOCATE (new_lds(ii*EXPAND_FACTOR))
     118        5712 :             new_lds = 0
     119        2736 :             new_lds(1:old_nblks) = matrix_data%obj%lds(1:old_nblks)
     120         240 :             DEALLOCATE (matrix_data%obj%lds)
     121         240 :             matrix_data%obj%lds => new_lds
     122             :          END IF
     123             :          ! add data block
     124        1664 :          matrix_data%obj%lds(ii) = nrows
     125        3328 :          CALL fb_buffer_add(matrix_data%obj%blks, RESHAPE(blk, (/nrows*ncols/)))
     126             :          ! record blk index in the index table
     127        1664 :          CALL fb_hash_table_add(matrix_data%obj%ind, pair_ind, ii)
     128             :       END IF
     129        1664 :    END SUBROUTINE fb_matrix_data_add
     130             : 
     131             : ! **************************************************************************************************
     132             : !> \brief Associates one fb_matrix_data object to another
     133             : !> \param a : the fb_matrix_data object to be associated
     134             : !> \param b : the fb_matrix_data object that a is to be associated to
     135             : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     136             : ! **************************************************************************************************
     137           0 :    SUBROUTINE fb_matrix_data_associate(a, b)
     138             :       TYPE(fb_matrix_data_obj), INTENT(OUT)              :: a
     139             :       TYPE(fb_matrix_data_obj), INTENT(IN)               :: b
     140             : 
     141           0 :       a%obj => b%obj
     142           0 :    END SUBROUTINE fb_matrix_data_associate
     143             : 
     144             : ! **************************************************************************************************
     145             : !> \brief Creates and initialises an empty fb_matrix_data object of a given size
     146             : !> \param matrix_data : the fb_matrix_data object, its content must be NULL
     147             : !>                      and cannot be UNDEFINED
     148             : !> \param nmax        : max number of matrix blks can be stored
     149             : !> \param nencode ...
     150             : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     151             : ! **************************************************************************************************
     152          48 :    SUBROUTINE fb_matrix_data_create(matrix_data, nmax, nencode)
     153             :       TYPE(fb_matrix_data_obj), INTENT(OUT)              :: matrix_data
     154             :       INTEGER, INTENT(IN)                                :: nmax, nencode
     155             : 
     156             :       NULLIFY (matrix_data%obj)
     157          48 :       ALLOCATE (matrix_data%obj)
     158          48 :       CALL fb_hash_table_nullify(matrix_data%obj%ind)
     159          48 :       CALL fb_buffer_nullify(matrix_data%obj%blks)
     160          48 :       NULLIFY (matrix_data%obj%lds)
     161          48 :       matrix_data%obj%nmax = 0
     162          48 :       matrix_data%obj%nblks = 0
     163          48 :       matrix_data%obj%nencode = nencode
     164             :       CALL fb_matrix_data_init(matrix_data=matrix_data, &
     165             :                                nmax=nmax, &
     166          48 :                                nencode=nencode)
     167             :       ! book keeping stuff
     168          48 :    END SUBROUTINE fb_matrix_data_create
     169             : 
     170             : ! **************************************************************************************************
     171             : !> \brief retrieve a matrix block from a matrix_data object
     172             : !> \param matrix_data : the fb_matrix_data object
     173             : !> \param row         : row index
     174             : !> \param col         : col index
     175             : !> \param blk_p       : pointer to the block in the fb_matrix_data object
     176             : !> \param found       : if the requested block exists in the fb_matrix_data
     177             : !>                      object
     178             : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     179             : ! **************************************************************************************************
     180       10240 :    SUBROUTINE fb_matrix_data_get(matrix_data, row, col, blk_p, found)
     181             :       TYPE(fb_matrix_data_obj), INTENT(IN)               :: matrix_data
     182             :       INTEGER, INTENT(IN)                                :: row, col
     183             :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: blk_p
     184             :       LOGICAL, INTENT(OUT)                               :: found
     185             : 
     186             :       INTEGER                                            :: ind_in_blks
     187             :       INTEGER(KIND=int_8)                                :: pair_ind
     188             :       LOGICAL                                            :: check_ok
     189             : 
     190        5120 :       check_ok = fb_matrix_data_has_data(matrix_data)
     191        5120 :       CPASSERT(check_ok)
     192        5120 :       pair_ind = fb_matrix_data_encode_pair(row, col, matrix_data%obj%nencode)
     193        5120 :       CALL fb_hash_table_get(matrix_data%obj%ind, pair_ind, ind_in_blks, found)
     194        5120 :       IF (found) THEN
     195             :          CALL fb_buffer_get(buffer=matrix_data%obj%blks, &
     196             :                             i_slice=ind_in_blks, &
     197             :                             data_2d=blk_p, &
     198        5120 :                             data_2d_ld=matrix_data%obj%lds(ind_in_blks))
     199             :       ELSE
     200           0 :          NULLIFY (blk_p)
     201             :       END IF
     202        5120 :    END SUBROUTINE fb_matrix_data_get
     203             : 
     204             : ! **************************************************************************************************
     205             : !> \brief check if the object has data associated to it
     206             : !> \param matrix_data : the fb_matrix_data object in question
     207             : !> \return : true if matrix_data%obj is associated, false otherwise
     208             : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     209             : ! **************************************************************************************************
     210        7136 :    PURE FUNCTION fb_matrix_data_has_data(matrix_data) RESULT(res)
     211             :       TYPE(fb_matrix_data_obj), INTENT(IN)               :: matrix_data
     212             :       LOGICAL                                            :: res
     213             : 
     214        7136 :       res = ASSOCIATED(matrix_data%obj)
     215        7136 :    END FUNCTION fb_matrix_data_has_data
     216             : 
     217             : ! **************************************************************************************************
     218             : !> \brief Initialises a fb_matrix_data object of a given size
     219             : !> \param matrix_data : the fb_matrix_data object, its content must be NULL
     220             : !>                      and cannot be UNDEFINED
     221             : !> \param nmax        : max number of matrix blocks can be stored, default is
     222             : !>                      to use the existing number of blocks in matrix_data
     223             : !> \param nencode     : integer used to incode (row, col) to a single combined
     224             : !>                      index
     225             : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     226             : ! **************************************************************************************************
     227          48 :    SUBROUTINE fb_matrix_data_init(matrix_data, nmax, nencode)
     228             :       TYPE(fb_matrix_data_obj), INTENT(INOUT)            :: matrix_data
     229             :       INTEGER, INTENT(IN), OPTIONAL                      :: nmax, nencode
     230             : 
     231             :       INTEGER                                            :: my_nmax
     232             :       LOGICAL                                            :: check_ok
     233             : 
     234          48 :       check_ok = fb_matrix_data_has_data(matrix_data)
     235          48 :       CPASSERT(check_ok)
     236          48 :       my_nmax = matrix_data%obj%nmax
     237          48 :       IF (PRESENT(nmax)) my_nmax = nmax
     238          48 :       my_nmax = MAX(my_nmax, 1)
     239          48 :       IF (fb_hash_table_has_data(matrix_data%obj%ind)) THEN
     240           0 :          CALL fb_hash_table_release(matrix_data%obj%ind)
     241             :       END IF
     242          48 :       CALL fb_hash_table_create(matrix_data%obj%ind, my_nmax)
     243          48 :       IF (fb_buffer_has_data(matrix_data%obj%blks)) THEN
     244           0 :          CALL fb_buffer_release(matrix_data%obj%blks)
     245             :       END IF
     246          48 :       CALL fb_buffer_create(buffer=matrix_data%obj%blks)
     247          48 :       IF (ASSOCIATED(matrix_data%obj%lds)) THEN
     248           0 :          DEALLOCATE (matrix_data%obj%lds)
     249             :       END IF
     250          48 :       ALLOCATE (matrix_data%obj%lds(0))
     251          48 :       matrix_data%obj%nblks = 0
     252          48 :       IF (PRESENT(nencode)) matrix_data%obj%nencode = nencode
     253          48 :    END SUBROUTINE fb_matrix_data_init
     254             : 
     255             : ! **************************************************************************************************
     256             : !> \brief Nullifies a fb_matrix_data object
     257             : !> \param matrix_data : the fb_matrix_data object
     258             : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     259             : ! **************************************************************************************************
     260          48 :    PURE SUBROUTINE fb_matrix_data_nullify(matrix_data)
     261             :       TYPE(fb_matrix_data_obj), INTENT(INOUT)            :: matrix_data
     262             : 
     263          48 :       NULLIFY (matrix_data%obj)
     264          48 :    END SUBROUTINE fb_matrix_data_nullify
     265             : 
     266             : ! **************************************************************************************************
     267             : !> \brief releases given object
     268             : !> \param matrix_data : the fb_matrix_data object in question
     269             : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     270             : ! **************************************************************************************************
     271          48 :    SUBROUTINE fb_matrix_data_release(matrix_data)
     272             :       TYPE(fb_matrix_data_obj), INTENT(INOUT)            :: matrix_data
     273             : 
     274          48 :       IF (ASSOCIATED(matrix_data%obj)) THEN
     275          48 :          IF (fb_hash_table_has_data(matrix_data%obj%ind)) THEN
     276          48 :             CALL fb_hash_table_release(matrix_data%obj%ind)
     277             :          END IF
     278          48 :          IF (fb_buffer_has_data(matrix_data%obj%blks)) THEN
     279          48 :             CALL fb_buffer_release(matrix_data%obj%blks)
     280             :          END IF
     281          48 :          IF (ASSOCIATED(matrix_data%obj%lds)) THEN
     282          48 :             DEALLOCATE (matrix_data%obj%lds)
     283             :          END IF
     284          48 :          DEALLOCATE (matrix_data%obj)
     285             :       END IF
     286          48 :       NULLIFY (matrix_data%obj)
     287          48 :    END SUBROUTINE fb_matrix_data_release
     288             : 
     289             : ! **************************************************************************************************
     290             : !> \brief outputs the current information about fb_matrix_data object
     291             : !> \param matrix_data : the fb_matrix_data object
     292             : !> \param nmax        : outputs fb_matrix_data%obj%nmax
     293             : !> \param nblks       : outputs fb_matrix_data%obj%nblks
     294             : !> \param nencode     : outputs fb_matrix_data%obj%nencode
     295             : !> \param blk_sizes   : blk_sizes(ii,jj) gives size of jj-th dim of the
     296             : !>                      ii-th block stored
     297             : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     298             : ! **************************************************************************************************
     299           0 :    SUBROUTINE fb_matrix_data_status(matrix_data, nmax, nblks, nencode, blk_sizes)
     300             :       TYPE(fb_matrix_data_obj), INTENT(INOUT)            :: matrix_data
     301             :       INTEGER, INTENT(OUT), OPTIONAL                     :: nmax, nblks, nencode
     302             :       INTEGER, DIMENSION(:, :), INTENT(OUT), OPTIONAL    :: blk_sizes
     303             : 
     304             :       INTEGER                                            :: ii
     305           0 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: buffer_sizes
     306             :       LOGICAL                                            :: check_ok
     307             : 
     308           0 :       check_ok = fb_matrix_data_has_data(matrix_data)
     309           0 :       CPASSERT(check_ok)
     310           0 :       IF (PRESENT(nmax)) nmax = matrix_data%obj%nmax
     311           0 :       IF (PRESENT(nblks)) nblks = matrix_data%obj%nblks
     312           0 :       IF (PRESENT(nencode)) nencode = matrix_data%obj%nencode
     313           0 :       IF (PRESENT(blk_sizes)) THEN
     314             :          check_ok = (SIZE(blk_sizes, 1) .GE. matrix_data%obj%nblks .AND. &
     315           0 :                      SIZE(blk_sizes, 2) .GE. 2)
     316           0 :          CPASSERT(check_ok)
     317           0 :          blk_sizes(:, :) = 0
     318           0 :          ALLOCATE (buffer_sizes(matrix_data%obj%nblks))
     319             :          CALL fb_buffer_get(buffer=matrix_data%obj%blks, &
     320           0 :                             sizes=buffer_sizes)
     321           0 :          DO ii = 1, matrix_data%obj%nblks
     322           0 :             blk_sizes(ii, 1) = matrix_data%obj%lds(ii)
     323           0 :             blk_sizes(ii, 2) = buffer_sizes(ii)/matrix_data%obj%lds(ii)
     324             :          END DO
     325           0 :          DEALLOCATE (buffer_sizes)
     326             :       END IF
     327           0 :    END SUBROUTINE fb_matrix_data_status
     328             : 
     329             : ! **************************************************************************************************
     330             : !> \brief Encodes (row, col) index pair into a single combined index
     331             : !> \param row     : row index (assume to start counting from 1)
     332             : !> \param col     : col index (assume to start counting from 1)
     333             : !> \param nencode : integer used for encoding
     334             : !> \return : the returned value
     335             : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     336             : ! **************************************************************************************************
     337        6784 :    PURE FUNCTION fb_matrix_data_encode_pair(row, col, nencode) &
     338             :       RESULT(pair_ind)
     339             :       INTEGER, INTENT(IN)                                :: row, col, nencode
     340             :       INTEGER(KIND=int_8)                                :: pair_ind
     341             : 
     342             :       INTEGER(KIND=int_8)                                :: col_8, nencode_8, row_8
     343             : 
     344        6784 :       row_8 = INT(row, int_8)
     345        6784 :       col_8 = INT(col, int_8)
     346        6784 :       nencode_8 = INT(nencode, int_8)
     347        6784 :       pair_ind = (row_8 - 1_int_8)*nencode_8 + (col_8 - 1_int_8) + 1
     348        6784 :    END FUNCTION fb_matrix_data_encode_pair
     349             : 
     350           0 : END MODULE qs_fb_matrix_data_types

Generated by: LCOV version 1.15