pub fn should_warn_cpu_on_apple_silicon(
device: &str,
is_apple_silicon: bool,
explicit: bool,
) -> bool {
!explicit && is_apple_silicon && device.eq_ignore_ascii_case("cpu")
}
pub fn is_device_explicit() -> bool {
matches!(
std::env::var("TRUSTY_DEVICE_EXPLICIT")
.ok()
.as_deref()
.map(str::to_ascii_lowercase)
.as_deref(),
Some("1") | Some("true") | Some("yes")
)
}
pub fn warn_if_stale_cpu_device_on_apple_silicon() {
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
{
let device = std::env::var("TRUSTY_DEVICE").unwrap_or_default();
let explicit = is_device_explicit();
if should_warn_cpu_on_apple_silicon(&device, true, explicit) {
tracing::warn!(
"TRUSTY_DEVICE=cpu is set on Apple Silicon — this disables CoreML ANE \
acceleration and is almost certainly a stale workaround from the resolved \
issue #24 (macOS jetsam SIGKILL during indexing). The root cause was fixed \
in trusty-search 0.3.55 by switching CoreML to CPUAndNeuralEngine mode, \
which avoids the unified-memory spike entirely. Remove TRUSTY_DEVICE=cpu \
from your daemon.env to restore ANE throughput (~10x CPU). If you \
intentionally want CPU-only mode, set TRUSTY_DEVICE_EXPLICIT=1 to suppress \
this warning."
);
}
}
}
#[cfg(test)]
mod tests {
use super::{is_device_explicit, should_warn_cpu_on_apple_silicon};
#[test]
fn should_warn_cpu_on_apple_silicon_true() {
assert!(should_warn_cpu_on_apple_silicon("cpu", true, false));
assert!(should_warn_cpu_on_apple_silicon("CPU", true, false));
assert!(should_warn_cpu_on_apple_silicon("Cpu", true, false));
}
#[test]
fn should_warn_cpu_on_apple_silicon_false_not_apple_silicon() {
assert!(!should_warn_cpu_on_apple_silicon("cpu", false, false));
assert!(!should_warn_cpu_on_apple_silicon("CPU", false, false));
}
#[test]
fn should_warn_cpu_on_apple_silicon_false_not_cpu() {
assert!(!should_warn_cpu_on_apple_silicon("", true, false));
assert!(!should_warn_cpu_on_apple_silicon("auto", true, false));
assert!(!should_warn_cpu_on_apple_silicon("gpu", true, false));
assert!(!should_warn_cpu_on_apple_silicon("GPU", true, false));
}
#[test]
fn should_warn_cpu_on_apple_silicon_false_explicit_set() {
assert!(!should_warn_cpu_on_apple_silicon("cpu", true, true));
assert!(!should_warn_cpu_on_apple_silicon("CPU", true, true));
assert!(!should_warn_cpu_on_apple_silicon("cpu", false, true));
}
#[test]
#[serial_test::serial]
fn device_explicit_flag_parses_truthy() {
for val in &["1", "true", "TRUE", "True", "yes", "YES"] {
unsafe { std::env::set_var("TRUSTY_DEVICE_EXPLICIT", val) };
assert!(
is_device_explicit(),
"TRUSTY_DEVICE_EXPLICIT={val} must be truthy"
);
}
unsafe { std::env::remove_var("TRUSTY_DEVICE_EXPLICIT") };
}
#[test]
#[serial_test::serial]
fn device_explicit_flag_parses_falsy() {
for val in &["0", "false", "no", "off", ""] {
unsafe { std::env::set_var("TRUSTY_DEVICE_EXPLICIT", val) };
assert!(
!is_device_explicit(),
"TRUSTY_DEVICE_EXPLICIT={val} must be falsy"
);
}
unsafe { std::env::remove_var("TRUSTY_DEVICE_EXPLICIT") };
assert!(
!is_device_explicit(),
"absent TRUSTY_DEVICE_EXPLICIT must be falsy"
);
}
}