File: GB_macrofy_reduce.c

package info (click to toggle)
suitesparse 1%3A7.10.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, 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 (189 lines) | stat: -rw-r--r-- 6,713 bytes parent folder | download
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
//------------------------------------------------------------------------------
// GB_macrofy_reduce: construct all macros for a reduction to scalar
//------------------------------------------------------------------------------

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

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

#include "GB.h"
#include "jitifyer/GB_stringify.h"

void GB_macrofy_reduce      // construct all macros for GrB_reduce to scalar
(
    FILE *fp,               // target file to write, already open
    // input:
    uint64_t rcode,         // encoded problem
    GrB_Monoid monoid,      // monoid to macrofy
    GrB_Type atype          // type of the A matrix to reduce
)
{ 

    //--------------------------------------------------------------------------
    // extract the reduction rcode
    //--------------------------------------------------------------------------

    // monoid
//  int cheese      = GB_RSHIFT (rcode, 16, 1) ;
//  int red_code    = GB_RSHIFT (rcode, 12, 4) ;

    // type of the monoid
    int zcode       = GB_RSHIFT (rcode, 8, 4) ;

    // type of A
    int acode       = GB_RSHIFT (rcode, 4, 4) ;

    // Ai: 32/64 bit
    bool Ai_is_32   = GB_RSHIFT (rcode, 3, 1) ;

    // zombies
    int azombies    = GB_RSHIFT (rcode, 2, 1) ;

    // format of A
    int asparsity   = GB_RSHIFT (rcode, 0, 2) ;

    //--------------------------------------------------------------------------
    // copyright, license, and describe monoid
    //--------------------------------------------------------------------------

    fprintf (fp, "// reduce: (%s, %s)\n",
        monoid->op->name, monoid->op->ztype->name) ;

    //--------------------------------------------------------------------------
    // construct the typedefs
    //--------------------------------------------------------------------------

    GB_macrofy_typedefs (fp, NULL, atype, NULL, NULL, NULL, monoid->op->ztype) ;

    //--------------------------------------------------------------------------
    // construct the monoid macros
    //--------------------------------------------------------------------------

    fprintf (fp, "\n// monoid:\n") ;
    GB_macrofy_type (fp, "Z", "_", monoid->op->ztype->name) ;
    GB_macrofy_monoid (fp, false, monoid, false, NULL, NULL) ;

    fprintf (fp, "#define GB_GETA_AND_UPDATE(z,Ax,p)") ;
    if (atype == monoid->op->ztype)
    { 
        // z += Ax [p], with no typecasting.  A is never iso.
        fprintf (fp, " GB_UPDATE (z, Ax [p])\n") ;
    }
    else
    { 
        // aij = (ztype) Ax [p] ; z += aij ; with typecasting.  A is never iso.
        fprintf (fp, " \\\n"
                     "{                             \\\n"
                     "    /* z += (ztype) Ax [p] */ \\\n"
                     "    GB_DECLAREA (aij) ;       \\\n"
                     "    GB_GETA (aij, Ax, p, ) ;  \\\n"
                     "    GB_UPDATE (z, aij) ;      \\\n"
                     "}\n"
                     ) ;
    }

    //--------------------------------------------------------------------------
    // construct the macros for A
    //--------------------------------------------------------------------------

    // iso reduction is handled by GB_reduce_to_scalar_iso, which takes
    // O(log(nvals(A))) for any monoid and uses the function pointer of the
    // monoid operator.  No JIT kernel is ever required to reduce an iso matrix
    // to a scalar, even for user-defined types and monoids.

    bool Ap_is_32 = false ; // OK: may be 32-bit but A->p is not accessed
    bool Aj_is_32 = false ; // OK: may be 32-bit but A->h is not accessed

    GB_macrofy_input (fp, "a", "A", "A", true, monoid->op->ztype,
        atype, asparsity, acode, /* A_iso: */ false, azombies,
        Ap_is_32, Aj_is_32, Ai_is_32) ;

    //--------------------------------------------------------------------------
    // reduction method
    //--------------------------------------------------------------------------

    fprintf (fp, "\n// panel size for reduction:\n") ;
    int zsize = (int) monoid->op->ztype->size ;
    int panel = 1 ;

    GB_Opcode opcode = monoid->op->opcode ;

    if (opcode == GB_ANY_binop_code || azombies)
    { 
        // ANY monoid, or zombies: do not use panel reduction method
        panel = 1 ;
    }
    else if (zcode == GB_BOOL_code)
    { 
        // all boolean monoids, including user-defined
        panel = 8 ;
    }
    else
    { 

        switch (monoid->op->opcode)
        {

            // min and max
            case GB_MIN_binop_code : 
            case GB_MAX_binop_code : 
                panel = 16 ;
                break ;

            // plus, times, and all bitwise monoids
            case GB_PLUS_binop_code  : 
            case GB_TIMES_binop_code : 
            case GB_BOR_binop_code   : 
            case GB_BAND_binop_code  : 
            case GB_BXOR_binop_code  : 
            case GB_BXNOR_binop_code : 
                switch (zcode)
                {
                    // integer:
                    case GB_INT8_code    : 
                    case GB_UINT8_code   : 
                    case GB_INT16_code   : 
                    case GB_UINT16_code  : 
                    case GB_INT32_code   : 
                    case GB_UINT32_code  : panel = 64 ; break ;
                    case GB_INT64_code   : 
                    case GB_UINT64_code  : panel = 32 ; break ;

                    // floating point:
                    case GB_FP32_code    : panel = 64 ; break ;
                    case GB_FP64_code    : panel = 32 ; break ;
                    case GB_FC32_code    : panel = 32 ; break ;
                    case GB_FC64_code    : panel = 16 ; break ;
                    default:;
                }
                break ;

            default : 

                // all other monoids, including user-defined monoids
                if (zsize <= 16)
                { 
                    panel = 16 ;
                }
                else if (zsize <= 32)
                { 
                    panel = 8 ;
                }
                else
                { 
                    // type is large; do not use panel reduction method
                    panel = 1 ;
                }
        }
    }

    fprintf (fp, "#define GB_PANEL %d\n", panel) ;

    //--------------------------------------------------------------------------
    // include the final default definitions
    //--------------------------------------------------------------------------

    fprintf (fp, "\n#include \"include/GB_monoid_shared_definitions.h\"\n") ;
}