1# Copyright 2019 The TensorFlow Authors. All Rights Reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# ============================================================================== 15"""Test configs for strided_slice operators.""" 16from __future__ import absolute_import 17from __future__ import division 18from __future__ import print_function 19 20import numpy as np 21import tensorflow.compat.v1 as tf 22from tensorflow.lite.testing.zip_test_utils import create_tensor_data 23from tensorflow.lite.testing.zip_test_utils import make_zip_of_tests 24from tensorflow.lite.testing.zip_test_utils import register_make_test_function 25from tensorflow.lite.testing.zip_test_utils import TF_TYPE_INFO 26 27 28def _make_strided_slice_tests(options, test_parameters, expected_tf_failures=0): 29 """Utility function to make strided_slice_tests based on parameters.""" 30 31 def build_graph(parameters): 32 """Build graph for stride_slice test.""" 33 input_tensor = tf.compat.v1.placeholder( 34 dtype=parameters["dtype"], 35 name="input", 36 shape=parameters["input_shape"]) 37 if parameters["constant_indices"]: 38 begin = parameters["begin"] 39 end = parameters["end"] 40 strides = parameters["strides"] 41 tensors = [input_tensor] 42 else: 43 begin = tf.compat.v1.placeholder( 44 dtype=parameters["index_type"], 45 name="begin", 46 shape=[len(parameters["begin"])]) 47 end = tf.compat.v1.placeholder( 48 dtype=parameters["index_type"], 49 name="end", 50 shape=[len(parameters["end"])]) 51 strides = None 52 if parameters["strides"] is not None: 53 strides = tf.compat.v1.placeholder( 54 dtype=parameters["index_type"], 55 name="strides", 56 shape=[len(parameters["strides"])]) 57 tensors = [input_tensor, begin, end] 58 if strides is not None: 59 tensors.append(strides) 60 61 kwargs = {} 62 if parameters.get("ellipsis_mask", None): 63 kwargs.update({"ellipsis_mask": parameters["ellipsis_mask"]}) 64 if parameters.get("new_axis_mask", None): 65 kwargs.update({"new_axis_mask": parameters["new_axis_mask"]}) 66 67 out = tf.strided_slice( 68 input_tensor, 69 begin, 70 end, 71 strides, 72 begin_mask=parameters["begin_mask"], 73 end_mask=parameters["end_mask"], 74 shrink_axis_mask=parameters["shrink_axis_mask"], 75 **kwargs) 76 return tensors, [out] 77 78 def build_inputs(parameters, sess, inputs, outputs): 79 """Build inputs for stride_slice test.""" 80 input_values = create_tensor_data( 81 parameters["dtype"], 82 parameters["input_shape"], 83 min_value=-1, 84 max_value=1) 85 index_type = TF_TYPE_INFO[parameters["index_type"]][0] 86 values = [input_values] 87 if not parameters["constant_indices"]: 88 begin_values = np.array(parameters["begin"]).astype(index_type) 89 end_values = np.array(parameters["end"]).astype(index_type) 90 stride_values = ( 91 np.array(parameters["strides"]).astype(index_type) 92 if parameters["strides"] is not None else None) 93 values.append(begin_values) 94 values.append(end_values) 95 if stride_values is not None: 96 values.append(stride_values) 97 98 return values, sess.run(outputs, feed_dict=dict(zip(inputs, values))) 99 100 make_zip_of_tests( 101 options, 102 test_parameters, 103 build_graph, 104 build_inputs, 105 expected_tf_failures=expected_tf_failures) 106 107 108@register_make_test_function() 109def make_strided_slice_tests(options): 110 """Make a set of tests to do strided_slice.""" 111 112 # TODO(soroosh): add test/support for uint8. 113 test_parameters = [ 114 # 4-D (basic cases with const/non-const indices). 115 { 116 "dtype": [tf.float32, tf.int32, tf.int64, tf.bool], 117 "index_type": [tf.int32], 118 "input_shape": [[12, 2, 2, 5]], 119 "strides": [None, [2, 1, 3, 1]], 120 "begin": [[0, 0, 0, 0]], 121 "end": [[12, 2, 2, 5]], 122 "begin_mask": [None], 123 "end_mask": [None], 124 "shrink_axis_mask": [None], 125 "constant_indices": [False, True], 126 "fully_quantize": [False], 127 }, 128 # 4-D with non-trivial begin & end. 129 { 130 "dtype": [tf.float32], 131 "index_type": [tf.int32], 132 "input_shape": [[12, 2, 2, 5]], 133 "begin": [[0, 0, 0, 0], [1, 0, 1, 0]], 134 "end": [[8, 2, 2, 3], [12, 2, 2, 5]], 135 "strides": [None, [2, 1, 3, 1]], 136 "begin_mask": [None, 8], 137 "end_mask": [None, 3], 138 "shrink_axis_mask": [None, 15, -1], 139 "constant_indices": [True], 140 "fully_quantize": [False], 141 }, 142 # Begin, end, strides dim are different from input shape 143 { 144 "dtype": [tf.float32], 145 "index_type": [tf.int32], 146 "input_shape": [[12, 2, 2, 5]], 147 "begin": [[0]], 148 "end": [[1]], 149 "strides": [None, [1]], 150 "begin_mask": [0], 151 "end_mask": [0], 152 "shrink_axis_mask": [1], 153 "constant_indices": [True, False], 154 "fully_quantize": [False], 155 }, 156 # 2-D 157 { 158 "dtype": [tf.float32], 159 "index_type": [tf.int32], 160 "input_shape": [[2, 3]], 161 "begin": [[0, 0]], 162 "end": [[2, 2]], 163 "strides": [None, [2, 2]], 164 "begin_mask": [None, 1, 2], 165 "end_mask": [None, 1, 2], 166 "shrink_axis_mask": [None, 1, 2, 3, -1], 167 "constant_indices": [False, True], 168 "fully_quantize": [False], 169 }, 170 # Negative strides 171 { 172 "dtype": [tf.float32], 173 "index_type": [tf.int32], 174 "input_shape": [[2, 3]], 175 "begin": [[0, -1]], 176 "end": [[2, -3]], 177 "strides": [[1, -1]], 178 "begin_mask": [None, 1, 2], 179 "end_mask": [None, 1, 2], 180 "shrink_axis_mask": [None, 1, 2, 3, -1], 181 "constant_indices": [False], 182 "fully_quantize": [False], 183 }, 184 # 4-D (cases with const indices and batchsize of 1). 185 { 186 "dtype": [tf.float32], 187 "index_type": [tf.int32], 188 "input_shape": [[1, 2, 2, 5]], 189 "strides": [None, [1, 1, 1, 1]], 190 "begin": [[0, 0, 0, 0], [0, 1, 1, 3]], 191 "end": [[1, 2, 2, 5], [1, 2, 2, 4]], 192 "begin_mask": [None], 193 "end_mask": [None], 194 "shrink_axis_mask": [None], 195 "constant_indices": [True], 196 "fully_quantize": [True], 197 }, 198 # Begin, end, strides dim are different from input shape 199 { 200 "dtype": [tf.float32], 201 "index_type": [tf.int32], 202 "input_shape": [[12, 2, 2, 5]], 203 "begin": [[0]], 204 "end": [[1]], 205 "strides": [None, [1]], 206 "begin_mask": [0], 207 "end_mask": [0], 208 "shrink_axis_mask": [1], 209 "constant_indices": [True], 210 "fully_quantize": [True], 211 }, 212 ] 213 214 if options.use_experimental_converter: 215 test_parameters = test_parameters + [ 216 # Begin equal to input dim. 217 { 218 "dtype": [tf.float32], 219 "index_type": [tf.int32], 220 "input_shape": [[1, 1, 2]], 221 "begin": [[1]], 222 "end": [[0]], 223 "strides": [[1]], 224 "begin_mask": [0], 225 "end_mask": [1], 226 "shrink_axis_mask": [0], 227 "constant_indices": [True, False], 228 "fully_quantize": [False], 229 }, 230 { 231 "dtype": [tf.float32], 232 "index_type": [tf.int32], 233 "input_shape": [[1, 1, 2]], 234 "begin": [[1, 0, 0]], 235 "end": [[0, -1, -1]], 236 "strides": [[1, 1, 1]], 237 "begin_mask": [6], 238 "end_mask": [7], 239 "shrink_axis_mask": [0], 240 "constant_indices": [True, False], 241 "fully_quantize": [False], 242 }, 243 # String input. 244 { 245 "dtype": [tf.string], 246 "index_type": [tf.int32], 247 "input_shape": [[12, 2, 2, 5]], 248 "begin": [[0, 0, 0, 0]], 249 "end": [[8, 2, 2, 3]], 250 "strides": [[2, 1, 3, 1]], 251 "begin_mask": [8], 252 "end_mask": [3], 253 "shrink_axis_mask": [None], 254 "constant_indices": [True, False], 255 "fully_quantize": [False], 256 }, 257 # ellipsis_mask and new_axis_mask. 258 { 259 "dtype": [tf.float32], 260 "index_type": [tf.int32], 261 "input_shape": [[5, 5, 7, 7]], 262 "begin": [[0, 0, 0, 0]], 263 "end": [[2, 3, 4, 5]], 264 "strides": [[1, 1, 1, 1]], 265 "begin_mask": [0, 8], 266 "end_mask": [0, 2], 267 "shrink_axis_mask": [0, 4], 268 "ellipsis_mask": [2, 4], 269 "new_axis_mask": [1, 6], 270 "constant_indices": [True], 271 "fully_quantize": [False], 272 }, 273 { 274 "dtype": [tf.float32], 275 "index_type": [tf.int32], 276 "input_shape": [[5, 6, 7]], 277 "begin": [[0, 0, 0]], 278 "end": [[2, 3, 4]], 279 "strides": [[1, 1, 1]], 280 "begin_mask": [0], 281 "end_mask": [0], 282 "shrink_axis_mask": [0, 2], 283 "ellipsis_mask": [2], 284 "new_axis_mask": [1, 2, 3, 4, 5], 285 "constant_indices": [False], 286 "fully_quantize": [False], 287 }, 288 # Shrink_axis and add_axis mask both set 289 { 290 "dtype": [tf.float32], 291 "index_type": [tf.int32], 292 "input_shape": [[6, 7, 8]], 293 "begin": [[0, 0, 0, 0]], 294 "end": [[2, 3, 4, 5]], 295 "strides": [[1, 1, 1, 1]], 296 "begin_mask": [0], 297 "end_mask": [0], 298 "new_axis_mask": [10], 299 "shrink_axis_mask": [1], 300 "constant_indices": [True], 301 "fully_quantize": [False], 302 }, 303 ] 304 _make_strided_slice_tests(options, test_parameters, expected_tf_failures=29) 305 306 307@register_make_test_function() 308def make_strided_slice_1d_exhaustive_tests(options): 309 """Make a set of exhaustive tests for 1D strided_slice.""" 310 test_parameters = [ 311 # 1-D Exhaustive 312 { 313 "dtype": [tf.float32], 314 "index_type": [tf.int32], 315 "input_shape": [[3]], 316 "begin": [[-2], [-1], [0], [1], [2]], 317 "end": [[-2], [-1], [0], [1], [2]], 318 "strides": [[-2], [-1], [1], [2]], 319 "begin_mask": [0, 1], 320 "end_mask": [0, 1], 321 "shrink_axis_mask": [0], 322 "constant_indices": [False], 323 }, 324 ] 325 _make_strided_slice_tests(options, test_parameters) 326