code: def plug_gpu_cards_to_vm(
      pyvmomi_sdk_provider,
      vm_name: str,
      gpu_cards: list,
      is_dynamic_pci_passthrough,
  ):
      """
      This function helps to add a list of gpu to a VM by PCI passthrough. Steps:
      1. Power off the VM if it is not at the off state.
      2. Construct a reconfigure spec and reconfigure the VM.
      3. Power on the VM.
      """
  
      # The VM is supposed to be at powered on status after instant clone.
      # We need to power it off.
      pyvmomi_sdk_provider.power_off_vm(vm_name)
  
      config_spec = vim.vm.ConfigSpec()
  
      # The below 2 advanced configs are needed for a VM to have a passthru PCI device
      config_spec.extraConfig = [
          vim.option.OptionValue(
              key="pciPassthru.64bitMMIOSizeGB", value="64"
          ),
          vim.option.OptionValue(
              key="pciPassthru.use64bitMMIO", value="TRUE"
          ),
      ]
  
      # PCI passthru device requires the memory to be hard reserved.
      config_spec.memoryReservationLockedToMax = True
      # https://kb.vmware.com/s/article/89638
      # Due to above known issue, we need to disable the cpu hot add for Ray nodes.
      # This will have no impact on our feature.
      config_spec.cpuHotAddEnabled = False
  
      # add the GPUs into the reconfigure spec.
      config_spec.deviceChange = []
  
      # get the VM's plugable PCI devices
      vm_obj = pyvmomi_sdk_provider.get_pyvmomi_obj(
          [vim.VirtualMachine], vm_name
      )
      pci_passthroughs = vm_obj.environmentBrowser.QueryConfigTarget(
          host=None
      ).pciPassthrough
  
      # The key is the id, such as '0000:3b:00.0'
      # The value is an instance of struct vim.vm.PciPassthroughInfo, please google it.
      id_to_pci_passthru_info = {
          item.pciDevice.id: item for item in pci_passthroughs
      }
  
      # The reason for this magic number -100 is following this page
      # https://gist.github.com/wiggin15/319b5e828c42af3aed40
      # The explanation can be found here:
      # https://vdc-download.vmware.com/vmwb-repository/dcr-public/
      # 790263bc-bd30-48f1-af12-ed36055d718b/e5f17bfc-ecba-40bf-a04f-376bbb11e811/
      # vim.vm.device.VirtualDevice.html
      key = -100
      for gpu_card in gpu_cards:
          pci_id = gpu_card.pciId
          custom_label = gpu_card.customLabel
          pci_passthru_info = id_to_pci_passthru_info[pci_id]
          device_id = pci_passthru_info.pciDevice.deviceId
          vendor_id = pci_passthru_info.pciDevice.vendorId
  
          backing = None
  
          if is_dynamic_pci_passthrough:
              logger.info(
                  f"Plugin GPU card - Id {pci_id} deviceId {device_id} "
                  f"vendorId {vendor_id} customLabel {custom_label} into VM {vm_name}"
              )
              allowed_device = vim.VirtualPCIPassthroughAllowedDevice(
                  vendorId=vendor_id,
                  deviceId=device_id,
              )
              backing = vim.VirtualPCIPassthroughDynamicBackingInfo(
                  allowedDevice=[allowed_device],
                  customLabel=custom_label,
                  assignedId=str(device_id),
              )
          else:
              logger.info(f"Plugin GPU card {pci_id} into VM {vm_name}")
              backing = vim.VirtualPCIPassthroughDeviceBackingInfo(
                  # This hex trick is what we must do to construct a backing info.
                  # https://gist.github.com/wiggin15/319b5e828c42af3aed40
                  # Otherwise the VM cannot be powered on.
                  deviceId=hex(
                      pci_passthru_info.pciDevice.deviceId % 2**16
                  ).lstrip("0x"),
                  id=pci_id,
                  systemId=pci_passthru_info.systemId,
                  vendorId=pci_passthru_info.pciDevice.vendorId,
                  deviceName=pci_passthru_info.pciDevice.deviceName,
              )
  
          gpu = vim.VirtualPCIPassthrough(key=key, backing=backing)
          device_change = vim.vm.device.VirtualDeviceSpec(
              operation="add", device=gpu
          )
          config_spec.deviceChange.append(device_change)
          key += 1
  
      WaitForTask(vm_obj.ReconfigVM_Task(spec=config_spec))
      pyvmomi_sdk_provider.power_on_vm(vm_name)
  
file_path: ray/python/ray/autoscaler/_private/vsphere/gpu_utils.py
imports: import logging
  from pyVim.task import WaitForTask
  from pyVmomi import vim
label_desc: Use image node_id 7 for calling a global function with example usage: plug_gpu_cards_to_vm(pyvmomi_sdk_provider, vm_name, gpu_cards, is_dynamic_pci_passthrough) without return types