code: def _get_target_activation_dtype_for_node(
      node: Node,
      qconfig: QConfigAny,
      qhandler: Optional[QuantizeHandler],
      named_modules: Dict[str, torch.nn.Module],
      backend_config: BackendConfig,
      cache_for_no_tensor_check: Dict[Node, bool],
  ) -> Dict[str, Any]:
      """
      For each op attribute in the op's input activation, output activation,
      weight, bias - returns the settings of dtype and is_dynamic we expect
      for the `quantize` call in the reference model representation, or None
      if there is no `quantize` call needed.
  
      For example, if we have a node corresponding to `op0` in
  
        x0 -> op0 -> x1
  
      And we want a reference quantized representation to be
  
        x0 -> quant_static -> dequant -> op0 -> quant_dynamic -> dequant -> x1
  
      Then this function will return
  
        {
          "input_act_obs_or_fq_ctr": MinMaxObserver.with_args(dtype=torch.quint8, is_dynamic=False),
          "output_act_obs_or_fq_ctr": MinMaxObserver.with_args(dtype=torch.quint8, is_dynamic=False),
        }
  
      TODO(future PR, if needed): explicitly spell out the non-Tensor
      dtypes.
      """
      args_have_no_tensors = all_node_args_have_no_tensors(
          node, named_modules, cache_for_no_tensor_check
      )
      if args_have_no_tensors:
          return {
              "input_act_obs_or_fq_ctr": None,
              "output_act_obs_or_fq_ctr": None,
          }
      # get qconfig to determine the eventual dtype of this node
      if qconfig is not None:
          (
              act_dtype,
              weight_dtype,
              input_act_is_dynamic,
          ) = get_qconfig_dtypes(qconfig)
  
          # Currently `QConfig` only has one `activation` field.
          # For static quantization, it is reused for both input
          # and output activation. For dynamic quantization, this
          # field is currently only used for the input activation,
          # with the output activation being in fp32.
          # In the future this may change as we add more fields
          # to the `QConfig` object.
          output_act_dtype = (
              act_dtype if (not input_act_is_dynamic) else torch.float
          )
  
          bias_dtype = (
              torch.float16
              if (
                  act_dtype == torch.float16
                  and weight_dtype == torch.float16
                  and (not input_act_is_dynamic)
              )
              else torch.float
          )
  
          is_general_tensor_value_op = (
              qhandler is not None
              and qhandler.is_general_tensor_value_op()
          )
  
          _is_standalone_module = (
              qhandler is not None and qhandler.is_standalone_module()
          )
  
          weight_index = None
          if (
              isinstance(node, Node)
              and node.op == "call_function"
              and node.target
              in backend_config._pattern_complex_format_to_config
          ):
              weight_index = (
                  backend_config._pattern_complex_format_to_config[
                      node.target
                  ]._input_type_to_index.get("weight")
              )
  
          bias_index = None
          if (
              isinstance(node, Node)
              and node.op == "call_function"
              and node.target
              in backend_config._pattern_complex_format_to_config
          ):
              bias_index = (
                  backend_config._pattern_complex_format_to_config[
                      node.target
                  ]._input_type_to_index.get("bias")
              )
  
          return {
              "input_act_obs_or_fq_ctr": qconfig.activation,
              "weight_obs_or_fq_ctr": qconfig.weight,
              "bias_obs_or_fq_ctr": PlaceholderObserver.with_args(
                  dtype=bias_dtype
              ),
              "weight_index": weight_index,
              "bias_index": bias_index,
              "output_act_obs_or_fq_ctr": qconfig.activation,
              "reuse_input_obs_or_fq": _is_reuse_input_qconfig(qconfig),
              "input_output_share_observers": is_general_tensor_value_op,
              "_is_standalone_module": _is_standalone_module,
          }
      return copy.copy(_DEFAULT_FP32_QCONFIG_FOR_TARGET_DTYPE_INFO)
  
imports: import copy
  import torch
  import warnings
  from torch.fx import GraphModule
  from torch.fx.graph import Graph, Node
  from torch.fx.node import Argument
  from ..quantize import propagate_qconfig_
  from ..observer import _is_activation_post_process, _PartialWrapper
  from ..qconfig import _is_reuse_input_qconfig, QConfigAny
  from ..qconfig_mapping import QConfigMapping
  from .qconfig_mapping_utils import _generate_node_name_to_qconfig, _update_qconfig_for_fusion, _get_flattened_qconfig_dict, _update_qconfig_for_qat
  from .quantize_handler import _default_root_node_getter, _get_pattern_to_quantize_handlers, QuantizeHandler
  from torch.ao.quantization import ObserverBase, FixedQParamsObserver, FixedQParamsFakeQuantize, _DerivedObserverOrFakeQuantize
  from torch.ao.quantization.utils import Pattern, NodePattern
  from ._equalize import is_equalization_observer, node_supports_equalization
  from .pattern_utils import _sorted_patterns_dict
  from .match_utils import _MatchResultWithQConfig, _find_matches
  from .utils import _insert_dequant_stubs_for_custom_module_lstm_output, _is_custom_module_lstm, _maybe_get_custom_module_lstm_from_node_arg, _qconfig_satisfies_dtype_config_constraints, get_custom_module_class_keys, all_node_args_have_no_tensors, assert_and_get_unique_device, get_non_observable_arg_indexes_and_types, get_new_attr_name_with_prefix, node_arg_is_weight, node_arg_is_bias, NON_QUANTIZABLE_WEIGHT_OPS, ObservedGraphModuleAttrs
  from torch.ao.quantization import PlaceholderObserver
  from torch.ao.quantization.quantize import convert
  from ..utils import _parent_name, get_qconfig_dtypes, get_swapped_custom_module_class
  from ..backend_config.utils import get_pattern_to_dtype_configs, get_module_to_qat_module, get_fusion_pattern_to_root_node_getter
  from ..backend_config import BackendConfig, DTypeConfig, get_native_backend_config
  from .custom_config import PrepareCustomConfig, StandaloneModuleConfigEntry
  from torch.ao.quantization.quantizer import EdgeOrNode, QuantizationSpec, QuantizationSpecBase, FixedQParamsQuantizationSpec, SharedQuantizationSpec, DerivedQuantizationSpec
  from torch.ao.quantization import ObserverOrFakeQuantize
  from torch._subclasses import FakeTensor
  from typing import Any, Dict, List, Optional, Set, Tuple, Type, Union
  from dataclasses import asdict
label_desc: Use image node_id 16 for calling a global function with example usage: _get_target_activation_dtype_for_node(node, qconfig, qhandler, named_modules, backend_config, cache_for_no_tensor_check) and returns: copy, dict, dict