ferrum_interfaces/vnext/execution/
planner.rs1use super::{
2 CapabilityCatalog, DeviceDescriptor, ExecutionPlan, PlanBuildRequest, RuntimePolicy, VNextError,
3};
4
5pub trait ExecutablePlanView {
9 fn execution_plan(&self) -> &ExecutionPlan;
10 fn device(&self) -> &DeviceDescriptor;
11 fn capabilities(&self) -> &CapabilityCatalog;
12}
13
14#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct ExecutablePlan {
19 plan: ExecutionPlan,
20 capabilities: CapabilityCatalog,
21}
22
23impl ExecutablePlan {
24 pub fn new(plan: ExecutionPlan, capabilities: CapabilityCatalog) -> Result<Self, VNextError> {
25 let catalog_fingerprint = capabilities.fingerprint()?;
26 if plan.payload().device_id() != &capabilities.device().id
27 || plan.payload().device_runtime_implementation_fingerprint()
28 != capabilities.device().runtime_implementation_fingerprint
29 || plan.payload().capability_catalog_fingerprint() != catalog_fingerprint
30 {
31 return Err(VNextError::InvalidExecutionPlan {
32 reason: "executable plan differs from its device capability catalog".to_owned(),
33 });
34 }
35 Ok(Self { plan, capabilities })
36 }
37
38 pub fn into_parts(self) -> (ExecutionPlan, CapabilityCatalog) {
39 (self.plan, self.capabilities)
40 }
41}
42
43impl ExecutablePlanView for ExecutablePlan {
44 fn execution_plan(&self) -> &ExecutionPlan {
45 &self.plan
46 }
47
48 fn device(&self) -> &DeviceDescriptor {
49 self.capabilities.device()
50 }
51
52 fn capabilities(&self) -> &CapabilityCatalog {
53 &self.capabilities
54 }
55}
56
57pub trait ExecutionPlanner: Send + Sync {
60 type Policy: RuntimePolicy;
61
62 fn build_plan(
63 &self,
64 request: PlanBuildRequest<'_, Self::Policy>,
65 ) -> Result<ExecutionPlan, VNextError>;
66}