topos 0.13.1

An autodiff compiler stack in Rust.
Documentation
//! The metal implementer: the always-compiled manifest, and the
//! simdgroup-matrix GPU kernels behind the `metal` feature.

use super::backend::BackendUnavailable;
use super::coverage::{Coverage, Dispatch, Fidelity};
use super::formula::{Formula, Precision};
use super::manifest::Manifest;

#[cfg(all(feature = "metal", target_os = "macos"))]
#[allow(unsafe_code)]
mod kernels;

#[cfg(all(feature = "metal", target_os = "macos"))]
pub(super) use kernels::{gemm_f32, map_f32};

/// The GPU rung for very large `f32` work, described in every build.
pub(super) struct Metal;

impl Manifest for Metal {
    const DISPATCH: Dispatch = Dispatch::Offered;

    fn coverage(formula: Formula) -> Coverage {
        match formula {
            // Hand-written simdgroup-matrix kernels for products and
            // elementwise maps; Metal has no `f64` at all, and the
            // GPU sums in tile order, so the fidelity is the envelope.
            Formula::Gemm | Formula::Map => Coverage::Serves {
                fidelity: Fidelity::Envelope,
                precisions: &[Precision::F32],
            },
            Formula::WindowProduct
            | Formula::ReduceWindow
            | Formula::BatchNormTraining
            | Formula::BatchNormInference => Coverage::Absent,
        }
    }

    fn compiled() -> bool {
        cfg!(all(feature = "metal", target_os = "macos"))
    }

    fn status() -> Result<(), BackendUnavailable> {
        if !cfg!(feature = "metal") {
            return Err(BackendUnavailable::NotCompiled);
        }
        if !cfg!(target_os = "macos") {
            return Err(BackendUnavailable::PlatformUnsupported);
        }
        #[cfg(all(feature = "metal", target_os = "macos"))]
        {
            kernels::status()
        }
        #[cfg(not(all(feature = "metal", target_os = "macos")))]
        {
            unreachable!("the cfg! guards above cover this build")
        }
    }
}