conv_common.hpp 5.11 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
Chao Liu committed
4
#include "tensor_descriptor.hpp"
5
6
7
8
9
10
11
12
13
14
#include "dynamic_tensor_descriptor.hpp"

enum ConvTensorLayout
{
    NCHW,
    NHWC,
    CHWN,
    NCHWc,
    NHWCc
};
Chao Liu's avatar
Chao Liu committed
15

16
17
18
19
template <class InDesc,
          class WeiDesc,
          class ConvStrides,
          class ConvDilations,
20
21
          class LeftPads,
          class RightPads>
Chao Liu's avatar
Chao Liu committed
22
constexpr auto get_convolution_output_default_4d_tensor_descriptor(
23
    InDesc, WeiDesc, ConvStrides, ConvDilations, LeftPads, RightPads)
24
{
Chao Liu's avatar
Chao Liu committed
25
26
    using namespace ck;

27
28
29
30
31
32
33
34
    constexpr auto in_desc  = InDesc{};
    constexpr auto wei_desc = WeiDesc{};

    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
35
36
    static_assert(in_desc.GetNumOfDimension() == 4, "input nDim is not 4");
    static_assert(wei_desc.GetNumOfDimension() == 4, "weight nDim is not 4");
37
38
39
    static_assert(in_desc.GetLength(I1) == wei_desc.GetLength(I1),
                  "input & weight dimension not consistent");

40
41
42
    constexpr index_t N  = in_desc.GetLength(I0);
    constexpr index_t Hi = in_desc.GetLength(I2);
    constexpr index_t Wi = in_desc.GetLength(I3);
43

44
45
46
    constexpr index_t K = wei_desc.GetLength(I0);
    constexpr index_t Y = wei_desc.GetLength(I2);
    constexpr index_t X = wei_desc.GetLength(I3);
47

48
49
    constexpr index_t LeftPadH = LeftPads{}.Get(I0);
    constexpr index_t LeftPadW = LeftPads{}.Get(I1);
50

51
52
    constexpr index_t RightPadH = RightPads{}.Get(I0);
    constexpr index_t RightPadW = RightPads{}.Get(I1);
53

54
55
    constexpr index_t YEff = (Y - 1) * ConvDilations{}[0] + 1;
    constexpr index_t XEff = (X - 1) * ConvDilations{}[1] + 1;
Chao Liu's avatar
Chao Liu committed
56

57
58
    constexpr index_t Ho = (Hi + LeftPadH + RightPadH - YEff) / ConvStrides{}[0] + 1;
    constexpr index_t Wo = (Wi + LeftPadW + RightPadW - XEff) / ConvStrides{}[1] + 1;
59

Chao Liu's avatar
Chao Liu committed
60
    return make_native_tensor_descriptor_packed(Sequence<N, K, Ho, Wo>{});
Chao Liu's avatar
Chao Liu committed
61
}
Chao Liu's avatar
Chao Liu committed
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
template <typename... InDesc,
          typename... WeiDesc,
          typename ConvStrides,
          typename ConvDilations,
          typename LeftPads,
          typename RightPads>
constexpr auto get_convolution_output_default_4d_tensor_descriptor(
    const ck::DynamicTensorDescriptor<InDesc...>& in_desc,
    const ck::DynamicTensorDescriptor<WeiDesc...>& wei_desc,
    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;

    return make_dynamic_naive_tensor_descriptor_packed_v2(make_tuple(N, K, Ho, Wo));
}

Chao Liu's avatar
Chao Liu committed
111
template <class InDesc, class WeiDesc, class OutDesc>
Chao Liu's avatar
Chao Liu committed
112
113
constexpr std::size_t
calculate_convolution_flops(const InDesc& in_desc, const WeiDesc& wei_desc, const OutDesc& out_desc)
Chao Liu's avatar
Chao Liu committed
114
{
Chao Liu's avatar
Chao Liu committed
115
116
    using namespace ck;

Chao Liu's avatar
Chao Liu committed
117
118
119
120
121
    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
122
123
124
125
    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
126

Chao Liu's avatar
Chao Liu committed
127
128
129
    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
130
131
132

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

template <class Float, class InDesc, class WeiDesc, class OutDesc>
constexpr std::size_t calculate_convolution_memory_size(Float, InDesc, WeiDesc, OutDesc)
{
Chao Liu's avatar
Chao Liu committed
137
138
    using namespace ck;

Chao Liu's avatar
Chao Liu committed
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    constexpr auto wei_desc = WeiDesc{};
    constexpr auto out_desc = OutDesc{};

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

    constexpr index_t N  = out_desc.GetLength(I0);
    constexpr index_t K  = out_desc.GetLength(I1);
    constexpr index_t Ho = out_desc.GetLength(I2);
    constexpr index_t Wo = out_desc.GetLength(I3);

    constexpr index_t C = wei_desc.GetLength(I1);
    constexpr index_t Y = wei_desc.GetLength(I2);
    constexpr index_t X = wei_desc.GetLength(I3);

156
157
    return sizeof(Float) *
           (InDesc::GetElementSpace() + WeiDesc::GetElementSpace() + OutDesc::GetElementSpace());
Chao Liu's avatar
Chao Liu committed
158
}
159
160

#endif