


"""simple docstring"""






import argparse
import json
import os

from tensorflow.core.protobuf.saved_model_pba import SavedModel


# All paths are set with the intent you should run this script from the root of the repo with the command
# python utils/check_copies.py
__snake_case							=       '''.'''

# Internal TensorFlow ops that can be safely ignored (mostly specific to a saved model)
__snake_case							=       [
    '''Assert''',
    '''AssignVariableOp''',
    '''EmptyTensorList''',
    '''MergeV2Checkpoints''',
    '''ReadVariableOp''',
    '''ResourceGather''',
    '''RestoreV2''',
    '''SaveV2''',
    '''ShardedFilename''',
    '''StatefulPartitionedCall''',
    '''StaticRegexFullMatch''',
    '''VarHandleOp''',
]
def       A_   (   _lowerCAmelCase     :					List[Any],     _lowerCAmelCase     :					Tuple,     _lowerCAmelCase     :					str       ):






     """simple docstring"""

     _a    	=				SavedModel()
     _a    	=				[]

     with open(os.path.join(lowerCAmelCase__,     '''utils''',     '''tf_ops''',     '''onnx.json'''       )       ) as f:
          _a    	=				json.load(lowerCAmelCase__       )['''opsets''']

     for i in range(1,     opset + 1       ):
          onnx_ops.extend(onnx_opsets[str(lowerCAmelCase__       )]       )

     with open(lowerCAmelCase__,     '''rb'''       ) as f:
          saved_model.ParseFromString(f.read()       )

     _a    	=				set()

     # Iterate over every metagraph in case there is more than one (a saved model can contain multiple graphs)
     for meta_graph in saved_model.meta_graphs:
          # Add operations in the graph definition
          model_op_names.update(node.op for node in meta_graph.graph_def.node       )

          # Go through the functions in the graph definition
          for func in meta_graph.graph_def.library.function:
               # Add operations in each function
               model_op_names.update(node.op for node in func.node_def       )

    # Convert to list, sorted if you want
     _a    	=				sorted(lowerCAmelCase__       )
     _a    	=				[]

     for op in model_op_names:
          if op not in onnx_ops and op not in INTERNAL_OPS:
               incompatible_ops.append(lowerCAmelCase__       )

     if strict and len(lowerCAmelCase__       ) > 0:
          raise Exception(f'Found the following incompatible ops for the opset {opset}:\n' + incompatible_ops       )
     elif len(lowerCAmelCase__       ) > 0:
          print(f'Found the following incompatible ops for the opset {opset}:'       )
          print(*lowerCAmelCase__,     sep='''\n'''       )
     else:
          print(f'The saved model {saved_model_path} can properly be converted with ONNX.'       )


if __name__ == "__main__":
   __snake_case							=       argparse.ArgumentParser()
   parser.add_argument('''--saved_model_path''', help='''Path of the saved model to check (the .pb file).''')
   parser.add_argument(
       '''--opset''', default=12, type=int, help='''The ONNX opset against which the model has to be tested.'''
   )
   parser.add_argument(
       '''--framework''', choices=['''onnx'''], default='''onnx''', help='''Frameworks against which to test the saved model.'''
   )
   parser.add_argument(
       '''--strict''', action='''store_true''', help='''Whether make the checking strict (raise errors) or not (raise warnings)'''
   )
   __snake_case							=       parser.parse_args()

   if args.framework == "onnx":
      onnx_compliancy(args.saved_model_path, args.strict, args.opset)



"""simple docstring"""






from typing import Any
def       A_   (   _lowerCAmelCase     :					list       ):






     """simple docstring"""

     if not input_list:
          return []
     _a    	=				[input_list.count(_lowerCAmelCase       ) for value in input_list]
     _a    	=				max(_lowerCAmelCase       )  # Gets the maximum count in the input list.
     # Gets values of modes
     return sorted({input_list[i] for i, value in enumerate(_lowerCAmelCase       ) if value == y}       )


if __name__ == "__main__":
   import doctest

   doctest.testmod()