19 const float *input,
size_t input_elements,
size_t input_stride,
20 const float *weight,
size_t weight_elements,
21 const float *bias,
size_t bias_elements,
22 float *output,
size_t output_elements,
size_t output_stride,
23 float *scratch,
size_t scratch_elements,
24 size_t input_channels,
size_t output_channels,
size_t input_frames,
25 size_t kernel_size,
size_t stride,
size_t padding,
26 size_t output_padding,
size_t output_frames) {
27 size_t geometry, input_span, output_span, weight_need, scratch_need;
28 if (!input_channels || !output_channels || !input_frames ||
29 !kernel_size || !stride || !output_frames || output_padding >= stride)
31 if (input_frames - 1 > SIZE_MAX / stride || padding > SIZE_MAX / 2)
33 geometry = (input_frames - 1) * stride;
34 if (geometry > SIZE_MAX - kernel_size ||
35 geometry + kernel_size > SIZE_MAX - output_padding)
37 geometry += kernel_size + output_padding;
38 if (2 * padding >= geometry || geometry - 2 * padding != output_frames)
44 input_channels > SIZE_MAX / output_channels ||
45 input_channels * output_channels > SIZE_MAX / kernel_size ||
47 output_channels, output_frames, &scratch_need))
49 weight_need = input_channels * output_channels * kernel_size;
50 if (weight_need > SIZE_MAX /
sizeof(
float))
52 if (input_elements < input_span || weight_elements < weight_need ||
53 bias_elements < output_channels || output_elements < output_span ||
54 scratch_elements < scratch_need)
72 for (
size_t ic = 0; ic < input_channels; ++ic)
76 for (
size_t oc = 0; oc < output_channels; ++oc)
77 for (
size_t frame = 0; frame < output_frames; ++frame)
78 scratch[oc * output_frames + frame] = bias[oc];
79 for (
size_t ic = 0; ic < input_channels; ++ic)
80 for (
size_t frame = 0; frame < input_frames; ++frame)
81 for (
size_t tap = 0; tap < kernel_size; ++tap) {
82 size_t target = frame * stride + tap;
83 if (target < padding || target - padding >= output_frames)
85 size_t out_frame = target - padding;
86 float value = input[ic * input_stride + frame];
87 for (
size_t oc = 0; oc < output_channels; ++oc) {
88 size_t index = oc * output_frames + out_frame;
89 scratch[index] = fmaf(value,
90 weight[(ic * output_channels + oc) * kernel_size + tap],
96 for (
size_t oc = 0; oc < output_channels; ++oc)
97 memcpy(output + oc * output_stride,
98 scratch + oc * output_frames,
99 output_frames *
sizeof(
float));
int audio_conv_transpose1d_dense_channel_major_f32_checked(const float *input, size_t input_elements, size_t input_stride, const float *weight, size_t weight_elements, const float *bias, size_t bias_elements, float *output, size_t output_elements, size_t output_stride, float *scratch, size_t scratch_elements, size_t input_channels, size_t output_channels, size_t input_frames, size_t kernel_size, size_t stride, size_t padding, size_t output_padding, size_t output_frames)