| 152 | } |
| 153 | |
| 154 | LSTMSequenceOutputs build_lstm_sequence( |
| 155 | core::ModuleBuildContext & ctx, |
| 156 | const LSTMSequenceConfig & config, |
| 157 | const core::TensorValue & input, |
| 158 | const core::TensorValue & initial_hidden, |
| 159 | const core::TensorValue & initial_cell, |
| 160 | const LSTMCellWeights & weights) { |
| 161 | if (ctx.ggml == nullptr) { |
| 162 | throw std::runtime_error("ModuleBuildContext.ggml is null"); |
| 163 | } |
| 164 | core::validate_shape(input, core::TensorShape::from_dims({input.shape.dims[0], config.input_size}), "input"); |
| 165 | core::validate_shape(initial_hidden, core::TensorShape::from_dims({1, config.hidden_size}), "initial_hidden"); |
| 166 | core::validate_shape(initial_cell, core::TensorShape::from_dims({1, config.hidden_size}), "initial_cell"); |
| 167 | validate_weight_shapes({config.input_size, config.hidden_size}, weights); |
| 168 | |
| 169 | const int64_t frames = input.shape.dims[0]; |
| 170 | const int64_t gates = 4 * config.hidden_size; |
| 171 | const auto projected_inputs = LinearModule({config.input_size, gates, true}).build( |
| 172 | ctx, |
| 173 | input, |
| 174 | {weights.weight_ih, weights.bias_ih}); |
| 175 | std::vector<core::TensorValue> steps(static_cast<size_t>(frames)); |
| 176 | auto hidden = initial_hidden; |
| 177 | auto cell = initial_cell; |
| 178 | const ConcatModule concat_rows({0}); |
| 179 | |
| 180 | for (int64_t step = 0; step < frames; ++step) { |
| 181 | const int64_t t = config.reverse ? (frames - 1 - step) : step; |
| 182 | const auto projected_x_t = SliceModule({0, t, 1}).build(ctx, projected_inputs); |
| 183 | const auto outputs = build_lstm_cell_from_projected_input( |
| 184 | ctx, |
| 185 | {config.input_size, config.hidden_size}, |
| 186 | projected_x_t, |
| 187 | hidden, |
| 188 | cell, |
| 189 | weights); |
| 190 | hidden = outputs.hidden; |
| 191 | cell = outputs.cell; |
| 192 | steps[static_cast<size_t>(t)] = hidden; |
| 193 | } |
| 194 | |
| 195 | auto sequence = steps[0]; |
| 196 | for (int64_t t = 1; t < frames; ++t) { |
| 197 | sequence = concat_rows.build(ctx, sequence, steps[static_cast<size_t>(t)]); |
| 198 | } |
| 199 | return LSTMSequenceOutputs{sequence, hidden, cell}; |
| 200 | } |
| 201 | |
| 202 | } // namespace |
| 203 |
no test coverage detected