conv_common.hpp 2.78 KB
Newer Older
Chao Liu's avatar
Chao Liu committed
1
2
#ifndef CONV_COMMON_HPP
#define CONV_COMMON_HPP
3

Chao Liu's avatar
rename  
Chao Liu committed
4
#include "tensor_descriptor.hpp"
5
6
7
8
9
10
11
12

template <typename... InDesc,
          typename... WeiDesc,
          typename ConvStrides,
          typename ConvDilations,
          typename LeftPads,
          typename RightPads>
constexpr auto get_convolution_output_default_4d_tensor_descriptor(
Chao Liu's avatar
rename  
Chao Liu committed
13
14
    const ck::TensorDescriptor<InDesc...>& in_desc,
    const ck::TensorDescriptor<WeiDesc...>& wei_desc,
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
    const ConvStrides& conv_strides,
    const ConvDilations conv_dilations,
    const LeftPads& left_pads,
    const RightPads& right_pads)
{
    using namespace ck;

    constexpr auto I0 = Number<0>{};
    constexpr auto I1 = Number<1>{};
    constexpr auto I2 = Number<2>{};
    constexpr auto I3 = Number<3>{};

    assert(in_desc.GetNumOfDimension() == 4);
    assert(wei_desc.GetNumOfDimension() == 4);
    assert(in_desc.GetLength(I1) == wei_desc.GetLength(I1));

    const auto N  = in_desc.GetLength(I0);
    const auto Hi = in_desc.GetLength(I2);
    const auto Wi = in_desc.GetLength(I3);

    const auto K = wei_desc.GetLength(I0);
    const auto Y = wei_desc.GetLength(I2);
    const auto X = wei_desc.GetLength(I3);

    const auto LeftPadH = left_pads[I0];
    const auto LeftPadW = left_pads[I1];

    const auto RightPadH = right_pads[I0];
    const auto RightPadW = right_pads[I1];

    const auto YEff = (Y - I1) * conv_dilations[I0] + I1;
    const auto XEff = (X - I1) * conv_dilations[I1] + I1;

    const auto Ho = (Hi + LeftPadH + RightPadH - YEff) / conv_strides[I0] + I1;
    const auto Wo = (Wi + LeftPadW + RightPadW - XEff) / conv_strides[I1] + I1;

Chao Liu's avatar
rename  
Chao Liu committed
51
    return make_naive_tensor_descriptor_packed(make_tuple(N, K, Ho, Wo));
52
53
}

Chao Liu's avatar
Chao Liu committed
54
template <class InDesc, class WeiDesc, class OutDesc>
Chao Liu's avatar
Chao Liu committed
55
constexpr std::size_t
Chao Liu's avatar
tidy  
Chao Liu committed
56
calculate_convolution_flops(const InDesc&, const WeiDesc& wei_desc, const OutDesc& out_desc)
Chao Liu's avatar
Chao Liu committed
57
{
Chao Liu's avatar
Chao Liu committed
58
59
    using namespace ck;

Chao Liu's avatar
Chao Liu committed
60
61
62
63
64
    constexpr auto I0 = Number<0>{};
    constexpr auto I1 = Number<1>{};
    constexpr auto I2 = Number<2>{};
    constexpr auto I3 = Number<3>{};

Chao Liu's avatar
Chao Liu committed
65
66
67
68
    const index_t N  = out_desc.GetLength(I0);
    const index_t K  = out_desc.GetLength(I1);
    const index_t Ho = out_desc.GetLength(I2);
    const index_t Wo = out_desc.GetLength(I3);
Chao Liu's avatar
Chao Liu committed
69

Chao Liu's avatar
Chao Liu committed
70
71
72
    const index_t C = wei_desc.GetLength(I1);
    const index_t Y = wei_desc.GetLength(I2);
    const index_t X = wei_desc.GetLength(I3);
Chao Liu's avatar
Chao Liu committed
73
74
75

    return std::size_t(2) * N * K * Ho * Wo * C * Y * X;
}
Chao Liu's avatar
Chao Liu committed
76

77
78
79
80
81
82
83
84
85
86
87
88
89
template <typename T>
inline auto activ(T v, const ck::ActivTypeEnum_t activ_type)
{
    const T alpha = 0.3;
    switch(activ_type)
    {
    case ck::ActivTypeEnum_t::None: return v;
    case ck::ActivTypeEnum_t::LeakyRelu: return (v >= 0 ? v : alpha * v);
    case ck::ActivTypeEnum_t::Sigmoid: return (1 / (1 + exp(-v)));
    default: throw std::runtime_error("unsupported activ type"); break;
    }
}

90
#endif