File: codegen_red.m

package info (click to toggle)
suitesparse-graphblas 7.4.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 67,112 kB
  • sloc: ansic: 1,072,243; cpp: 8,081; sh: 512; makefile: 506; asm: 369; python: 125; awk: 10
file content (177 lines) | stat: -rw-r--r-- 10,252 bytes parent folder | download | duplicates (3)
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
170
171
172
173
174
175
176
177
function codegen_red
%CODEGEN_RED create functions for all reduction operators
%
% This function creates all files of the form GB_red__*.c,
% and the include file GB_red__include.h.

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

fprintf ('\nreduction operators:\n') ;

f = fopen ('Generated2/GB_red__include.h', 'w') ;
fprintf (f, '//------------------------------------------------------------------------------\n') ;
fprintf (f, '// GB_red__include.h: definitions for GB_red__*.c\n') ;
fprintf (f, '//------------------------------------------------------------------------------\n') ;
fprintf (f, '\n') ;
fprintf (f, '// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2022, All Rights Reserved.\n') ;
fprintf (f, '// SPDX-License-Identifier: Apache-2.0\n\n') ;
fprintf (f, '// This file has been automatically generated from Generator/GB_red.h') ;
fprintf (f, '\n\n') ;
fclose (f) ;

%-------------------------------------------------------------------------------
% the monoid: MIN, MAX, PLUS, TIMES, ANY, OR, AND, XOR, EQ
%-------------------------------------------------------------------------------

% Note that the min and max monoids are written to obtain the correct
% NaN behavior for float and double.  Compares with NaN are always false.
% zarg is the accumulator.  If zarg is not NaN and the compare is false,
% zarg is not modified and the value of yarg is properly ignored.  Thus if zarg
% is not NaN but yarg is NaN, then yarg is ignored.  If zarg is NaN, the
% condition becomes true and zarg is replaced with yarg.

% The panel size is selected so that the Panel array in GB_reduce_panel.c is
% always 128 bytes in size (16 doubles = 16*8 = 128 bytes, 32 floats, etc).
% This is 1024 bits, which can be computed with two 512-bit Intel vector
% instructions.  Reducing the panel to 64 bytes (512 bits), or increasing
% the panel size, is slightly slower.

% Panel sizes are optimal for gcc 8.3, on a MacBook.  They are probably fine
% for other architectures and compilers, too, but they haven't been tuned
% except for gcc 8.3 on a Mac.

% MIN: 10 monoids:  name      op   type        identity      terminal   panel
% (all but bool and complex)
fprintf ('\nmin    ') ;
op = 'if (yarg < zarg) { zarg = yarg ; }' ;
codegen_red_method ('min',    op, 'int8_t'  , 'INT8_MAX'  , 'INT8_MIN'  , 16) ;
codegen_red_method ('min',    op, 'int16_t' , 'INT16_MAX' , 'INT16_MIN' , 16) ;
codegen_red_method ('min',    op, 'int32_t' , 'INT32_MAX' , 'INT32_MIN' , 16) ;
codegen_red_method ('min',    op, 'int64_t' , 'INT64_MAX' , 'INT64_MIN' , 16) ;
codegen_red_method ('min',    op, 'uint8_t' , 'UINT8_MAX' , '0'         , 16) ;
codegen_red_method ('min',    op, 'uint16_t', 'UINT16_MAX', '0'         , 16) ;
codegen_red_method ('min',    op, 'uint32_t', 'UINT32_MAX', '0'         , 16) ;
codegen_red_method ('min',    op, 'uint64_t', 'UINT64_MAX', '0'         , 16) ;
op = 'if ((yarg < zarg) || (zarg != zarg)) { zarg = yarg ; }' ;
codegen_red_method ('min',    op, 'float'   , 'INFINITY' , [ ] , 16) ;
codegen_red_method ('min',    op, 'double'  , '((double) INFINITY)', [ ], 16) ;

% MAX: 10 monoids (all but bool and complex)
fprintf ('\nmax    ') ;
op = 'if (yarg > zarg) { zarg = yarg ; }' ;
codegen_red_method ('max',    op, 'int8_t'  , 'INT8_MIN'  , 'INT8_MAX'  , 16) ;
codegen_red_method ('max',    op, 'int16_t' , 'INT16_MIN' , 'INT16_MAX' , 16) ;
codegen_red_method ('max',    op, 'int32_t' , 'INT32_MIN' , 'INT32_MAX' , 16) ;
codegen_red_method ('max',    op, 'int64_t' , 'INT64_MIN' , 'INT64_MAX' , 16) ;
codegen_red_method ('max',    op, 'uint8_t' , '0'         , 'UINT8_MAX' , 16) ;
codegen_red_method ('max',    op, 'uint16_t', '0'         , 'UINT16_MAX', 16) ;
codegen_red_method ('max',    op, 'uint32_t', '0'         , 'UINT32_MAX', 16) ;
codegen_red_method ('max',    op, 'uint64_t', '0'         , 'UINT64_MAX', 16) ;
op = 'if ((yarg > zarg) || (zarg != zarg)) { zarg = yarg ; }' ;
codegen_red_method ('max',    op, 'float'   , '(-INFINITY)' , [ ] , 16) ;
codegen_red_method ('max',    op, 'double'  , '((double) -INFINITY)', [ ], 16) ;

% ANY: 13 monoids (including bool and complex)
fprintf ('\nany    ') ;
op = 'zarg = yarg' ;
codegen_red_method ('any' ,   op, 'bool'      , '0') ;
codegen_red_method ('any',    op, 'int8_t'    , '0') ;
codegen_red_method ('any',    op, 'int16_t'   , '0') ;
codegen_red_method ('any',    op, 'int32_t'   , '0') ;
codegen_red_method ('any',    op, 'int64_t'   , '0') ;
codegen_red_method ('any',    op, 'uint8_t'   , '0') ;
codegen_red_method ('any',    op, 'uint16_t'  , '0') ;
codegen_red_method ('any',    op, 'uint32_t'  , '0') ;
codegen_red_method ('any',    op, 'uint64_t'  , '0') ;
codegen_red_method ('any',    op, 'float'     , '0') ;
codegen_red_method ('any',    op, 'double'    , '0') ;
codegen_red_method ('any',    op, 'GxB_FC32_t', 'GxB_CMPLXF(0,0)') ;
codegen_red_method ('any',    op, 'GxB_FC64_t', 'GxB_CMPLX(0,0)') ;

% PLUS: 12 monoids (all but bool)
fprintf ('\nplus   ') ;
op = 'zarg += yarg' ;
codegen_red_method ('plus',   op, 'int8_t'    , '0'              , [ ], 64) ;
codegen_red_method ('plus',   op, 'int16_t'   , '0'              , [ ], 64) ;
codegen_red_method ('plus',   op, 'int32_t'   , '0'              , [ ], 64) ;
codegen_red_method ('plus',   op, 'int64_t'   , '0'              , [ ], 32) ;
codegen_red_method ('plus',   op, 'uint8_t'   , '0'              , [ ], 64) ;
codegen_red_method ('plus',   op, 'uint16_t'  , '0'              , [ ], 64) ;
codegen_red_method ('plus',   op, 'uint32_t'  , '0'              , [ ], 64) ;
codegen_red_method ('plus',   op, 'uint64_t'  , '0'              , [ ], 32) ;
codegen_red_method ('plus',   op, 'float'     , '0'              , [ ], 64) ;
codegen_red_method ('plus',   op, 'double'    , '0'              , [ ], 32) ;
op = 'zarg = GB_FC32_add (zarg, yarg)' ;
codegen_red_method ('plus',   op, 'GxB_FC32_t', 'GxB_CMPLXF(0,0)', [ ], 32) ;
op = 'zarg = GB_FC64_add (zarg, yarg)' ;
codegen_red_method ('plus',   op, 'GxB_FC64_t', 'GxB_CMPLX(0,0)' , [ ], 16) ;

% TIMES: 12 monoids (all but bool)
fprintf ('\ntimes  ') ;
op = 'zarg *= yarg' ;
codegen_red_method ('times',  op, 'int8_t'    , '1'              , '0', 64) ;
codegen_red_method ('times',  op, 'int16_t'   , '1'              , '0', 64) ;
codegen_red_method ('times',  op, 'int32_t'   , '1'              , '0', 64) ;
codegen_red_method ('times',  op, 'int64_t'   , '1'              , '0', 16) ;
codegen_red_method ('times',  op, 'uint8_t'   , '1'              , '0', 64) ;
codegen_red_method ('times',  op, 'uint16_t'  , '1'              , '0', 64) ;
codegen_red_method ('times',  op, 'uint32_t'  , '1'              , '0', 64) ;
codegen_red_method ('times',  op, 'uint64_t'  , '1'              , '0', 16) ;
codegen_red_method ('times',  op, 'float'     , '1'              , [ ], 64) ;
codegen_red_method ('times',  op, 'double'    , '1'              , [ ], 32) ;
op = 'zarg = GB_FC32_mul (zarg, yarg)' ;
codegen_red_method ('times',  op, 'GxB_FC32_t', 'GxB_CMPLXF(1,0)', [ ], 32) ;
op = 'zarg = GB_FC64_mul (zarg, yarg)' ;
codegen_red_method ('times',  op, 'GxB_FC64_t', 'GxB_CMPLX(1,0)' , [ ], 16) ;

% 4 boolean monoids
fprintf ('\nlor    ') ;
codegen_red_method ('lor' , 'zarg = (zarg || yarg)', 'bool','false', 'true' ,8);
fprintf ('\nland   ') ;
codegen_red_method ('land', 'zarg = (zarg && yarg)', 'bool','true' , 'false',8);
fprintf ('\nlxor   ') ;
codegen_red_method ('lxor', 'zarg = (zarg != yarg)', 'bool','false', [ ]    ,8);
fprintf ('\neq     ') ;
codegen_red_method ('eq'  , 'zarg = (zarg == yarg)', 'bool','true' , [ ]    ,8);
fprintf ('\nany    ') ;
codegen_red_method ('any' , 'zarg = (yarg)'        , 'bool','false') ;

%-------------------------------------------------------------------------------
% FIRST and SECOND (not monoids; used for GB_red_build__first,second_type)
%-------------------------------------------------------------------------------

% FIRST: 13 ops:    name      op           type        identity terminal panel
fprintf ('\nfirst  ') ;
codegen_red_method ('first',  ';'          , 'bool'      , [ ]  , [ ],   1  ) ;
codegen_red_method ('first',  ';'          , 'int8_t'    , [ ]  , [ ],   1  ) ;
codegen_red_method ('first',  ';'          , 'int16_t'   , [ ]  , [ ],   1  ) ;
codegen_red_method ('first',  ';'          , 'int32_t'   , [ ]  , [ ],   1  ) ;
codegen_red_method ('first',  ';'          , 'int64_t'   , [ ]  , [ ],   1  ) ;
codegen_red_method ('first',  ';'          , 'uint8_t'   , [ ]  , [ ],   1  ) ;
codegen_red_method ('first',  ';'          , 'uint16_t'  , [ ]  , [ ],   1  ) ;
codegen_red_method ('first',  ';'          , 'uint32_t'  , [ ]  , [ ],   1  ) ;
codegen_red_method ('first',  ';'          , 'uint64_t'  , [ ]  , [ ],   1  ) ;
codegen_red_method ('first',  ';'          , 'float'     , [ ]  , [ ],   1  ) ;
codegen_red_method ('first',  ';'          , 'double'    , [ ]  , [ ],   1  ) ;
codegen_red_method ('first',  ';'          , 'GxB_FC32_t', [ ]  , [ ],   1  ) ;
codegen_red_method ('first',  ';'          , 'GxB_FC64_t', [ ]  , [ ],   1  ) ;

% SECOND: 13 ops    name      op           type        identity terminal panel
fprintf ('\nsecond ') ;
codegen_red_method ('second', 'zarg = yarg', 'bool'      , [ ]  , [ ],   1  ) ;
codegen_red_method ('second', 'zarg = yarg', 'int8_t'    , [ ]  , [ ],   1  ) ;
codegen_red_method ('second', 'zarg = yarg', 'int16_t'   , [ ]  , [ ],   1  ) ;
codegen_red_method ('second', 'zarg = yarg', 'int32_t'   , [ ]  , [ ],   1  ) ;
codegen_red_method ('second', 'zarg = yarg', 'int64_t'   , [ ]  , [ ],   1  ) ;
codegen_red_method ('second', 'zarg = yarg', 'uint8_t'   , [ ]  , [ ],   1  ) ;
codegen_red_method ('second', 'zarg = yarg', 'uint16_t'  , [ ]  , [ ],   1  ) ;
codegen_red_method ('second', 'zarg = yarg', 'uint32_t'  , [ ]  , [ ],   1  ) ;
codegen_red_method ('second', 'zarg = yarg', 'uint64_t'  , [ ]  , [ ],   1  ) ;
codegen_red_method ('second', 'zarg = yarg', 'float'     , [ ]  , [ ],   1  ) ;
codegen_red_method ('second', 'zarg = yarg', 'double'    , [ ]  , [ ],   1  ) ;
codegen_red_method ('second', 'zarg = yarg', 'GxB_FC32_t', [ ]  , [ ],   1  ) ;
codegen_red_method ('second', 'zarg = yarg', 'GxB_FC64_t', [ ]  , [ ],   1  ) ;

fprintf ('\n') ;