1 //------------------------------------------------------------------------------
2 // GB_mex_triple_mxm: C = A*B*E
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 #include "GB_mex.h"
11
12 #define USAGE "C = GB_mex_triple_mxm (semiring, A, B, E, desc)"
13
14 #define FREE_ALL \
15 { \
16 GrB_Matrix_free_(&A) ; \
17 GrB_Matrix_free_(&B) ; \
18 GrB_Matrix_free_(&C) ; \
19 GrB_Matrix_free_(&E) ; \
20 GrB_Matrix_free_(&T) ; \
21 if (semiring != Complex_plus_times) \
22 { \
23 if (semiring != NULL) \
24 { \
25 GrB_Monoid_free_(&(semiring->add)) ; \
26 } \
27 GrB_Semiring_free_(&semiring) ; \
28 } \
29 GrB_Descriptor_free_(&desc) ; \
30 GB_mx_put_global (true) ; \
31 }
32
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])33 void mexFunction
34 (
35 int nargout,
36 mxArray *pargout [ ],
37 int nargin,
38 const mxArray *pargin [ ]
39 )
40 {
41
42 bool malloc_debug = GB_mx_get_global (true) ;
43 GrB_Matrix A = NULL ;
44 GrB_Matrix B = NULL ;
45 GrB_Matrix C = NULL ;
46 GrB_Matrix E = NULL ;
47 GrB_Matrix T = NULL ;
48 GrB_Semiring semiring = NULL ;
49 GrB_Descriptor desc = NULL ;
50
51 // check inputs
52 if (nargout > 1 || nargin < 4 || nargin > 5)
53 {
54 mexErrMsgTxt ("Usage: " USAGE) ;
55 }
56
57 #define GET_DEEP_COPY ;
58 #define FREE_DEEP_COPY ;
59
60 // get A (shallow copy)
61 A = GB_mx_mxArray_to_Matrix (pargin [1], "A input", false, true) ;
62 if (A == NULL)
63 {
64 FREE_ALL ;
65 mexErrMsgTxt ("A failed") ;
66 }
67
68 // get B (shallow copy)
69 B = GB_mx_mxArray_to_Matrix (pargin [2], "B input", false, true) ;
70 if (B == NULL)
71 {
72 FREE_ALL ;
73 mexErrMsgTxt ("B failed") ;
74 }
75
76 // get E (shallow copy)
77 E = GB_mx_mxArray_to_Matrix (pargin [3], "E input", false, true) ;
78 if (E == NULL)
79 {
80 FREE_ALL ;
81 mexErrMsgTxt ("B failed") ;
82 }
83
84 bool user_complex = (Complex != GxB_FC64) && (A->type == Complex) ;
85
86 // get semiring
87 if (!GB_mx_mxArray_to_Semiring (&semiring, pargin [0], "semiring",
88 A->type, user_complex))
89 {
90 FREE_ALL ;
91 mexErrMsgTxt ("semiring failed") ;
92 }
93
94 // get desc
95 if (!GB_mx_mxArray_to_Descriptor (&desc, PARGIN (4), "desc"))
96 {
97 FREE_ALL ;
98 mexErrMsgTxt ("desc failed") ;
99 }
100
101 // T = B*E
102 GrB_Index nrows, ncols ;
103 GrB_Matrix_nrows (&nrows, B) ;
104 GrB_Matrix_ncols (&ncols, E) ;
105 GrB_Matrix_new (&T, A->type, nrows, ncols) ;
106 GxB_Matrix_Option_set_(T, GxB_SPARSITY_CONTROL, GxB_SPARSE) ;
107 GrB_mxm (T, NULL, NULL, semiring, B, E, desc) ;
108
109 // C = A*T
110 GrB_Matrix_ncols (&nrows, A) ;
111 GrB_Matrix_new (&C, A->type, nrows, ncols) ;
112 GrB_mxm (C, NULL, NULL, semiring, A, T, desc) ;
113
114 // return C to MATLAB as a struct and free the GraphBLAS C
115 pargout [0] = GB_mx_Matrix_to_mxArray (&C, "C from GrB_mxm_triple", true) ;
116
117 FREE_ALL ;
118 }
119
120