14#if defined(__AVX2__) && defined(__FMA__)
18#define CK_AUDIO_PI_F 3.14159265358979323846f
19#define CK_AUDIO_PI_D 3.14159265358979323846264338327950288
59 if (result == NULL ||
left > SIZE_MAX -
right) {
68 if (input <= 0 || kernel <= 0 || stride <= 0 || padding < 0 ||
69 input > INT_MAX - 2 * padding || input + 2 * padding < kernel) {
72 return (input + 2 * padding - kernel) / stride + 1;
77 while (index < 0 || index >= length) {
81 index = 2 * length - index - 2;
89 return (uint16_t)p[0] | ((uint16_t)p[1] << 8);
94 return (uint32_t)p[0] | ((uint32_t)p[1] << 8) |
95 ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24);
103 if (bytes == NULL || info == NULL) {
106 if (byte_count < 12 || memcmp(bytes,
"RIFF", 4) != 0 ||
107 memcmp(bytes + 8,
"WAVE", 4) != 0) {
110 const size_t riff_end = (size_t)
read_u32_le(bytes + 4) + 8u;
111 if (riff_end < 12 || riff_end > byte_count) {
114 memset(info, 0,
sizeof(*info));
115 int found_format = 0;
118 while (offset + 8 <= riff_end) {
119 const uint8_t *chunk = bytes + offset;
120 const uint32_t chunk_bytes =
read_u32_le(chunk + 4);
121 const size_t payload = offset + 8;
122 if ((
size_t)chunk_bytes > riff_end - payload) {
125 if (!found_format && memcmp(chunk,
"fmt ", 4) == 0) {
126 if (chunk_bytes < 16) {
134 }
else if (!found_data && memcmp(chunk,
"data", 4) == 0) {
139 const size_t padded = (size_t)chunk_bytes + ((
size_t)chunk_bytes & 1u);
140 if (padded > SIZE_MAX - payload) {
143 offset = payload + padded;
145 if (!found_format || !found_data || info->
format_tag != 1 ||
150 const size_t bytes_per_frame = (size_t)info->
channels * 2u;
151 if (bytes_per_frame == 0 || info->
data_bytes % bytes_per_frame != 0 ||
152 info->
data_bytes / bytes_per_frame > (
size_t)INT_MAX) {
156 return info->
frames > 0 ? 0 : -6;
160 const uint8_t *bytes,
166 if (bytes == NULL || info == NULL || mono == NULL) {
170 info->
channels <= 0 || info->
frames <= 0 || mono_capacity < info->frames ||
175 const float scale = 1.0f / 32768.0f;
176 for (
int frame = 0; frame < info->
frames; ++frame) {
178 for (
int channel = 0; channel < info->
channels; ++channel) {
179 const size_t index = ((size_t)frame * info->
channels + channel) * 2u;
182 mono[frame] = (sum / (float)info->
channels) * scale;
188 const uint8_t *bytes,
195 bytes, byte_count, 0, mono, mono_capacity, info);
199 const uint8_t *bytes,
210 if (start_frame < 0 || start_frame >= info->
frames || mono_capacity <= 0) {
213 const int available = info->
frames - start_frame;
214 const int decoded = available < mono_capacity ? available : mono_capacity;
216 const float scale = 1.0f / 32768.0f;
217 for (
int frame = 0; frame < decoded; ++frame) {
219 const size_t source_frame = (size_t)start_frame + (
size_t)frame;
220 for (
int channel = 0; channel < info->
channels; ++channel) {
222 (source_frame * (size_t)info->
channels + (
size_t)channel) * 2u;
225 mono[frame] = (sum / (float)info->
channels) * scale;
231 const int16_t *interleaved,
236 if (interleaved == NULL || mono == NULL) {
239 if (n_frames <= 0 || n_channels <= 0) {
242 const float scale = 1.0f / 32768.0f;
243 for (
int frame = 0; frame < n_frames; ++frame) {
245 for (
int channel = 0; channel < n_channels; ++channel) {
246 sum += (float)interleaved[(
size_t)frame * n_channels + channel];
248 mono[frame] = (sum / (float)n_channels) * scale;
258 if (input_frames <= 0 || input_rate <= 0 || output_rate <= 0) {
261 return 1 + (int)(((
long long)(input_frames - 1) * output_rate) / input_rate);
272 if (input == NULL || output == NULL) {
276 if (expected <= 0 || output_frames != expected) {
279 for (
int frame = 0; frame < output_frames; ++frame) {
280 const long long numerator = (
long long)frame * input_rate;
281 const int left = (int)(numerator / output_rate);
283 const float fraction = (float)(numerator % output_rate) / (float)output_rate;
284 output[frame] = fmaf(input[
right] - input[
left], fraction, input[
left]);
298 if (input == NULL || output == NULL) {
302 if (expected <= 0 || output_frames != expected || radius < 2 || radius > 128) {
305 const double ratio = (double)output_rate / (
double)input_rate;
306 const double cutoff = ratio < 1.0 ? ratio : 1.0;
307 for (
int frame = 0; frame < output_frames; ++frame) {
308 const double source = (double)frame * (
double)input_rate / (double)output_rate;
309 const int center = (int)floor(source);
310 double weighted = 0.0;
311 double weight_sum = 0.0;
312 for (
int tap = center - radius + 1; tap <= center + radius; ++tap) {
313 if (tap < 0 || tap >= input_frames) {
316 const double distance = source - (double)tap;
317 const double scaled = cutoff * distance;
318 const double sinc = fabs(scaled) < 1.0e-12 ? 1.0 :
320 const double window_x = distance / (double)radius;
321 if (fabs(window_x) >= 1.0) {
324 const double window = 0.5 * (1.0 + cos(
CK_AUDIO_PI_D * window_x));
325 const double weight = cutoff * sinc * window;
326 weighted += (double)input[tap] * weight;
327 weight_sum += weight;
329 output[frame] = weight_sum != 0.0 ? (float)(weighted / weight_sum) : 0.0f;
340 if (input == NULL || output == NULL) {
343 if (input_frames <= 0 || output_frames <= 0) {
346 const int copied = input_frames < output_frames ? input_frames : output_frames;
347 memmove(output, input, (
size_t)copied *
sizeof(
float));
348 if (copied < output_frames) {
352 (
size_t)(output_frames - copied) *
sizeof(
float));
359 if (output == NULL) {
362 if (frames <= 1 || (periodic != 0 && periodic != 1)) {
365 const double denominator = (double)(periodic ? frames : frames - 1);
366 for (
int frame = 0; frame < frames; ++frame) {
367 const double phase = 2.0 *
CK_AUDIO_PI_D * (double)frame / denominator;
368 output[frame] = (float)(0.5 - 0.5 * cos(phase));
379 if (input == NULL || output == NULL) {
382 if (frames <= 0 || !isfinite(coefficient)) {
385 if (input == output) {
386 for (
int frame = frames - 1; frame > 0; --frame) {
387 output[frame] = input[frame] - coefficient * input[frame - 1];
390 output[0] = input[0];
391 for (
int frame = 1; frame < frames; ++frame) {
392 output[frame] = input[frame] - coefficient * input[frame - 1];
405 if (input == NULL || output == NULL) {
408 if (channels <= 0 || frames <= 0 || !isfinite(epsilon) || epsilon < 0.0f) {
411 const int denominator = frames > 1 ? frames - 1 : 1;
412 for (
int channel = 0; channel < channels; ++channel) {
414 double sum_squared_difference = 0.0;
415 for (
int frame = 0; frame < frames; ++frame) {
416 sum += (double)input[(
size_t)frame * channels + channel];
418 const double mean = sum / (double)frames;
419 for (
int frame = 0; frame < frames; ++frame) {
420 const double difference =
421 (double)input[(
size_t)frame * channels + channel] - mean;
422 sum_squared_difference += difference * difference;
424 float standard_deviation = sqrtf(
425 (
float)(sum_squared_difference / (
double)denominator));
426 if (isnan(standard_deviation)) {
427 standard_deviation = 0.0f;
429 const float inverse_standard_deviation =
430 1.0f / (standard_deviation + epsilon);
431 for (
int frame = 0; frame < frames; ++frame) {
432 const size_t index = (size_t)frame * channels + channel;
433 output[index] = (float)((
double)input[index] - mean) *
434 inverse_standard_deviation;
445 if (output == NULL) {
448 if (frames <= 0 || frames > (INT_MAX / 2) + 1 ||
449 channels <= 0 || (channels & 1) != 0) {
452 if ((
size_t)(2 * frames - 1) > SIZE_MAX / (
size_t)channels) {
455 const int positions = 2 * frames - 1;
456 for (
int row = 0; row < positions; ++row) {
457 const float position = (float)(frames - 1 - row);
458 for (
int channel = 0; channel < channels; channel += 2) {
459 const float exponent = (float)channel / (
float)channels;
460 const float inverse_frequency = 1.0f / powf(10000.0f, exponent);
461 const float frequency = inverse_frequency * position;
462 output[(size_t)row * channels + channel] = sinf(frequency);
463 output[(size_t)row * channels + channel + 1] = cosf(frequency);
471 const float *running_mean,
472 const float *running_variance,
480 if (input == NULL || running_mean == NULL || running_variance == NULL ||
481 weight == NULL || bias == NULL || output == NULL) {
484 if (channels <= 0 || frames <= 0 || !isfinite(epsilon) || epsilon < 0.0f) {
487 for (
int channel = 0; channel < channels; ++channel) {
488 const float variance = running_variance[channel];
489 if (!isfinite(variance) || variance + epsilon <= 0.0f) {
493 for (
int channel = 0; channel < channels; ++channel) {
494 const float variance = running_variance[channel];
495 const float scale = weight[channel] / sqrtf(variance + epsilon);
496 const float offset = bias[channel] - running_mean[channel] * scale;
497 for (
int frame = 0; frame < frames; ++frame) {
498 const size_t index = (size_t)channel * frames + frame;
499 output[index] = input[index] * scale + offset;
507 const float *weight_ih,
508 const float *weight_hh,
509 const float *bias_ih,
510 const float *bias_hh,
514 float *gates_scratch,
515 size_t gates_scratch_bytes,
519 if (input == NULL || weight_ih == NULL || weight_hh == NULL ||
520 bias_ih == NULL || bias_hh == NULL || hidden_state == NULL ||
521 cell_state == NULL || output == NULL || gates_scratch == NULL) {
525 if (input_size <= 0 || hidden_size <= 0 ||
526 hidden_size > INT_MAX / 4 ||
527 (
size_t)hidden_size > SIZE_MAX / 4u) {
530 const size_t gate_count = (size_t)hidden_size * 4u;
531 if (gate_count > SIZE_MAX /
sizeof(
float) ||
532 gates_scratch_bytes < gate_count *
sizeof(float)) {
536 for (
size_t gate = 0; gate < gate_count; ++gate) {
537 float sum = bias_ih[gate] + bias_hh[gate];
538 const float *input_weight = weight_ih + gate * (size_t)input_size;
539 const float *hidden_weight = weight_hh + gate * (size_t)hidden_size;
540 for (
int index = 0; index < input_size; ++index) {
541 sum += input_weight[index] * input[index];
543 for (
int index = 0; index < hidden_size; ++index) {
544 sum += hidden_weight[index] * hidden_state[index];
546 gates_scratch[gate] = sum;
549 for (
int index = 0; index < hidden_size; ++index) {
550 const float input_gate = 1.0f /
551 (1.0f + expf(-gates_scratch[index]));
552 const float forget_gate = 1.0f /
553 (1.0f + expf(-gates_scratch[hidden_size + index]));
554 const float cell_gate = tanhf(gates_scratch[2 * hidden_size + index]);
555 const float output_gate = 1.0f /
556 (1.0f + expf(-gates_scratch[3 * hidden_size + index]));
557 const float cell = forget_gate * cell_state[index] +
558 input_gate * cell_gate;
559 const float hidden = output_gate * tanhf(cell);
560 cell_state[index] = cell;
561 hidden_state[index] = hidden;
562 output[index] = hidden;
573 if (window == NULL || cos_table == NULL || sin_table == NULL) {
576 if (n_fft <= 0 || (n_fft & 1) != 0) {
579 const int bins = n_fft / 2 + 1;
580 for (
int sample = 0; sample < n_fft; ++sample) {
581 window[sample] = 0.5f - 0.5f * cosf(
584 for (
int bin = 0; bin < bins; ++bin) {
585 for (
int sample = 0; sample < n_fft; ++sample) {
587 (float)(bin * sample) / (float)n_fft;
588 const size_t index = (size_t)bin * n_fft + sample;
589 cos_table[index] = cosf(angle);
590 sin_table[index] = sinf(angle);
599 return hz / (200.0 / 3.0);
601 return 15.0 + log(hz / 1000.0) / (log(6.4) / 27.0);
607 return (200.0 / 3.0) * mel;
609 return 1000.0 * exp((log(6.4) / 27.0) * (mel - 15.0));
618 if (mel_filters == NULL) {
621 if (sample_rate <= 0 || n_fft <= 0 || (n_fft & 1) != 0 || n_mels <= 0) {
624 const int bins = n_fft / 2 + 1;
627 for (
int mel = 0; mel < n_mels; ++mel) {
628 const double left_mel =
629 mel_min + (mel_max - mel_min) * (
double)mel / (double)(n_mels + 1);
630 const double center_mel =
631 mel_min + (mel_max - mel_min) * (
double)(mel + 1) / (
double)(n_mels + 1);
632 const double right_mel =
633 mel_min + (mel_max - mel_min) * (
double)(mel + 2) / (
double)(n_mels + 1);
637 const double normalization = 2.0 / (
right -
left);
638 for (
int bin = 0; bin < bins; ++bin) {
640 ((double)sample_rate / 2.0) * (double)bin / (
double)(bins - 1);
641 const double lower = (hz -
left) / (center -
left);
642 const double upper = (
right - hz) / (
right - center);
643 const double triangle = fmax(0.0, fmin(lower, upper));
644 mel_filters[(size_t)mel * bins + bin] =
645 (
float)(triangle * normalization);
652 const float *samples,
655 const float *cos_table,
656 const float *sin_table,
662 if (samples == NULL || window == NULL || cos_table == NULL ||
663 sin_table == NULL || power == NULL) {
666 if (n_fft <= 0 || hop_length <= 0 || n_samples <= n_fft / 2 ||
667 (n_fft & 1) != 0 || n_frames <= 0) {
670 if (n_frames != n_samples / hop_length) {
673 const int bins = n_fft / 2 + 1;
674 const int center = n_fft / 2;
675 for (
int frame = 0; frame < n_frames; ++frame) {
676 for (
int bin = 0; bin < bins; ++bin) {
677 const float *cos_row = cos_table + (size_t)bin * n_fft;
678 const float *sin_row = sin_table + (size_t)bin * n_fft;
681 for (
int sample = 0; sample < n_fft; ++sample) {
683 frame * hop_length + sample - center, n_samples);
684 const float value = samples[source] * window[sample];
685 real = fmaf(value, cos_row[sample], real);
686 imag = fmaf(value, sin_row[sample], imag);
688 power[(size_t)frame * bins + bin] =
689 fmaf(real, real, imag * imag);
696 const float *samples,
700 const float *cos_table,
701 const float *sin_table,
708 if (samples == NULL || window == NULL || cos_table == NULL ||
709 sin_table == NULL || power == NULL) {
712 if (n_samples <= 0 || window_length <= 0 || n_fft <= 0 ||
713 window_length > n_fft || (n_fft & 1) != 0 || hop_length <= 0 ||
714 n_frames <= 0 || (reflect_padding != 0 && reflect_padding != 1)) {
717 if (n_frames != n_samples / hop_length + 1) {
721 const int bins = n_fft / 2 + 1;
722 const int center = n_fft / 2;
723 const int window_start = (n_fft - window_length) / 2;
724 for (
int frame = 0; frame < n_frames; ++frame) {
725 for (
int bin = 0; bin < bins; ++bin) {
726 const float *cos_row = cos_table + (size_t)bin * n_fft;
727 const float *sin_row = sin_table + (size_t)bin * n_fft;
730 for (
int sample = 0; sample < window_length; ++sample) {
731 const int fft_sample = window_start + sample;
732 int source = frame * hop_length + fft_sample - center;
733 if (source < 0 || source >= n_samples) {
734 if (!reflect_padding) {
739 const float value = samples[source] * window[sample];
740 real = fmaf(value, cos_row[fft_sample], real);
741 imag = fmaf(value, sin_row[fft_sample], imag);
743 power[(size_t)frame * bins + bin] =
744 fmaf(real, real, imag * imag);
752 const float *mel_filters,
759 if (power == NULL || mel_filters == NULL || log_mel == NULL) {
762 if (frames <= 0 || bins <= 0 || channels <= 0 || epsilon <= 0.0f) {
765 for (
int frame = 0; frame < frames; ++frame) {
766 const float *spectrum = power + (size_t)frame * bins;
767 float *output = log_mel + (size_t)frame * channels;
768 for (
int channel = 0; channel < channels; ++channel) {
769 const float *filter = mel_filters + (size_t)channel * bins;
771 for (
int bin = 0; bin < bins; ++bin) {
772 sum = fmaf(spectrum[bin], filter[bin], sum);
774 output[channel] = logf(sum + epsilon);
781 const float *samples,
785 const float *cos_table,
786 const float *sin_table,
791 const float *samples,
794 const float *cos_table,
795 const float *sin_table,
802 if (samples == NULL || window == NULL || cos_table == NULL ||
803 sin_table == NULL || power == NULL || fft_scratch == NULL) {
807 n_samples <= n_fft / 2 || n_frames <= 0 ||
808 n_frames != n_samples / hop_length) {
811 for (
int frame = 0; frame < n_frames; ++frame) {
826 const float *samples,
830 const float *cos_table,
831 const float *sin_table,
835 const int radix = 20;
837 float *stage_real = fft_scratch;
839 for (
int p = 0; p < radix; ++p) {
840 for (
int k = 0; k < radix; ++k) {
843 for (
int q = 0; q < radix; ++q) {
844 const int sample = p + radix * q;
848 const float value = samples[source] * window[sample];
849 const size_t twiddle =
851 real = fmaf(value, cos_table[twiddle], real);
852 imag = fmaf(value, sin_table[twiddle], imag);
854 stage_real[p * radix + k] = real;
855 stage_imag[p * radix + k] = imag;
858 for (
int frequency = 0;
861 const int k = frequency % radix;
864 for (
int p = 0; p < radix; ++p) {
865 const float a = stage_real[p * radix + k];
866 const float b = stage_imag[p * radix + k];
867 const size_t twiddle =
869 const float c = cos_table[twiddle];
870 const float s = sin_table[twiddle];
871 real = fmaf(a, c, fmaf(-b, s, real));
872 imag = fmaf(a, s, fmaf(b, c, imag));
874 power[frequency] = fmaf(real, real, imag * imag);
879 const uint8_t *bytes,
882 int target_sample_rate,
884 const float *cos_table,
885 const float *sin_table,
886 const float *mel_filters,
891 if (bytes == NULL || window == NULL || cos_table == NULL ||
892 sin_table == NULL || mel_filters == NULL || log_mel == NULL) {
901 n_mels <= 0 || output_frames <= 0) {
904 float *samples = (
float *)malloc((
size_t)info.
frames *
sizeof(float));
905 if (samples == NULL) {
909 bytes, byte_count, &info, samples, info.
frames);
910 if (decoded != info.
frames) {
918 (
size_t)n_mels * (
size_t)output_frames *
sizeof(
float));
921 float maximum = -INFINITY;
924 for (
int frame = 0; frame < global_frames; ++frame) {
934 for (
int mel = 0; mel < n_mels; ++mel) {
935 const float *filter =
939 sum = fmaf(filter[bin], power[bin], sum);
941 const float value = log10f(fmaxf(sum, 1.0e-10f));
942 maximum = fmaxf(maximum, value);
943 const int output_frame = frame - start_feature;
944 if (output_frame >= 0 && output_frame < output_frames) {
945 log_mel[(size_t)mel * output_frames + output_frame] = value;
950 if (!isfinite(maximum)) {
954 const int available = global_frames - start_feature;
955 const int valid_frames =
956 available < output_frames ? (available > 0 ? available : 0) : output_frames;
957 const float floor = maximum - 8.0f;
958 for (
int mel = 0; mel < n_mels; ++mel) {
959 float *output = log_mel + (size_t)mel * output_frames;
960 for (
int frame = 0; frame < valid_frames; ++frame) {
961 output[frame] = (fmaxf(output[frame], floor) + 4.0f) / 4.0f;
969 int feature_channels,
974 if (feature_frames <= 0 || feature_channels <= 0 || conv_channels <= 0 ||
975 kernel_size != 3 || stride != 2) {
978 const int padding = kernel_size / 2;
980 feature_frames, kernel_size, stride, padding);
982 feature_channels, kernel_size, stride, padding);
983 if (stage_frames <= 0 || stage_width <= 0) {
988 if (
checked_mul_size((
size_t)stage_frames, (
size_t)stage_width, &elements) != 0 ||
1003 if (live_frames >= frames) {
1006 const size_t row_bytes = (size_t)width *
sizeof(
float);
1007 for (
int channel = 0; channel < channels; ++channel) {
1008 float *channel_data = value + (size_t)channel * (
size_t)frames * (size_t)width;
1009 for (
int frame = live_frames; frame < frames; ++frame) {
1010 memset(channel_data + (
size_t)frame * (
size_t)width, 0, row_bytes);
1017 for (
size_t index = 0; index < elements; ++index) {
1018 if (value[index] < 0.0f) {
1019 value[index] = 0.0f;
1025 const float *features,
1026 const float *conv0_weight,
1027 const float *conv0_bias,
1028 const float *depthwise1_weight,
1029 const float *depthwise1_bias,
1030 const float *pointwise1_weight,
1031 const float *pointwise1_bias,
1032 const float *depthwise2_weight,
1033 const float *depthwise2_bias,
1034 const float *pointwise2_weight,
1035 const float *pointwise2_bias,
1036 const float *linear_weight,
1037 const float *linear_bias,
1040 size_t workspace_bytes,
1043 int feature_channels,
1048 int output_capacity_frames,
1051 if (features == NULL || conv0_weight == NULL || conv0_bias == NULL ||
1052 depthwise1_weight == NULL || depthwise1_bias == NULL ||
1053 pointwise1_weight == NULL || pointwise1_bias == NULL ||
1054 depthwise2_weight == NULL || depthwise2_bias == NULL ||
1055 pointwise2_weight == NULL || pointwise2_bias == NULL ||
1056 linear_weight == NULL || linear_bias == NULL || output == NULL ||
1057 workspace == NULL || output_frames == NULL || feature_frames <= 0 ||
1058 live_frames <= 0 || live_frames > feature_frames || feature_channels <= 0 ||
1059 conv_channels <= 0 || hidden_size <= 0 || kernel_size != 3 || stride != 2 ||
1060 output_capacity_frames <= 0) {
1065 feature_frames, feature_channels, conv_channels, kernel_size, stride);
1066 if (required_workspace == 0 || workspace_bytes < required_workspace) {
1070 const int padding = kernel_size / 2;
1073 int live_heights[3];
1077 for (
int stage = 1; stage < 3; ++stage) {
1078 heights[stage] =
conv_output_extent(heights[stage - 1], kernel_size, stride, padding);
1081 live_heights[stage - 1], kernel_size, stride, padding);
1083 if (heights[2] <= 0 || widths[2] <= 0 || live_heights[2] <= 0 ||
1084 output_capacity_frames < heights[2]) {
1088 size_t stage0_elements = 0;
1089 if (
checked_mul_size((
size_t)conv_channels, (
size_t)heights[0], &stage0_elements) != 0 ||
1090 checked_mul_size(stage0_elements, (
size_t)widths[0], &stage0_elements) != 0) {
1093 float *ping = (
float *)workspace;
1094 float *pong = ping + stage0_elements;
1097 features, conv0_weight, conv0_bias, ping,
1098 feature_channels, feature_frames, 1, conv_channels,
1099 kernel_size, kernel_size, stride, stride, padding, padding, 1,
1100 widths[0], heights[0]);
1101 if (status != 0)
return -10;
1106 ping, depthwise1_weight, depthwise1_bias, pong,
1107 widths[0], heights[0], conv_channels, conv_channels,
1108 kernel_size, kernel_size, stride, stride, padding, padding, conv_channels,
1109 widths[1], heights[1]);
1110 if (status != 0)
return -11;
1114 pong, pointwise1_weight, pointwise1_bias, ping,
1115 widths[1], heights[1], conv_channels, conv_channels,
1116 1, 1, 1, 1, 0, 0, 1, widths[1], heights[1]);
1117 if (status != 0)
return -12;
1118 size_t stage1_elements = 0;
1119 if (
checked_mul_size((
size_t)conv_channels, (
size_t)heights[1], &stage1_elements) != 0 ||
1120 checked_mul_size(stage1_elements, (
size_t)widths[1], &stage1_elements) != 0) {
1127 ping, depthwise2_weight, depthwise2_bias, pong,
1128 widths[1], heights[1], conv_channels, conv_channels,
1129 kernel_size, kernel_size, stride, stride, padding, padding, conv_channels,
1130 widths[2], heights[2]);
1131 if (status != 0)
return -13;
1135 pong, pointwise2_weight, pointwise2_bias, ping,
1136 widths[2], heights[2], conv_channels, conv_channels,
1137 1, 1, 1, 1, 0, 0, 1, widths[2], heights[2]);
1138 if (status != 0)
return -14;
1139 size_t final_elements = 0;
1140 if (
checked_mul_size((
size_t)conv_channels, (
size_t)heights[2], &final_elements) != 0 ||
1141 checked_mul_size(final_elements, (
size_t)widths[2], &final_elements) != 0) {
1147 if (widths[2] > INT_MAX / conv_channels)
return -4;
1148 const int flattened_width = conv_channels * widths[2];
1149 for (
int frame = 0; frame < heights[2]; ++frame) {
1150 float *row = pong + (size_t)frame * (
size_t)flattened_width;
1151 for (
int channel = 0; channel < conv_channels; ++channel) {
1152 const float *source = ping +
1153 ((size_t)channel * (
size_t)heights[2] + (size_t)frame) * (size_t)widths[2];
1154 memcpy(row + (
size_t)channel * (
size_t)widths[2], source,
1155 (
size_t)widths[2] *
sizeof(
float));
1160 pong, linear_weight, linear_bias, output,
1161 heights[2], hidden_size, flattened_width);
1162 *output_frames = heights[2];
1168 const float *weight;
1172 int output_channels;
1179 int input_channels_per_group;
1180 int output_channels_per_group;
1181 int use_stride2_contiguous;
1182} ck_audio_conv1d_f32_args_t;
1184#if defined(__AVX2__) && defined(__FMA__)
1185static inline __m256 ck_audio_load_stride2_8(
const float *input)
1187 const __m256i select_even = _mm256_setr_epi32(0, 2, 4, 6, 0, 0, 0, 0);
1188 const __m256 lo = _mm256_permutevar8x32_ps(
1189 _mm256_loadu_ps(input), select_even);
1190 const __m256 hi = _mm256_permutevar8x32_ps(
1191 _mm256_loadu_ps(input + 8), select_even);
1192 return _mm256_insertf128_ps(
1193 _mm256_castps128_ps256(_mm256_castps256_ps128(lo)),
1194 _mm256_castps256_ps128(hi), 1);
1204 const ck_audio_conv1d_f32_args_t *args =
1205 (
const ck_audio_conv1d_f32_args_t *)opaque;
1206 for (
int out_channel = ith; out_channel < args->output_channels;
1207 out_channel += nth) {
1208 const int group = out_channel / args->output_channels_per_group;
1209 const int input_channel_offset = group * args->input_channels_per_group;
1210 const float *weight_channel = args->weight +
1211 (size_t)out_channel * args->input_channels_per_group * args->kernel_size;
1212 float *output_channel = args->output +
1213 (size_t)out_channel * args->output_frames;
1215 const int interior_begin =
1216 (args->padding + args->stride - 1) / args->stride;
1217 for (; out_frame < interior_begin && out_frame < args->output_frames;
1219 float sum = args->bias != NULL ? args->bias[out_channel] : 0.0f;
1220 for (
int local_channel = 0;
1221 local_channel < args->input_channels_per_group;
1223 const int in_channel = input_channel_offset + local_channel;
1224 const float *input_channel = args->input +
1225 (size_t)in_channel * args->input_frames;
1226 const float *weight_row = weight_channel +
1227 (size_t)local_channel * args->kernel_size;
1228 for (
int kernel = 0; kernel < args->kernel_size; ++kernel) {
1229 const int in_frame =
1230 out_frame * args->stride + kernel - args->padding;
1231 if (in_frame >= 0 && in_frame < args->input_frames) {
1232 sum = fmaf(input_channel[in_frame], weight_row[kernel], sum);
1236 output_channel[out_frame] = sum;
1238#if defined(__AVX2__) && defined(__FMA__)
1239 for (; out_frame + 7 < args->output_frames &&
1240 (out_frame + 7) * args->stride + args->kernel_size - 1 -
1241 args->padding < args->input_frames;
1243 __m256 sums = _mm256_set1_ps(
1244 args->bias != NULL ? args->bias[out_channel] : 0.0f);
1245 for (
int local_channel = 0;
1246 local_channel < args->input_channels_per_group;
1248 const int in_channel = input_channel_offset + local_channel;
1249 const float *input_channel = args->input +
1250 (size_t)in_channel * args->input_frames;
1251 const float *weight_row = weight_channel +
1252 (size_t)local_channel * args->kernel_size;
1253 for (
int kernel = 0; kernel < args->kernel_size; ++kernel) {
1255 out_frame * args->stride + kernel - args->padding;
1257 if (args->stride == 1) {
1258 samples = _mm256_loadu_ps(input_channel + base);
1259 }
else if (args->stride == 2 &&
1260 args->use_stride2_contiguous &&
1261 base + 15 < args->input_frames) {
1262 samples = ck_audio_load_stride2_8(input_channel + base);
1263 }
else if (args->stride == 2) {
1264 const __m256i indices = _mm256_setr_epi32(
1265 base, base + 2, base + 4, base + 6,
1266 base + 8, base + 10, base + 12, base + 14);
1267 samples = _mm256_i32gather_ps(input_channel, indices, 4);
1269 samples = _mm256_setr_ps(
1270 input_channel[base],
1271 input_channel[base + args->stride],
1272 input_channel[base + 2 * args->stride],
1273 input_channel[base + 3 * args->stride],
1274 input_channel[base + 4 * args->stride],
1275 input_channel[base + 5 * args->stride],
1276 input_channel[base + 6 * args->stride],
1277 input_channel[base + 7 * args->stride]);
1279 sums = _mm256_fmadd_ps(
1280 samples, _mm256_set1_ps(weight_row[kernel]), sums);
1283 _mm256_storeu_ps(output_channel + out_frame, sums);
1286 for (; out_frame < args->output_frames; ++out_frame) {
1287 float sum = args->bias != NULL ? args->bias[out_channel] : 0.0f;
1288 for (
int local_channel = 0;
1289 local_channel < args->input_channels_per_group;
1291 const int in_channel = input_channel_offset + local_channel;
1292 const float *input_channel = args->input +
1293 (size_t)in_channel * args->input_frames;
1294 const float *weight_row = weight_channel +
1295 (size_t)local_channel * args->kernel_size;
1296 for (
int kernel = 0; kernel < args->kernel_size; ++kernel) {
1297 const int in_frame =
1298 out_frame * args->stride + kernel - args->padding;
1299 if (in_frame >= 0 && in_frame < args->input_frames) {
1300 sum = fmaf(input_channel[in_frame], weight_row[kernel], sum);
1304 output_channel[out_frame] = sum;
1311 const float *weight,
1315 int output_channels,
1323 input, weight, bias, output, input_channels, output_channels,
1324 input_frames, kernel_size, stride, padding, 1, output_frames);
1329 const float *weight,
1333 int output_channels,
1341 if (input == NULL || weight == NULL || output == NULL) {
1344 if (input_channels <= 0 || output_channels <= 0 || input_frames <= 0 ||
1345 kernel_size <= 0 || stride <= 0 || padding < 0 || groups <= 0 ||
1346 output_frames <= 0 || input_channels % groups != 0 ||
1347 output_channels % groups != 0) {
1350 const int64_t padded_frames =
1351 (int64_t)input_frames + 2 * (int64_t)padding - kernel_size;
1352 if (padded_frames < 0 || padded_frames / stride + 1 > INT_MAX ||
1353 output_frames != (
int)(padded_frames / stride + 1)) {
1356 const char *disable_stride2 =
1357 getenv(
"CK_DISABLE_AUDIO_CONV_STRIDE2_CONTIGUOUS");
1358 ck_audio_conv1d_f32_args_t args = {
1363 .input_channels = input_channels,
1364 .output_channels = output_channels,
1365 .input_frames = input_frames,
1366 .kernel_size = kernel_size,
1369 .output_frames = output_frames,
1371 .input_channels_per_group = input_channels / groups,
1372 .output_channels_per_group = output_channels / groups,
1373 .use_stride2_contiguous = !(
1374 disable_stride2 && disable_stride2[0] &&
1375 strcmp(disable_stride2,
"0") != 0),
1379 if (active > output_channels) active = output_channels;
1380 if (pool != NULL && active > 1) {
1391 const float *weight;
1397 int output_channels;
1408} ck_audio_conv2d_whc_f32_args_t;
1415 const ck_audio_conv2d_whc_f32_args_t *args =
1416 (
const ck_audio_conv2d_whc_f32_args_t *)opaque;
1417 const int outputs_per_channel = args->output_width * args->output_height;
1418 const int input_channels_per_group = args->input_channels / args->groups;
1419 const int output_channels_per_group = args->output_channels / args->groups;
1421 while (index <
end) {
1422 const int output_channel = index / outputs_per_channel;
1423 const int spatial = index - output_channel * outputs_per_channel;
1424 const int output_y = spatial / args->output_width;
1425 const int output_x = spatial - output_y * args->output_width;
1426 const int group = output_channel / output_channels_per_group;
1427 const int input_channel_begin = group * input_channels_per_group;
1428#if defined(__AVX2__) && defined(__FMA__)
1429 const int input_x_begin = output_x - args->padding_width;
1430 if (args->use_width_simd && args->stride_width == 1 &&
1431 output_x + 8 <= args->output_width && index + 8 <=
end &&
1432 input_x_begin >= 0 &&
1433 input_x_begin + 7 + args->kernel_width <= args->input_width) {
1434 __m256 sums = _mm256_set1_ps(
1435 args->bias != NULL ? args->bias[output_channel] : 0.0f);
1436 for (
int input_channel_offset = 0;
1437 input_channel_offset < input_channels_per_group;
1438 ++input_channel_offset) {
1439 const int input_channel =
1440 input_channel_begin + input_channel_offset;
1441 for (
int kernel_y = 0; kernel_y < args->kernel_height; ++kernel_y) {
1443 output_y * args->stride_height + kernel_y -
1444 args->padding_height;
1445 if (input_y < 0 || input_y >= args->input_height) {
1448 for (
int kernel_x = 0; kernel_x < args->kernel_width; ++kernel_x) {
1449 const size_t input_index =
1450 ((size_t)input_channel * args->input_height + input_y) *
1451 args->input_width + input_x_begin + kernel_x;
1452 const size_t weight_index =
1453 (((size_t)output_channel * input_channels_per_group +
1454 input_channel_offset) * args->kernel_height + kernel_y) *
1455 args->kernel_width + kernel_x;
1456 sums = _mm256_fmadd_ps(
1457 _mm256_loadu_ps(args->input + input_index),
1458 _mm256_set1_ps(args->weight[weight_index]), sums);
1462 _mm256_storeu_ps(args->output + index, sums);
1467 float sum = args->bias != NULL ? args->bias[output_channel] : 0.0f;
1468 for (
int input_channel_offset = 0;
1469 input_channel_offset < input_channels_per_group;
1470 ++input_channel_offset) {
1471 const int input_channel = input_channel_begin + input_channel_offset;
1472 for (
int kernel_y = 0; kernel_y < args->kernel_height; ++kernel_y) {
1473 const int input_y = output_y * args->stride_height + kernel_y -
1474 args->padding_height;
1475 if (input_y < 0 || input_y >= args->input_height) {
1478 for (
int kernel_x = 0; kernel_x < args->kernel_width; ++kernel_x) {
1479 const int input_x = output_x * args->stride_width + kernel_x -
1480 args->padding_width;
1481 if (input_x < 0 || input_x >= args->input_width) {
1484 const size_t input_index =
1485 ((size_t)input_channel * args->input_height + input_y) *
1486 args->input_width + input_x;
1487 const size_t weight_index =
1488 (((size_t)output_channel * input_channels_per_group +
1489 input_channel_offset) * args->kernel_height + kernel_y) *
1490 args->kernel_width + kernel_x;
1491 sum = fmaf(args->input[input_index], args->weight[weight_index], sum);
1495 args->output[index] = sum;
1502 const float *weight,
1508 int output_channels,
1519 if (input == NULL || weight == NULL || output == NULL) {
1522 if (input_width <= 0 || input_height <= 0 || input_channels <= 0 ||
1523 output_channels <= 0 || kernel_width <= 0 || kernel_height <= 0 ||
1524 stride_width <= 0 || stride_height <= 0 || padding_width < 0 ||
1525 padding_height < 0 || groups <= 0 || output_width <= 0 ||
1526 output_height <= 0 || input_channels % groups != 0 ||
1527 output_channels % groups != 0) {
1530 const int expected_width =
1531 (input_width + 2 * padding_width - kernel_width) / stride_width + 1;
1532 const int expected_height =
1533 (input_height + 2 * padding_height - kernel_height) / stride_height + 1;
1534 if (output_width != expected_width || output_height != expected_height) {
1537 ck_audio_conv2d_whc_f32_args_t args = {
1542 .input_width = input_width,
1543 .input_height = input_height,
1544 .input_channels = input_channels,
1545 .output_channels = output_channels,
1546 .kernel_width = kernel_width,
1547 .kernel_height = kernel_height,
1548 .stride_width = stride_width,
1549 .stride_height = stride_height,
1550 .padding_width = padding_width,
1551 .padding_height = padding_height,
1553 .output_width = output_width,
1554 .output_height = output_height,
1555 .use_width_simd = 1,
1557 const char *disable_width_simd = getenv(
"CK_AUDIO_DISABLE_CONV2D_WIDTH_SIMD");
1558 if (disable_width_simd != NULL && disable_width_simd[0] !=
'\0' &&
1559 strcmp(disable_width_simd,
"0") != 0) {
1560 args.use_width_simd = 0;
1562 const int output_elements = output_channels * output_height * output_width;
1565 if (active > output_elements) {
1566 active = output_elements;
1568 if (pool != NULL && active > 1) {
1569 const int grain = output_width > 0 ? output_width : 1;
1571 pool, active, 0, output_elements, grain,
1583} ck_audio_glu_split_f32_args_t;
1587 const ck_audio_glu_split_f32_args_t *args =
1588 (
const ck_audio_glu_split_f32_args_t *)opaque;
1589 for (
int index = begin; index <
end; ++index) {
1590 const float gate = args->gate[index];
1591 const float sigmoid = 1.0f / (1.0f + expf(-gate));
1592 args->output[index] = args->value[index] * sigmoid;
1602 if (input == NULL || output == NULL) {
1605 if (channels <= 0 || frames <= 0) {
1608 const int elements = channels * frames;
1609 ck_audio_glu_split_f32_args_t args = {
1611 .gate = input + elements,
1616 if (active > elements) {
1619 if (pool != NULL && active > 1) {
1621 pool, active, 0, elements, 256,
1630 const float *raw_scores;
1634} ck_audio_relative_shift_f32_args_t;
1637 int begin,
int end,
void *opaque)
1639 const ck_audio_relative_shift_f32_args_t *args =
1640 (
const ck_audio_relative_shift_f32_args_t *)opaque;
1641 const int frames = args->query_frames;
1642 const int raw_frames = args->raw_key_frames;
1643 for (
int row = begin; row <
end; ++row) {
1644 const int query = row % frames;
1645 const float *raw = args->raw_scores + (size_t)row * raw_frames;
1646 float *output = args->scores + (size_t)row * frames;
1647 const int origin = frames - 1 - query;
1648 for (
int key = 0; key < frames; ++key) {
1649 output[key] = raw[origin + key];
1655 const float *raw_scores,
1660 if (raw_scores == NULL || scores == NULL) {
1663 if (heads <= 0 || query_frames <= 0) {
1666 const int rows = heads * query_frames;
1667 ck_audio_relative_shift_f32_args_t args = {
1668 .raw_scores = raw_scores,
1670 .query_frames = query_frames,
1671 .raw_key_frames = 2 * query_frames - 1,
1675 if (active > rows) {
1678 if (pool != NULL && active > 1) {
1680 pool, active, 0, rows, 1,
1692 const float *relative_key;
1693 const float *bias_u;
1694 const float *bias_v;
1696 float *scores_scratch;
1697 ck_threadpool_t *pool;
1703} ck_audio_conformer_relative_attention_f32_args_t;
1710 const ck_audio_conformer_relative_attention_f32_args_t *args =
1711 (
const ck_audio_conformer_relative_attention_f32_args_t *)opaque;
1712 int scratch_slot = args->pool
1714 if (scratch_slot < 0) scratch_slot = 0;
1715 float *scores = args->scores_scratch +
1716 (size_t)scratch_slot * (
size_t)args->frames;
1717 for (
int row = begin; row <
end; ++row) {
1718 const int head = row / args->frames;
1719 const int query_frame = row % args->frames;
1720 const int head_offset = head * args->head_dim;
1721 const float *u = args->bias_u + head_offset;
1722 const float *v = args->bias_v + head_offset;
1723 const float *q = args->query +
1724 (size_t)query_frame * args->channels + head_offset;
1725 float maximum = -INFINITY;
1726 for (
int key_frame = 0; key_frame < args->frames; ++key_frame) {
1727 const float *k = args->key +
1728 (size_t)key_frame * args->channels + head_offset;
1729 const int relative_frame =
1730 args->frames - 1 + key_frame - query_frame;
1731 const float *r = args->relative_key +
1732 (size_t)relative_frame * args->channels + head_offset;
1733 float content = 0.0f;
1734 float position = 0.0f;
1735 for (
int dim = 0; dim < args->head_dim; ++dim) {
1736 content += (q[dim] + u[dim]) * k[dim];
1737 position += (q[dim] + v[dim]) * r[dim];
1739 const float score = (content + position) * args->scale;
1740 scores[key_frame] =
score;
1741 if (
score > maximum) {
1745 float denominator = 0.0f;
1746 for (
int key_frame = 0; key_frame < args->frames; ++key_frame) {
1747 const float probability = expf(scores[key_frame] - maximum);
1748 scores[key_frame] = probability;
1749 denominator += probability;
1751 const float inverse_denominator = 1.0f / denominator;
1752 float *out = args->output +
1753 (size_t)query_frame * args->channels + head_offset;
1754 for (
int dim = 0; dim < args->head_dim; ++dim) {
1756 for (
int key_frame = 0; key_frame < args->frames; ++key_frame) {
1757 const float *value_row = args->value +
1758 (size_t)key_frame * args->channels + head_offset;
1759 sum += scores[key_frame] * inverse_denominator * value_row[dim];
1770 const float *relative_key,
1771 const float *bias_u,
1772 const float *bias_v,
1778 float *scores_scratch,
1779 size_t scores_scratch_bytes)
1781 if (query == NULL || key == NULL || value == NULL || relative_key == NULL ||
1782 bias_u == NULL || bias_v == NULL || output == NULL ||
1783 scores_scratch == NULL) {
1786 if (frames <= 0 || frames > (INT_MAX / 2) + 1 || heads <= 0 ||
1787 head_dim <= 0 || heads > INT_MAX / head_dim ||
1788 heads > INT_MAX / frames || !isfinite(scale) || scale <= 0.0f) {
1791 if ((
size_t)frames > SIZE_MAX / (
size_t)heads ||
1792 (
size_t)frames * (
size_t)heads > SIZE_MAX /
sizeof(
float) ||
1793 scores_scratch_bytes <
1794 (
size_t)frames * (
size_t)heads *
sizeof(
float)) {
1797 const int channels = heads * head_dim;
1799 ck_audio_conformer_relative_attention_f32_args_t args = {
1803 .relative_key = relative_key,
1807 .scores_scratch = scores_scratch,
1811 .head_dim = head_dim,
1812 .channels = channels,
1816 const size_t scratch_slots = scores_scratch_bytes /
1817 ((size_t)frames *
sizeof(
float));
1818 const int rows = heads * frames;
1819 if ((
size_t)active > scratch_slots) active = (
int)scratch_slots;
1820 if (active > rows) active = rows;
1821 if (pool != NULL && active > 1) {
1823 pool, active, 0, rows, 1,
1837 if (input == NULL || output == NULL) {
1840 if (channels <= 0 || frames <= 0) {
1843 for (
int frame = 0; frame < frames; ++frame) {
1844 for (
int channel = 0; channel < channels; ++channel) {
1845 output[(size_t)frame * channels + channel] =
1846 input[(
size_t)channel * frames + frame];
1853 const float *residual,
1854 const float *branch,
1859 if (residual == NULL || branch == NULL || output == NULL) {
1862 if (elements == 0 || !isfinite(scale)) {
1865 for (
size_t index = 0; index < elements; ++index) {
1867 volatile float scaled = branch[index] * scale;
1868 output[index] = residual[index] + scaled;
1876 int intermediate_size,
1880 if (frames <= 0 || frames > (INT_MAX / 2) + 1 || hidden_size <= 0 ||
1881 intermediate_size <= 0 || heads <= 0 || hidden_size % heads != 0 ||
1882 score_slots < (
size_t)heads) {
1885 size_t token_elements = 0;
1886 size_t ff_elements = 0;
1887 size_t relative_elements = 0;
1888 size_t doubled_token_elements = 0;
1889 size_t score_elements = 0;
1890 if (
checked_mul_size((
size_t)frames, (
size_t)hidden_size, &token_elements) != 0 ||
1891 checked_mul_size((
size_t)frames, (
size_t)intermediate_size, &ff_elements) != 0 ||
1893 &relative_elements) != 0 ||
1898 size_t large_elements = ff_elements;
1899 if (relative_elements > large_elements) large_elements = relative_elements;
1900 if (doubled_token_elements > large_elements) {
1901 large_elements = doubled_token_elements;
1903 size_t total_elements = 0;
1904 size_t token_buffers = 0;
1911 return total_elements;
1917 int intermediate_size,
1922 const size_t score_slots = (size_t)(requested_threads > heads
1923 ? requested_threads : heads);
1925 frames, hidden_size, intermediate_size, heads, score_slots);
1930 const float *relative_positions,
1931 const float *ff1_norm_weight,
1932 const float *ff1_norm_bias,
1933 const float *ff1_up_weight,
1934 const float *ff1_up_bias,
1935 const float *ff1_down_weight,
1936 const float *ff1_down_bias,
1937 const float *attn_norm_weight,
1938 const float *attn_norm_bias,
1939 const float *q_weight,
1940 const float *q_bias,
1941 const float *k_weight,
1942 const float *k_bias,
1943 const float *v_weight,
1944 const float *v_bias,
1945 const float *relative_weight,
1946 const float *attn_bias_u,
1947 const float *attn_bias_v,
1948 const float *attn_out_weight,
1949 const float *attn_out_bias,
1950 const float *conv_norm_weight,
1951 const float *conv_norm_bias,
1952 const float *conv_pw1_weight,
1953 const float *conv_pw1_bias,
1954 const float *conv_dw_weight,
1955 const float *conv_dw_bias,
1956 const float *conv_bn_mean,
1957 const float *conv_bn_variance,
1958 const float *conv_bn_weight,
1959 const float *conv_bn_bias,
1960 const float *conv_pw2_weight,
1961 const float *conv_pw2_bias,
1962 const float *ff2_norm_weight,
1963 const float *ff2_norm_bias,
1964 const float *ff2_up_weight,
1965 const float *ff2_up_bias,
1966 const float *ff2_down_weight,
1967 const float *ff2_down_bias,
1968 const float *out_norm_weight,
1969 const float *out_norm_bias,
1972 size_t workspace_bytes,
1975 int intermediate_size,
1978 int conv_kernel_size,
1979 float layer_norm_epsilon,
1980 float batch_norm_epsilon)
1982 if (input == NULL || relative_positions == NULL ||
1983 ff1_norm_weight == NULL || ff1_norm_bias == NULL ||
1984 ff1_up_weight == NULL || ff1_down_weight == NULL ||
1985 attn_norm_weight == NULL || attn_norm_bias == NULL ||
1986 q_weight == NULL || k_weight == NULL || v_weight == NULL ||
1987 relative_weight == NULL || attn_bias_u == NULL || attn_bias_v == NULL ||
1988 attn_out_weight == NULL || conv_norm_weight == NULL ||
1989 conv_norm_bias == NULL || conv_pw1_weight == NULL ||
1990 conv_dw_weight == NULL || conv_bn_mean == NULL ||
1991 conv_bn_variance == NULL || conv_bn_weight == NULL ||
1992 conv_bn_bias == NULL || conv_pw2_weight == NULL ||
1993 ff2_norm_weight == NULL || ff2_norm_bias == NULL ||
1994 ff2_up_weight == NULL || ff2_down_weight == NULL ||
1995 out_norm_weight == NULL || out_norm_bias == NULL || output == NULL ||
1996 workspace == NULL) {
1999 if (frames <= 0 || hidden_size <= 0 || intermediate_size <= 0 ||
2000 heads <= 0 || head_dim <= 0 || heads > INT_MAX / head_dim ||
2001 heads * head_dim != hidden_size || conv_kernel_size <= 0 ||
2002 (conv_kernel_size & 1) == 0 || !isfinite(layer_norm_epsilon) ||
2003 layer_norm_epsilon <= 0.0f || !isfinite(batch_norm_epsilon) ||
2004 batch_norm_epsilon <= 0.0f) {
2007 const size_t minimum_workspace =
2009 frames, hidden_size, intermediate_size, heads, (
size_t)heads);
2010 if (minimum_workspace == 0 || workspace_bytes < minimum_workspace) {
2014 const size_t token_elements = (size_t)frames * (
size_t)hidden_size;
2015 const size_t ff_elements = (size_t)frames * (
size_t)intermediate_size;
2016 const size_t relative_elements =
2017 (size_t)(2 * frames - 1) * (size_t)hidden_size;
2018 const size_t doubled_token_elements = 2u * token_elements;
2019 size_t large_elements = ff_elements;
2020 if (relative_elements > large_elements) large_elements = relative_elements;
2021 if (doubled_token_elements > large_elements) {
2022 large_elements = doubled_token_elements;
2025 float *cursor = (
float *)workspace;
2026 float *norm = cursor;
2027 cursor += token_elements;
2028 float *large = cursor;
2029 cursor += large_elements;
2030 float *buffer2 = cursor;
2031 cursor += token_elements;
2032 float *buffer3 = cursor;
2033 cursor += token_elements;
2034 float *buffer4 = cursor;
2035 cursor += token_elements;
2036 float *buffer5 = cursor;
2037 cursor += token_elements;
2038 float *scores = cursor;
2039 const size_t scores_offset = (size_t)(
2040 (
unsigned char *)scores - (
unsigned char *)workspace);
2042 memcpy(output, input, token_elements *
sizeof(
float));
2045 output, ff1_norm_weight, ff1_norm_bias, norm, NULL, NULL,
2046 frames, hidden_size, layer_norm_epsilon);
2048 norm, ff1_up_weight, ff1_up_bias, large,
2049 frames, intermediate_size, hidden_size);
2052 large, ff1_down_weight, ff1_down_bias, buffer2,
2053 frames, hidden_size, intermediate_size);
2055 output, buffer2, 0.5f, output, token_elements) != 0) {
2060 output, attn_norm_weight, attn_norm_bias, norm, NULL, NULL,
2061 frames, hidden_size, layer_norm_epsilon);
2063 norm, q_weight, q_bias, buffer2, frames, hidden_size, hidden_size);
2065 norm, k_weight, k_bias, buffer3, frames, hidden_size, hidden_size);
2067 norm, v_weight, v_bias, buffer4, frames, hidden_size, hidden_size);
2069 relative_positions, relative_weight, NULL, large,
2070 2 * frames - 1, hidden_size, hidden_size);
2072 buffer2, buffer3, buffer4, large, attn_bias_u, attn_bias_v,
2073 buffer5, frames, heads, head_dim, 1.0f / sqrtf((
float)head_dim),
2074 scores, workspace_bytes - scores_offset) != 0) {
2078 buffer5, attn_out_weight, attn_out_bias, norm,
2079 frames, hidden_size, hidden_size);
2081 output, norm, 1.0f, output, token_elements) != 0) {
2086 output, conv_norm_weight, conv_norm_bias, norm, NULL, NULL,
2087 frames, hidden_size, layer_norm_epsilon);
2088 for (
int frame = 0; frame < frames; ++frame) {
2089 for (
int channel = 0; channel < hidden_size; ++channel) {
2090 buffer2[(size_t)channel * (
size_t)frames + (size_t)frame] =
2091 norm[(
size_t)frame * (size_t)hidden_size + (
size_t)channel];
2095 buffer2, conv_pw1_weight, conv_pw1_bias, large,
2096 hidden_size, 2 * hidden_size, frames, 1, 1, 0, 1, frames) != 0 ||
2098 large, buffer3, hidden_size, frames) != 0 ||
2100 buffer3, conv_dw_weight, conv_dw_bias, buffer4,
2101 hidden_size, hidden_size, frames, conv_kernel_size, 1,
2102 conv_kernel_size / 2, hidden_size, frames) != 0 ||
2104 buffer4, conv_bn_mean, conv_bn_variance, conv_bn_weight,
2105 conv_bn_bias, buffer5, hidden_size, frames,
2106 batch_norm_epsilon) != 0) {
2111 buffer5, conv_pw2_weight, conv_pw2_bias, buffer3,
2112 hidden_size, hidden_size, frames, 1, 1, 0, 1, frames) != 0) {
2115 for (
int frame = 0; frame < frames; ++frame) {
2116 for (
int channel = 0; channel < hidden_size; ++channel) {
2117 norm[(size_t)frame * (
size_t)hidden_size + (size_t)channel] =
2118 buffer3[(
size_t)channel * (size_t)frames + (
size_t)frame];
2122 output, norm, 1.0f, output, token_elements) != 0) {
2127 output, ff2_norm_weight, ff2_norm_bias, norm, NULL, NULL,
2128 frames, hidden_size, layer_norm_epsilon);
2130 norm, ff2_up_weight, ff2_up_bias, large,
2131 frames, intermediate_size, hidden_size);
2134 large, ff2_down_weight, ff2_down_bias, buffer2,
2135 frames, hidden_size, intermediate_size);
2137 output, buffer2, 0.5f, output, token_elements) != 0) {
2141 output, out_norm_weight, out_norm_bias, norm, NULL, NULL,
2142 frames, hidden_size, layer_norm_epsilon);
2143 memcpy(output, norm, token_elements *
sizeof(
float));
2149 if (values == NULL || selected == NULL) {
2152 if (elements <= 0) {
2155 if (!isfinite(values[0])) {
2159 float maximum = values[0];
2160 for (
int index = 1; index < elements; ++index) {
2161 if (!isfinite(values[index])) {
2164 if (values[index] > maximum) {
2165 maximum = values[index];
2174 const float *samples,
2179 if (samples == NULL || power == NULL) {
2190 for (
int frame = 0; frame < n_frames; ++frame) {
2198 const float window = 0.5f - 0.5f * cosf(
2201 const float value = samples[source] * window;
2204 real = fmaf(value, cosf(angle), real);
2205 imag = fmaf(value, sinf(angle), imag);
2208 fmaf(real, real, imag * imag);
2216 const float *mel_filters,
2221 if (power == NULL || mel_filters == NULL || log_mel == NULL) {
2224 if (n_mels <= 0 || n_frames <= 0) {
2228 float maximum = -INFINITY;
2229 for (
int mel = 0; mel < n_mels; ++mel) {
2231 float *output = log_mel + (size_t)mel * n_frames;
2232 for (
int frame = 0; frame < n_frames; ++frame) {
2236 sum = fmaf(filter[bin], spectrum[bin], sum);
2238 const float value = log10f(fmaxf(sum, 1.0e-10f));
2239 output[frame] = value;
2240 maximum = fmaxf(maximum, value);
2244 const float floor = maximum - 8.0f;
2245 for (
int mel = 0; mel < n_mels; ++mel) {
2246 float *output = log_mel + (size_t)mel * n_frames;
2247 for (
int frame = 0; frame < n_frames; ++frame) {
2248 output[frame] = (fmaxf(output[frame], floor) + 4.0f) / 4.0f;
2255 const float *samples,
2257 const float *mel_filters,
2259 float *power_scratch,
2264 samples, n_samples, power_scratch, n_frames);
2265 if (stft_status != 0) {
2269 power_scratch, mel_filters, n_mels, n_frames, log_mel);
int audio_whisper_mel_filters_slaney_f32(int sample_rate, int n_fft, int n_mels, float *mel_filters)
int audio_lstm_step_f32(const float *input, const float *weight_ih, const float *weight_hh, const float *bias_ih, const float *bias_hh, float *hidden_state, float *cell_state, float *output, float *gates_scratch, size_t gates_scratch_bytes, int input_size, int hidden_size)
int audio_whisper_log_mel_reference_f32(const float *samples, int n_samples, const float *mel_filters, int n_mels, float *power_scratch, float *log_mel, int n_frames)
int audio_stft_power_precomputed_f32(const float *samples, int n_samples, const float *window, const float *cos_table, const float *sin_table, int n_fft, int hop_length, float *power, int n_frames)
int audio_resample_linear_f32(const float *input, int input_frames, int input_rate, float *output, int output_frames, int output_rate)
void recurrent_silu_forward(const float *input, float *output, int rows, int dim)
int audio_wav_parse_memory(const uint8_t *bytes, size_t byte_count, CKAudioWavInfo *info)
int audio_conv2d_whc_grouped_f32(const float *input, const float *weight, const float *bias, float *output, int input_width, int input_height, int input_channels, int output_channels, int kernel_width, int kernel_height, int stride_width, int stride_height, int padding_width, int padding_height, int groups, int output_width, int output_height)
int audio_log_mel_time_major_f32(const float *power, const float *mel_filters, float *log_mel, int frames, int bins, int channels, float epsilon)
static void ck_audio_relative_shift_f32_range(int begin, int end, void *opaque)
int audio_conv1d_channel_major_grouped_f32(const float *input, const float *weight, const float *bias, float *output, int input_channels, int output_channels, int input_frames, int kernel_size, int stride, int padding, int groups, int output_frames)
int audio_wav_decode_pcm16_mono_f32(const uint8_t *bytes, size_t byte_count, const CKAudioWavInfo *info, float *mono, int mono_capacity)
void layernorm_naive_serial_matched_precision(const float *input, const float *gamma, const float *beta, float *output, float *mean_cache, float *rstd_cache, int tokens, int d_model, float eps)
int audio_whisper_log_mel_window_wav_pcm16_f32(const uint8_t *bytes, size_t byte_count, int start_frame, int target_sample_rate, const float *window, const float *cos_table, const float *sin_table, const float *mel_filters, int n_mels, int output_frames, float *log_mel)
int audio_batch_norm_inference_channel_major_f32(const float *input, const float *running_mean, const float *running_variance, const float *weight, const float *bias, float *output, int channels, int frames, float epsilon)
static size_t audio_fastconformer_block_workspace_bytes_for_score_slots(int frames, int hidden_size, int intermediate_size, int heads, size_t score_slots)
size_t audio_fastconformer_subsampling_workspace_bytes(int feature_frames, int feature_channels, int conv_channels, int kernel_size, int stride)
static void relu_subsampling_inplace(float *value, size_t elements)
static uint16_t read_u16_le(const uint8_t *p)
static int reflect_index(int index, int length)
int audio_preemphasis_f32(const float *input, float *output, int frames, float coefficient)
int audio_scaled_residual_add_f32(const float *residual, const float *branch, float scale, float *output, size_t elements)
int audio_relative_shift_f32(const float *raw_scores, float *scores, int heads, int query_frames)
int audio_argmax_first_f32(const float *values, int elements, int *selected)
int audio_whisper_stft_power_reference_f32(const float *samples, int n_samples, float *power, int n_frames)
int audio_stft_power_centered_window_f32(const float *samples, int n_samples, const float *window, int window_length, const float *cos_table, const float *sin_table, int n_fft, int hop_length, int reflect_padding, float *power, int n_frames)
int audio_stft_precompute_tables_f32(int n_fft, float *window, float *cos_table, float *sin_table)
static void audio_stft_power_fft400_frame_f32(const float *samples, int n_samples, int frame, const float *window, const float *cos_table, const float *sin_table, float *power, float *fft_scratch)
static int conv_output_extent(int input, int kernel, int stride, int padding)
static void ck_audio_conformer_relative_attention_f32_row_range(int begin, int end, void *opaque)
int audio_fastconformer_block_f32(const float *input, const float *relative_positions, const float *ff1_norm_weight, const float *ff1_norm_bias, const float *ff1_up_weight, const float *ff1_up_bias, const float *ff1_down_weight, const float *ff1_down_bias, const float *attn_norm_weight, const float *attn_norm_bias, const float *q_weight, const float *q_bias, const float *k_weight, const float *k_bias, const float *v_weight, const float *v_bias, const float *relative_weight, const float *attn_bias_u, const float *attn_bias_v, const float *attn_out_weight, const float *attn_out_bias, const float *conv_norm_weight, const float *conv_norm_bias, const float *conv_pw1_weight, const float *conv_pw1_bias, const float *conv_dw_weight, const float *conv_dw_bias, const float *conv_bn_mean, const float *conv_bn_variance, const float *conv_bn_weight, const float *conv_bn_bias, const float *conv_pw2_weight, const float *conv_pw2_bias, const float *ff2_norm_weight, const float *ff2_norm_bias, const float *ff2_up_weight, const float *ff2_up_bias, const float *ff2_down_weight, const float *ff2_down_bias, const float *out_norm_weight, const float *out_norm_bias, float *output, void *workspace, size_t workspace_bytes, int frames, int hidden_size, int intermediate_size, int heads, int head_dim, int conv_kernel_size, float layer_norm_epsilon, float batch_norm_epsilon)
static double audio_hz_to_mel_slaney(double hz)
int audio_glu_split_channel_major_f32(const float *input, float *output, int channels, int frames)
static void ck_audio_conv1d_channel_major_f32_work(int ith, int nth, void *opaque)
int audio_conformer_relative_attention_f32(const float *query, const float *key, const float *value, const float *relative_key, const float *bias_u, const float *bias_v, float *output, int frames, int heads, int head_dim, float scale, float *scores_scratch, size_t scores_scratch_bytes)
void gemm_nt_f32_llama_production_parallel_dispatch(const float *A, const float *B, const float *bias, float *C, int M, int N, int K)
int audio_pcm_s16_to_mono_f32(const int16_t *interleaved, int n_frames, int n_channels, float *mono)
static int checked_add_size(size_t left, size_t right, size_t *result)
int audio_transpose_channel_to_token_f32(const float *input, float *output, int channels, int frames)
static double audio_mel_to_hz_slaney(double mel)
static void zero_subsampling_padding(float *value, int channels, int frames, int width, int live_frames)
int audio_fastconformer_subsampling_f32(const float *features, const float *conv0_weight, const float *conv0_bias, const float *depthwise1_weight, const float *depthwise1_bias, const float *pointwise1_weight, const float *pointwise1_bias, const float *depthwise2_weight, const float *depthwise2_bias, const float *pointwise2_weight, const float *pointwise2_bias, const float *linear_weight, const float *linear_bias, float *output, void *workspace, size_t workspace_bytes, int feature_frames, int live_frames, int feature_channels, int conv_channels, int hidden_size, int kernel_size, int stride, int output_capacity_frames, int *output_frames)
int audio_whisper_log_mel_from_power_reference_f32(const float *power, const float *mel_filters, int n_mels, int n_frames, float *log_mel)
size_t audio_fastconformer_block_workspace_bytes(int frames, int hidden_size, int intermediate_size, int heads)
int audio_feature_normalize_per_feature_f32(const float *input, float *output, int channels, int frames, float epsilon)
static uint32_t read_u32_le(const uint8_t *p)
int audio_pad_or_truncate_f32(const float *input, int input_frames, float *output, int output_frames)
static int checked_mul_size(size_t left, size_t right, size_t *result)
int audio_conv1d_channel_major_f32(const float *input, const float *weight, const float *bias, float *output, int input_channels, int output_channels, int input_frames, int kernel_size, int stride, int padding, int output_frames)
int audio_resample_windowed_sinc_f32(const float *input, int input_frames, int input_rate, float *output, int output_frames, int output_rate, int radius)
int audio_relative_sinusoidal_position_f32(float *output, int frames, int channels)
int audio_hann_window_f32(float *output, int frames, int periodic)
int audio_wav_decode_memory_pcm16_mono_window_f32(const uint8_t *bytes, size_t byte_count, int start_frame, float *mono, int mono_capacity, CKAudioWavInfo *info)
int audio_stft_power_fft400_f32(const float *samples, int n_samples, const float *window, const float *cos_table, const float *sin_table, int hop_length, float *power, int n_frames, float *fft_scratch)
static void ck_audio_glu_split_f32_range(int begin, int end, void *opaque)
int audio_resampled_frame_count(int input_frames, int input_rate, int output_rate)
static void ck_audio_conv2d_whc_grouped_f32_range(int begin, int end, void *opaque)
int audio_wav_decode_memory_pcm16_mono_f32(const uint8_t *bytes, size_t byte_count, float *mono, int mono_capacity, CKAudioWavInfo *info)
Persistent pthread thread pool for CK-Engine inference.
void ck_threadpool_parallel_for_n(ck_threadpool_t *pool, int active_threads, int begin, int end, int grain_size, ck_range_fn_t fn, void *args)
void ck_threadpool_dispatch_n(ck_threadpool_t *pool, int active_threads, ck_work_fn_t fn, void *args)
ck_threadpool_t * ck_threadpool_global(void)
int ck_threadpool_thread_id(const ck_threadpool_t *pool)
int ck_threadpool_n_threads(const ck_threadpool_t *pool)
#define CK_AUDIO_WHISPER_N_FFT
#define CK_AUDIO_WHISPER_HOP_LENGTH
#define CK_AUDIO_WHISPER_SAMPLE_RATE
#define CK_AUDIO_WHISPER_POWER_BINS
const char const char * right