1 //------------------------------------------------------------------------------
2 // GB_dense_ewise3_accum: C += A+B where all 3 matries are dense
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_dense.h"
11 #include "GB_binop.h"
12 #ifndef GBCOMPACT
13 #include "GB_binop__include.h"
14
GB_dense_ewise3_accum(GrB_Matrix C,const GrB_Matrix A,const GrB_Matrix B,const GrB_BinaryOp op,GB_Context Context)15 void GB_dense_ewise3_accum // C += A+B, all matrices dense
16 (
17 GrB_Matrix C, // input/output matrix
18 const GrB_Matrix A,
19 const GrB_Matrix B,
20 const GrB_BinaryOp op, // only GB_BINOP_SUBSET operators supported
21 GB_Context Context
22 )
23 {
24
25 //--------------------------------------------------------------------------
26 // check inputs
27 //--------------------------------------------------------------------------
28
29 ASSERT_MATRIX_OK (C, "C for dense C+=A+B", GB0) ;
30 ASSERT (!GB_ZOMBIES (C)) ;
31 ASSERT (!GB_JUMBLED (C)) ;
32 ASSERT (!GB_PENDING (C)) ;
33 ASSERT (GB_is_dense (C)) ;
34
35 ASSERT_MATRIX_OK (A, "A for dense C+=A+B", GB0) ;
36 ASSERT (!GB_ZOMBIES (A)) ;
37 ASSERT (!GB_JUMBLED (A)) ;
38 ASSERT (!GB_PENDING (A)) ;
39 ASSERT (GB_is_dense (A)) ;
40
41 ASSERT_MATRIX_OK (B, "B for dense C+=A+B", GB0) ;
42 ASSERT (!GB_ZOMBIES (B)) ;
43 ASSERT (!GB_JUMBLED (B)) ;
44 ASSERT (!GB_PENDING (B)) ;
45 ASSERT (GB_is_dense (B)) ;
46
47 ASSERT (!GB_IS_BITMAP (C)) ;
48 ASSERT (!GB_IS_BITMAP (A)) ;
49 ASSERT (!GB_IS_BITMAP (B)) ;
50
51 ASSERT_BINARYOP_OK (op, "op for dense C+=A+B", GB0) ;
52 ASSERT (!GB_OP_IS_POSITIONAL (op)) ;
53 ASSERT (op->ztype == C->type) ;
54 ASSERT (op->ztype == A->type) ;
55 ASSERT (op->ztype == B->type) ;
56 ASSERT (op->ztype == op->xtype) ;
57 ASSERT (op->ztype == op->ytype) ;
58 ASSERT (op->opcode >= GB_MIN_opcode) ;
59 ASSERT (op->opcode <= GB_RDIV_opcode) ;
60
61 GB_ENSURE_FULL (C) ; // convert C to full
62
63 // FUTURE::: handle IS*, LOR, LAND, LXOR operators
64
65 //--------------------------------------------------------------------------
66 // determine the number of threads to use
67 //--------------------------------------------------------------------------
68
69 int64_t cnz = GB_NNZ (C) ;
70
71 GB_GET_NTHREADS_MAX (nthreads_max, chunk, Context) ;
72 int nthreads = GB_nthreads (3 * cnz, chunk, nthreads_max) ;
73
74 //--------------------------------------------------------------------------
75 // define the worker for the switch factory
76 //--------------------------------------------------------------------------
77
78 #define GB_Cdense_ewise3_accum(op,xname) \
79 GB (_Cdense_ewise3_accum_ ## op ## xname)
80
81 #define GB_BINOP_WORKER(op,xname) \
82 { \
83 GB_Cdense_ewise3_accum(op,xname) (C, A, B, nthreads) ; \
84 } \
85 break ;
86
87 //--------------------------------------------------------------------------
88 // launch the switch factory
89 //--------------------------------------------------------------------------
90
91 GB_Opcode opcode ;
92 GB_Type_code xcode, ycode, zcode ;
93 if (GB_binop_builtin (A->type, false, B->type, false,
94 op, false, &opcode, &xcode, &ycode, &zcode))
95 {
96 #define GB_BINOP_SUBSET
97 #include "GB_binop_factory.c"
98 }
99 else
100 {
101 // this function is not called if the op cannot be applied
102 ASSERT (GB_DEAD_CODE) ;
103 }
104
105 //--------------------------------------------------------------------------
106 // return result
107 //--------------------------------------------------------------------------
108
109 ASSERT_MATRIX_OK (C, "C+=A+B output", GB0) ;
110 }
111
112 #endif
113
114