Skip to content

Commit

Permalink
support asymmetric padding (#13) (more tests required)
Browse files Browse the repository at this point in the history
* #12

* update configuration flags

* simplify

* remove unused code

* make private

* multi_linear_sample_trait

* fix test

* simplify

* fix test

* [email protected]
  • Loading branch information
lgarithm authored Jan 28, 2019
1 parent 8aa104f commit 33b76c2
Show file tree
Hide file tree
Showing 8 changed files with 350 additions and 140 deletions.
23 changes: 10 additions & 13 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ set -e
CMAKE_FLAGS=

# defaults
# WITH_BLAS=1
USE_BLAS=0
USE_OPENCV=0
BUILD_TESTS=1

add_cmake_flag() {
echo "usinig $1=$2"
Expand All @@ -18,15 +19,15 @@ parse_args() {
--prefix=*)
PREFIX="${i#*=}"
;;
--use-blas)
USE_BLAS=1
;;
--use-opencv)
USE_OPENCV=1
;;
# --with-blas)
# WITH_BLAS=1
# ;;
# --without-blas)
# WITH_BLAS=
# ;;
--no-tests)
BUILD_TESTS=0
;;
*)
echo "unknown argument $1"
exit
Expand Down Expand Up @@ -65,12 +66,8 @@ add_cmake_flags() {

# add_cmake_flag USE_OPT 1
add_cmake_flag USE_OPENCV ${USE_OPENCV}
# add_cmake_flag USE_OPENBLAS 1
# add_cmake_flag BUILD_TESTS 0

# if [ ! -z ${WITH_BLAS} ]; then
# add_cmake_flag USE_BLAS 1
# fi
add_cmake_flag USE_OPENBLAS ${USE_BLAS}
add_cmake_flag BUILD_TESTS ${BUILD_TESTS}
}

parse_args $@
Expand Down
14 changes: 10 additions & 4 deletions include/nn/bits/layers/conv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ class conv_layer_trait : public ops::conv_trait<ops::hw>
{
}

conv_layer_trait(const ksize_t &ksize, size_t n_filters,
const conv_trait &trait)
: conv_trait(trait), ksize_(ksize), n_filters_(n_filters)
{
}

template <typename image_order, typename filter_order>
shape<4> filter_shape(const shape<4> &x) const
{
Expand Down Expand Up @@ -63,8 +69,8 @@ class conv<image_order, filter_order, false, Act> : public conv_layer_trait
{
auto w = ops::new_parameter<ttl::tensor<R, 4>>(
filter_shape<image_order, filter_order>(x.shape()), w_init);
auto y = ops::new_result<ttl::tensor<R, 4>>(
conv_op(padding_, stride_, rate_), x, *w);
auto y = ops::new_result<ttl::tensor<R, 4>>(conv_op(h_trait_, w_trait_),
x, *w);

Act()(ref(*y), view(*y));
return make_layer(y, w);
Expand All @@ -86,8 +92,8 @@ class conv<image_order, filter_order, true, Act> : public conv_layer_trait
{
auto w = ops::new_parameter<ttl::tensor<R, 4>>(
filter_shape<image_order, filter_order>(x.shape()), w_init);
auto y = ops::new_result<ttl::tensor<R, 4>>(
conv_op(padding_, stride_, rate_), x, *w);
auto y = ops::new_result<ttl::tensor<R, 4>>(conv_op(h_trait_, w_trait_),
x, *w);

using add_bias = nn::ops::apply_bias<image_order, std::plus<R>>;
auto b = ops::new_parameter<ttl::tensor<R, 1>>(bias_shape(x.shape()),
Expand Down
91 changes: 64 additions & 27 deletions include/nn/bits/ops/conv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,18 @@ template <typename dim_t> class linear_conv_trait
const dim_t rate_;
const dim_t stride_;

using sample_t = linear_sample_trait<dim_t>;

public:
using padding_t = typename sample_t::padding_t;

static padding_t padding(int p) { return padding_t(p, p); }

static padding_t padding(int left, int right)
{
return padding_t(left, right);
};

linear_conv_trait() : linear_conv_trait(default_pad_lr) {}

linear_conv_trait(dim_t pad_lr) : linear_conv_trait(pad_lr, default_stride)
Expand All @@ -34,53 +45,82 @@ template <typename dim_t> class linear_conv_trait
}

linear_conv_trait(dim_t pad_lr, dim_t stride, dim_t rate)
: pad_l_(pad_lr), pad_r_(pad_lr), rate_(rate), stride_(stride)
: linear_conv_trait(paddint(pad_lr), stride, rate)
{
}

dim_t operator()(dim_t n, dim_t k) const
linear_conv_trait(const padding_t &pad, dim_t stride, dim_t rate)
: pad_l_(std::get<0>(pad.dims)),
pad_r_(std::get<1>(pad.dims)),
rate_(rate),
stride_(stride)
{
return linear_sample_trait(k, stride_, rate_, pad_l_, pad_r_)(n);
}

sample_t get_sample(dim_t ksize) const
{
return sample_t(ksize, stride_, rate_, pad_l_, pad_r_);
}

dim_t operator()(dim_t n, dim_t k) const { return get_sample(k)(n); }
};

template <typename image_order> class conv_trait;

template <> class conv_trait<hw>
{
using conv_trait_1d_t = linear_conv_trait<size_t>;
using dim_t = size_t;
using conv_trait_1d_t = linear_conv_trait<dim_t>;
using padding_1d_t = conv_trait_1d_t::padding_t;

protected:
struct padding_trait;
struct stride_trait;
struct rate_trait;

using padding_t = std::experimental::new_type<shape<2>, padding_trait>;
using padding_t = std::array<padding_1d_t, 2>;

using stride_t = std::experimental::new_type<shape<2>, stride_trait>;
using rate_t = std::experimental::new_type<shape<2>, rate_trait>;

static constexpr auto default_padding = padding_t(0, 0);
static constexpr auto default_stride = stride_t(1, 1);
static constexpr auto default_rate = rate_t(1, 1);

const padding_t padding_;
const stride_t stride_;
const rate_t rate_;

const conv_trait_1d_t h_trait_;
const conv_trait_1d_t w_trait_;

static padding_t default_padding() { return padding(0, 0); }

public:
static padding_t padding(int r, int s) { return padding_t(r, s); };
static padding_1d_t padding_1d(dim_t p) { return padding_1d_t(p, p); }

static padding_1d_t padding_1d(dim_t left, dim_t right)
{
return padding_1d_t(left, right);
}

static padding_t padding(dim_t r, dim_t s)
{
return padding(padding_1d(r), padding_1d(s));
};

static padding_t padding(const padding_1d_t &r, const padding_1d_t &s)
{
return {r, s};
};

static stride_t stride(int r, int s) { return stride_t(r, s); };

conv_trait() : conv_trait(default_padding) {}
static rate_t rate(int r, int s) { return rate_t(r, s); };

conv_trait() : conv_trait(default_padding()) {}

conv_trait(const padding_t &padding) : conv_trait(padding, default_stride)
{
}

conv_trait(const stride_t &stride) : conv_trait(default_padding, stride) {}
conv_trait(const stride_t &stride) : conv_trait(default_padding(), stride)
{
}

conv_trait(const padding_t &padding, const stride_t &stride)
: conv_trait(padding, stride, default_rate)
Expand All @@ -89,11 +129,13 @@ template <> class conv_trait<hw>

conv_trait(const padding_t &padding, const stride_t &stride,
const rate_t &rate)
: padding_(padding),
stride_(stride),
rate_(rate),
h_trait_(padding.dims[0], stride.dims[0], rate.dims[0]),
w_trait_(padding.dims[1], stride.dims[1], rate.dims[1])
: h_trait_(padding[0], stride.dims[0], rate.dims[0]),
w_trait_(padding[1], stride.dims[1], rate.dims[1])
{
}

conv_trait(const conv_trait_1d_t &h_trait, const conv_trait_1d_t &w_trait)
: h_trait_(h_trait), w_trait_(w_trait)
{
}

Expand Down Expand Up @@ -139,10 +181,7 @@ template <> class conv<nhwc, rscd> : public conv_trait<hw>

using upper_op = im2col<hwc, hwrsc>;
const auto upper = internal::make_batched(
upper_op(upper_op::ksize(r, s),
upper_op::padding(padding_.dims[0], padding_.dims[1]),
upper_op::stride(stride_.dims[0], stride_.dims[1]),
upper_op::rate(rate_.dims[0], rate_.dims[1])));
upper_op(h_trait_.get_sample(r), w_trait_.get_sample(s)));

ttl::tensor<R, 6> x_upper(upper(x.shape()));
upper(ref(x_upper), view(x));
Expand Down Expand Up @@ -172,10 +211,8 @@ template <> class conv<nchw, dcrs> : public conv_trait<hw>
using upper_op = im2col<hw, rshw>;
const auto [r, s] = filter_shape<dcrs>(y.shape()).dims;
const auto upper = internal::make_batched(
upper_op(upper_op::ksize(r, s),
upper_op::padding(padding_.dims[0], padding_.dims[1]),
upper_op::stride(stride_.dims[0], stride_.dims[1]),
upper_op::rate(rate_.dims[0], rate_.dims[1])));
upper_op(h_trait_.get_sample(r), w_trait_.get_sample(s)));

ttl::tensor<R, 5> x_upper(upper(x.shape().template subshape<1>()));
const auto n = batch_size<nchw>(z.shape());
for (auto l : range(n)) {
Expand Down
86 changes: 15 additions & 71 deletions include/nn/bits/ops/im2col.hpp
Original file line number Diff line number Diff line change
@@ -1,82 +1,16 @@
#pragma once
#include <experimental/contract>
#include <experimental/new_type>
#include <nn/bits/ops/linear_sample.hpp>
#include <nn/bits/ops/reshape.hpp>
#include <nn/bits/ops/traits.hpp>
#include <stdtensor>
#include <nn/common.hpp>

namespace nn::ops
{
template <typename image_order> class im2col_trait;

template <> class im2col_trait<hw>
template <> class im2col_trait<hw> : public multi_linear_sample_trait<2, size_t>
{
protected:
struct ksize_trait;
struct padding_trait;
struct stride_trait;
struct rate_trait;

using ksize_t = std::experimental::new_type<shape<2>, ksize_trait>;
using padding_t = std::experimental::new_type<shape<2>, padding_trait>;
using stride_t = std::experimental::new_type<shape<2>, stride_trait>;
using rate_t = std::experimental::new_type<shape<2>, rate_trait>;

static constexpr auto default_padding = padding_t(0, 0);
static constexpr auto default_stride = stride_t(1, 1);
static constexpr auto default_rate = rate_t(1, 1);

using sample_t = linear_sample_trait<size_t>;

const sample_t h_sample_;
const sample_t w_sample_;

ksize_t get_ksize() const
{
return ksize_t(h_sample_.ksize_, w_sample_.ksize_);
}

public:
static ksize_t ksize(int r, int s) { return ksize_t(r, s); };
static padding_t padding(int r, int s) { return padding_t(r, s); };
static stride_t stride(int r, int s) { return stride_t(r, s); };
static rate_t rate(int r, int s) { return rate_t(r, s); };

im2col_trait(const ksize_t &ksize)
: im2col_trait(ksize, default_padding, default_stride)
{
}

im2col_trait(const ksize_t &ksize, const padding_t &padding)
: im2col_trait(ksize, padding, default_stride)
{
}

im2col_trait(const ksize_t &ksize, const stride_t &stride)
: im2col_trait(ksize, default_padding, stride)
{
}

im2col_trait(const ksize_t &ksize, const padding_t &padding,
const stride_t &stride)
: im2col_trait(ksize, padding, stride, default_rate)
{
}

im2col_trait(const ksize_t &ksize, const padding_t &padding,
const stride_t &stride, const rate_t &rate)
: h_sample_(ksize.dims[0], stride.dims[0], rate.dims[0],
padding.dims[0]),
w_sample_(ksize.dims[1], stride.dims[1], rate.dims[1],
padding.dims[1])
{
}

shape<2> operator()(const shape<2> &x) const
{
return shape<2>(h_sample_(x.dims[0]), w_sample_(x.dims[1]));
}
using multi_linear_sample_trait::multi_linear_sample_trait;
};

template <typename image_order, typename ColOrder> class im2col;
Expand All @@ -98,6 +32,9 @@ template <> class im2col<hw, hwrs> : public im2col_trait<hw>
const auto [h, w] = x.shape().dims;
const auto [h_, w_, r, s] = y.shape().dims;

const sample_t &h_sample_ = std::get<0>(samples_);
const sample_t &w_sample_ = std::get<1>(samples_);

for (const auto i_ : range(h_)) {
for (const auto j_ : range(w_)) {
for (const auto u : range(r)) {
Expand Down Expand Up @@ -134,6 +71,9 @@ template <> class im2col<hw, rshw> : public im2col_trait<hw>
const auto [h, w] = x.shape().dims;
const auto [r, s, h_, w_] = y.shape().dims;

const sample_t &h_sample_ = std::get<0>(samples_);
const sample_t &w_sample_ = std::get<1>(samples_);

for (const auto u : range(r)) {
for (const auto v : range(s)) {
for (const auto i_ : range(h_)) {
Expand Down Expand Up @@ -162,8 +102,9 @@ template <> class im2col<hwc, hwrsc> : public im2col_trait<hw>
shape<5> operator()(const shape<3> &x) const
{
const auto [r, s] = get_ksize().dims;
return shape<5>(h_sample_(x.dims[0]), w_sample_(x.dims[1]), r, s,
x.dims[2]);
const auto [h, w, c] = x.dims;
const auto [h_, w_] = im2col_trait::operator()(shape<2>(h, w)).dims;
return shape<5>(h_, w_, r, s, c);
}

template <typename R>
Expand All @@ -174,6 +115,9 @@ template <> class im2col<hwc, hwrsc> : public im2col_trait<hw>
const auto [h_, w_, r, s, _c] = y.shape().dims;
contract_assert(_c == c);

const sample_t &h_sample_ = std::get<0>(samples_);
const sample_t &w_sample_ = std::get<1>(samples_);

for (const auto i_ : range(h_)) {
for (const auto j_ : range(w_)) {
for (const auto u : range(r)) {
Expand Down
Loading

0 comments on commit 33b76c2

Please sign in to comment.