File: codegen_red_method.m

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 (169 lines) | stat: -rw-r--r-- 6,501 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
159
160
161
162
163
164
165
166
167
168
169
function codegen_red_method (opname, op, atype, identity, terminal, panel)
%CODEGEN_RED_METHOD create a reduction function, C = reduce (A)
%
% codegen_red_method (opname, op, atype, identity, terminal)

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

f = fopen ('control.m4', 'w') ;
fprintf (f, 'm4_divert(-1)\n') ;

[aname, unsigned, bits] = codegen_type (atype) ;
codegen_type_enabled (f, aname) ;

name = sprintf ('%s_%s', opname, aname) ;
is_any = isequal (opname, 'any') ;

% function names
fprintf (f, 'm4_define(`_bld'', `_bld__%s'')\n', name) ;

% the type of A, S, T, X, Y, and Z (no typecasting)
ztype = atype ;
fprintf (f, 'm4_define(`GB_atype'', `#define GB_A_TYPE  %s'')\n', atype) ;
fprintf (f, 'm4_define(`GB_stype'', `#define GB_Sx_TYPE %s'')\n', atype) ;
fprintf (f, 'm4_define(`GB_ttype'', `#define GB_Tx_TYPE %s'')\n', atype) ;
fprintf (f, 'm4_define(`GB_xtype'', `#define GB_X_TYPE  %s'')\n', atype) ;
fprintf (f, 'm4_define(`GB_ytype'', `#define GB_Y_TYPE  %s'')\n', atype) ;
fprintf (f, 'm4_define(`GB_ztype'', `#define GB_Z_TYPE  %s'')\n', atype) ;

fprintf (f, 'm4_define(`GB_atype_parameter'', `%s'')\n', atype) ;
fprintf (f, 'm4_define(`GB_stype_parameter'', `%s'')\n', atype) ;
fprintf (f, 'm4_define(`GB_ttype_parameter'', `%s'')\n', atype) ;

is_monoid = ~isempty (identity) ;
if (is_monoid)
    % monoid function name and identity value
    fprintf (f, 'm4_define(`_red'',    `_red__%s'')\n', name) ;
    fprintf (f, 'm4_define(`GB_identity'', `%s'')\n', identity) ;
else
    % first and second operators are not monoids
    fprintf (f, 'm4_define(`_red'',    `_red__(none)'')\n') ;
    fprintf (f, 'm4_define(`GB_identity'', `(none)'')\n') ;
end

% identity value for the monoid
if (is_monoid)
    define_id = sprintf (' %s z = %s', ztype, identity) ;
    define_const_id = sprintf (' const %s z = %s', ztype, identity) ;
    fprintf (f, 'm4_define(`GB_declare_identity'', `#define GB_DECLARE_IDENTITY(z)%s'')\n', define_id) ;
    fprintf (f, 'm4_define(`GB_declare_const_identity'', `#define GB_DECLARE_IDENTITY_CONST(z)%s'')\n', define_const_id) ;
end

% A is never iso
fprintf (f, 'm4_define(`GB_declarea'', `#define GB_DECLAREA(aij) %s aij'')\n', atype) ;
fprintf (f, 'm4_define(`GB_geta'', `#define GB_GETA(aij,Ax,pA,A_iso) aij = Ax [pA]'')\n') ;

tvalue = '' ;
tbreak = '' ;
tcondition = '' ;

if (is_any)
    % ANY monoid is terminal
    terminal = ' ' ;
    is_terminal = 1 ;
elseif (~isempty (terminal))
    % monoid is terminal
    is_terminal = 1 ;
    tbreak = sprintf (' if (z == %s) { break ; }', terminal) ;
%   tvalue = sprintf (' const %s zterminal = %s ;', ztype, terminal) ;
    tvalue = '' ;
    tcondition = sprintf (' (z == %s)', terminal) ;
else
    % monoid is not terminal
    is_terminal = 0 ;
end

if (is_any)
    fprintf (f, 'm4_define(`GB_is_any_monoid'', `%s'')\n', ...
        '#define GB_IS_ANY_MONOID 1') ;
else
    fprintf (f, 'm4_define(`GB_is_any_monoid'', `'')\n') ;
end

if (is_terminal)
    fprintf (f, 'm4_define(`GB_monoid_is_terminal'', `%s'')\n', ...
        '#define GB_MONOID_IS_TERMINAL 1') ;
else
    fprintf (f, 'm4_define(`GB_monoid_is_terminal'', `'')\n') ;
end

if (~isempty (tcondition))
    % monoid is terminal
    fprintf (f, 'm4_define(`GB_terminal_condition'', `#define GB_TERMINAL_CONDITION(z,zterminal)%s'')\n', tcondition) ;
    fprintf (f, 'm4_define(`GB_if_terminal_break'', `#define GB_IF_TERMINAL_BREAK(z,zterminal)%s'')\n', tbreak) ;
else
    % will be defined by GB_monoid_shared_definitions.h
    fprintf (f, 'm4_define(`GB_terminal_condition'', `'')\n') ;
    fprintf (f, 'm4_define(`GB_if_terminal_break'', `'')\n') ;
end

if (~isempty (tvalue))
    fprintf (f, 'm4_define(`GB_declare_const_terminal'', `#define GB_DECLARE_TERMINAL_CONST(zterminal)%s'')\n', tvalue) ;
else
    fprintf (f, 'm4_define(`GB_declare_const_terminal'', `'')\n') ;
end

if (is_any)
    % no panel for the ANY monoid
    fprintf (f, 'm4_define(`GB_panel'', `'')\n') ;
else
    fprintf (f, 'm4_define(`GB_panel'', `#define GB_PANEL %d'')\n', panel) ;
end

% create the update operator
update_op = op {1} ;
update_op = strrep (update_op, 'zarg', 'z') ;
update_op = strrep (update_op, 'yarg', 'a') ;
fprintf (f, 'm4_define(`GB_update_op'', `#define GB_UPDATE(z,a)  %s'')\n', update_op) ;

% create the geta_and_update macro
geta_and_update = op {1} ;
geta_and_update = strrep (geta_and_update, 'zarg', 'z') ;
geta_and_update = strrep (geta_and_update, 'yarg', 'Ax [p]') ;
fprintf (f, 'm4_define(`GB_geta_and_update'', `#define GB_GETA_AND_UPDATE(z,Ax,p) %s'')\n', geta_and_update) ;

% create the dup operator
dup_op = op {1} ;
dup_op = strrep (dup_op, 'zarg', 'Tx [k]') ;
dup_op = strrep (dup_op, 'yarg', 'Sx [i]') ;
fprintf (f, 'm4_define(`GB_bld_dup'', `#define GB_BLD_DUP(Tx,k,Sx,i)  %s'')\n', dup_op) ;
if (isequal (opname, 'first'))
    fprintf (f, 'm4_define(`GB_dup_is_first'', `#define GB_DUP_IS_FIRST'')\n') ;
else
    fprintf (f, 'm4_define(`GB_dup_is_first'', `'')\n') ;
end

% create the function operator
add_op = op {2} ;
add_op = strrep (add_op, 'zarg', 'z') ;
add_op = strrep (add_op, 'xarg', 'zin') ;
add_op = strrep (add_op, 'yarg', 'a') ;
fprintf (f, 'm4_define(`GB_add_op'', `#define GB_ADD(z,zin,a) %s'')\n', add_op) ;

% create the disable flag
disable  = sprintf ('defined(GxB_NO_%s)', upper (opname)) ;
disable = [disable (sprintf (' || defined(GxB_NO_%s)', upper (aname)))] ;
disable = [disable (sprintf (' || defined(GxB_NO_%s_%s)', upper (opname), upper (aname)))] ;
fprintf (f, 'm4_define(`GB_disable'', `#if (%s)\n#define GB_DISABLE 1\n#else\n#define GB_DISABLE 0\n#endif\n'')\n', disable) ;

fprintf (f, 'm4_divert(0)\n') ;
fclose (f) ;

if (is_monoid)
    % construct the *.c file for the reduction to scalar
    cmd = sprintf ('cat control.m4 Generator/GB_red.c | m4 -P | awk -f codegen_blank.awk > ../../FactoryKernels/GB_red__%s.c', name) ;
    fprintf ('.') ;
    system (cmd) ;
    % append to the *.h file
    system ('cat control.m4 Generator/GB_red.h | m4 -P | awk -f codegen_blank.awk | grep -v SPDX >> ../../FactoryKernels/GB_red__include.h') ;
end

% construct the build *.c and *.h files
cmd = sprintf ('cat control.m4 Generator/GB_bld.c | m4 -P | awk -f codegen_blank.awk > ../../FactoryKernels/GB_bld__%s.c', name) ;
fprintf ('.') ;
system (cmd) ;
system ('cat control.m4 Generator/GB_bld.h | m4 -P | awk -f codegen_blank.awk | grep -v SPDX >> ../../FactoryKernels/GB_bld__include.h') ;

delete ('control.m4') ;