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