code: def setup_cluster(
      cls, address_to_resources: Dict[str, Dict[str, Number]]
  ):
      logger.info("Setup cluster with %s", address_to_resources)
      # Note: Deep copy the dict to keep the origin values, because `bundles`
      # returned by `addresses_to_placement_group_info()` will be modified
      # by `ray.util.placement_group()`
      original_address_to_resources = copy.deepcopy(
          address_to_resources
      )
      pg_name, bundles = addresses_to_placement_group_info(
          address_to_resources
      )
      logger.info(
          "Creating placement group %s with bundles %s.",
          pg_name,
          bundles,
      )
      pg = ray.util.placement_group(
          name=pg_name, bundles=bundles, strategy="SPREAD"
      )
      create_pg_timeout = 120
      done, _ = ray.wait([pg.ready()], timeout=create_pg_timeout)
      if not done:  # pragma: no cover
          raise Exception(
              f"""Can't create placement group {pg.bundle_specs} in {create_pg_timeout} seconds"""
          )
      cluster_info = {
          "original_address_to_resources": original_address_to_resources,
          "address_to_resources": address_to_resources,
          "pg_name": pg_name,
          "pg_group": pg,
          "main_pool_handles": [],  # Hold actor_handle to avoid actor being freed.
      }
      logger.info("Create placement group success.")
      cls._cluster_info = cluster_info
  
file_path: mars/mars/oscar/backends/ray/driver.py
imports: import copy
  import logging
  import os
  from numbers import Number
  from typing import Dict
  from ....utils import lazy_import
  from ...driver import BaseActorDriver
  from .utils import process_placement_to_address, addresses_to_placement_group_info
label_desc: Use image node_id 1 for calling the RayActorDriver obj's underlying member method code with example usage: obj.setup_cluster(cls, address_to_resources) without return types