def test_ne(self): value_1a = value.InputValue(tf.constant([1, 2]), 'a') value_1b = value.OutputValue(tf.constant([1, 2])) value_2 = value.InputValue(tf.constant([1, 3]), 'a') # We want to explicitly test __ne__. self.assertFalse(value_1a != value_1b) # pylint: disable=g-generic-assert self.assertTrue(value_1a != value_2) # pylint: disable=g-generic-assert
def is_castable(to_cast, dtype): """Returns whether `to_cast` (a Value) can be safely casted to the dtype. This filtering strategy is a workaround for undefined behavior in TensorFlow (b/119633897). Args: to_cast: A Value object that would be casted. dtype: A Value containing a tf.DType that `to_cast` would be casted to. """ if not dtype.is_int_dtype(): return True # We can always cast to a non-int dtype. to_cast_value = to_cast.value if to_cast.is_sparse_tensor: to_cast_value = to_cast.value.values if to_cast.is_tensor or to_cast.is_sparse_tensor: if not to_cast.has_float_dtype(): return True # Only float -> int is potentially unsafe. if not _check_tensor_finite(to_cast_value): return False # Non-finite floats cannot be casted to int dtypes. elif to_cast.is_sequence: if to_cast.elem_type is float: if float('nan') in to_cast_value: return False # inf and -inf will be caught by the min/max logic. elif to_cast.elem_type_is_tensor: return all( tf.size(element) and is_castable( value_module.InputValue(element, 'dummy'), to_cast) for element in to_cast_value) elif to_cast.elem_type_is_sparse_tensor: return all( tf.size(element.values) and is_castable( value_module.InputValue(element, 'dummy'), to_cast) for element in to_cast_value) else: return True # Only lists of floats or float tensors can be unsafe. elif to_cast.type is float: if math.isnan(to_cast_value): return False else: return True min_int, max_int = tf_coder_utils.INT_DTYPE_MIN_MAX[dtype.value] # Floats are truncated when casted to int (nearest int in the zero direction). # Assuming min_int <= 0, the minimum safe float is (min_int - 1 + epsilon), # and the maximum safe float is (max_int + 1 - epsilon). return to_cast.min() > min_int - 1 and to_cast.max() < max_int + 1
def test_reconstruct_all_expressions_with_input_names(self): input_0 = value.InputValue(0, 'in_0') constant_1 = value.ConstantValue(1) constant_2 = value.ConstantValue(2) my_input = value.InputValue([[1, 3, 2], [-3, 0, 4]], 'my_input') final_value = self.operation.apply([my_input, constant_1], self.settings) add_operation = function_operation.FunctionOperation( tf_functions.FunctionInfo( name='tf.add(x, y)', filter_group=filter_group.FilterGroup.NONE, weight=1)) input_1321 = value.InputValue([[1, 3], [2, 1]], 'in_1321') value_2432 = add_operation.apply([input_1321, constant_1], self.settings) input_0210 = value.InputValue([[0, 2], [1, 0]], 'in_0210') value_2432_duplicate = add_operation.apply([input_0210, constant_2], self.settings) self.assertEqual(value_2432, value_2432_duplicate) value_2432.merge_reconstructions(value_2432_duplicate) final_value_duplicate = self.operation.apply([value_2432, input_0], self.settings) self.assertEqual(final_value, final_value_duplicate) final_value.merge_reconstructions(final_value_duplicate) input_1430 = value.InputValue([[1, 4], [3, 0]], 'in_1430') final_value_duplicate = self.operation.apply([input_1430, input_0], self.settings) self.assertEqual(final_value, final_value_duplicate) final_value.merge_reconstructions(final_value_duplicate) expected = [ ('tf.reduce_max(my_input, axis=1)', {'my_input'}), ('tf.reduce_max(tf.add(in_1321, 1), axis=in_0)', {'in_1321', 'in_0'}), ('tf.reduce_max(tf.add(in_0210, 2), axis=in_0)', {'in_0210', 'in_0'}), ('tf.reduce_max(in_1430, axis=in_0)', {'in_1430', 'in_0'}), ] self.assertEqual( final_value.reconstruct_all_expressions_with_input_names(), expected)
def test_merge_reconstructions(self): tensor_value = value.InputValue([[1, 3, 2], [-3, 0, 4]], 'my_input') axis_value = value.ConstantValue(1) operation_value = self.operation.apply([tensor_value, axis_value], self.settings) self.assertLen(operation_value.operation_applications, 1) tensor_value_2 = value.InputValue([[1, 4], [3, 0]], 'my_input_2') axis_value_2 = value.ConstantValue(0) operation_value_2 = self.operation.apply([tensor_value_2, axis_value_2], self.settings) self.assertEqual(operation_value, operation_value_2) operation_value.merge_reconstructions(operation_value_2) self.assertLen(operation_value.operation_applications, 2)
def setUp(self): super(SlicingAxis1RightOperationTest, self).setUp() self.operation = python_operations.SlicingAxis1RightOperation() self.arg_values = [ value.InputValue([[12, 34, 56]], 'my_input'), value.ConstantValue(-1) ]
def extract_values_with_collapsed_subtrees( value: value_module.Value) -> List[value_module.Value]: """Collapses subtrees, see docstring of extract_examples_from_value.""" if not isinstance(value, value_module.OperationValue): # Base case: the value is a leaf. return [value] value = typing.cast(value_module.OperationValue, value) results = [] # type: List[value_module.Value] # Each OperationApplication namedtuple represents one way of reaching this # Value by applying an operation to some arguments. Choose one at random. # If we recursed through all possible choices, we would heavily bias the # dataset toward Values with many possible expressions, e.g., those using many # commutative ops. operation_application = random.choice(value.operation_applications) children_possibilities = [extract_values_with_collapsed_subtrees(child) for child in operation_application.arg_values] for children_choices in itertools.product(*children_possibilities): results.append(value_module.OperationValue( value=value.value, operation=operation_application.operation, arg_values=children_choices)) # Include the case where the entire AST is replaced with a new input. Skip # tensor conversion, meaning don't convert a tuple of tensors into a single # tensor with one greater rank; keep the object as-is. results.append(value_module.InputValue(value=value.value, name=NEW_INPUT_NAME, skip_tensor_conversion=True)) return results
def _check_target_program(self, benchmark): """Checks that a benchmark's target program is consistent with its examples. Args: benchmark: A Benchmark to verify. """ self.assertIsNotNone(benchmark.target_program) for example in benchmark.examples: # Turn inputs into constant tensors and assign them to variables using a # new global namespace. global_namespace = {'tf': tf} input_names_to_objects = value_search._input_names_to_objects( example.inputs) for input_name, input_object in input_names_to_objects.items(): input_value = value_module.InputValue(input_object, name='dummy_name') global_namespace[input_name] = input_value.value # Evaluate the target program, which uses the canonical variables. target_program_output = eval(benchmark.target_program, global_namespace) # pylint: disable=eval-used # Check that the two outputs have equal string representation. expected_output = tf_coder_utils.convert_to_tensor(example.output) self.assertEqual( tf_coder_utils.object_to_string(expected_output), tf_coder_utils.object_to_string(target_program_output))
def operation_multipliers_from_tensor_model( benchmark: benchmark_module.Benchmark, tensor_model: tensor_features_model.Model, tensor_config: Dict[Text, Any], settings: settings_module.Settings) -> Dict[Text, float]: """Runs the tensor features model to get operation weight multipliers.""" # TODO(kshi): Duplicate creation of InputValue and OutputValue objects. inputs = [ value_module.InputValue(user_input, '') for user_input in _user_inputs(benchmark.examples[0].inputs) ] output = value_module.OutputValue(benchmark.examples[0].output) example_protos = collect_tensor_data.create_tf_examples( io_example=collect_tensor_data.IOExample( expression='', input_values=inputs, output_value=output, num_inputs=benchmark.num_inputs, operations=[]), max_num_inputs=tensor_config['max_num_inputs'], permute_inputs=False) if example_protos: example_proto = example_protos[0] result = tensor_features_model.eval_single_example( tensor_model, example_proto.SerializeToString()) operation_ranks = tf.argsort( tf.argsort(tf.squeeze(result.operation_logits), stable=True)) operation_probabilities = tf.squeeze( tf.sigmoid(result.operation_logits)) operation_names = tensor_config['operation_names'] assert len(operation_names) == len(operation_probabilities) multipliers = {} for index in tf.where(operation_probabilities >= settings.tensor_model.prioritize_threshold): chosen_op_name = operation_names[int(index)] if settings.printing.prioritized_operations: print('Tensor features model prioritized {}, p={}'.format( chosen_op_name, operation_probabilities[int(index)])) multipliers[ chosen_op_name] = settings.tensor_model.prioritize_multiplier for index in tf.where(operation_probabilities <= settings.tensor_model.deprioritize_threshold): int_index = int(index) chosen_op_name = operation_names[int_index] if (int(operation_ranks[int_index]) >= settings.tensor_model.max_deprioritized): continue if settings.printing.deprioritized_operations: print('Tensor features model deprioritized {}, p={}, logit={}'. format(chosen_op_name, operation_probabilities[int_index], result.operation_logits[0][int_index])) multipliers[chosen_op_name] = ( settings.tensor_model.deprioritize_multiplier) return multipliers else: logging.error('Failed to create example for inputs %s and output %s', inputs, output) return {}
def setUp(self): super(IndexingAxis1OperationTest, self).setUp() self.operation = python_operations.IndexingAxis1Operation() self.arg_values = [ value.InputValue([[12, 34], [56, 78]], 'my_input'), value.ConstantValue(1) ]
def setUp(self): super(CollectTensorDataTest, self).setUp() self.settings = settings_module.default_settings() operations = all_operations.get_operations() self.unique_with_counts_operation = all_operations.find_operation_with_name( 'tf.unique_with_counts(x)', operation_list=operations) self.indexing_operation = all_operations.find_operation_with_name( 'IndexingOperation', operation_list=operations) self.gather_operation = all_operations.find_operation_with_name( 'tf.gather(params, indices)', operation_list=operations) self.add_operation = all_operations.find_operation_with_name( 'tf.add(x, y)', operation_list=operations) # Example with many operations. in1 = value_module.InputValue([1, 1, 2, 5, 6, 5], 'in1') in2 = value_module.InputValue([0, 10, 20, 30, 40, 50, 60, 70], 'in2') constant_1 = value_module.ConstantValue(1) unique = self.unique_with_counts_operation.apply([in1], self.settings) indexed = self.indexing_operation.apply([unique, constant_1], self.settings) gathered = self.gather_operation.apply([in2, in1], self.settings) self.example_value_1 = self.add_operation.apply([indexed, gathered], self.settings) self.assertEqual( self.example_value_1.reconstruct_expression(), 'tf.add(tf.unique_with_counts(in1)[1], tf.gather(in2, in1))') self.assertEqual(self.example_value_1, value_module.OutputValue([10, 10, 21, 52, 63, 52])) # Example with many variables and new inputs. in3 = value_module.InputValue([1], 'in3') in4 = value_module.InputValue([2], 'in4') a = self.add_operation.apply([in3, new_input([10])], self.settings) b = self.add_operation.apply([in4, in3], self.settings) c = self.add_operation.apply([new_input([20]), in3], self.settings) d = self.add_operation.apply([a, b], self.settings) self.example_value_2 = self.add_operation.apply([c, d], self.settings) self.assertEqual( self.example_value_2.reconstruct_expression(), 'tf.add(tf.add(NEW_INPUT, in3), ' 'tf.add(tf.add(in3, NEW_INPUT), tf.add(in4, in3)))') self.assertEqual(self.example_value_2, value_module.OutputValue([35]))
def setUp(self): super(SlicingAxis1BothOperationTest, self).setUp() self.operation = python_operations.SlicingAxis1BothOperation() self.arg_values = [ value.InputValue([[12, 34, 56, 78], [-1, -2, -3, -4]], 'my_input'), value.ConstantValue(1), value.ConstantValue(-1) ]
def test_init_with_tensor(self): input_value = value.InputValue(tf.constant([[11, 22, 33], [4, 5, 6]]), 'in') self.assertTrue(input_value.is_tensor) self.assertFalse(input_value.is_sparse_tensor) self.assertEqual(input_value.dtype, tf.int32) self.assertEqual(input_value.shape, [2, 3]) # The shape should be a native Python list containing native Python ints. self.assertEqual(type(input_value.shape), list) self.assertEqual(type(input_value.shape[0]), int)
def test_copy(self): input_value = value.InputValue([1, 2], 'a') copy_value = input_value.copy() self.assertIsNot(input_value, copy_value) self.assertEqual(input_value.reconstruct_expression(use_cache=False), copy_value.reconstruct_expression(use_cache=False)) copy_value.name = 'b' self.assertNotEqual(input_value.reconstruct_expression(use_cache=False), copy_value.reconstruct_expression(use_cache=False))
def test_reconstruct_expression(self): operation = function_operation.FunctionOperation( tf_functions.FunctionInfo( name='tf.reduce_sum(input_tensor, axis)', filter_group=filter_group.FilterGroup.NONE, weight=2)) arg_1 = value.InputValue([[1, 3], [50, 20]], 'my_input') arg_2 = value.ConstantValue('tf-coder') self.assertEqual(operation.reconstruct_expression([arg_1, arg_2]), "tf.reduce_sum(my_input, axis='tf-coder')")
def test_extract_examples_from_value(self, max_num_inputs, expected_expressions): actual = collect_tensor_data.extract_examples_from_value( self.example_value_1, max_num_inputs=max_num_inputs) # Check that all expressions are as expected. self.assertCountEqual([example.expression for example in actual], expected_expressions) # Check all elements of one IOExample namedtuple. This example is at index 1 # when max_num_inputs > 1. if max_num_inputs > 1: expected_index_1 = collect_tensor_data.IOExample( expression='tf.add(tf.unique_with_counts(in1)[1], in2)', input_values=[ value_module.InputValue([1, 1, 2, 5, 6, 5], 'in1'), value_module.InputValue([10, 10, 20, 50, 60, 50], 'in2') ], output_value=value_module.OutputValue([10, 10, 21, 52, 63, 52]), num_inputs=2, operations=[ self.add_operation, self.indexing_operation, self.unique_with_counts_operation ]) self.assertEqual(actual[1], expected_index_1) # Equality of Value objects is done by comparing the wrapped values. Check # the names in input_values too. for actual_value, expected_value in zip( actual[1].input_values, expected_index_1.input_values): self.assertIsInstance(actual_value, value_module.InputValue) self.assertEqual(actual_value.name, expected_value.name) # Check that all extracted examples actually work by eval-ing them. for example in actual: namespace_dict = {'tf': tf} self.assertLen(example.input_values, example.num_inputs) for input_value in example.input_values: namespace_dict[input_value.name] = input_value.value eval_output = eval(example.expression, namespace_dict) # pylint: disable=eval-used self.assertEqual(value_module.OutputValue(eval_output), example.output_value) self.assertEqual(example.output_value, self.example_value_1)
def test_check_sparse_tensor_size(self, sparse_tensor, expected_result): # check_tensor_size() expects a Value object, but is also called from # Value.__init__. We first create a Value object with an ok tensor size, and # then replace its wrapped value with the new tensor, so that we can check # the result of check_tensor_size() without it causing the Value constructor # to throw an exception. input_value = value.InputValue( tf.sparse.from_dense(tf.constant([[0, 1], [0, 0]])), 'test') input_value.value = sparse_tensor input_value.cached_info = {} self.assertEqual(value_search_utils.check_sparse_tensor_size(input_value), expected_result)
def test_init_with_sparse_tensor(self): input_value = value.InputValue( tf.SparseTensor(indices=[[12, 34]], values=tf.constant([5.6], dtype=tf.float16), dense_shape=[50, 60]), 'in') self.assertTrue(input_value.is_sparse_tensor) self.assertFalse(input_value.is_tensor) self.assertEqual(input_value.dtype, tf.float16) self.assertEqual(input_value.shape, [50, 60]) # The shape should be a native Python list containing native Python ints. self.assertEqual(type(input_value.shape), list) self.assertEqual(type(input_value.shape[0]), int)
def test_check_tensor_size(self, tensor_shape, expected_result): # check_tensor_size() expects a Value object, but is also called from # Value.__init__. We first create a Value object with an ok tensor size, and # then replace its wrapped value with the new tensor, so that we can check # the result of check_tensor_size() without it causing the Value constructor # to throw an exception. tensor = tf.zeros(tensor_shape) tensor_value = value.InputValue(tf.constant([1]), 'test') tensor_value.value = tensor tensor_value.cached_info = {} self.assertEqual(value_search_utils.check_tensor_size(tensor_value), expected_result)
def test_copy(self): tensor_value = value.InputValue([[1, 3, 2], [-3, 0, 4]], 'my_input') axis_value = value.ConstantValue(1) operation_value = self.operation.apply([tensor_value, axis_value], self.settings) copy_value = operation_value.copy() self.assertIsNot(operation_value, copy_value) self.assertTrue(operation_value.reconstruct_expression(use_cache=False) # pylint: disable=g-generic-assert == copy_value.reconstruct_expression(use_cache=False) == 'tf.reduce_max(my_input, axis=1)') copy_value.operation_applications[0].arg_values[0].name = 'new_name' self.assertEqual(operation_value.reconstruct_expression(use_cache=False), 'tf.reduce_max(my_input, axis=1)') self.assertEqual(copy_value.reconstruct_expression(use_cache=False), 'tf.reduce_max(new_name, axis=1)')
def test_reconstruct_expression(self): tensor_value = value.InputValue([[1, 3, 2], [-3, 0, 4]], 'my_input') axis_value = value.ConstantValue(1) operation_value = value.OperationValue(tf.constant([3, 4]), self.operation, [tensor_value, axis_value]) expected_expression = 'tf.reduce_max(my_input, axis=1)' self.assertEqual(operation_value.reconstruct_expression(), expected_expression) self.assertEqual(operation_value.reconstruct_expression(), expected_expression) # Cached. operation_value_apply = self.operation.apply([tensor_value, axis_value], self.settings) self.assertEqual(operation_value, operation_value_apply) self.assertEqual(operation_value_apply.reconstruct_expression(), expected_expression)
def test_init_does_not_convert_primitive_to_tensor(self): input_value = value.InputValue(1, 'descriptive_name') self.assertFalse(input_value.is_tensor) self.assertTrue(input_value.is_primitive)
def new_input(raw_value): return value_module.InputValue(raw_value, 'NEW_INPUT')
def test_generate_random_input(self): for i in range(1000): # Just check that generation completes and produces valid Values. random_input = random_inputs.generate_random_input(random_seed=i) value = value_module.InputValue(random_input, name='dummy_name') self.assertIsNotNone(value)
def test_hash(self): value_1a = value.InputValue(tf.constant([1, 2]), 'a') value_1b = value.OutputValue(tf.constant([1, 2])) value_2 = value.InputValue(tf.constant([1, 3]), 'a') self.assertEqual(hash(value_1a), hash(value_1b)) self.assertNotEqual(hash(value_1a), hash(value_2))
def test_create_tf_examples(self): sparse_tensor = tf.SparseTensor(values=[0, -15, 30], indices=[[12], [34], [56]], dense_shape=[100]) # This example does not represent a realistic tensor transformation. It uses # variety in the input/output tensors to exercise the featurization. io_example = collect_tensor_data.IOExample( expression='tf.dummy_expression(in1, in2)', input_values=[ value_module.InputValue( [[[0.5, 2.5, 9.0], [-0.25, 0.0, 1.25]]], 'in1'), value_module.InputValue(sparse_tensor, 'in2'), ], output_value=value_module.OutputValue([[1.0], [0.0], [1.0], [0.0]]), num_inputs=2, operations=[ self.add_operation, self.add_operation, self.gather_operation ]) with mock.patch.object(collect_tensor_data, 'COUNT_BOUNDARIES', new=[0, 1, 3, 50, float('inf')]): with mock.patch.object( collect_tensor_data, 'FLOAT_BOUNDARIES', new=[-float('inf'), -10, -1e-8, 1e-8, 10, float('inf')]): tf_examples = collect_tensor_data.create_tf_examples( io_example) operation_list = all_operations.get_operations( include_sparse_operations=True) expected_operations = [ 2 if op.name == 'tf.add(x, y)' else 1 if op.name == 'tf.gather(params, indices)' else 0 for op in operation_list ] expected_tf_example_1 = { # Features from featurize_value. 'kind': [2, 2, 3, 0], 'dtype': [8, 8, 0, 0], 'rank': [2, 3, 1, 0], 'shape': [4, 1, 0, 0, 1, 2, 3, 0, 100, 0, 0, 0, 0, 0, 0, 0], 'shape_buckets': [2, 1, 0, 0, 1, 1, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0], 'floats': [ 1.0, 0.0, 0.5, 0.5, 9.0, -0.25, 13 / 6, 13.5 / 6, 30, -15, 5, 15, 0, 0, 0, 0 ], 'float_buckets': [3, 2, 3, 3, 3, 1, 3, 3, 4, 0, 3, 4, 2, 2, 2, 2], 'counts': [ 4, 4, 2, 2, 2, 0, 4, 2, 6, 6, 4, 1, 0, 1, 2, 6, 100, 3, 1, 1, 0, 1, 1, 3, 1, 1, 0, 1, 0, 0, 1, 1 ], 'count_buckets': [ 2, 2, 1, 1, 1, 0, 2, 1, 2, 2, 2, 1, 0, 1, 1, 2, 3, 2, 1, 1, 0, 1, 1, 2, 1, 1, 0, 1, 0, 0, 1, 1 ], 'fractions': [ 4 / 4, 2 / 4, 2 / 4, 2 / 4, 0 / 4, 4 / 4, 2 / 4, 6 / 6, 4 / 6, 1 / 6, 0 / 6, 1 / 6, 2 / 6, 6 / 6, 3 / 100, 1 / 3, 1 / 3, 0 / 3, 1 / 3, 1 / 3, 3 / 3, 1 / 1, 0 / 1, 1 / 1, 0 / 1, 0 / 1, 1 / 1, 1 / 1 ], 'booleans': [ 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1 ], 'value_string': [ b'tf.float32:[[1.0], [0.0], [1.0], [0.0]]', b'tf.float32:[[[0.5, 2.5, 9.0], [-0.25, 0.0, 1.25]]]', (b'SparseTensor(indices=tf.Tensor(\n[[12]\n [34]\n [56]], ' b'shape=(3, 1), dtype=int64), ' b'values=tf.Tensor([ 0 -15 30], shape=(3,), dtype=int32), ' b'dense_shape=tf.Tensor([100], shape=(1,), dtype=int64))'), b'0' ], # Features from featurize_input_and_output. 'io_comparisons': [2, 2, 2, 0, 2, 2, 1, 2, 0, 0, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'io_booleans': [ 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 ], 'io_counts': [1, 2, 1, 1, 2, 1, 1, 1, 1], 'io_count_buckets': [1, 1, 1, 1, 1, 1, 1, 1, 1], 'io_fractions': [ 1 / 6, 2 / 4, 1 / 6, 1 / 4, 1 / 3, 2 / 4, 1 / 3, 1 / 4, 1 / 1, 1 / 1, 1 / 1, 1 / 1 ], # Features added in create_examples. 'num_inputs': [2], 'operations': expected_operations, 'expression': [b'tf.dummy_expression(in1, in2)'], } print(tf_examples) self.assertLen(tf_examples, 2) actual_tf_example_1, actual_tf_example_2 = tf_examples # Check the entire first example. for key, expected in six.iteritems(expected_tf_example_1): some_list = actual_tf_example_1.features.feature[key] if some_list.HasField('float_list'): actual = some_list.float_list.value actual = [round(f, 6) for f in actual] expected = [round(f, 6) for f in expected] elif some_list.HasField('int64_list'): actual = some_list.int64_list.value elif some_list.HasField('bytes_list'): actual = some_list.bytes_list.value else: self.fail('Failed to extract list from TF example.') # Printing side-by-side like this in the test log is more helpful than the # AssertionError message. Look at the Python3 log, which prints ints # without the L suffix. print('key: {}\n' ' expected: {}\n' ' got: {}'.format(key, expected, actual)) self.assertEqual(actual, expected) # Less rigorous checks for the second example, where the two inputs have # swapped. self.assertEqual( actual_tf_example_2.features.feature['rank'].int64_list.value, [2, 1, 3, 0]) self.assertEqual( actual_tf_example_2.features.feature['shape'].int64_list.value, [4, 1, 0, 0, 100, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0])
def _add_constants_and_inputs_and_print( values_by_weight: ValuesByWeight, benchmark: benchmark_module.Benchmark, output_value: value_module.OutputValue, constant_operation: operation_base.Operation, settings: settings_module.Settings) -> None: """Adds constant/input Values to values_by_weight, and prints to stdout.""" # Conceptually this is a set, but it's actually a list so that constants can # be printed in the same order they are chosen by the heuristics. The reduced # efficiency of membership-checking is not a big deal because we have few # constants. constants_so_far = set() constants_to_print = [] # User-provided constants. for c in benchmark.constants: if not _constant_exists(c, constants_so_far): constant_value = value_module.ConstantValue(c) weight = tf_functions.PROVIDED_CONSTANT_WEIGHT _add_value_by_weight(values_by_weight, constant_value, weight) constants_so_far.add(c) constants_to_print.append(c) # Add inputs, while computing some info for extra constants later. max_input_tensor_rank = 0 dimension_lengths = set() input_names_to_objects = _input_names_to_objects(benchmark.examples[0].inputs) for name, input_object in input_names_to_objects.items(): input_value = value_module.InputValue(input_object, name) if input_value.is_tensor: max_input_tensor_rank = max(max_input_tensor_rank, len(input_value.shape)) dimension_lengths.update(input_value.shape) if input_value.is_primitive and constant_operation is not None: scalar_tensor_value = constant_operation.apply([input_value], settings) _add_value_by_weight(values_by_weight, scalar_tensor_value, tf_functions.PRIMITIVE_INPUT_AS_TENSOR_WEIGHT) _add_value_by_weight(values_by_weight, input_value, tf_functions.INPUT_VARIABLE_WEIGHT) if input_value.is_primitive: constants_so_far.add(input_value.value) print("Input '{}':\n{!s}\n".format(name, input_value.value)) if output_value.shape is not None: dimension_lengths.update(output_value.shape) # Always include these as constants. common_constants = [0, 1, -1, True, False] # Also include 2, 3, ..., max_example_input_tensor_rank - 1 when applicable. axis_constants = list(range(2, max_input_tensor_rank)) # Also include dimension lengths of input and output tensors. shape_constants = sorted(dimension_lengths) constant_weight_pairs = ( [(c, tf_functions.COMMON_CONSTANT_WEIGHT) for c in common_constants] + [(c, tf_functions.AXIS_CONSTANT_WEIGHT) for c in axis_constants] + [(c, tf_functions.SHAPE_CONSTANT_WEIGHT) for c in shape_constants]) for constant, weight in constant_weight_pairs: if not _constant_exists(constant, constants_so_far): constant_value = value_module.ConstantValue(constant) _add_value_by_weight(values_by_weight, constant_value, weight) constants_so_far.add(constant) constants_to_print.append(constant) # DTypes for casting. for dtype, weight in tf_functions.CONSTANT_DTYPES_AND_WEIGHTS.items(): dtype_value = value_module.ConstantValue(dtype) _add_value_by_weight(values_by_weight, dtype_value, weight) if output_value.shape: # Add the output shape as a constant. shape_tuple = tuple(output_value.shape) shape_tuple_value = value_module.ConstantValue(shape_tuple) weight = tf_functions.OUTPUT_SHAPE_TUPLE_WEIGHT _add_value_by_weight(values_by_weight, shape_tuple_value, weight) # Don't add shape_tuple to constants_to_print, because printing it out could # be confusing to users. # Only for experiments in the PLDI paper. if settings.paper_experiments.uniform_weights: # Count the number of values. num_values = sum(len(values_with_weight) for values_with_weight in values_by_weight) # Take all values and put them in the collection for weight 1. for weight in range(2, len(values_by_weight)): for heavy_value in values_by_weight[weight]: values_by_weight[1][heavy_value] = heavy_value values_by_weight[weight].clear() # Make sure we did it right. for weight, values_with_weight in enumerate(values_by_weight): assert len(values_with_weight) == (num_values if weight == 1 else 0) print('Output:\n{!s}\n'.format(output_value.value)) print('Constants: {!r}\n'.format(constants_to_print)) if benchmark.description: print('Description: {}\n'.format(benchmark.description)) print('Searching...\n') sys.stdout.flush() # Flush so the inputs/output appear in Colab immediately.
def test_eq_comparing_to_non_value(self): input_value = value.InputValue(tf.constant([1, 2]), 'a') not_comparable = [1, 2] # We want to explicitly test __eq__. self.assertFalse(input_value == not_comparable) # pylint: disable=g-generic-assert
def test_init_converts_list_to_tensor(self): input_value = value.InputValue([1], 'descriptive_name') self.assertTrue(input_value.is_tensor) self.assertFalse(input_value.is_primitive)
def test_reconstruct_expression(self): to_index = value.InputValue([1.2, 3.4], 'my_list') index = value.ConstantValue(0) self.assertEqual( self.operation.reconstruct_expression([to_index, index]), 'my_list[0]')
def test_reconstruct_expression(self): input_value = value.InputValue([1], 'descriptive_name') self.assertEqual(input_value.reconstruct_expression(), 'descriptive_name')