Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Branch 198913026 #19701

Merged
merged 30 commits into from
Jun 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2f97b2f
[tf.data] Changed parsing logic for CsvDataset for better performance…
Jun 1, 2018
16c6cac
Raise the test timeout for tensorflow/python:warm_starting_util_test …
hawkinsp Jun 1, 2018
d3095c9
Automated g4 rollback of changelist 198812512
tensorflower-gardener Jun 1, 2018
3df9efb
Add a single positional argument mode for shape inference in subclass…
allenlavoie Jun 1, 2018
8d1d8c1
Disable tensorflow/contrib/stat_summarizer:stat_summarizer_test from …
hawkinsp Jun 1, 2018
54b20c4
Making sure that weight_collections are respected for shared_embeddin…
rohan100jain Jun 1, 2018
961a393
Unify error handling in CudnnSupport.
tensorflower-gardener Jun 1, 2018
73e5438
Remove the constructor in shared memory.
zheng-xq Jun 1, 2018
c9fb2a5
Use ConstantDataArray to lower arrays of constants.
tensorflower-gardener Jun 1, 2018
246a056
Fix a bug for unspecified dtype of acc_shape that can cause type mism…
tensorflower-gardener Jun 1, 2018
347e69f
Support bfloat16 in LiteralBase::Slice
tensorflower-gardener Jun 1, 2018
75a7b91
Mark tensorflow/python/kernel_tests/linalg:linear_operator_identity_t…
hawkinsp Jun 1, 2018
e6aca21
Disable test on windows until we figure out what's wrong.
Jun 1, 2018
4349f66
Resubmitting CL 196349902: Adding cuDNN header dependency to targets …
tensorflower-gardener Jun 1, 2018
ccbb840
implement a generic reduce method so that later we can easily impleme…
tensorflower-gardener Jun 1, 2018
46cd110
Automated g4 rollback of changelist 198810875
hawkinsp Jun 1, 2018
6bb35f8
Automated g4 rollback of changelist 198815200
Jun 1, 2018
662c5dd
remove typo
gunan Jun 1, 2018
6a7cd2e
Fixed a bug introduced by cl/197941474.
benoitsteiner Jun 1, 2018
dae529b
Fix ProfileSummarizer build, use properly qualified string references.
shashishekhar Jun 1, 2018
72314bf
Add a dependency optimization that eliminates multiple cross-device c…
hawkinsp Jun 1, 2018
bb94c57
Fix bug in eager documentation.
akshayka Jun 1, 2018
6b76b64
Updates Interpreter to be initialized with a MappedByteBuffer for bac…
tensorflower-gardener Jun 1, 2018
46afa1f
Amend cluster resolver error to suggest oauth2client as a possible is…
tensorflower-gardener Jun 1, 2018
229a6fb
Printing bools in graphviz.
tensorflower-gardener Jun 1, 2018
508860f
[TF2XLA] Decompose resize bilinear with large filters to work on dime…
blakehechtman Jun 1, 2018
5fa6409
[TF:XLA] Bump open source llvm revision to r333578
Jun 1, 2018
10b2b3b
[TF:XLA] Refactor implementation of TruncatedNormal to avoid redundan…
hawkinsp Jun 1, 2018
b812f37
TFLite: adding tile and expand_dims ops.
tensorflower-gardener Jun 1, 2018
1e9a8e9
Merge commit for internal changes
Jun 1, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 10 additions & 1 deletion tensorflow/compiler/jit/xla_device_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,16 @@ class XlaAssignVariableOp : public AsyncOpKernel {
REGISTER_KERNEL_BUILDER(Name("Switch").Device(DEVICE).HostMemory("pred"), \
SwitchOp); \
REGISTER_KERNEL_BUILDER( \
Name("Merge").Device(DEVICE).HostMemory("value_index"), MergeOp);
Name("Merge").Device(DEVICE).HostMemory("value_index"), MergeOp); \
REGISTER_KERNEL_BUILDER(Name("Enter").Device(DEVICE), EnterOp); \
REGISTER_KERNEL_BUILDER(Name("Exit").Device(DEVICE), ExitOp); \
REGISTER_KERNEL_BUILDER(Name("NextIteration").Device(DEVICE), \
NextIterationOp); \
REGISTER_KERNEL_BUILDER(Name("LoopCond") \
.Device(DEVICE) \
.HostMemory("input") \
.HostMemory("output"), \
LoopCondOp);

} // namespace tensorflow

Expand Down
39 changes: 31 additions & 8 deletions tensorflow/compiler/tests/image_ops_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,7 @@ def testBatch(self):
join1 = array_ops.stack(split1)
join2 = array_ops.stack(split2)
batch1, batch2, join1, join2 = sess.run([batch1, batch2, join1, join2],
{
batch0: inp
})
{batch0: inp})

# Verify that processing batch elements together is the same as separate
self.assertAllClose(batch1, join1)
Expand Down Expand Up @@ -401,9 +399,7 @@ def testAdjustRandomSaturation(self):
x = array_ops.placeholder(dtypes.float32, shape=x_shape)
with self.test_scope():
y_fused = self._adjust_saturation(x,
scale).eval(feed_dict={
x: x_np
})
scale).eval(feed_dict={x: x_np})
self.assertAllClose(y_fused, y_baseline, rtol=2e-5, atol=1e-5)


Expand All @@ -412,15 +408,20 @@ class ResizeBilinearTest(XLATestCase):
def _assertForwardOpMatchesExpected(self,
image_np,
target_shape,
expected=None):
expected=None,
large_tolerance=False):
if expected is None:
self.fail("expected must be specified")
with self.test_session() as sess, self.test_scope():
image = array_ops.placeholder(image_np.dtype)
resized = gen_image_ops.resize_bilinear(
image, target_shape, align_corners=True)
out = sess.run(resized, {image: image_np[np.newaxis, :, :, np.newaxis]})
self.assertAllClose(expected[np.newaxis, :, :, np.newaxis], out)
if large_tolerance:
self.assertAllClose(
expected[np.newaxis, :, :, np.newaxis], out, rtol=0.03, atol=0.1)
else:
self.assertAllClose(expected[np.newaxis, :, :, np.newaxis], out)

def _assertBackwardOpMatchesExpected(self,
grads_np,
Expand Down Expand Up @@ -555,6 +556,28 @@ def testAlignCorners3x3To9x9Grad(self):
[[12.5, 27.5, 21.875], [42.5, 80.0, 57.5], [40.625, 72.5, 50]],
dtype=np.float32))

def testAlignCorners4x4To8x8(self):
self._assertForwardOpMatchesExpected(
(np.array([[0, 1, 2, 3]], dtype=np.float32) + np.array(
[[0], [1], [2], [3]], dtype=np.float32)) * 7.0, [8, 8],
expected=3 *
(np.array([[0, 1, 2, 3, 4, 5, 6, 7]], dtype=np.float32) + np.array(
[[0], [1], [2], [3], [4], [5], [6], [7]], dtype=np.float32)),
large_tolerance=True)

def testAlignCorners8x8To16x16(self):
self._assertForwardOpMatchesExpected(
(np.array([[0, 1, 2, 3, 4, 5, 6, 7]], dtype=np.float32) + np.array(
[[0], [1], [2], [3], [4], [5], [6], [7]], dtype=np.float32)) * 15.0,
[16, 16],
expected=7 * (np.array(
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]],
dtype=np.float32) + np.array(
[[0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11],
[12], [13], [14], [15]],
dtype=np.float32)),
large_tolerance=True)


if __name__ == "__main__":
test.main()
7 changes: 7 additions & 0 deletions tensorflow/compiler/tests/random_ops_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ def testRandomUniformIsInRange(self):
self.assertTrue((y >= -2).sum() == 1000)
self.assertTrue((y < 33).sum() == 1000)

def testTruncatedNormalIsNotConstant(self):
def rng(dtype):
return random_ops.truncated_normal(shape=[2], dtype=dtype)

# TODO(b/34339814): implement inverse erf support for non-F32 types.
self._testRngIsNotConstant(rng, dtypes.float32)

def testTruncatedNormalIsInRange(self):
count = 10000
# TODO(b/34339814): implement inverse erf support for non-F32 types.
Expand Down
183 changes: 137 additions & 46 deletions tensorflow/compiler/tf2xla/kernels/image_resize_ops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,27 +99,34 @@ ResizeConvolutionDims ComputeResizeConvolutionParameters(
return dims;
}

// Form a 2D convolution kernel like:
// 1 2 3 2 1
// 2 4 6 4 2
// 1/9 * 3 6 9 6 3
// 2 4 6 4 2
// 1 2 3 2 1
// by multiplying two 1D kernels of the form:
// 1/3 * [1 2 3 2 1]
// If the 2D kernel would be very large, the 1D kernel can be applied once in
// each dimension due to the symmetry of the kernel along all axis to reduce the
// computational intensity.
std::vector<float> Make1DKernel(int64 n) {
std::vector<float> kernel(n * 2 - 1);
for (int64 i = 0; i < n; ++i) {
float v = (i + 1.0f) / n;
kernel[i] = v;
kernel[n * 2 - 2 - i] = v;
}
return kernel;
}

// Kernels with more than 16 spatial elements are considered intense and the
// kernel should applied to each dimension independently.
const int64 kMax2DKernelSize = 16;

xla::XlaOp MakeBilinearResizeKernel(xla::XlaBuilder* builder,
gtl::ArraySlice<int64> kernel_size,
int64 channels) {
// Form a 2D convolution kernel like:
// 1 2 3 2 1
// 2 4 6 4 2
// 1/9 * 3 6 9 6 3
// 2 4 6 4 2
// 1 2 3 2 1
// by multiplying two 1D kernels of the form:
// 1/3 * [1 2 3 2 1]
auto make_1d_kernel = [](int64 n) {
std::vector<float> kernel(n * 2 - 1);
for (int64 i = 0; i < n; ++i) {
float v = (i + 1.0f) / n;
kernel[i] = v;
kernel[n * 2 - 2 - i] = v;
}
return kernel;
};

xla::XlaOp channels_iota;
// DT_INT32 Iota will always return status::OK().
TF_CHECK_OK(
Expand All @@ -133,12 +140,37 @@ xla::XlaOp MakeBilinearResizeKernel(xla::XlaBuilder* builder,
xla::PrimitiveType::F32);
return builder->Mul(
builder->Mul(diag,
builder->ConstantR1<float>(make_1d_kernel(kernel_size[1])),
builder->ConstantR1<float>(Make1DKernel(kernel_size[1])),
/*broadcast_dimensions=*/{1}),
builder->ConstantR1<float>(make_1d_kernel(kernel_size[0])),
builder->ConstantR1<float>(Make1DKernel(kernel_size[0])),
/*broadcast_dimensions=*/{0});
}

xla::XlaOp MakeBilinearResizeKernelInDim(xla::XlaBuilder* builder,
gtl::ArraySlice<int64> kernel_size,
int64 channels, int64 dim) {
xla::XlaOp channels_iota;
// DT_INT32 Iota will always return status::OK().
TF_CHECK_OK(
XlaHelpers::Iota(builder, DataType::DT_INT32, channels, &channels_iota));

auto diag = builder->ConvertElementType(
builder->Eq(builder->Broadcast(
channels_iota,
{dim == 0 ? (2 * kernel_size[0] - 1) : 1,
dim == 1 ? (2 * kernel_size[1] - 1) : 1, channels}),
channels_iota, /*broadcast_dimensions=*/{2}),
xla::PrimitiveType::F32);
if (dim == 1) {
return builder->Mul(
diag, builder->ConstantR1<float>(Make1DKernel(kernel_size[1])),
/*broadcast_dimensions=*/{1});
}
return builder->Mul(diag,
builder->ConstantR1<float>(Make1DKernel(kernel_size[0])),
/*broadcast_dimensions=*/{0});
}

xla::XlaOp ResizeUsingDilationAndConvolution(xla::XlaBuilder* builder,
const xla::XlaOp& input,
const int num_spatial_dims,
Expand Down Expand Up @@ -170,15 +202,37 @@ xla::XlaOp ResizeUsingDilationAndConvolution(xla::XlaBuilder* builder,

ResizeConvolutionDims dims =
ComputeResizeConvolutionParameters(in_size, out_size);
xla::XlaOp kernel =
MakeBilinearResizeKernel(builder, dims.kernel_size, channels);
xla::XlaOp output = builder->ConvGeneralDilated(
input, kernel, dims.stride,
/*padding=*/
{{dims.kernel_size[0] - 1, dims.kernel_size[0] - 1},
{dims.kernel_size[1] - 1, dims.kernel_size[1] - 1}},
/*lhs_dilation=*/dims.kernel_size,
/*rhs_dilation=*/{1, 1}, dimension_numbers);
xla::XlaOp output;
// Split convolutions into independent dimensions if they wmuld be a very
// large kernel.
if (dims.kernel_size[0] * dims.kernel_size[1] < kMax2DKernelSize) {
xla::XlaOp kernel =
MakeBilinearResizeKernel(builder, dims.kernel_size, channels);
output = builder->ConvGeneralDilated(
input, kernel, dims.stride,
/*padding=*/
{{dims.kernel_size[0] - 1, dims.kernel_size[0] - 1},
{dims.kernel_size[1] - 1, dims.kernel_size[1] - 1}},
/*lhs_dilation=*/dims.kernel_size,
/*rhs_dilation=*/{1, 1}, dimension_numbers);
} else {
xla::XlaOp kernel0 =
MakeBilinearResizeKernelInDim(builder, dims.kernel_size, channels, 0);
output = builder->ConvGeneralDilated(
input, kernel0, {dims.stride[0], 1},
/*padding=*/
{{dims.kernel_size[0] - 1, dims.kernel_size[0] - 1}, {0, 0}},
/*lhs_dilation=*/{dims.kernel_size[0], 1},
/*rhs_dilation=*/{1, 1}, dimension_numbers);
xla::XlaOp kernel1 =
MakeBilinearResizeKernelInDim(builder, dims.kernel_size, channels, 1);
output = builder->ConvGeneralDilated(
output, kernel1, {1, dims.stride[1]},
/*padding=*/
{{0, 0}, {dims.kernel_size[1] - 1, dims.kernel_size[1] - 1}},
/*lhs_dilation=*/{1, dims.kernel_size[1]},
/*rhs_dilation=*/{1, 1}, dimension_numbers);
}

// Add broadcasts to handle expanding from a size == 1 dimension to a
// size > 1 dimension.
Expand Down Expand Up @@ -214,26 +268,63 @@ xla::XlaOp ResizeUsingDilationAndConvolutionGradOp(xla::XlaBuilder* builder,
}
dimension_numbers.set_kernel_input_feature_dimension(num_spatial_dims);
dimension_numbers.set_kernel_output_feature_dimension(num_spatial_dims + 1);
xla::XlaOp kernel =
MakeBilinearResizeKernel(builder, dims.kernel_size, channels);
xla::XlaOp output;
if (dims.kernel_size[0] * dims.kernel_size[1] < kMax2DKernelSize) {
xla::XlaOp kernel =
MakeBilinearResizeKernel(builder, dims.kernel_size, channels);

// Broadcast the input kernel where the forward op expanded from a size == 1
// dimension to a size > 1 dimension. This has the effect of summing the
// gradient contributions in that dimension.
for (int i = 0; i < num_spatial_dims; ++i) {
if (in_size[i] == 1 && grad_size[i] > 1) {
kernel =
builder->Add(kernel, builder->ConstantR1<float>(grad_size[i], 0),
/*broadcast_dimensions=*/{i});
}
}

// Broadcast the input kernel where the forward op expanded from a size == 1
// dimension to a size > 1 dimension. This has the effect of summing the
// gradient contributions in that dimension.
for (int i = 0; i < num_spatial_dims; ++i) {
if (in_size[i] == 1 && grad_size[i] > 1) {
kernel = builder->Add(kernel, builder->ConstantR1<float>(grad_size[i], 0),
/*broadcast_dimensions=*/{i});
output = builder->ConvGeneralDilated(
grad, kernel, /*window_strides=*/dims.kernel_size,
/*padding=*/
{{dims.kernel_size[0] - 1, dims.kernel_size[0] - 1},
{dims.kernel_size[1] - 1, dims.kernel_size[1] - 1}},
/*lhs_dilation=*/dims.stride,
/*rhs_dilation=*/{1, 1}, dimension_numbers);
} else {
xla::XlaOp kernel0 =
MakeBilinearResizeKernelInDim(builder, dims.kernel_size, channels, 0);
xla::XlaOp kernel1 =
MakeBilinearResizeKernelInDim(builder, dims.kernel_size, channels, 1);

// Broadcast the input kernel where the forward op expanded from a size == 1
// dimension to a size > 1 dimension. This has the effect of summing the
// gradient contributions in that dimension.
if (in_size[0] == 1 && grad_size[0] > 1) {
kernel0 =
builder->Add(kernel0, builder->ConstantR1<float>(grad_size[0], 0),
/*broadcast_dimensions=*/{0});
}
if (in_size[1] == 1 && grad_size[1] > 1) {
kernel1 =
builder->Add(kernel0, builder->ConstantR1<float>(grad_size[1], 0),
/*broadcast_dimensions=*/{1});
}
}

xla::XlaOp output = builder->ConvGeneralDilated(
grad, kernel, /*window_strides=*/dims.kernel_size,
/*padding=*/
{{dims.kernel_size[0] - 1, dims.kernel_size[0] - 1},
{dims.kernel_size[1] - 1, dims.kernel_size[1] - 1}},
/*lhs_dilation=*/dims.stride,
/*rhs_dilation=*/{1, 1}, dimension_numbers);
output = builder->ConvGeneralDilated(
grad, kernel0, /*window_strides=*/{dims.kernel_size[0], 1},
/*padding=*/
{{dims.kernel_size[0] - 1, dims.kernel_size[0] - 1}, {0, 0}},
/*lhs_dilation=*/{dims.stride[0], 1},
/*rhs_dilation=*/{1, 1}, dimension_numbers);

output = builder->ConvGeneralDilated(
output, kernel1, /*window_strides=*/{1, dims.kernel_size[1]},
/*padding=*/
{{0, 0}, {dims.kernel_size[1] - 1, dims.kernel_size[1] - 1}},
/*lhs_dilation=*/{1, dims.stride[1]},
/*rhs_dilation=*/{1, 1}, dimension_numbers);
}

// If in_size[i] > 1 and grad_size[i] == 1, pad the output in dimension i.
// Opposite of the slice performed by the forward op.
Expand Down