1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#[macro_export]
macro_rules! impl_ilayer_common {
() => (
fn exact_num_output_blobs(&self) -> Option<usize> { Some(1) }
fn exact_num_input_blobs(&self) -> Option<usize> { Some(1) }
)
}
#[cfg(all(feature="cuda", not(feature="native")))]
pub use self::convolution::{Convolution, ConvolutionConfig};
pub use self::linear::{Linear, LinearConfig};
pub use self::log_softmax::LogSoftmax;
#[cfg(all(feature="cuda", not(feature="native")))]
pub use self::pooling::{Pooling, PoolingConfig, PoolingMode};
pub use self::softmax::Softmax;
#[cfg(all(feature="cuda", not(feature="native")))]
pub mod convolution;
pub mod linear;
pub mod log_softmax;
#[cfg(all(feature="cuda", not(feature="native")))]
pub mod pooling;
pub mod softmax;
pub trait FilterLayer {
fn calculate_spatial_output_dims(input_dims: &[usize], filter_dims: &[usize], padding: &[usize], stride: &[usize]) -> Vec<usize> {
let mut output_dims = Vec::with_capacity(input_dims.len());
for (i, _) in input_dims.iter().enumerate() {
output_dims.push(((input_dims[i] + (2 * padding[i]) - filter_dims[i]) / stride[i]) + 1);
}
output_dims
}
fn calculate_output_shape(&self, input_shape: &[usize]) -> Vec<usize>;
fn num_spatial_dims(&self, input_shape: &[usize]) -> usize;
fn spatial_filter_dims(&self, num_spatial_dims: usize) -> Vec<usize> {
let mut spatial_dims = Vec::with_capacity(num_spatial_dims);
let filter_shape = self.filter_shape();
if filter_shape.len() == 1 {
for i in 0..num_spatial_dims {
spatial_dims.push(filter_shape[0]);
}
} else if filter_shape.len() == num_spatial_dims {
panic!("unimplemented: You can not yet specify one filter dimension per spatial dimension");
} else {
panic!("Must either specify one filter_shape or one filter_shape per spatial dimension. Supplied {:?}", filter_shape.len());
}
spatial_dims
}
fn stride_dims(&self, num_spatial_dims: usize) -> Vec<usize> {
let mut stride_dims = Vec::with_capacity(num_spatial_dims);
let stride = self.stride();
if stride.len() == 1 {
for i in 0..num_spatial_dims {
stride_dims.push(stride[0]);
}
} else if stride.len() == num_spatial_dims {
panic!("unimplemented: You can not yet specify one stride per spatial dimension");
} else {
panic!("Must either specify one stride or one stride per spatial dimension. Supplied {:?}", stride.len());
}
stride_dims
}
fn padding_dims(&self, num_spatial_dims: usize) -> Vec<usize> {
let mut padding_dims = Vec::with_capacity(num_spatial_dims);
let padding = self.padding();
if padding.len() == 1 {
for i in 0..num_spatial_dims {
padding_dims.push(padding[0]);
}
} else if padding.len() == num_spatial_dims {
panic!("unimplemented: You can not yet specify one padding per spatial dimension");
} else {
panic!("Must either specify one padding or one padding per spatial dimension. Supplied {:?}", padding.len());
}
padding_dims
}
fn filter_shape(&self) -> &[usize];
fn stride(&self) -> &[usize];
fn padding(&self) -> &[usize];
}