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 *
28 * failure testing code.
29 * \internal
30 *
31 * */
32 #include "rsb_common.h"
33
34 RSB_INTERNALS_COMMON_HEAD_DECLS
35
36 #define RSB_WANT_FAILURE_TESTER 1
37 #define RSB_FAILURE_NOTICE(STMT) STMT;RSB_INFO("Injecting failure:\n%s\n",#STMT)
38 #define RSB_VARIATION_NOTICE(STMT) STMT;RSB_INFO("Injecting variation:\n%s\n",#STMT)
39 #define RSB_FT_FFL_PRINTF printf("In %s located in %20s:%d :\n",__func__,__FILE__,__LINE__)
40 #if 0
41 static rsb_err_t rsb_do_meminfo(void)
42 {
43 /*!
44 \ingroup rsb_doc_library
45
46 Write to the info stream (see #RSB_IO_WANT_OUTPUT_STREAM) some memory allocation info.
47
48 \warning \rsb_warn_soon_to_be_deprecated_msg
49 \return \rsberrcodemsg
50 */
51 #ifndef RSB_DISABLE_ALLOCATOR_WRAPPER
52 RSB_INFO("allocated %zd bytes of memory in %zu chunks\n",rsb__get_g_rsb_memory_count(),rsb__get_g_rsb_allocations_count());
53 #endif
54 return RSB_ERR_NO_ERROR;
55 }
56 #define RSB_ALLOC_INFO() RSB_FT_FFL_PRINTF ;rsb_do_meminfo()
57 #else
58 #define RSB_ALLOC_INFO() RSB_NULL_STATEMENT_FOR_COMPILER_HAPPINESS
59 #endif
60 #define RSB_MTX_FREE_PARANOID(MTXAP) if(MTXAP) { RSB_ALLOC_INFO(); RSB_MTX_FREE(MTXAP); }
61 #define RSB_FREE_PARANOID(PTR) if(PTR) { RSB_ALLOC_INFO(); RSB_CONDITIONAL_FREE(PTR); }
62
rsb_random_event(rsb_int out_of)63 static rsb_bool_t rsb_random_event(rsb_int out_of)
64 {
65 rsb_bool_t res = RSB_BOOL_FALSE;
66
67 RSB_ALLOC_INFO();
68 if(!out_of)
69 goto rf;
70 if( rsb__rand_coo_index(out_of) + 1 == out_of)
71 res = RSB_BOOL_TRUE;
72 rf:
73 RSB_ALLOC_INFO();
74 return res;
75 }
76
rsb_blas_failure_tester(const rsb_char_t * tds)77 rsb_err_t rsb_blas_failure_tester(const rsb_char_t*tds)
78 {
79 /**
80 * \ingroup gr_internals
81 * FIXME: still unfinished. this tester shall perform randomized failure-prone operations.
82 * */
83 rsb_err_t errval = RSB_ERR_NO_ERROR;
84 #if RSB_WANT_FAILURE_TESTER
85 struct rsb_limiter ls;
86 struct rsb_mtx_t * mtxAp=NULL, * mtxBp=NULL, * mtxCp=NULL;
87 rsb_coo_idx_t*IA = NULL;
88 rsb_coo_idx_t*JA = NULL;
89 rsb_type_t typecodea[] = RSB_MATRIX_TYPE_CODES_ARRAY;
90 const int typecodei = 0;
91 const int af = 1;/* allow failures */
92 rsb_type_t typecode = typecodea[typecodei];
93 void*VA = NULL;
94 rsb_coo_idx_t nr = 16, nc = nr , nm = RSB_MAX(nr,nc);
95 const rsb_coo_idx_t bs = 1, maxdim = 16, mindim = 4;
96 const rsb_coo_idx_t lbw = mindim, ubw = mindim;
97 rsb_nnz_idx_t nnz = 0;
98 //const int fipi=0; /* if -1: probability 0; else, probability 1/fipi */
99 const rsb_flags_t flags = RSB_FLAG_DEFAULT_MATRIX_FLAGS;
100 void * xp = NULL, * yp = NULL;
101 rsb_aligned_t alpha[RSB_CONST_ENOUGH_ALIGNED_FOR_ANY_TYPE], beta[RSB_CONST_ENOUGH_ALIGNED_FOR_ANY_TYPE];
102 const void *alphap = &alpha,* betap = β
103 const int /*sp=20,*/hp = 10,lp =100, mp = 1000,ip = 10000;
104 const int maxasym = 5;
105
106 RSB_INFO("BASIC FAILURE BASED TEST: BEGIN\n");
107 RSB_ALLOC_INFO();
108 for(errval = rsb__limiter_init_from_str(&ls,tds);rsb__limiter_continue(&ls);rsb__limiter_step(&ls))
109 {
110 RSB_ALLOC_INFO();
111 typecode = typecodea[typecodei];
112 /* FIXME: please write here */
113 if(!mtxAp)
114 {
115 /* random size */
116 nr = mindim+rsb__rand_coo_index(maxdim)+lbw+ubw;
117 if(rsb_random_event(lp*af))
118 {RSB_VARIATION_NOTICE(nc*=1+rsb__rand_coo_index(maxasym));}
119 else
120 nc = nr;/* square matrix */
121 nm = RSB_MAX(nr,nc);
122 RSB_INFO("Create a %d x %d matrix...\n",nr,nc);
123
124 if(RSB_SOME_ERROR(errval = rsb__generate_blocked_banded_coo(nr,1,lbw,ubw,&IA,&JA,&VA,&nnz,typecode)))
125 {
126 RSB_PERR_GOTO(dca,RSB_ERRM_ES);
127 }
128 /* try to instantiate one, with a probability of failure injection */
129 /* if(...) ... */
130 /* change typecode, possibly to an invalid one */
131 /* zero a parameter */
132 /* dealloc an array and nullify its pointer */
133 /* zeros in numbers */
134 /* too big indices */
135 /* negative indices */
136 /* inject a NaN */
137 //if(rsb_random_event(lp*af)) {nc=nr = RSB_MAX_MATRIX_DIM+1;}
138 //if(rsb_random_event(lp*af)) {nnz=0;}
139 if(rsb_random_event(lp*af)) {RSB_FAILURE_NOTICE(typecode = RSB_NUMERICAL_TYPE_INVALID_TYPE);}
140 /**/
141 /**/
142 if(!IA||!JA||!VA)
143 {
144 RSB_PERR_GOTO(dca,RSB_ERRM_ES);
145 }
146 RSB_ALLOC_INFO();
147 mtxAp = rsb__do_mtx_alloc_from_coo_inplace(VA,IA,JA,nnz,typecode,nr,nc,bs,bs,flags,&errval);
148 RSB_ALLOC_INFO();
149
150 if(!mtxAp || RSB_SOME_ERROR(errval))
151 {
152 /**/
153 rsb__do_perror(NULL,errval);
154 RSB_PERR_GOTO(dca,RSB_ERRM_ES);
155 }
156 else
157 {
158 xp = rsb__calloc_vector(nm,typecode);
159 yp = rsb__calloc_vector(nm,typecode);
160 if(!xp || !yp)
161 {
162 RSB_FREE_PARANOID(xp);
163 RSB_FREE_PARANOID(yp);
164 RSB_PERR_GOTO(dca,RSB_ERRM_ES);
165 }
166 }
167 RSB_ALLOC_INFO();
168 goto ndca;
169 dca:
170 RSB_INFO("At:\n");
171 rsb__limiter_info(&ls);
172 RSB_INFO("Freeing matrix due to error\n");
173 RSB_FREE_PARANOID(xp); RSB_FREE_PARANOID(yp);
174 RSB_FREE_PARANOID(IA); RSB_FREE_PARANOID(JA); RSB_FREE_PARANOID(VA);
175 ndca:
176 RSB_NULL_STATEMENT_FOR_COMPILER_HAPPINESS
177 }
178 else
179 {
180 rsb_trans_t transA = RSB_TRANSPOSITION_N, transB = transA;
181 rsb_coo_idx_t incx=1,incy=1;
182 RSB_INFO("Use the matrix...\n");
183 if(rsb_random_event(ip*af)) {RSB_FAILURE_NOTICE(RSB_MTX_FREE_PARANOID(mtxAp));}
184 if(rsb_random_event(lp*af)) {RSB_FAILURE_NOTICE(RSB_FREE_PARANOID(xp));}
185 if(rsb_random_event(lp*af)) {RSB_FAILURE_NOTICE(RSB_FREE_PARANOID(yp));}
186 if(rsb_random_event(ip*af)) {RSB_FAILURE_NOTICE(transA = RSB_INVALID_TRANS);}
187 if(rsb_random_event(mp*af)) {RSB_FAILURE_NOTICE(incx=-1);}
188 if(rsb_random_event(mp*af)) {RSB_FAILURE_NOTICE(incy=-1);}
189 if(RSB_SOME_ERROR(errval = rsb_do_spmv(transA,alphap,mtxAp,xp,incx,betap,yp,incy)))
190 {
191 rsb__do_perror(NULL,errval);
192 RSB_PERR_GOTO(mdca,RSB_ERRM_ES);
193 }
194 if(rsb_random_event(2*af))
195 {
196 RSB_MTX_FREE_PARANOID(mtxBp);
197 RSB_ALLOC_INFO();
198 /* if( ( mtxBp = rsb__mtx_clone_simple(mtxAp) ) != NULL ) */
199 if( rsb__mtx_clone(&mtxBp, mtxAp->typecode,RSB_TRANSPOSITION_N,NULL,mtxAp,flags) == RSB_ERR_NO_ERROR )
200 {
201 RSB_ALLOC_INFO();
202 rsb__do_perror(NULL,errval);
203 RSB_PERR_GOTO(mdca,RSB_ERRM_ES);
204 }
205 }
206 if(rsb_random_event(2*af))
207 {
208 RSB_MTX_FREE_PARANOID(mtxCp);
209 mtxCp = rsb__do_matrix_mul(typecode,transA,alphap,mtxAp,transB,betap,mtxBp,&errval);
210 if(RSB_SOME_ERROR(errval))
211 {
212 rsb__do_perror(NULL,errval);
213 RSB_PERR_GOTO(mdca,RSB_ERRM_ES);
214 }
215 }
216 if(rsb_random_event(hp*af))
217 {
218 RSB_FAILURE_NOTICE(goto mdca);
219 }
220 goto nmdca;
221 mdca:
222 rsb__limiter_info(&ls);
223 RSB_MTX_FREE_PARANOID(mtxAp);
224 RSB_MTX_FREE_PARANOID(mtxBp);
225 RSB_FREE_PARANOID(xp);
226 RSB_FREE_PARANOID(yp);
227 RSB_FREE_PARANOID(IA);
228 RSB_FREE_PARANOID(JA);
229 RSB_FREE_PARANOID(VA);
230 nmdca:
231 RSB_NULL_STATEMENT_FOR_COMPILER_HAPPINESS
232 }
233 }
234 RSB_MTX_FREE_PARANOID(mtxAp);
235 RSB_MTX_FREE_PARANOID(mtxBp);
236 RSB_MTX_FREE_PARANOID(mtxCp);
237 RSB_FREE_PARANOID(xp);
238 RSB_FREE_PARANOID(yp);
239 RSB_FREE_PARANOID(IA);
240 RSB_FREE_PARANOID(JA);
241 RSB_FREE_PARANOID(VA);
242 rsb__limiter_info(&ls);
243 RSB_ALLOC_INFO();
244 rsb__do_check_leak();
245 RSB_INFO("BASIC FAILURE BASED TEST: END\n");
246 #endif /* RSB_WANT_FAILURE_TESTER */
247 return errval;
248 }
249
250 /* @endcond */
251