Repository: Genesis-Embodied-AI/Genesis
File: genesis/utils/array_class.py (Python)

Code before:
    para_level: int = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    use_hibernation: bool = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    use_contact_island: bool = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    batch_links_info: bool = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    batch_dofs_info: bool = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    batch_joints_info: bool = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    enable_mujoco_compatibility: bool = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    enable_multi_contact: bool = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    enable_self_collision: bool = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    enable_adjacent_collision: bool = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    enable_collision: bool = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    box_box_detection: bool = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    integrator: int = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    sparse_solve: bool = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    solver_type: int = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})

    # dynamic properties
    substep_dt: float = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    iterations: int = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    tolerance: float = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    ls_iterations: int = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    ls_tolerance: float = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    n_equalities: int = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    n_equalities_candidate: int = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    hibernation_thresh_acc: float = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})
    hibernation_thresh_vel: float = dataclasses.field(metadata={FIELD_METADATA_CACHE_VALUE: True})


def get_static_rigid_sim_dummy(solver):
    kwargs = {
        "para_level": solver.sim._para_level,
        "use_hibernation": getattr(solver, "_use_hibernation", False),
        "use_contact_island": getattr(solver, "_use_contact_island", False),
        "batch_links_info": getattr(solver._options, "batch_links_info", False),
        "batch_dofs_info": getattr(solver._options, "batch_dofs_info", False),
        "batch_joints_info": getattr(solver._options, "batch_joints_info", False),
        "enable_mujoco_compatibility": getattr(solver, "_enable_mujoco_compatibility", False),
        "enable_multi_contact": getattr(solver, "_enable_multi_contact", True),
        "enable_self_collision": getattr(solver, "_enable_self_collision", True),
        "enable_adjacent_collision": getattr(solver, "_enable_adjacent_collision", False),
        "enable_collision": getattr(solver, "_enable_collision", False),
        "box_box_detection": getattr(solver, "_box_box_detection", False),
        "integrator": getattr(solver, "_integrator", gs.integrator.implicitfast),
        "sparse_solve": getattr(solver._options, "sparse_solve", False),
        "solver_type": getattr(solver._options, "constraint_solver", gs.constraint_solver.CG),
        # dynamic properties
        "substep_dt": solver._substep_dt,
        "iterations": getattr(solver._options, "iterations", 10),
        "tolerance": getattr(solver._options, "tolerance", 1e-6),
        "ls_iterations": getattr(solver._options, "ls_iterations", 10),
        "ls_tolerance": getattr(solver._options, "ls_tolerance", 1e-6),

Review comment (suggestion):
There was no request ot support floats, only ints and bools. Whilst it seems plausible tht it might work with floats, note that this is not tested. Please consider creating a PR onto gstaichi to add a test for floats. Something like https://github.com/Genesis-Embodied-AI/gstaichi/blob/a00b3aa5154b4b983df0c181cba3d60e20d190a8/tests/python/gstaichi/lang/fast_caching/test_args_hasher.py#L245 . (Yes, I agree that it also doesn't test bools, but floats seem more concerning to me, because of the potential for rounding issues).

Code after:
@dataclasses.dataclass
class StaticRigidSimCacheKey:
    para_level: int = cache_value()
    use_hibernation: bool = cache_value()
    batch_links_info: bool = cache_value()
    batch_dofs_info: bool = cache_value()
    batch_joints_info: bool = cache_value()
    enable_mujoco_compatibility: bool = cache_value()
    enable_multi_contact: bool = cache_value()
    enable_adjacent_collision: bool = cache_value()
    enable_collision: bool = cache_value()
    box_box_detection: bool = cache_value()
    integrator: int = cache_value()
    sparse_solve: bool = cache_value()
    solver_type: int = cache_value()


def get_static_rigid_sim_cache_key(solver):
    kwargs = {
        "para_level": solver.sim._para_level,
        "use_hibernation": getattr(solver, "_use_hibernation", False),
        "batch_links_info": getattr(solver._options, "batch_links_info", False),
        "batch_dofs_info": getattr(solver._options, "batch_dofs_info", False),
        "batch_joints_info": getattr(solver._options, "batch_joints_info", False),
        "enable_mujoco_compatibility": getattr(solver, "_enable_mujoco_compatibility", False),
        "enable_multi_contact": getattr(solver, "_enable_multi_contact", True),
        "enable_adjacent_collision": getattr(solver, "_enable_adjacent_collision", False),
        "enable_collision": getattr(solver, "_enable_collision", False),
        "box_box_detection": getattr(solver, "_box_box_detection", False),
        "integrator": getattr(solver, "_integrator", gs.integrator.implicitfast),
        "sparse_solve": getattr(solver._options, "sparse_solve", False),
        "solver_type": getattr(solver._options, "constraint_solver", gs.constraint_solver.CG),
    }
    return StaticRigidSimCacheKey(**kwargs)


# =========================================== DataManager ===========================================


@ti.data_oriented
class DataManager:
    def __init__(self, solver):
        # self.doughs = {}
        self.rigid_global_info = get_rigid_global_info(solver)
        self.dofs_info = get_dofs_info(solver)
        self.dofs_state = get_dofs_state(solver)
        self.links_info = get_links_info(solver)
        self.links_state = get_links_state(solver)
        self.joints_info = get_joints_info(solver)
        self.joints_state = get_joints_state(solver)
        self.geoms_info = get_geoms_info(solver)