1function codegen_red
2%CODEGEN_RED create functions for all reduction operators
3%
4% This function creates all files of the form GB_red__*.c,
5% and the include file GB_red__include.h.
6
7% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
8% SPDX-License-Identifier: Apache-2.0
9
10fprintf ('\nreduction operators:\n') ;
11
12f = fopen ('Generated/GB_red__include.h', 'w') ;
13fprintf (f, '//------------------------------------------------------------------------------\n') ;
14fprintf (f, '// GB_red__include.h: definitions for GB_red__*.c\n') ;
15fprintf (f, '//------------------------------------------------------------------------------\n') ;
16fprintf (f, '\n') ;
17fprintf (f, '// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.\n') ;
18fprintf (f, '// SPDX-License-Identifier: Apache-2.0\n\n') ;
19fprintf (f, '// This file has been automatically generated from Generator/GB_red.h') ;
20fprintf (f, '\n\n') ;
21fclose (f) ;
22
23%-------------------------------------------------------------------------------
24% the monoid: MIN, MAX, PLUS, TIMES, ANY, OR, AND, XOR, EQ
25%-------------------------------------------------------------------------------
26
27% Note that the min and max monoids are written to obtain the correct
28% NaN behavior for float and double.  Comparisons with NaN are always false.
29% zarg is the accumulator.  If zarg is not NaN and the comparison is false,
30% zarg is not modified and the value of yarg is properly ignored.  Thus if zarg
31% is not NaN but yarg is NaN, then yarg is ignored.  If zarg is NaN, the
32% condition becomes true and zarg is replaced with yarg.
33
34% The panel size is selected so that the Panel array in GB_reduce_panel.c is
35% always 128 bytes in size (16 doubles = 16*8 = 128 bytes, 32 floats, etc).
36% This is 1024 bits, which can be computed with two 512-bit Intel vector
37% instructions.  Reducing the panel to 64 bytes (512 bits), or increasing
38% the panel size, is slightly slower.
39
40% Panel sizes are optimal for gcc 8.3, on a MacBook.  They are probably fine
41% for other architectures and compilers, too, but they haven't been tuned
42% except for gcc 8.3 on a Mac.
43
44% MIN: 10 monoids:  name      op   type        identity      terminal   panel
45% (all but bool and complex)
46fprintf ('\nmin    ') ;
47op = 'if (yarg < zarg) { zarg = yarg ; }' ;
48codegen_red_method ('min',    op, 'int8_t'  , 'INT8_MAX'  , 'INT8_MIN'  , 16) ;
49codegen_red_method ('min',    op, 'int16_t' , 'INT16_MAX' , 'INT16_MIN' , 16) ;
50codegen_red_method ('min',    op, 'int32_t' , 'INT32_MAX' , 'INT32_MIN' , 16) ;
51codegen_red_method ('min',    op, 'int64_t' , 'INT64_MAX' , 'INT64_MIN' , 16) ;
52codegen_red_method ('min',    op, 'uint8_t' , 'UINT8_MAX' , '0'         , 16) ;
53codegen_red_method ('min',    op, 'uint16_t', 'UINT16_MAX', '0'         , 16) ;
54codegen_red_method ('min',    op, 'uint32_t', 'UINT32_MAX', '0'         , 16) ;
55codegen_red_method ('min',    op, 'uint64_t', 'UINT64_MAX', '0'         , 16) ;
56op = 'if ((yarg < zarg) || (zarg != zarg)) { zarg = yarg ; }' ;
57codegen_red_method ('min',    op, 'float'   , 'INFINITY' , '(-INFINITY)', 16) ;
58codegen_red_method ('min',    op, 'double'  , ...
59    '((double) INFINITY)'  , '((double) -INFINITY)' , 16) ;
60
61% MAX: 10 monoids (all but bool and complex)
62fprintf ('\nmax    ') ;
63op = 'if (yarg > zarg) { zarg = yarg ; }' ;
64codegen_red_method ('max',    op, 'int8_t'  , 'INT8_MIN'  , 'INT8_MAX'  , 16) ;
65codegen_red_method ('max',    op, 'int16_t' , 'INT16_MIN' , 'INT16_MAX' , 16) ;
66codegen_red_method ('max',    op, 'int32_t' , 'INT32_MIN' , 'INT32_MAX' , 16) ;
67codegen_red_method ('max',    op, 'int64_t' , 'INT64_MIN' , 'INT64_MAX' , 16) ;
68codegen_red_method ('max',    op, 'uint8_t' , '0'         , 'UINT8_MAX' , 16) ;
69codegen_red_method ('max',    op, 'uint16_t', '0'         , 'UINT16_MAX', 16) ;
70codegen_red_method ('max',    op, 'uint32_t', '0'         , 'UINT32_MAX', 16) ;
71codegen_red_method ('max',    op, 'uint64_t', '0'         , 'UINT64_MAX', 16) ;
72op = 'if ((yarg > zarg) || (zarg != zarg)) { zarg = yarg ; }' ;
73codegen_red_method ('max',    op, 'float'   , '(-INFINITY)', 'INFINITY' , 16) ;
74codegen_red_method ('max',    op, 'double'  , ...
75    '((double) -INFINITY)'  , '((double) INFINITY)' , 16) ;
76
77% ANY: 13 monoids (including bool and complex)
78fprintf ('\nany    ') ;
79op = 'zarg = yarg' ;
80codegen_red_method ('any' ,   op, 'bool'      , '0') ;
81codegen_red_method ('any',    op, 'int8_t'    , '0') ;
82codegen_red_method ('any',    op, 'int16_t'   , '0') ;
83codegen_red_method ('any',    op, 'int32_t'   , '0') ;
84codegen_red_method ('any',    op, 'int64_t'   , '0') ;
85codegen_red_method ('any',    op, 'uint8_t'   , '0') ;
86codegen_red_method ('any',    op, 'uint16_t'  , '0') ;
87codegen_red_method ('any',    op, 'uint32_t'  , '0') ;
88codegen_red_method ('any',    op, 'uint64_t'  , '0') ;
89codegen_red_method ('any',    op, 'float'     , '0') ;
90codegen_red_method ('any',    op, 'double'    , '0') ;
91codegen_red_method ('any',    op, 'GxB_FC32_t', 'GxB_CMPLXF(0,0)') ;
92codegen_red_method ('any',    op, 'GxB_FC64_t', 'GxB_CMPLX(0,0)') ;
93
94% PLUS: 12 monoids (all but bool)
95fprintf ('\nplus   ') ;
96op = 'zarg += yarg' ;
97codegen_red_method ('plus',   op, 'int8_t'    , '0'              , [ ], 64) ;
98codegen_red_method ('plus',   op, 'int16_t'   , '0'              , [ ], 64) ;
99codegen_red_method ('plus',   op, 'int32_t'   , '0'              , [ ], 64) ;
100codegen_red_method ('plus',   op, 'int64_t'   , '0'              , [ ], 32) ;
101codegen_red_method ('plus',   op, 'uint8_t'   , '0'              , [ ], 64) ;
102codegen_red_method ('plus',   op, 'uint16_t'  , '0'              , [ ], 64) ;
103codegen_red_method ('plus',   op, 'uint32_t'  , '0'              , [ ], 64) ;
104codegen_red_method ('plus',   op, 'uint64_t'  , '0'              , [ ], 32) ;
105codegen_red_method ('plus',   op, 'float'     , '0'              , [ ], 64) ;
106codegen_red_method ('plus',   op, 'double'    , '0'              , [ ], 32) ;
107op = 'zarg = GB_FC32_add (zarg, yarg)' ;
108codegen_red_method ('plus',   op, 'GxB_FC32_t', 'GxB_CMPLXF(0,0)', [ ], 32) ;
109op = 'zarg = GB_FC64_add (zarg, yarg)' ;
110codegen_red_method ('plus',   op, 'GxB_FC64_t', 'GxB_CMPLX(0,0)' , [ ], 16) ;
111
112% TIMES: 12 monoids (all but bool)
113fprintf ('\ntimes  ') ;
114op = 'zarg *= yarg' ;
115codegen_red_method ('times',  op, 'int8_t'    , '1'              , '0', 64) ;
116codegen_red_method ('times',  op, 'int16_t'   , '1'              , '0', 64) ;
117codegen_red_method ('times',  op, 'int32_t'   , '1'              , '0', 64) ;
118codegen_red_method ('times',  op, 'int64_t'   , '1'              , '0', 16) ;
119codegen_red_method ('times',  op, 'uint8_t'   , '1'              , '0', 64) ;
120codegen_red_method ('times',  op, 'uint16_t'  , '1'              , '0', 64) ;
121codegen_red_method ('times',  op, 'uint32_t'  , '1'              , '0', 64) ;
122codegen_red_method ('times',  op, 'uint64_t'  , '1'              , '0', 16) ;
123codegen_red_method ('times',  op, 'float'     , '1'              , [ ], 64) ;
124codegen_red_method ('times',  op, 'double'    , '1'              , [ ], 32) ;
125op = 'zarg = GB_FC32_mul (zarg, yarg)' ;
126codegen_red_method ('times',  op, 'GxB_FC32_t', 'GxB_CMPLXF(1,0)', [ ], 32) ;
127op = 'zarg = GB_FC64_mul (zarg, yarg)' ;
128codegen_red_method ('times',  op, 'GxB_FC64_t', 'GxB_CMPLX(1,0)' , [ ], 16) ;
129
130% 4 boolean monoids
131fprintf ('\nlor    ') ;
132codegen_red_method ('lor' , 'zarg = (zarg || yarg)', 'bool','false', 'true' ,8);
133fprintf ('\nland   ') ;
134codegen_red_method ('land', 'zarg = (zarg && yarg)', 'bool','true' , 'false',8);
135fprintf ('\nlxor   ') ;
136codegen_red_method ('lxor', 'zarg = (zarg != yarg)', 'bool','false', [ ]    ,8);
137fprintf ('\neq     ') ;
138codegen_red_method ('eq'  , 'zarg = (zarg == yarg)', 'bool','true' , [ ]    ,8);
139fprintf ('\nany    ') ;
140codegen_red_method ('any' , 'zarg = (yarg)'        , 'bool','false') ;
141
142%-------------------------------------------------------------------------------
143% FIRST and SECOND (not monoids; used for GB_red_build__first,second_type)
144%-------------------------------------------------------------------------------
145
146% FIRST: 13 ops:    name      op           type        identity terminal panel
147fprintf ('\nfirst  ') ;
148codegen_red_method ('first',  ';'          , 'bool'      , [ ]  , [ ],   1  ) ;
149codegen_red_method ('first',  ';'          , 'int8_t'    , [ ]  , [ ],   1  ) ;
150codegen_red_method ('first',  ';'          , 'int16_t'   , [ ]  , [ ],   1  ) ;
151codegen_red_method ('first',  ';'          , 'int32_t'   , [ ]  , [ ],   1  ) ;
152codegen_red_method ('first',  ';'          , 'int64_t'   , [ ]  , [ ],   1  ) ;
153codegen_red_method ('first',  ';'          , 'uint8_t'   , [ ]  , [ ],   1  ) ;
154codegen_red_method ('first',  ';'          , 'uint16_t'  , [ ]  , [ ],   1  ) ;
155codegen_red_method ('first',  ';'          , 'uint32_t'  , [ ]  , [ ],   1  ) ;
156codegen_red_method ('first',  ';'          , 'uint64_t'  , [ ]  , [ ],   1  ) ;
157codegen_red_method ('first',  ';'          , 'float'     , [ ]  , [ ],   1  ) ;
158codegen_red_method ('first',  ';'          , 'double'    , [ ]  , [ ],   1  ) ;
159codegen_red_method ('first',  ';'          , 'GxB_FC32_t', [ ]  , [ ],   1  ) ;
160codegen_red_method ('first',  ';'          , 'GxB_FC64_t', [ ]  , [ ],   1  ) ;
161
162% SECOND: 13 ops    name      op           type        identity terminal panel
163fprintf ('\nsecond ') ;
164codegen_red_method ('second', 'zarg = yarg', 'bool'      , [ ]  , [ ],   1  ) ;
165codegen_red_method ('second', 'zarg = yarg', 'int8_t'    , [ ]  , [ ],   1  ) ;
166codegen_red_method ('second', 'zarg = yarg', 'int16_t'   , [ ]  , [ ],   1  ) ;
167codegen_red_method ('second', 'zarg = yarg', 'int32_t'   , [ ]  , [ ],   1  ) ;
168codegen_red_method ('second', 'zarg = yarg', 'int64_t'   , [ ]  , [ ],   1  ) ;
169codegen_red_method ('second', 'zarg = yarg', 'uint8_t'   , [ ]  , [ ],   1  ) ;
170codegen_red_method ('second', 'zarg = yarg', 'uint16_t'  , [ ]  , [ ],   1  ) ;
171codegen_red_method ('second', 'zarg = yarg', 'uint32_t'  , [ ]  , [ ],   1  ) ;
172codegen_red_method ('second', 'zarg = yarg', 'uint64_t'  , [ ]  , [ ],   1  ) ;
173codegen_red_method ('second', 'zarg = yarg', 'float'     , [ ]  , [ ],   1  ) ;
174codegen_red_method ('second', 'zarg = yarg', 'double'    , [ ]  , [ ],   1  ) ;
175codegen_red_method ('second', 'zarg = yarg', 'GxB_FC32_t', [ ]  , [ ],   1  ) ;
176codegen_red_method ('second', 'zarg = yarg', 'GxB_FC64_t', [ ]  , [ ],   1  ) ;
177
178fprintf ('\n') ;
179
180