candding 0.1.0

Pure candle embeddings for Rust with no ONNX: dense, sparse, multi-vector and rerank models today, image models on the roadmap
Documentation
use super::*;
use crate::registry::CellException;
use crate::registry::multi_vector;
use crate::registry::rerank;
use crate::registry::sparse;
use crate::registry::support::rules::Cells;

const V: Support = Support::Verified;

pub(super) fn every_entry() -> Vec<(&'static str, Cells<'static>)> {
  let mut every: Vec<_> = entries().map(|entry| ("dense", entry.cells())).collect();
  every.extend(
    sparse::ENTRIES
      .iter()
      .map(|entry| ("sparse", entry.cells())),
  );
  every.extend(
    multi_vector::ENTRIES
      .iter()
      .map(|entry| ("multi-vector", entry.cells())),
  );
  every.extend(
    rerank::ENTRIES
      .iter()
      .map(|entry| ("rerank", entry.cells())),
  );
  every
}

#[test]
fn every_cell_exception_in_every_catalog_holds() {
  let every = every_entry();
  assert_eq!(every.len(), 35 + 6 + 4 + 8);
  for (_, cells) in every {
    assert_eq!(cells.exception_violation(), None);
  }
}

/// `registry::tests::verified` counts `Verified` cells, so none may come from an exception.
#[test]
fn no_cell_exception_in_any_catalog_writes_a_verified_cell() {
  for (catalog, cells) in every_entry() {
    let found = cells.verified_by_an_exception();
    assert!(found.is_empty(), "{catalog} {}: {found:?}", cells.id);
  }
}

fn crafted(exceptions: &[CellException]) -> Cells<'_> {
  let backends = BackendSupport {
    cpu: V,
    metal: V,
    cuda: V,
  };
  let rows = DtypeBackendSupport::derive(backends, DtypeSupport::verified(), &[]);
  Cells {
    id: "crafted",
    backends,
    dtypes: DtypeSupport::verified(),
    accel_only: &[],
    exceptions,
    rows: rows.with_exceptions(exceptions),
  }
}

fn exception(dtype: DType, backend: Backend, status: Support) -> CellException {
  CellException {
    dtype,
    backend,
    status,
    reason: "a run that decided this cell",
  }
}

#[test]
fn a_cuda_exception_writes_untested_or_a_failure_a_cited_run_measured() {
  let cuda = |status, reason| CellException {
    dtype: DType::BF16,
    backend: Backend::Cuda,
    status,
    reason,
  };
  for (status, reason, allowed) in [
    (Support::Untested, "no BF16 kernels below sm_80", true),
    (
      Support::Unsupported,
      "cuda.yml run 42 on a T4: NaN vectors",
      true,
    ),
    (Support::Unsupported, "a run that decided this cell", false),
    (Support::Unsupported, "NaN vectors on a T4", false),
    (Support::Pending, "cuda.yml run 42 is queued", false),
  ] {
    let violation = crafted(&[cuda(status, reason)]).exception_violation();
    match allowed {
      true => assert_eq!(violation, None, "{status:?} {reason}"),
      false => assert!(
        violation.is_some_and(|v| v.contains("a CUDA cell other than untested")),
        "{status:?} {reason}"
      ),
    }
  }
  for status in [Support::Untested, Support::Unsupported, Support::Pending] {
    let on_metal = [exception(DType::F32, Backend::Metal, status)];
    assert_eq!(crafted(&on_metal).exception_violation(), None, "{status:?}");
  }
}

const METAL_F32_UNRUN: &[CellException] = &[CellException {
  dtype: DType::F32,
  backend: Backend::Metal,
  status: Support::Untested,
  reason: "a Metal F32 load that did not fit the machine",
}];

#[test]
fn the_dense_sparse_and_multi_vector_descriptors_write_their_exceptions() {
  let dense = Entry {
    cell_exceptions: METAL_F32_UNRUN,
    ..crate::registry::bert::ENTRIES[0]
  };
  let sparse = sparse::SparseEntry {
    cell_exceptions: METAL_F32_UNRUN,
    ..sparse::ENTRIES[0]
  };
  let multi_vector = multi_vector::MultiVectorEntry {
    cell_exceptions: METAL_F32_UNRUN,
    ..multi_vector::ENTRIES[0]
  };
  for cells in [dense.cells(), sparse.cells(), multi_vector.cells()] {
    assert_eq!(cells.rows.f32.metal, Support::Untested, "{}", cells.id);
    assert_eq!(cells.exception_violation(), None);
  }
}