Skip to content

Commit 58d72f5

Browse files
committed
feat/features: change meaning of framework features
1 parent c36149e commit 58d72f5

File tree

9 files changed

+206
-31
lines changed

9 files changed

+206
-31
lines changed

Cargo.toml

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ keywords = ["deep-learning", "neural-networks", "machine-learning", "framework"]
1414
license = "MIT OR Apache-2.0"
1515

1616
[dependencies]
17-
collenchyma = { version = "0.0.8", default-features = false }
18-
collenchyma-blas = { version = "0.2.0", default-features = false }
17+
collenchyma = { version = "0.0.8", default-features = false, features = ["native"] } # native feature to read/write data into tensors
18+
collenchyma-blas = { version = "0.2.0", default-features = false, features = ["native"] } # only compiles with native feature
1919
collenchyma-nn = { version = "0.3.2", default-features = false }
2020

2121
log = "0.3.2"
@@ -30,8 +30,8 @@ timeit = "0.1.2"
3030
env_logger = "0.3"
3131

3232
[features]
33-
default = ["native", "cuda", "opencl"]
34-
native = ["collenchyma/native", "collenchyma-blas/native", "collenchyma-nn/native"]
33+
default = ["native"]
34+
native = ["collenchyma-blas/native", "collenchyma-nn/native"]
3535
cuda = ["collenchyma/cuda", "collenchyma-blas/cuda", "collenchyma-nn/cuda"]
3636
opencl = ["collenchyma/opencl", "collenchyma-blas/opencl", "collenchyma-nn/opencl"]
3737

examples/benchmarks.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,12 @@ fn get_time_scale<'a>(sec: f64) -> (f64, &'a str) {
112112
}
113113
}
114114

115-
#[cfg(not(feature = "cuda"))]
115+
#[cfg(feature="native")]
116116
fn bench_alexnet() {
117117
println!("Examples run only with CUDA support at the moment, because of missing native convolution implementation for the Collenchyma NN Plugin.");
118-
println!("Try compiling with the \"cuda\" feature flag.");
118+
println!("Try running with `cargo run --no-default-features --features cuda --example benchmarks alexnet`.");
119119
}
120-
#[cfg(feature = "cuda")]
120+
#[cfg(all(feature="cuda", not(feature="native")))]
121121
fn bench_alexnet() {
122122
let mut cfg = SequentialConfig::default();
123123
cfg.add_input("data", &vec![128, 3, 224, 224]);
@@ -194,12 +194,12 @@ fn bench_alexnet() {
194194
}
195195
}
196196

197-
#[cfg(not(feature = "cuda"))]
197+
#[cfg(feature="native")]
198198
fn bench_overfeat() {
199199
println!("Examples run only with CUDA support at the moment, because of missing native convolution implementation for the Collenchyma NN Plugin.");
200-
println!("Try compiling with the \"cuda\" feature flag.");
200+
println!("Try running with `cargo run --no-default-features --features cuda --example benchmarks overfeat`.");
201201
}
202-
#[cfg(feature = "cuda")]
202+
#[cfg(all(feature="cuda", not(feature="native")))]
203203
fn bench_overfeat() {
204204
let mut cfg = SequentialConfig::default();
205205
cfg.add_input("data", &vec![128, 3, 231, 231]);
@@ -276,12 +276,12 @@ fn bench_overfeat() {
276276
}
277277
}
278278

279-
#[cfg(not(feature = "cuda"))]
279+
#[cfg(feature="native")]
280280
fn bench_vgg_a() {
281281
println!("Examples run only with CUDA support at the moment, because of missing native convolution implementation for the Collenchyma NN Plugin.");
282-
println!("Try compiling with the \"cuda\" feature flag.");
282+
println!("Try running with `cargo run --no-default-features --features cuda --example benchmarks vgg`.");
283283
}
284-
#[cfg(feature = "cuda")]
284+
#[cfg(all(feature="cuda", not(feature="native")))]
285285
fn bench_vgg_a() {
286286
let mut cfg = SequentialConfig::default();
287287
cfg.add_input("data", &vec![64, 3, 224, 224]);

src/layer.rs

+12
Original file line numberDiff line numberDiff line change
@@ -687,9 +687,11 @@ impl<B: IBackend + LayerOps<f32> + 'static> Layer<B> {
687687
/// [3]: ../layers/index.html
688688
fn worker_from_config(backend: Rc<B>, config: &LayerConfig) -> Box<ILayer<B>> {
689689
match config.layer_type.clone() {
690+
#[cfg(all(feature="cuda", not(feature="native")))]
690691
LayerType::Convolution(layer_config) => Box::new(Convolution::from_config(&layer_config)),
691692
LayerType::Linear(layer_config) => Box::new(Linear::from_config(&layer_config)),
692693
LayerType::LogSoftmax => Box::new(LogSoftmax::default()),
694+
#[cfg(all(feature="cuda", not(feature="native")))]
693695
LayerType::Pooling(layer_config) => Box::new(Pooling::from_config(&layer_config)),
694696
LayerType::Sequential(layer_config) => Box::new(Sequential::from_config(backend, &layer_config)),
695697
LayerType::Softmax => Box::new(Softmax::default()),
@@ -1103,12 +1105,14 @@ pub struct LayerConfig {
11031105
pub enum LayerType {
11041106
// Common layers
11051107
/// Convolution Layer
1108+
#[cfg(all(feature="cuda", not(feature="native")))]
11061109
Convolution(ConvolutionConfig),
11071110
/// Linear Layer
11081111
Linear(LinearConfig),
11091112
/// LogSoftmax Layer
11101113
LogSoftmax,
11111114
/// Pooling Layer
1115+
#[cfg(all(feature="cuda", not(feature="native")))]
11121116
Pooling(PoolingConfig),
11131117
/// Sequential Layer
11141118
Sequential(SequentialConfig),
@@ -1131,14 +1135,22 @@ impl LayerType {
11311135
/// Returns wether the LayerType supports in-place operations.
11321136
pub fn supports_in_place(&self) -> bool {
11331137
match *self {
1138+
#[cfg(all(feature="cuda", not(feature="native")))]
11341139
LayerType::Convolution(_) => false,
11351140
LayerType::Linear(_) => false,
11361141
LayerType::LogSoftmax => false,
1142+
#[cfg(all(feature="cuda", not(feature="native")))]
11371143
LayerType::Pooling(_) => false,
11381144
LayerType::Sequential(_) => false,
11391145
LayerType::Softmax => false,
1146+
#[cfg(all(feature="cuda", not(feature="native")))]
11401147
LayerType::ReLU => true,
1148+
#[cfg(feature="native")]
1149+
LayerType::ReLU => false,
1150+
#[cfg(all(feature="cuda", not(feature="native")))]
11411151
LayerType::Sigmoid => true,
1152+
#[cfg(feature="native")]
1153+
LayerType::Sigmoid => false,
11421154
LayerType::NegativeLogLikelihood(_) => false,
11431155
LayerType::Reshape(_) => true,
11441156
}

src/layers/activation/relu.rs

+70-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
//! needed in a Sigmoid layer.
88
99
use co::{IBackend,SharedTensor};
10-
use conn::{Relu, ReluPointwise};
10+
use conn::Relu;
11+
#[cfg(all(feature="cuda", not(feature="native")))]
12+
use conn::ReluPointwise;
1113
use layer::*;
1214
use util::ArcLock;
1315

@@ -16,6 +18,11 @@ use util::ArcLock;
1618
/// ReLU Activation Layer
1719
pub struct ReLU;
1820

21+
//
22+
// ReLU + ReLUPointwise
23+
// Only on CUDA
24+
//
25+
#[cfg(all(feature="cuda", not(feature="native")))]
1926
impl<B: IBackend + Relu<f32> + ReluPointwise<f32>> ILayer<B> for ReLU {
2027
impl_ilayer_activation!();
2128

@@ -41,6 +48,7 @@ impl<B: IBackend + Relu<f32> + ReluPointwise<f32>> ILayer<B> for ReLU {
4148
}
4249
}
4350

51+
#[cfg(all(feature="cuda", not(feature="native")))]
4452
impl<B: IBackend + Relu<f32> + ReluPointwise<f32>> ComputeOutput<f32, B> for ReLU {
4553
fn compute_output(&self,
4654
backend: &B,
@@ -54,6 +62,7 @@ impl<B: IBackend + Relu<f32> + ReluPointwise<f32>> ComputeOutput<f32, B> for ReL
5462
}
5563
}
5664

65+
#[cfg(all(feature="cuda", not(feature="native")))]
5766
impl<B: IBackend + Relu<f32> + ReluPointwise<f32>> ComputeInputGradient<f32, B> for ReLU {
5867
fn compute_input_gradient(&self,
5968
backend: &B,
@@ -69,4 +78,64 @@ impl<B: IBackend + Relu<f32> + ReluPointwise<f32>> ComputeInputGradient<f32, B>
6978
}
7079
}
7180

81+
#[cfg(all(feature="cuda", not(feature="native")))]
7282
impl<B: IBackend + Relu<f32> + ReluPointwise<f32>> ComputeParametersGradient<f32, B> for ReLU {}
83+
84+
//
85+
// ReLU without ReLUPointwise
86+
// Only on CUDA
87+
//
88+
#[cfg(feature="native")]
89+
impl<B: IBackend + Relu<f32>> ILayer<B> for ReLU {
90+
impl_ilayer_activation!();
91+
92+
fn reshape(&mut self,
93+
backend: ::std::rc::Rc<B>,
94+
input_data: &mut Vec<ArcLock<SharedTensor<f32>>>,
95+
input_gradient: &mut Vec<ArcLock<SharedTensor<f32>>>,
96+
weights_data: &mut Vec<ArcLock<SharedTensor<f32>>>,
97+
weights_gradient: &mut Vec<ArcLock<SharedTensor<f32>>>,
98+
output_data: &mut Vec<ArcLock<SharedTensor<f32>>>,
99+
output_gradient: &mut Vec<ArcLock<SharedTensor<f32>>>) {
100+
if let Some(inp) = input_data.get(0) {
101+
let read_inp = inp.read().unwrap();
102+
let input_desc = read_inp.desc();
103+
input_gradient[0].write().unwrap().resize(input_desc).unwrap();
104+
output_data[0].write().unwrap().resize(input_desc).unwrap();
105+
output_gradient[0].write().unwrap().resize(input_desc).unwrap();
106+
}
107+
}
108+
}
109+
110+
#[cfg(feature="native")]
111+
impl<B: IBackend + Relu<f32>> ComputeOutput<f32, B> for ReLU {
112+
fn compute_output(&self,
113+
backend: &B,
114+
_weights: &[&SharedTensor<f32>],
115+
input_data: &[&SharedTensor<f32>],
116+
output_data: &mut [&mut SharedTensor<f32>]) {
117+
match input_data.get(0) {
118+
Some(input) => backend.relu_plain(input, output_data[0]).unwrap(),
119+
None => panic!("No input provided for ReLU layer."),
120+
}
121+
}
122+
}
123+
124+
#[cfg(feature="native")]
125+
impl<B: IBackend + Relu<f32>> ComputeInputGradient<f32, B> for ReLU {
126+
fn compute_input_gradient(&self,
127+
backend: &B,
128+
weights_data: &[&SharedTensor<f32>],
129+
output_data: &[&SharedTensor<f32>],
130+
output_gradients: &[&SharedTensor<f32>],
131+
input_data: &[&SharedTensor<f32>],
132+
input_gradients: &mut [&mut SharedTensor<f32>]) {
133+
match output_data.get(0) {
134+
Some(_) => backend.relu_grad_plain(output_data[0], output_gradients[0], input_data[0], input_gradients[0]).unwrap(),
135+
None => panic!("No output_data provided for ReLU layer backward."),
136+
}
137+
}
138+
}
139+
140+
#[cfg(feature="native")]
141+
impl<B: IBackend + Relu<f32>> ComputeParametersGradient<f32, B> for ReLU {}

src/layers/activation/sigmoid.rs

+67
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ use util::ArcLock;
2222
/// Sigmoid Activation Layer
2323
pub struct Sigmoid;
2424

25+
//
26+
// Sigmoid + SigmoidPointwise
27+
// Only on CUDA
28+
//
29+
#[cfg(all(feature="cuda", not(feature="native")))]
2530
impl<B: IBackend + conn::Sigmoid<f32> + conn::SigmoidPointwise<f32>> ILayer<B> for Sigmoid {
2631
impl_ilayer_activation!();
2732

@@ -47,6 +52,7 @@ impl<B: IBackend + conn::Sigmoid<f32> + conn::SigmoidPointwise<f32>> ILayer<B> f
4752
}
4853
}
4954

55+
#[cfg(all(feature="cuda", not(feature="native")))]
5056
impl<B: IBackend + conn::Sigmoid<f32> + conn::SigmoidPointwise<f32>> ComputeOutput<f32, B> for Sigmoid {
5157
fn compute_output(&self,
5258
backend: &B,
@@ -60,6 +66,7 @@ impl<B: IBackend + conn::Sigmoid<f32> + conn::SigmoidPointwise<f32>> ComputeOutp
6066
}
6167
}
6268

69+
#[cfg(all(feature="cuda", not(feature="native")))]
6370
impl<B: IBackend + conn::Sigmoid<f32> + conn::SigmoidPointwise<f32>> ComputeInputGradient<f32, B> for Sigmoid {
6471
fn compute_input_gradient(&self,
6572
backend: &B,
@@ -75,4 +82,64 @@ impl<B: IBackend + conn::Sigmoid<f32> + conn::SigmoidPointwise<f32>> ComputeInpu
7582
}
7683
}
7784

85+
#[cfg(all(feature="cuda", not(feature="native")))]
7886
impl<B: IBackend + conn::Sigmoid<f32> + conn::SigmoidPointwise<f32>> ComputeParametersGradient<f32, B> for Sigmoid {}
87+
88+
//
89+
// Sigmoid without SigmoidPointwise
90+
// Only on CUDA
91+
//
92+
#[cfg(feature="native")]
93+
impl<B: IBackend + conn::Sigmoid<f32>> ILayer<B> for Sigmoid {
94+
impl_ilayer_activation!();
95+
96+
fn reshape(&mut self,
97+
backend: ::std::rc::Rc<B>,
98+
input_data: &mut Vec<ArcLock<SharedTensor<f32>>>,
99+
input_gradient: &mut Vec<ArcLock<SharedTensor<f32>>>,
100+
weights_data: &mut Vec<ArcLock<SharedTensor<f32>>>,
101+
weights_gradient: &mut Vec<ArcLock<SharedTensor<f32>>>,
102+
output_data: &mut Vec<ArcLock<SharedTensor<f32>>>,
103+
output_gradient: &mut Vec<ArcLock<SharedTensor<f32>>>) {
104+
if let Some(inp) = input_data.get(0) {
105+
let read_inp = inp.read().unwrap();
106+
let input_desc = read_inp.desc();
107+
input_gradient[0].write().unwrap().resize(input_desc).unwrap();
108+
output_data[0].write().unwrap().resize(input_desc).unwrap();
109+
output_gradient[0].write().unwrap().resize(input_desc).unwrap();
110+
}
111+
}
112+
}
113+
114+
#[cfg(feature="native")]
115+
impl<B: IBackend + conn::Sigmoid<f32>> ComputeOutput<f32, B> for Sigmoid {
116+
fn compute_output(&self,
117+
backend: &B,
118+
_weights: &[&SharedTensor<f32>],
119+
input_data: &[&SharedTensor<f32>],
120+
output_data: &mut [&mut SharedTensor<f32>]) {
121+
match input_data.get(0) {
122+
Some(input) => backend.sigmoid_plain(input, output_data[0]).unwrap(),
123+
None => panic!("No input provided for Sigmoid layer."),
124+
}
125+
}
126+
}
127+
128+
#[cfg(feature="native")]
129+
impl<B: IBackend + conn::Sigmoid<f32>> ComputeInputGradient<f32, B> for Sigmoid {
130+
fn compute_input_gradient(&self,
131+
backend: &B,
132+
weights_data: &[&SharedTensor<f32>],
133+
output_data: &[&SharedTensor<f32>],
134+
output_gradients: &[&SharedTensor<f32>],
135+
input_data: &[&SharedTensor<f32>],
136+
input_gradients: &mut [&mut SharedTensor<f32>]) {
137+
match output_data.get(0) {
138+
Some(_) => backend.sigmoid_grad_plain(output_data[0], output_gradients[0], input_data[0], input_gradients[0]).unwrap(),
139+
None => panic!("No output_data provided for Sigmoid layer backward."),
140+
}
141+
}
142+
}
143+
144+
#[cfg(feature="native")]
145+
impl<B: IBackend + conn::Sigmoid<f32>> ComputeParametersGradient<f32, B> for Sigmoid {}

src/layers/common/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,20 @@ macro_rules! impl_ilayer_common {
1010
)
1111
}
1212

13+
#[cfg(all(feature="cuda", not(feature="native")))]
1314
pub use self::convolution::{Convolution, ConvolutionConfig};
1415
pub use self::linear::{Linear, LinearConfig};
1516
pub use self::log_softmax::LogSoftmax;
17+
#[cfg(all(feature="cuda", not(feature="native")))]
1618
pub use self::pooling::{Pooling, PoolingConfig, PoolingMode};
1719
pub use self::sequential::{Sequential, SequentialConfig};
1820
pub use self::softmax::Softmax;
1921

22+
#[cfg(all(feature="cuda", not(feature="native")))]
2023
pub mod convolution;
2124
pub mod linear;
2225
pub mod log_softmax;
26+
#[cfg(all(feature="cuda", not(feature="native")))]
2327
pub mod pooling;
2428
pub mod sequential;
2529
pub mod softmax;

src/layers/mod.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -46,28 +46,28 @@
4646
/// [1]: ./layer/trait.ILayer.html
4747
/// [2]: ./layers/activation/index.html
4848
49-
#[allow(unused_import_braces)]
5049
pub use self::activation::{
5150
ReLU,
5251
Sigmoid,
5352
};
5453

55-
#[allow(unused_import_braces)]
54+
#[cfg(all(feature="cuda", not(feature="native")))]
5655
pub use self::common::{
5756
Convolution, ConvolutionConfig,
57+
Pooling, PoolingConfig, PoolingMode,
58+
};
59+
60+
pub use self::common::{
5861
Linear, LinearConfig,
5962
LogSoftmax,
60-
Pooling, PoolingConfig, PoolingMode,
6163
Sequential, SequentialConfig,
6264
Softmax,
6365
};
6466

65-
#[allow(unused_import_braces)]
6667
pub use self::loss::{
6768
NegativeLogLikelihood, NegativeLogLikelihoodConfig,
6869
};
6970

70-
#[allow(unused_import_braces)]
7171
pub use self::utility::{
7272
Flatten,
7373
Reshape, ReshapeConfig,

0 commit comments

Comments
 (0)