1 /* 2 3 Copyright (C) 2008-2021 Michele Martone 4 5 This file is part of librsb. 6 7 librsb is free software; you can redistribute it and/or modify it 8 under the terms of the GNU Lesser General Public License as published 9 by the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 librsb is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 License for more details. 16 17 You should have received a copy of the GNU Lesser General Public 18 License along with librsb; see the file COPYING. 19 If not, see <http://www.gnu.org/licenses/>. 20 21 */ 22 /* @cond INNERDOC */ 23 /*! 24 * @file 25 * @author Michele Martone 26 * @brief 27 * This source file contains locks for sparse recursive multicore operations. 28 * */ 29 30 #ifndef RSB_LOCK_H_INCLUDED 31 #define RSB_LOCK_H_INCLUDED 32 33 #include "rsb_internals.h" 34 35 #define RSB__TRSV_OUT 0 36 #define RSB__TRSV_OUT_ 0 37 #define RSB__TRSV_OUT__ 0 38 39 #define RSB_CONST_MIN_SUPPORTED_CORES 1 40 #define RSB_CONST_MAX_SUPPORTED_CORES RSB_CONST_MAX_SUPPORTED_THREADS /* The maximum number of cores (TODO: support any number of cores) */ 41 #define RSB_CONST_MAX_SUPPORTED_TEMPORARY_VECTORS RSB_CONST_MAX_SUPPORTED_CORES 42 43 typedef int rsb_thr_t; 44 45 /*! 46 * \ingroup gr_internals 47 * \brief An internal, helper structure. 48 */ 49 struct rsb_rows_lock_struct_t 50 { 51 /* FIXME : EXPERIMENTAL,NEW */ 52 /* FIXME : THE LOCK SHULD BE SIZED PROPORTIONALLY TO THE MATRIX, INSTEAD ! */ 53 rsb_coo_idx_t coresrowf[RSB_CONST_MAX_SUPPORTED_CORES]; /* first locked row, for each thread */ 54 rsb_coo_idx_t coresrowl[RSB_CONST_MAX_SUPPORTED_CORES]; /* last locked row, for each thread */ 55 rsb_coo_idx_t corescolf[RSB_CONST_MAX_SUPPORTED_CORES]; /* first locked col, for each thread */ 56 rsb_coo_idx_t corescoll[RSB_CONST_MAX_SUPPORTED_CORES]; /* last locked col, for each thread */ 57 rsb_bitmap_data_t * bmap; /* done matrices bitmap */ 58 rsb_submatrix_idx_t subms; /* all matrices count */ 59 rsb_submatrix_idx_t dm; /* done matrices count */ 60 rsb_submatrix_idx_t dr; /* last done row */ 61 rsb_int_t nt; /* number of threads */ 62 rsb_bool_t want_symlock; /* symmetrical lock -- will lock both row and column region of output vector */ 63 rsb_bool_t want_fake_lock; /* fake lock -- will allow concurrent writes (debug only) */ 64 }; 65 66 /*! 67 * \ingroup gr_internals 68 * \brief An internal, helper structure. 69 */ 70 struct rsb_bti_lock_struct 71 { 72 rsb_coo_idx_t mvleaves; /* maximal vertical leaves (>=itl) (2**(nlevels)) */ 73 rsb_coo_idx_t nlevels; /* number of subdivisions */ 74 rsb_coo_idx_t bsz; /* (=2*mvleaves-1)*/ 75 rsb_coo_idx_t itl; /* lock interval total length (e.g.: matrix dimension) */ 76 rsb_bitmap_data_t * bmap; /* done intervals bitmap */ 77 rsb_bitmap_data_t * tmap; /* tainted intervals bitmap */ 78 }; 79 80 /*! 81 * \ingroup gr_internals 82 * \brief An internal, helper structure. 83 */ 84 struct rsb_mv_lock_t 85 { 86 /** 87 * NEW: EXPERIMENTAL 88 * */ 89 struct rsb_rows_lock_struct_t olock; /* output vector lock */ 90 struct rsb_bti_lock_struct locks[RSB_CONST_MAX_SUPPORTED_TEMPORARY_VECTORS]; /* it has no sense to have more locks than cores */ 91 size_t el_size; /* numerical element size */ 92 rsb_type_t typecode; /* type code */ 93 rsb_coo_idx_t nv; /* number of vectors */ 94 rsb_char_t * mv[RSB_CONST_MAX_SUPPORTED_TEMPORARY_VECTORS]; /* multiple vectors */ 95 rsb_char_t * ov; /* master (output) vector */ 96 rsb_coo_idx_t itl; /* interval total length */ 97 rsb_submatrix_idx_t last_subm[RSB_CONST_MAX_SUPPORTED_CORES]; /* last (tried unsuccessfully) matrix, per thread */ 98 rsb_coo_idx_t in[RSB_CONST_MAX_SUPPORTED_CORES]; /* interval index, non transposed */ 99 rsb_coo_idx_t it[RSB_CONST_MAX_SUPPORTED_CORES]; /* interval index, transposed */ 100 rsb_coo_idx_t incov; /* FIXME: NEW */ 101 rsb_trans_t transA; /* FIXME: NEW */ 102 /* rsb_bitmap_data_t ir[RSB_WORDS_PER_BITVECTOR(RSB_CONST_MAX_SUPPORTED_CORES)]; */ /* is reducing ? */ 103 }; 104 105 #define RSB_WANT_SPMV_WITH_REDUCE 0 106 107 #if !RSB_WANT_SPMV_WITH_REDUCE 108 #define RSB_BOOL_ALMOST_TRUE 2 /* :) */ 109 #define rsb_spmv_lock_struct_t rsb_rows_lock_struct_t 110 #define rsb_do_spmv_lock_init(LOCK,NT,SUMBS,MATRIX,OPFLAGS,TRANSA,OV,IO) rsb__do_lock_init(LOCK,NT,SUMBS,MATRIX,OPFLAGS) 111 #define rsb_do_spmv_lock_free(LOCK) rsb__do_lock_free(LOCK) 112 #define rsb_do_spmv_lock_release(LOCK,THID,OV) rsb__do_lock_release(LOCK,THID) 113 #define rsb_do_spmv_lock_get(LOCK,THID,ROFF,M,COFF,K,SUBM,TRANSA,OV,OI) rsb__do_lock_get(LOCK,THID,ROFF,M,COFF,K,SUBM,TRANSA) 114 #define RSB_DO_SPMV_LOCK_DM(LOCK) ((LOCK).dm) 115 #define RSB_DO_SPMV_LOCK_DM_INC(LOCK) ((LOCK).dm)++ 116 #else 117 #define RSB_BOOL_ALMOST_TRUE 2 /* :) */ 118 #define rsb_spmv_lock_struct_t rsb_mv_lock_t 119 #define rsb_do_spmv_lock_init(LOCK,NT,SUMBS,MATRIX,OPFLAGS,TRANSA,OV,IO) rsb__do_mv_lock_init(LOCK,NT,SUMBS,MATRIX,OPFLAGS,TRANSA,OV,IO) 120 #define rsb_do_spmv_lock_free(LOCK) rsb__do_mv_lock_free(LOCK) 121 #define rsb_do_spmv_lock_release(LOCK,THID,OV) rsb__do_mv_lock_release(LOCK,THID,OV) 122 #define rsb_do_spmv_lock_get(LOCK,THID,ROFF,M,COFF,K,SUBM,TRANSA,OV,OI) rsb__do_mv_lock_get(LOCK,THID,ROFF,M,COFF,K,SUBM,TRANSA,OV,OI) 123 #define RSB_DO_SPMV_LOCK_DM(LOCK) ((LOCK).olock.dm) 124 #define RSB_DO_SPMV_LOCK_DM_INC(LOCK) ((LOCK).olock.dm)++ 125 #endif /* RSB_WANT_SPMV_WITH_REDUCE */ 126 127 rsb_err_t rsb__do_mv_lock_init(struct rsb_mv_lock_t *lock, rsb_int_t num_threads, rsb_submatrix_idx_t subms, const struct rsb_mtx_t * mtxAp, enum rsb_op_flags_t op_flags, rsb_trans_t transA, rsb_char_t * ov, rsb_coo_idx_t incov); 128 rsb_err_t rsb__do_mv_lock_free(struct rsb_mv_lock_t *lock); 129 rsb_err_t rsb__do_mv_lock_release(struct rsb_mv_lock_t *lock, rsb_thr_t th_id, rsb_char_t *ov); 130 rsb_bool_t rsb__do_mv_lock_get(struct rsb_mv_lock_t *lock ,rsb_thr_t th_id, rsb_coo_idx_t roff, rsb_coo_idx_t m, rsb_coo_idx_t coff, rsb_coo_idx_t k, rsb_submatrix_idx_t subm, rsb_trans_t transA, rsb_char_t **ov, rsb_coo_idx_t *incov); 131 rsb_err_t rsb__do_pick_candidate_interval_for_reduce(struct rsb_mv_lock_t *lock, rsb_thr_t th_id, rsb_char_t ** ov, rsb_coo_idx_t * roff, rsb_coo_idx_t * m); 132 rsb_err_t rsb__do_release_candidate_interval_for_reduce(struct rsb_mv_lock_t *lock, rsb_thr_t th_id, rsb_char_t *ov, rsb_coo_idx_t roff, rsb_coo_idx_t m); 133 134 rsb_bool_t rsb__do_lock_release(struct rsb_rows_lock_struct_t *lock, rsb_thr_t th_id); 135 rsb_bool_t rsb__do_lock_get(struct rsb_rows_lock_struct_t *lock,rsb_thr_t th_id, rsb_coo_idx_t roff, rsb_coo_idx_t m, rsb_coo_idx_t coff, rsb_coo_idx_t k, rsb_submatrix_idx_t subm, rsb_trans_t transA); 136 rsb_err_t rsb__do_lock_init(struct rsb_rows_lock_struct_t *lock, rsb_int_t num_threads, rsb_submatrix_idx_t subms, const struct rsb_mtx_t * mtxAp, enum rsb_op_flags_t op_flags); 137 rsb_err_t rsb__do_lock_free(struct rsb_rows_lock_struct_t *lock); 138 #if 0 139 rsb_err_t rsb__do_lock_test(void); 140 #endif 141 142 #endif /* RSB_LOCK_H_INCLUDED */ 143 144 /* @endcond */ 145