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: BSD-3-Clause */ 6 : /*----------------------------------------------------------------------------*/ 7 : 8 : #ifndef DBM_MATRIX_H 9 : #define DBM_MATRIX_H 10 : 11 : #include <stdbool.h> 12 : 13 : #include "dbm_distribution.h" 14 : #include "dbm_shard.h" 15 : 16 : /******************************************************************************* 17 : * \brief Internal struct for storing a matrix. 18 : * \author Ole Schuett 19 : ******************************************************************************/ 20 : typedef struct { 21 : dbm_distribution_t *dist; 22 : char *name; 23 : int nrows; 24 : int ncols; 25 : int *row_sizes; 26 : int *col_sizes; 27 : 28 : dbm_shard_t *shards; 29 : } dbm_matrix_t; 30 : 31 : /******************************************************************************* 32 : * \brief Internal struct for storing a block iterator. 33 : * \author Ole Schuett 34 : ******************************************************************************/ 35 : typedef struct { 36 : const dbm_matrix_t *matrix; 37 : int next_block; 38 : int next_shard; 39 : } dbm_iterator_t; 40 : 41 : /******************************************************************************* 42 : * \brief Creates a new matrix. 43 : * \author Ole Schuett 44 : ******************************************************************************/ 45 : void dbm_create(dbm_matrix_t **matrix_out, dbm_distribution_t *dist, 46 : const char name[], const int nrows, const int ncols, 47 : const int row_sizes[nrows], const int col_sizes[ncols]); 48 : 49 : /******************************************************************************* 50 : * \brief Releases a matrix and all its ressources. 51 : * \author Ole Schuett 52 : ******************************************************************************/ 53 : void dbm_release(dbm_matrix_t *matrix); 54 : 55 : /******************************************************************************* 56 : * \brief Copies content of matrix_b into matrix_a. 57 : * Matrices must have the same row/col block sizes and distribution. 58 : * \author Ole Schuett 59 : ******************************************************************************/ 60 : void dbm_copy(dbm_matrix_t *matrix_a, const dbm_matrix_t *matrix_b); 61 : 62 : /******************************************************************************* 63 : * \brief Copies content of matrix_b into matrix_a. 64 : * Matrices may have different distributions. 65 : * \author Ole Schuett 66 : ******************************************************************************/ 67 : void dbm_redistribute(const dbm_matrix_t *matrix, dbm_matrix_t *redist); 68 : 69 : /******************************************************************************* 70 : * \brief Looks up a block from given matrics. This routine is thread-safe. 71 : * If the block is not found then a null pointer is returned. 72 : * \author Ole Schuett 73 : ******************************************************************************/ 74 : void dbm_get_block_p(dbm_matrix_t *matrix, const int row, const int col, 75 : double **block, int *row_size, int *col_size); 76 : 77 : /******************************************************************************* 78 : * \brief Adds a block to given matrix. This routine is thread-safe. 79 : * If block already exist then it gets overwritten (or summed). 80 : * \author Ole Schuett 81 : ******************************************************************************/ 82 : void dbm_put_block(dbm_matrix_t *matrix, const int row, const int col, 83 : const bool summation, const double *block); 84 : 85 : /******************************************************************************* 86 : * \brief Remove all blocks from matrix, but does not release underlying memory. 87 : * \author Ole Schuett 88 : ******************************************************************************/ 89 : void dbm_clear(dbm_matrix_t *matrix); 90 : 91 : /******************************************************************************* 92 : * \brief Removes all blocks from the matrix whose norm is below the threshold. 93 : * Blocks of size zero are always kept. 94 : * \author Ole Schuett 95 : ******************************************************************************/ 96 : void dbm_filter(dbm_matrix_t *matrix, const double eps); 97 : 98 : /******************************************************************************* 99 : * \brief Adds list of blocks efficiently. The blocks will be filled with zeros. 100 : * This routine must always be called within an OpenMP parallel region. 101 : * \author Ole Schuett 102 : ******************************************************************************/ 103 : void dbm_reserve_blocks(dbm_matrix_t *matrix, const int nblocks, 104 : const int rows[], const int cols[]); 105 : 106 : /******************************************************************************* 107 : * \brief Multiplies all entries in the given matrix by the given factor alpha. 108 : * \author Ole Schuett 109 : ******************************************************************************/ 110 : void dbm_scale(dbm_matrix_t *matrix, const double alpha); 111 : 112 : /******************************************************************************* 113 : * \brief Sets all blocks in the given matrix to zero. 114 : * \author Ole Schuett 115 : ******************************************************************************/ 116 : void dbm_zero(dbm_matrix_t *matrix); 117 : 118 : /******************************************************************************* 119 : * \brief Adds matrix_b to matrix_a. 120 : * \author Ole Schuett 121 : ******************************************************************************/ 122 : void dbm_add(dbm_matrix_t *matrix_a, const dbm_matrix_t *matrix_b); 123 : 124 : /******************************************************************************* 125 : * \brief Creates an iterator for the blocks of the given matrix. 126 : * The iteration order is not stable. 127 : * This routine must always be called within an OpenMP parallel region. 128 : * \author Ole Schuett 129 : ******************************************************************************/ 130 : void dbm_iterator_start(dbm_iterator_t **iter_out, const dbm_matrix_t *matrix); 131 : 132 : /******************************************************************************* 133 : * \brief Returns number of blocks the iterator will provide to calling thread. 134 : * \author Ole Schuett 135 : ******************************************************************************/ 136 : int dbm_iterator_num_blocks(const dbm_iterator_t *iter); 137 : 138 : /******************************************************************************* 139 : * \brief Tests whether the given iterator has any block left. 140 : * \author Ole Schuett 141 : ******************************************************************************/ 142 : bool dbm_iterator_blocks_left(const dbm_iterator_t *iter); 143 : 144 : /******************************************************************************* 145 : * \brief Returns the next block from the given iterator. 146 : * \author Ole Schuett 147 : ******************************************************************************/ 148 : void dbm_iterator_next_block(dbm_iterator_t *iter, int *row, int *col, 149 : double **block, int *row_size, int *col_size); 150 : 151 : /******************************************************************************* 152 : * \brief Releases the given iterator. 153 : * \author Ole Schuett 154 : ******************************************************************************/ 155 : void dbm_iterator_stop(dbm_iterator_t *iter); 156 : 157 : /******************************************************************************* 158 : * \brief Computes a checksum of the given matrix. 159 : * \author Ole Schuett 160 : ******************************************************************************/ 161 : double dbm_checksum(const dbm_matrix_t *matrix); 162 : 163 : /******************************************************************************* 164 : * \brief Returns the absolute value of the larges element of the entire matrix. 165 : * \author Ole Schuett 166 : ******************************************************************************/ 167 : double dbm_maxabs(const dbm_matrix_t *matrix); 168 : 169 : /******************************************************************************* 170 : * \brief Returns the name of the matrix of the given matrix. 171 : * \author Ole Schuett 172 : ******************************************************************************/ 173 : const char *dbm_get_name(const dbm_matrix_t *matrix); 174 : 175 : /******************************************************************************* 176 : * \brief Returns the number of local Non-Zero Elements of the given matrix. 177 : * \author Ole Schuett 178 : ******************************************************************************/ 179 : int dbm_get_nze(const dbm_matrix_t *matrix); 180 : 181 : /******************************************************************************* 182 : * \brief Returns the number of local blocks of the given matrix. 183 : * \author Ole Schuett 184 : ******************************************************************************/ 185 : int dbm_get_num_blocks(const dbm_matrix_t *matrix); 186 : 187 : /******************************************************************************* 188 : * \brief Returns the row block sizes of the given matrix. 189 : * \author Ole Schuett 190 : ******************************************************************************/ 191 : void dbm_get_row_sizes(const dbm_matrix_t *matrix, int *nrows, 192 : const int **row_sizes); 193 : 194 : /******************************************************************************* 195 : * \brief Returns the column block sizes of the given matrix. 196 : * \author Ole Schuett 197 : ******************************************************************************/ 198 : void dbm_get_col_sizes(const dbm_matrix_t *matrix, int *ncols, 199 : const int **col_sizes); 200 : 201 : /******************************************************************************* 202 : * \brief Returns the local row block sizes of the given matrix. 203 : * \author Ole Schuett 204 : ******************************************************************************/ 205 : void dbm_get_local_rows(const dbm_matrix_t *matrix, int *nlocal_rows, 206 : const int **local_rows); 207 : 208 : /******************************************************************************* 209 : * \brief Returns the local column block sizes of the given matrix. 210 : * \author Ole Schuett 211 : ******************************************************************************/ 212 : void dbm_get_local_cols(const dbm_matrix_t *matrix, int *nlocal_cols, 213 : const int **local_cols); 214 : 215 : /******************************************************************************* 216 : * \brief Returns the MPI rank on which the given block should be stored. 217 : * \author Ole Schuett 218 : ******************************************************************************/ 219 : int dbm_get_stored_coordinates(const dbm_matrix_t *matrix, const int row, 220 : const int col); 221 : 222 : /******************************************************************************* 223 : * \brief Returns the distribution of the given matrix. 224 : * \author Ole Schuett 225 : ******************************************************************************/ 226 : const dbm_distribution_t *dbm_get_distribution(const dbm_matrix_t *matrix); 227 : 228 : /******************************************************************************* 229 : * \brief Internal routine that returns the number of shards for given matrix. 230 : * \author Ole Schuett 231 : ******************************************************************************/ 232 142300862 : static inline int dbm_get_num_shards(const dbm_matrix_t *matrix) { 233 84940726 : return matrix->dist->rows.nshards * matrix->dist->cols.nshards; 234 : } 235 : 236 : /******************************************************************************* 237 : * \brief Internal routine for getting a block's shard index. 238 : * \author Ole Schuett 239 : ******************************************************************************/ 240 50224370 : static inline int dbm_get_shard_index(const dbm_matrix_t *matrix, const int row, 241 : const int col) { 242 85237001 : const int shard_row = row % matrix->dist->rows.nshards; 243 85237001 : const int shard_col = col % matrix->dist->cols.nshards; 244 85237001 : return shard_row * matrix->dist->cols.nshards + shard_col; 245 : } 246 : 247 : #endif 248 : 249 : // EOF