Skip to content

Commit

Permalink
feat/convolution: implement convolutions correctly
Browse files Browse the repository at this point in the history
also implements chosing of convolution algorithm for the first time.

BREAKING CHANGE: breaks pretty much everything around convolutions,
but wasn't in a working state before that.
  • Loading branch information
hobofan committed Feb 3, 2016
1 parent 19b9d3d commit 24b164b
Show file tree
Hide file tree
Showing 6 changed files with 463 additions and 151 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ license = "MIT"

[dependencies]
collenchyma = { version = "0.0.7", default-features = false }
cudnn = { version = "1.0.1", optional = true }
cudnn = { version = "1.1.0", optional = true }
libc = "0.2"
lazy_static = "0.1"

Expand Down
76 changes: 60 additions & 16 deletions src/frameworks/cuda/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,21 +288,23 @@ macro_rules! impl_ops_tanh_for {

#[macro_export]
macro_rules! impl_ops_convolution_for {
($t:ident, $b:ty) => (
($t:ty, $b:ty) => (
fn convolution(
&self,
filter: &mut ::co::tensor::SharedTensor<$t>,
x: &mut ::co::tensor::SharedTensor<$t>,
result: &mut ::co::tensor::SharedTensor<$t>,
config: &Self::CC //::frameworks::cuda::CC
) -> Result<(), ::co::error::Error> {
match x.add_device(self.device()) { _ => try!(x.sync(self.device())) }
match result.add_device(self.device()) { _ => () }

self.convolution_plain(x, result, config)
self.convolution_plain(filter, x, result, config)
}

fn convolution_plain(
&self,
filter: &::co::tensor::SharedTensor<$t>,
x: &::co::tensor::SharedTensor<$t>,
result: &mut ::co::tensor::SharedTensor<$t>,
config: &Self::CC
Expand All @@ -311,6 +313,7 @@ macro_rules! impl_ops_convolution_for {

Ok(try!(match CUDNN.convolution_forward(
config,
try!(unsafe { ::frameworks::cuda::helper::receive_memory_ptr(filter, self.device()) }),
&try!(x.cudnn_tensor_desc()), // src_desc
try!(unsafe { ::frameworks::cuda::helper::receive_memory_ptr(x, self.device()) }), //src_data
&try!(result.cudnn_tensor_desc()), // dest_desc
Expand All @@ -325,37 +328,78 @@ macro_rules! impl_ops_convolution_for {
}

#[allow(unused_variables)]
fn convolution_grad(
fn convolution_grad_filter(
&self,
x: &mut ::co::tensor::SharedTensor<$t>,
src_data: &mut ::co::tensor::SharedTensor<$t>,
dest_diff: &mut ::co::tensor::SharedTensor<$t>,
filter_diff: &mut ::co::tensor::SharedTensor<$t>,
config: &Self::CC
) -> Result<(), ::co::error::Error> {
match src_data.add_device(self.device()) { _ => try!(src_data.sync(self.device())) }
match dest_diff.add_device(self.device()) { _ => try!(dest_diff.sync(self.device())) }
match filter_diff.add_device(self.device()) { _ => try!(filter_diff.sync(self.device())) }

self.convolution_grad_filter_plain(src_data, dest_diff, filter_diff, config)
}

#[allow(unused_variables)]
fn convolution_grad_filter_plain(
&self,
src_data: &::co::tensor::SharedTensor<$t>,
dest_diff: &::co::tensor::SharedTensor<$t>,
filter_diff: &mut ::co::tensor::SharedTensor<$t>,
config: &Self::CC
) -> Result<(), ::co::error::Error> {
let scal_params: ::cudnn::utils::ScalParams<$t> = ::cudnn::utils::ScalParams::default();

Ok(try!(match CUDNN.convolution_backward_filter(
config,
&try!(src_data.cudnn_tensor_desc()),
try!(unsafe { ::frameworks::cuda::helper::receive_memory_ptr(src_data, self.device()) }),
&try!(dest_diff.cudnn_tensor_desc()),
try!(unsafe { ::frameworks::cuda::helper::receive_memory_ptr(dest_diff, self.device()) }),
try!(unsafe { ::frameworks::cuda::helper::receive_memory_ptr_mut(filter_diff, self.device()) }),
scal_params
) {
Ok(_) => Ok(()),
Err(_) => {
Err(::co::plugin::Error::Operation("Unable to execute CUDA cuDNN Activation convolution Backward."))
}
}))
}

#[allow(unused_variables)]
fn convolution_grad_data(
&self,
filter: &mut ::co::tensor::SharedTensor<$t>,
x_diff: &mut ::co::tensor::SharedTensor<$t>,
result: &mut ::co::tensor::SharedTensor<$t>,
result_diff: &mut ::co::tensor::SharedTensor<$t>,
config: &Self::CC
) -> Result<(), ::co::error::Error> {
match x_diff.add_device(self.device()) { _ => try!(x.sync(self.device())) }
match result_diff.add_device(self.device()) { _ => () }
match filter.add_device(self.device()) { _ => try!(filter.sync(self.device())) }
match x_diff.add_device(self.device()) { _ => try!(x_diff.sync(self.device())) }
match result_diff.add_device(self.device()) { _ => try!(result_diff.sync(self.device())) }

self.convolution_grad_plain(x, x_diff, result, result_diff, config)
self.convolution_grad_data_plain(filter, x_diff, result_diff, config)
}

#[allow(unused_variables)]
fn convolution_grad_plain(
fn convolution_grad_data_plain(
&self,
x: &::co::tensor::SharedTensor<$t>,
filter: &::co::tensor::SharedTensor<$t>,
x_diff: &::co::tensor::SharedTensor<$t>,
result: &::co::tensor::SharedTensor<$t>,
result_diff: &mut ::co::tensor::SharedTensor<$t>,
config: &Self::CC
) -> Result<(), ::co::error::Error> {
let scal_params: ::cudnn::utils::ScalParams<$t> = ::cudnn::utils::ScalParams::default();

Ok(try!(match CUDNN.convolution_backward(
Ok(try!(match CUDNN.convolution_backward_data(
config,
&try!(x_diff.cudnn_tensor_desc()), // src_diff_desc
try!(unsafe { ::frameworks::cuda::helper::receive_memory_ptr(x_diff, self.device()) }), //src_diff_data
&try!(result_diff.cudnn_tensor_desc()), // dest_diff_desc
try!(unsafe { ::frameworks::cuda::helper::receive_memory_ptr_mut(result_diff, self.device()) }), // dest_diff_data
try!(unsafe { ::frameworks::cuda::helper::receive_memory_ptr(filter, self.device()) }),
&try!(x_diff.cudnn_tensor_desc()),
try!(unsafe { ::frameworks::cuda::helper::receive_memory_ptr(x_diff, self.device()) }),
&try!(result_diff.cudnn_tensor_desc()),
try!(unsafe { ::frameworks::cuda::helper::receive_memory_ptr_mut(result_diff, self.device()) }),
scal_params
) {
Ok(_) => Ok(()),
Expand Down
Loading

0 comments on commit 24b164b

Please sign in to comment.