#[cfg(feature = "gpu")]
use super::backend;
#[must_use]
pub fn gpu_probe() -> (bool, Option<String>, Option<u64>) {
if env_no_gpu() {
return (false, None, None);
}
#[cfg(feature = "gpu")]
if let Some(gpu) = backend::get_gpu() {
return (true, Some(gpu.gpu_name().to_string()), gpu.vram_mb());
}
(false, None, None)
}
#[must_use]
pub fn env_require_gpu() -> bool {
std::env::var("KEYHOG_REQUIRE_GPU").as_deref() == Ok("1")
}
pub fn require_gpu_preflight() -> Result<(), String> {
if !env_require_gpu() {
return Ok(());
}
let caps = crate::hw_probe::probe_hardware();
if !caps.gpu_available || caps.gpu_is_software {
let detail = match (&caps.gpu_name, caps.gpu_is_software) {
(Some(name), true) => {
format!("only a software GPU adapter is present ({name})")
}
(Some(name), false) => format!("adapter present but unusable ({name})"),
(None, _) => "no GPU adapter detected".to_string(),
};
return Err(format!(
"KEYHOG_REQUIRE_GPU=1 but {detail}; refusing to run on CPU. \
Install or enable a non-software GPU adapter + driver, or unset \
KEYHOG_REQUIRE_GPU to allow the CPU/SIMD path."
));
}
if let Err(reason) = super::gpu_self_test() {
return Err(format!(
"KEYHOG_REQUIRE_GPU=1 but the GPU self-test failed ({reason}); \
refusing to run on CPU. Fix the GPU stack or unset \
KEYHOG_REQUIRE_GPU."
));
}
Ok(())
}
pub fn env_no_gpu() -> bool {
if let Ok(v) = std::env::var("KEYHOG_NO_GPU") {
return !matches!(v.as_str(), "" | "0" | "false" | "FALSE" | "off" | "OFF");
}
if env_require_gpu() {
return false;
}
is_ci_environment()
}
pub fn is_ci_environment() -> bool {
if let Ok(v) = std::env::var("CI") {
if !matches!(v.as_str(), "" | "0" | "false" | "FALSE" | "off" | "OFF") {
return true;
}
}
const CI_MARKERS: &[&str] = &[
"GITHUB_ACTIONS", "GITLAB_CI", "JENKINS_URL", "TF_BUILD", "TEAMCITY_VERSION", "BITBUCKET_BUILD_NUMBER", "BUILDKITE", "CIRCLECI", "DRONE", "TRAVIS", "APPVEYOR", "CODEBUILD_BUILD_ID", "WERCKER", "SEMAPHORE", ];
CI_MARKERS.iter().any(|k| std::env::var(k).is_ok())
}