← Back to C-Kernel-Engine Docs Doxygen Source Documentation
 
Loading...
Searching...
No Matches
linear_rows_checked.c
Go to the documentation of this file.
2
3#include <float.h>
4#include <math.h>
5#include <stdint.h>
6
7static int span_fits(size_t rows, size_t stride, size_t width, size_t elements)
8{
9 return rows && width && stride >= width &&
10 rows - 1 <= (SIZE_MAX - width) / stride &&
11 (rows - 1) * stride + width <= elements;
12}
13
14static double dot_bias(const float *input, const float *weight,
15 size_t width, float bias)
16{
17 double sum = (double)bias;
18 for (size_t c = 0; c < width; ++c) {
19 volatile double product = (double)input[c] * (double)weight[c];
20 sum += product;
21 }
22 return sum;
23}
24
26 const float *input, size_t input_elements, size_t input_stride,
27 const float *weight, size_t weight_elements, size_t weight_stride,
28 const float *bias, size_t bias_elements,
29 float *output, size_t output_elements, size_t output_stride,
30 size_t rows, size_t input_channels, size_t output_channels)
31{
32 if (!input || !weight || !bias || !output ||
33 !span_fits(rows, input_stride, input_channels, input_elements) ||
34 !span_fits(output_channels, weight_stride, input_channels, weight_elements) ||
35 !span_fits(rows, output_stride, output_channels, output_elements) ||
36 bias_elements < output_channels)
37 return -1;
38
39 /* Validate every accessed value and every result before the first write. */
40 for (size_t r = 0; r < rows; ++r)
41 for (size_t c = 0; c < input_channels; ++c)
42 if (!isfinite(input[r * input_stride + c])) return -1;
43 for (size_t o = 0; o < output_channels; ++o) {
44 if (!isfinite(bias[o])) return -1;
45 for (size_t c = 0; c < input_channels; ++c)
46 if (!isfinite(weight[o * weight_stride + c])) return -1;
47 }
48 for (size_t r = 0; r < rows; ++r)
49 for (size_t o = 0; o < output_channels; ++o) {
50 const double result = dot_bias(input + r * input_stride,
51 weight + o * weight_stride,
52 input_channels, bias[o]);
53 if (!isfinite(result) || fabs(result) > FLT_MAX) return -1;
54 }
55 for (size_t r = 0; r < rows; ++r)
56 for (size_t o = 0; o < output_channels; ++o)
57 output[r * output_stride + o] = (float)dot_bias(
58 input + r * input_stride, weight + o * weight_stride,
59 input_channels, bias[o]);
60 return 0;
61}
static int product(size_t a, size_t b, size_t *out)
static int span_fits(size_t rows, size_t stride, size_t width, size_t elements)
int linear_rows_checked_f32(const float *input, size_t input_elements, size_t input_stride, const float *weight, size_t weight_elements, size_t weight_stride, const float *bias, size_t bias_elements, float *output, size_t output_elements, size_t output_stride, size_t rows, size_t input_channels, size_t output_channels)
static double dot_bias(const float *input, const float *weight, size_t width, float bias)