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