use std::any::Any;
use std::fmt;
use std::hash::Hasher;
use tenferro_ops::ext_op::ExtensionOp;
use super::{
ExecutionContextIdentity, HardwareClassId, InputSignature, PrepareCapability, PrepareError,
PrepareOptionsKey, PreparedOperationBinding, ResolvedPlanningConfig, ResolvedProgramPlacement,
SpecializationProjection,
};
pub trait ExtensionPlanningConfig: Any + fmt::Debug + Send + Sync + 'static {
fn family_id(&self) -> &'static str;
fn as_any(&self) -> &dyn Any;
fn payload_hash(&self, state: &mut dyn Hasher);
fn payload_eq(&self, other: &dyn ExtensionPlanningConfig) -> bool;
fn retained_bytes(&self) -> usize;
}
pub struct ExtensionPrepareRequest<'a> {
operation: &'a dyn ExtensionOp,
binding: &'a PreparedOperationBinding,
resolved_placement: &'a ResolvedProgramPlacement,
hardware_class: &'a HardwareClassId,
planning: &'a ResolvedPlanningConfig,
extension_config: &'a dyn ExtensionPlanningConfig,
inputs: &'a InputSignature,
prepare_options_key: &'a PrepareOptionsKey,
specialization: &'a SpecializationProjection,
}
impl<'a> ExtensionPrepareRequest<'a> {
#[allow(dead_code)]
#[allow(clippy::too_many_arguments)]
pub(crate) fn new(
operation: &'a dyn ExtensionOp,
binding: &'a PreparedOperationBinding,
resolved_placement: &'a ResolvedProgramPlacement,
hardware_class: &'a HardwareClassId,
planning: &'a ResolvedPlanningConfig,
extension_config: &'a dyn ExtensionPlanningConfig,
inputs: &'a InputSignature,
prepare_options_key: &'a PrepareOptionsKey,
specialization: &'a SpecializationProjection,
) -> Self {
Self {
operation,
binding,
resolved_placement,
hardware_class,
planning,
extension_config,
inputs,
prepare_options_key,
specialization,
}
}
pub fn operation(&self) -> &'a dyn ExtensionOp {
self.operation
}
pub fn binding(&self) -> &'a PreparedOperationBinding {
self.binding
}
pub fn resolved_placement(&self) -> &'a ResolvedProgramPlacement {
self.resolved_placement
}
pub fn hardware_class(&self) -> &'a HardwareClassId {
self.hardware_class
}
pub fn planning(&self) -> &'a ResolvedPlanningConfig {
self.planning
}
pub fn extension_config(&self) -> &'a dyn ExtensionPlanningConfig {
self.extension_config
}
pub fn inputs(&self) -> &'a InputSignature {
self.inputs
}
pub fn prepare_options_key(&self) -> &'a PrepareOptionsKey {
self.prepare_options_key
}
pub fn specialization(&self) -> &'a SpecializationProjection {
self.specialization
}
}
impl fmt::Debug for ExtensionPrepareRequest<'_> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("ExtensionPrepareRequest")
.field("operation", &self.operation.family_id())
.field("binding", self.binding)
.field("resolved_placement", self.resolved_placement)
.field("hardware_class", self.hardware_class)
.field("planning", self.planning)
.field("extension_config", &self.extension_config.family_id())
.field("inputs", &self.inputs.entries().len())
.field("prepare_options_key", self.prepare_options_key)
.field("specialization", self.specialization)
.finish()
}
}
pub trait ExtensionEngine: fmt::Debug + Send + Sync + 'static {
fn family_id(&self) -> &'static str;
fn engine_id(&self) -> &super::EngineId;
fn context_identity(&self) -> ExecutionContextIdentity;
fn prepare(
&self,
request: ExtensionPrepareRequest<'_>,
) -> Result<PrepareCapability, PrepareError>;
}