class_docstr: Helper class to compare architecturally identical Models across frameworks.
  
  Holds a ModelConfig, such that individual models can be added simply via their
  framework string (by building them with config.build(framework=...).
  A call to `check()` forces all added models to be compared in terms of their
  number of trainable and non-trainable parameters, as well as, their
  computation results given a common weights structure and values and identical
  inputs to the models.
class_docstr_tok: ["Helper","class","to","compare","architecturally","identical","Models","across","frameworks",".","Holds","a","ModelConfig",",","such","that","individual","models","can","be","added","simply","via","their","framework","string","(","by","building","them","with","config.build","(","framework=","...",")",".","A","call","to","`","check","(",")","`","forces","all","added","models","to","be","compared","in","terms","of","their","number","of","trainable","and","non-trainable","parameters",",","as","well","as",",","their","computation","results","given","a","common","weights","structure","and","values","and","identical","inputs","to","the","models","."]
docstr: Builds a new Model for the given framework.
code: def add(self, framework: str = "torch") -> Any:
      """Builds a new Model for the given framework."""
      model = self.models[framework] = self.config.build(
          framework=framework
      )
  
      # Pass a B=1 observation through the model.
      from ray.rllib.core.models.specs.specs_dict import SpecDict
  
      if isinstance(model.input_specs, SpecDict):
          inputs = {}
          for key, spec in model.input_specs.items():
              dict_ = inputs
              for i, sub_key in enumerate(key):
                  if sub_key not in dict_:
                      dict_[sub_key] = {}
                  if i < len(key) - 1:
                      dict_ = dict_[sub_key]
              if spec is not None:
                  dict_[sub_key] = spec.fill(
                      self.random_fill_input_value
                  )
              else:
                  dict_[sub_key] = None
      else:
          inputs = model.input_specs.fill(self.random_fill_input_value)
  
      outputs = model(inputs)
  
      # Bring model into a reproducible, comparable state (so we can compare
      # computations across frameworks). Use only a value-sequence of len=1 here
      # as it could possibly be that the layers are stored in different order
      # across the different frameworks.
      model._set_to_dummy_weights(
          value_sequence=(self.random_fill_input_value,)
      )
  
      # Perform another forward pass.
      comparable_outputs = model(inputs)
  
      # Store the number of parameters for this framework's net.
      self.param_counts[framework] = model.get_num_parameters()
      # Store the fixed-weights-net outputs for this framework's net.
      if framework == "torch":
          self.output_values[framework] = tree.map_structure(
              lambda s: s.detach().numpy() if s is not None else None,
              comparable_outputs,
          )
      else:
          self.output_values[framework] = tree.map_structure(
              lambda s: s.numpy() if s is not None else None,
              comparable_outputs,
          )
      return outputs
  
imports: from collections import Counter
  import copy
  import gymnasium
  from gymnasium.spaces import Box, Discrete, MultiDiscrete, MultiBinary
  from gymnasium.spaces import Dict
  from gymnasium.spaces import Tuple
  import inspect
  import logging
  import numpy
  import os
  import pprint
  import random
  import re
  import time
  import tree
  from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Tuple, Type, Union
  import yaml
  import ray
  from ray import air, tune
  from ray.rllib.env.wrappers.atari_wrappers import is_atari, wrap_deepmind
  from ray.rllib.utils.framework import try_import_jax, try_import_tf, try_import_torch
  from ray.rllib.utils.metrics import DIFF_NUM_GRAD_UPDATES_VS_SAMPLER_POLICY, NUM_ENV_STEPS_SAMPLED, NUM_ENV_STEPS_TRAINED
  from ray.rllib.utils.nested_dict import NestedDict
  from ray.rllib.utils.typing import ResultDict
  from ray.rllib.utils.error import UnsupportedSpaceException
  from ray.tune import CLIReporter, run_experiments
label_desc: Use image node_id 2 for calling the ModelChecker obj's underlying member method code with example usage: obj.add(framework) and returns: outputs