class_docstr: Resource Spec.
  
  Contains node and SSH information found by parsing a `resource_spec.yml`.
  
  # TODO: Make it a real Graph (a clique), with edge weights being network bandwidth.
      This would allow for even more intelligent strategy generation.
class_docstr_tok: ["Resource","Spec",".","Contains","node","and","SSH","information","found","by","parsing","a","`","resource_spec.yml","`",".","#","TODO",":","Make","it","a","real","Graph","(","a","clique",")",",","with","edge","weights","being","network","bandwidth",".","This","would","allow","for","even","more","intelligent","strategy","generation","."]
code: def _from_resource_info(self, resource_file=None):
      if resource_file is None:
          # TODO(Hao): To deal with single-node GPUs
          return
  
      resource_info = yaml.safe_load(open(resource_file, "r"))
      num_nodes = len(resource_info.get("nodes", {}))
  
      for node in resource_info.pop("nodes", {}):
          self._parse_node(node, num_nodes)
  
      # Make sure there is a chief set
      if not self.__chief_address:
          raise ValueError("Must specify one of the nodes to be chief.")
  
      # all other configs except nodes are (optional) ssh config
      gpu_devices = self.node_gpu_devices
      if is_local_address(self.__chief_address):
          self.__ssh_config_map = SSHConfigMap(
              resource_info.pop("ssh", {}),
              self.__ssh_group,
              gpu_devices,
          )
  
      # checks
      if self.__chief_address is None:
          raise ValueError(
              'Must provide "chief: true" in one of the nodes in resource spec.'
          )
  
imports: import os
  import re
  from enum import Enum
  from typing import NamedTuple, Optional, Dict
  import yaml
  import paramiko
  from autodist.utils import logging
  from autodist.utils.network import is_loopback_address, is_local_address
label_desc: Use image node_id 15 for calling the ResourceSpec obj's underlying member method code with example usage: obj._from_resource_info(resource_file) without return types