Resize the output and scratch tensors based on the sizes of the input tensors. Also check that the size of the input tensors match each other.
| 389 | // Resize the output and scratch tensors based on the sizes of the input |
| 390 | // tensors. Also check that the size of the input tensors match each other. |
| 391 | TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { |
| 392 | int* scratch_tensor_index = reinterpret_cast<int*>(node->user_data); |
| 393 | const auto* params = reinterpret_cast<TfLiteBidirectionalSequenceLSTMParams*>( |
| 394 | node->builtin_data); |
| 395 | |
| 396 | // Check we have all the inputs and outputs we need. |
| 397 | TF_LITE_ENSURE_EQ(context, node->inputs->size, 48); |
| 398 | TF_LITE_ENSURE_EQ(context, node->outputs->size, |
| 399 | params->merge_outputs ? 1 : 2); |
| 400 | |
| 401 | // Inferring batch size, number of outputs and sequence length and |
| 402 | // number of cells from the input tensors. |
| 403 | const TfLiteTensor* input = GetInput(context, node, kInputTensor); |
| 404 | TF_LITE_ENSURE_EQ(context, input->type, kTfLiteFloat32); |
| 405 | TF_LITE_ENSURE_EQ(context, input->dims->size, 3); |
| 406 | const bool time_major = params->time_major; |
| 407 | const int max_time = time_major ? input->dims->data[0] : input->dims->data[1]; |
| 408 | const int n_batch = time_major ? input->dims->data[1] : input->dims->data[0]; |
| 409 | const int n_input = input->dims->data[2]; |
| 410 | |
| 411 | const TfLiteTensor* fw_input_to_output_weights = |
| 412 | GetInput(context, node, kFwInputToOutputWeightsTensor); |
| 413 | const int n_fw_cell = fw_input_to_output_weights->dims->data[0]; |
| 414 | TF_LITE_ENSURE_EQ(context, fw_input_to_output_weights->dims->size, 2); |
| 415 | TF_LITE_ENSURE_EQ(context, fw_input_to_output_weights->dims->data[1], |
| 416 | n_input); |
| 417 | |
| 418 | const TfLiteTensor* bw_input_to_output_weights = |
| 419 | GetInput(context, node, kBwInputToOutputWeightsTensor); |
| 420 | const int n_bw_cell = bw_input_to_output_weights->dims->data[0]; |
| 421 | TF_LITE_ENSURE_EQ(context, bw_input_to_output_weights->dims->size, 2); |
| 422 | TF_LITE_ENSURE_EQ(context, bw_input_to_output_weights->dims->data[1], |
| 423 | n_input); |
| 424 | TF_LITE_ENSURE_EQ(context, bw_input_to_output_weights->type, |
| 425 | fw_input_to_output_weights->type); |
| 426 | |
| 427 | const TfLiteTensor* fw_recurrent_to_output_weights = |
| 428 | GetInput(context, node, kFwRecurrentToOutputWeightsTensor); |
| 429 | TF_LITE_ENSURE_EQ(context, fw_recurrent_to_output_weights->dims->size, 2); |
| 430 | TF_LITE_ENSURE_EQ(context, fw_recurrent_to_output_weights->dims->data[0], |
| 431 | n_fw_cell); |
| 432 | TF_LITE_ENSURE_EQ(context, fw_recurrent_to_output_weights->type, |
| 433 | fw_input_to_output_weights->type); |
| 434 | const int n_fw_output = fw_recurrent_to_output_weights->dims->data[1]; |
| 435 | |
| 436 | const TfLiteTensor* bw_recurrent_to_output_weights = |
| 437 | GetInput(context, node, kBwRecurrentToOutputWeightsTensor); |
| 438 | TF_LITE_ENSURE_EQ(context, bw_recurrent_to_output_weights->dims->size, 2); |
| 439 | TF_LITE_ENSURE_EQ(context, bw_recurrent_to_output_weights->dims->data[0], |
| 440 | n_bw_cell); |
| 441 | TF_LITE_ENSURE_EQ(context, bw_recurrent_to_output_weights->type, |
| 442 | fw_input_to_output_weights->type); |
| 443 | const int n_bw_output = bw_recurrent_to_output_weights->dims->data[1]; |
| 444 | |
| 445 | // Check that input tensor dimensions matches with each other. |
| 446 | TF_LITE_ENSURE_OK( |
| 447 | context, CheckInputTensorDimensions(context, node, n_input, n_fw_output, |
| 448 | n_fw_cell)); |
nothing calls this directly
no test coverage detected