File: GB_demacrofy_name.c

package info (click to toggle)
suitesparse 1%3A7.11.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 258,172 kB
  • sloc: ansic: 1,153,566; cpp: 48,145; makefile: 4,997; fortran: 2,087; java: 1,826; sh: 1,113; ruby: 725; python: 676; asm: 371; sed: 166; awk: 44
file content (136 lines) | stat: -rw-r--r-- 4,913 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
//------------------------------------------------------------------------------
// GB_demacrofy_name: parse a kernel name for its kname, method_code, and suffix
//------------------------------------------------------------------------------

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

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

// The kernel name has the following form, if the suffix is non-NULL:
//
//      namespace__kname__012345__suffix
//
// or, when suffix is NULL:
//
//      namespace__kname__012345
//
// where "012345" is a hexadecimal printing of the method_code.  Note the double
// underscores that precede the method_code and the suffix.
//
// GB_demacrofy_name parses the kernel_name of a PreJIT kernel, extracting the
// namespace, kname, method_code (as a uint64_t), and suffix.  NUL characters
// are inserted into kernel_name where the dots appear:
//
//      namespace._kname._012345._suffix
//
//      namespace._kname._012345.
//
// The suffix is used only for user-defined types and operators.
//
// CUDA kernels are not supported.

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

GrB_Info GB_demacrofy_name
(
    // input/output:
    char *kernel_name,      // string of length GB_KLEN; NUL's are inserted
                            // to demarcate each part of the kernel_name.
    // output
    char **name_space,      // namespace for the kernel_name
    char **kname,           // kname for the kernel_name
    uint64_t *method_code,  // enumify'd code of the kernel
    char **suffix           // suffix for the kernel_name (NULL if none)
)
{

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

    ASSERT (kernel_name != NULL) ;
    ASSERT (name_space != NULL) ;
    ASSERT (kname != NULL) ;
    ASSERT (method_code != NULL) ;
    ASSERT (suffix != NULL) ;

    (*name_space) = NULL ;
    (*kname) = NULL ;
    (*method_code) = 0 ;
    (*suffix) = NULL ;  // remains NULL if kernel uses only builtin types/ops

    //--------------------------------------------------------------------------
    // find the first 2 or 3 pairs of double underscores
    //--------------------------------------------------------------------------

    size_t len = strlen (kernel_name) ;  
    if (len < 4 || len > GB_KLEN)
    { 
        // kernel_name is invalid; ignore this kernel
        return (GrB_NO_VALUE) ;     // name invalid; ignore this PreJIT kernel
    }

    int ndouble = 0 ;
    (*name_space) = kernel_name ;
    char *method_code_string = NULL ;

    for (int k = 1 ; k < len - 1 ; k++)
    {
        if (kernel_name [k-1] == '_' && kernel_name [k] == '_')
        {
            // kernel_name [k-1:k] is a double underscore: "__"
            ndouble++ ;
            // mark the end of a component of the kernel_name
            kernel_name [k-1] = '\0' ;
            // advance to the start of the next component of the kernel_name
            k++ ;
            ASSERT (kernel_name [k] != '\0') ;
            if (ndouble == 1)
            { 
                // save the start of the kname component of the kernel_name
                (*kname) = &(kernel_name [k]) ;
            }
            else if (ndouble == 2)
            { 
                // save start of the method_code component of the kernel_name
                method_code_string = &(kernel_name [k]) ;
            }
            else if (ndouble == 3)
            { 
                // save the start of the suffix component of the kernel_name
                (*suffix) = &(kernel_name [k]) ;
                // the rest of the kernel_name is the entire suffix, so quit
                break ;
            }
        }
    }

    if (ndouble < 2)
    { 
        // didn't find 2 pairs of double underscores
        // kernel_name is invalid; ignore this kernel
        return (GrB_NO_VALUE) ;     // name invald; ignore this PreJIT kernel
    }

    //--------------------------------------------------------------------------
    // parse the method_code_string
    //--------------------------------------------------------------------------

    // If this is a CUDA kernel, the method_code_string has the form 012345_72,
    // where 012345 is the method_code and 72 denotes the sm_72 CUDA
    // architecture.  The sscanf will return the method_code and the CUDA
    // architecture will be ignored.

    uint64_t method_code_result = 0 ;
    if (sscanf (method_code_string, "%" SCNx64, &method_code_result) != 1)
    { 
        // didn't find method_code: kernel_name is invalid; ignore this kernel
        return (GrB_NO_VALUE) ;     // name invald; ignore this PreJIT kernel
    }

    (*method_code) = method_code_result ;
    return (GrB_SUCCESS) ;
}