From f47c9d49200a3ade5ecfdcd5e1787932c6430e0d Mon Sep 17 00:00:00 2001
From: Vasileios Lioutas <contact@vlioutas.com>
Date: Fri, 14 Jun 2019 23:40:41 -0400
Subject: [PATCH 1/4] fix grad of variable size on extract_image_patches

---
 .../extract_image_patches_grad_test.py        | 48 +++++++++++++++++++
 tensorflow/python/ops/array_grad.py           | 12 ++---
 2 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/tensorflow/python/kernel_tests/extract_image_patches_grad_test.py b/tensorflow/python/kernel_tests/extract_image_patches_grad_test.py
index cfc3ea787b2..b7ac616c01f 100644
--- a/tensorflow/python/kernel_tests/extract_image_patches_grad_test.py
+++ b/tensorflow/python/kernel_tests/extract_image_patches_grad_test.py
@@ -124,6 +124,54 @@ class ExtractImagePatchesGradTest(test.TestCase):
     # Won't time out.
     self.assertIsNotNone(gradients)
 
+  def _VariableShapeGradient(self, test_shape_pattern):
+    """Use test_shape_pattern to infer which dimensions are of
+    variable size.
+    """
+    # Set graph seed for determinism.
+    random_seed = 42
+    random_seed_lib.set_random_seed(random_seed)
+
+    with self.test_session():
+      for test_case in self._TEST_CASES:
+        np.random.seed(random_seed)
+        in_shape = test_case['in_shape']
+        test_shape = [x if x is None else y
+                      for x, y in zip(test_shape_pattern, in_shape)]
+        in_val = array_ops.placeholder(
+          shape=test_shape,
+          dtype=dtypes.float32)
+
+        feed_dict = {in_val: np.random.random(in_shape)}
+        for padding in ['VALID', 'SAME']:
+          out_val = array_ops.extract_image_patches(in_val, test_case['ksizes'],
+                                                    test_case['strides'],
+                                                    test_case['rates'], padding)
+          out_val_tmp = out_val.eval(feed_dict=feed_dict)
+          out_shape = out_val_tmp.shape
+
+          err = gradient_checker.compute_gradient_error(in_val, in_shape,
+                                                        out_val, out_shape)
+
+          print('extract_image_patches gradient err: %.4e' % err)
+          self.assertLess(err, 1e-4)
+
+  @test_util.run_deprecated_v1
+  def test_BxxC_Gradient(self):
+    self._VariableShapeGradient([-1, None, None, -1])
+
+  @test_util.run_deprecated_v1
+  def test_xHWx_Gradient(self):
+    self._VariableShapeGradient([None, -1, -1, None])
+
+  @test_util.run_deprecated_v1
+  def test_BHWC_Gradient(self):
+    self._VariableShapeGradient([-1, -1, -1, -1])
+
+  @test_util.run_deprecated_v1
+  def test_AllNone_Gradient(self):
+    self._VariableShapeGradient([None, None, None, None])
+
 
 if __name__ == '__main__':
   test.main()
diff --git a/tensorflow/python/ops/array_grad.py b/tensorflow/python/ops/array_grad.py
index fa7dad85cde..cb3da724761 100644
--- a/tensorflow/python/ops/array_grad.py
+++ b/tensorflow/python/ops/array_grad.py
@@ -831,12 +831,9 @@ def _QuantizeAndDequantizeV3Grad(_, grad):
 
 @ops.RegisterGradient("ExtractImagePatches")
 def _ExtractImagePatchesGrad(op, grad):
-  batch_size, rows_in, cols_in, channels = [
-      dim.value for dim in op.inputs[0].shape.dims
-  ]
-  input_bhwc = array_ops.shape(op.inputs[0])
-  batch_size = input_bhwc[0]
-  channels = input_bhwc[3]
+  input_bhwc = math_ops.cast(array_ops.shape(op.inputs[0]), ops.dtypes.int64)
+  batch_size, rows_in, cols_in, channels = input_bhwc[0], input_bhwc[1], \
+                                           input_bhwc[2], input_bhwc[3]
 
   # Create indices matrix for input tensor.
   # Note that 0 is preserved for padding location,
@@ -853,7 +850,8 @@ def _ExtractImagePatchesGrad(op, grad):
       op.get_attr("padding"))
 
   # Create indices matrix for output tensor.
-  _, rows_out, cols_out, _ = [dim.value for dim in op.outputs[0].shape.dims]
+  output_bhwc = math_ops.cast(array_ops.shape(op.outputs[0]), ops.dtypes.int64)
+  rows_out, cols_out = output_bhwc[1], output_bhwc[2]
   _, ksize_r, ksize_c, _ = op.get_attr("ksizes")
   # Indices for output start from 0.
   output_indices_num = rows_out * cols_out * ksize_r * ksize_c

From e67dc75850fe3a54071fdd9db6ad91906ad51797 Mon Sep 17 00:00:00 2001
From: Vasileios Lioutas <contact@vlioutas.com>
Date: Mon, 17 Jun 2019 19:11:19 -0400
Subject: [PATCH 2/4] remove cast and use imported dtypes

---
 tensorflow/python/ops/array_grad.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tensorflow/python/ops/array_grad.py b/tensorflow/python/ops/array_grad.py
index cb3da724761..c51783387ab 100644
--- a/tensorflow/python/ops/array_grad.py
+++ b/tensorflow/python/ops/array_grad.py
@@ -831,7 +831,7 @@ def _QuantizeAndDequantizeV3Grad(_, grad):
 
 @ops.RegisterGradient("ExtractImagePatches")
 def _ExtractImagePatchesGrad(op, grad):
-  input_bhwc = math_ops.cast(array_ops.shape(op.inputs[0]), ops.dtypes.int64)
+  input_bhwc = array_ops.shape(op.inputs[0], out_type=dtypes.int64)
   batch_size, rows_in, cols_in, channels = input_bhwc[0], input_bhwc[1], \
                                            input_bhwc[2], input_bhwc[3]
 
@@ -850,7 +850,7 @@ def _ExtractImagePatchesGrad(op, grad):
       op.get_attr("padding"))
 
   # Create indices matrix for output tensor.
-  output_bhwc = math_ops.cast(array_ops.shape(op.outputs[0]), ops.dtypes.int64)
+  output_bhwc = array_ops.shape(op.outputs[0], out_type=dtypes.int64)
   rows_out, cols_out = output_bhwc[1], output_bhwc[2]
   _, ksize_r, ksize_c, _ = op.get_attr("ksizes")
   # Indices for output start from 0.

From 5b587208fa1f293d69d3694301691ab4c49d217c Mon Sep 17 00:00:00 2001
From: Vasileios Lioutas <contact@vlioutas.com>
Date: Tue, 18 Jun 2019 18:37:03 -0400
Subject: [PATCH 3/4] Remove debug print from unit test

---
 .../python/kernel_tests/extract_image_patches_grad_test.py    | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/tensorflow/python/kernel_tests/extract_image_patches_grad_test.py b/tensorflow/python/kernel_tests/extract_image_patches_grad_test.py
index b7ac616c01f..ebee740f6f5 100644
--- a/tensorflow/python/kernel_tests/extract_image_patches_grad_test.py
+++ b/tensorflow/python/kernel_tests/extract_image_patches_grad_test.py
@@ -100,8 +100,6 @@ class ExtractImagePatchesGradTest(test.TestCase):
 
           err = gradient_checker.compute_gradient_error(in_val, in_shape,
                                                         out_val, out_shape)
-
-          print('extract_image_patches gradient err: %.4e' % err)
           self.assertLess(err, 1e-4)
 
   @test_util.run_deprecated_v1
@@ -152,8 +150,6 @@ class ExtractImagePatchesGradTest(test.TestCase):
 
           err = gradient_checker.compute_gradient_error(in_val, in_shape,
                                                         out_val, out_shape)
-
-          print('extract_image_patches gradient err: %.4e' % err)
           self.assertLess(err, 1e-4)
 
   @test_util.run_deprecated_v1

From e5fe4ccdf9916eb2330c376f20f001e2da403ddc Mon Sep 17 00:00:00 2001
From: Vasileios Lioutas <contact@vlioutas.com>
Date: Wed, 19 Jun 2019 21:27:51 -0400
Subject: [PATCH 4/4] fix hanging indentation

---
 .../python/kernel_tests/extract_image_patches_grad_test.py    | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/tensorflow/python/kernel_tests/extract_image_patches_grad_test.py b/tensorflow/python/kernel_tests/extract_image_patches_grad_test.py
index ebee740f6f5..a394467b105 100644
--- a/tensorflow/python/kernel_tests/extract_image_patches_grad_test.py
+++ b/tensorflow/python/kernel_tests/extract_image_patches_grad_test.py
@@ -136,9 +136,7 @@ class ExtractImagePatchesGradTest(test.TestCase):
         in_shape = test_case['in_shape']
         test_shape = [x if x is None else y
                       for x, y in zip(test_shape_pattern, in_shape)]
-        in_val = array_ops.placeholder(
-          shape=test_shape,
-          dtype=dtypes.float32)
+        in_val = array_ops.placeholder(shape=test_shape, dtype=dtypes.float32)
 
         feed_dict = {in_val: np.random.random(in_shape)}
         for padding in ['VALID', 'SAME']: