File: GB_macrofy_query.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 (152 lines) | stat: -rw-r--r-- 5,113 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
//------------------------------------------------------------------------------
// GB_macrofy_query: construct GB_jit_query function for a kernel
//------------------------------------------------------------------------------

// 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_query
(
    FILE *fp,
    const bool builtin, // true if method is all builtin
    GrB_Monoid monoid,  // monoid for reduce or semiring; NULL otherwise
    GB_Operator op0,    // monoid op, select op, unary op, etc
    GB_Operator op1,    // binaryop for a semring
    GrB_Type type0,
    GrB_Type type1,
    GrB_Type type2,
    uint64_t hash,      // hash code for the kernel
    GB_jit_kcode kcode
)
{

    //--------------------------------------------------------------------------
    // create the function header, and query the version
    //--------------------------------------------------------------------------

    if (kcode >= GB_JIT_CUDA_KERNEL)
    {
        // ensure the query function can be called from a C function
        fprintf (fp, "extern \"C\"\n{\n") ;
    }

    fprintf (fp,
        "GB_JIT_GLOBAL GB_JIT_QUERY_PROTO (GB_jit_query) ;\n") ;

    if (kcode >= GB_JIT_CUDA_KERNEL)
    {
        fprintf (fp, "}\n") ;
    }

    fprintf (fp,
        "GB_JIT_GLOBAL GB_JIT_QUERY_PROTO (GB_jit_query)\n"
        "{\n"
        "    (*hash) = 0x%016" PRIx64 " ;\n"
        "    v [0] = %d ; v [1] = %d ; v [2] = %d ;\n",
            hash,
            GxB_IMPLEMENTATION_MAJOR,
            GxB_IMPLEMENTATION_MINOR,
            GxB_IMPLEMENTATION_SUB) ;

    //--------------------------------------------------------------------------
    // query the operators
    //--------------------------------------------------------------------------

    // create the definition string for op0
    if (builtin || op0 == NULL || op0->defn == NULL)
    { 
        // op0 does not appear, or is builtin
        fprintf (fp, "    defn [0] = NULL ;\n") ;
    }
    else
    { 
        // op0 is user-defined
        fprintf (fp, "    defn [0] = GB_%s_USER_DEFN ;\n", op0->name) ;
    }

    // create the definition string for op1
    if (builtin || op1 == NULL || op1->defn == NULL)
    { 
        // op1 does not appear, or is builtin
        fprintf (fp, "    defn [1] = NULL ;\n") ;
    }
    else if (op0 == op1)
    { 
        // op1 is user-defined, but the same as op0
        fprintf (fp, "    defn [1] = defn [0] ;\n") ;
    }
    else
    { 
        // op1 is user-defined, and differs from op0
        fprintf (fp, "    defn [1] = GB_%s_USER_DEFN ;\n", op1->name) ;
    }

    //--------------------------------------------------------------------------
    // query the three types
    //--------------------------------------------------------------------------

    GrB_Type types [3] ;
    types [0] = type0 ;
    types [1] = type1 ;
    types [2] = type2 ;
    for (int k = 0 ; k <= 2 ; k++)
    {
        GrB_Type type = types [k] ;
        if (builtin || type == NULL || type->defn == NULL)
        { 
            // types [k] does not appear, or is builtin
            fprintf (fp, "    defn [%d] = NULL ;\n", k+2) ;
        }
        else
        { 
            // see if the type definition already appears
            bool is_unique = true ;
            for (int j = 0 ; j < k ; j++)
            {
                if (type == types [j])
                { 
                    is_unique = false ;
                    fprintf (fp, "    defn [%d] = defn [%d] ;\n", k+2, j+2) ;
                    break ;
                }
            }
            if (is_unique)
            { 
                // this type is unique, and user-defined
                fprintf (fp, "    defn [%d] = GB_%s_USER_DEFN ;\n", k+2,
                    type->name) ;
            }
        }
    }

    //--------------------------------------------------------------------------
    // query the monoid identity and terminal values
    //--------------------------------------------------------------------------

    if (monoid != NULL && monoid->hash != 0)
    { 
        // only create the query_monoid method if the monoid is not builtin
        bool has_terminal = (monoid->terminal != NULL) ;
        int zsize = (int) monoid->op->ztype->size ;
        int tsize = (has_terminal) ? zsize : 0 ;
        fprintf (fp,
            "    if (id_size != %d || term_size != %d) return (false) ;\n"
            "    GB_DECLARE_IDENTITY_CONST (zidentity) ;\n"
            "    if (id == NULL || memcmp (id, &zidentity, %d) != 0) "
                     "return (false) ;\n", zsize, tsize, zsize) ;
        if (has_terminal)
        { 
            fprintf (fp,
            "    GB_DECLARE_TERMINAL_CONST (zterminal) ;\n"
            "    if (term == NULL || memcmp (term, &zterminal, %d) != 0) "
                    "return (false) ;\n", tsize) ;
        }
    }
    fprintf (fp, "    return (true) ;\n}\n") ;
}