nullary.c (13388B)
1 /** 2 * @license Apache-2.0 3 * 4 * Copyright (c) 2018 The Stdlib Authors. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 /** 20 * Strided array functions for nullary callbacks. 21 * 22 * ## Notes 23 * 24 * - Character codes for data types: 25 * 26 * - d: float64 (double) 27 * - f: float32 (float) 28 * - b: int8 (signed char) 29 * - B: uint8 (unsigned char) 30 * - h: int16 (signed short) 31 * - H: uint16 (unsigned short) 32 * - i: int32 (signed int) 33 * - I: uint32 (unsigned int) 34 * 35 * - Function name suffix naming convention: 36 * 37 * ```text 38 * <base_function_name>[_<input_data_types>]_<output_data_type>[_as_<callback_arg_data_types>_<callback_return_data_type>] 39 * ``` 40 * 41 * For example, 42 * 43 * ```c 44 * void stdlib_strided_dd_d(...) {...} 45 * ``` 46 * 47 * is a function which accepts two strided input arrays containing double-precision floating-point numbers and whose results are cast as double-precision floating-point numbers. In other words, the suffix encodes the function type signature. 48 * 49 * - To support callbacks whose input arguments and/or return values are of a different data type than the input and/or output strided array data types, the naming convention supports appending an `as` suffix. For example, 50 * 51 * ```c 52 * void stdlib_strided_ff_f_as_dd_d(...) {...} 53 * ``` 54 * 55 * is a function which accepts two strided input arrays containing single-precision floating-point numbers and whose results are cast as single-precision floating-point numbers. However, the callback requires each pair of single-precision floating-point numbers be cast to double-precision floating-point numbers when provided as arguments, and the callback return value is a double-precision floating-point number. Accordingly, the conversion process would be 56 * 57 * ```text 58 * float in1 -> double in1 59 * float in2 -> double in2 60 * double out1 = f( in1, in2 ) 61 * float out1 <- double out1 62 * ``` 63 * 64 * - The functions included in this file are **not** exhaustive and that is intentional. Namely, with few exceptions, functions which convert nullary callback return values to a different type are not included (e.g., widening an `int16` to an `int32`). Nullary functions should be simple enough that this can be handled in userland via function wrappers which return the desired types. 65 */ 66 #include "stdlib/strided/common/nullary.h" 67 #include "stdlib/strided/common/nullary_typedefs.h" 68 #include "stdlib/strided/common/nullary_macros.h" 69 #include <stdint.h> 70 71 /** 72 * Applies a nullary callback to each element in a strided output array. 73 * 74 * @param arrays array whose only element is a pointer to the output array 75 * @param shape array whose only element is the number of elements over which to iterate 76 * @param strides array containing strides (in bytes) for each strided array 77 * @param fcn callback 78 * 79 * @example 80 * #include "stdlib/strided/common/nullary.h" 81 * #include <stdint.h> 82 * 83 * // Create a zeroed underlying byte array: 84 * uint8_t out[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 85 * 86 * // Define a pointer to an array containing pointers to strided arrays: 87 * uint8_t *arrays[] = { out }; 88 * 89 * // Define the strides: 90 * int64_t strides[] = { 8 }; // 8 bytes per double 91 * 92 * // Define the number of elements over which to iterate: 93 * int64_t shape[] = { 3 }; 94 * 95 * // Define a callback: 96 * double ones() { 97 * return 1.0; 98 * } 99 * 100 * // Fill the output array with ones: 101 * stdlib_strided_d( arrays, shape, strides, (void *)ones ); 102 */ 103 void stdlib_strided_d( uint8_t *arrays[], int64_t *shape, int64_t *strides, void *fcn ) { 104 NullaryFcnFloat64 *f = (NullaryFcnFloat64 *)fcn; 105 STDLIB_NULLARY_LOOP_CLBK( double ) 106 } 107 108 /** 109 * Applies a nullary callback to each element in a strided output array. 110 * 111 * @param arrays array whose only element is a pointer to the output array 112 * @param shape array whose only element is the number of elements over which to iterate 113 * @param strides array containing strides (in bytes) for each strided array 114 * @param fcn callback 115 * 116 * @example 117 * #include "stdlib/strided/common/nullary.h" 118 * #include <stdint.h> 119 * 120 * // Create a zeroed underlying byte array: 121 * uint8_t out[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 122 * 123 * // Define a pointer to an array containing pointers to strided arrays: 124 * uint8_t *arrays[] = { out }; 125 * 126 * // Define the strides: 127 * int64_t strides[] = { 4 }; // 4 bytes per float 128 * 129 * // Define the number of elements over which to iterate: 130 * int64_t shape[] = { 3 }; 131 * 132 * // Define a callback: 133 * float ones() { 134 * return 1.0f; 135 * } 136 * 137 * // Fill the output array with ones: 138 * stdlib_strided_f( arrays, shape, strides, (void *)ones ); 139 */ 140 void stdlib_strided_f( uint8_t *arrays[], int64_t *shape, int64_t *strides, void *fcn ) { 141 NullaryFcnFloat32 *f = (NullaryFcnFloat32 *)fcn; 142 STDLIB_NULLARY_LOOP_CLBK( float ) 143 } 144 145 /** 146 * Applies a nullary callback to each element in a strided output array, casting the callback's double-precision return value to a single-precision floating-point number. 147 * 148 * @param arrays array whose only element is a pointer to the output array 149 * @param shape array whose only element is the number of elements over which to iterate 150 * @param strides array containing strides (in bytes) for each strided array 151 * @param fcn callback 152 * 153 * @example 154 * #include "stdlib/strided/common/nullary.h" 155 * #include <stdint.h> 156 * 157 * // Create a zeroed underlying byte array: 158 * uint8_t out[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 159 * 160 * // Define a pointer to an array containing pointers to strided arrays: 161 * uint8_t *arrays[] = { out }; 162 * 163 * // Define the strides: 164 * int64_t strides[] = { 4 }; // 4 bytes per float 165 * 166 * // Define the number of elements over which to iterate: 167 * int64_t shape[] = { 3 }; 168 * 169 * // Define a callback: 170 * double ones() { 171 * return 1.0; 172 * } 173 * 174 * // Fill the output array with ones: 175 * stdlib_strided_f_as_d( arrays, shape, strides, (void *)ones ); 176 */ 177 void stdlib_strided_f_as_d( uint8_t *arrays[], int64_t *shape, int64_t *strides, void *fcn ) { 178 NullaryFcnFloat64 *f = (NullaryFcnFloat64 *)fcn; 179 STDLIB_NULLARY_LOOP_CLBK( float ) 180 } 181 182 /** 183 * Applies a nullary callback to each element in a strided output array. 184 * 185 * @param arrays array whose only element is a pointer to the output array 186 * @param shape array whose only element is the number of elements over which to iterate 187 * @param strides array containing strides (in bytes) for each strided array 188 * @param fcn callback 189 * 190 * @example 191 * #include "stdlib/strided/common/nullary.h" 192 * #include <stdint.h> 193 * 194 * // Create a zeroed underlying byte array: 195 * uint8_t out[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 196 * 197 * // Define a pointer to an array containing pointers to strided arrays: 198 * uint8_t *arrays[] = { out }; 199 * 200 * // Define the strides: 201 * int64_t strides[] = { 4 }; // 4 bytes per uint32 202 * 203 * // Define the number of elements over which to iterate: 204 * int64_t shape[] = { 3 }; 205 * 206 * // Define a callback: 207 * uint32_t ones() { 208 * return 1; 209 * } 210 * 211 * // Fill the output array with ones: 212 * stdlib_strided_I( arrays, shape, strides, (void *)ones ); 213 */ 214 void stdlib_strided_I( uint8_t *arrays[], int64_t *shape, int64_t *strides, void *fcn ) { 215 NullaryFcnUint32 *f = (NullaryFcnUint32 *)fcn; 216 STDLIB_NULLARY_LOOP_CLBK( uint32_t ) 217 } 218 219 /** 220 * Applies a nullary callback to each element in a strided output array. 221 * 222 * @param arrays array whose only element is a pointer to the output array 223 * @param shape array whose only element is the number of elements over which to iterate 224 * @param strides array containing strides (in bytes) for each strided array 225 * @param fcn callback 226 * 227 * @example 228 * #include "stdlib/strided/common/nullary.h" 229 * #include <stdint.h> 230 * 231 * // Create a zeroed underlying byte array: 232 * uint8_t out[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 233 * 234 * // Define a pointer to an array containing pointers to strided arrays: 235 * uint8_t *arrays[] = { out }; 236 * 237 * // Define the strides: 238 * int64_t strides[] = { 4 }; // 4 bytes per int32 239 * 240 * // Define the number of elements over which to iterate: 241 * int64_t shape[] = { 3 }; 242 * 243 * // Define a callback: 244 * int32_t ones() { 245 * return 1; 246 * } 247 * 248 * // Fill the output array with ones: 249 * stdlib_strided_i( arrays, shape, strides, (void *)ones ); 250 */ 251 void stdlib_strided_i( uint8_t *arrays[], int64_t *shape, int64_t *strides, void *fcn ) { 252 NullaryFcnInt32 *f = (NullaryFcnInt32 *)fcn; 253 STDLIB_NULLARY_LOOP_CLBK( int32_t ) 254 } 255 256 /** 257 * Applies a nullary callback to each element in a strided output array. 258 * 259 * @param arrays array whose only element is a pointer to the output array 260 * @param shape array whose only element is the number of elements over which to iterate 261 * @param strides array containing strides (in bytes) for each strided array 262 * @param fcn callback 263 * 264 * @example 265 * #include "stdlib/strided/common/nullary.h" 266 * #include <stdint.h> 267 * 268 * // Create a zeroed underlying byte array: 269 * uint8_t out[] = { 0, 0, 0, 0, 0, 0 }; 270 * 271 * // Define a pointer to an array containing pointers to strided arrays: 272 * uint8_t *arrays[] = { out }; 273 * 274 * // Define the strides: 275 * int64_t strides[] = { 2 }; // 2 bytes per uint16 276 * 277 * // Define the number of elements over which to iterate: 278 * int64_t shape[] = { 3 }; 279 * 280 * // Define a callback: 281 * uint16_t ones() { 282 * return 1; 283 * } 284 * 285 * // Fill the output array with ones: 286 * stdlib_strided_H( arrays, shape, strides, (void *)ones ); 287 */ 288 void stdlib_strided_H( uint8_t *arrays[], int64_t *shape, int64_t *strides, void *fcn ) { 289 NullaryFcnUint16 *f = (NullaryFcnUint16 *)fcn; 290 STDLIB_NULLARY_LOOP_CLBK( uint16_t ) 291 } 292 293 /** 294 * Applies a nullary callback to each element in a strided output array. 295 * 296 * @param arrays array whose only element is a pointer to the output array 297 * @param shape array whose only element is the number of elements over which to iterate 298 * @param strides array containing strides (in bytes) for each strided array 299 * @param fcn callback 300 * 301 * @example 302 * #include "stdlib/strided/common/nullary.h" 303 * #include <stdint.h> 304 * 305 * // Create a zeroed underlying byte array: 306 * uint8_t out[] = { 0, 0, 0, 0, 0, 0 }; 307 * 308 * // Define a pointer to an array containing pointers to strided arrays: 309 * uint8_t *arrays[] = { out }; 310 * 311 * // Define the strides: 312 * int64_t strides[] = { 2 }; // 2 bytes per int16 313 * 314 * // Define the number of elements over which to iterate: 315 * int64_t shape[] = { 3 }; 316 * 317 * // Define a callback: 318 * int16_t ones() { 319 * return 1; 320 * } 321 * 322 * // Fill the output array with ones: 323 * stdlib_strided_h( arrays, shape, strides, (void *)ones ); 324 */ 325 void stdlib_strided_h( uint8_t *arrays[], int64_t *shape, int64_t *strides, void *fcn ) { 326 NullaryFcnInt16 *f = (NullaryFcnInt16 *)fcn; 327 STDLIB_NULLARY_LOOP_CLBK( int16_t ) 328 } 329 330 /** 331 * Applies a nullary callback to each element in a strided output array. 332 * 333 * @param arrays array whose only element is a pointer to the output array 334 * @param shape array whose only element is the number of elements over which to iterate 335 * @param strides array containing strides (in bytes) for each strided array 336 * @param fcn callback 337 * 338 * @example 339 * #include "stdlib/strided/common/nullary.h" 340 * #include <stdint.h> 341 * 342 * // Create a zeroed underlying byte array: 343 * uint8_t out[] = { 0, 0, 0 }; 344 * 345 * // Define a pointer to an array containing pointers to strided arrays: 346 * uint8_t *arrays[] = { out }; 347 * 348 * // Define the strides: 349 * int64_t strides[] = { 1 }; // 1 byte per uint8 350 * 351 * // Define the number of elements over which to iterate: 352 * int64_t shape[] = { 3 }; 353 * 354 * // Define a callback: 355 * uint8_t ones() { 356 * return 1; 357 * } 358 * 359 * // Fill the output array with ones: 360 * stdlib_strided_B( arrays, shape, strides, (void *)ones ); 361 */ 362 void stdlib_strided_B( uint8_t *arrays[], int64_t *shape, int64_t *strides, void *fcn ) { 363 NullaryFcnUint8 *f = (NullaryFcnUint8 *)fcn; 364 STDLIB_NULLARY_LOOP_CLBK( uint8_t ) 365 } 366 367 /** 368 * Applies a nullary callback to each element in a strided output array. 369 * 370 * @param arrays array whose only element is a pointer to the output array 371 * @param shape array whose only element is the number of elements over which to iterate 372 * @param strides array containing strides (in bytes) for each strided array 373 * @param fcn callback 374 * 375 * @example 376 * #include "stdlib/strided/common/nullary.h" 377 * #include <stdint.h> 378 * 379 * // Create a zeroed underlying byte array: 380 * uint8_t out[] = { 0, 0, 0 }; 381 * 382 * // Define a pointer to an array containing pointers to strided arrays: 383 * uint8_t *arrays[] = { out }; 384 * 385 * // Define the strides: 386 * int64_t strides[] = { 1 }; // 1 byte per int8 387 * 388 * // Define the number of elements over which to iterate: 389 * int64_t shape[] = { 3 }; 390 * 391 * // Define a callback: 392 * int8_t ones() { 393 * return 1; 394 * } 395 * 396 * // Fill the output array with ones: 397 * stdlib_strided_b( arrays, shape, strides, (void *)ones ); 398 */ 399 void stdlib_strided_b( uint8_t *arrays[], int64_t *shape, int64_t *strides, void *fcn ) { 400 NullaryFcnInt8 *f = (NullaryFcnInt8 *)fcn; 401 STDLIB_NULLARY_LOOP_CLBK( int8_t ) 402 }