use super::slimmable::SlimmableModel;
use super::{NamModel, StaticModel};
use std::sync::Arc;
impl StaticModel {
pub fn inject_rt_status(&mut self, rt_status: Arc<crate::common::spsc::RtStatusFlags>) {
match self {
Self::WavenetA2Full(m) => m.inject_rt_status(rt_status),
Self::WavenetA2Lite(m) => m.inject_rt_status(rt_status),
Self::WavenetA2Dyn(_) => {}
Self::WavenetA2Cascade(_) => {}
_ => {}
}
}
#[cfg(any(test, feature = "testing"))]
pub fn process_scalar(&mut self, input: &[f32], output: &mut [f32]) {
match self {
Self::Lstm1x3(m) => m.process_scalar(input, output),
Self::Lstm1x8(m) => m.process_scalar(input, output),
Self::Lstm1x12(m) => m.process_scalar(input, output),
Self::Lstm1x16(m) => m.process_scalar(input, output),
Self::Lstm1x24(m) => m.process_scalar(input, output),
Self::Lstm2x8(m) => m.process_scalar(input, output),
Self::Lstm2x12(m) => m.process_scalar(input, output),
Self::Lstm2x16(m) => m.process_scalar(input, output),
Self::Lstm1x40(m) => m.process_scalar(input, output),
Self::Lstm2x24(m) => m.process_scalar(input, output),
Self::LstmDyn(m) => m.process_scalar(input, output),
Self::ConvNet(m) => m.process(input, output),
Self::WavenetA2Cascade(m) => m.process(input, output),
other => other.process(input, output),
}
}
#[inline(always)]
pub fn set_effective_layers(&mut self, n: usize) {
match self {
Self::WavenetStandard(m) => m.set_effective_layers(n),
Self::WavenetLite(m) => m.set_effective_layers(n),
Self::WavenetFeather(m) => m.set_effective_layers(n),
Self::WavenetNano(m) => m.set_effective_layers(n),
Self::WavenetDyn(m) => m.set_effective_layers(n),
Self::WavenetA2Cascade(_)
| Self::WavenetA2Full(_)
| Self::WavenetA2Lite(_)
| Self::WavenetA2Dyn(_)
| Self::Container(_)
| Self::Lstm1x3(_)
| Self::Lstm1x8(_)
| Self::Lstm1x12(_)
| Self::Lstm1x16(_)
| Self::Lstm1x24(_)
| Self::Lstm2x8(_)
| Self::Lstm2x12(_)
| Self::Lstm2x16(_)
| Self::Lstm1x40(_)
| Self::Lstm2x24(_)
| Self::LstmDyn(_) => {}
Self::Linear(_) => {}
Self::ConvNet(_) => {}
}
}
#[inline(always)]
pub fn backup_buffer_starts(&self, starts: &mut [usize], offset: &mut usize) {
match self {
Self::WavenetStandard(m) => m.backup_buffer_starts(starts, offset),
Self::WavenetLite(m) => m.backup_buffer_starts(starts, offset),
Self::WavenetFeather(m) => m.backup_buffer_starts(starts, offset),
Self::WavenetNano(m) => m.backup_buffer_starts(starts, offset),
Self::WavenetDyn(m) => m.backup_buffer_starts(starts, offset),
Self::WavenetA2Cascade(_) => {}
_ => {}
}
}
#[inline(always)]
pub fn restore_buffer_starts(&mut self, starts: &[usize], offset: &mut usize) {
match self {
Self::WavenetStandard(m) => m.restore_buffer_starts(starts, offset),
Self::WavenetLite(m) => m.restore_buffer_starts(starts, offset),
Self::WavenetFeather(m) => m.restore_buffer_starts(starts, offset),
Self::WavenetNano(m) => m.restore_buffer_starts(starts, offset),
Self::WavenetDyn(m) => m.restore_buffer_starts(starts, offset),
Self::WavenetA2Cascade(_) => {}
_ => {}
}
}
#[inline(always)]
pub fn set_slimmable_size(
&mut self,
val: f32,
rt_status: Option<&crate::common::spsc::RtStatusFlags>,
) {
if let Self::Container(c) = self {
c.set_slimmable_size(val, rt_status);
}
}
pub fn slimmable_breakpoints(&self) -> Vec<f64> {
if let Self::Container(c) = self {
SlimmableModel::slimmable_breakpoints(c.as_ref())
} else {
vec![]
}
}
#[inline(always)]
pub fn layer_count(&self) -> usize {
match self {
Self::WavenetStandard(m) => m.array1.layers.len(),
Self::WavenetLite(m) => m.array1.layers.len(),
Self::WavenetFeather(m) => m.array1.layers.len(),
Self::WavenetNano(m) => m.array1.layers.len(),
Self::WavenetDyn(m) => m.arrays[0].layers.len(),
Self::WavenetA2Full(_) | Self::WavenetA2Lite(_) | Self::WavenetA2Dyn(_) => {
crate::models::a2::A2_NUM_LAYERS
}
Self::WavenetA2Cascade(m) => m.arrays.iter().map(|a| a.num_layers).sum(),
Self::Container(c) => c.active().layer_count(),
Self::Lstm2x8(_) | Self::Lstm2x12(_) | Self::Lstm2x16(_) | Self::Lstm2x24(_) => 2,
Self::LstmDyn(m) => m.layers.len(),
Self::Lstm1x3(_)
| Self::Lstm1x8(_)
| Self::Lstm1x12(_)
| Self::Lstm1x16(_)
| Self::Lstm1x24(_)
| Self::Lstm1x40(_) => 1,
Self::Linear(_) => 0,
Self::ConvNet(m) => m.blocks.len(),
}
}
#[cold]
pub fn class_label(&self) -> String {
match self {
Self::WavenetStandard(_) => "WaveNet A1 Standard (CH=16)".into(),
Self::WavenetLite(_) => "WaveNet A1 Lite (CH=12)".into(),
Self::WavenetFeather(_) => "WaveNet A1 Feather (CH=8)".into(),
Self::WavenetNano(_) => "WaveNet A1 Nano (CH=4)".into(),
Self::WavenetA2Full(_) => "WaveNet A2 (CH=8)".into(),
Self::WavenetA2Lite(_) => "WaveNet A2 Lite (CH=3)".into(),
Self::WavenetA2Dyn(m) => format!("WaveNet A2 (CH={})", m.channels),
Self::WavenetA2Cascade(m) => format!("WaveNet A2 Cascade ({} arrays)", m.arrays.len()),
Self::WavenetDyn(m) => {
if m.arrays.len() == 2 {
"WaveNet A1 (Custom)".into()
} else {
"WaveNet (Custom Layers)".into()
}
}
Self::Container(c) => {
let active_label = c.active().class_label();
if active_label.starts_with("WaveNet") {
active_label
} else {
"SlimmableContainer".into()
}
}
Self::Lstm1x3(_) => "LSTM 1x3".into(),
Self::Lstm1x8(_) => "LSTM 1x8".into(),
Self::Lstm1x12(_) => "LSTM 1x12".into(),
Self::Lstm1x16(_) => "LSTM 1x16".into(),
Self::Lstm1x24(_) => "LSTM 1x24".into(),
Self::Lstm1x40(_) => "LSTM 1x40".into(),
Self::Lstm2x8(_) => "LSTM 2x8".into(),
Self::Lstm2x12(_) => "LSTM 2x12".into(),
Self::Lstm2x16(_) => "LSTM 2x16".into(),
Self::Lstm2x24(_) => "LSTM 2x24".into(),
Self::LstmDyn(m) => format!("LSTM {}x{}", m.layers.len(), m.head_weights.len()),
Self::Linear(_) => "Linear".into(),
Self::ConvNet(m) => format!("ConvNet (CH={})", m.in_channels()),
}
}
#[inline(always)]
pub fn is_lstm(&self) -> bool {
matches!(
self,
Self::Lstm1x3(_)
| Self::Lstm1x8(_)
| Self::Lstm1x12(_)
| Self::Lstm1x16(_)
| Self::Lstm1x24(_)
| Self::Lstm2x8(_)
| Self::Lstm2x12(_)
| Self::Lstm2x16(_)
| Self::Lstm1x40(_)
| Self::Lstm2x24(_)
| Self::LstmDyn(_)
)
}
#[inline(always)]
pub fn is_wavenet(&self) -> bool {
matches!(
self,
Self::WavenetStandard(_)
| Self::WavenetLite(_)
| Self::WavenetFeather(_)
| Self::WavenetNano(_)
| Self::WavenetA2Full(_)
| Self::WavenetA2Lite(_)
| Self::WavenetA2Dyn(_)
| Self::WavenetA2Cascade(_)
| Self::WavenetDyn(_)
)
}
#[inline(always)]
pub fn supports_layer_skip(&self) -> bool {
matches!(
self,
Self::WavenetStandard(_)
| Self::WavenetLite(_)
| Self::WavenetFeather(_)
| Self::WavenetNano(_)
| Self::WavenetDyn(_)
)
}
#[inline(always)]
pub fn is_container(&self) -> bool {
matches!(self, Self::Container(_))
}
pub fn channels(&self) -> usize {
match self {
Self::WavenetStandard(_) => 16,
Self::WavenetLite(_) => 12,
Self::WavenetFeather(_) => 8,
Self::WavenetNano(_) => 4,
Self::WavenetA2Full(_) => 8,
Self::WavenetA2Lite(_) => 3,
Self::WavenetA2Dyn(m) => m.channels,
Self::WavenetA2Cascade(m) => m.channels(),
Self::WavenetDyn(m) => m.ch,
Self::Container(c) => c.active().channels(),
Self::Lstm1x3(_) => 3,
Self::Lstm1x8(_) | Self::Lstm2x8(_) => 8,
Self::Lstm1x12(_) | Self::Lstm2x12(_) => 12,
Self::Lstm1x16(_) | Self::Lstm2x16(_) => 16,
Self::Lstm1x24(_) | Self::Lstm2x24(_) => 24,
Self::Lstm1x40(_) => 40,
Self::LstmDyn(m) => m.head_weights.len(),
Self::Linear(_) => 1,
Self::ConvNet(m) => m.in_channels(),
}
}
pub fn in_channels(&self) -> usize {
match self {
Self::WavenetStandard(_)
| Self::WavenetLite(_)
| Self::WavenetFeather(_)
| Self::WavenetNano(_) => 1,
Self::WavenetA2Full(_) => 1,
Self::WavenetA2Lite(_) => 1,
Self::WavenetA2Dyn(_) => 1,
Self::WavenetA2Cascade(_) => 1,
Self::WavenetDyn(_) => 1,
Self::Container(c) => c.active().in_channels(),
Self::Lstm1x3(_)
| Self::Lstm1x8(_)
| Self::Lstm1x12(_)
| Self::Lstm1x16(_)
| Self::Lstm1x24(_)
| Self::Lstm2x8(_)
| Self::Lstm2x12(_)
| Self::Lstm2x16(_)
| Self::Lstm1x40(_)
| Self::Lstm2x24(_)
| Self::LstmDyn(_) => 1,
Self::Linear(_) => 1,
Self::ConvNet(m) => m.in_channels(),
}
}
pub fn receptive_field(&self) -> usize {
match self {
Self::Container(_) => 0,
Self::Linear(m) => m.receptive_field,
_ if self.is_lstm() => 0,
_ => self.prewarm_samples(),
}
}
pub fn num_output_channels(&self) -> usize {
match self {
Self::WavenetStandard(_)
| Self::WavenetLite(_)
| Self::WavenetFeather(_)
| Self::WavenetNano(_) => 1,
Self::WavenetA2Full(_) => 1,
Self::WavenetA2Lite(_) => 1,
Self::WavenetA2Dyn(_) => 1,
Self::WavenetA2Cascade(m) => m.arrays.last().map(|a| a.head_size).unwrap_or(1),
Self::WavenetDyn(m) => m.arrays.last().map(|a| a.head).unwrap_or(0),
Self::Container(c) => c.active().num_output_channels(),
Self::Lstm1x3(_)
| Self::Lstm1x8(_)
| Self::Lstm2x8(_)
| Self::Lstm1x12(_)
| Self::Lstm2x12(_)
| Self::Lstm1x16(_)
| Self::Lstm2x16(_)
| Self::Lstm1x24(_)
| Self::Lstm2x24(_)
| Self::Lstm1x40(_)
| Self::LstmDyn(_) => 1,
Self::Linear(_) => 1,
Self::ConvNet(m) => m.out_channels(),
}
}
}
pub(crate) fn clone_condition_dsp(model: &Option<Box<StaticModel>>) -> Option<Box<StaticModel>> {
model.as_ref().and_then(|m| match m.as_ref() {
StaticModel::WavenetDyn(w) => Some(Box::new(StaticModel::WavenetDyn(w.clone()))),
StaticModel::WavenetA2Cascade(_) => None,
_ => None,
})
}