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