1function codegen_sel_method (opname, func, atype, kind) 2%CODEGEN_SEL_METHOD create a selection function, C = select (A,thunk) 3% 4% codegen_sel_method (opname, func, atype, kind) 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, ~] = codegen_type (atype) ; 12 13if (nargin < 4) 14 kind = 'GB_ENTRY_SELECTOR'; 15end 16name = sprintf ('%s_%s', opname, aname) ; 17 18is_nonzombie = (isequal (opname, 'nonzombie') && ~isequal (atype, 'GB_void')) ; 19 20% function names 21if (is_nonzombie) 22 fprintf (f, 'define(`_sel_phase1'', `_sel_phase1__(none)'')\n') ; 23else 24 fprintf (f, 'define(`_sel_phase1'', `_sel_phase1__%s'')\n', name) ; 25end 26fprintf (f, 'define(`_sel_phase2'', `_sel_phase2__%s'')\n', name) ; 27 28if isequal (opname, 'nonzombie') || isequal (opname, 'resize') 29 fprintf (f, 'define(`_sel_bitmap'', `_sel_bitmap__(none)'')\n') ; 30 fprintf (f, 'define(`if_bitmap'', `#if 0'')\n') ; 31 fprintf (f, 'define(`endif_bitmap'', `#endif'')\n') ; 32else 33 fprintf (f, 'define(`_sel_bitmap'', `_sel_bitmap__%s'')\n', name) ; 34 fprintf (f, 'define(`if_bitmap'', `'')\n') ; 35 fprintf (f, 'define(`endif_bitmap'', `'')\n') ; 36end 37 38% the type of A (no typecasting) 39fprintf (f, 'define(`GB_atype'', `%s'')\n', atype) ; 40 41% create the operator to test the numerical values of the entries 42if (isempty (func)) 43 fprintf (f, 'define(`GB_test_value_of_entry'', `(no test; %s ignores values)'')\n', opname) ; 44else 45 fprintf (f, 'define(`GB_test_value_of_entry'', `%s'')\n', func) ; 46end 47 48fprintf (f, 'define(`GB_kind'', `#define %s'')\n', kind) ; 49 50% get vector index for user-defined select operator 51if (isequal (opname, 'user')) 52 fprintf (f, 'define(`GB_get_j'', `int64_t j = GBH (Ah, k)'')\n') ; 53else 54 fprintf (f, 'define(`GB_get_j'', `;'')\n') ; 55end 56 57% get scalar thunk 58if (~isequal (atype, 'GB_void') && ~isempty (strfind (opname, 'thunk'))) 59 fprintf (f, 'define(`GB_get_thunk'', `%s thunk = (*xthunk) ;'')\n', atype) ; 60else 61 fprintf (f, 'define(`GB_get_thunk'', `;'')\n') ; 62end 63 64% enable phase1 65if (is_nonzombie) 66 % nonzombie: phase1 uses a single worker: GB_sel_phase1__nonzombie_any 67 fprintf (f, 'define(`if_phase1'', `#if 0'')\n') ; 68 fprintf (f, 'define(`endif_phase1'', `#endif'')\n') ; 69else 70 fprintf (f, 'define(`if_phase1'', `'')\n') ; 71 fprintf (f, 'define(`endif_phase1'', `'')\n') ; 72end 73 74% for phase2: copy the numerical value of the entry 75if (isequal (opname, 'eq_zero')) 76 fprintf (f, 'define(`GB_select_entry'', `/* assignment skipped, Cx already all zero */'')\n') ; 77elseif (isequal (opname, 'eq_thunk')) 78 if (isequal (atype, 'GB_void')) 79 fprintf (f, 'define(`GB_select_entry'', `memcpy (Cx +((pC)*asize), xthunk, asize)'')\n') ; 80 else 81 fprintf (f, 'define(`GB_select_entry'', `Cx [pC] = thunk'')\n') ; 82 end 83else 84 if (isequal (opname, 'nonzero') && isequal (atype, 'bool')) 85 fprintf (f, 'define(`GB_select_entry'', `Cx [pC] = true'')\n') ; 86 elseif (isequal (atype, 'GB_void')) 87 fprintf (f, 'define(`GB_select_entry'', `memcpy (Cx +((pC)*asize), Ax +((pA)*asize), asize)'')\n') ; 88 else 89 fprintf (f, 'define(`GB_select_entry'', `Cx [pC] = Ax [pA]'')\n') ; 90 end 91end 92 93fclose (f) ; 94 95% construct the *.c file 96cmd = sprintf (... 97'cat control.m4 Generator/GB_sel.c | m4 | tail -n +14 > Generated/GB_sel__%s.c', ... 98name) ; 99fprintf ('.') ; 100system (cmd) ; 101 102% append to the *.h file 103cmd = sprintf (... 104'cat control.m4 Generator/GB_sel.h | m4 | tail -n +14 >> Generated/GB_sel__include.h') ; 105system (cmd) ; 106 107delete ('control.m4') ; 108 109 110