Add Qualcomm Dragonwing NPU detection via FastRPC and selector support#335
Add Qualcomm Dragonwing NPU detection via FastRPC and selector support#335Sinan-Karakaya wants to merge 6 commits into
Conversation
… bus Introduce the FastRPC bus type and restrict it to NPU devices. Add Qualcomm hardware detection by checking for fastrpc nodes. Include NodeGlob field for NPU devices and update disk info gathering to silently skip nonexistent directories. Signed-off-by: Sinan KARAKAYA <sinan.karakaya@canonical.com>
| Platforms []PlatformInfo `json:"platforms,omitempty" yaml:"platforms,omitempty"` | ||
| Devices []DetectedDevice `json:"devices,omitempty" yaml:"devices,omitempty"` |
There was a problem hiding this comment.
I have concerns, that we are going to end up in a messy struct if we go this way.
Pci is a bus, PciDevice is a device on pci bus
Devices is like all devices? (excluding the ones on pci bus??)
And I see in DetectedDevice struct we have Bus field but then why pcidevices can not be part of Devices?
This will require some fundamental changes in this PR so feel free to challenge or ask questions if you need things to be cleared
There was a problem hiding this comment.
Mmh right, the option I could see to fix that would be to consolidate everything under DetectedDevice and maybe deprecate PciDevices, but that's not ideal either, I don't want to introduce breaking changes.
I thought about maybe merging the 2 kind of devices together, but they map very differently (PciDevice is a detailed catalog entry from lspci, while DetectedDevice is a runtime signal that a device exists, regardless of its bus).
So I'm not sure if there would have been a cleaner solution than I could have done. I can document a bit more DetectedDevice to emphasize that it serves a different purpose than PciDevice
There was a problem hiding this comment.
I would prefer to have cleaner solution even if it causes breaking changes as it maybe way harder to change things later once they are grown so much. (Thats why versioning exist I think)
But that said I am not the owner of this repo/project so it is up to @farshidtz and/or @jpm-canonical decide if they dont want breaking changes.
There was a problem hiding this comment.
I already made @jpm-canonical aware of this issue, they'll discuss it in their team and come back to us for this issue :)
There was a problem hiding this comment.
Pull request overview
This PR extends the hardware detection + engine selection pipeline to recognize Qualcomm Dragonwing NPUs exposed via FastRPC device nodes, enabling manifests to target type: npu with bus: fastrpc. It also adds a small robustness improvement to disk info collection when directories are missing.
Changes:
- Add
HwInfo.Platforms/HwInfo.Devicesplus newPlatformInfo/DetectedDevicetypes to represent non-PCI device detections. - Implement Qualcomm FastRPC node detection and integrate FastRPC device matching into the engine selector (including
node-globsupport). - Make disk info collection skip missing directories instead of failing.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/types/hw_info.go | Extends HwInfo with Platforms and Devices to support non-PCI detections. |
| pkg/types/detected_devices.go | Adds new types for detected platforms and devices (bus/type/nodes). |
| pkg/hardware_info/qualcomm/qualcomm.go | Implements Qualcomm detection via /dev/fastrpc-* and CDSP node discovery. |
| pkg/hardware_info/qualcomm/qualcomm_test.go | Tests Qualcomm platform/device detection and node filtering/sorting. |
| pkg/hardware_info/hardware-info.go | Wires Qualcomm detection into Get() and raw-data test harness ingestion. |
| pkg/selector/select_stack.go | Adds FastRPC bus support to selection scoring for all-of / any-of device requirements. |
| pkg/selector/fastrpc/fastrpc.go | Implements FastRPC matcher using node globbing + optional snap-connection checks. |
| pkg/selector/fastrpc/fastrpc_test.go | Unit tests for FastRPC matching behavior (default/custom/no match). |
| pkg/selector/fastrpc_test.go | End-to-end selector test ensuring a FastRPC NPU device yields a compatible engine. |
| pkg/engines/types.go | Adds node-glob to device schema and documents fastrpc as a supported bus. |
| pkg/engines/busses.go | Adds bus validation for fastrpc and permits NodeGlob + snap connections. |
| pkg/engines/busses_test.go | Adds validation test ensuring fastrpc is rejected for non-NPU device types. |
| pkg/engines/devices_test.go | Adds NPU FastRPC validation tests for allowed/forbidden fields. |
| pkg/hardware_info/disk/disk_info.go | Skips missing directories during disk stat collection. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| compatible = false | ||
| device.CompatibilityIssues = append(device.CompatibilityIssues, "usb device matching not implemented") |
| continue | ||
| } | ||
|
|
||
| score := weights.PciDevice + weights.PciDeviceType |
| for _, connection := range manifestDevice.SnapConnections { | ||
| if testing.Testing() { | ||
| continue | ||
| } | ||
| connected, err := snapctl.IsConnected(connection).Run() | ||
| if err != nil { | ||
| return 0, []string{fmt.Sprintf("checking snap connection %q: %v", connection, err)} | ||
| } | ||
| if !connected { | ||
| return 0, []string{fmt.Sprintf("%q is not connected", connection)} | ||
| } | ||
| } |
| func (device Device) validateFastRpc(extraFields []string) error { | ||
| if device.Type != "" && device.Type != "npu" { | ||
| return fmt.Errorf("fastrpc bus only supports npu devices") | ||
| } | ||
|
|
||
| validFields := []string{ | ||
| "Type", | ||
| "Bus", | ||
| "NodeGlob", | ||
| "SnapConnections", | ||
| } | ||
| validFields = append(validFields, extraFields...) |
…edDevices Flattened NPU nodes (ADSP, CDSP, GDSP) to be considered as distinct devices rather than relying on DetectedDevice.Nodes. PlatformsInfo was moved from Devices to DetectedDevices, to avoid having to keep a relationship between each devices and their respective platform's metadata. Signed-off-by: Sinan KARAKAYA <sinan.karakaya@canonical.com> Co-authored-by: Copilot <copilot@github.com>
…C->VendorName Co-authored-by: Copilot <copilot@github.com>
…metadata Co-authored-by: Copilot <copilot@github.com>
849e490 to
b7e3e6a
Compare
21a9558 to
a0be393
Compare
a0be393 to
ca750dd
Compare
|
Corresponding PR for the detection moved to lscompute: canonical/lscompute#15 |
|
The hardware detection part of this change has been merged into lscompute in this PR. And this project has been updated to use lscompute for hardware detection. The selection logic from this PR is however still missing. @Sinan-Karakaya could you refactor this PR, or create a new one, that adds the selection logic for fastrpc devices to this project? |
This PR adds proper support for Qualcomm Dragonwing NPUs that show up through FastRPC device nodes.
Until now, our detection/selection flow was mostly centered around PCI/USB-style signals. On Dragonwing systems that meant we could miss valid NPU-capable setups, or fail to confidently match engines that should run there. This change closes that gap.
What’s in here
Added new hardware info fields for detected platforms/devices.
Added Qualcomm detection logic that looks at FastRPC nodes (
/dev/fastrpc-*, especially CDSP nodes).Added
fastrpcas a supported bus in engine/device validation.Added selector matching/scoring logic for FastRPC devices.
Added tests across detection, validation, and selector behavior.
Small robustness fix: disk info collection now skips missing directories instead of failing hard.
Why this matters
On Dragonwing hardware, NPU availability is represented differently from traditional PCI GPU-style setups. By recognizing FastRPC directly, we can now:
type: npu+bus: fastrpc.Behavior after this PR
On a Dragonwing machine with FastRPC CDSP nodes present:
show-machineincludes Qualcomm/Dragonwing in platforms and an NPU FastRPC device entry.debug select-enginecan positively match engines that target FastRPC NPUs.Compatibility
This is additive. Existing PCI/USB paths are unchanged, and current manifests continue to behave as before.