# Lint as: python3
# Copyright 2020 Google LLC
#
# 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
#
#      https://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.
"""Test concat op."""

from absl import app
import numpy as np
from pyiree.tf.support import tf_test_utils
from pyiree.tf.support import tf_utils
import tensorflow.compat.v2 as tf


class ConcatOpsModule(tf.Module):

  @tf.function(input_signature=[
      tf.TensorSpec([1, 5, 0], tf.float32),
      tf.TensorSpec([1, 5, 1], tf.float32),
  ])
  def concat_zero_dim(self, a, b):
    return tf.concat([a, b], axis=2)

  @tf.function(input_signature=[
      tf.TensorSpec([1, 5, 1], tf.float32),
      tf.TensorSpec([1, 5, 1], tf.float32),
  ])
  def concat0axis(self, a, b):
    return tf.concat([a, b], axis=0)

  @tf.function(input_signature=[
      tf.TensorSpec([1, 5, 1], tf.float32),
      tf.TensorSpec([1, 5, 1], tf.float32),
  ])
  def concat1axis(self, a, b):
    return tf.concat([a, b], axis=1)

  @tf.function(input_signature=[
      tf.TensorSpec([1, 5, 1], tf.float32),
      tf.TensorSpec([1, 5, 1], tf.float32),
  ])
  def concat2axis(self, a, b):
    return tf.concat([a, b], axis=2)


class ConcatOpsTest(tf_test_utils.TracedModuleTestCase):

  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self._modules = tf_test_utils.compile_tf_module(ConcatOpsModule)

  def test_concat_zero_dim(self):

    def concat_zero_dim(module):
      a = tf_utils.uniform([1, 5, 0])
      b = tf_utils.uniform([1, 5, 1])
      module.concat_zero_dim(a, b)

    self.compare_backends(concat_zero_dim, self._modules)

  def test_concat0axis(self):

    def concat0axis(module):
      a = tf_utils.uniform([1, 5, 1])
      b = tf_utils.uniform([1, 5, 1])
      module.concat0axis(a, b)

    self.compare_backends(concat0axis, self._modules)

  def test_concat1axis(self):

    def concat1axis(module):
      a = tf_utils.uniform([1, 5, 1])
      b = tf_utils.uniform([1, 5, 1])
      module.concat1axis(a, b)

    self.compare_backends(concat1axis, self._modules)

  def test_concat2axis(self):

    def concat2axis(module):
      a = tf_utils.uniform([1, 5, 1])
      b = tf_utils.uniform([1, 5, 1])
      module.concat2axis(a, b)

    self.compare_backends(concat2axis, self._modules)


def main(argv):
  del argv  # Unused
  if hasattr(tf, 'enable_v2_behavior'):
    tf.enable_v2_behavior()
  tf.test.main()


if __name__ == '__main__':
  app.run(main)
