File: GB_ewise_fulln.c

package info (click to toggle)
suitesparse 1%3A7.10.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 254,920 kB
  • sloc: ansic: 1,134,743; cpp: 46,133; makefile: 4,875; fortran: 2,087; java: 1,826; sh: 996; ruby: 725; python: 495; asm: 371; sed: 166; awk: 44
file content (158 lines) | stat: -rw-r--r-- 5,409 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//------------------------------------------------------------------------------
// GB_ewise_fulln: C = A+B where A and B are full, C is anything
//------------------------------------------------------------------------------

// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2025, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

//------------------------------------------------------------------------------

// C can have any sparsity on input; it becomes a full non-iso matrix on output.
// C can have pending work, which is discarded.

#include "ewise/GB_ewise.h"
#include "binaryop/GB_binop.h"
#include "jitifyer/GB_stringify.h"
#ifndef GBCOMPACT
#include "GB_control.h"
#include "FactoryKernels/GB_ew__include.h"
#endif

#define GB_FREE_ALL ;

GrB_Info GB_ewise_fulln      // C = A+B
(
    GrB_Matrix C,                   // input/output matrix
    const GrB_BinaryOp op,          // must not be a positional op
    const GrB_Matrix A,
    const GrB_Matrix B
)
{

    //--------------------------------------------------------------------------
    // check inputs
    //--------------------------------------------------------------------------

    GrB_Info info ;

    ASSERT_MATRIX_OK (C, "C for full C=A+B", GB0) ;
    ASSERT (GB_ZOMBIES_OK (C)) ;
    ASSERT (GB_JUMBLED_OK (C)) ;    // C is entirely overwritten by A+B
    ASSERT (GB_PENDING_OK (C)) ;

    ASSERT_MATRIX_OK (A, "A for full C=A+B", GB0) ;
    ASSERT (!GB_ZOMBIES (A)) ;
    ASSERT (!GB_JUMBLED (A)) ;
    ASSERT (!GB_PENDING (A)) ;

    ASSERT_MATRIX_OK (B, "B for full C=A+B", GB0) ;
    ASSERT (!GB_ZOMBIES (B)) ;
    ASSERT (!GB_JUMBLED (B)) ;
    ASSERT (!GB_PENDING (B)) ;

    ASSERT (GB_IS_FULL (A)) ;
    ASSERT (GB_IS_FULL (B)) ;

    ASSERT (!GB_IS_BITMAP (A)) ;
    ASSERT (!GB_IS_BITMAP (B)) ;

    ASSERT (!A->iso) ;
    ASSERT (!B->iso) ;

    ASSERT_BINARYOP_OK (op, "op for full C=A+B", GB0) ;
    ASSERT (!GB_OP_IS_POSITIONAL (op)) ;

    //--------------------------------------------------------------------------
    // determine the number of threads to use
    //--------------------------------------------------------------------------

    int64_t anz = GB_nnz (A) ;
    int nthreads_max = GB_Context_nthreads_max ( ) ;
    double chunk = GB_Context_chunk ( ) ;
    int nthreads = GB_nthreads (2 * anz, chunk, nthreads_max) ;

    //--------------------------------------------------------------------------
    // if C not already full, allocate it as full
    //--------------------------------------------------------------------------

    // clear prior content and create C as a full matrix.  Keep the same type
    // and CSR/CSC for C.  Allocate the values of C but do not initialize them.

    if (!GB_as_if_full (C))
    { 
        // free the content of C and reallocate it as a non-iso full matrix
        ASSERT (C != A && C != B) ;
        GB_phybix_free (C) ;
        GB_OK (GB_new_bix (&C,  // existing header
            C->type, C->vlen, C->vdim, GB_ph_null, C->is_csc, GxB_FULL, false,
            C->hyper_switch, -1, GB_nnz_full (C), true, false,
            /* OK: */ false, false, false)) ;
        C->magic = GB_MAGIC ;
    }
    else if (!GB_IS_FULL (C))
    { 
        // ensure C is full
        GB_convert_any_to_full (C) ;
    }
    ASSERT (GB_IS_FULL (C)) ;

    //--------------------------------------------------------------------------
    // via the factory kernel
    //--------------------------------------------------------------------------

    info = GrB_NO_VALUE ;

    #ifndef GBCOMPACT
    GB_IF_FACTORY_KERNELS_ENABLED
    { 

        //----------------------------------------------------------------------
        // define the worker for the switch factory
        //----------------------------------------------------------------------

        #define GB_Cewise_fulln(op,xname) \
            GB (_Cewise_fulln_ ## op ## xname)

        #define GB_BINOP_WORKER(op,xname)                           \
        {                                                           \
            info = GB_Cewise_fulln(op,xname) (C, A, B, nthreads) ;  \
        }                                                           \
        break ;

        //----------------------------------------------------------------------
        // launch the switch factory
        //----------------------------------------------------------------------

        GB_Opcode opcode ;
        GB_Type_code xcode, ycode, zcode ;
        if (GB_binop_builtin (A->type, false, B->type, false,
            op, false, &opcode, &xcode, &ycode, &zcode))
        { 
            #include "binaryop/factory/GB_binop_factory.c"
        }
    }
    #endif

    //--------------------------------------------------------------------------
    // via the JIT or PreJIT kernel
    //--------------------------------------------------------------------------

    if (info == GrB_NO_VALUE)
    { 
        info = GB_ewise_fulln_jit (C, op, A, B, nthreads) ;
    }

    // no generic kernel: returns GrB_NO_VALUE if no factory kernel exists and
    // no JIT kernel created.

    //--------------------------------------------------------------------------
    // return result
    //--------------------------------------------------------------------------

    if (info == GrB_SUCCESS)
    { 
        ASSERT_MATRIX_OK (C, "C output, full C=A+B", GB0) ;
    }
    return (info) ;
}