use std::fmt::Debug;
#[allow(dead_code)]
use scirs2_core::ndarray::{Array1, Array2, Array3};
use scirs2_core::numeric::Float;
use std::collections::{HashMap, HashSet, VecDeque};
use crate::error::{OptimError, Result};
#[derive(Debug, Clone)]
pub struct ArchitectureEncodingConfig {
pub max_sequence_length: usize,
pub vocabulary_size: usize,
pub embedding_dimensions: HashMap<EncodingType, usize>,
pub use_positional_encoding: bool,
pub normalization_method: NormalizationMethod,
pub operation_vocabulary: Vec<String>,
pub max_graph_depth: usize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum EncodingType {
Sequential,
Graph,
Tree,
PathBased,
ContinuousVector,
Categorical,
Hybrid,
}
#[derive(Debug, Clone, Copy)]
pub enum NormalizationMethod {
None,
MinMax,
ZScore,
LayerNorm,
BatchNorm,
}
#[derive(Debug)]
pub struct ArchitectureEncoder<T: Float + Debug + Send + Sync + 'static> {
config: ArchitectureEncodingConfig,
encodings: HashMap<EncodingType, Box<dyn EncodingStrategy<T>>>,
operation_to_index: HashMap<String, usize>,
index_to_operation: HashMap<usize, String>,
embedding_matrices: HashMap<EncodingType, Array2<T>>,
normalization_stats: HashMap<String, NormalizationStats<T>>,
}
pub trait EncodingStrategy<T: Float + Debug + Send + Sync + 'static> {
fn encode(&self, architecture: &ArchitectureDefinition<T>) -> Result<EncodedArchitecture<T>>;
fn decode(&self, encoded: &EncodedArchitecture<T>) -> Result<ArchitectureDefinition<T>>;
fn get_dimensions(&self) -> Vec<usize>;
fn validate(&self, encoded: &EncodedArchitecture<T>) -> Result<bool>;
}
#[derive(Debug, Clone)]
pub struct ArchitectureDefinition<T: Float + Debug + Send + Sync + 'static> {
pub id: String,
pub operations: Vec<OperationSpec<T>>,
pub connections: ConnectionGraph,
pub global_parameters: HashMap<String, T>,
pub io_specs: IOSpecifications,
pub metadata: ArchitectureMetadata,
}
#[derive(Debug, Clone)]
pub struct OperationSpec<T: Float + Debug + Send + Sync + 'static> {
pub id: String,
pub operation_type: String,
pub parameters: HashMap<String, ParameterValue<T>>,
pub input_shapes: Vec<Vec<usize>>,
pub output_shapes: Vec<Vec<usize>>,
pub position: Position,
}
#[derive(Debug, Clone)]
pub enum ParameterValue<T: Float + Debug + Send + Sync + 'static> {
Integer(i64),
Float(T),
Boolean(bool),
String(String),
Array(Vec<T>),
Tensor(Array3<T>),
}
#[derive(Debug, Clone)]
pub struct ConnectionGraph {
pub adjacency_matrix: Array2<f32>,
pub edge_types: HashMap<(usize, usize), EdgeType>,
pub node_properties: HashMap<usize, NodeProperties>,
pub topology: GraphTopology,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum EdgeType {
DataFlow,
Skip,
Residual,
Attention,
Dense,
Custom(u8),
}
#[derive(Debug, Clone)]
pub struct NodeProperties {
pub node_type: NodeType,
pub depth: usize,
pub in_degree: usize,
pub out_degree: usize,
pub attributes: HashMap<String, String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NodeType {
Input,
Output,
Operation,
Merge,
Split,
}
#[derive(Debug, Clone)]
pub struct GraphTopology {
pub scc: Vec<Vec<usize>>,
pub topological_order: Vec<usize>,
pub longest_paths: HashMap<usize, usize>,
pub diameter: usize,
pub clustering_coefficient: f64,
}
#[derive(Debug, Clone)]
pub struct Position {
pub layer_index: usize,
pub block_index: usize,
pub operation_index: usize,
pub coordinates: Option<(f64, f64)>,
}
#[derive(Debug, Clone)]
pub struct IOSpecifications {
pub input_shapes: Vec<Vec<usize>>,
pub output_shapes: Vec<Vec<usize>>,
pub data_types: Vec<String>,
pub constraints: Vec<IOConstraint>,
}
#[derive(Debug, Clone)]
pub struct IOConstraint {
pub constraint_type: String,
pub parameters: HashMap<String, f64>,
}
#[derive(Debug, Clone)]
pub struct ArchitectureMetadata {
pub created_at: u64,
pub modified_at: u64,
pub tags: Vec<String>,
pub performance_estimates: HashMap<String, f64>,
pub complexity_metrics: ComplexityMetrics,
}
#[derive(Debug, Clone)]
pub struct ComplexityMetrics {
pub total_parameters: usize,
pub flops: u64,
pub memory_mb: f64,
pub graph_complexity: f64,
pub diversity_score: f64,
}
#[derive(Debug, Clone)]
pub struct EncodedArchitecture<T: Float + Debug + Send + Sync + 'static> {
pub encoding_type: EncodingType,
pub primary_encoding: Array2<T>,
pub secondary_encodings: HashMap<String, Array2<T>>,
pub categorical_features: HashMap<String, Vec<usize>>,
pub continuous_features: HashMap<String, Array1<T>>,
pub sequence_lengths: Vec<usize>,
pub padding_mask: Option<Array2<bool>>,
pub metadata: EncodingMetadata<T>,
}
#[derive(Debug, Clone)]
pub struct EncodingMetadata<T: Float + Debug + Send + Sync + 'static> {
pub architecture_id: String,
pub encoded_at: u64,
pub quality_metrics: EncodingQualityMetrics<T>,
pub reconstruction_error: Option<T>,
pub version: String,
}
#[derive(Debug, Clone)]
pub struct EncodingQualityMetrics<T: Float + Debug + Send + Sync + 'static> {
pub information_preservation: T,
pub compression_ratio: T,
pub stability: T,
pub semantic_consistency: T,
}
#[derive(Debug, Clone)]
pub struct NormalizationStats<T: Float + Debug + Send + Sync + 'static> {
pub mean: Array1<T>,
pub std: Array1<T>,
pub min: Array1<T>,
pub max: Array1<T>,
pub sample_count: usize,
}
#[derive(Debug)]
pub struct SequentialEncoder<T: Float + Debug + Send + Sync + 'static> {
max_length: usize,
vocabulary: HashMap<String, usize>,
embedding_dim: usize,
positional_encoding: Option<Array2<T>>,
}
#[derive(Debug)]
pub struct GraphEncoder<T: Float + Debug + Send + Sync + 'static> {
max_nodes: usize,
node_feature_dim: usize,
edge_feature_dim: usize,
normalization: GraphNormalization,
}
#[derive(Debug, Clone, Copy)]
pub enum GraphNormalization {
None,
Symmetric,
RandomWalk,
Spectral,
}
#[derive(Debug)]
pub struct TreeEncoder<T: Float + Debug + Send + Sync + 'static> {
max_depth: usize,
max_branching: usize,
node_dim: usize,
traversal_order: TreeTraversalOrder,
}
#[derive(Debug, Clone, Copy)]
pub enum TreeTraversalOrder {
DepthFirst,
BreadthFirst,
PreOrder,
PostOrder,
InOrder,
}
#[derive(Debug)]
pub struct PathEncoder<T: Float + Debug + Send + Sync + 'static> {
max_path_length: usize,
num_paths: usize,
sampling_strategy: PathSamplingStrategy,
path_dim: usize,
}
#[derive(Debug, Clone, Copy)]
pub enum PathSamplingStrategy {
Shortest,
Longest,
Random,
Important,
AllSimple,
}
#[derive(Debug)]
pub struct ContinuousEncoder<T: Float + Debug + Send + Sync + 'static> {
vector_dim: usize,
encoder_network: Vec<Array2<T>>,
decoder_network: Vec<Array2<T>>,
variational_params: Option<VariationalParams<T>>,
}
#[derive(Debug, Clone)]
pub struct VariationalParams<T: Float + Debug + Send + Sync + 'static> {
latent_dim: usize,
kl_weight: T,
reconstruction_weight: T,
}
impl<T: Float + Debug + Default + Clone + Send + Sync + 'static> ArchitectureEncoder<T> {
pub fn new(config: ArchitectureEncodingConfig) -> Result<Self> {
let mut encoder = Self {
config: config.clone(),
encodings: HashMap::new(),
operation_to_index: HashMap::new(),
index_to_operation: HashMap::new(),
embedding_matrices: HashMap::new(),
normalization_stats: HashMap::new(),
};
encoder.initialize_vocabulary()?;
encoder.initialize_encoders()?;
encoder.initialize_embeddings()?;
Ok(encoder)
}
fn initialize_vocabulary(&mut self) -> Result<()> {
for (i, op) in self.config.operation_vocabulary.iter().enumerate() {
self.operation_to_index.insert(op.clone(), i);
self.index_to_operation.insert(i, op.clone());
}
Ok(())
}
fn initialize_encoders(&mut self) -> Result<()> {
if let Some(&dim) = self.config.embedding_dimensions.get(&EncodingType::Sequential) {
let seq_encoder = SequentialEncoder::new(
self.config.max_sequence_length,
self.operation_to_index.clone(),
dim,
self.config.use_positional_encoding,
)?;
self.encodings.insert(EncodingType::Sequential, Box::new(seq_encoder));
}
if let Some(&dim) = self.config.embedding_dimensions.get(&EncodingType::Graph) {
let graph_encoder = GraphEncoder::new(
self.config.max_sequence_length, dim,
dim / 2, GraphNormalization::Symmetric,
)?;
self.encodings.insert(EncodingType::Graph, Box::new(graph_encoder));
}
Ok(())
}
fn initialize_embeddings(&mut self) -> Result<()> {
use scirs2_core::random::Rng;
let mut rng = scirs2_core::random::thread_rng();
for (&encoding_type, &dim) in &self.config.embedding_dimensions {
let vocab_size = self.config.vocabulary_size;
let mut embedding = Array2::zeros((vocab_size, dim));
for i in 0..vocab_size {
for j in 0..dim {
embedding[[i, j]] = T::from(rng.gen_range(-0.1..0.1)).expect("unwrap failed");
}
}
self.embedding_matrices.insert(encoding_type, embedding);
}
Ok(())
}
pub fn encode(&self, architecture: &ArchitectureDefinition<T>, encoding_type: EncodingType) -> Result<EncodedArchitecture<T>> {
if let Some(encoder) = self.encodings.get(&encoding_type) {
let mut encoded = encoder.encode(architecture)?;
if let NormalizationMethod::MinMax | NormalizationMethod::ZScore = self.config.normalization_method {
self.apply_normalization(&mut encoded)?;
}
Ok(encoded)
} else {
Err(OptimError::UnsupportedOperation(
format!("Encoding type {:?} not supported", encoding_type)
))
}
}
pub fn decode(&self, encoded: &EncodedArchitecture<T>) -> Result<ArchitectureDefinition<T>> {
if let Some(encoder) = self.encodings.get(&encoded.encoding_type) {
encoder.decode(encoded)
} else {
Err(OptimError::UnsupportedOperation(
format!("Encoding type {:?} not supported", encoded.encoding_type)
))
}
}
pub fn encode_multi(&self, architecture: &ArchitectureDefinition<T>,
encoding_types: &[EncodingType]) -> Result<HashMap<EncodingType, EncodedArchitecture<T>>> {
let mut results = HashMap::new();
for &encoding_type in encoding_types {
let encoded = self.encode(architecture, encoding_type)?;
results.insert(encoding_type, encoded);
}
Ok(results)
}
fn apply_normalization(&self, encoded: &mut EncodedArchitecture<T>) -> Result<()> {
match self.config.normalization_method {
NormalizationMethod::MinMax => {
self.apply_minmax_normalization(&mut encoded.primary_encoding)?;
}
NormalizationMethod::ZScore => {
self.apply_zscore_normalization(&mut encoded.primary_encoding)?;
}
_ => {} }
Ok(())
}
fn apply_minmax_normalization(&self, data: &mut Array2<T>) -> Result<()> {
for j in 0..data.ncols() {
let mut col = data.column_mut(j);
let min_val = col.iter().cloned().fold(scirs2_core::numeric::NumCast::from(f64::INFINITY).unwrap_or_else(|| T::zero()), T::min);
let max_val = col.iter().cloned().fold(scirs2_core::numeric::NumCast::from(f64::NEG_INFINITY).unwrap_or_else(|| T::zero()), T::max);
if max_val > min_val {
let range = max_val - min_val;
for val in col.iter_mut() {
*val = (*val - min_val) / range;
}
}
}
Ok(())
}
fn apply_zscore_normalization(&self, data: &mut Array2<T>) -> Result<()> {
for j in 0..data.ncols() {
let mut col = data.column_mut(j);
let n = T::from(col.len() as f64).expect("unwrap failed");
let mean = col.iter().cloned().fold(T::zero(), |acc, x| acc + x) / n;
let variance = col.iter().map(|&x| (x - mean) * (x - mean)).fold(T::zero(), |acc, x| acc + x) / n;
let std_dev = variance.sqrt();
if std_dev > T::zero() {
for val in col.iter_mut() {
*val = (*val - mean) / std_dev;
}
}
}
Ok(())
}
pub fn compute_similarity(&self, encoded1: &EncodedArchitecture<T>,
encoded2: &EncodedArchitecture<T>) -> Result<T> {
if encoded1.encoding_type != encoded2.encoding_type {
return Err(OptimError::InvalidInput(
"Cannot compute similarity between different encoding types".to_string()
));
}
let flat1 = encoded1.primary_encoding.as_slice().expect("unwrap failed");
let flat2 = encoded2.primary_encoding.as_slice().expect("unwrap failed");
if flat1.len() != flat2.len() {
return Err(OptimError::InvalidInput(
"Encoded architectures have different dimensions".to_string()
));
}
let dot_product = flat1.iter().zip(flat2.iter()).map(|(&a, &b)| a * b).fold(T::zero(), |acc, x| acc + x);
let norm1 = flat1.iter().map(|&x| x * x).fold(T::zero(), |acc, x| acc + x).sqrt();
let norm2 = flat2.iter().map(|&x| x * x).fold(T::zero(), |acc, x| acc + x).sqrt();
if norm1 > T::zero() && norm2 > T::zero() {
Ok(dot_product / (norm1 * norm2))
} else {
Ok(T::zero())
}
}
pub fn update_normalization_stats(&mut self, encoded: &EncodedArchitecture<T>) -> Result<()> {
let stats_key = format!("{:?}", encoded.encoding_type);
let stats = self.normalization_stats.entry(stats_key).or_insert_with(|| NormalizationStats {
mean: Array1::zeros(encoded.primary_encoding.ncols()),
std: Array1::ones(encoded.primary_encoding.ncols()),
min: Array1::from_elem(encoded.primary_encoding.ncols(), scirs2_core::numeric::NumCast::from(f64::INFINITY).unwrap_or_else(|| T::zero())),
max: Array1::from_elem(encoded.primary_encoding.ncols(), scirs2_core::numeric::NumCast::from(f64::NEG_INFINITY).unwrap_or_else(|| T::zero())),
sample_count: 0,
});
for j in 0..encoded.primary_encoding.ncols() {
let col = encoded.primary_encoding.column(j);
let col_min = col.iter().cloned().fold(scirs2_core::numeric::NumCast::from(f64::INFINITY).unwrap_or_else(|| T::zero()), T::min);
let col_max = col.iter().cloned().fold(scirs2_core::numeric::NumCast::from(f64::NEG_INFINITY).unwrap_or_else(|| T::zero()), T::max);
stats.min[j] = stats.min[j].min(col_min);
stats.max[j] = stats.max[j].max(col_max);
}
stats.sample_count += 1;
Ok(())
}
pub fn get_supported_encoding_types(&self) -> Vec<EncodingType> {
self.encodings.keys().copied().collect()
}
pub fn get_encoding_dimensions(&self, encoding_type: EncodingType) -> Option<Vec<usize>> {
self.encodings.get(&encoding_type).map(|encoder| encoder.get_dimensions())
}
pub fn validate_encoding(&self, encoded: &EncodedArchitecture<T>) -> Result<bool> {
if let Some(encoder) = self.encodings.get(&encoded.encoding_type) {
encoder.validate(encoded)
} else {
Ok(false)
}
}
}
impl<T: Float + Debug + Default + Clone + Send + Sync + 'static> SequentialEncoder<T> {
pub fn new(max_length: usize, vocabulary: HashMap<String, usize>,
embedding_dim: usize, use_positional: bool) -> Result<Self> {
let positional_encoding = if use_positional {
Some(Self::create_positional_encoding(max_length, embedding_dim)?)
} else {
None
};
Ok(Self {
max_length,
vocabulary,
embedding_dim,
positional_encoding,
})
}
fn create_positional_encoding(max_length: usize, embedding_dim: usize) -> Result<Array2<T>> {
let mut pos_encoding = Array2::zeros((max_length, embedding_dim));
for pos in 0..max_length {
for i in 0..(embedding_dim / 2) {
let angle = scirs2_core::numeric::NumCast::from(pos as f64).unwrap_or_else(|| T::zero()) /
T::from(10000.0_f64.powf(2.0 * i as f64 / embedding_dim as f64)).expect("unwrap failed");
pos_encoding[[pos, 2 * i]] = angle.sin();
pos_encoding[[pos, 2 * i + 1]] = angle.cos();
}
}
Ok(pos_encoding)
}
}
impl<T: Float + Debug + Default + Clone + Send + Sync + 'static> EncodingStrategy<T> for SequentialEncoder<T> {
fn encode(&self, architecture: &ArchitectureDefinition<T>) -> Result<EncodedArchitecture<T>> {
let seq_len = architecture.operations.len().min(self.max_length);
let mut encoding = Array2::zeros((seq_len, self.embedding_dim));
for (i, operation) in architecture.operations.iter().enumerate().take(seq_len) {
if let Some(&op_idx) = self.vocabulary.get(&operation.operation_type) {
if op_idx < self.embedding_dim {
encoding[[i, op_idx]] = T::one();
}
}
}
if let Some(ref pos_enc) = self.positional_encoding {
for i in 0..seq_len {
for j in 0..self.embedding_dim.min(pos_enc.ncols()) {
encoding[[i, j]] = encoding[[i, j]] + pos_enc[[i, j]];
}
}
}
Ok(EncodedArchitecture {
encoding_type: EncodingType::Sequential,
primary_encoding: encoding,
secondary_encodings: HashMap::new(),
categorical_features: HashMap::new(),
continuous_features: HashMap::new(),
sequence_lengths: vec![seq_len],
padding_mask: None,
metadata: EncodingMetadata {
architecture_id: architecture.id.clone(),
encoded_at: std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_secs(),
quality_metrics: EncodingQualityMetrics {
information_preservation: scirs2_core::numeric::NumCast::from(0.9).unwrap_or_else(|| T::zero()),
compression_ratio: T::from(seq_len as f64 / architecture.operations.len() as f64).expect("unwrap failed"),
stability: scirs2_core::numeric::NumCast::from(0.8).unwrap_or_else(|| T::zero()),
semantic_consistency: scirs2_core::numeric::NumCast::from(0.85).unwrap_or_else(|| T::zero()),
},
reconstruction_error: None,
version: "1.0".to_string(),
},
})
}
fn decode(&self, encoded: &EncodedArchitecture<T>) -> Result<ArchitectureDefinition<T>> {
let mut operations = Vec::new();
for i in 0..encoded.primary_encoding.nrows() {
let row = encoded.primary_encoding.row(i);
if let Some((max_idx, _)) = row.indexed_iter().max_by(|(_, a), (_, b)| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal)) {
if let Some(op_name) = self.vocabulary.iter().find(|(_, &idx)| idx == max_idx).map(|(name, _)| name) {
operations.push(OperationSpec {
id: format!("op_{}", i),
operation_type: op_name.clone(),
parameters: HashMap::new(),
input_shapes: vec![vec![224, 224, 3]], output_shapes: vec![vec![224, 224, 3]], position: Position {
layer_index: i,
block_index: 0,
operation_index: 0,
coordinates: None,
},
});
}
}
}
Ok(ArchitectureDefinition {
id: encoded.metadata.architecture_id.clone(),
operations,
connections: ConnectionGraph {
adjacency_matrix: Array2::eye(operations.len()),
edge_types: HashMap::new(),
node_properties: HashMap::new(),
topology: GraphTopology {
scc: vec![vec![0]],
topological_order: (0..operations.len()).collect(),
longest_paths: HashMap::new(),
diameter: operations.len(),
clustering_coefficient: 0.0,
},
},
global_parameters: HashMap::new(),
io_specs: IOSpecifications {
input_shapes: vec![vec![224, 224, 3]],
output_shapes: vec![vec![1000]],
data_types: vec!["float32".to_string()],
constraints: Vec::new(),
},
metadata: ArchitectureMetadata {
created_at: encoded.metadata.encoded_at,
modified_at: encoded.metadata.encoded_at,
tags: Vec::new(),
performance_estimates: HashMap::new(),
complexity_metrics: ComplexityMetrics {
total_parameters: operations.len() * 1000, flops: operations.len() as u64 * 1000000, memory_mb: operations.len() as f64 * 10.0, graph_complexity: operations.len() as f64,
diversity_score: 0.5,
},
},
})
}
fn get_dimensions(&self) -> Vec<usize> {
vec![self.max_length, self.embedding_dim]
}
fn validate(&self, encoded: &EncodedArchitecture<T>) -> Result<bool> {
Ok(encoded.primary_encoding.nrows() <= self.max_length &&
encoded.primary_encoding.ncols() == self.embedding_dim)
}
}
impl<T: Float + Debug + Default + Clone + Send + Sync + 'static> GraphEncoder<T> {
pub fn new(max_nodes: usize, node_feature_dim: usize,
edge_feature_dim: usize, normalization: GraphNormalization) -> Result<Self> {
Ok(Self {
max_nodes,
node_feature_dim,
edge_feature_dim,
normalization,
})
}
}
impl<T: Float + Debug + Default + Clone + Send + Sync + 'static> EncodingStrategy<T> for GraphEncoder<T> {
fn encode(&self, architecture: &ArchitectureDefinition<T>) -> Result<EncodedArchitecture<T>> {
let num_nodes = architecture.operations.len().min(self.max_nodes);
let mut node_features = Array2::zeros((self.max_nodes, self.node_feature_dim));
for (i, operation) in architecture.operations.iter().enumerate().take(num_nodes) {
node_features[[i, 0]] = scirs2_core::numeric::NumCast::from(i as f64).unwrap_or_else(|| T::zero()); node_features[[i, 1]] = T::from(operation.parameters.len() as f64).expect("unwrap failed"); }
Ok(EncodedArchitecture {
encoding_type: EncodingType::Graph,
primary_encoding: node_features,
secondary_encodings: {
let mut secondary = HashMap::new();
secondary.insert("adjacency_matrix".to_string(),
architecture.connections.adjacency_matrix.mapv(|x| scirs2_core::numeric::NumCast::from(x).unwrap_or_else(|| T::zero())));
secondary
},
categorical_features: HashMap::new(),
continuous_features: HashMap::new(),
sequence_lengths: vec![num_nodes],
padding_mask: None,
metadata: EncodingMetadata {
architecture_id: architecture.id.clone(),
encoded_at: std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_secs(),
quality_metrics: EncodingQualityMetrics {
information_preservation: scirs2_core::numeric::NumCast::from(0.95).unwrap_or_else(|| T::zero()),
compression_ratio: T::from(num_nodes as f64 / architecture.operations.len() as f64).expect("unwrap failed"),
stability: scirs2_core::numeric::NumCast::from(0.9).unwrap_or_else(|| T::zero()),
semantic_consistency: scirs2_core::numeric::NumCast::from(0.9).unwrap_or_else(|| T::zero()),
},
reconstruction_error: None,
version: "1.0".to_string(),
},
})
}
fn decode(&self, _encoded: &EncodedArchitecture<T>) -> Result<ArchitectureDefinition<T>> {
Err(OptimError::UnsupportedOperation("Graph decoding not implemented".to_string()))
}
fn get_dimensions(&self) -> Vec<usize> {
vec![self.max_nodes, self.node_feature_dim]
}
fn validate(&self, encoded: &EncodedArchitecture<T>) -> Result<bool> {
Ok(encoded.primary_encoding.nrows() <= self.max_nodes &&
encoded.primary_encoding.ncols() == self.node_feature_dim)
}
}
impl Default for ArchitectureEncodingConfig {
fn default() -> Self {
let mut embedding_dimensions = HashMap::new();
embedding_dimensions.insert(EncodingType::Sequential, 128);
embedding_dimensions.insert(EncodingType::Graph, 64);
embedding_dimensions.insert(EncodingType::ContinuousVector, 256);
Self {
max_sequence_length: 50,
vocabulary_size: 1000,
embedding_dimensions,
use_positional_encoding: true,
normalization_method: NormalizationMethod::MinMax,
operation_vocabulary: vec![
"conv2d".to_string(),
"dense".to_string(),
"batch_norm".to_string(),
"relu".to_string(),
"max_pool".to_string(),
"avg_pool".to_string(),
"dropout".to_string(),
"attention".to_string(),
"lstm".to_string(),
"gru".to_string(),
],
max_graph_depth: 20,
}
}
}