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
|
function codegen_sel_method (opname, func, atype, kind, iso)
%CODEGEN_SEL_METHOD create a selection function, C = select (A,thunk)
%
% codegen_sel_method (opname, func, atype, kind)
% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2022, All Rights Reserved.
% SPDX-License-Identifier: Apache-2.0
if (nargin < 4)
kind = [ ] ;
end
if (nargin < 5)
iso = 0 ;
end
is_entry_selector = isempty (kind) ;
is_nonzombie_selector = isequal (opname, 'nonzombie') ;
is_idxunop_selector = codegen_contains (opname, 'idxunop') ;
f = fopen ('control.m4', 'w') ;
[aname, ~, ~] = codegen_type (atype) ;
if (iso)
aname = 'iso' ;
end
name = sprintf ('%s_%s', opname, aname) ;
if (test_contains (opname, 'col'))
% only bitmap selector is used
enable_phase1 = false ;
enable_phase2 = false ;
else
enable_phase1 = iso || (is_entry_selector && ~is_nonzombie_selector) ;
enable_phase2 = true ;
end
fprintf (f, 'define(`GB_iso_select'', `%d'')\n', iso) ;
% function names
if (enable_phase1)
fprintf (f, 'define(`_sel_phase1'', `_sel_phase1__%s'')\n', name) ;
else
fprintf (f, 'define(`_sel_phase1'', `_sel_phase1__(none)'')\n') ;
end
if (enable_phase2)
fprintf (f, 'define(`_sel_phase2'', `_sel_phase2__%s'')\n', name) ;
else
fprintf (f, 'define(`_sel_phase2'', `_sel_phase2__(none)'')\n', name) ;
end
% zcode, zsize, xcode, xsize
zxtype = '' ;
if (is_idxunop_selector)
zcode = 'GB_Type_code zcode = op->ztype->code, ' ;
xcode = 'xcode = op->xtype->code, ' ;
acode = 'acode = A->type->code ; ' ;
sizes = 'size_t zsize = op->ztype->size, xsize = op->xtype->size ;' ;
zxtype = [zcode xcode acode sizes] ;
end
fprintf (f, 'define(`GB_get_zxtypes'', `%s'')\n', zxtype) ;
if isequal (opname, 'nonzombie')
% no bitmap selectors for nonzombie selectors
fprintf (f, 'define(`_sel_bitmap'', `_sel_bitmap__(none)'')\n') ;
fprintf (f, 'define(`if_bitmap'', `#if 0'')\n') ;
fprintf (f, 'define(`endif_bitmap'', `#endif'')\n') ;
else
fprintf (f, 'define(`_sel_bitmap'', `_sel_bitmap__%s'')\n', name) ;
fprintf (f, 'define(`if_bitmap'', `'')\n') ;
fprintf (f, 'define(`endif_bitmap'', `'')\n') ;
end
% the type of A (no typecasting)
fprintf (f, 'define(`GB_atype'', `%s'')\n', atype) ;
% create the operator to test the numerical values of the entries
if (isempty (func))
fprintf (f, 'define(`GB_setup'', `'')\n') ;
fprintf (f, 'define(`GB_test_value_of_entry'', `(no test; %s ignores values)'')\n', opname) ;
elseif (iscell (func))
fprintf (f, 'define(`GB_setup'', `%s'')\n', func {1}) ;
fprintf (f, 'define(`GB_test_value_of_entry'', `%s'')\n', func {2}) ;
else
fprintf (f, 'define(`GB_setup'', `'')\n') ;
fprintf (f, 'define(`GB_test_value_of_entry'', `%s'')\n', func) ;
end
if (is_entry_selector || is_nonzombie_selector)
fprintf (f, 'define(`GB_kind'', `#define GB_ENTRY_SELECTOR'')\n') ;
else
fprintf (f, 'define(`GB_kind'', `#define %s'')\n', kind) ;
end
% get scalar thunk
if (~isequal (atype, 'GB_void') && ~isempty (strfind (opname, 'thunk')))
fprintf (f, 'define(`GB_get_thunk'', `%s thunk = (*athunk) ;'')\n', atype) ;
else
fprintf (f, 'define(`GB_get_thunk'', `'')\n') ;
end
% enable phase1
if (enable_phase1)
% nonzombie: phase1 uses a single worker: GB_sel_phase1__nonzombie_iso
fprintf (f, 'define(`if_phase1'', `'')\n') ;
fprintf (f, 'define(`endif_phase1'', `'')\n') ;
else
fprintf (f, 'define(`if_phase1'', `#if 0'')\n') ;
fprintf (f, 'define(`endif_phase1'', `#endif'')\n') ;
end
% enable phase2
if (enable_phase2)
fprintf (f, 'define(`if_phase2'', `'')\n') ;
fprintf (f, 'define(`endif_phase2'', `'')\n') ;
else
fprintf (f, 'define(`if_phase2'', `#if 0'')\n') ;
fprintf (f, 'define(`endif_phase2'', `#endif'')\n') ;
end
% for phase2: copy the numerical value of the entry
if (iso)
% A is iso
fprintf (f, 'define(`GB_select_entry'', `/* assignment skipped, C and A are iso */'')\n') ;
elseif (isequal (opname, 'eq_zero'))
% create C as iso for all EQ_ZERO ops even when A is not iso, with iso value zero
fprintf (f, 'define(`GB_select_entry'', `/* assignment skipped, C is iso with all entries zero */'')\n') ;
elseif (isequal (opname, 'eq_thunk'))
% create C as iso for all EQ_THUNK ops even when A is not iso, with iso value athunk
fprintf (f, 'define(`GB_select_entry'', `/* assignment skipped, C is iso with all entries equal to thunk */'')\n') ;
elseif (isequal (opname, 'nonzero') && isequal (atype, 'bool'))
% create C as iso for NONZERO_BOOL even when A is not iso, with iso value true
fprintf (f, 'define(`GB_select_entry'', `/* assignment skipped, C is iso with all entries true */'')\n') ;
elseif (isequal (atype, 'GB_void'))
fprintf (f, 'define(`GB_select_entry'', `memcpy (Cx +((pC)*asize), Ax +((pA)*asize), asize)'')\n') ;
else
fprintf (f, 'define(`GB_select_entry'', `Cx [pC] = Ax [pA]'')\n') ;
end
fclose (f) ;
% construct the *.c file
cmd = sprintf (...
'cat control.m4 Generator/GB_sel.c | m4 | tail -n +18 > Generated1/GB_sel__%s.c', ...
name) ;
fprintf ('.') ;
system (cmd) ;
% append to the *.h file
cmd = sprintf (...
'cat control.m4 Generator/GB_sel.h | m4 | tail -n +18 >> Generated1/GB_sel__include.h') ;
system (cmd) ;
delete ('control.m4') ;
|