docstr: Tests if we can create a bunch of encoders from the base catalog class.
docstr_tok: ["Tests","if","we","can","create","a","bunch","of","encoders","from","the","base","catalog","class","."]
code: def test_get_encoder_config(self):
      """Tests if we can create a bunch of encoders from the base catalog class."""
  
      # TODO (Artur): Add support for the commented out spaces
      input_spaces_and_config_types = [
          (Box(-1.0, 1.0, (5,), dtype=np.float32), MLPEncoderConfig),
          (
              Box(-1.0, 1.0, (84, 84, 1), dtype=np.float32),
              CNNEncoderConfig,
          ),
          # Box(-1.0, 1.0, (5, 5), dtype=np.float32),
          # MultiBinary([3, 10, 10]),
          # Discrete(5),
          # Tuple([Discrete(10), Box(-1.0, 1.0, (5,), dtype=np.float32)]),
          # Dict(
          #     {
          #         "task": Discrete(10),
          #         "position": Box(-1.0, 1.0, (5,), dtype=np.float32),
          #     }
          # ),
          # Text(),
          # Graph(),
          # GraphInstance(),
          # MultiDiscrete(),
          # Sequence(),
      ]
  
      # TODO (Artur): Add support for the commented out configs
      model_config_dicts = [
          # This should produce an MLPEncoder with three hidden layers
          {
              "fcnet_activation": "relu",
              "fcnet_hiddens": [256, 256, 256],
          },
          # This should produce an MLPEncoder with one hidden layer
          {
              "fcnet_hiddens": [512],
              "encoder_latent_dim": 512,
              "fcnet_activation": "relu",
          },
          # This should produce an LSTMEncoder with one hidden layer
          # {"use_lstm": True},
          # This should produce an AttentionNetEncoder with default configuration
          # {"use_attention": True, "attention_num_transformer_units": 4},
          # This should produce an AttentionNetEncoder with one hidden layer and
          # other custom configuration
          # {
          #     "fcnet_hiddens": [32],
          #     "fcnet_activation": "linear",
          #     "vf_share_layers": True,
          #     "use_attention": True,
          #     "max_seq_len": 10,
          #     "attention_num_transformer_units": 1,
          #     "attention_dim": 32,
          #     "attention_memory_inference": 10,
          #     "attention_memory_training": 10,
          #     "attention_num_heads": 1,
          #     "attention_head_dim": 32,
          #     "attention_position_wise_mlp_dim": 32,
          # },
          # This should produce an LSTMEncoder wrapping an CNNEncoder with
          # additional other custom configuration
          # {
          #     "use_lstm": True,
          #     "conv_activation": "elu",
          #     "dim": 42,
          #     "grayscale": True,
          #     "zero_mean": False,
          #     # Reduced channel depth and kernel size from default
          #     "conv_filters": [
          #         [32, [3, 3], 2],
          #         [32, [3, 3], 2],
          #         [32, [3, 3], 2],
          #         [32, [3, 3], 2],
          #     ]
          # }
      ]
  
      frameworks = ["tf2", "torch"]
  
      # First check if encoders can be created for non-composite spaces
      print("Testing encoders for non-composite input spaces...")
      config_combinations = [
          frameworks,
          input_spaces_and_config_types,
          model_config_dicts,
      ]
      for config in itertools.product(*config_combinations):
          (
              framework,
              input_space_and_config_type,
              model_config_dict,
          ) = config
          input_space, model_config_type = input_space_and_config_type
          print(
              f"Testing framework: \n{framework}\n, input space: \n{input_space}\n "
              f"and config: \n{model_config_dict}\n"
          )
          catalog = Catalog(
              observation_space=input_space,
              # Action space does not matter for encoders
              action_space=gym.spaces.Box(1, 1, (1,)),
              model_config_dict=model_config_dict,
              # TODO(Artur): Add view requirements when we need them
              view_requirements=None,
          )
  
          model_config = catalog._get_encoder_config(
              observation_space=input_space,
              model_config_dict=model_config_dict,
          )
          self.assertEqual(type(model_config), model_config_type)
          model = model_config.build(framework=framework)
  
          # Do a forward pass and check if the output has the correct shape
          self._check_model_outputs(
              model, framework, model_config_dict, input_space
          )
  
imports: from collections import namedtuple
  import functools
  import itertools
  import unittest
  import gymnasium
  from gymnasium.spaces import Box, Discrete, Dict, Tuple, MultiDiscrete
  import numpy
  import tree
  from ray.rllib.algorithms.ppo.ppo import PPOConfig
  from ray.rllib.algorithms.ppo.ppo_catalog import PPOCatalog
  from ray.rllib.algorithms.ppo.torch.ppo_torch_rl_module import PPOTorchRLModule
  from ray.rllib.core.models.base import Encoder, STATE_IN, ENCODER_OUT, STATE_OUT
  from ray.rllib.core.models.catalog import Catalog, _multi_action_dist_partial_helper, _multi_categorical_dist_partial_helper
  from ray.rllib.core.models.configs import MLPEncoderConfig, ModelConfig, CNNEncoderConfig
  from ray.rllib.core.models.torch.base import TorchModel
  from ray.rllib.core.rl_module.rl_module import SingleAgentRLModuleSpec
  from ray.rllib.models import MODEL_DEFAULTS
  from ray.rllib.models.tf.tf_distributions import TfCategorical, TfDiagGaussian, TfMultiCategorical, TfMultiDistribution
  from ray.rllib.models.torch.torch_distributions import TorchCategorical, TorchDiagGaussian, TorchMultiCategorical, TorchMultiDistribution
  from ray.rllib.policy.sample_batch import SampleBatch
  from ray.rllib.utils.framework import try_import_tf, try_import_torch
  from ray.rllib.utils.numpy import convert_to_numpy
  from ray.rllib.utils.spaces.space_utils import get_dummy_batch_for_space
  from ray.rllib.utils.test_utils import framework_iterator
  from ray.rllib.utils.torch_utils import convert_to_torch_tensor
label_desc: Use image node_id 2 for calling the TestCatalog obj's underlying member method code with example usage: obj.test_get_encoder_config() without return types