Fixed the shape function of the SplitV op that incorrectly often assumed that
authorBenoit Steiner <bsteiner@google.com>
Thu, 29 Mar 2018 04:07:02 +0000 (21:07 -0700)
committerTensorFlower Gardener <gardener@tensorflow.org>
Thu, 29 Mar 2018 04:09:28 +0000 (21:09 -0700)
the shape of all the outputs is the same.

PiperOrigin-RevId: 190879600

tensorflow/contrib/signal/python/kernel_tests/shape_ops_test.py
tensorflow/contrib/signal/python/ops/shape_ops.py
tensorflow/core/ops/array_ops.cc

index bc4663f..64cc8c7 100644 (file)
@@ -338,10 +338,7 @@ class FrameTest(test.TestCase):
 
   def test_constant_folding(self):
     """frame should be constant foldable for constant inputs."""
-    # Padding is incorrectly defined in shape_ops.py (the rank of the padding
-    # tensor should be equal to the rank of the input tensor + 1): only test
-    # with padding set to False to avoid this.
-    for pad_end in [False]:
+    for pad_end in [True, False]:
       g = ops.Graph()
       with g.as_default():
         frame_length, frame_step = 32, 16
index 97fe208..1ddc294 100644 (file)
@@ -139,8 +139,6 @@ def frame(signal, frame_length, frame_step, pad_end=False, pad_value=0, axis=-1,
            [[0, pad_samples]],
            array_ops.zeros([num_inner_dimensions, 2], dtype=pad_samples.dtype)],
           0)
-      # TODO(rjryan): the paddings tensor must of rank tf.rank(signal) + 1. This
-      # isn't the case here and should be fixed.
       signal = array_ops.pad(signal, paddings, constant_values=pad_value)
 
       signal_shape = array_ops.shape(signal)
index 88d2aa3..af8afc9 100644 (file)
@@ -494,9 +494,9 @@ REGISTER_OP("SplitV")
       const Tensor* size_splits = c->input_tensor(1);
       if (rank == InferenceContext::kUnknownRank) {
         // If the rank of input tensor is unknown, then return unknown shapes.
-        output_shape = c->UnknownShape();
+        // Note that the shape of each output can be different.
         for (int i = 0; i < num_outputs; ++i) {
-          c->set_output(i, output_shape);
+          c->set_output(i, c->UnknownShape());
         }
       } else if (rank == 0) {
         // Throw error if input is a scalar.
@@ -505,18 +505,19 @@ REGISTER_OP("SplitV")
         // If split dimension is known, but the sizes are unknown, then
         // only the split dimension is unknown
         output_shape = input;
-        TF_RETURN_IF_ERROR(c->ReplaceDim(output_shape,
-                                         c->Value(split_dimension),
-                                         c->UnknownDim(), &output_shape));
         for (int i = 0; i < num_outputs; ++i) {
+          TF_RETURN_IF_ERROR(c->ReplaceDim(output_shape,
+                                           c->Value(split_dimension),
+                                           c->UnknownDim(), &output_shape));
           c->set_output(i, output_shape);
         }
       } else if (size_splits == nullptr && !c->ValueKnown(split_dimension)) {
         // If split dimension or tensor containing the split sizes is unknown,
-        // then return unknown shapes of same rank as input.
-        output_shape = c->UnknownShapeOfRank(rank);
+        // then return unknown shapes of same rank as input. Note that each
+        // output shape can be different since splitv doesn't always split
+        // tensors evenly.
         for (int i = 0; i < num_outputs; ++i) {
-          c->set_output(i, output_shape);
+          c->set_output(i, c->UnknownShapeOfRank(rank));
         }
       } else {
         // Determine the output shape if split dimension and split sizes are