class_docstr: There are three kinds of operations that we could register:
  
  (1) core_ops:  dict[str, dict[Operation]]
      - These are the core ops in PyMIL, which have a direct mapping to the backend in neural_network or mlprogram
      - The registered op is considered a core op if the namespace is not provided
      - coreml_ops[op_type] is a dict that tracks different opset versions for an op. For instance
          - ``core_ops[op_1] = {
                  ct.target.iOS13: op_1_iOS13,
                  ct.target.iOS14: op_1_iOS13,
                  ct.target.iOS15: op_1_iOS13,
                  ct.target.iOS16: op_1_iOS13,
             }``
              . Only one version of op type ``op_1`` is registered, and it is defined in iOS13, which both
                neural_network and mlprogram backend support
          - ``core_ops[op_2] = {
                  ct.target.iOS13: op_2_iOS13,
                  ct.target.iOS14: op_2_iOS13,
                  ct.target.iOS15: op_2_iOS13,
                  ct.target.iOS16: op_2_iOS16,
             }``
              . Two versions of op type ``op_2`` are registered, one each for iOS13, iOS16.
              . The builder picks up correct version of the op according to curr_opset_version(), which returns the opset version of
                the current function.
                  -- If ``curr_opset_version()`` is ``None`` (the version of the function is not set), ``mb.op_2`` would call the oldest version of the op by default, which is ``op_2_ios13``
                  -- Otherwise, the builder would pick up core_ops[op_2][curr_opset_version()]
      - In the highest level, users can choose the desired version by specifying the ``minum_deployment_target`` argument in ``coremltools.convert``
      - The default ``opset_version`` for the core ops would be set to iOS13, for which neural_network backend supports
  
  (2) dialect_ops: dict[str, Operation]
      - These are the ops that are created for specific frontend framework, for instance: ``tf_lstm_block, torch_upsample_nearest_neighbor``
      - A graph pass must be customized by the developer to translate a dialect_ops into core ops
  
  (3) custom_ops: dict[str, Operation]
      - These are the custom ops, in which an additional ``bindings`` which should be specified in operator
docstr: A utility function that retrieves an op cls using the curr_opset_version
docstr_tok: ["A","utility","function","that","retrieves","an","op","cls","using","the","curr_opset_version"]
code: def _get_core_op_cls(op_type=None):
      """
      A utility function that retrieves an op cls using the curr_opset_version
      """
      if op_type not in SSAOpRegistry.core_ops:
          raise ValueError("op {} not registered.".format(op_type))
      candidate_ops = SSAOpRegistry.core_ops[op_type]
      return _get_version_of_op(candidate_ops, curr_opset_version())
  
file_path: coremltools/coremltools/converters/mil/mil/ops/registry.py
imports: from collections import defaultdict
  from coremltools import _logger
  from coremltools.converters.mil._deployment_compatibility import AvailableTarget
  from coremltools.converters.mil.mil.block import curr_opset_version
  from ..builder import Builder
  from .helper import _get_version_of_op
label_desc: Use image node_id 1 for calling the SSAOpRegistry obj's underlying member method code with example usage: obj._get_core_op_cls(op_type) and returns: _get_version_of_op