22
22
23
23
// MODULES //
24
24
25
+ var join = require ( 'path' ) . join ;
26
+ var readJSON = require ( '@stdlib/fs/read-json' ) . sync ;
25
27
var db = require ( '@stdlib/math/special/data/unary_function_database.json' ) ;
26
28
var scaffoldDatabase = require ( '@stdlib/math/special/data/unary.json' ) ;
27
29
var dtypes = require ( '@stdlib/ndarray/dtypes' ) ;
28
30
var dtypeChar = require ( '@stdlib/ndarray/base/dtype-char' ) ;
29
31
var mostlySafeCasts = require ( '@stdlib/ndarray/mostly-safe-casts' ) ;
30
32
var promotionRules = require ( '@stdlib/ndarray/promotion-rules' ) ;
31
- // Generate list of available ndarray kernels from source file names
32
- var fs = require ( 'fs' ) ;
33
- var path = require ( 'path' ) ;
34
- var NDARRAY_KERNELS = ( function ( ) {
35
- var srcDir = path . join ( __dirname , '../../../../../../../lib/node_modules/@stdlib/ndarray/base/unary/src' ) ;
36
- var files = fs . readdirSync ( srcDir ) ;
37
- var kernels = [ ] ;
38
-
39
- for ( var i = 0 ; i < files . length ; i ++ ) {
40
- var file = files [ i ] ;
41
- if ( file . endsWith ( '.c' ) && ! file . startsWith ( 'internal' ) ) {
42
- // Extract function name from file name (e.g., 'd_d.c' -> 'stdlib_ndarray_d_d')
43
- var baseName = file . replace ( '.c' , '' ) ;
44
- kernels . push ( 'stdlib_ndarray_' + baseName ) ;
45
- }
46
- }
47
- return kernels ;
48
- } ) ( ) ;
33
+
34
+
35
+ // VARIABLES //
36
+
37
+ var pkgPath = join ( __dirname , '..' , 'package.json' ) ;
38
+ var pkg = readJSON ( pkgPath ) ;
39
+ var basePkg = pkg . name . split ( '/' ) . pop ( ) ;
49
40
50
41
51
42
// FUNCTIONS //
@@ -58,20 +49,36 @@ var NDARRAY_KERNELS = (function() {
58
49
* @param {string } outputDtype - output dtype
59
50
* @param {string } inputDtype - input dtype
60
51
* @returns {string } scalar kernel name
52
+ *
53
+ * @example
54
+ * var kernels = {
55
+ * 'float64': '@stdlib /math/base/special/floor',
56
+ * 'float32': '@stdlib/math/base/special/floorf',
57
+ * 'generic': '@stdlib/math/base/special/floor'
58
+ * };
59
+ * var kernel = selectScalarKernel( kernels, 'float64', 'float32' );
60
+ * // returns '@stdlib/math/base/special/floor'
61
61
*/
62
62
function selectScalarKernel ( scalarKernels , outputDtype , inputDtype ) {
63
63
var higherPrecisionDtype ;
64
64
var scalarKernel ;
65
65
66
+ /*
67
+ * For example:
68
+ *
69
+ * inputDtype = 'complex64'
70
+ * outputDtype = 'float32'
71
+ */
72
+
66
73
if ( inputDtype === 'generic' ) {
67
74
scalarKernel = scalarKernels [ outputDtype ] || scalarKernels . generic ;
68
75
} else if ( outputDtype === 'generic' ) {
69
76
// Using the function appropriate for the input dtype, in case of generic output:
70
77
scalarKernel = scalarKernels [ inputDtype ] || scalarKernels . generic ;
71
78
} else {
72
79
// Determine which dtype has higher priority using promotion rules:
73
- higherPrecisionDtype = promotionRules ( inputDtype , outputDtype ) ;
74
- scalarKernel = scalarKernels [ higherPrecisionDtype ] ;
80
+ higherPrecisionDtype = promotionRules ( inputDtype , outputDtype ) ; // promotionRules( 'complex64', 'float32' ) => 'complex64'
81
+ scalarKernel = scalarKernels [ higherPrecisionDtype ] ; // scalarKernels[ 'complex64' ] => '@stdlib/math/base/special/cfloorf'
75
82
if ( ! scalarKernel ) {
76
83
scalarKernel = scalarKernels . generic ;
77
84
}
@@ -87,36 +94,38 @@ function selectScalarKernel( scalarKernels, outputDtype, inputDtype ) {
87
94
* @param {string } inputDtype - input dtype
88
95
* @param {string } outputDtype - output dtype
89
96
* @param {string } scalarKernel - scalar kernel name
90
- * @param {Array } kernelList - list of available kernels
91
97
* @returns {string } kernel name
98
+ *
99
+ * @example
100
+ * var kernel = selectKernelName( 'float32', 'float64', '@stdlib/math/base/special/abs' );
101
+ * // returns 'stdlib_ndarray_f_d_as_d_d'
102
+ *
103
+ * @example
104
+ * var kernel = selectKernelName( 'float64', 'float32', '@stdlib/math/base/special/absf' );
105
+ * // returns 'stdlib_ndarray_d_f_as_f_f'
92
106
*/
93
- function selectKernelName ( inputDtype , outputDtype , scalarKernel , kernelList ) {
107
+ function selectKernelName ( inputDtype , outputDtype , scalarKernel ) {
94
108
var scalarKernelOutputDtype ;
95
109
var scalarKernelInputDtype ;
96
110
var ndarrayKernel ;
97
- var scaffoldEntry ;
98
-
99
- // Check if the scalar kernel exists in the scaffold database
100
- scaffoldEntry = scaffoldDatabase [ scalarKernel ] ;
101
- if ( ! scaffoldEntry || ! scaffoldEntry . parameters || scaffoldEntry . parameters . length === 0 ) {
102
- // Fallback: use input and output dtypes directly
103
- scalarKernelInputDtype = inputDtype ;
104
- scalarKernelOutputDtype = outputDtype ;
105
- } else {
106
- scalarKernelInputDtype = scaffoldEntry . parameters [ 0 ] . type . dtype ;
107
- scalarKernelOutputDtype = scaffoldEntry . returns . type . dtype ;
108
- }
111
+
112
+ /*
113
+ * For example:
114
+ *
115
+ * inputDtype = 'complex64'
116
+ * outputDtype = 'float32'
117
+ * scalarKernel = '@stdlib/math/base/special/cfloorf'
118
+ */
119
+
120
+ scalarKernelInputDtype = scaffoldDatabase [ scalarKernel ] . parameters [ 0 ] . type . dtype ; // scaffoldDatabase[ '@stdlib/math/base/special/cfloorf' ].parameters[ 0 ].type.dtype => 'complex64'
121
+ scalarKernelOutputDtype = scaffoldDatabase [ scalarKernel ] . returns . type . dtype ; // scaffoldDatabase[ '@stdlib/math/base/special/cfloorf' ].returns.type.dtype => 'complex64'
109
122
110
123
// Exact match:
111
124
if ( inputDtype === scalarKernelInputDtype && outputDtype === scalarKernelOutputDtype ) {
112
125
ndarrayKernel = 'stdlib_ndarray_' + dtypeChar ( inputDtype ) + '_' + dtypeChar ( outputDtype ) ;
113
126
} else {
114
127
// Not an exact match:
115
- ndarrayKernel = 'stdlib_ndarray_' + dtypeChar ( inputDtype ) + '_' + dtypeChar ( outputDtype ) + '_as_' + dtypeChar ( scalarKernelInputDtype ) + '_' + dtypeChar ( scalarKernelOutputDtype ) ;
116
- }
117
-
118
- if ( kernelList . indexOf ( ndarrayKernel ) === - 1 ) {
119
- return ;
128
+ ndarrayKernel = 'stdlib_ndarray_' + dtypeChar ( inputDtype ) + '_' + dtypeChar ( outputDtype ) + '_as_' + dtypeChar ( scalarKernelInputDtype ) + '_' + dtypeChar ( scalarKernelOutputDtype ) ; // => 'stdlib_ndarray_c_f_as_c_c'
120
129
}
121
130
122
131
return ndarrayKernel ;
@@ -129,10 +138,9 @@ function selectKernelName( inputDtype, outputDtype, scalarKernel, kernelList ) {
129
138
* Main function to generate dtype mappings.
130
139
*
131
140
* @private
132
- * @param {string } funcAlias - function alias
133
141
* @returns {Array } array of mappings
134
142
*/
135
- function main ( funcAlias ) {
143
+ function main ( ) {
136
144
var needsPromotion ;
137
145
var cFunctionName ;
138
146
var allowedCasts ;
@@ -152,17 +160,55 @@ function main( funcAlias ) {
152
160
mappings = [ ] ;
153
161
154
162
// Get scalar kernels and configuration for this function:
155
- obj = db [ funcAlias ] ;
156
- if ( ! obj ) {
157
- throw new Error ( 'Function alias not found in database: ' + funcAlias ) ;
158
- }
163
+ obj = db [ basePkg ] ;
164
+
165
+ /*
166
+ * obj = {
167
+ * "input_dtypes": "numeric_and_generic",
168
+ * "output_dtypes": "numeric_and_generic",
169
+ * "output_policy": "same",
170
+ * "excluded_dtypes": [ "float16", "uint8c", "complex32" ],
171
+ * "scalar_kernels": {
172
+ * "int8": "@stdlib /number/int8/base/identity",
173
+ * "int16": "@stdlib/number/int16/base/identity",
174
+ * "int32": "@stdlib/number/int32/base/identity",
175
+ * "uint8": "@stdlib/number/uint8/base/identity",
176
+ * "uint16": "@stdlib/number/uint16/base/identity",
177
+ * "uint32": "@stdlib/number/uint32/base/identity",
178
+ * "float32": "@stdlib/math/base/special/floorf",
179
+ * "float64": "@stdlib/math/base/special/floor",
180
+ * "complex64": "@stdlib/math/base/special/cfloorf",
181
+ * "complex128": "@stdlib/math/base/special/cfloor",
182
+ * "generic": "@stdlib/math/base/special/floor"
183
+ * }
184
+ * }
185
+ */
159
186
160
187
// Get input dtypes:
161
188
idt = dtypes ( obj . input_dtypes ) ;
162
189
163
190
// Get output dtypes:
164
191
odt = dtypes ( obj . output_dtypes ) ;
165
192
193
+ /*
194
+ * idt = [
195
+ * 'complex32',
196
+ * 'complex64',
197
+ * 'complex128',
198
+ * 'float16',
199
+ * 'float32',
200
+ * 'float64',
201
+ * 'int16',
202
+ * 'int32',
203
+ * 'int8',
204
+ * 'uint16',
205
+ * 'uint32',
206
+ * 'uint8',
207
+ * 'uint8c',
208
+ * 'generic'
209
+ * ]
210
+ */
211
+
166
212
// Filter out excluded dtypes:
167
213
filtered = [ ] ;
168
214
for ( i = 0 ; i < idt . length ; i ++ ) {
@@ -172,15 +218,48 @@ function main( funcAlias ) {
172
218
}
173
219
idt = filtered ;
174
220
221
+ /*
222
+ * idt = [
223
+ * 'complex64',
224
+ * 'complex128',
225
+ * 'float32',
226
+ * 'float64',
227
+ * 'int16',
228
+ * 'int32',
229
+ * 'int8',
230
+ * 'uint16',
231
+ * 'uint32',
232
+ * 'uint8',
233
+ * 'generic'
234
+ * ]
235
+ */
236
+
175
237
// Generate all mostly-safe cast combinations:
176
238
for ( i = 0 ; i < idt . length ; i ++ ) {
177
239
inputDtype = idt [ i ] ;
178
240
241
+ /*
242
+ * For the first iteration:
243
+ *
244
+ * inputDtype = 'complex64'
245
+ */
246
+
179
247
if ( inputDtype === 'generic' ) {
180
248
allowedCasts = [ 'generic' ] ;
181
249
} else {
182
250
// Get all dtypes this input can be mostly-safely cast to:
183
251
allowedCasts = mostlySafeCasts ( inputDtype ) ;
252
+
253
+ /*
254
+ * For the first iteration:
255
+ *
256
+ * allowedCasts = [
257
+ * 'complex64',
258
+ * 'complex128',
259
+ * 'float32',
260
+ * 'float64'
261
+ * ]
262
+ */
184
263
}
185
264
186
265
// Remove the dtypes which are not allowed for output, according to the output policy:
@@ -192,23 +271,26 @@ function main( funcAlias ) {
192
271
}
193
272
allowedCasts = filtered ;
194
273
274
+ // console.log( 'allowedCasts for input dtype %s: %s', inputDtype, allowedCasts );
275
+
195
276
for ( j = 0 ; j < allowedCasts . length ; j ++ ) {
196
277
outputDtype = allowedCasts [ j ] ;
197
278
198
279
if ( obj . excluded_dtypes . indexOf ( outputDtype ) !== - 1 ) {
199
280
continue ;
200
281
}
201
282
283
+ /*
284
+ * For example:
285
+ *
286
+ * outputDtype = 'float32'
287
+ */
288
+
202
289
// Get scalar kernel for this dtype combination:
203
- scalarKernel = selectScalarKernel ( obj . scalar_kernels , outputDtype , inputDtype ) ;
290
+ scalarKernel = selectScalarKernel ( obj . scalar_kernels , outputDtype , inputDtype ) ; // selectScalarKernel( kernels, 'float32', 'complex64' ) => '@stdlib/math/base/special/cfloorf'
204
291
205
292
// Generate ndarray kernel name:
206
- kernelName = selectKernelName ( inputDtype , outputDtype , scalarKernel , NDARRAY_KERNELS ) ;
207
-
208
- // Skip if no kernel available:
209
- if ( ! kernelName ) {
210
- continue ;
211
- }
293
+ kernelName = selectKernelName ( inputDtype , outputDtype , scalarKernel ) ; // selectKernelName( 'complex64', 'float32', '@stdlib/math/base/special/cfloorf' ) => 'stdlib_ndarray_c_f_as_c_c'
212
294
213
295
// Generate mapping:
214
296
needsPromotion = inputDtype !== outputDtype ;
0 commit comments