Address review (stage 1) of PR 55739
diff --git a/tensorflow/python/kernel_tests/nn_ops/BUILD b/tensorflow/python/kernel_tests/nn_ops/BUILD
index 242334d9..164761b 100644
--- a/tensorflow/python/kernel_tests/nn_ops/BUILD
+++ b/tensorflow/python/kernel_tests/nn_ops/BUILD
@@ -281,6 +281,7 @@
"//tensorflow/python:constant_op",
"//tensorflow/python:dtypes",
"//tensorflow/python:nn_ops",
+ "//tensorflow/python/eager:backprop",
"//third_party/py/numpy",
],
)
diff --git a/tensorflow/python/kernel_tests/nn_ops/cudnn_deterministic_base.py b/tensorflow/python/kernel_tests/nn_ops/cudnn_deterministic_base.py
index 77851ff..7a9793a 100644
--- a/tensorflow/python/kernel_tests/nn_ops/cudnn_deterministic_base.py
+++ b/tensorflow/python/kernel_tests/nn_ops/cudnn_deterministic_base.py
@@ -18,6 +18,7 @@
import numpy as np
+from tensorflow.python.eager import backprop
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import test_util
@@ -106,9 +107,10 @@
in_op, filter_op, strides=[1, 1, 1, 1, 1], padding='VALID',
data_format='NCDHW', dilations=[1, 1, 2, 2, 2]))
- # This test intends to exercise nondeterminism of convolution in the forward
- # direction for XLA only. cuDNN does not have nondeterministic forward
- # convolution algorithms.
+ # This test is primarily testing XLA since cuDNN forward convolutions are
+ # always deterministic, even when determinism is not enabled. The convolution
+ # configuration tested is nondeterministic with XLA when determinism is not
+ # enabled.
@test_util.run_cuda_only
def testConvForwardXLA(self):
in_shape = LayerShapeNCDHW(
@@ -137,7 +139,7 @@
dilations=dilations))
# A configuration for this test could not be found that exercises
- # nondeterminism on XLA.
+ # nondeterminism when using XLA with determinism not enabled.
@test_util.run_cuda_only
def testConvBackwardFilterGradientWithDilations(self):
self.testConvBackwardFilterGradient(rate=2)
@@ -158,14 +160,11 @@
dilations=dilations))
# A configuration for this test could not be found that exercises
- # nondeterminism on XLA.
+ # nondeterminism when using XLA with determinism not enabled.
@test_util.run_cuda_only
def testConvBackwardInputGradientWithDilations(self):
self.testConvBackwardInputGradient(rate=2)
- # A 2D convolution configuration that exercises nondeterminism in the forward
- # direction (i.e. tf.nn.conv2d) using XLA was not found and therefore no tests
- # for the backprop of tf.nn.conv2d_transpose have been included.
@test_util.run_cuda_only
def testConvTransposeForward(self, rate=1):
in_channels = 3; out_channels = 1
@@ -183,7 +182,71 @@
data_format='NHWC', dilations=[1, rate, rate, 1]))
# A configuration for this test could not be found that exercises
- # nondeterminism on XLA.
+ # nondeterminism when using XLA with determinism not enabled.
@test_util.run_cuda_only
def testConvTransposeForwardWithDilations(self):
self.testConvTransposeForward(rate=2)
+
+ @test_util.run_cuda_only
+ def testConvTransposeBackwardFilterGradient(self, rate=1):
+ in_channels = 8; out_channels = 8
+ in_shape = LayerShapeNHWC(
+ batch=8, height=64, width=64, channels=in_channels)
+ filter_shape = FilterShape2DTranspose(
+ height=3, width=3, out_channels=out_channels, in_channels=in_channels)
+ in_op = self._random_data_op(in_shape)
+ filter_op = self._random_data_op(filter_shape)
+ out_shape = LayerShapeNHWC(
+ batch=in_shape.batch, height=in_shape.height, width=in_shape.width,
+ channels=out_channels)
+ upstream_gradients = self._random_data_op(out_shape)
+
+ def gradient():
+ with backprop.GradientTape() as tape:
+ tape.watch(filter_op)
+ op_output = nn_ops.conv2d_transpose_v2(
+ in_op, filter_op, out_shape, strides=1, padding='SAME',
+ data_format='NHWC', dilations=[1, rate, rate, 1])
+ gradient_injector_output = op_output * upstream_gradients
+ return tape.gradient(gradient_injector_output, [filter_op])[0]
+
+ self._assert_reproducible(gradient)
+
+ # A configuration for this test could not be found that exercises
+ # nondeterminism when using XLA with determinism not enabled.
+ @test_util.run_cuda_only
+ def testConvTransposeBackwardFilterGradientWithDilations(self, rate=1):
+ self.testConvTransposeBackwardFilterGradient(rate=2)
+
+ # A configuration for this test could not be found that exercises
+ # nondeterminism when determinism is not enabled (for either XLA or non-XLA).
+ @test_util.run_cuda_only
+ def testConvTransposeBackwardInputGradient(self, rate=1):
+ in_channels = 1; out_channels = 3
+ in_shape = LayerShapeNHWC(
+ batch=1, height=16, width=16, channels=in_channels)
+ filter_shape = FilterShape2DTranspose(
+ height=7, width=7, out_channels=out_channels, in_channels=in_channels)
+ in_op = self._random_data_op(in_shape)
+ filter_op = self._random_data_op(filter_shape)
+ out_shape = LayerShapeNHWC(
+ batch=in_shape.batch, height=in_shape.height, width=in_shape.width,
+ channels=out_channels)
+ upstream_gradients = self._random_data_op(out_shape)
+
+ def gradient():
+ with backprop.GradientTape() as tape:
+ tape.watch(in_op)
+ op_output = nn_ops.conv2d_transpose_v2(
+ in_op, filter_op, out_shape, strides=1, padding='SAME',
+ data_format='NHWC', dilations=[1, rate, rate, 1])
+ gradient_injector_output = op_output * upstream_gradients
+ return tape.gradient(gradient_injector_output, [in_op])[0]
+
+ self._assert_reproducible(gradient)
+
+ # A configuration for this test could not be found that exercises
+ # nondeterminism when determinism is not enabled (for either XLA or non-XLA).
+ @test_util.run_cuda_only
+ def testConvTransposeBackwardInputGradientWithDilations(self, rate=1):
+ self.testConvTransposeBackwardInputGradient(rate=2)