1 //------------------------------------------------------------------------------
2 // GB_mex_gabor: test case from Gabor Szarnyas and Marton Elekes
3 //------------------------------------------------------------------------------
4 
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: Apache-2.0
7 
8 //------------------------------------------------------------------------------
9 
10 // This test triggers the C<M>=A assignment where C starts out as sparse with
11 // has many pending tuples, and is converted to bitmap by the assignment.  In
12 // this case, C is the vector w.  If w_sparsity is 15 and 'wait' is false, then
13 // it starts the w<v>=sum(A) reduction with many pending tuples, and converts w
14 // from sparse/hyper with many pending tuples into a bitmap vector.  The
15 // outputs w, v, and A should be the same, regardless of the input parameter s.
16 
17 // s is an optional vector of length 4, containing 4 parameters:
18 // s = [wait, w_sparsity, v_sparsity, A_sparsity] ;
19 // with wait 0 or 1, and the sparsity controls in range 1 to 15.
20 
21 #include "GB_mex.h"
22 
23 #define USAGE "[w,v,A] = GB_mex_gabor (s)"
24 
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])25 void mexFunction
26 (
27     int nargout,
28     mxArray *pargout [ ],
29     int nargin,
30     const mxArray *pargin [ ]
31 )
32 {
33 
34     bool malloc_debug = GB_mx_get_global (false) ;
35     GrB_Matrix A = NULL ;
36     GrB_Vector v = NULL ;
37     GrB_Vector w = NULL ;
38 
39     // check inputs
40     if (nargout > 3 || nargin > 1)
41     {
42         mexErrMsgTxt ("Usage: " USAGE) ;
43     }
44 
45     // get the sparsity control for w, v, and A, and the wait flag
46     int w_sparsity = 15 ;
47     int v_sparsity = 15 ;
48     int A_sparsity = 15 ;
49     bool wait = false ;
50 
51     if (nargin > 0)
52     {
53         if (mxGetNumberOfElements (pargin [0]) != 4 || !mxIsDouble (pargin [0]))
54         {
55             mexErrMsgTxt ("Usage: " USAGE
56                 "\ns must be a double vector of length 4\n") ;
57         }
58         double *p = mxGetDoubles (pargin [0]) ;
59         wait = (bool) p [0] ;
60         w_sparsity = (int) p [1] ;
61         v_sparsity = (int) p [2] ;
62         A_sparsity = (int) p [3] ;
63     }
64 
65     // define the problem
66     uint64_t I [ ] = { 1, 2, 4, 5, 7, 11, 12, 13, 15, 18, 19, 20, 27, 32, 33,
67         35, 37, 41, 46, 50, 52, 53, 55, 57, 58, 61, 62, 63, 65, 66, 69, 70, 72,
68         73, 74, 75, 78, 79, 81, 84, 86, 87, 90, 91, 94, 96, 97, 98, 99, 100,
69         101, 102, 103, 104, 105, 107, 108, 109, 110, 115, 116, 117, 118, 120,
70         123, 129, 131, 132, 133, 134, 136, 140, 145, 146, 149, 152, 153, 154,
71         156, 158, 159, 160, 161, 163, 164, 165, 166, 168, 169, 172, 176, 177,
72         181, 184, 186, 187, 189, 191, 193, 194, 195, 197, 200, 201, 202, 203,
73         204, 205, 208, 209, 210, 211, 216, 217, 218, 219, 224, 225, 229, 230,
74         232, 235, 236, 238, 239, 242, 243 } ;
75 
76     uint64_t nvals = sizeof (I) / sizeof (uint64_t) ;
77     uint64_t n = 1000 ;
78 
79     // construct a diagonal matrix A where A(i,i)=i for each i in I
80     GrB_Matrix_new (&A, GrB_UINT64, n, n) ;
81     GxB_Matrix_Option_set_ (A, GxB_SPARSITY_CONTROL, A_sparsity) ;
82     GrB_Matrix_build (A, I, I, I, nvals, GrB_PLUS_UINT64) ;
83     if (wait) GrB_Matrix_wait (&A) ;
84 
85     // construct v from I, with value v (i) = i
86     GrB_Vector_new (&v, GrB_UINT64, n) ;
87     GxB_Vector_Option_set_ (v, GxB_SPARSITY_CONTROL, v_sparsity) ;
88     GrB_Vector_build (v, I, I, nvals, GrB_PLUS_UINT64) ;
89     if (wait) GrB_Vector_wait (&v) ;
90 
91     // w<v> = 1
92     GrB_Vector_new (&w, GrB_UINT64, n) ;
93     GxB_Vector_Option_set_ (w, GxB_SPARSITY_CONTROL, w_sparsity) ;
94     GrB_Vector_assign_UINT64 (w, v, NULL, 1, GrB_ALL, 0, NULL) ;
95     if (wait) GrB_Vector_wait (&w) ;
96 
97     // w<v> = sum (A)
98     GrB_Matrix_reduce_Monoid (w, v, NULL, GrB_PLUS_MONOID_UINT64, A, NULL) ;
99 
100     // return A, v, and w to MATLAB as structs
101     pargout [0] = GB_mx_Vector_to_mxArray (&w, "w output", true) ;
102     pargout [1] = GB_mx_Vector_to_mxArray (&v, "v output", true) ;
103     pargout [2] = GB_mx_Matrix_to_mxArray (&A, "A output", true) ;
104 
105     // log the test coverage
106     GB_mx_put_global (true) ;
107 }
108 
109