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