1function codegen_red_method (opname, func, atype, identity, terminal, panel)
2%CODEGEN_RED_METHOD create a reduction function, C = reduce (A)
3%
4% codegen_red_method (opname, func, atype, identity, terminal)
5
6% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
7% SPDX-License-Identifier: Apache-2.0
8
9f = fopen ('control.m4', 'w') ;
10
11[aname, unsigned, bits] = codegen_type (atype) ;
12
13name = sprintf ('%s_%s', opname, aname) ;
14is_any = isequal (opname, 'any') ;
15
16% function names
17fprintf (f, 'define(`_red_build'', `_red_build__%s'')\n', name) ;
18
19% the type of A and C (no typecasting)
20fprintf (f, 'define(`GB_atype'', `%s'')\n', atype) ;
21fprintf (f, 'define(`GB_ctype'', `%s'')\n', atype) ;
22
23if (~isempty (identity))
24    fprintf (f, 'define(`_red_scalar'',    `_red_scalar__%s'')\n',    name);
25    % identity and terminal values for the monoid
26    fprintf (f, 'define(`GB_identity'', `%s'')\n', identity) ;
27    fprintf (f, 'define(`if_is_monoid'', `'')\n') ;
28    fprintf (f, 'define(`endif_is_monoid'', `'')\n') ;
29else
30    fprintf (f, 'define(`_red_scalar'',    `_red_scalar__(none)'')\n') ;
31    % first and second operators are not monoids
32    fprintf (f, 'define(`GB_identity'', `(none)'')\n') ;
33    fprintf (f, 'define(`if_is_monoid'', `#if 0'')\n') ;
34    fprintf (f, 'define(`endif_is_monoid'', `#endif'')\n') ;
35end
36
37if (is_any)
38    fprintf (f, 'define(`GB_is_any_monoid'', `1'')\n') ;
39    fprintf (f, 'define(`GB_has_terminal'', `1'')\n') ;
40    fprintf (f, 'define(`GB_terminal_value'', `(any value)'')\n') ;
41    fprintf (f, 'define(`GB_is_terminal'', `true'')\n') ;
42    fprintf (f, 'define(`GB_terminal'', `break ;'')\n') ;
43elseif (~isempty (terminal))
44    fprintf (f, 'define(`GB_is_any_monoid'', `0'')\n') ;
45    fprintf (f, 'define(`GB_has_terminal'', `1'')\n') ;
46    fprintf (f, 'define(`GB_terminal_value'', `%s'')\n', terminal) ;
47    fprintf (f, 'define(`GB_is_terminal'', `(s == %s)'')\n', terminal) ;
48    fprintf (f, 'define(`GB_terminal'', `if (s == %s) { break ; }'')\n', terminal) ;
49else
50    fprintf (f, 'define(`GB_is_any_monoid'', `0'')\n') ;
51    fprintf (f, 'define(`GB_has_terminal'', `0'')\n') ;
52    fprintf (f, 'define(`GB_terminal_value'', `(none)'')\n') ;
53    fprintf (f, 'define(`GB_is_terminal'', `(none)'')\n') ;
54    fprintf (f, 'define(`GB_terminal'', `;'')\n') ;
55end
56
57if (is_any)
58    fprintf (f, 'define(`GB_panel'', `(no panel)'')\n') ;
59else
60    fprintf (f, 'define(`GB_panel'', `%d'')\n', panel) ;
61end
62
63% create the operator
64func = strrep (func, 'zarg', '`$1''') ;
65func = strrep (func, 'yarg', '`$2''') ;
66fprintf (f, 'define(`GB_REDUCE_OP'', `%s'')\n', func) ;
67
68% create the disable flag
69disable  = sprintf ('GxB_NO_%s', upper (opname)) ;
70disable = [disable (sprintf (' || GxB_NO_%s', upper (aname)))] ;
71disable = [disable (sprintf (' || GxB_NO_%s_%s', upper (opname), upper (aname)))] ;
72fprintf (f, 'define(`GB_disable'', `(%s)'')\n', disable) ;
73
74fclose (f) ;
75
76% construct the *.c file
77cmd = sprintf (...
78'cat control.m4 Generator/GB_red.c | m4 | tail -n +16 > Generated/GB_red__%s.c', ...
79name) ;
80fprintf ('.') ;
81system (cmd) ;
82
83% append to the *.h file
84cmd = sprintf (...
85'cat control.m4 Generator/GB_red.h | m4 | tail -n +16 >> Generated/GB_red__include.h') ;
86system (cmd) ;
87
88delete ('control.m4') ;
89
90