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","."]
docstr: Node_address-to-device_string mapping of all gpu devices.
code: def node_gpu_devices(self):
      """Node_address-to-device_string mapping of all gpu devices."""
      _gpu_devices = dict()
      for device in self.gpu_devices:
          _gpu_devices.setdefault(device[0].split(":")[0], []).append(
              device[0]
          )
      return _gpu_devices
  
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 8 for calling the ResourceSpec obj's underlying member method code with example usage: obj.node_gpu_devices() and returns: _gpu_devices