"""Generate a mock model for LLVM tests. The generated model is not a neural net - it is just a tf.function with the correct input and output parameters. By construction, the mock model will always output 1. """ import os import importlib.util import sys import tensorflow as tf POLICY_DECISION_LABEL = 'inlining_decision' POLICY_OUTPUT_SPEC = """ [ { "logging_name": "inlining_decision", "tensor_spec": { "name": "StatefulPartitionedCall", "port": 0, "type": "int64_t", "shape": [ 1 ] } } ] """ # pylint: disable=g-complex-comprehension def get_input_signature(): """Returns the list of features for LLVM inlining.""" # int64 features inputs = [ tf.TensorSpec(dtype=tf.int64, shape=(), name=key) for key in [ 'caller_basic_block_count', 'caller_conditionally_executed_blocks', 'caller_users', 'callee_basic_block_count', 'callee_conditionally_executed_blocks', 'callee_users', 'nr_ctant_params', 'node_count', 'edge_count', 'callsite_height', 'cost_estimate', 'inlining_default', 'sroa_savings', 'sroa_losses', 'load_elimination', 'call_penalty', 'call_argument_setup', 'load_relative_intrinsic', 'lowered_call_arg_setup', 'indirect_call_penalty', 'jump_table_penalty', 'case_cluster_penalty', 'switch_penalty', 'unsimplified_common_instructions', 'num_loops', 'dead_blocks', 'simplified_instructions', 'constant_args', 'constant_offset_ptr_args', 'callsite_cost', 'cold_cc_penalty', 'last_call_to_static_bonus', 'is_multiple_blocks', 'nested_inlines', 'nested_inline_cost_estimate', 'threshold', ] ] # float32 features inputs.extend([ tf.TensorSpec(dtype=tf.float32, shape=(), name=key) for key in ['discount', 'reward'] ]) # int32 features inputs.extend([ tf.TensorSpec(dtype=tf.int32, shape=(), name=key) for key in ['step_type'] ]) return inputs def get_output_signature(): return POLICY_DECISION_LABEL def get_output_spec(): return POLICY_OUTPUT_SPEC def get_output_spec_path(path): return os.path.join(path, 'output_spec.json') def build_mock_model(path, signature): """Build and save the mock model with the given signature""" module = tf.Module() def action(*inputs): return {signature['output']: tf.constant(value=1, dtype=tf.int64)} module.action = tf.function()(action) action = {'action': module.action.get_concrete_function(signature['inputs'])} tf.saved_model.save(module, path, signatures=action) output_spec_path = get_output_spec_path(path) with open(output_spec_path, 'w') as f: print(f'Writing output spec to {output_spec_path}.') f.write(signature['output_spec']) def get_signature(): return { 'inputs': get_input_signature(), 'output': get_output_signature(), 'output_spec': get_output_spec() } def main(argv): assert len(argv) == 2 model_path = argv[1] print(f'Output model to: [{argv[1]}]') signature = get_signature() build_mock_model(model_path, signature) if __name__ == '__main__': main(sys.argv)