Skip to content

Add Qualcomm Dragonwing NPU detection via FastRPC and selector support#335

Draft
Sinan-Karakaya wants to merge 6 commits into
canonical:mainfrom
Sinan-Karakaya:sinan/hw-detection-qualcomm
Draft

Add Qualcomm Dragonwing NPU detection via FastRPC and selector support#335
Sinan-Karakaya wants to merge 6 commits into
canonical:mainfrom
Sinan-Karakaya:sinan/hw-detection-qualcomm

Conversation

@Sinan-Karakaya

Copy link
Copy Markdown

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 fastrpc as 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:

  • report the platform/device state more accurately, and
  • successfully select engines that declare type: npu + bus: fastrpc.

Behavior after this PR

On a Dragonwing machine with FastRPC CDSP nodes present:

  • show-machine includes Qualcomm/Dragonwing in platforms and an NPU FastRPC device entry.
  • debug select-engine can 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.

… 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>
Comment thread pkg/types/hw_info.go Outdated
Comment on lines +8 to +9
Platforms []PlatformInfo `json:"platforms,omitempty" yaml:"platforms,omitempty"`
Devices []DetectedDevice `json:"devices,omitempty" yaml:"devices,omitempty"`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I already made @jpm-canonical aware of this issue, they'll discuss it in their team and come back to us for this issue :)

@Sinan-Karakaya Sinan-Karakaya marked this pull request as ready for review April 23, 2026 12:05
Copilot AI review requested due to automatic review settings April 23, 2026 12:05

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.Devices plus new PlatformInfo / DetectedDevice types to represent non-PCI device detections.
  • Implement Qualcomm FastRPC node detection and integrate FastRPC device matching into the engine selector (including node-glob support).
  • 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.

Comment on lines 214 to 215
compatible = false
device.CompatibilityIssues = append(device.CompatibilityIssues, "usb device matching not implemented")
Comment thread pkg/selector/fastrpc/fastrpc.go Outdated
continue
}

score := weights.PciDevice + weights.PciDeviceType
Comment thread pkg/selector/fastrpc/fastrpc.go Outdated
Comment on lines +40 to +51
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)}
}
}
Comment thread pkg/engines/busses.go
Comment on lines +55 to +66
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>
Comment thread pkg/types/detected_devices.go Outdated
…C->VendorName

Co-authored-by: Copilot <copilot@github.com>
Comment thread pkg/types/detected_devices.go Outdated
@Sinan-Karakaya Sinan-Karakaya force-pushed the sinan/hw-detection-qualcomm branch from a0be393 to ca750dd Compare April 29, 2026 14:44
@farshidtz

Copy link
Copy Markdown
Member

Corresponding PR for the detection moved to lscompute: canonical/lscompute#15

@farshidtz farshidtz marked this pull request as draft June 9, 2026 08:32
@jpm-canonical

Copy link
Copy Markdown
Contributor

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants