Skip to main content

hrx/
target.rs

1use crate::{Error, Result};
2use std::ffi::CString;
3
4/// Default compiler target; devices report their architecture at runtime.
5pub const TARGET_KEY: &str = "gfx1151";
6
7/// An exact AMDGPU or XDNA deployment key.
8///
9/// This is the *profile* target: what a device reports and what the compiler
10/// emits for. It is deliberately narrower than the target a Loom source file
11/// names in `amdgpu.target<...>`, which accepts generic families such as
12/// `gfx11-generic`. The two are chosen independently — generic source compiles
13/// under a bare profile — so this type rejects generic names rather than
14/// silently accepting one a device can never report.
15#[derive(Clone, Debug, PartialEq, Eq)]
16pub struct Target(CString);
17impl Target {
18    /// Validate an architecture key, for example gfx1100, gfx1151 or gfx942.
19    /// Availability is determined by the selected native runtime and compiler.
20    /// Keys must be bare architecture names, without feature suffixes.
21    pub fn new(key: &str) -> Result<Self> {
22        if key == "amd.xdna.strix_halo.17f0_11" {
23            return Ok(Self(CString::new(key).unwrap()));
24        }
25        if key.contains(':') {
26            return Err(Error::Message(format!(
27                "expected a bare AMDGPU target, found feature-suffixed name {key:?}"
28            )));
29        }
30        let suffix = key.strip_prefix("gfx").unwrap_or("");
31        if !(3..=4).contains(&suffix.len())
32            || !suffix
33                .bytes()
34                .all(|b| b.is_ascii_digit() || (b'a'..=b'f').contains(&b))
35        {
36            return Err(Error::Message(format!("invalid AMDGPU target {key:?}")));
37        }
38        Ok(Self(
39            CString::new(key).expect("validated target has no NUL"),
40        ))
41    }
42    /// Exact Strix Halo NPU5 deployment profile.
43    pub fn xdna() -> Self {
44        Self::new("amd.xdna.strix_halo.17f0_11").unwrap()
45    }
46    /// Whether this profile targets native XDNA execution.
47    pub fn is_xdna(&self) -> bool {
48        self.as_str().starts_with("amd.xdna.")
49    }
50    pub(crate) fn artifact_format(&self) -> &'static str {
51        if self.is_xdna() {
52            "xdna"
53        } else {
54            "amdgpu-hsaco"
55        }
56    }
57    pub(crate) fn artifact_filename(&self) -> &'static str {
58        if self.is_xdna() {
59            "kernel.xdna"
60        } else {
61            "kernel.hsaco"
62        }
63    }
64    /// Exact architecture key.
65    pub fn as_str(&self) -> &str {
66        self.0.to_str().expect("validated ASCII target")
67    }
68    /// Bundle platform and architecture identifier.
69    pub fn manifest_key(&self) -> String {
70        format!("x86_64-unknown-linux-gnu-{}", self.as_str())
71    }
72}
73
74impl Default for Target {
75    fn default() -> Self {
76        Self::new(TARGET_KEY).expect("valid default target")
77    }
78}