TfLiteStatus EvalFloat(const TfLiteTensor* input,
                       const TfLiteTensor* input_weights,
                       const TfLiteTensor* recurrent_weights,
                       const TfLiteTensor* bias,
                       const TfLiteSequenceRNNParams* params,
                       TfLiteTensor* hidden_state, TfLiteTensor* output) {
  // Initialize the pointer bias.
  const float* bias_ptr = GetTensorData<float>(bias);

  const bool time_major = params->time_major;
  const int batch_size =
      (time_major) ? input->dims->data[1] : input->dims->data[0];
  const int max_time =
      (time_major) ? input->dims->data[0] : input->dims->data[1];
  const int num_units = input_weights->dims->data[0];
  const int input_size = input->dims->data[2];

  // Initialize input_weights and recurrent_weights.
  const float* input_weights_ptr = GetTensorData<float>(input_weights);
  const float* recurrent_weights_ptr = GetTensorData<float>(recurrent_weights);

  if (time_major) {
    // Initialize the pointer to hidden state.
    float* hidden_state_ptr_batch = GetTensorData<float>(hidden_state);
    // Unroll the sequence and use batch operations for efficiency.
    for (int s = 0; s < max_time; s++) {
      // Initialize the pointer to input and output.
      const float* input_ptr_batch =
          GetTensorData<float>(input) + s * input_size * batch_size;
      float* output_ptr_batch =
          GetTensorData<float>(output) + s * num_units * batch_size;

      kernel_utils::RnnBatchStep(
          input_ptr_batch, input_weights_ptr, recurrent_weights_ptr, bias_ptr,
          input_size, num_units, batch_size, num_units, params->activation,
          hidden_state_ptr_batch, output_ptr_batch);
    }
  } else {
    // For each batch
    for (int b = 0; b < batch_size; b++) {
      // Initialize the pointer to hidden state.
      float* hidden_state_ptr_batch =
          GetTensorData<float>(hidden_state) + b * num_units;
      for (int s = 0; s < max_time; s++) {
        // Initialize the pointer to input and output.
        const float* input_ptr_batch = GetTensorData<float>(input) +
                                       b * input_size * max_time +
                                       s * input_size;
        float* output_ptr_batch = GetTensorData<float>(output) +
                                  b * num_units * max_time + s * num_units;

        kernel_utils::RnnBatchStep(
            input_ptr_batch, input_weights_ptr, recurrent_weights_ptr, bias_ptr,
            input_size, num_units, /*batch_size=*/1, num_units,
            params->activation, hidden_state_ptr_batch, output_ptr_batch);
      }
    }
  }
  return kTfLiteOk;
}
TfLiteStatus EvalFloat(const TfLiteTensor* input,
                       const TfLiteTensor* input_weights,
                       const TfLiteTensor* recurrent_weights,
                       const TfLiteTensor* bias,
                       const TfLiteSequenceRNNParams* params,
                       TfLiteTensor* hidden_state, TfLiteTensor* output) {
   
  const float* bias_ptr = GetTensorData<float>(bias);

  const bool time_major = params->time_major;
  const int batch_size =
      (time_major) ? input->dims->data[1] : input->dims->data[0];
  const int max_time =
      (time_major) ? input->dims->data[0] : input->dims->data[1];
  const int num_units = input_weights->dims->data[0];
  const int input_size = input->dims->data[2];

   
  const float* input_weights_ptr = GetTensorData<float>(input_weights);
  const float* recurrent_weights_ptr = GetTensorData<float>(recurrent_weights);

  if (time_major) {
     
    float* hidden_state_ptr_batch = GetTensorData<float>(hidden_state);
     
    for (int s = 0; s < max_time; s++) {
       
      const float* input_ptr_batch =
          GetTensorData<float>(input) + s * input_size * batch_size;
      float* output_ptr_batch =
          GetTensorData<float>(output) + s * num_units * batch_size;

      kernel_utils::RnnBatchStep(
          input_ptr_batch, input_weights_ptr, recurrent_weights_ptr, bias_ptr,
          input_size, num_units, batch_size, num_units, params->activation,
          hidden_state_ptr_batch, output_ptr_batch);
    }
  } else {
     
    for (int b = 0; b < batch_size; b++) {
       
      float* hidden_state_ptr_batch =
          GetTensorData<float>(hidden_state) + b * num_units;
      for (int s = 0; s < max_time; s++) {
         
        const float* input_ptr_batch = GetTensorData<float>(input) +
                                       b * input_size * max_time +
                                       s * input_size;
        float* output_ptr_batch = GetTensorData<float>(output) +
                                  b * num_units * max_time + s * num_units;

        kernel_utils::RnnBatchStep(
            input_ptr_batch, input_weights_ptr, recurrent_weights_ptr, bias_ptr,
            input_size, num_units,  1, num_units,
            params->activation, hidden_state_ptr_batch, output_ptr_batch);
      }
    }
  }
  return kTfLiteOk;
}