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