use candle_core::DType;
use candle_core::Device;
use crate::embed::builder::reject_unsupported_dtype;
use crate::error::CanddingError;
use crate::registry::Backend;
use crate::registry::BackendSupport;
use crate::registry::DtypeBackendSupport;
use crate::registry::Support;
use crate::registry::sparse;
const V: Support = Support::Verified;
const U: Support = Support::Unsupported;
const T: Support = Support::Untested;
fn row(cpu: Support, metal: Support, cuda: Support) -> BackendSupport {
BackendSupport { cpu, metal, cuda }
}
fn axis() -> DtypeBackendSupport {
DtypeBackendSupport {
f32: row(V, V, T),
f16: row(U, V, T),
bf16: row(U, U, U),
}
}
#[test]
fn a_cpu_only_unsupported_cell_is_refused_on_the_cpu_as_accelerator_only() {
let err = reject_unsupported_dtype("m", DType::F16, axis(), &Device::Cpu).unwrap_err();
assert!(
matches!(&err, CanddingError::UnsupportedOnDevice { model, backend: Backend::Cpu, dtype: DType::F16 } if model == "m"),
"{err}"
);
let message = err.to_string();
assert!(message.contains("f16"), "{message}");
assert!(message.contains("accelerator-only"), "{message}");
assert!(!message.contains("NaN"), "{message}");
}
#[test]
fn a_dtype_unsupported_on_every_device_is_refused_as_unsupported() {
let err = reject_unsupported_dtype("m", DType::BF16, axis(), &Device::Cpu).unwrap_err();
assert!(
matches!(&err, CanddingError::UnsupportedDtype { model, dtype: DType::BF16 } if model == "m"),
"{err}"
);
}
#[test]
fn a_verified_cell_passes() {
assert!(reject_unsupported_dtype("m", DType::F32, axis(), &Device::Cpu).is_ok());
}
#[test]
fn a_supplied_row_is_trusted_over_the_registry_entry_the_spec_names() {
let verified = DtypeBackendSupport {
f16: row(V, V, T),
..axis()
};
assert!(reject_unsupported_dtype("BAAI/bge-m3", DType::F16, verified, &Device::Cpu).is_ok());
}
#[test]
fn both_registered_accelerator_only_entries_are_refused_on_the_cpu_and_verified_on_metal() {
for id in ["BAAI/bge-m3", "jinaai/jina-embeddings-v2-small-en"] {
let descriptor = sparse::lookup(id).expect("registered");
assert_eq!(descriptor.dtype_backends.f16.metal, V, "{id}");
let err = reject_unsupported_dtype(id, DType::F16, descriptor.dtype_backends, &Device::Cpu)
.unwrap_err();
assert!(
matches!(&err, CanddingError::UnsupportedOnDevice { model, backend: Backend::Cpu, dtype: DType::F16 } if model == id),
"{id}: {err}"
);
}
}