(gpu_cfg: &rpc::GpuConfig)
| 84 | } |
| 85 | |
| 86 | pub fn resolve_gpus(gpu_cfg: &rpc::GpuConfig) -> Result<GpuConfig> { |
| 87 | // Check the attach mode to determine how to handle GPUs |
| 88 | match gpu_cfg.attach_mode.as_str() { |
| 89 | "listed" => { |
| 90 | // If the mode is "listed", use the GPUs specified in the request |
| 91 | let gpus = gpu_cfg |
| 92 | .gpus |
| 93 | .iter() |
| 94 | .map(|g| GpuSpec { |
| 95 | slot: g.slot.clone(), |
| 96 | }) |
| 97 | .collect(); |
| 98 | |
| 99 | Ok(GpuConfig { |
| 100 | attach_mode: AttachMode::Listed, |
| 101 | gpus, |
| 102 | bridges: Vec::new(), |
| 103 | }) |
| 104 | } |
| 105 | "all" => { |
| 106 | // If the mode is "all", find all NVIDIA GPUs and NVSwitches |
| 107 | let devices = lspci::lspci_filtered(|dev| { |
| 108 | // Check if it's an NVIDIA device (vendor ID 10de) |
| 109 | dev.vendor_id == "10de" |
| 110 | }) |
| 111 | .context("Failed to list PCI devices")?; |
| 112 | |
| 113 | let mut gpus = Vec::new(); |
| 114 | let mut bridges = Vec::new(); |
| 115 | |
| 116 | for dev in devices { |
| 117 | // Check if it's a GPU (3D controller) or NVSwitch (Bridge) |
| 118 | if dev.class.contains("3D controller") { |
| 119 | gpus.push(GpuSpec { slot: dev.slot }); |
| 120 | } else if dev.class.contains("Bridge") { |
| 121 | bridges.push(GpuSpec { slot: dev.slot }); |
| 122 | } |
| 123 | } |
| 124 | Ok(GpuConfig { |
| 125 | attach_mode: AttachMode::All, |
| 126 | gpus, |
| 127 | bridges, |
| 128 | }) |
| 129 | } |
| 130 | _ => bail!("Invalid GPU attach mode: {}", gpu_cfg.attach_mode), |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | // Shared function to create manifest from VM configuration |
| 135 | pub fn create_manifest_from_vm_config( |
no test coverage detected