32 const float *input,
size_t input_elements,
33 const float *weight_ih,
size_t weight_ih_elements,
34 const float *weight_hh,
size_t weight_hh_elements,
35 const float *bias_ih,
size_t bias_ih_elements,
36 const float *bias_hh,
size_t bias_hh_elements,
37 float *output,
size_t output_elements,
38 float *hidden_state,
size_t hidden_state_elements,
39 float *cell_state,
size_t cell_state_elements,
40 float *gates_scratch,
size_t gates_scratch_bytes,
41 int tokens,
int input_size,
int hidden_size,
42 size_t input_stride,
size_t output_stride)
44 if (input == NULL || weight_ih == NULL || weight_hh == NULL ||
45 bias_ih == NULL || bias_hh == NULL || output == NULL ||
46 hidden_state == NULL || cell_state == NULL || gates_scratch == NULL) {
49 if (tokens <= 0 || input_size <= 0 || hidden_size <= 0 ||
50 hidden_size > INT_MAX / 4) {
54 const size_t token_count = (size_t)tokens;
55 const size_t input_width = (size_t)input_size;
56 const size_t hidden_width = (size_t)hidden_size;
57 const size_t output_width = hidden_width * 2u;
58 size_t input_required, output_required, gates_count;
59 size_t ih_per_direction, hh_per_direction, bias_required;
60 size_t ih_required, hh_required, gates_bytes, state_bytes;
61 if (input_stride < input_width || output_stride < output_width ||
62 !
checked_span(token_count, input_stride, input_width, &input_required) ||
63 !
checked_span(token_count, output_stride, output_width, &output_required) ||
74 if (input_elements < input_required || output_elements < output_required ||
75 weight_ih_elements < ih_required || weight_hh_elements < hh_required ||
76 bias_ih_elements < bias_required || bias_hh_elements < bias_required ||
77 hidden_state_elements < output_width ||
78 cell_state_elements < output_width ||
79 gates_scratch_bytes < gates_bytes) {
86 memset(hidden_state, 0, state_bytes);
87 memset(cell_state, 0, state_bytes);
88 for (
size_t index = 0u; index < token_count; ++index) {
90 input + index * input_stride,
91 weight_ih, weight_hh, bias_ih, bias_hh,
92 hidden_state, cell_state,
93 output + index * output_stride,
94 gates_scratch, gates_scratch_bytes, input_size, hidden_size);
99 for (
size_t reverse_index = 0u; reverse_index < token_count;
101 const size_t index = token_count - 1u - reverse_index;
103 input + index * input_stride,
104 weight_ih + ih_per_direction,
105 weight_hh + hh_per_direction,
106 bias_ih + gates_count,
107 bias_hh + gates_count,
108 hidden_state + hidden_width,
109 cell_state + hidden_width,
110 output + index * output_stride + hidden_width,
111 gates_scratch, gates_scratch_bytes, input_size, hidden_size);
int audio_lstm_bidirectional_scan_f32(const float *input, size_t input_elements, const float *weight_ih, size_t weight_ih_elements, const float *weight_hh, size_t weight_hh_elements, const float *bias_ih, size_t bias_ih_elements, const float *bias_hh, size_t bias_hh_elements, float *output, size_t output_elements, float *hidden_state, size_t hidden_state_elements, float *cell_state, size_t cell_state_elements, float *gates_scratch, size_t gates_scratch_bytes, int tokens, int input_size, int hidden_size, size_t input_stride, size_t output_stride)
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)