| 216 | } |
| 217 | |
| 218 | LSTMCellOutputs LSTMCellModule::build( |
| 219 | core::ModuleBuildContext & ctx, |
| 220 | const core::TensorValue & input, |
| 221 | const core::TensorValue & hidden, |
| 222 | const core::TensorValue & cell, |
| 223 | const LSTMCellWeights & weights) const { |
| 224 | if (ctx.ggml == nullptr) { |
| 225 | throw std::runtime_error("ModuleBuildContext.ggml is null"); |
| 226 | } |
| 227 | core::validate_rank_between(input, 2, 2, "input"); |
| 228 | core::validate_shape(hidden, core::TensorShape::from_dims({input.shape.dims[0], config_.hidden_size}), "hidden"); |
| 229 | core::validate_shape(cell, core::TensorShape::from_dims({input.shape.dims[0], config_.hidden_size}), "cell"); |
| 230 | core::validate_shape(input, core::TensorShape::from_dims({input.shape.dims[0], config_.input_size}), "input"); |
| 231 | validate_weight_shapes(config_, weights); |
| 232 | |
| 233 | const int64_t gates = 4 * config_.hidden_size; |
| 234 | const auto projected_input = LinearModule({config_.input_size, gates, true}).build( |
| 235 | ctx, |
| 236 | input, |
| 237 | {weights.weight_ih, weights.bias_ih}); |
| 238 | return build_lstm_cell_from_projected_input(ctx, config_, projected_input, hidden, cell, weights); |
| 239 | } |
| 240 | |
| 241 | const core::ModuleSchema & LSTMCellModule::static_schema() noexcept { |
| 242 | return kLstmSchema; |
no test coverage detected