// SPDX-License-Identifier: Apache-2.0
/*
 * Copyright IBM Corp. 2021, 2024
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "testsupport.h"

void setUp(void) {
  VERIFY_HW_ENV;
  tol_bfloat.ulps = MAX_ULPS_BFLOAT;
  tol_bfloat.epsilon_mult = MAX_EPSILON_MULT_BFLOAT;

  tol_fp16.ulps = MAX_ULPS_FP16;
  tol_fp16.epsilon_mult = MAX_EPSILON_MULT_FP16;

  if (is_query_parmblock_installed(NNPA_PARMBLKFORMAT_1)) {
    // note: gru_bidir_to_bidir (FP32) needs custom tolerance
    tol_fp32.ulps = MAX_ULPS_FLOAT;
    tol_fp32.epsilon_mult = (0.003 / EPSILON_FLOAT) + 1;
  } else { // set default tol values
    tol_fp32.ulps = MAX_ULPS_FLOAT;
    tol_fp32.epsilon_mult = MAX_EPSILON_MULT_FLOAT;
  }
}

void tearDown(void) {}

zdnn_ztensor *test_layer(zdnn_ztensor *input, uint32_t *h0_shape,
                         void *h0_values, uint32_t *weights_shape,
                         void *weights_values, uint32_t *biases_shape,
                         void *biases_values, uint32_t *hidden_weights_shape,
                         void *hidden_weights_values,
                         uint32_t *hidden_biases_shape,
                         void *hidden_biases_values, uint32_t *all_ts_out_shape,
                         void *all_ts_out_exp_values, bool is_prev_layer_bidir,
                         bool is_this_layer_bidir) {

  zdnn_ztensor *h0, *weights, *biases, *hidden_weights, *hidden_biases,
      *all_ts_out;

  h0 = alloc_ztensor_with_values(h0_shape, ZDNN_3DS, test_datatype, NO_CONCAT,
                                 false, (float *)h0_values);

  // FICO/ZRH elements coming in as one pointer instead of four or three
  // pointers

  uint32_t num_elements_weights =
      weights_shape[0] * weights_shape[1] * weights_shape[2];
  weights = alloc_ztensor_with_values(
      weights_shape, ZDNN_3DS, test_datatype,
      RNN_TYPE_GRU | (is_prev_layer_bidir ? PREV_LAYER_BIDIR : PREV_LAYER_UNI) |
          USAGE_WEIGHTS,
      false, (float *)weights_values,
      (float *)weights_values + num_elements_weights,
      (float *)weights_values + 2 * num_elements_weights);

  uint32_t num_elements_biases = biases_shape[0] * biases_shape[1];
  biases = alloc_ztensor_with_values(
      biases_shape, ZDNN_2DS, test_datatype, RNN_TYPE_GRU | USAGE_BIASES, false,
      (float *)biases_values, (float *)biases_values + num_elements_biases,
      (float *)biases_values + 2 * num_elements_biases);

  uint32_t num_elements_hidden_weights = hidden_weights_shape[0] *
                                         hidden_weights_shape[1] *
                                         hidden_weights_shape[2];
  hidden_weights = alloc_ztensor_with_values(
      hidden_weights_shape, ZDNN_3DS, test_datatype,
      RNN_TYPE_GRU | USAGE_HIDDEN_WEIGHTS, false,
      (float *)hidden_weights_values,
      (float *)hidden_weights_values + num_elements_hidden_weights,
      (float *)hidden_weights_values + 2 * num_elements_hidden_weights);

  uint32_t num_elements_hidden_biases =
      hidden_biases_shape[0] * hidden_biases_shape[1];
  hidden_biases = alloc_ztensor_with_values(
      hidden_biases_shape, ZDNN_2DS, test_datatype,
      RNN_TYPE_GRU | USAGE_HIDDEN_BIASES, false, (float *)hidden_biases_values,
      (float *)hidden_biases_values + num_elements_hidden_biases,
      (float *)hidden_biases_values + 2 * num_elements_hidden_biases);

  all_ts_out = alloc_ztensor_with_values(
      all_ts_out_shape, ZDNN_4DS, test_datatype, NO_CONCAT, true, ZERO_ARRAY);

  zdnn_status status =
      zdnn_gru(input, h0, weights, biases, hidden_weights, hidden_biases,
               is_this_layer_bidir ? BIDIR : FWD, NULL, all_ts_out);

  if (status != ZDNN_OK) {
    TEST_FAIL_MESSAGE_FORMATTED("%s() - zdnn_gru() not ZDNN_OK, status = %08x",
                                __func__, status);
  }

  // To allow for unique tolerance
  fp_tolerance *tol = NULL;
  switch (all_ts_out->pre_transformed_desc->type) {
  case BFLOAT:
    tol = &tol_bfloat;
    break;
  case FP16:
    tol = &tol_fp16;
    break;
  case FP32:
    tol = &tol_fp32;
    break;
  default:
    break;
    // should never get here
  }
  assert_ztensor_values_adv(all_ts_out, false, all_ts_out_exp_values, *tol);

  free_ztensor_buffers(5, h0, weights, biases, hidden_weights, hidden_biases);

  return all_ts_out;
}

void gru_fwd_to_fwd() {

  // num_timesteps = 5
  // num_batches = 2
  // num_features = 4
  // num_hidden = 4, 5

  bool is_layer_bidir[] = {false, false};

  // first layer

  uint32_t input0_shape[] = {5, 2, 4};
  uint32_t input0_values[] = {
      0x3f80f554, 0x3eed5744, 0x3fe9598b, 0x3fde3340, 0x3fb14cbd, 0x3f3b5a0a,
      0x3f82893d, 0x3e5414c8, 0x3f8b5bf7, 0x3f3c425a, 0x3fa6aeeb, 0x3f99290e,
      0x3ffa48dc, 0x3fd4c5a9, 0x3fb4c3ba, 0x3f768450, 0x3f1acb50, 0x3eccc9d0,
      0x3fd6c6c6, 0x3fb7bd3f, 0x3f230434, 0x3e2daec8, 0x3f9a57a9, 0x3e80dd48,
      0x3f94a1a8, 0x3f64e95e, 0x3dc195b0, 0x3ff6bde7, 0x3fd094b3, 0x3fa067b8,
      0x3fb1e4f7, 0x3e0b4360, 0x3fd2f78d, 0x3fbaec30, 0x3fd96d0d, 0x3ff7e13b,
      0x3fcab802, 0x3e0fc588, 0x3f0dc4a2, 0x3f03ec80};
  uint32_t h00_shape[] = {1, 2, 4};
  uint32_t h00_values[] = {0x3f72895c, 0x3fc19f9d, 0x3f54b050, 0x3ff7834f,
                           0x3fdc7d0d, 0x3fc1fce3, 0x3ebcf5b4, 0x3ed3cdb4};
  uint32_t weights0_shape[] = {1, 4, 4};
  uint32_t weights0_values[] = {
      0x3e8c896e, 0x3e9ed100, 0x3e493898, 0x3dcbca78, 0xbd813f20, 0x3ef5cf48,
      0x3ed41bd0, 0xbede9cf8, 0x3c9c6440, 0xbec54796, 0x3edec5e8, 0x3d3c6690,
      0x3ded4400, 0xbe3ba1ec, 0x3ee1e222, 0xbea027ac, 0xbe6311c8, 0x3e4b3424,
      0x3dbed0f8, 0x3e67aa8c, 0xbc93cb20, 0x3d8a55c8, 0xbec67a6c, 0x3e4de7f8,
      0x3ea3ba40, 0x3eaba4fe, 0xbeb16e18, 0xbe97a46a, 0x3efe7f82, 0xbe96bbc0,
      0xbe843ed2, 0x3e1aadc8, 0xbeee948c, 0x3dbfaa08, 0x3e44e48c, 0x3eb7435c,
      0x3ee3743e, 0xbdac80c8, 0xbe97a134, 0x3e3f7148, 0x3ec2a6f0, 0xbda882b8,
      0x3e3bb1dc, 0xbefd5f4a, 0xbeff5dfe, 0xbe6a5f1c, 0x3e817616, 0xbea61100};
  uint32_t biases0_shape[] = {1, 4};
  uint32_t biases0_values[] = {0xbe7e7cdc, 0xbec42d02, 0xbeef9400, 0xbed810ec,
                               0xbee5f866, 0xbe72ba40, 0x3eae4fce, 0xbb546b00,
                               0xbdcfb470, 0x3e8c6456, 0x3e8a6774, 0xbef6e502};
  uint32_t hidden_weights0_shape[] = {1, 4, 4};
  uint32_t hidden_weights0_values[] = {
      0xbe9bc938, 0xbdfedb88, 0x3e48ec5c, 0xbef59156, 0x3ee84968, 0x3cb8d280,
      0x3cf559e0, 0xbe97bba0, 0x3eaf6fd0, 0x3d956718, 0xbe79d1cc, 0xbe002b3c,
      0xbed7e164, 0x3df2ddd0, 0x3e7245d4, 0xbe7966ec, 0x3e7fa638, 0x3ef0d4f2,
      0xbef3dd78, 0xbce1b020, 0x3dd65318, 0x3eac7f54, 0xbc133e80, 0x3d99bfa0,
      0xbec7b396, 0xbe5f3eb0, 0xbec0c878, 0xbe51adf4, 0xbe9368e8, 0xbe00dcd4,
      0xbec577a2, 0x3e97e798, 0xbe331d5c, 0xbea6c676, 0x3c63ac80, 0x3ef27eba,
      0xbed1d2ba, 0xbcd23440, 0xbd30adc0, 0x3ea29306, 0xbdd9d200, 0x3eb74200,
      0x3dcf3d10, 0x3ef30cc4, 0x3ddae2f8, 0xbd5288f0, 0x3ea2c660, 0xbd141d60};
  uint32_t hidden_biases0_shape[] = {1, 4};
  uint32_t hidden_biases0_values[] = {
      0xbdc53cf0, 0xbdc90e10, 0xbee5b8ba, 0xbedd0a44, 0x3e9fb02e, 0xbec8528a,
      0xbdd87bf0, 0xbe4f9a1c, 0xbda03c28, 0x3bd3e180, 0xbe6896b8, 0x3e40deb8};
  uint32_t all_ts_out0_shape[] = {5, 1, 2, 4};
  uint32_t all_ts_out0_exp_values[] = {
      0x3dbbe338, 0x3e91c6be, 0x3f53d36d, 0xbee51fe8, 0x3f248241, 0x3f14fbd0,
      0x3ed3b798, 0x3ed452e7, 0xbdfe4e88, 0x3e12cda1, 0x3f3e34b7, 0xbf103a51,
      0x3e33cc72, 0x3e93fd0d, 0x3ee42df8, 0x3d790f32, 0xbe6f1ec6, 0x3c36a710,
      0x3f380cab, 0xbf4b6960, 0x3ce736e8, 0x3e6fd98a, 0x3ef5e203, 0xbedb0b88,
      0xbedb1a27, 0xbc8798ec, 0x3f1fe987, 0xbecfbd8c, 0x3cd23b72, 0x3e817b76,
      0x3edf4e9e, 0xbe603530, 0xbeee1f9e, 0xbda1fc72, 0x3f24978b, 0xbf2e6ce5,
      0xbe8638b3, 0x3e90d126, 0x3f01ed5f, 0xbdfc585c};

  zdnn_ztensor *input0 =
      alloc_ztensor_with_values(input0_shape, ZDNN_3DS, test_datatype,
                                NO_CONCAT, false, (void *)input0_values);

  zdnn_ztensor *all_ts_out0 = test_layer(
      input0, h00_shape, (void *)h00_values, weights0_shape,
      (void *)weights0_values, biases0_shape, (void *)biases0_values,
      hidden_weights0_shape, (void *)hidden_weights0_values,
      hidden_biases0_shape, (void *)hidden_biases0_values, all_ts_out0_shape,
      (void *)all_ts_out0_exp_values, false, is_layer_bidir[0]);

  // second layer

  uint32_t h01_shape[] = {1, 2, 5};
  uint32_t h01_values[] = {0x3ff3351d, 0x3f88a36c, 0x3df6f2f0, 0x3fb435ce,
                           0x3dc6a650, 0x3f2349e4, 0x3ff383d7, 0x3ebc0f18,
                           0x3f8ec53f, 0x3fb923dc};
  uint32_t weights1_shape[] = {1, 4, 5};
  uint32_t weights1_values[] = {
      0xbe8872c0, 0xbead15e7, 0xbe249da6, 0xbb5a2c80, 0xbb4def80, 0xbc1fdba0,
      0xbe9d3169, 0x3ec122ee, 0xbdb50e24, 0x3d69b920, 0x3c9a1ea0, 0xbe84f4be,
      0x3e2598d4, 0x3d65d3e0, 0xbeb31aa8, 0x3e9399fc, 0x3ea04420, 0x3d67f3b0,
      0xbdd123b0, 0xbe700636, 0x3eb7196c, 0x3ea38344, 0xbddc3fcc, 0x3eb5ccc2,
      0xbea16940, 0xbeb90843, 0x3dffaaa8, 0xbdc09e0c, 0x3e9cab54, 0xbe7c17a9,
      0x3d448f50, 0x3e5c0bbc, 0xbebcb154, 0xbea1834a, 0xbe856c8e, 0xbdbfc268,
      0x3e21ba5c, 0x3e7822c0, 0x3ca36520, 0x3e1c8044, 0x3eb8e4f2, 0x3e256d64,
      0xbea317e4, 0x3ba04b00, 0x3e8c10dc, 0xbeb9d294, 0x3c4f7420, 0xbe01fea6,
      0x3ebcdbe4, 0xbe90c29a, 0xbd0388a0, 0xbec66e3b, 0xbe19a60a, 0x3d64ada0,
      0x3e4d6418, 0x3ee28262, 0x3e62db50, 0xbd87a1dc, 0x3ecd16fc, 0xbea1dc41};
  uint32_t biases1_shape[] = {1, 5};
  uint32_t biases1_values[] = {0x3e3d5c4c, 0x3d0f9250, 0x3d190310, 0x3d64ba10,
                               0xbeb401c3, 0xbe271822, 0x3e2dd3f4, 0x3e987cda,
                               0xbe6f1e1b, 0x3b9084c0, 0x3d0ff4f8, 0x3e9e8ea0,
                               0x3ece54c0, 0x3e86944e, 0x3d757710};
  uint32_t hidden_weights1_shape[] = {1, 5, 5};
  uint32_t hidden_weights1_values[] = {
      0x3eafbdf8, 0x3ebc395c, 0x3dc5e080, 0xbd506310, 0x3eb682ba, 0x3e261b9c,
      0x3df90638, 0xbe807ef0, 0x3e0332e4, 0x3d952498, 0xbe18ef8e, 0xbe58ace5,
      0xbecc25a9, 0x3c696e40, 0x3ebdf640, 0xbdfff1d8, 0xbe574539, 0x3ec8c806,
      0xbe9a126e, 0xbe1985b8, 0x3e074a8c, 0xbed87cba, 0xbe94b2a7, 0xbeb9158a,
      0x3e06e404, 0xbe4216de, 0x3a3bae00, 0x3bc9f900, 0xbe05dde4, 0xbe5bef69,
      0x3e06b148, 0x3e6bc304, 0xbd9bb79c, 0xbe87f0ac, 0xbe98cd9b, 0x3e1735dc,
      0xbedd7037, 0xbe71302b, 0xbe295dd2, 0xbe83e971, 0x3eabc840, 0x3ea58b16,
      0x3d721bf0, 0xbee2f252, 0x3e83a64e, 0xbe136b9a, 0xbebd57dc, 0x3ebd57a4,
      0x3e4eb6e0, 0x3e72843c, 0xbdd1716c, 0xbc172600, 0x3e3b9ae0, 0x3dd306b8,
      0x3e354500, 0xbca2ec60, 0xbdcdfc84, 0xbe19fc78, 0x3db3dd28, 0xbd669538,
      0xbe8b7474, 0xbe8d2560, 0xbe5cf1d4, 0xbeaa02a3, 0xbebbb5a4, 0x3e1ae0c4,
      0x3e9e5868, 0x3da48928, 0x3d987eb0, 0xbd8d3050, 0x3e10c984, 0xbeaa740b,
      0xbe6de235, 0x3e430d88, 0x3e1f0c64};
  uint32_t hidden_biases1_shape[] = {1, 5};
  uint32_t hidden_biases1_values[] = {
      0x3e915990, 0xbe9e462c, 0x3e332b14, 0x3eace9cc, 0x3ee4e29a,
      0x3e55de1c, 0xbe5ec821, 0xbebdbf60, 0xbec4e626, 0x3ee46d12,
      0x3ec83690, 0x3eb165e2, 0xbdd1fa20, 0xbe20b66c, 0x3ebbff92};
  uint32_t all_ts_out1_shape[] = {5, 1, 2, 5};
  uint32_t all_ts_out1_exp_values[] = {
      0x3faed879, 0x3f212916, 0x3e315ac6, 0x3f584762, 0x3e773eca, 0x3f1a0e70,
      0x3f30b93c, 0x3cd3b530, 0x3f55a8be, 0x3f7349dc, 0x3f67b47e, 0x3ea2e278,
      0x3e728624, 0x3f05967e, 0x3eae0ece, 0x3f01eb96, 0x3ed38c5e, 0x3d76c0f6,
      0x3f1f4629, 0x3f31922a, 0x3f018d7e, 0x3db2f8c8, 0x3e962ef5, 0x3e91c9db,
      0x3ed82154, 0x3eab6769, 0x3e736499, 0x3e04e914, 0x3eda874c, 0x3f183a7d,
      0x3e91da9e, 0x3cec7d07, 0x3eaa587e, 0x3e519080, 0x3ed40a7e, 0x3e783466,
      0x3e5bb505, 0x3e2863f0, 0x3eb7d4c3, 0x3efefd82, 0x3daf16aa, 0xbd5aa005,
      0x3eba1ae9, 0x3dcca13b, 0x3edeb73c, 0x3e1b0164, 0x3e316c76, 0x3e5809ce,
      0x3eaea292, 0x3ec931ed};

  zdnn_ztensor *all_ts_out1 = test_layer(
      all_ts_out0, h01_shape, (void *)h01_values, weights1_shape,
      (void *)weights1_values, biases1_shape, (void *)biases1_values,
      hidden_weights1_shape, (void *)hidden_weights1_values,
      hidden_biases1_shape, (void *)hidden_biases1_values, all_ts_out1_shape,
      (void *)all_ts_out1_exp_values, is_layer_bidir[0], is_layer_bidir[1]);

  free_ztensor_buffers(3, input0, all_ts_out0, all_ts_out1);
}

void gru_fwd_to_bidir() {

  // num_timesteps = 5
  // num_batches = 2
  // num_features = 4
  // num_hidden = 4, 5

  bool is_layer_bidir[] = {false, true};

  // first layer

  uint32_t input0_shape[] = {5, 2, 4};
  uint32_t input0_values[] = {
      0x3f80f554, 0x3eed5744, 0x3fe9598b, 0x3fde3340, 0x3fb14cbd, 0x3f3b5a0a,
      0x3f82893d, 0x3e5414c8, 0x3f8b5bf7, 0x3f3c425a, 0x3fa6aeeb, 0x3f99290e,
      0x3ffa48dc, 0x3fd4c5a9, 0x3fb4c3ba, 0x3f768450, 0x3f1acb50, 0x3eccc9d0,
      0x3fd6c6c6, 0x3fb7bd3f, 0x3f230434, 0x3e2daec8, 0x3f9a57a9, 0x3e80dd48,
      0x3f94a1a8, 0x3f64e95e, 0x3dc195b0, 0x3ff6bde7, 0x3fd094b3, 0x3fa067b8,
      0x3fb1e4f7, 0x3e0b4360, 0x3fd2f78d, 0x3fbaec30, 0x3fd96d0d, 0x3ff7e13b,
      0x3fcab802, 0x3e0fc588, 0x3f0dc4a2, 0x3f03ec80};
  uint32_t h00_shape[] = {1, 2, 4};
  uint32_t h00_values[] = {0x3f72895c, 0x3fc19f9d, 0x3f54b050, 0x3ff7834f,
                           0x3fdc7d0d, 0x3fc1fce3, 0x3ebcf5b4, 0x3ed3cdb4};
  uint32_t weights0_shape[] = {1, 4, 4};
  uint32_t weights0_values[] = {
      0x3e8c896e, 0x3e9ed100, 0x3e493898, 0x3dcbca78, 0xbd813f20, 0x3ef5cf48,
      0x3ed41bd0, 0xbede9cf8, 0x3c9c6440, 0xbec54796, 0x3edec5e8, 0x3d3c6690,
      0x3ded4400, 0xbe3ba1ec, 0x3ee1e222, 0xbea027ac, 0xbe6311c8, 0x3e4b3424,
      0x3dbed0f8, 0x3e67aa8c, 0xbc93cb20, 0x3d8a55c8, 0xbec67a6c, 0x3e4de7f8,
      0x3ea3ba40, 0x3eaba4fe, 0xbeb16e18, 0xbe97a46a, 0x3efe7f82, 0xbe96bbc0,
      0xbe843ed2, 0x3e1aadc8, 0xbeee948c, 0x3dbfaa08, 0x3e44e48c, 0x3eb7435c,
      0x3ee3743e, 0xbdac80c8, 0xbe97a134, 0x3e3f7148, 0x3ec2a6f0, 0xbda882b8,
      0x3e3bb1dc, 0xbefd5f4a, 0xbeff5dfe, 0xbe6a5f1c, 0x3e817616, 0xbea61100};
  uint32_t biases0_shape[] = {1, 4};
  uint32_t biases0_values[] = {0xbe7e7cdc, 0xbec42d02, 0xbeef9400, 0xbed810ec,
                               0xbee5f866, 0xbe72ba40, 0x3eae4fce, 0xbb546b00,
                               0xbdcfb470, 0x3e8c6456, 0x3e8a6774, 0xbef6e502};
  uint32_t hidden_weights0_shape[] = {1, 4, 4};
  uint32_t hidden_weights0_values[] = {
      0xbe9bc938, 0xbdfedb88, 0x3e48ec5c, 0xbef59156, 0x3ee84968, 0x3cb8d280,
      0x3cf559e0, 0xbe97bba0, 0x3eaf6fd0, 0x3d956718, 0xbe79d1cc, 0xbe002b3c,
      0xbed7e164, 0x3df2ddd0, 0x3e7245d4, 0xbe7966ec, 0x3e7fa638, 0x3ef0d4f2,
      0xbef3dd78, 0xbce1b020, 0x3dd65318, 0x3eac7f54, 0xbc133e80, 0x3d99bfa0,
      0xbec7b396, 0xbe5f3eb0, 0xbec0c878, 0xbe51adf4, 0xbe9368e8, 0xbe00dcd4,
      0xbec577a2, 0x3e97e798, 0xbe331d5c, 0xbea6c676, 0x3c63ac80, 0x3ef27eba,
      0xbed1d2ba, 0xbcd23440, 0xbd30adc0, 0x3ea29306, 0xbdd9d200, 0x3eb74200,
      0x3dcf3d10, 0x3ef30cc4, 0x3ddae2f8, 0xbd5288f0, 0x3ea2c660, 0xbd141d60};
  uint32_t hidden_biases0_shape[] = {1, 4};
  uint32_t hidden_biases0_values[] = {
      0xbdc53cf0, 0xbdc90e10, 0xbee5b8ba, 0xbedd0a44, 0x3e9fb02e, 0xbec8528a,
      0xbdd87bf0, 0xbe4f9a1c, 0xbda03c28, 0x3bd3e180, 0xbe6896b8, 0x3e40deb8};
  uint32_t all_ts_out0_shape[] = {5, 1, 2, 4};
  uint32_t all_ts_out0_exp_values[] = {
      0x3dbbe338, 0x3e91c6be, 0x3f53d36d, 0xbee51fe8, 0x3f248241, 0x3f14fbd0,
      0x3ed3b798, 0x3ed452e7, 0xbdfe4e88, 0x3e12cda1, 0x3f3e34b7, 0xbf103a51,
      0x3e33cc72, 0x3e93fd0d, 0x3ee42df8, 0x3d790f32, 0xbe6f1ec6, 0x3c36a710,
      0x3f380cab, 0xbf4b6960, 0x3ce736e8, 0x3e6fd98a, 0x3ef5e203, 0xbedb0b88,
      0xbedb1a27, 0xbc8798ec, 0x3f1fe987, 0xbecfbd8c, 0x3cd23b72, 0x3e817b76,
      0x3edf4e9e, 0xbe603530, 0xbeee1f9e, 0xbda1fc72, 0x3f24978b, 0xbf2e6ce5,
      0xbe8638b3, 0x3e90d126, 0x3f01ed5f, 0xbdfc585c};

  zdnn_ztensor *input0 =
      alloc_ztensor_with_values(input0_shape, ZDNN_3DS, test_datatype,
                                NO_CONCAT, false, (void *)input0_values);

  zdnn_ztensor *all_ts_out0 = test_layer(
      input0, h00_shape, (void *)h00_values, weights0_shape,
      (void *)weights0_values, biases0_shape, (void *)biases0_values,
      hidden_weights0_shape, (void *)hidden_weights0_values,
      hidden_biases0_shape, (void *)hidden_biases0_values, all_ts_out0_shape,
      (void *)all_ts_out0_exp_values, false, is_layer_bidir[0]);

  // second layer

  uint32_t h01_shape[] = {2, 2, 5};
  uint32_t h01_values[] = {0x3ff3351d, 0x3f88a36c, 0x3df6f2f0, 0x3fb435ce,
                           0x3dc6a650, 0x3f2349e4, 0x3ff383d7, 0x3ebc0f18,
                           0x3f8ec53f, 0x3fb923dc, 0x3e4d27b0, 0x3fe76faa,
                           0x3f6487aa, 0x3f9acc98, 0x3e925fd4, 0x3f3889fc,
                           0x3f04fd9a, 0x3f259760, 0x3f9ec7e0, 0x3f9aeb4a};
  uint32_t weights1_shape[] = {2, 4, 5};
  uint32_t weights1_values[] = {
      0x3e2598d4, 0x3d65d3e0, 0xbeb31aa8, 0xbd0388a0, 0xbec66e3b, 0x3d67f3b0,
      0xbdd123b0, 0xbe700636, 0x3ee28262, 0x3e62db50, 0xbb5a2c80, 0xbb4def80,
      0x3eb8e4f2, 0x3e256d64, 0xbea317e4, 0xbdb50e24, 0x3d69b920, 0xbeb9d294,
      0x3c4f7420, 0xbe01fea6, 0xbe5f6ed0, 0x3ebb7968, 0xbdea86c4, 0x3ee4e636,
      0x3e5bbc44, 0xbedd358e, 0x3ea3e864, 0x3e497f5c, 0x3e6d851c, 0x3d527bf8,
      0xbe81ffa5, 0x3eb0cbec, 0x3ecbffd4, 0x3e8e5746, 0xbddabb30, 0x3ebc5350,
      0x3ecb999a, 0x3e177f54, 0xbe20471c, 0xbe811315, 0xbebcb154, 0xbea1834a,
      0xbe856c8e, 0x3c9a1ea0, 0xbe84f4be, 0x3e7822c0, 0x3ca36520, 0x3e1c8044,
      0x3e9399fc, 0x3ea04420, 0x3eb5ccc2, 0xbea16940, 0xbe8872c0, 0xbead15e7,
      0xbe249da6, 0x3e9cab54, 0xbe7c17a9, 0xbc1fdba0, 0xbe9d3169, 0x3ec122ee,
      0x3e3248cc, 0x3e5f481c, 0xbee1e40d, 0x3ed6d390, 0xbd93fe10, 0x3da2aec0,
      0xbe9fee66, 0xbeb7e0dd, 0x3eb76f78, 0xbe94b3e4, 0x3e42d780, 0x3dcedbf0,
      0x3eb4c482, 0xbecc7bce, 0x3e9eff90, 0xbe1b9f76, 0xbe9aebe8, 0x3e77c3f8,
      0xbe9c4230, 0xbead1b0c, 0xbe19a60a, 0x3d64ada0, 0x3e4d6418, 0x3e1735dc,
      0x3e6bc304, 0xbd87a1dc, 0x3ecd16fc, 0xbea1dc41, 0x3eabc840, 0xbedd7037,
      0x3ba04b00, 0x3e8c10dc, 0xbe4216de, 0xbe136b9a, 0x3ea58b16, 0x3ebcdbe4,
      0xbe90c29a, 0x3e06b148, 0x3a3bae00, 0xbebd57dc, 0xbe807b12, 0xbd507b08,
      0x3d082a00, 0xbeadd2f6, 0x3e80b7ea, 0xbeb030cc, 0xbe8480f1, 0xbe58367b,
      0x3edb2580, 0xbe8219a4, 0x3e99b77e, 0x3eb0f98a, 0x3ed26ffe, 0x3eade05a,
      0xbd8f889c, 0x3ea2c8c8, 0x3e926d0a, 0x3e3b45e4, 0xbe26eada, 0x3ec26bea};
  uint32_t biases1_shape[] = {2, 5};
  uint32_t biases1_values[] = {
      0x3e55de1c, 0xbe5ec821, 0xbebdbf60, 0xbec4e626, 0x3ee46d12, 0xbea06a9a,
      0x3ec02c1a, 0xbd472b98, 0xbebfde02, 0xbe77c691, 0x3d0ff4f8, 0x3e9e8ea0,
      0x3ece54c0, 0x3e86944e, 0x3d757710, 0x3c6b9ce0, 0xbe0d9648, 0xbdc724ec,
      0x3d737210, 0x3e630230, 0x3e915990, 0xbe9e462c, 0x3e332b14, 0x3eace9cc,
      0x3ee4e29a, 0x3eca9984, 0x3ed16702, 0xbed417e7, 0x3ea17e98, 0x3e658114};
  uint32_t hidden_weights1_shape[] = {2, 5, 5};
  uint32_t hidden_weights1_values[] = {
      0x3dc5e080, 0xbd506310, 0x3eb682ba, 0xbdd1716c, 0xbc172600, 0xbe807ef0,
      0x3e0332e4, 0x3d952498, 0xbca2ec60, 0xbdcdfc84, 0xbecc25a9, 0x3c696e40,
      0x3ebdf640, 0xbe8b7474, 0xbe8d2560, 0x3ec8c806, 0xbe9a126e, 0xbe1985b8,
      0x3e1ae0c4, 0x3e9e5868, 0xbe94b2a7, 0xbeb9158a, 0x3e06e404, 0x3e10c984,
      0xbeaa740b, 0x3e63833c, 0x3e99f81e, 0x3ca711d0, 0x3e675c3c, 0xbeb798f6,
      0xbecfe0c1, 0xbed8b7ed, 0xbece783b, 0xbe972362, 0xbe03b7b6, 0xbedc1c4e,
      0x3ebe51d8, 0x3ebde4ee, 0x3ebf18f2, 0xbee0d2e5, 0xbede7c01, 0xbe37306c,
      0x3e769414, 0x3cc4e590, 0xbe325de8, 0xbdb9cd1c, 0x3e062014, 0x3ee39938,
      0x3e592a78, 0x3dc59638, 0x3bc9f900, 0xbe05dde4, 0xbe5bef69, 0x3eafbdf8,
      0x3ebc395c, 0xbd9bb79c, 0xbe87f0ac, 0xbe98cd9b, 0x3e261b9c, 0x3df90638,
      0xbe71302b, 0xbe295dd2, 0xbe83e971, 0xbe18ef8e, 0xbe58ace5, 0x3d721bf0,
      0xbee2f252, 0x3e83a64e, 0xbdfff1d8, 0xbe574539, 0x3ebd57a4, 0x3e4eb6e0,
      0x3e72843c, 0x3e074a8c, 0xbed87cba, 0x3c976030, 0x3d2f4d98, 0x3e5b9460,
      0xbe436636, 0x3cf049b0, 0xbea1ef22, 0x3ed3c2e8, 0x3e6328f4, 0x3e24fec4,
      0xbe989ba1, 0xbe190f96, 0x3cc42620, 0xbed14480, 0xbea299d4, 0xbe24134e,
      0xbdf89d64, 0xbe8d6097, 0xbda3e468, 0x3e2a3b28, 0x3dc7ff90, 0xbdb0b3c4,
      0x3cbbc620, 0xbeaa2909, 0x3ec258fa, 0xbeae8cee, 0x3e3b9ae0, 0x3dd306b8,
      0x3e354500, 0xbe271822, 0x3e3d5c4c, 0xbe19fc78, 0x3db3dd28, 0xbd669538,
      0x3e2dd3f4, 0x3d0f9250, 0xbe5cf1d4, 0xbeaa02a3, 0xbebbb5a4, 0x3e987cda,
      0x3d190310, 0x3da48928, 0x3d987eb0, 0xbd8d3050, 0xbe6f1e1b, 0x3d64ba10,
      0xbe6de235, 0x3e430d88, 0x3e1f0c64, 0x3b9084c0, 0xbeb401c3, 0xbeb3c7f8,
      0xbeb1870e, 0xbd4e46b0, 0xbe81b1a9, 0x3e6ef9a8, 0x3e11fa20, 0xbe0d48c0,
      0x3e20904c, 0x3e5c50f0, 0xbd3aa670, 0x3e75d434, 0x3e4904fc, 0xbee0a324,
      0xbea1a3c0, 0x3eb037d8, 0x3d7f2f50, 0x3ee1dbc6, 0xbec39102, 0xbe62d375,
      0x3e8db48a, 0xbe9933c8, 0x3e83aa94, 0x3e55ae7c, 0xbebc9a53, 0x3e7d66c4};
  uint32_t hidden_biases1_shape[] = {2, 5};
  uint32_t hidden_biases1_values[] = {
      0x3e804fe0, 0xbe89ca96, 0x3ecdd9da, 0x3e5d42c8, 0x3e79a49c, 0xbe0751fa,
      0x3e1940d8, 0xbe03c1e6, 0x3e8d90bc, 0xbdfe1e6c, 0x3ec83690, 0x3eb165e2,
      0xbdd1fa20, 0xbe20b66c, 0x3ebbff92, 0x3e878898, 0x3ec1d528, 0xbe76cf7f,
      0x3e109bc4, 0x3e3b6830, 0xbe8f83dc, 0x3e036284, 0xbe2089f6, 0x3eb2e8ec,
      0xbda4ce70, 0xbe2ab878, 0x3de69348, 0x3e226e48, 0xbe5fbd62, 0x3d21ed48};
  uint32_t all_ts_out1_shape[] = {5, 2, 2, 5};
  uint32_t all_ts_out1_exp_values[] = {
      0x3fb07596, 0x3f0724ff, 0x3d69c926, 0x3f5b7fa7, 0x3e9f50e4, 0x3e47b948,
      0x3f169176, 0x3e5bd372, 0x3f6ed378, 0x3f48821b, 0x3e88bf42, 0x3f1503cf,
      0xbe228c59, 0x3f0cf024, 0x3d87f2ca, 0x3e298037, 0x3f0cee29, 0xbe29a96c,
      0x3e9dca6b, 0x3ec26071, 0x3f6dcbb8, 0x3ebb0660, 0x3c74d650, 0x3f117062,
      0x3ee3a265, 0x3db18655, 0x3e677394, 0x3db978f5, 0x3f3bbe5a, 0x3f1d1df8,
      0x3e9c2766, 0x3f1e9c69, 0xbe214906, 0x3f0e5d23, 0x3d5ee33f, 0x3e809bf2,
      0x3f0fa73a, 0xbe160d84, 0x3ec20162, 0x3e9546b7, 0x3f0d0270, 0x3ea79919,
      0xbc9908d0, 0x3ed83b4c, 0x3f0a1d62, 0xbba4d360, 0x3e5a624c, 0x3a3d5a00,
      0x3f19d3f1, 0x3f137653, 0x3ea3d178, 0x3f33a091, 0xbdfac5f0, 0x3f118a1b,
      0x3db83b0a, 0x3e44b9c6, 0x3f10e4c8, 0xbdc43ac6, 0x3edf58bb, 0x3e902384,
      0x3ea54086, 0x3e589718, 0xbd23b7e4, 0x3eb6e5d1, 0x3f0c00aa, 0xbd1787d8,
      0x3e2d45a3, 0xbd1be2d7, 0x3f094a68, 0x3f050376, 0x3ef25316, 0x3f66231a,
      0xbbf4ad80, 0x3f1f5c9d, 0x3e57ea78, 0x3e7b6112, 0x3f182175, 0x3da612d0,
      0x3f04cef6, 0x3ee8d645, 0x3e136cf0, 0x3e5768e7, 0xbd873546, 0x3ea25dfa,
      0x3f133a2c, 0xbce72cb2, 0x3e1813fb, 0xbdb1ffc8, 0x3ef86608, 0x3eea8306,
      0x3f02832e, 0x3f97b462, 0x3e814796, 0x3f4e1d12, 0x3e7082c4, 0x3ea66204,
      0x3f147ff7, 0x3ebb4a06, 0x3f477b01, 0x3f2985fa};

  zdnn_ztensor *all_ts_out1 = test_layer(
      all_ts_out0, h01_shape, (void *)h01_values, weights1_shape,
      (void *)weights1_values, biases1_shape, (void *)biases1_values,
      hidden_weights1_shape, (void *)hidden_weights1_values,
      hidden_biases1_shape, (void *)hidden_biases1_values, all_ts_out1_shape,
      (void *)all_ts_out1_exp_values, is_layer_bidir[0], is_layer_bidir[1]);

  free_ztensor_buffers(3, input0, all_ts_out0, all_ts_out1);
}

void gru_bidir_to_bidir() {

  // num_timesteps = 5
  // num_batches = 2
  // num_features = 4
  // num_hidden = 4, 5

  bool is_layer_bidir[] = {true, true};

  // first layer

  uint32_t input0_shape[] = {5, 2, 4};
  uint32_t input0_values[] = {
      0x3f80f554, 0x3eed5744, 0x3fe9598b, 0x3fde3340, 0x3fb14cbd, 0x3f3b5a0a,
      0x3f82893d, 0x3e5414c8, 0x3f8b5bf7, 0x3f3c425a, 0x3fa6aeeb, 0x3f99290e,
      0x3ffa48dc, 0x3fd4c5a9, 0x3fb4c3ba, 0x3f768450, 0x3f1acb50, 0x3eccc9d0,
      0x3fd6c6c6, 0x3fb7bd3f, 0x3f230434, 0x3e2daec8, 0x3f9a57a9, 0x3e80dd48,
      0x3f94a1a8, 0x3f64e95e, 0x3dc195b0, 0x3ff6bde7, 0x3fd094b3, 0x3fa067b8,
      0x3fb1e4f7, 0x3e0b4360, 0x3fd2f78d, 0x3fbaec30, 0x3fd96d0d, 0x3ff7e13b,
      0x3fcab802, 0x3e0fc588, 0x3f0dc4a2, 0x3f03ec80};
  uint32_t h00_shape[] = {2, 2, 4};
  uint32_t h00_values[] = {0x3f72895c, 0x3fc19f9d, 0x3f54b050, 0x3ff7834f,
                           0x3fdc7d0d, 0x3fc1fce3, 0x3ebcf5b4, 0x3ed3cdb4,
                           0x3fb8c472, 0x3f849e59, 0x3eb88b80, 0x3bc03f00,
                           0x3f1a65ee, 0x3f5d6a8e, 0x3ea8b604, 0x3fcb5de0};
  uint32_t weights0_shape[] = {2, 4, 4};
  uint32_t weights0_values[] = {
      0x3e493898, 0x3dcbca78, 0xbeee948c, 0x3dbfaa08, 0x3ed41bd0, 0xbede9cf8,
      0x3ee3743e, 0xbdac80c8, 0x3edec5e8, 0x3d3c6690, 0x3ec2a6f0, 0xbda882b8,
      0x3ee1e222, 0xbea027ac, 0xbeff5dfe, 0xbe6a5f1c, 0xbeb493ac, 0xbe952c30,
      0x3cac4fa0, 0xbe94a63c, 0x3cb6ae60, 0x3e2ef934, 0x3ea50604, 0x3eb32ed6,
      0xbeb47690, 0xbe988dc4, 0xbec183fa, 0xbe380bcc, 0xbe8cec88, 0xbc32ba00,
      0xbeafbf44, 0x3ed7eee0, 0x3dbed0f8, 0x3e67aa8c, 0x3e8c896e, 0x3e9ed100,
      0xbec67a6c, 0x3e4de7f8, 0xbd813f20, 0x3ef5cf48, 0xbeb16e18, 0xbe97a46a,
      0x3c9c6440, 0xbec54796, 0xbe843ed2, 0x3e1aadc8, 0x3ded4400, 0xbe3ba1ec,
      0xbd6c53f0, 0x3d5bc2b0, 0x3e7604cc, 0xbed2f700, 0xbe648f70, 0xbdd664c0,
      0x3e34d140, 0x3e8ab64c, 0x3eccb614, 0x3eb6d016, 0xbdf63f00, 0x3ecb4226,
      0xbecedf54, 0x3e0eec08, 0xbdd75a50, 0x3eaf295c, 0x3e44e48c, 0x3eb7435c,
      0x3e7fa638, 0x3ef0d4f2, 0xbe97a134, 0x3e3f7148, 0x3dd65318, 0x3eac7f54,
      0x3e3bb1dc, 0xbefd5f4a, 0xbec7b396, 0xbe5f3eb0, 0x3e817616, 0xbea61100,
      0xbe9368e8, 0xbe00dcd4, 0x3e3924a0, 0x3d807a40, 0xbec83e98, 0xbd130f20,
      0x3d81aa40, 0xbde9d330, 0xbe862d7a, 0x3efd3ec0, 0xbb73ed00, 0xbb663e00,
      0x3eceb7d8, 0x3e38f410, 0xbdca6d08, 0x3d82a7c0, 0xbecfc186, 0x3c67f0c0};
  uint32_t biases0_shape[] = {2, 4};
  uint32_t biases0_values[] = {
      0x3e9fb02e, 0xbec8528a, 0xbdd87bf0, 0xbe4f9a1c, 0x3ee07afa, 0xbea63fd0,
      0xbd68fbd0, 0x3e12af48, 0xbdcfb470, 0x3e8c6456, 0x3e8a6774, 0xbef6e502,
      0xbef20a42, 0x3ddd3bb0, 0xbe8fa9a8, 0xbee43e50, 0xbdc53cf0, 0xbdc90e10,
      0xbee5b8ba, 0xbedd0a44, 0x3c827de0, 0xbeac41fa, 0xbeceee2c, 0x3ecc0d98};
  uint32_t hidden_weights0_shape[] = {2, 4, 4};
  uint32_t hidden_weights0_values[] = {
      0x3e48ec5c, 0xbef59156, 0xbe331d5c, 0xbea6c676, 0x3cf559e0, 0xbe97bba0,
      0xbed1d2ba, 0xbcd23440, 0xbe79d1cc, 0xbe002b3c, 0xbdd9d200, 0x3eb74200,
      0x3e7245d4, 0xbe7966ec, 0x3ddae2f8, 0xbd5288f0, 0x3e290ef0, 0x3e83cb7a,
      0x3be1d000, 0x3ed3b0f2, 0x3ec00ef2, 0xbef7935a, 0xbdae18e0, 0xbe15aae8,
      0xbe24d228, 0x3eb91542, 0xbe86d40a, 0xbe97fc56, 0x3a51d400, 0xbed3b130,
      0x3d8757d8, 0xbe3d5b84, 0xbef3dd78, 0xbce1b020, 0xbe9bc938, 0xbdfedb88,
      0xbc133e80, 0x3d99bfa0, 0x3ee84968, 0x3cb8d280, 0xbec0c878, 0xbe51adf4,
      0x3eaf6fd0, 0x3d956718, 0xbec577a2, 0x3e97e798, 0xbed7e164, 0x3df2ddd0,
      0xbeddda26, 0xbe2bc8cc, 0x3d7fab80, 0x3e65a254, 0x3e7da22c, 0xbd97a438,
      0x3ee54c20, 0xbeb4f724, 0xbeb65808, 0x3bb33680, 0x3e9c9930, 0xbe58ff9c,
      0xbe1156a8, 0x3ed32696, 0xbea1d8c6, 0x3e169740, 0x3c63ac80, 0x3ef27eba,
      0xbee5f866, 0xbe7e7cdc, 0xbd30adc0, 0x3ea29306, 0xbe72ba40, 0xbec42d02,
      0x3dcf3d10, 0x3ef30cc4, 0x3eae4fce, 0xbeef9400, 0x3ea2c660, 0xbd141d60,
      0xbb546b00, 0xbed810ec, 0xbefdbbe6, 0xbe937b62, 0x3e39b6d8, 0x3ed270de,
      0x3e671d1c, 0x3e933052, 0xbe2afcc4, 0x3e0b3574, 0xbe75e520, 0x3e879224,
      0xbe0f13d4, 0xbe72401c, 0xbeaad6d0, 0x3ec47c50, 0x3e174298, 0xbe70adfc};
  uint32_t hidden_biases0_shape[] = {2, 4};
  uint32_t hidden_biases0_values[] = {
      0xbee66a3a, 0xbd0a36c0, 0x3ee121a2, 0xbe50d738, 0xbdea2a18, 0xbcb62760,
      0xbe9bea52, 0x3e2d28ac, 0xbda03c28, 0x3bd3e180, 0xbe6896b8, 0x3e40deb8,
      0x3da6bf30, 0x3ed46246, 0xbe2ba4a8, 0x3e16cff8, 0x3ee72b36, 0x3e396c38,
      0xbee707ae, 0x3ea1f874, 0x3e21e080, 0xbc28fd40, 0xbde64cc0, 0xbe9dce58};
  uint32_t all_ts_out0_shape[] = {5, 2, 2, 4};
  uint32_t all_ts_out0_exp_values[] = {
      0x3f6bce30, 0x3beaf6b0, 0xbec8dfee, 0xbd929bc0, 0x3fb6725f, 0x3f5a6c8b,
      0xbee4e44b, 0xbdb632bc, 0x3d9293c4, 0xbeb2a8df, 0xbf3182a1, 0x3f098928,
      0x3e809ad9, 0xbeaffc95, 0xbf27c972, 0x3f331a57, 0x3f5aaeda, 0xbe80c748,
      0xbf27f391, 0xbc2d591f, 0x3faa62a2, 0x3f0a4d52, 0xbf36fb1c, 0x3ec311f0,
      0x3e085652, 0xbec6dc8d, 0xbf337790, 0x3efc9499, 0x3e91c071, 0xbe90d269,
      0xbf2fab83, 0x3f3dd627, 0x3f50bbdd, 0xbf231060, 0xbf498fe4, 0xbea2a61f,
      0x3f8e5d9f, 0x3c3ce7d0, 0xbf4c17b3, 0xbe4c7e78, 0x3dd54579, 0xbecb384e,
      0xbf1ee32c, 0x3ed38a87, 0x3e22ecd6, 0xbe6019ea, 0xbebcd226, 0x3f30504a,
      0x3f4025f6, 0xbe8eb1d6, 0xbf4b2853, 0x3eac30ec, 0x3f79e857, 0x3e21b530,
      0xbf4bce96, 0x3ecebfe8, 0x3e88787f, 0xbe832944, 0xbf56da6c, 0x3e9e64a2,
      0x3ea35eab, 0xbd986300, 0xbf12712f, 0x3f597df2, 0x3f3d9310, 0xbf083670,
      0xbf5b102b, 0x3ec92c09, 0x3f5df7b3, 0x3e6c9d73, 0xbf43d815, 0x3e9aa38c,
      0x3f09f861, 0x3d10f6e8, 0xbf26dab4, 0x3e60c564, 0x3ea667e6, 0x3ee0c930,
      0xbed2d9b6, 0x3f655092};

  zdnn_ztensor *input0 =
      alloc_ztensor_with_values(input0_shape, ZDNN_3DS, test_datatype,
                                NO_CONCAT, false, (void *)input0_values);

  zdnn_ztensor *all_ts_out0 = test_layer(
      input0, h00_shape, (void *)h00_values, weights0_shape,
      (void *)weights0_values, biases0_shape, (void *)biases0_values,
      hidden_weights0_shape, (void *)hidden_weights0_values,
      hidden_biases0_shape, (void *)hidden_biases0_values, all_ts_out0_shape,
      (void *)all_ts_out0_exp_values, false, is_layer_bidir[0]);

  // second layer

  uint32_t h01_shape[] = {2, 2, 5};
  uint32_t h01_values[] = {0x3e9dedd8, 0x3fdf494a, 0x3f17202a, 0x3fab0a5b,
                           0x3fbdc183, 0x3f5202c8, 0x3fc27d91, 0x3f450430,
                           0x3f4db9fc, 0x3fdf09e5, 0x3f55605a, 0x3f12f64e,
                           0x3f1aaad2, 0x3f901ccb, 0x3fe8eecd, 0x3f93bb52,
                           0x3f2716d8, 0x3faeb44b, 0x3f1ed3c6, 0x3eab06f4};
  uint32_t weights1_shape[] = {2, 8, 5};
  uint32_t weights1_values[] = {
      0xbe1b9f76, 0x3e77c3f8, 0xbead1b0c, 0x3ecb999a, 0xbe20471c, 0x3e5f481c,
      0x3ed6d390, 0xbe5f6ed0, 0xbdea86c4, 0x3e5bbc44, 0xbe9fee66, 0x3eb76f78,
      0xbedd358e, 0x3e497f5c, 0x3d527bf8, 0x3dcedbf0, 0xbecc7bce, 0xbe81ffa5,
      0x3ecbffd4, 0xbddabb30, 0xbe9aebe8, 0xbe9c4230, 0x3ebc5350, 0x3e177f54,
      0xbe811315, 0xbee1e40d, 0xbd93fe10, 0x3ebb7968, 0x3ee4e636, 0xbe807b12,
      0xbeb7e0dd, 0xbe94b3e4, 0x3ea3e864, 0x3e6d851c, 0xbeb030cc, 0x3eb4c482,
      0x3e9eff90, 0x3eb0cbec, 0x3e8e5746, 0x3e99b77e, 0xbebd9868, 0x3eb1c556,
      0x3ed4086e, 0xbe5113e1, 0xbe4a029f, 0xbecfb148, 0xbd891828, 0x3ed8ea94,
      0x3e6fec98, 0x3e2270c4, 0x3de585b8, 0xbec9e6b4, 0x3ecebb20, 0xbe53d7b8,
      0x3ec72844, 0xbd0ab3d0, 0xbecee7d6, 0xbec12893, 0xbe618c84, 0x3e66f338,
      0xbe6741db, 0x3ed5ca40, 0xbe2ccb44, 0xbd203aa8, 0x3d81ac10, 0x3db92198,
      0x3e4a7010, 0xbe9d7ac6, 0xbd301208, 0x3ec2d2d6, 0x3e2de8c8, 0x3e479f54,
      0x3ed8d474, 0xbeb25d85, 0x3d763d80, 0x3eb61b5a, 0xbec61cd1, 0xbe44c542,
      0x3ebee346, 0xbe53df41, 0xbe6f1e1b, 0x3e9e8ea0, 0x3ee46d12, 0xbdd1fa20,
      0xbe8f83dc, 0x3b9084c0, 0x3ece54c0, 0x3e915990, 0xbe20b66c, 0x3e036284,
      0x3e3d5c4c, 0x3e86944e, 0xbe9e462c, 0x3ebbff92, 0xbe2089f6, 0x3d0f9250,
      0x3d757710, 0x3e332b14, 0x3e804fe0, 0x3eb2e8ec, 0x3d190310, 0x3e55de1c,
      0x3eace9cc, 0xbe89ca96, 0xbda4ce70, 0x3d64ba10, 0xbe5ec821, 0x3ee4e29a,
      0x3ecdd9da, 0x3e3248cc, 0xbeb401c3, 0xbebdbf60, 0x3ec83690, 0x3e5d42c8,
      0x3da2aec0, 0x3d0ff4f8, 0xbec4e626, 0x3eb165e2, 0x3e79a49c, 0x3e42d780,
      0x3dcaf230, 0x3ee0b168, 0xbdcc9010, 0x3ed7e74a, 0xbe97eae2, 0xbdd20768,
      0xbed93dd3, 0x3e917fbc, 0xbdcbff10, 0xbd084a60, 0xbe5de779, 0xbedb8204,
      0x3caf1b90, 0xbda475ac, 0x3ebd81c8, 0x3d7ba930, 0x3ee1a07c, 0xbedeee8a,
      0x3eb369f6, 0xbe19b22c, 0x3ebc4676, 0xbe90de80, 0xbe872d40, 0x3e662ae4,
      0xbed457d0, 0xbe9acddc, 0x3daf9920, 0xbe1c1d3a, 0x3ec2326c, 0x3e3bb9b4,
      0x3caa1db0, 0xbd1e1828, 0x3e667240, 0x3e8472c6, 0x3edee626, 0xbe28e040,
      0xbdc0f07c, 0xbe942d27, 0xbe0aeb80, 0xbe025ea8, 0x3ea2c8c8, 0x3e3b45e4,
      0x3ec26bea, 0x3cc42620, 0xbe436636, 0xbd507b08, 0xbeadd2f6, 0x3c976030,
      0xbe8d6097, 0x3e24fec4, 0xbe8480f1, 0x3edb2580, 0xbea1ef22, 0x3cbbc620,
      0xbea299d4, 0x3eb0f98a, 0x3eade05a, 0xbe190f96, 0x3e5b9460, 0x3e2a3b28,
      0x3e926d0a, 0xbe26eada, 0xbdf89d64, 0x3e6328f4, 0x3ec258fa, 0x3d082a00,
      0x3e80b7ea, 0xbdb0b3c4, 0xbed14480, 0x3cf049b0, 0xbe58367b, 0xbe8219a4,
      0x3d2f4d98, 0xbda3e468, 0xbe989ba1, 0x3ed26ffe, 0xbd8f889c, 0x3ed3c2e8,
      0xbeaa2909, 0xbe24134e, 0x3ed89bd2, 0xbce64df0, 0xbed605fa, 0x3edaf946,
      0xbe9d91cb, 0x3dd8c630, 0x3e8fcc58, 0xbeac7e7c, 0xbe8525dc, 0xbec0490a,
      0xbedf67a9, 0x3dedf310, 0x3e4679ac, 0x3ebc54aa, 0xbe4e7f38, 0xbe025fa2,
      0x3e10ce08, 0xbe879404, 0xbeb62674, 0x3d940df8, 0xbe9bf81e, 0x3d2a1fb8,
      0x3d836668, 0xbddc5118, 0x3ed2d41c, 0x3ec8c0ca, 0x3e2abb28, 0x3e122c34,
      0x3e791bd4, 0xbe5a9fca, 0xbd97418c, 0xbddf28c4, 0x3d01b298, 0xbe3b1bb2,
      0x3e23c650, 0xbed0b705, 0xbe362bda, 0xbe94746f, 0x3ec058f2, 0xbde59ef4};
  uint32_t biases1_shape[] = {2, 5};
  uint32_t biases1_values[] = {
      0xbe5fbd62, 0x3d21ed48, 0x3e84b2c0, 0xbd3641c0, 0x3e0b5e64, 0x3cdf2e90,
      0x3eb58a42, 0xbe019774, 0x3e578a54, 0x3ec4c2fc, 0x3e8d90bc, 0xbdfe1e6c,
      0xbe2ab878, 0x3de69348, 0x3e226e48, 0xbd6ccb78, 0xbea7780c, 0x3e061770,
      0xbea2cdd5, 0xbeb5b12a, 0xbddce6cc, 0x3e208298, 0xbea5ddf2, 0xbe86a497,
      0xbe68730d, 0x3e97de7c, 0xbe703894, 0xbd48ccd8, 0xbe101be0, 0xbeb81f6b};
  uint32_t hidden_weights1_shape[] = {2, 5, 5};
  uint32_t hidden_weights1_values[] = {
      0xbe325de8, 0x3d7f2f50, 0x3ee1dbc6, 0xbec39102, 0xbe62d375, 0x3dc59638,
      0xbe9933c8, 0x3e83aa94, 0x3e55ae7c, 0xbebc9a53, 0xbeb3c7f8, 0xbeb1870e,
      0xbd4e46b0, 0xbe81b1a9, 0x3e6ef9a8, 0x3e11fa20, 0xbe0d48c0, 0x3e20904c,
      0x3e5c50f0, 0xbd3aa670, 0x3e75d434, 0x3e4904fc, 0xbee0a324, 0xbea1a3c0,
      0x3eb037d8, 0xbd912c2c, 0xbe8d3f0b, 0x3ea0bcaa, 0x3e1f747c, 0x3d6b9ee0,
      0xbebdb332, 0x3e935dc2, 0xbea9c5c8, 0xbecccd1f, 0x3ec31294, 0x3e62e8b8,
      0x3ed8df8e, 0x3dd289d0, 0x3dd09a78, 0xbe5a7ee4, 0x3e08fc84, 0x3d1ef258,
      0x3d851878, 0xbe91286a, 0x3e92b048, 0x3e37f4f4, 0xbed5df49, 0xbe5655f7,
      0xbd4613f0, 0xbd68b2e8, 0x3dc7ff90, 0xbede7c01, 0xbe37306c, 0x3e769414,
      0x3cc4e590, 0xbeae8cee, 0xbdb9cd1c, 0x3e062014, 0x3ee39938, 0x3e592a78,
      0x3e63833c, 0x3e99f81e, 0x3ca711d0, 0x3e675c3c, 0xbeb798f6, 0xbecfe0c1,
      0xbed8b7ed, 0xbece783b, 0xbe972362, 0xbe03b7b6, 0xbedc1c4e, 0x3ebe51d8,
      0x3ebde4ee, 0x3ebf18f2, 0xbee0d2e5, 0xbdc69f70, 0xbd7bb5b8, 0xbd840080,
      0xbd88748c, 0xbe987408, 0x3ea85d6a, 0x3eb1c89c, 0xbda0df98, 0xbc914780,
      0xbd4637a8, 0xbeb1737d, 0xbe0d071e, 0x3e1469e4, 0x3e9ccdb4, 0xbcc4c620,
      0x3d428f68, 0x3eb8509c, 0x3e33aa40, 0xbdf7d0f0, 0x3e4c5720, 0x3ed75422,
      0xbedd7e2d, 0x3eafcf42, 0x3ec8b9ca, 0x3e9c8b2a, 0x3e8db48a, 0x3d737210,
      0xbebfde02, 0x3ea17e98, 0x3e109bc4, 0x3e7d66c4, 0x3e630230, 0xbe77c691,
      0x3e658114, 0x3e3b6830, 0x3c6b9ce0, 0xbea06a9a, 0x3eca9984, 0x3e878898,
      0xbe0751fa, 0xbe0d9648, 0x3ec02c1a, 0x3ed16702, 0x3ec1d528, 0x3e1940d8,
      0xbdc724ec, 0xbd472b98, 0xbed417e7, 0xbe76cf7f, 0xbe03c1e6, 0xbe597ddb,
      0x3cb6fdc0, 0xbea9a47a, 0x3ed6ece6, 0x3eb5c09c, 0xbec763d2, 0x3df84f58,
      0xbd92bdd4, 0xbeb76e74, 0xbdcf25dc, 0xbed21657, 0x3e9ba3fc, 0xbe877dfe,
      0x3e8a9360, 0x3d26cb70, 0x3edf9e2a, 0x3ec36c40, 0xbe82d308, 0xbe6d6e1d,
      0xbea00f51, 0xbde46c64, 0x3eb9b38a, 0x3dd941a0, 0xbdb26478, 0x3ec2e956};
  uint32_t hidden_biases1_shape[] = {2, 5};
  uint32_t hidden_biases1_values[] = {
      0x3edfa1a6, 0xbeacb04b, 0xbeb99f2f, 0xbead8f69, 0xbb0d5900, 0xbe46414a,
      0x3eacd6bc, 0xbe3e8e36, 0xbe9f0e96, 0x3d8d0aa8, 0x3ed26dd4, 0xbdf673cc,
      0xbaa00c00, 0xbe5ddf86, 0x3ee494f2, 0x3941c000, 0x3eac49a0, 0x3ec0e9e4,
      0x3d2ae830, 0x3dd00540, 0xbde97700, 0xbe95df9f, 0xbe2440b2, 0x3dad0a60,
      0xbe6f45de, 0x3e893e48, 0xbece70c1, 0x3ecefc06, 0x3e24bcd8, 0xbea06bf2};
  uint32_t all_ts_out1_shape[] = {5, 2, 2, 5};
  uint32_t all_ts_out1_exp_values[] = {
      0x3ebd7308, 0x3f64bfca, 0x3e96c38c, 0x3f3d08b3, 0x3f4ed9a0, 0x3f4cbe71,
      0x3f4eb04c, 0x3e85fce6, 0x3e97fd95, 0x3f8901b2, 0x3f2f67f8, 0xbedb2fa7,
      0xbefa32c3, 0x3ec8b1e1, 0xbed037d0, 0x3f4ba138, 0xbeabf370, 0xbf4120d0,
      0x3ecca2bb, 0xbf2c7ea2, 0x3ee040ab, 0x3eedbe60, 0x3e6717ff, 0x3ec905c6,
      0x3ed8b348, 0x3f4ef281, 0x3ed71f06, 0x3dc962ab, 0x3d91f336, 0x3f248a02,
      0x3f2dcf90, 0xbe9f2068, 0xbedd7c39, 0x3ead94a9, 0xbe50a7d2, 0x3f4577ae,
      0xbe58e036, 0xbf377f08, 0x3eb83368, 0xbf0e3834, 0x3ef216aa, 0x3e5e4d08,
      0x3e745018, 0x3e62837b, 0x3e11ab71, 0x3f4573d1, 0x3e0c25a8, 0x3debf382,
      0xbdd8e72a, 0x3e7fc71f, 0x3f2cd1a8, 0xbe07a588, 0xbea8172b, 0x3ea0fd5a,
      0x3d6961d8, 0x3f3b7bd9, 0xbc7f2780, 0xbf166c22, 0x3ed1edf5, 0xbed9aa68,
      0x3f0c0d67, 0x3e330cab, 0x3e2f6954, 0x3e448f94, 0x3dfbfbd1, 0x3f4a1f6a,
      0x3d3c12cf, 0x3dfc4ab2, 0xbe278de1, 0x3e04a44b, 0x3f2753d8, 0x3e1a2b60,
      0xbee04b4a, 0x3e6e3232, 0x3ee33cb4, 0x3f25b2fe, 0x3e751f72, 0xbf051b4b,
      0x3ed8a638, 0xbe8dcab2, 0x3f1f2826, 0x3e559c26, 0x3dbbfaaa, 0x3e4feb0b,
      0x3e147845, 0x3f4b713c, 0x3c42a99e, 0x3de07552, 0xbe9fcdb7, 0x3d18e8b6,
      0x3f2e37ae, 0x3eea935e, 0xbe97bb49, 0x3eefdd22, 0x3f84dd69, 0x3f3c21fd,
      0x3f0577d9, 0xbceedc60, 0x3f1a0c27, 0xbd85eeb0};

  zdnn_ztensor *all_ts_out1 = test_layer(
      all_ts_out0, h01_shape, (void *)h01_values, weights1_shape,
      (void *)weights1_values, biases1_shape, (void *)biases1_values,
      hidden_weights1_shape, (void *)hidden_weights1_values,
      hidden_biases1_shape, (void *)hidden_biases1_values, all_ts_out1_shape,
      (void *)all_ts_out1_exp_values, is_layer_bidir[0], is_layer_bidir[1]);

  free_ztensor_buffers(3, input0, all_ts_out0, all_ts_out1);
}

void gru_bidir_to_fwd() {

  // num_timesteps = 5
  // num_batches = 2
  // num_features = 4
  // num_hidden = 5, 4

  bool is_layer_bidir[] = {true, false};

  // first layer

  uint32_t input0_shape[] = {5, 2, 4};
  uint32_t input0_values[] = {
      0x3f80f554, 0x3eed5744, 0x3fe9598b, 0x3fde3340, 0x3fb14cbd, 0x3f3b5a0a,
      0x3f82893d, 0x3e5414c8, 0x3f8b5bf7, 0x3f3c425a, 0x3fa6aeeb, 0x3f99290e,
      0x3ffa48dc, 0x3fd4c5a9, 0x3fb4c3ba, 0x3f768450, 0x3f1acb50, 0x3eccc9d0,
      0x3fd6c6c6, 0x3fb7bd3f, 0x3f230434, 0x3e2daec8, 0x3f9a57a9, 0x3e80dd48,
      0x3f94a1a8, 0x3f64e95e, 0x3dc195b0, 0x3ff6bde7, 0x3fd094b3, 0x3fa067b8,
      0x3fb1e4f7, 0x3e0b4360, 0x3fd2f78d, 0x3fbaec30, 0x3fd96d0d, 0x3ff7e13b,
      0x3fcab802, 0x3e0fc588, 0x3f0dc4a2, 0x3f03ec80};
  uint32_t h00_shape[] = {2, 2, 5};
  uint32_t h00_values[] = {0x3f72895c, 0x3fc19f9d, 0x3f54b050, 0x3ff7834f,
                           0x3fdc7d0d, 0x3fc1fce3, 0x3ebcf5b4, 0x3ed3cdb4,
                           0x3fb8c472, 0x3f849e59, 0x3eb88b80, 0x3bc03f00,
                           0x3f1a65ee, 0x3f5d6a8e, 0x3ea8b604, 0x3fcb5de0,
                           0x3f504bc2, 0x3fe33d36, 0x3fd8b70c, 0x3fc21f69};
  uint32_t weights0_shape[] = {2, 4, 5};
  uint32_t weights0_values[] = {
      0xbed56486, 0x3dab6e00, 0x3e301b34, 0x3ea3ea60, 0x3e64a8e0, 0x3ecb70ec,
      0xbd9a4a9c, 0xbe879f2a, 0x3e2b3b3c, 0x3dbfb2a0, 0x3eae1a26, 0xbd96b870,
      0x3e27e118, 0xbee29f7d, 0xbeb29e53, 0xbee46847, 0xbe51a0d6, 0x3e67965c,
      0xbe9488c8, 0xbe83d8ea, 0xbedd7037, 0xbd9bb79c, 0xbe05dde4, 0x3e4eb6e0,
      0x3e83a64e, 0x3ea58b16, 0xbe71302b, 0xbe87f0ac, 0xbe5bef69, 0x3e72843c,
      0xbebd57dc, 0x3d721bf0, 0xbe295dd2, 0xbe98cd9b, 0x3eafbdf8, 0x3bc9f900,
      0x3ebd57a4, 0xbee2f252, 0xbe83e971, 0x3e261b9c, 0x3e4f3564, 0x3e7b6660,
      0x3e8e0cba, 0x3e33fa44, 0x3db646b0, 0x3e382b04, 0xbd673410, 0x3edbdbde,
      0x3ebdb73a, 0xbec71c7c, 0xbe87a208, 0x3c8be180, 0xbeb073c8, 0x3ec7411a,
      0x3d2882b8, 0x3e0a5954, 0x3dd43780, 0xbe27d2d8, 0x3eca0944, 0xbe8f3f38,
      0x3e62db50, 0xbd87a1dc, 0x3ecd16fc, 0xbea1dc41, 0x3eabc840, 0xbea317e4,
      0x3ba04b00, 0x3e8c10dc, 0xbe4216de, 0xbe136b9a, 0xbe01fea6, 0x3ebcdbe4,
      0xbe90c29a, 0x3e06b148, 0x3a3bae00, 0xbe19a60a, 0x3d64ada0, 0x3e4d6418,
      0x3e1735dc, 0x3e6bc304, 0x3ed76812, 0xbeda1e9d, 0xbcc9dc90, 0xbe8b56d8,
      0xbde3f398, 0x3e9a494e, 0xbc03b300, 0x3d898450, 0x3ecfc37a, 0x3ca54f60,
      0xbe47ad20, 0xbeac6e30, 0xbe3b8b06, 0x3e9cea58, 0x3d85a140, 0xbde68434,
      0xbeb09ec1, 0x3e87de1e, 0xbec116de, 0x3dd939f0, 0xbe18ef8e, 0x3df90638,
      0x3dc5e080, 0xbe94b2a7, 0xbe9a126e, 0xbdfff1d8, 0xbe58ace5, 0xbe807ef0,
      0xbd506310, 0xbeb9158a, 0x3e074a8c, 0xbe574539, 0xbecc25a9, 0x3e0332e4,
      0x3eb682ba, 0x3ebc395c, 0xbed87cba, 0x3ec8c806, 0x3c696e40, 0x3d952498};
  uint32_t biases0_shape[] = {2, 5};
  uint32_t biases0_values[] = {
      0x3c9a1ea0, 0x3e9399fc, 0xbead15e7, 0xbe9d3169, 0xbe84f4be, 0x3ed6d390,
      0x3eb76f78, 0xbecc7bce, 0xbe9c4230, 0xbd93fe10, 0xbe7c17a9, 0xbe856c8e,
      0x3e1c8044, 0xbe8872c0, 0xbc1fdba0, 0xbe9aebe8, 0xbee1e40d, 0xbeb7e0dd,
      0x3eb4c482, 0x3e77c3f8, 0x3ea04420, 0xbe249da6, 0x3ec122ee, 0x3e2598d4,
      0x3d67f3b0, 0xbe94b3e4, 0x3e9eff90, 0xbead1b0c, 0xbe5f6ed0, 0xbedd358e};
  uint32_t hidden_weights0_shape[] = {2, 5, 5};
  uint32_t hidden_weights0_values[] = {
      0xbe591a24, 0xbed64902, 0xbedcd447, 0xbdb06a40, 0x3bbd8300, 0x3e9be8be,
      0xbec14162, 0x3e8ed458, 0xbdb3d438, 0xbe5008a0, 0xbb3dfe00, 0xbdb9c6e0,
      0xbeb32c7f, 0xbecd7820, 0x3e2c8218, 0xbe639ee9, 0x3e7b2408, 0xbdc1a118,
      0xbec5b44b, 0xbece16e2, 0xbeaf7709, 0x3e7795b4, 0xbe39af54, 0xbd8f518c,
      0xbcf73e90, 0xbebbb5a4, 0x3e987cda, 0x3d190310, 0x3ece54c0, 0xbebdbf60,
      0xbd8d3050, 0xbe6f1e1b, 0x3d64ba10, 0x3e86944e, 0xbec4e626, 0x3e1f0c64,
      0x3b9084c0, 0xbeb401c3, 0x3d757710, 0x3ee46d12, 0xbe271822, 0x3e3d5c4c,
      0x3d0ff4f8, 0x3e55de1c, 0x3e915990, 0x3e2dd3f4, 0x3d0f9250, 0x3e9e8ea0,
      0xbe5ec821, 0xbe9e462c, 0x3e33b614, 0xbe87b6cc, 0xbdc2d30c, 0xbd3c4ee0,
      0x3ed8e4e6, 0x3cdb72e0, 0xbde54684, 0x3dc3c730, 0x3c4ba340, 0x3e916930,
      0xbe5f7204, 0xbe5f126c, 0xbe952b16, 0xbd1e06b8, 0x3ed963f2, 0x3e58b204,
      0xbe20347e, 0xbcbc0320, 0x3db95c18, 0xbd047a58, 0xbedba477, 0xbebbabe9,
      0x3ea3e928, 0x3e91971e, 0xbecdb113, 0x3ebdf640, 0xbe8b7474, 0xbe8d2560,
      0xbe5cf1d4, 0xbeaa02a3, 0xbe1985b8, 0x3e1ae0c4, 0x3e9e5868, 0x3da48928,
      0x3d987eb0, 0x3e06e404, 0x3e10c984, 0xbeaa740b, 0xbe6de235, 0x3e430d88,
      0xbdd1716c, 0xbc172600, 0x3e3b9ae0, 0x3dd306b8, 0x3e354500, 0xbca2ec60,
      0xbdcdfc84, 0xbe19fc78, 0x3db3dd28, 0xbd669538, 0x3ec95d16, 0x3e90def0,
      0x3d448f50, 0x3e21ba5c, 0x3eb5ccc2, 0xbe3acaf4, 0xbd5360c8, 0xbdbfc268,
      0xbddc3fcc, 0x3e9cab54, 0x3ecec37e, 0xbe4c6e38, 0x3ea38344, 0xbdc09e0c,
      0xbea1834a, 0x3e25d8dc, 0x3eb7196c, 0x3dffaaa8, 0xbebcb154, 0x3ca36520,
      0xbecea3b7, 0xbeb90843, 0x3e5c0bbc, 0x3e7822c0, 0xbea16940, 0x3e332b14,
      0xbdd1fa20, 0x3ecdd9da, 0xbe2089f6, 0x3e42d780, 0x3eace9cc, 0xbe20b66c,
      0x3e5d42c8, 0x3eb2e8ec, 0xbe1b9f76, 0x3ee4e29a, 0x3ebbff92, 0x3e79a49c,
      0xbda4ce70, 0x3e5f481c, 0x3ec83690, 0x3e804fe0, 0xbe8f83dc, 0x3e3248cc,
      0xbe9fee66, 0x3eb165e2, 0xbe89ca96, 0x3e036284, 0x3da2aec0, 0x3dcedbf0};
  uint32_t hidden_biases0_shape[] = {2, 5};
  uint32_t hidden_biases0_values[] = {
      0x3d69b920, 0xbeb31aa8, 0xbe700636, 0x3eb8e4f2, 0xbeb9d294, 0x3ecb999a,
      0xbdea86c4, 0x3e497f5c, 0x3ecbffd4, 0x3e177f54, 0xbb5a2c80, 0xbdb50e24,
      0x3d65d3e0, 0xbdd123b0, 0xbb4def80, 0xbe81ffa5, 0x3ebc5350, 0x3ebb7968,
      0x3ea3e864, 0x3eb0cbec, 0xbd0388a0, 0x3ee28262, 0x3e256d64, 0x3c4f7420,
      0xbec66e3b, 0x3ee4e636, 0x3e6d851c, 0x3e8e5746, 0xbe20471c, 0x3e5bbc44};
  uint32_t all_ts_out0_shape[] = {5, 2, 2, 5};
  uint32_t all_ts_out0_exp_values[] = {
      0x3ef5b84b, 0xbdc926d0, 0x3f497c28, 0xbdfc36e0, 0x3e607fa7, 0x3f82f3c5,
      0xbe8cee08, 0x3f14bc02, 0x3f188fa6, 0x3e241ab6, 0x3eac5206, 0xbedcec07,
      0xbe3aac82, 0xbefbfe4a, 0x3d0ad0f8, 0xbda044a0, 0xbbf714b4, 0xbee36d2e,
      0xbee0ad51, 0xbe2f3894, 0x3f13e1fa, 0xbf189b8e, 0x3f2c5fec, 0x3dc15418,
      0xbc762fd0, 0x3f76bfe3, 0xbf2b3644, 0x3f21d8d1, 0x3ede3af5, 0xbc315408,
      0x3e8d057a, 0xbeb31b94, 0xbe3ae016, 0xbefdfa09, 0xbc714a80, 0x3e15b5fa,
      0xbd251f38, 0xbec45527, 0xbe918512, 0xbb884180, 0x3ef72c4b, 0xbf41095a,
      0x3f193819, 0x3e22c8d5, 0xbc6dc4e6, 0x3f42b484, 0xbf1bf022, 0x3eedea11,
      0x3eb9245f, 0xbdfb31b3, 0x3ecf949d, 0xbea0e868, 0xbde5266b, 0xbecc0f8c,
      0x3d2635b8, 0x3ed43076, 0x3e94113c, 0xbe8f5d00, 0x3e26030d, 0x3e5ae9d3,
      0x3f3f74e5, 0xbf47bebc, 0x3f40cc76, 0xbe345ea9, 0xbd596022, 0x3f5486e7,
      0xbf33d933, 0x3edef9ca, 0x3ee99606, 0xbe2fe4f9, 0x3ec22476, 0xbe846bbc,
      0x3ec65d70, 0xbebc0ca3, 0xbd2b4ab0, 0x3f239afa, 0x3ee52450, 0xbdbb9c94,
      0x3f011b6e, 0x3ef79e50, 0x3f51084e, 0xbf65575e, 0x3f388490, 0x3debd8da,
      0xbcaa7ed3, 0x3f58d051, 0xbf2f19e6, 0x3f027aa7, 0x3d9a45a2, 0xbe5edb76,
      0x3edce200, 0xbe25588a, 0xbde12298, 0xbce7e6a0, 0x3e6c86cc, 0x3f932f62,
      0x3f32daf3, 0x3f4d9d22, 0x3f9152b4, 0x3f61d3b8};

  zdnn_ztensor *input0 =
      alloc_ztensor_with_values(input0_shape, ZDNN_3DS, test_datatype,
                                NO_CONCAT, false, (void *)input0_values);

  zdnn_ztensor *all_ts_out0 = test_layer(
      input0, h00_shape, (void *)h00_values, weights0_shape,
      (void *)weights0_values, biases0_shape, (void *)biases0_values,
      hidden_weights0_shape, (void *)hidden_weights0_values,
      hidden_biases0_shape, (void *)hidden_biases0_values, all_ts_out0_shape,
      (void *)all_ts_out0_exp_values, false, is_layer_bidir[0]);

  // second layer

  uint32_t h01_shape[] = {1, 2, 4};
  uint32_t h01_values[] = {0x3f62957c, 0x3f9e9191, 0x3fc827a5, 0x3fc7d2ab,
                           0x3fe27e59, 0x3ea84764, 0x3e9400d4, 0x3f8e916a};
  uint32_t weights1_shape[] = {1, 10, 4};
  uint32_t weights1_values[] = {
      0x3e7e5dec, 0x3cbaca20, 0xbecd44ac, 0xbec67b5a, 0xbee86a24, 0xbee6d710,
      0xbe1343c8, 0xbe1df5e4, 0xbef61752, 0x3ed44ee8, 0xbefb5c54, 0x3e60bf20,
      0xbef8bec0, 0x3e89d76e, 0xbe476b90, 0x3efc847a, 0xbdcfbb68, 0x3efe7680,
      0x3ddce8a0, 0x3e93351a, 0x3eac2490, 0x3e815596, 0xbec9005c, 0xbd669fb0,
      0xbef24c72, 0xbea8fa48, 0x3e233510, 0x3e338400, 0x3ed4c8ae, 0x3ed5a748,
      0x3e896c2c, 0xbefb26f0, 0xbe4ccfcc, 0x3cdc2320, 0x3d8ea718, 0xbedaa662,
      0x3e15f4e8, 0x3e72cc80, 0xbeab490c, 0x3e6ee73c, 0xbe9424c4, 0xbe3a9e8c,
      0x3d43feb0, 0xbe5a7688, 0x3ec5dd22, 0x3e8fe95c, 0x3eecc1a2, 0x3e387860,
      0x3ea3b58c, 0xbe9174d6, 0x3cdb4d20, 0xbeb5cb18, 0x3d183c70, 0xbda079b8,
      0xbe9e108c, 0x3e3e52fc, 0xbe71bbb8, 0x3ed95eb2, 0x3cd1f000, 0x3ed94986,
      0x3eeb46b8, 0x3ca93e40, 0x3e757f58, 0x3d065330, 0x3e5160ac, 0xbeb50c40,
      0x3e7df8fc, 0xbeaa9ef0, 0xbec2575a, 0xbe2b2094, 0xbee9f7e0, 0xbe377120,
      0x3ef50362, 0xbe0afadc, 0xbdb73cb0, 0x3ddf9ad8, 0x3ec26652, 0xbdc58f20,
      0xbebe3eb8, 0xbec32746, 0xbe910096, 0x3c83b620, 0x3ee2836a, 0xbe174ae8,
      0x3e76522c, 0xbe1e4c94, 0x3eea1e74, 0x3e2b57a8, 0xbeb4b7f8, 0xbddea668,
      0xbeed20aa, 0xbe134f2c, 0xbe7d9964, 0x3d881718, 0x3eb48e6e, 0x3e9e4660,
      0xbed2dd48, 0x3e7dcda4, 0x3e804bf8, 0xbe0e0e88, 0x3e85975a, 0xbeb359dc,
      0x3e9787f8, 0xbe3edf14, 0xbd50ae60, 0x3ed6daea, 0x3ed8b624, 0x3e00e540,
      0x3ec50494, 0xbd5eade0, 0xbe89f8a6, 0x3e359a68, 0x3e9e6e68, 0xbed6839a,
      0x3e21ad5c, 0xbe7a2610, 0x3e8da7dc, 0xbe8a82c4, 0x3e518704, 0x3d350a30};
  uint32_t biases1_shape[] = {1, 4};
  uint32_t biases1_values[] = {0x3ed91e6a, 0x3e9414ee, 0xbe1b5134, 0xbea9d954,
                               0xbde41328, 0xbdb7df18, 0x3ec89742, 0x3e80aae6,
                               0xbd1860a0, 0x3ed3e00e, 0xbe2bd65c, 0xbeed681e};
  uint32_t hidden_weights1_shape[] = {1, 4, 4};
  uint32_t hidden_weights1_values[] = {
      0xbec20bd4, 0xbe37a3e0, 0xbdead1c8, 0xbead1388, 0xbb1e0800, 0x3dc17718,
      0xbe7818b0, 0x3cbe3200, 0xbe0282c4, 0xbe85c1f4, 0x3d8caec8, 0xbe3ccf20,
      0xbea7904e, 0x3de2e688, 0x3ed27f84, 0x3efb36e4, 0x3e945c74, 0x3e3374b0,
      0x3eeb444c, 0x3eff8ff0, 0xbd4bc4f0, 0xbeb971e6, 0xbe09c564, 0x3efa070e,
      0x3e1bd1a8, 0xbe96890e, 0xbab2f000, 0xbec11260, 0xbdf6f9b8, 0xbe81f174,
      0xbe780fcc, 0xbecf8810, 0xbef2e226, 0x3dc45320, 0x3ea2ac3c, 0xbe2e8a7c,
      0xbef56ad2, 0xbd30c140, 0x3cc3c6c0, 0x3e80d2ca, 0x3efc4230, 0xbdd7b678,
      0xbef93ece, 0xbea5aa8e, 0xbea1f7f8, 0xbde4b548, 0xbe9721d8, 0x3ef1632e};
  uint32_t hidden_biases1_shape[] = {1, 4};
  uint32_t hidden_biases1_values[] = {
      0xbee83510, 0x3e004e90, 0xbd1b12f0, 0xbe8146d8, 0x3e51e224, 0x3ef9356c,
      0xbe11c200, 0xbed3f95a, 0x3dcefba8, 0x3e426fc0, 0x3ecb9a06, 0x3ec6c0fc};
  uint32_t all_ts_out1_shape[] = {5, 1, 2, 4};
  uint32_t all_ts_out1_exp_values[] = {
      0xbe93b296, 0x3f6c52a6, 0x3df2ed90, 0x3ef58c75, 0xbedbef50, 0x3eed420e,
      0x3ec9725f, 0x3ec154ec, 0xbeeff3f1, 0x3f4f798a, 0xbe9a656d, 0x3d7b8358,
      0xbf152f9e, 0x3ef51830, 0x3cccae54, 0xbd1913d8, 0xbf05fe08, 0x3f3bc79e,
      0xbeb73f4b, 0xbe1f8736, 0xbefd88cc, 0x3ee483a5, 0x3e477805, 0xbe95932c,
      0xbf043d99, 0x3f2ccf54, 0xbefa4aaa, 0xbebf8337, 0xbe99bc9a, 0x3ebeeba4,
      0x3ec71822, 0xbef39d98, 0xbf09c6e7, 0x3f1c7ff1, 0xbe53e20e, 0xbef9fb1e,
      0x3cfaaa80, 0x3e6a580a, 0x3ee7dd5b, 0xbf2cbac5};

  zdnn_ztensor *all_ts_out1 = test_layer(
      all_ts_out0, h01_shape, (void *)h01_values, weights1_shape,
      (void *)weights1_values, biases1_shape, (void *)biases1_values,
      hidden_weights1_shape, (void *)hidden_weights1_values,
      hidden_biases1_shape, (void *)hidden_biases1_values, all_ts_out1_shape,
      (void *)all_ts_out1_exp_values, is_layer_bidir[0], is_layer_bidir[1]);

  free_ztensor_buffers(3, input0, all_ts_out0, all_ts_out1);
}

int main() {
  UNITY_BEGIN();
  RUN_TEST_ALL_DLFLOAT16_PRE_DATATYPES(gru_fwd_to_fwd);
  RUN_TEST_ALL_DLFLOAT16_PRE_DATATYPES(gru_fwd_to_bidir);
  RUN_TEST_ALL_DLFLOAT16_PRE_DATATYPES(gru_bidir_to_bidir);
  RUN_TEST_ALL_DLFLOAT16_PRE_DATATYPES(gru_bidir_to_fwd);
  return UNITY_END();
}
