docstr: Tests whether SAC can be built with all frameworks.
code: def test_sac_compilation(self):
      """Tests whether SAC can be built with all frameworks."""
      config = (
          sac.SACConfig()
          .training(
              n_step=3,
              twin_q=True,
              replay_buffer_config={
                  "capacity": 40000,
              },
              num_steps_sampled_before_learning_starts=0,
              store_buffer_in_checkpoints=True,
              train_batch_size=10,
          )
          .rollouts(num_rollout_workers=0, rollout_fragment_length=10)
      )
      num_iterations = 1
  
      ModelCatalog.register_custom_model(
          "batch_norm", KerasBatchNormModel
      )
      ModelCatalog.register_custom_model(
          "batch_norm_torch", TorchBatchNormModel
      )
  
      image_space = Box(-1.0, 1.0, shape=(84, 84, 3))
      simple_space = Box(-1.0, 1.0, shape=(3,))
  
      tune.register_env(
          "random_dict_env",
          lambda _: RandomEnv(
              {
                  "observation_space": Dict(
                      {
                          "a": simple_space,
                          "b": Discrete(2),
                          "c": image_space,
                      }
                  ),
                  "action_space": Box(-1.0, 1.0, shape=(1,)),
              }
          ),
      )
      tune.register_env(
          "random_tuple_env",
          lambda _: RandomEnv(
              {
                  "observation_space": Tuple(
                      [simple_space, Discrete(2), image_space]
                  ),
                  "action_space": Box(-1.0, 1.0, shape=(1,)),
              }
          ),
      )
  
      for fw in framework_iterator(config):
          # Test for different env types (discrete w/ and w/o image, + cont).
          for env in [
              "random_dict_env",
              "random_tuple_env",
              "CartPole-v1",
          ]:
              print("Env={}".format(env))
              config.environment(env)
              # Test making the Q-model a custom one for CartPole, otherwise,
              # use the default model.
              config.q_model_config["custom_model"] = (
                  "batch_norm{}".format(
                      "_torch" if fw == "torch" else ""
                  )
                  if env == "CartPole-v1"
                  else None
              )
              algo = config.build()
              for i in range(num_iterations):
                  results = algo.train()
                  check_train_results(results)
                  print(results)
              check_compute_single_action(algo)
  
              # Test, whether the replay buffer is saved along with
              # a checkpoint (no point in doing it for all frameworks since
              # this is framework agnostic).
              if fw == "tf" and env == "CartPole-v1":
                  checkpoint = algo.save()
                  new_algo = config.build()
                  new_algo.restore(checkpoint)
                  # Get some data from the buffer and compare.
                  data = algo.local_replay_buffer.replay_buffers[
                      "default_policy"
                  ]._storage[: 42 + 42]
                  new_data = (
                      new_algo.local_replay_buffer.replay_buffers[
                          "default_policy"
                      ]._storage[: 42 + 42]
                  )
                  check(data, new_data)
                  new_algo.stop()
  
              algo.stop()
  
imports: import gymnasium
  from gymnasium.spaces import Box, Dict, Discrete, Tuple
  import numpy
  import re
  import unittest
  import ray
  from ray.rllib.algorithms import sac
  from ray.rllib.algorithms.sac.sac_tf_policy import sac_actor_critic_loss
  from ray.rllib.algorithms.sac.sac_torch_policy import actor_critic_loss
  from ray.rllib.examples.env.random_env import RandomEnv
  from ray.rllib.examples.models.batch_norm_model import KerasBatchNormModel, TorchBatchNormModel
  from ray.rllib.models.catalog import ModelCatalog
  from ray.rllib.models.tf.tf_action_dist import Dirichlet
  from ray.rllib.models.torch.torch_action_dist import TorchDirichlet
  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 fc, huber_loss, relu
  from ray.rllib.utils.spaces.simplex import Simplex
  from ray.rllib.utils.test_utils import check, check_compute_single_action, check_train_results, framework_iterator
  from ray.rllib.utils.torch_utils import convert_to_torch_tensor
  from ray import tune
  from ray.rllib.utils.replay_buffers.utils import patch_buffer_with_fake_sampling_method
label_desc: Use image node_id 3 for calling the TestSAC obj's underlying member method code with example usage: obj.test_sac_compilation() without return types