README.md (11386B)
1 <!-- 2 3 @license Apache-2.0 4 5 Copyright (c) 2020 The Stdlib Authors. 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 19 --> 20 21 # Function Object 22 23 > C APIs for creating and managing strided array function objects. 24 25 <!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. --> 26 27 <section class="intro"> 28 29 </section> 30 31 <!-- /.intro --> 32 33 <!-- Package usage documentation. --> 34 35 <section class="usage"> 36 37 ## Usage 38 39 ```javascript 40 var headerDir = require( '@stdlib/strided/base/function-object' ); 41 ``` 42 43 #### headerDir 44 45 Absolute file path for the directory containing header files for C APIs. 46 47 ```javascript 48 var dir = headerDir; 49 // returns <string> 50 ``` 51 52 </section> 53 54 <!-- /.usage --> 55 56 <!-- Package usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. --> 57 58 <section class="notes"> 59 60 </section> 61 62 <!-- /.notes --> 63 64 <!-- Package usage examples. --> 65 66 <section class="examples"> 67 68 ## Examples 69 70 ```javascript 71 var headerDir = require( '@stdlib/strided/base/function-object' ); 72 73 console.log( headerDir ); 74 ``` 75 76 </section> 77 78 <!-- /.examples --> 79 80 <!-- C interface documentation. --> 81 82 * * * 83 84 <section class="c"> 85 86 ## C APIs 87 88 <!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. --> 89 90 <section class="intro"> 91 92 </section> 93 94 <!-- /.intro --> 95 96 <!-- C usage documentation. --> 97 98 <section class="usage"> 99 100 ### Usage 101 102 ```c 103 #include "stdlib/strided/base/function_object.h" 104 ``` 105 106 #### StridedFunctionObject 107 108 Structure for grouping strided array function information. 109 110 ```c 111 struct StridedFunctionObject { 112 // Strided array function name: 113 const char *name; 114 115 // Number of input strided arrays: 116 int32_t nin; 117 118 // Number of output strided arrays: 119 int32_t nout; 120 121 // Total number of strided array arguments (nin + nout): 122 int32_t narrays; 123 124 // Array containing strided array functions: 125 StridedArrayFcn *functions; 126 127 // Number of strided array functions: 128 int32_t nfunctions; 129 130 // Array of type "numbers" (as enumerated elsewhere), where the total number of types equals `narrays * nfunctions` and where each set of `narrays` consecutive types (non-overlapping) corresponds to the set of strided array argument types for a corresponding strided array function: 131 int32_t *types; 132 133 // Array of void pointers corresponding to the "data" (e.g., callbacks) which should be passed to a respective strided array function (note: the number of pointers should match the number of strided array functions): 134 void **data; 135 }; 136 ``` 137 138 #### StridedArrayFcn 139 140 Function pointer type for a strided array function. 141 142 ```c 143 typedef void (*StridedArrayFcn)( uint8_t *arrays[], int64_t *shape, int64_t *strides, void *data ); 144 ``` 145 146 A `StridedArrayFcn` function should accept the following arguments: 147 148 - **arrays**: `[in] uint8_t**` array containing pointers to both input and output strided arrays. 149 - **shape**: `[in] int64_t*` array whose only element is the number of elements over which to iterate. 150 - **strided**: `[in] int64_t*` array containing strides (in bytes) for each strided array. 151 - **data**: `[in] void*` function data (e.g., a callback). 152 153 <!-- lint disable maximum-heading-length --> 154 155 #### stdlib_strided_function_allocate( *name, nin, nout, *functions, nfunctions, *types, *data[] ) 156 157 Returns a pointer to a dynamically allocated strided array function object. 158 159 ```c 160 #include "stdlib/strided/base/unary.h" 161 #include "stdlib/strided/dtypes.h" 162 #include <stdlib.h> 163 #include <stdio.h> 164 165 // Define the function(s) we want to apply to strided arrays: 166 double scale( const double x ) { 167 return x * 10.0; 168 } 169 170 // Define a function name: 171 const char name[] = "unary_strided_array_function"; 172 173 // Define a list of strided array functions (in this case, as the function to be applied accepts doubles, we only use strided array functions which handle doubles as function arguments and, for the purposes of this example, we assume that the output strided array is always a double-precision floating-point number array): 174 StridedArrayFcn functions[] = { 175 stdlib_strided_d_d, 176 stdlib_strided_f_f_as_d_d, 177 stdlib_strided_u_d_as_d_d, 178 stdlib_strided_i_d_as_d_d, 179 stdlib_strided_t_d_as_d_d, 180 stdlib_strided_k_d_as_d_d, 181 stdlib_strided_b_d_as_d_d, 182 stdlib_strided_s_d_as_d_d 183 }; 184 185 // Define the **strided array** argument types for each strided array function: 186 int32_t types[] = { 187 STDLIB_STRIDED_FLOAT64, STDLIB_STRIDED_FLOAT64, 188 STDLIB_STRIDED_FLOAT32, STDLIB_STRIDED_FLOAT64, 189 STDLIB_STRIDED_UINT32, STDLIB_STRIDED_FLOAT64, 190 STDLIB_STRIDED_INT32, STDLIB_STRIDED_FLOAT64, 191 STDLIB_STRIDED_UINT16, STDLIB_STRIDED_FLOAT64, 192 STDLIB_STRIDED_INT16, STDLIB_STRIDED_FLOAT64, 193 STDLIB_STRIDED_UINT8, STDLIB_STRIDED_FLOAT64, 194 STDLIB_STRIDED_INT8, STDLIB_STRIDED_FLOAT64 195 }; 196 197 // Define a list of strided array function "data" (in this case, callbacks): 198 void *data[] = { 199 (void *)scale, 200 (void *)scale, 201 (void *)scale, 202 (void *)scale, 203 (void *)scale, 204 (void *)scale, 205 (void *)scale, 206 (void *)scale 207 }; 208 209 // Create a new strided function object: 210 struct StridedFunctionObject *obj = stdlib_strided_function_allocate( name, 1, 1, functions, 8, types, data ); 211 if ( obj == NULL ) { 212 fprintf( stderr, "Error allocating memory.\n" ); 213 exit( 1 ); 214 } 215 216 // Free allocated memory: 217 stdlib_strided_function_free( obj ); 218 ``` 219 220 The function accepts the following arguments: 221 222 - **name**: `[in] char*` strided array function name. 223 - **nin**: `[in] int32_t` number of input strided arrays. 224 - **nout**: `[in] int32_t` number of output strided arrays. 225 - **functions**: `[in] StridedArrayFcn*` array containing strided array functions. 226 - **nfunctions**: `[in] int32_t` number of strided array functions. 227 - **types**: `[in] int32_t*` array of type "numbers", where the total number of types equals `(nin+nout)*nfunctions` and where each set of `nin+nout` consecutive types (non-overlapping) corresponds to the set of strided array argument types for a corresponding strided array function. 228 - **data**: `[in] void*` array of void pointers corresponding to the "data" (e.g., callbacks) which should be passed to a respective strided array function. 229 230 ```c 231 struct StridedFunctionObject * stdlib_strided_function_allocate( const char *name, int32_t nin, int32_t nout, StridedArrayFcn *functions, int32_t nfunctions, int32_t *types, void *data[] ) 232 ``` 233 234 The function returns a pointer to a dynamically allocated strided array function or, if unable to allocate memory, a null pointer. The **user** is responsible for freeing the allocated memory. 235 236 #### stdlib_strided_function_free( *obj ) 237 238 Frees a strided array function object's allocated memory. 239 240 ```c 241 #include "stdlib/strided/base/unary.h" 242 #include "stdlib/strided/dtypes.h" 243 #include <stdlib.h> 244 #include <stdio.h> 245 246 // Define the function(s) we want to apply to strided arrays: 247 double scale( const double x ) { 248 return x * 10.0; 249 } 250 251 // Define a function name: 252 const char name[] = "unary_strided_array_function"; 253 254 // Define a list of strided array functions: 255 StridedArrayFcn functions[] = { 256 stdlib_strided_d_d 257 }; 258 259 // Define the **strided array** argument types for each strided array function: 260 int32_t types[] = { 261 STDLIB_STRIDED_FLOAT64, STDLIB_STRIDED_FLOAT64 262 }; 263 264 // Define a list of strided array function "data" (in this case, callbacks): 265 void *data[] = { 266 (void *)scale 267 }; 268 269 // Create a new strided function object: 270 struct StridedFunctionObject *obj = stdlib_strided_function_allocate( name, 1, 1, functions, 1, types, data ); 271 if ( obj == NULL ) { 272 fprintf( stderr, "Error allocating memory.\n" ); 273 exit( 1 ); 274 } 275 276 // ... 277 278 // Free allocated memory: 279 stdlib_strided_function_free( obj ); 280 ``` 281 282 The function accepts the following arguments: 283 284 - **obj**: `[in] StridedFunctionObject*` strided array function object. 285 286 ```c 287 void stdlib_strided_function_free( struct StridedFunctionObject *obj ) 288 ``` 289 290 #### stdlib_strided_function_dispatch_index_of( *obj, *types ) 291 292 Returns the first index of a function whose signature satisfies a provided list of array types. 293 294 ```c 295 #include "stdlib/strided/base/unary.h" 296 #include "stdlib/strided/dtypes.h" 297 #include <stdlib.h> 298 #include <stdio.h> 299 300 // Define the function(s) we want to apply to strided arrays: 301 double scale( const double x ) { 302 return x * 10.0; 303 } 304 305 // ... 306 307 // Define a function name: 308 const char name[] = "unary_strided_array_function"; 309 310 // Define a list of strided array functions: 311 StridedArrayFcn functions[] = { 312 stdlib_strided_d_d, 313 stdlib_strided_f_f_as_d_d 314 }; 315 316 // Define the **strided array** argument types for each strided array function: 317 int32_t types[] = { 318 STDLIB_STRIDED_FLOAT64, STDLIB_STRIDED_FLOAT64, 319 STDLIB_STRIDED_FLOAT32, STDLIB_STRIDED_FLOAT64 320 }; 321 322 // Define a list of strided array function "data" (in this case, callbacks): 323 void *data[] = { 324 (void *)scale, 325 (void *)scale 326 }; 327 328 // Create a new strided function object: 329 struct StridedFunctionObject *obj = stdlib_strided_function_allocate( name, 1, 1, functions, 2, types, data ); 330 if ( obj == NULL ) { 331 fprintf( stderr, "Error allocating memory.\n" ); 332 exit( 1 ); 333 } 334 335 // ... 336 337 // Define a list of types on which to dispatch: 338 int32_t itypes[] = { 339 STDLIB_STRIDED_FLOAT32, STDLIB_STRIDED_FLOAT64 340 }; 341 342 // Find a function satisfying the list of types: 343 int64_t idx = stdlib_strided_function_dispatch_index_of( obj, itypes ); 344 if ( idx < 0 ) { 345 fprintf( stderr, "Unable to find function.\n" ); 346 exit( 1 ); 347 } 348 349 // ... 350 351 // Free allocated memory: 352 stdlib_strided_function_free( obj ); 353 ``` 354 355 The function accepts the following arguments: 356 357 - **obj**: `[in] StridedFunctionObject*` strided array function object. 358 - **types**: `[in] int32_t*` list of array types on which to dispatch. 359 360 ```c 361 int64_t stdlib_strided_function_dispatch_index_of( const struct StridedFunctionObject *obj, const int32_t *types ) 362 ``` 363 364 If a function is found, the function returns the index of the function, and the function returns `-1` if unable to find a function. 365 366 </section> 367 368 <!-- /.usage --> 369 370 <!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. --> 371 372 <section class="notes"> 373 374 </section> 375 376 <!-- /.notes --> 377 378 <!-- C API usage examples. --> 379 380 <section class="examples"> 381 382 </section> 383 384 <!-- /.examples --> 385 386 </section> 387 388 <!-- /.c --> 389 390 <!-- Section to include cited references. If references are included, add a horizontal rule *before* the section. Make sure to keep an empty line after the `section` element and another before the `/section` close. --> 391 392 <section class="references"> 393 394 </section> 395 396 <!-- /.references --> 397 398 <!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. --> 399 400 <section class="links"> 401 402 </section> 403 404 <!-- /.links -->