class_docstr: Registry of models, preprocessors, and action distributions for envs.
  
  .. testcode::
      :skipif: True
  
      prep = ModelCatalog.get_preprocessor(env)
      observation = prep.transform(raw_observation)
  
      dist_class, dist_dim = ModelCatalog.get_action_dist(
          env.action_space, {})
      model = ModelCatalog.get_model_v2(
          obs_space, action_space, num_outputs, options)
      dist = dist_class(model.outputs, model)
      action = dist.sample()
class_docstr_tok: ["Registry","of","models",",","preprocessors",",","and","action","distributions","for","envs",".","..","testcode",":",":",":","skipif",":","True","prep","=","ModelCatalog.get_preprocessor","(","env",")","observation","=","prep.transform","(","raw_observation",")","dist_class",",","dist_dim","=","ModelCatalog.get_action_dist","(","env.action_space",",","{","}",")","model","=","ModelCatalog.get_model_v2","(","obs_space",",","action_space",",","num_outputs",",","options",")","dist","=","dist_class","(","model.outputs",",","model",")","action","=","dist.sample","(",")"]
code: def _get_multi_action_distribution(
      dist_class, action_space, config, framework
  ):
      # In case the custom distribution is a child of MultiActionDistr.
      # If users want to completely ignore the suggested child
      # distributions, they should simply do so in their custom class'
      # constructor.
      if issubclass(
          dist_class,
          (MultiActionDistribution, TorchMultiActionDistribution),
      ):
          flat_action_space = flatten_space(action_space)
          child_dists_and_in_lens = tree.map_structure(
              lambda s: ModelCatalog.get_action_dist(
                  s, config, framework=framework
              ),
              flat_action_space,
          )
          child_dists = [e[0] for e in child_dists_and_in_lens]
          input_lens = [int(e[1]) for e in child_dists_and_in_lens]
          return (
              partial(
                  dist_class,
                  action_space=action_space,
                  child_distributions=child_dists,
                  input_lens=input_lens,
              ),
              int(sum(input_lens)),
          )
      return dist_class, dist_class.required_model_output_shape(
          action_space, config
      )
  
imports: from functools import partial
  import gymnasium
  from gymnasium.spaces import Box, Dict, Discrete, MultiDiscrete, Tuple
  import logging
  import numpy
  import tree
  from typing import List, Optional, Type, Union
  from ray.tune.registry import RLLIB_MODEL, RLLIB_ACTION_DIST, _global_registry
  from ray.rllib.models.action_dist import ActionDistribution
  from ray.rllib.models.modelv2 import ModelV2
  from ray.rllib.models.preprocessors import get_preprocessor, Preprocessor
  from ray.rllib.models.tf.tf_action_dist import Categorical, Deterministic, DiagGaussian, Dirichlet, MultiActionDistribution, MultiCategorical
  from ray.rllib.models.torch.torch_action_dist import TorchCategorical, TorchDeterministic, TorchDirichlet, TorchDiagGaussian, TorchMultiActionDistribution, TorchMultiCategorical
  from ray.rllib.utils.annotations import DeveloperAPI, PublicAPI
  from ray.rllib.utils.deprecation import DEPRECATED_VALUE, deprecation_warning
  from ray.rllib.utils.error import UnsupportedSpaceException
  from ray.rllib.utils.framework import try_import_tf, try_import_torch
  from ray.rllib.utils.from_config import from_config
  from ray.rllib.utils.spaces.simplex import Simplex
  from ray.rllib.utils.spaces.space_utils import flatten_space
  from ray.rllib.utils.typing import ModelConfigDict, TensorType
label_desc: Use image node_id 11 for calling the ModelCatalog obj's underlying member method code with example usage: obj._get_multi_action_distribution(dist_class, action_space, config, framework) and returns: dist_class,  dist_class, partial,  int