1 //------------------------------------------------------------------------------
2 // GrB_Vector_apply: apply a unary or binary operator to a vector
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_apply.h"
11 #include "GB_scalar.h"
12
13 //------------------------------------------------------------------------------
14 // GrB_Vector_apply: apply a unary operator to a vector
15 //------------------------------------------------------------------------------
16
GrB_Vector_apply(GrB_Vector w,const GrB_Vector M,const GrB_BinaryOp accum,const GrB_UnaryOp op,const GrB_Vector u,const GrB_Descriptor desc)17 GrB_Info GrB_Vector_apply // w<M> = accum (w, op(u))
18 (
19 GrB_Vector w, // input/output vector for results
20 const GrB_Vector M, // optional mask for w, unused if NULL
21 const GrB_BinaryOp accum, // optional accum for z=accum(w,t)
22 const GrB_UnaryOp op, // operator to apply to the entries
23 const GrB_Vector u, // first input: vector u
24 const GrB_Descriptor desc // descriptor for w and M
25 )
26 {
27
28 //--------------------------------------------------------------------------
29 // check inputs
30 //--------------------------------------------------------------------------
31
32 GB_WHERE (w, "GrB_Vector_apply (w, M, accum, op, u, desc)") ;
33 GB_BURBLE_START ("GrB_apply") ;
34 GB_RETURN_IF_NULL_OR_FAULTY (w) ;
35 GB_RETURN_IF_FAULTY (M) ;
36 GB_RETURN_IF_NULL_OR_FAULTY (u) ;
37
38 ASSERT (GB_VECTOR_OK (w)) ;
39 ASSERT (M == NULL || GB_VECTOR_OK (M)) ;
40 ASSERT (GB_VECTOR_OK (u)) ;
41
42 // get the descriptor
43 GB_GET_DESCRIPTOR (info, desc, C_replace, Mask_comp, Mask_struct,
44 xx1, xx2, xx3, xx7) ;
45
46 //--------------------------------------------------------------------------
47 // apply the operator; do not transpose
48 //--------------------------------------------------------------------------
49
50 info = GB_apply (
51 (GrB_Matrix) w, C_replace, // w and its descriptor
52 (GrB_Matrix) M, Mask_comp, Mask_struct, // mask and its descriptor
53 accum, // optional accum for Z=accum(w,T)
54 op, // operator op(.) to apply to the entries
55 NULL, NULL, false, // no binary operator
56 (GrB_Matrix) u, false, // u, not transposed
57 Context) ;
58
59 GB_BURBLE_END ;
60 return (info) ;
61 }
62
63 //------------------------------------------------------------------------------
64 // GB_1st: apply a binary operator: op(x,u)
65 //------------------------------------------------------------------------------
66
GB_1st(GrB_Vector w,const GrB_Vector M,const GrB_BinaryOp accum,const GrB_BinaryOp op,const GxB_Scalar x,const GrB_Vector u,const GrB_Descriptor desc,GB_Context Context)67 static inline GrB_Info GB_1st // w<mask> = accum (w, op(x,u))
68 (
69 GrB_Vector w, // input/output vector for results
70 const GrB_Vector M, // optional mask for w, unused if NULL
71 const GrB_BinaryOp accum, // optional accum for z=accum(w,t)
72 const GrB_BinaryOp op, // operator to apply to the entries
73 const GxB_Scalar x, // first input: scalar x
74 const GrB_Vector u, // second input: vector u
75 const GrB_Descriptor desc, // descriptor for w and M
76 GB_Context Context
77 )
78 {
79
80 //--------------------------------------------------------------------------
81 // check inputs
82 //--------------------------------------------------------------------------
83
84 GB_BURBLE_START ("GrB_apply") ;
85 GB_RETURN_IF_NULL_OR_FAULTY (w) ;
86 GB_RETURN_IF_FAULTY (M) ;
87 GB_RETURN_IF_NULL_OR_FAULTY (x) ;
88 GB_RETURN_IF_NULL_OR_FAULTY (u) ;
89
90 ASSERT (GB_VECTOR_OK (w)) ;
91 ASSERT (M == NULL || GB_VECTOR_OK (M)) ;
92 ASSERT (GB_VECTOR_OK (u)) ;
93
94 // get the descriptor
95 GB_GET_DESCRIPTOR (info, desc, C_replace, Mask_comp, Mask_struct,
96 xx1, xx2, xx3, xx7) ;
97
98 //--------------------------------------------------------------------------
99 // apply the operator; do not transpose
100 //--------------------------------------------------------------------------
101
102 info = GB_apply (
103 (GrB_Matrix) w, C_replace, // w and its descriptor
104 (GrB_Matrix) M, Mask_comp, Mask_struct, // mask and its descriptor
105 accum, // optional accum for Z=accum(w,T)
106 NULL, // no unary operator
107 op, x, true, // operator op(x,.) to apply to the entries
108 (GrB_Matrix) u, false, // u, not transposed
109 Context) ;
110
111 GB_BURBLE_END ;
112 return (info) ;
113 }
114
115 //------------------------------------------------------------------------------
116 // GB_2nd: apply a binary operator: op(u,y)
117 //------------------------------------------------------------------------------
118
GB_2nd(GrB_Vector w,const GrB_Vector M,const GrB_BinaryOp accum,const GrB_BinaryOp op,const GrB_Vector u,const GxB_Scalar y,const GrB_Descriptor desc,GB_Context Context)119 static inline GrB_Info GB_2nd // w<mask> = accum (w, op(u,y))
120 (
121 GrB_Vector w, // input/output vector for results
122 const GrB_Vector M, // optional mask for w, unused if NULL
123 const GrB_BinaryOp accum, // optional accum for z=accum(w,t)
124 const GrB_BinaryOp op, // operator to apply to the entries
125 const GrB_Vector u, // first input: vector u
126 const GxB_Scalar y, // second input: scalar y
127 const GrB_Descriptor desc, // descriptor for w and M
128 GB_Context Context
129 )
130 {
131
132 //--------------------------------------------------------------------------
133 // check inputs
134 //--------------------------------------------------------------------------
135
136 GB_BURBLE_START ("GrB_apply") ;
137 GB_RETURN_IF_NULL_OR_FAULTY (w) ;
138 GB_RETURN_IF_FAULTY (M) ;
139 GB_RETURN_IF_NULL_OR_FAULTY (u) ;
140 GB_RETURN_IF_NULL_OR_FAULTY (y) ;
141
142 ASSERT (GB_VECTOR_OK (w)) ;
143 ASSERT (M == NULL || GB_VECTOR_OK (M)) ;
144 ASSERT (GB_VECTOR_OK (u)) ;
145
146 // get the descriptor
147 GB_GET_DESCRIPTOR (info, desc, C_replace, Mask_comp, Mask_struct,
148 xx1, xx2, xx3, xx7) ;
149
150 //--------------------------------------------------------------------------
151 // apply the operator; do not transpose
152 //--------------------------------------------------------------------------
153
154 info = GB_apply (
155 (GrB_Matrix) w, C_replace, // w and its descriptor
156 (GrB_Matrix) M, Mask_comp, Mask_struct, // mask and its descriptor
157 accum, // optional accum for Z=accum(w,T)
158 NULL, // no unary operator
159 op, y, false, // operator op(.,y) to apply to the entries
160 (GrB_Matrix) u, false, // u, not transposed
161 Context) ;
162
163 GB_BURBLE_END ;
164 return (info) ;
165 }
166
167 //------------------------------------------------------------------------------
168 // GxB_Vector_apply_BinaryOp1st: apply a binary operator: op(x,u)
169 //------------------------------------------------------------------------------
170
GxB_Vector_apply_BinaryOp1st(GrB_Vector w,const GrB_Vector M,const GrB_BinaryOp accum,const GrB_BinaryOp op,const GxB_Scalar x,const GrB_Vector u,const GrB_Descriptor desc)171 GrB_Info GxB_Vector_apply_BinaryOp1st // w<mask> = accum (w, op(x,u))
172 (
173 GrB_Vector w, // input/output vector for results
174 const GrB_Vector M, // optional mask for w, unused if NULL
175 const GrB_BinaryOp accum, // optional accum for z=accum(w,t)
176 const GrB_BinaryOp op, // operator to apply to the entries
177 const GxB_Scalar x, // first input: scalar x
178 const GrB_Vector u, // second input: vector u
179 const GrB_Descriptor desc // descriptor for w and M
180 )
181 {
182 GB_WHERE (w, "GxB_Vector_apply_BinaryOp1st (w, M, accum, op, x, u, desc)") ;
183 return (GB_1st (w, M, accum, op, x, u, desc, Context)) ;
184 }
185
186 //------------------------------------------------------------------------------
187 // GxB_Vector_apply_BinaryOp2nd: apply a binary operator: op(u,y)
188 //------------------------------------------------------------------------------
189
GxB_Vector_apply_BinaryOp2nd(GrB_Vector w,const GrB_Vector M,const GrB_BinaryOp accum,const GrB_BinaryOp op,const GrB_Vector u,const GxB_Scalar y,const GrB_Descriptor desc)190 GrB_Info GxB_Vector_apply_BinaryOp2nd // w<mask> = accum (w, op(u,y))
191 (
192 GrB_Vector w, // input/output vector for results
193 const GrB_Vector M, // optional mask for w, unused if NULL
194 const GrB_BinaryOp accum, // optional accum for z=accum(w,t)
195 const GrB_BinaryOp op, // operator to apply to the entries
196 const GrB_Vector u, // first input: vector u
197 const GxB_Scalar y, // second input: scalar y
198 const GrB_Descriptor desc // descriptor for w and M
199 )
200 {
201 GB_WHERE (w, "GxB_Vector_apply_BinaryOp2nd (w, M, accum, op, u, y, desc)") ;
202 return (GB_2nd (w, M, accum, op, u, y, desc, Context)) ;
203 }
204
205 //------------------------------------------------------------------------------
206 // GrB_Vector_apply_BinaryOp1st_TYPE: apply a binary operator: op(x,u)
207 //------------------------------------------------------------------------------
208
209 #define GB_BIND1ST(prefix,type,T,ampersand,stype) \
210 GrB_Info GB_EVAL3 (prefix, _Vector_apply_BinaryOp1st_, T) \
211 ( \
212 GrB_Vector w, /* input/output vector for results */ \
213 const GrB_Vector M, /* optional mask for w */ \
214 const GrB_BinaryOp accum, /* optional accum for Z=accum(w,T) */ \
215 const GrB_BinaryOp op, /* operator to apply to the entries */ \
216 const type x, /* first input: scalar x */ \
217 const GrB_Vector u, /* second input: vector u */ \
218 const GrB_Descriptor desc /* descriptor for w and M */ \
219 ) \
220 { \
221 GB_WHERE (w, "GrB_Vector_apply_BinaryOp1st_" GB_STR(T) \
222 "(w, M, accum, op, x, u, desc)") ; \
223 GB_SCALAR_WRAP (scalar, T, ampersand, x, stype) ; \
224 ASSERT_SCALAR_OK (scalar, "scalar for vector_apply_bind1st", GB0) ; \
225 return (GB_1st (w, M, accum, op, scalar, u, desc, Context)) ; \
226 }
227
228 GB_BIND1ST (GrB, bool , BOOL , &, GrB_BOOL )
229 GB_BIND1ST (GrB, int8_t , INT8 , &, GrB_INT8 )
230 GB_BIND1ST (GrB, int16_t , INT16 , &, GrB_INT16 )
231 GB_BIND1ST (GrB, int32_t , INT32 , &, GrB_INT32 )
232 GB_BIND1ST (GrB, int64_t , INT64 , &, GrB_INT64 )
233 GB_BIND1ST (GrB, uint8_t , UINT8 , &, GrB_UINT8 )
234 GB_BIND1ST (GrB, uint16_t , UINT16 , &, GrB_UINT16)
235 GB_BIND1ST (GrB, uint32_t , UINT32 , &, GrB_UINT32)
236 GB_BIND1ST (GrB, uint64_t , UINT64 , &, GrB_UINT64)
237 GB_BIND1ST (GrB, float , FP32 , &, GrB_FP32 )
238 GB_BIND1ST (GrB, double , FP64 , &, GrB_FP64 )
239 GB_BIND1ST (GxB, GxB_FC32_t, FC32 , &, GxB_FC32 )
240 GB_BIND1ST (GxB, GxB_FC64_t, FC64 , &, GxB_FC64 )
241 GB_BIND1ST (GrB, void * , UDT , , op->xtype )
242
243 //------------------------------------------------------------------------------
244 // GrB_Vector_apply_BinaryOp2nd_TYPE: apply a binary operator: op(u,y)
245 //------------------------------------------------------------------------------
246
247 #define GB_BIND2ND(prefix,type,T,ampersand,stype) \
248 GrB_Info GB_EVAL3 (prefix, _Vector_apply_BinaryOp2nd_, T) \
249 ( \
250 GrB_Vector w, /* input/output vector for results */ \
251 const GrB_Vector M, /* optional mask for w*/ \
252 const GrB_BinaryOp accum, /* optional accum for Z=accum(w,T) */ \
253 const GrB_BinaryOp op, /* operator to apply to the entries */ \
254 const GrB_Vector u, /* first input: vector u */ \
255 const type y, /* second input: scalar y */ \
256 const GrB_Descriptor desc /* descriptor for w and M */ \
257 ) \
258 { \
259 GB_WHERE (w, "GrB_Vector_apply_BinaryOp2nd_" GB_STR(T) \
260 "(w, M, accum, op, u, y, desc)") ; \
261 GB_SCALAR_WRAP (scalar, T, ampersand, y, stype) ; \
262 ASSERT_SCALAR_OK (scalar, "scalar for vector_apply_bind2nd", GB0) ; \
263 return (GB_2nd (w, M, accum, op, u, scalar, desc, Context)) ; \
264 }
265
266 GB_BIND2ND (GrB, bool , BOOL , &, GrB_BOOL )
267 GB_BIND2ND (GrB, int8_t , INT8 , &, GrB_INT8 )
268 GB_BIND2ND (GrB, int16_t , INT16 , &, GrB_INT16 )
269 GB_BIND2ND (GrB, int32_t , INT32 , &, GrB_INT32 )
270 GB_BIND2ND (GrB, int64_t , INT64 , &, GrB_INT64 )
271 GB_BIND2ND (GrB, uint8_t , UINT8 , &, GrB_UINT8 )
272 GB_BIND2ND (GrB, uint16_t , UINT16 , &, GrB_UINT16)
273 GB_BIND2ND (GrB, uint32_t , UINT32 , &, GrB_UINT32)
274 GB_BIND2ND (GrB, uint64_t , UINT64 , &, GrB_UINT64)
275 GB_BIND2ND (GrB, float , FP32 , &, GrB_FP32 )
276 GB_BIND2ND (GrB, double , FP64 , &, GrB_FP64 )
277 GB_BIND2ND (GxB, GxB_FC32_t, FC32 , &, GxB_FC32 )
278 GB_BIND2ND (GxB, GxB_FC64_t, FC64 , &, GxB_FC64 )
279 GB_BIND2ND (GrB, void * , UDT , , op->ytype )
280
281