ferrum_kernels/backend/reference/
composition.rs1use std::collections::BTreeSet;
2use std::sync::Arc;
3
4use ferrum_interfaces::vnext::{
5 dense_linear_contract, CapabilityCatalog, CapabilityId, ContractVersion, DeviceClass,
6 DeviceDescriptor, DeviceId, DeviceRuntime, DynamicStorageAllocator, DynamicStorageProfile,
7 DynamicStorageView, EngineProviderDescriptor, OperationContract, OperationProvider,
8 OperationRuntimeRegistry, ProviderId, VNextError, WeightMaterializerId,
9 WeightMaterializerRegistry, DENSE_LINEAR_F16_CAPABILITY_ID, IDENTITY_WEIGHT_MATERIALIZER_ID,
10};
11
12use super::dense_linear::{implementation_fingerprint, ReferenceDenseLinearProvider};
13use super::runtime::{
14 ReferenceDeviceRuntime, ReferenceDeviceRuntimeConfig, ReferenceDeviceRuntimeError,
15};
16
17const REFERENCE_ENGINE_PROVIDER_ID: &str = "provider.engine.reference.vnext";
18pub const REFERENCE_DENSE_SAFETENSORS_FORMAT_ID: &str = "weight-format.safetensors.dense";
19const REFERENCE_MEMORY_BYTES: u64 = 64 * 1024 * 1024;
20
21pub fn reference_vnext_capabilities() -> Result<BTreeSet<CapabilityId>, VNextError> {
22 Ok(BTreeSet::from([CapabilityId::new(
23 DENSE_LINEAR_F16_CAPABILITY_ID,
24 )?]))
25}
26
27pub(super) fn reference_vnext_runtime_config(
28 device_id: DeviceId,
29) -> Result<ReferenceDeviceRuntimeConfig, VNextError> {
30 let descriptor = DeviceDescriptor {
31 id: device_id,
32 class: DeviceClass::Reference,
33 ordinal: 0,
34 total_memory_bytes: REFERENCE_MEMORY_BYTES,
35 runtime_implementation_fingerprint: implementation_fingerprint(&[
36 include_str!("runtime.rs").as_bytes(),
37 include_str!("dense_linear.rs").as_bytes(),
38 include_str!("composition.rs").as_bytes(),
39 ]),
40 capabilities: reference_vnext_capabilities()?,
41 dynamic_storage_profiles: BTreeSet::from([DynamicStorageProfile::new(
42 DynamicStorageAllocator::LinearArena,
43 DynamicStorageView::Contiguous,
44 )?]),
45 };
46 descriptor.validate()?;
47 Ok(ReferenceDeviceRuntimeConfig { descriptor })
48}
49
50pub fn reference_vnext_operation_registry(
51 runtime: &ReferenceDeviceRuntime,
52) -> Result<OperationRuntimeRegistry<ReferenceDeviceRuntime>, ReferenceDeviceRuntimeError> {
53 let contracts: Vec<Box<dyn OperationContract>> =
54 vec![Box::new(dense_linear_contract().map_err(contract_error)?)];
55 let providers: Vec<Box<dyn OperationProvider<ReferenceDeviceRuntime>>> =
56 vec![Box::new(ReferenceDenseLinearProvider::new(runtime)?)];
57 OperationRuntimeRegistry::new(contracts, providers).map_err(contract_error)
58}
59
60pub struct ReferenceVNextComposition {
63 runtime: Arc<ReferenceDeviceRuntime>,
64 registry: OperationRuntimeRegistry<ReferenceDeviceRuntime>,
65 weight_materializers: WeightMaterializerRegistry,
66 weight_materializer_id: WeightMaterializerId,
67 catalog: CapabilityCatalog,
68}
69
70impl ReferenceVNextComposition {
71 pub fn create(device_id: DeviceId) -> Result<Self, ReferenceDeviceRuntimeError> {
72 let config = reference_vnext_runtime_config(device_id).map_err(contract_error)?;
73 let runtime = Arc::new(ReferenceDeviceRuntime::new(config)?);
74 let registry = reference_vnext_operation_registry(&runtime)?;
75 let weight_materializers =
76 WeightMaterializerRegistry::identity_only().map_err(contract_error)?;
77 let weight_materializer_id =
78 WeightMaterializerId::new(IDENTITY_WEIGHT_MATERIALIZER_ID).map_err(contract_error)?;
79 let engine = EngineProviderDescriptor::new(
80 ProviderId::new(REFERENCE_ENGINE_PROVIDER_ID).map_err(contract_error)?,
81 ContractVersion::new(1, 0),
82 implementation_fingerprint(&[
83 include_str!("composition.rs").as_bytes(),
84 REFERENCE_ENGINE_PROVIDER_ID.as_bytes(),
85 ]),
86 runtime.descriptor().id.clone(),
87 runtime.descriptor().capabilities.clone(),
88 )
89 .map_err(contract_error)?;
90 let catalog = registry
91 .capability_catalog(runtime.descriptor().clone(), vec![engine])
92 .map_err(contract_error)?;
93 let catalog = weight_materializers
94 .augment_catalog(catalog)
95 .map_err(contract_error)?;
96 Ok(Self {
97 runtime,
98 registry,
99 weight_materializers,
100 weight_materializer_id,
101 catalog,
102 })
103 }
104
105 pub fn runtime(&self) -> &Arc<ReferenceDeviceRuntime> {
106 &self.runtime
107 }
108
109 pub fn registry(&self) -> &OperationRuntimeRegistry<ReferenceDeviceRuntime> {
110 &self.registry
111 }
112
113 pub fn catalog(&self) -> &CapabilityCatalog {
114 &self.catalog
115 }
116
117 pub fn weight_materializers(&self) -> &WeightMaterializerRegistry {
118 &self.weight_materializers
119 }
120
121 pub fn weight_materializer_id(&self) -> &WeightMaterializerId {
122 &self.weight_materializer_id
123 }
124}
125
126fn contract_error(error: VNextError) -> ReferenceDeviceRuntimeError {
127 ReferenceDeviceRuntimeError::contract(error.to_string())
128}