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 = &beta;
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