1 //------------------------------------------------------------------------------
2 // SLIP_LU/Tcov/tcov_test.c: test coverage for SLIP_LU
3 //------------------------------------------------------------------------------
4
5 // SLIP_LU: (c) 2019-2020, Chris Lourenco, Jinhao Chen, Erick Moreno-Centeno,
6 // Timothy A. Davis, Texas A&M University. All Rights Reserved. See
7 // SLIP_LU/License for the license.
8
9 //------------------------------------------------------------------------------
10
11 /*
12 * When the test is run without input argument, brutal test is used and simple
13 * test otherwise. Read the following for detailed instruction and information
14 *
15 * For simple test, the test needs to be run with command
16 * ./tcov_test Ab_type N list1[0] ... list1[N-1] M list2[0] ... list2[M-1]
17 * Ab_type: type of original matrix A and vector b: 0 mpz, 1 mpq, 2 mpfr, 3
18 * int64, 4 double. For Ab_type >= 5, it corresponds to 15 type of original
19 * matrix A (i.e., (csc, triplet, dense) x (mpz, mpq, mpfr, int64, double)),
20 * specifically, A->type=(Ab_type-5)%5, and A->kind=(Ab_type-5)/5.
21 * N and list1 specify the test list for slip_gmp_ntrials (in SLIP_gmp.h)
22 * M and list2 specify the test list for malloc_count (in tcov_malloc_test.h)
23 * N, list1, M, list2 are optional, but N and list1 are required when M and
24 * list2 is wanted
25 *
26 * For brutal test, the test is run with command
27 * ./tcov_test
28 * the test will run through all cases
29 * (specifically, Ab_type={0, 1, 2, 3, 4, 5,...,20})
30 * each case run from malloc_count = 0 to a number that can guarantee
31 * malloc_count > 0 when the case finishes
32 */
33
34 /* For simple test ONLY!!
35 * uncomment to show the input lists for slip_gmp_ntrials and malloc_count
36 */
37 // #define SLIP_TCOV_SHOW_LIST
38
39 /* This program will exactly solve the sparse linear system Ax = b by performing
40 * the SLIP LU factorization. Refer to README.txt for information on how
41 * to properly use this code.
42 */
43
44 #define SLIP_FREE_ALL \
45 { \
46 SLIP_matrix_free(&A,option); \
47 SLIP_matrix_free(&b, option); \
48 SLIP_matrix_free(&B, option); \
49 SLIP_matrix_free(&Ax, option); \
50 SLIP_matrix_free(&sol, option); \
51 SLIP_FREE(option); \
52 SLIP_finalize() ; \
53 }
54
55 #include "tcov_malloc_test.h"
56
57 #define TEST_CHECK(method) \
58 { \
59 info = (method) ; \
60 if (info != SLIP_OK) \
61 { \
62 SLIP_PRINT_INFO (info) ; \
63 SLIP_FREE_ALL; \
64 continue; \
65 } \
66 }
67
68 #define TEST_CHECK_FAILURE(method) \
69 { \
70 info = (method) ; \
71 if (info != SLIP_INCORRECT_INPUT && info != SLIP_SINGULAR) \
72 { \
73 SLIP_PRINT_INFO (info) ; \
74 SLIP_FREE_ALL ; \
75 continue ; \
76 } \
77 else \
78 { \
79 printf("Expected failure at line %d\n", __LINE__);\
80 } \
81 }
82
83 #define MAX_MALLOC_COUNT 1000
84
85 int64_t Ap[5] = {0, 3, 5, 8, 11};
86 int64_t Ai[11] = {0, 1, 2, 2, 3, 1, 2, 3, 0, 1, 2};
87 double Axnum[11] = {1, 2, 7, 1, 2, 4, 1, 3, 1, 12, 1}; // Numerator of x
88 double Axden[11] = {3, 3, 6, 1, 7, 1, 1, 1, 5, 1, 1}; // Denominator of x
89 double bxnum[4] = {170, 1820, 61, 670}; // Numerator of b
90 double bxden[4] = {15, 3, 6, 7}; // Denominator of b
91 int64_t Axnum3[11] = {1, 2, 7, 1, 2, 4, 1, 3, 1, 12, 1}; // Numerator of x
92 int64_t Axden3[11] = {3, 3, 6, 1, 7, 1, 1, 1, 5, 1, 1}; // Denominator of x
93 int64_t bxnum3[4] = {17, 182, 61, 67}; // Numerator of b
94 int64_t bxden3[4] = {15, 3, 6, 7}; // Denominator of b
95
96 #include <assert.h>
97
main(int argc,char * argv[])98 int main( int argc, char* argv[])
99 {
100 bool IS_SIMPLE_TEST = true;
101 int Ab_type = 0;
102 int64_t malloc_count_list[20]= { -1, -1, -1, -1, -1,
103 -1, -1, -1, -1, -1,
104 -1, -1, -1, -1, -1,
105 -1, -1, -1, -1, -1};
106 int64_t NUM_OF_TRIALS = 0 ;
107 int64_t NUM_OF_MALLOC_T = 0;
108 int64_t *gmp_ntrial_list=NULL; // only used in simple test
109 int64_t *malloc_trials_list=NULL; // only used in simple test
110
111 //--------------------------------------------------------------------------
112 // parse input arguments
113 //--------------------------------------------------------------------------
114
115 if (argc == 1) // brutal test
116 {
117 IS_SIMPLE_TEST = false;
118 NUM_OF_TRIALS = 20;
119 }
120 else // simple test
121 {
122 IS_SIMPLE_TEST = true;
123
124 int64_t arg_count = 0;
125 // type of Matrix A and vector b:
126 // 0 mpz, 1 double, 2 int64_t, 3 mpq, 4 mpfr
127 Ab_type = atoi(argv[++arg_count]);
128 if (!argv[++arg_count])
129 {
130 NUM_OF_TRIALS=1;
131 gmp_ntrial_list= malloc (NUM_OF_TRIALS* sizeof(int64_t));
132 gmp_ntrial_list[0]=-1;
133 arg_count--;
134 }
135 else
136 {
137 NUM_OF_TRIALS=atoi(argv[arg_count]);
138 gmp_ntrial_list= malloc (NUM_OF_TRIALS* sizeof(int64_t));
139 for (int64_t k=0; k<NUM_OF_TRIALS; k++)
140 {
141 if (argv[++arg_count])
142 {
143 gmp_ntrial_list[k]=atoi(argv[arg_count]);
144 }
145 else
146 {
147 fprintf(stderr, "WARNING: MISSING gmp trial\n");
148 NUM_OF_TRIALS=1;
149 gmp_ntrial_list[0]=-1;
150 arg_count--;
151 }
152 }
153 }
154 if (!argv[++arg_count])
155 {
156 NUM_OF_MALLOC_T=1;
157 malloc_trials_list= malloc (NUM_OF_MALLOC_T* sizeof(int64_t));
158 malloc_trials_list[0]=MAX_MALLOC_COUNT;//INT_MAX;
159 }
160 else
161 {
162 NUM_OF_MALLOC_T=atoi(argv[arg_count]);
163 malloc_trials_list= malloc (NUM_OF_MALLOC_T* sizeof(int64_t));
164 for (int64_t k=0; k<NUM_OF_MALLOC_T; k++)
165 {
166 if (argv[++arg_count])
167 {
168 malloc_trials_list[k]=atoi(argv[arg_count]);
169 }
170 else
171 {
172 fprintf(stderr, "WARNING: MISSING malloc trial\n");
173 NUM_OF_MALLOC_T=1;
174 malloc_trials_list[0]=MAX_MALLOC_COUNT;//INT_MAX;
175 }
176 }
177 }
178
179 #ifdef SLIP_TCOV_SHOW_LIST
180 printf ("gmp ntrials list is: ");
181 for (int64_t k=0; k<NUM_OF_TRIALS; k++)
182 {
183 printf("%ld ",gmp_ntrial_list[k]);
184 }
185 printf("\nmalloc trial list is: ");
186 for (int64_t k=0; k<NUM_OF_MALLOC_T; k++)
187 {
188 printf("%d ",malloc_trials_list[k]);
189 }
190 printf("\n");
191 #endif /* SLIP_TCOV_SHOW_LIST */
192 }
193
194 //--------------------------------------------------------------------------
195 // test calloc, realloc, free
196 //--------------------------------------------------------------------------
197
198 SLIP_info info ;
199 info = SLIP_initialize ( ) ; assert (info == SLIP_OK) ;
200 info = SLIP_finalize ( ) ; assert (info == SLIP_OK) ;
201 info = SLIP_initialize ( ) ; assert (info == SLIP_OK) ;
202 int *p4 = SLIP_calloc (5, sizeof (int)) ; assert (p4 != NULL) ;
203 bool ok ;
204 p4 = SLIP_realloc (6, 5, sizeof (int), p4, &ok) ; assert (ok) ;
205 info = SLIP_finalize ( ) ; assert (info == SLIP_OK) ;
206 p4 = SLIP_realloc (7, 6, sizeof (int), p4, &ok) ; assert (!ok) ;
207 info = SLIP_initialize ( ) ; assert (info == SLIP_OK) ;
208 SLIP_FREE (p4) ;
209 info = SLIP_finalize ( ) ; assert (info == SLIP_OK) ;
210
211 //--------------------------------------------------------------------------
212 // run all trials
213 //--------------------------------------------------------------------------
214
215 // For SIMPLE_TEST, outer loop iterates for slip_gmp_ntrials initialized
216 // from list1 (input for tcov_test) and inner loop interates for
217 // malloc_count initialized from list2 (input for tcov_test).
218 //
219 // For non SIMPLE_TEST, outer loop iterates for Ab_type from 0 to 5, and
220 // inner loop iterates for malloc_count initialized from 0 to
221 // MAX_MALLOC_COUNT, break when malloc_count>0 at the end of inner loop.
222
223 for (int64_t k=0; k<NUM_OF_TRIALS; k++)
224 {
225 if (IS_SIMPLE_TEST)
226 {
227 // only the first outter loop will iterate across all list2
228 if (k == 1)
229 {
230 NUM_OF_MALLOC_T=1;
231 malloc_trials_list[0]=INT_MAX;
232 }
233 }
234 else
235 {
236 Ab_type = k;
237 NUM_OF_MALLOC_T = MAX_MALLOC_COUNT;
238 }
239
240 for (int64_t kk=0; kk<NUM_OF_MALLOC_T; kk++)
241 {
242 if (IS_SIMPLE_TEST)
243 {
244 slip_gmp_ntrials=gmp_ntrial_list[k];
245 printf("initial slip_gmp_ntrials=%ld\n",slip_gmp_ntrials);
246 malloc_count=malloc_trials_list[kk];
247 printf("%"PRId64" out of %"PRId64", "
248 "initial malloc_count=%"PRId64"\n",
249 kk, NUM_OF_MALLOC_T, malloc_count);
250 }
251 else
252 {
253 malloc_count = kk;
254 printf("[Ab_type malloc_count] = [%d %"PRId64"]\n",
255 Ab_type, malloc_count);
256 }
257
258 //------------------------------------------------------------------
259 // Initialize SLIP LU process
260 //------------------------------------------------------------------
261
262 SLIP_initialize_expert (tcov_malloc, tcov_calloc,
263 tcov_realloc, tcov_free) ;
264
265 info = SLIP_initialize ( ) ;
266 assert (info == SLIP_PANIC) ;
267
268 //------------------------------------------------------------------
269 // Allocate memory
270 //------------------------------------------------------------------
271
272 int64_t n=4, numRHS=1, j, nz=11;
273 SLIP_options* option = SLIP_create_default_options();
274 if (!option) {continue;}
275 option->print_level = 3;
276
277 // used in as source in different Ab_type for A and b
278 SLIP_matrix *B = NULL;
279 SLIP_matrix *Ax = NULL;
280
281 // matrix A, b and solution
282 SLIP_matrix *A = NULL ;
283 SLIP_matrix *b = NULL ;
284 SLIP_matrix *sol = NULL;
285
286 if (Ab_type >= 0 && Ab_type <= 4)
287 {
288
289 //--------------------------------------------------------------
290 // Solve A*x=b where A and b are created from mpz entries
291 //--------------------------------------------------------------
292
293 TEST_CHECK(SLIP_matrix_allocate(&B, SLIP_DENSE,
294 (SLIP_type) Ab_type, n,
295 numRHS, n*numRHS, false, true, option));
296 TEST_CHECK(SLIP_matrix_allocate(&Ax, SLIP_CSC,
297 (SLIP_type) Ab_type, n,
298 n, nz, false, true, option));
299
300 // fill Ax->i and Ax->p
301 for (j = 0; j < n+1; j++)
302 {
303 Ax->p[j] = Ap[j];
304 }
305 for (j = 0; j < nz; j++)
306 {
307 Ax->i[j] = Ai[j];
308 }
309
310 // special failure cases
311 if (Ab_type == 2)// MPFR
312 {
313 // create empty A and b using uninitialized double mat/array
314 // to trigger all-zero array condition
315 TEST_CHECK(SLIP_matrix_copy(&A, SLIP_CSC, SLIP_MPZ, Ax,
316 option));
317 TEST_CHECK(SLIP_matrix_copy(&b, SLIP_DENSE, SLIP_MPZ, B,
318 option));
319 // to trigger SLIP_SINGULAR
320 TEST_CHECK_FAILURE(SLIP_backslash(&sol, SLIP_MPQ, A, b,
321 option));
322 option->pivot = SLIP_LARGEST;
323 TEST_CHECK_FAILURE(SLIP_backslash(&sol, SLIP_MPQ, A, b,
324 option));
325 option->pivot = SLIP_FIRST_NONZERO;
326 TEST_CHECK_FAILURE(SLIP_backslash(&sol, SLIP_MPQ, A, b,
327 option));
328
329 //free the memory alloc'd
330 SLIP_matrix_free (&A, option) ;
331 SLIP_matrix_free (&b, option) ;
332
333 // trigger gcd == 1
334 int32_t prec = option->prec;
335 option->prec = 17;
336 double pow2_17 = pow(2,17);
337 for (j = 0; j < n; j++) // Get B
338 {
339 TEST_CHECK(SLIP_mpfr_set_d(SLIP_2D(B,j,0,mpfr),
340 bxnum[j]/pow2_17, MPFR_RNDN));
341 }
342 TEST_CHECK(SLIP_matrix_copy(&b, SLIP_DENSE, SLIP_MPZ,B,
343 option));
344 SLIP_matrix_free (&b, option) ;
345
346 // restore default precision
347 option->prec = prec;
348
349 // use diagonal entries as pivot
350 option->pivot = SLIP_DIAGONAL;
351 }
352 else if (Ab_type == 4)// double
353 {
354 // create empty A using uninitialized double mat/array
355 // to trigger all-zero array condition
356 TEST_CHECK(SLIP_matrix_copy(&A, SLIP_CSC, SLIP_MPZ, Ax,
357 option));
358 SLIP_matrix_free (&A, option) ;
359
360 // trigger gcd == 1
361 for (j = 0; j < n; j++) // Get b
362 {
363 SLIP_2D(B,j,0,fp64) = bxnum[j]/1e17;
364 }
365 TEST_CHECK(SLIP_matrix_copy(&b, SLIP_DENSE, SLIP_MPZ, B,
366 option));
367 SLIP_matrix_free (&b, option) ;
368
369 // use smallest entry as pivot
370 option->pivot = SLIP_SMALLEST;
371 }
372
373 // fill Ax->x and b->x
374 for (j = 0; j < n; j++) // Get b
375 {
376 if (Ab_type == 0) //MPZ
377 {
378 TEST_CHECK(SLIP_mpz_set_ui(SLIP_2D(B, j, 0, mpz),
379 bxnum3[j]));
380 }
381 else if (Ab_type == 1)// MPQ
382 {
383 TEST_CHECK(SLIP_mpq_set_ui(SLIP_2D(B,j,0,mpq),
384 bxnum3[j], bxden3[j]));
385 }
386 else if (Ab_type == 2)// MPFR
387 {
388 TEST_CHECK(SLIP_mpfr_set_d(SLIP_2D(B,j,0,mpfr),bxnum[j],
389 MPFR_RNDN));
390 TEST_CHECK(SLIP_mpfr_div_d(SLIP_2D(B,j,0,mpfr),
391 SLIP_2D(B,j,0,mpfr), bxden[j], MPFR_RNDN));
392 }
393 else if (Ab_type == 3)// INT64
394 {
395 SLIP_2D(B,j,0,int64)=bxnum3[j];
396 }
397 else // double
398 {
399 SLIP_2D(B,j,0,fp64) = bxnum[j];
400 }
401 }
402 for (j = 0; j < nz; j++) // Get Ax
403 {
404 if (Ab_type == 0)
405 {
406 TEST_CHECK(SLIP_mpz_set_ui(Ax->x.mpz[j],Axnum3[j]));
407 }
408 else if (Ab_type == 1)
409 {
410 TEST_CHECK(SLIP_mpq_set_ui(Ax->x.mpq[j],Axnum3[j],
411 Axden3[j]));
412 }
413 else if (Ab_type == 2)
414 {
415 TEST_CHECK(SLIP_mpfr_set_d(Ax->x.mpfr[j], Axnum[j],
416 MPFR_RNDN));
417 TEST_CHECK(SLIP_mpfr_div_d(Ax->x.mpfr[j], Ax->x.mpfr[j],
418 Axden[j], MPFR_RNDN))
419 }
420 else if (Ab_type == 3)
421 {
422 Ax->x.int64[j]=Axnum3[j];
423 }
424 else
425 {
426 Ax->x.fp64[j] = Axnum[j]/Axden[j];
427 }
428 }
429
430 // successful case
431 TEST_CHECK(SLIP_matrix_copy(&A, SLIP_CSC, SLIP_MPZ, Ax,option));
432 TEST_CHECK(SLIP_matrix_copy(&b, SLIP_DENSE, SLIP_MPZ,B,option));
433 SLIP_matrix_free(&B, option);
434 SLIP_matrix_free(&Ax, option);
435 }
436 else // 5 =< Ab_type < 20
437 {
438
439 //--------------------------------------------------------------
440 // Test SLIP_matrix_copy and SLIP_matrix_check brutally
441 // and some special failure cases
442 //--------------------------------------------------------------
443
444 n = 4, nz = 11;
445 int64_t m1, n1, nz1;
446 int64_t I[11]={0, 1, 2, 2, 3, 1, 2, 3, 0, 1, 2};
447 int64_t J[11]={0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3};
448 int64_t P[11]={0, 3, 5, 8, 11};
449
450 double x_doub2[11] = {1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4};
451 int64_t x_int64[11] = {1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4};
452
453 // find the type and kind of the source matrix to copy from
454 Ab_type = Ab_type > 19 ? 19:Ab_type;
455 int tk = Ab_type-5;
456 int type = tk%5;
457 int kind = tk/5;
458 if (kind != 2)
459 {
460 m1 = n;
461 n1 = n;
462 nz1 = nz;
463 }
464 else
465 {
466 m1 = nz1;
467 n1 = 1;
468 nz1 = nz1;
469 }
470 TEST_CHECK(SLIP_matrix_allocate(&Ax, (SLIP_type) kind,
471 (SLIP_type)type, m1, n1, nz1, false, true, option));
472 if (kind == 1){Ax->nz = nz1;}
473
474 // fill Ax->p
475 if(kind == 0)
476 {
477 for (j = 0; j < n+1; j++)
478 {
479 Ax->p[j] = P[j];
480 }
481 }
482 // fill Ax->i and Ax->j
483 for (j = 0; j < nz; j++)
484 {
485 if (kind != 2) {Ax->i[j] = I[j];}
486 // triplet
487 if (kind == 1){ Ax->j[j] = J[j];}
488 switch (type)
489 {
490 case 0: // MPZ
491 {
492 TEST_CHECK(SLIP_mpz_set_si(Ax->x.mpz[j],
493 x_int64[j]));
494 }
495 break;
496
497 case 1: // MPQ
498 {
499 TEST_CHECK(SLIP_mpq_set_ui(Ax->x.mpq[j],
500 2*x_int64[j],2));
501 }
502 break;
503
504 case 2: // MPFR
505 {
506 TEST_CHECK(SLIP_mpfr_set_d(Ax->x.mpfr[j],
507 x_doub2[j], MPFR_RNDN));
508 TEST_CHECK(SLIP_mpfr_div_d(Ax->x.mpfr[j],
509 Ax->x.mpfr[j], 1, MPFR_RNDN));
510 }
511 break;
512
513 case 3: // INT64
514 {
515 Ax->x.int64[j] = x_int64[j];
516 }
517 break;
518
519 case 4: // double
520 {
521 Ax->x.fp64[j] = x_doub2[j];
522 }
523 break;
524
525 default: break;
526 }
527 }
528 TEST_CHECK (SLIP_matrix_check (Ax, option));
529
530 // convert to all different type of matrix
531 for (int tk1 = 0; tk1 < 15 && info == SLIP_OK; tk1++)
532 {
533 // successful cases
534 int type1 = tk1%5;
535 int kind1 = tk1/5;
536 printf("converting from %s(%d) %s(%d) to %s(%d) "
537 "%s(%d)\n",kind < 1 ? "CSC" : kind < 2 ? "Triplet" :
538 "Dense",kind, type < 1 ? "MPZ" : type < 2 ? "MPQ" :
539 type <3 ? "MPFR" : type < 4 ? "int64" :
540 "double",type, kind1 < 1 ? "CSC" : kind1 < 2 ?
541 "Triplet" : "Dense", kind1,type1 < 1 ? "MPZ" :
542 type1 < 2 ? "MPQ" : type1 < 3 ? "MPFR" : type1 < 4
543 ? "int64" : "double",type1) ;
544
545 TEST_CHECK(SLIP_matrix_copy(&A, (SLIP_kind)kind1,
546 (SLIP_type) type1, Ax, option));
547
548 TEST_CHECK (SLIP_matrix_check (A, NULL));
549
550 // just perform once to try some failure cases
551 if (tk == 0 && tk1 == 0)
552 {
553 // fail SLIP_LU_solve
554 TEST_CHECK(SLIP_matrix_allocate(&b, SLIP_DENSE,
555 SLIP_MPZ, 1, 1, 1, true, true, option));
556 TEST_CHECK_FAILURE(SLIP_LU_solve(NULL, b, A, A, A,
557 b, NULL, NULL, option));
558 SLIP_matrix_free (&b, option) ;
559 }
560 else if (tk == 0 && (tk1 == 1 || tk1 == 2 || tk1 == 4))
561 {
562 // test SLIP_matrix_copy with scale
563 SLIP_matrix_free (&A, option) ;
564 TEST_CHECK (SLIP_mpq_set_ui (Ax->scale, 2, 5)) ;
565 TEST_CHECK(SLIP_matrix_copy(&A, (SLIP_kind)kind1,
566 (SLIP_type) type1, Ax, option));
567 TEST_CHECK (SLIP_mpq_set_ui (Ax->scale, 1, 1)) ;
568 }
569 else if (tk == 0 && tk1 == 3)//A = CSC int64
570 {
571 // test SLIP_matrix_check
572 A->i[0] = -1;
573 TEST_CHECK_FAILURE(SLIP_matrix_check(A, option));
574 SLIP_FREE(A->x.int64);
575 TEST_CHECK_FAILURE(SLIP_matrix_check(A, option));
576 A->p[1] = 2;
577 A->p[2] = 1;
578 TEST_CHECK_FAILURE(SLIP_matrix_check(A, option));
579 A->p[0] = 1;
580 TEST_CHECK_FAILURE(SLIP_matrix_check(A, option));
581 A->type = -1;// invalid type
582 TEST_CHECK_FAILURE(SLIP_matrix_check(A, option));
583 A->nzmax = -1;
584 TEST_CHECK_FAILURE(SLIP_matrix_check(A, option));
585 A->m = -1;
586 TEST_CHECK_FAILURE(SLIP_matrix_check(A, option));
587 TEST_CHECK_FAILURE(SLIP_matrix_check(NULL, option));
588
589 // Incorrect calling with NULL pointer(s)
590 TEST_CHECK_FAILURE(SLIP_LU_analyze(NULL,A,NULL));
591
592 // test SLIP_matrix_copy with scale
593 SLIP_matrix_free (&A, option) ;
594 TEST_CHECK (SLIP_mpq_set_ui (Ax->scale, 5, 2)) ;
595 TEST_CHECK(SLIP_matrix_copy(&A, (SLIP_kind)kind1,
596 (SLIP_type) type1, Ax, option));
597 TEST_CHECK (SLIP_mpq_set_ui (Ax->scale, 1, 1)) ;
598 }
599 else if (tk == 0 && tk1 == 8) // A= Triplet int64
600 {
601 // test SLIP_matrix_check
602 A->i[0] = -1;
603 TEST_CHECK_FAILURE(SLIP_matrix_check(A, option));
604 SLIP_FREE(A->x.int64);
605 TEST_CHECK_FAILURE(SLIP_matrix_check(A, option));
606 A->n = -1;
607 TEST_CHECK_FAILURE(SLIP_matrix_check(A, option));
608 }
609 else if (tk == 0 && tk1 == 13)//A= dense int64
610 {
611 SLIP_FREE(A->x.int64);
612 TEST_CHECK_FAILURE(SLIP_matrix_check(A, option));
613 }
614 SLIP_matrix_free (&A, option) ;
615 info = SLIP_OK;
616
617 }
618 TEST_CHECK(info);
619 if (tk == 3)
620 {
621 // fail SLIP_matrix_copy
622 TEST_CHECK_FAILURE(SLIP_matrix_copy(&A, 7,
623 (SLIP_type) type, Ax, option));
624 // failure case: Ax->x = NULL
625 SLIP_FREE(Ax->x.int64);
626 TEST_CHECK_FAILURE(SLIP_matrix_copy(&A, SLIP_CSC, SLIP_MPZ,
627 Ax,option));
628
629 // fail SLIP_matrix_allocate
630 TEST_CHECK_FAILURE(SLIP_matrix_allocate(NULL,
631 SLIP_DENSE, SLIP_MPZ, 1, 1, 1,
632 true, true, option));
633 TEST_CHECK_FAILURE(SLIP_matrix_allocate(&b,
634 SLIP_DENSE, SLIP_MPZ, -1, 1, 1,
635 true, true, option));
636
637 // test SLIP_matrix_allocate
638 TEST_CHECK(SLIP_matrix_allocate(&b, SLIP_DENSE,
639 SLIP_MPQ, 1, 1, 1, false, false, option));
640 SLIP_matrix_free (&b, option) ;
641 TEST_CHECK(SLIP_matrix_allocate(&b, SLIP_DENSE,
642 SLIP_MPFR, 1, 1, 1, false, false, option));
643 SLIP_matrix_free (&b, option) ;
644
645 //test coverage for slip_gmp_reallocate()
646 void *p_new = NULL;
647 TEST_CHECK(slip_gmp_realloc_test(&p_new, NULL,0,1));
648 TEST_CHECK(slip_gmp_realloc_test(&p_new,p_new,1,0));
649 }
650
651 //--------------------------------------------------------------
652 // test SLIP_matrix_check on a triplet matrix with bad triplets
653 //--------------------------------------------------------------
654
655 printf ("\n[ SLIP_matrix_check -------------------------\n") ;
656 SLIP_matrix_free (&A, option) ;
657 int64_t I2 [4] = { 1, 2, 1, 1 } ;
658 int64_t J2 [4] = { 1, 0, 0, 1 } ;
659 TEST_CHECK (SLIP_matrix_allocate (&A, SLIP_TRIPLET,
660 SLIP_INT64, 3, 3, 4, true, false, option)) ;
661 A->i = I2 ;
662 A->j = J2 ;
663 A->x.int64 = I2 ;
664 A->nz = 4 ;
665 printf ("invalid triplet matrix expected:\n") ;
666 TEST_CHECK_FAILURE (SLIP_matrix_check (A, option)) ;
667 SLIP_matrix_free (&A, option) ;
668
669 TEST_CHECK (SLIP_matrix_allocate (&A, SLIP_CSC,
670 SLIP_INT64, 3, 3, 4, true, false, option)) ;
671 int64_t P3 [4] = { 0, 2, 4, 4 } ;
672 int64_t I3 [4] = { 0, 0, 0, 0 } ;
673 A->p = P3 ;
674 A->i = I3 ;
675 A->x.int64 = I3 ;
676 printf ("invalid CSC matrix expected:\n") ;
677 TEST_CHECK_FAILURE (SLIP_matrix_check (A, option)) ;
678 SLIP_matrix_free (&A, option) ;
679 printf ("-----------------------------------------------]\n") ;
680
681 //--------------------------------------------------------------
682
683 SLIP_FREE_ALL;
684
685 // for miscellaneous test, continue to next loop directly
686 if (!IS_SIMPLE_TEST)
687 {
688 if (malloc_count > 0)
689 {
690 malloc_count_list[Ab_type] = kk;
691 break;
692 }
693 else {continue;}
694 }
695 else
696 {
697 continue;
698 }
699 }
700
701 if (Ab_type%2 == 0)
702 {
703 //--------------------------------------------------------------
704 // SLIP LU backslash
705 // solve Ax=b in full precision rational arithmetic
706 //--------------------------------------------------------------
707 TEST_CHECK(SLIP_backslash(&sol, SLIP_MPQ, A, b, option));
708
709 if (Ab_type == 4)
710 {
711 // This would return SLIP_INCORRECT since sol has been
712 // scaled down so that sol->scale = 1. Therefore sol is
713 // solution for original unscaled Ax=b, while this is
714 // checking if x is the solution for scaled Ax=b
715 info = slip_check_solution(A, sol, b, option);
716 if (info == SLIP_INCORRECT) {;}
717 else {TEST_CHECK(info);}
718 }
719
720 }
721 else
722 {
723 //--------------------------------------------------------------
724 // SLIP LU backslash
725 // solve Ax=b in double precision
726 //--------------------------------------------------------------
727 SLIP_matrix *sol_doub;
728 TEST_CHECK(SLIP_backslash(&sol_doub, SLIP_FP64, A, b, option));
729 SLIP_matrix_free(&sol_doub, option);
730
731 // failure case
732 if (Ab_type == 1)
733 {
734 TEST_CHECK_FAILURE(SLIP_LU_factorize(NULL, NULL,
735 NULL, NULL, A, NULL, NULL));
736 // incorrect solution type
737 TEST_CHECK_FAILURE(SLIP_backslash(&sol, SLIP_MPZ, A, b,
738 option));
739 // NULL solution pointer
740 TEST_CHECK_FAILURE(SLIP_backslash(NULL, SLIP_MPZ, A, b,
741 option));
742 // invalid kind
743 A->kind = 4;
744 SLIP_matrix_nnz(A, NULL);
745 A->kind = SLIP_CSC;
746 }
747
748 }
749
750 //------------------------------------------------------------------
751 // Free Memory
752 //------------------------------------------------------------------
753
754 SLIP_FREE_ALL;
755 if(!IS_SIMPLE_TEST)
756 {
757 if (malloc_count > 0)
758 {
759 malloc_count_list[k] = kk;
760 break;
761 }
762 else {continue;}
763 }
764 }
765 }
766
767 //--------------------------------------------------------------------------
768 // wrapup
769 //--------------------------------------------------------------------------
770
771 if (IS_SIMPLE_TEST)
772 {
773 free(gmp_ntrial_list);
774 free(malloc_trials_list);
775 printf ("tests finished\n") ;
776 }
777 else
778 {
779 printf("least required malloc_count for Ab_type = 0~20 are ");
780 for (int i = 0; i < 20; i++)
781 {
782 printf("%ld ", malloc_count_list[i]);
783 }
784 printf("\nbrutal tests finished\n");
785 }
786
787 return 0;
788 }
789
790