1 //------------------------------------------------------------------------------
2 // GB_mex_Matrix_eWiseAdd: C<M> = accum(C,A+B)
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 \
13     "C = GB_mex_Matrix_eWiseAdd (C, M, accum, add, A, B, desc, test)"
14 
15 #define FREE_ALL                        \
16 {                                       \
17     GrB_Matrix_free_(&A) ;              \
18     GrB_Matrix_free_(&B) ;              \
19     GrB_Matrix_free_(&C) ;              \
20     GrB_Descriptor_free_(&desc) ;       \
21     GrB_Matrix_free_(&M) ;              \
22     GB_mx_put_global (true) ;           \
23 }
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 (true) ;
35     GrB_Matrix A = NULL ;
36     GrB_Matrix B = NULL ;
37     GrB_Matrix C = NULL ;
38     GrB_Matrix M = NULL ;
39     GrB_Descriptor desc = NULL ;
40 
41     // check inputs
42     if (nargout > 1 || nargin < 6 || nargin > 8)
43     {
44         mexErrMsgTxt ("Usage: " USAGE) ;
45     }
46 
47     // get C (make a deep copy)
48     #define GET_DEEP_COPY \
49     C = GB_mx_mxArray_to_Matrix (pargin [0], "C input", true, true) ;   \
50     if (nargin > 7 && C != NULL) C->nvec_nonempty = -1 ;
51     #define FREE_DEEP_COPY GrB_Matrix_free_(&C) ;
52     GET_DEEP_COPY ;
53     if (C == NULL)
54     {
55         FREE_ALL ;
56         mexErrMsgTxt ("C failed") ;
57     }
58 
59     // get M (shallow copy)
60     M = GB_mx_mxArray_to_Matrix (pargin [1], "M", false, false) ;
61     if (M == NULL && !mxIsEmpty (pargin [1]))
62     {
63         FREE_ALL ;
64         mexErrMsgTxt ("M failed") ;
65     }
66 
67     // get A (shallow copy)
68     A = GB_mx_mxArray_to_Matrix (pargin [4], "A input", false, true) ;
69     if (A == NULL)
70     {
71         FREE_ALL ;
72         mexErrMsgTxt ("A failed") ;
73     }
74 
75     // get B (shallow copy)
76     B = GB_mx_mxArray_to_Matrix (pargin [5], "B input", false, true) ;
77     if (B == NULL)
78     {
79         FREE_ALL ;
80         mexErrMsgTxt ("B failed") ;
81     }
82 
83     // get add operator
84     bool user_complex = (Complex != GxB_FC64)
85         && (A->type == Complex || B->type == Complex) ;
86     GrB_BinaryOp add ;
87     if (!GB_mx_mxArray_to_BinaryOp (&add, pargin [3], "add",
88         C->type, user_complex) || add == NULL)
89     {
90         FREE_ALL ;
91         mexErrMsgTxt ("add failed") ;
92     }
93 
94     // get accum, if present
95     user_complex = (Complex != GxB_FC64)
96         && (C->type == Complex || add->ztype == Complex) ;
97     GrB_BinaryOp accum ;
98     if (!GB_mx_mxArray_to_BinaryOp (&accum, pargin [2], "accum",
99         C->type, user_complex))
100     {
101         FREE_ALL ;
102         mexErrMsgTxt ("accum failed") ;
103     }
104 
105     // get desc
106     if (!GB_mx_mxArray_to_Descriptor (&desc, PARGIN (6), "desc"))
107     {
108         FREE_ALL ;
109         mexErrMsgTxt ("desc failed") ;
110     }
111 
112     // just for testing
113     if (nargin > 7)
114     {
115         if (M != NULL) M->nvec_nonempty = -1 ;
116         A->nvec_nonempty = -1 ;
117         B->nvec_nonempty = -1 ;
118         C->nvec_nonempty = -1 ;
119     }
120 
121     // C<M> = accum(C,A+B)
122     METHOD (GrB_Matrix_eWiseAdd_BinaryOp_(C, M, accum, add, A, B, desc)) ;
123 
124     // return C to MATLAB as a struct and free the GraphBLAS C
125     pargout [0] = GB_mx_Matrix_to_mxArray (&C, "C output", true) ;
126 
127     FREE_ALL ;
128 }
129 
130