use std::collections::BTreeMap;
use std::sync::Arc;
use uqa_core::{IndexStats, Payload, PostingEntry, PostingList, Value};
use uqa_scoring::prob::{confidence_scaled_log_odds_pool_weighted, logit, sigmoid, PROB_EPSILON};
use uqa_operators::{
base::{Direction, OperatorResult},
ExecutionContext, Operator,
};
use uqa_storage::{StorageBackendError, StorageBackendResult};
use crate::backend::{try_filled_vec, try_vec_with_capacity, MLError, MLResult};
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum Gating {
#[default]
None,
Softplus,
Sigmoid,
ReLU,
Swish,
Gelu,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GlobalPoolMethod {
Avg,
Max,
AvgMax,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AggregationKind {
Mean,
Sum,
Max,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PoolMethod {
Avg,
Max,
}
#[allow(clippy::upper_case_acronyms)]
#[derive(Clone)]
pub enum Layer {
Input { dimensions: usize },
Signal(Vec<Arc<dyn Operator>>),
Embed(Vec<f64>),
Dense {
weights: Vec<f64>,
bias: Vec<f64>,
output_channels: usize,
input_channels: usize,
},
Flatten,
GlobalPool(GlobalPoolMethod),
Softmax,
BatchNorm { epsilon: f64 },
Dropout { p: f64 },
CNN1D {
weights: Vec<f64>,
bias: Vec<f64>,
output_channels: usize,
input_channels: usize,
kernel_size: usize,
stride: usize,
padding: usize,
},
CNN2D {
weights: Vec<f64>,
bias: Vec<f64>,
output_channels: usize,
input_channels: usize,
input_height: usize,
input_width: usize,
kernel_height: usize,
kernel_width: usize,
stride_height: usize,
stride_width: usize,
padding_height: usize,
padding_width: usize,
},
Propagate {
edge_label: String,
aggregation: AggregationKind,
direction: Direction,
},
Conv {
edge_label: String,
hop_weights: Vec<f64>,
direction: Direction,
},
Pool {
edge_label: String,
pool_size: usize,
method: PoolMethod,
direction: Direction,
},
Attention,
RNN {
weights_input: Vec<f64>,
weights_hidden: Vec<f64>,
bias: Vec<f64>,
hidden_channels: usize,
input_channels: usize,
return_sequences: bool,
},
LSTM {
weights_input: Vec<f64>,
weights_hidden: Vec<f64>,
bias: Vec<f64>,
hidden_channels: usize,
input_channels: usize,
return_sequences: bool,
},
}
pub struct DeepFusionOperator {
layers: Vec<Layer>,
alpha: f64,
gating: Gating,
}
impl DeepFusionOperator {
pub fn new(layers: Vec<Layer>, alpha: f64, gating: Gating) -> MLResult<Self> {
validate_layers(&layers, alpha)?;
Ok(Self {
layers,
alpha,
gating,
})
}
pub fn layers(&self) -> &[Layer] {
&self.layers
}
pub fn alpha(&self) -> f64 {
self.alpha
}
pub fn gating(&self) -> Gating {
self.gating
}
}
mod attention;
mod cnn;
mod execution;
mod graph_layers;
mod layer_dispatch;
mod recurrent;
mod runtime;
mod state;
mod tensor_layers;
mod validation;
use attention::{apply_attention, build_result};
use cnn::{apply_cnn_1d, apply_cnn_2d};
use graph_layers::{apply_conv, apply_pool, apply_propagate};
use layer_dispatch::{apply_cnn_1d_layer, apply_cnn_2d_layer, apply_lstm_layer, apply_rnn_layer};
use recurrent::{apply_lstm, apply_rnn};
use runtime::{
apply_gating, runtime_filled_vec, runtime_model_error, runtime_vec_with_capacity, safe_logit,
usize_to_f64_exact,
};
use state::{Convolution1D, Convolution2D, ForwardState, LongShortTermMemory, Recurrent};
use tensor_layers::{
apply_batch_norm, apply_dense, apply_dropout, apply_embed, apply_flatten, apply_global_pool,
apply_signal, apply_softmax,
};
use validation::{validate_layers, validate_state};
#[cfg(test)]
mod tests;