"tests/vscode:/vscode.git/clone" did not exist on "d9b8adc4cac287a10d0641533bf6741cd9e5c80a"
convolution_parameter.cpp 6.58 KB
Newer Older
Chao Liu's avatar
Chao Liu committed
1
2
3
// SPDX-License-Identifier: MIT
// Copyright (c) 2018-2022, Advanced Micro Devices, Inc. All rights reserved.

Chao Liu's avatar
Chao Liu committed
4
5
#include "ck/host_utility/io.hpp"

Chao Liu's avatar
Chao Liu committed
6
7
8
#include "ck/library/utility/convolution_parameter.hpp"

namespace ck {
Chao Liu's avatar
clean  
Chao Liu committed
9
10
namespace utils {
namespace conv {
Chao Liu's avatar
Chao Liu committed
11

Chao Liu's avatar
clean  
Chao Liu committed
12
ConvParam::ConvParam(ck::index_t n_dim,
Chao Liu's avatar
add G  
Chao Liu committed
13
                     ck::index_t group_count,
Chao Liu's avatar
clean  
Chao Liu committed
14
15
16
17
18
19
20
21
22
                     ck::index_t n_batch,
                     ck::index_t n_out_channels,
                     ck::index_t n_in_channels,
                     const std::vector<ck::index_t>& filters_len,
                     const std::vector<ck::index_t>& input_len,
                     const std::vector<ck::index_t>& strides,
                     const std::vector<ck::index_t>& dilations,
                     const std::vector<ck::index_t>& left_pads,
                     const std::vector<ck::index_t>& right_pads)
Chao Liu's avatar
Chao Liu committed
23
    : num_dim_spatial_(n_dim),
Chao Liu's avatar
add G  
Chao Liu committed
24
      G_(group_count),
Chao Liu's avatar
Chao Liu committed
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
      N_(n_batch),
      K_(n_out_channels),
      C_(n_in_channels),
      filter_spatial_lengths_(filters_len),
      input_spatial_lengths_(input_len),
      output_spatial_lengths_(num_dim_spatial_),
      conv_filter_strides_(strides),
      conv_filter_dilations_(dilations),
      input_left_pads_(left_pads),
      input_right_pads_(right_pads)
{
    if(static_cast<ck::index_t>(filter_spatial_lengths_.size()) != num_dim_spatial_ ||
       static_cast<ck::index_t>(input_spatial_lengths_.size()) != num_dim_spatial_ ||
       static_cast<ck::index_t>(conv_filter_strides_.size()) != num_dim_spatial_ ||
       static_cast<ck::index_t>(conv_filter_dilations_.size()) != num_dim_spatial_ ||
       static_cast<ck::index_t>(input_left_pads_.size()) != num_dim_spatial_ ||
       static_cast<ck::index_t>(input_right_pads_.size()) != num_dim_spatial_)
    {
        throw(
Chao Liu's avatar
clean  
Chao Liu committed
44
            std::runtime_error("ConvParam::ConvParam: "
Chao Liu's avatar
Chao Liu committed
45
46
47
48
49
50
51
                               "parameter size is different from number of declared dimensions!"));
    }

    for(ck::index_t i = 0; i < num_dim_spatial_; ++i)
    {
        // XEff = (X - 1) * conv_dilation_w + 1;
        // Wo = (Wi + in_left_pad_w + in_right_pad_w - XEff) / conv_stride_w + 1;
Chao Liu's avatar
Chao Liu committed
52
53
        const ck::index_t x_eff = (filter_spatial_lengths_[i] - 1) * conv_filter_dilations_[i] + 1;

Chao Liu's avatar
Chao Liu committed
54
        output_spatial_lengths_[i] =
Chao Liu's avatar
Chao Liu committed
55
            (input_spatial_lengths_[i] + input_left_pads_[i] + input_right_pads_[i] - x_eff) /
Chao Liu's avatar
Chao Liu committed
56
57
58
59
60
                conv_filter_strides_[i] +
            1;
    }
}

Chao Liu's avatar
clean  
Chao Liu committed
61
ConvParam::ConvParam()
Chao Liu's avatar
add G  
Chao Liu committed
62
    : ConvParam::ConvParam(2, 1, 128, 256, 192, {3, 3}, {71, 71}, {2, 2}, {1, 1}, {1, 1}, {1, 1})
Chao Liu's avatar
Chao Liu committed
63
64
65
{
}

Chao Liu's avatar
clean  
Chao Liu committed
66
std::vector<ck::index_t> ConvParam::GetOutputSpatialLengths() const
Chao Liu's avatar
Chao Liu committed
67
68
69
70
{
    return output_spatial_lengths_;
}

Chao Liu's avatar
clean  
Chao Liu committed
71
std::size_t ConvParam::GetFlops() const
Chao Liu's avatar
Chao Liu committed
72
{
Chao Liu's avatar
add G  
Chao Liu committed
73
74
    // 2 * G * N * K * C * <output spatial lengths product> * <filter spatial lengths product>
    return static_cast<std::size_t>(2) * G_ * N_ * K_ * C_ *
Chao Liu's avatar
Chao Liu committed
75
           std::accumulate(std::begin(output_spatial_lengths_),
Chao Liu's avatar
add G  
Chao Liu committed
76
                           std::begin(output_spatial_lengths_) + num_dim_spatial_,
Chao Liu's avatar
Chao Liu committed
77
78
79
                           static_cast<std::size_t>(1),
                           std::multiplies<std::size_t>()) *
           std::accumulate(std::begin(filter_spatial_lengths_),
Chao Liu's avatar
add G  
Chao Liu committed
80
                           std::begin(filter_spatial_lengths_) + num_dim_spatial_,
Chao Liu's avatar
Chao Liu committed
81
82
83
84
                           static_cast<std::size_t>(1),
                           std::multiplies<std::size_t>());
}

Chao Liu's avatar
clean  
Chao Liu committed
85
86
} // namespace conv
} // namespace utils
Chao Liu's avatar
Chao Liu committed
87
88
} // namespace ck

Chao Liu's avatar
clean  
Chao Liu committed
89
std::ostream& operator<<(std::ostream& os, const ck::utils::conv::ConvParam& p)
Chao Liu's avatar
Chao Liu committed
90
{
Chao Liu's avatar
clean  
Chao Liu committed
91
    os << "ConvParam {"
Chao Liu's avatar
add G  
Chao Liu committed
92
93
94
       << "\nnum_dim_spatial: " << p.num_dim_spatial_ << "\nG: " << p.G_ << "\nN: " << p.N_
       << "\nK: " << p.K_ << "\nC: " << p.C_
       << "\nfilter_spatial_lengths: " << p.filter_spatial_lengths_
Chao Liu's avatar
Chao Liu committed
95
96
97
98
       << "\ninput_spatial_lengths: " << p.input_spatial_lengths_
       << "\nconv_filter_strides: " << p.conv_filter_strides_
       << "\nconv_filter_dilations: " << p.conv_filter_dilations_
       << "\ninput_left_pads: " << p.input_left_pads_
Chao Liu's avatar
add G  
Chao Liu committed
99
       << "\ninput_right_pads: " << p.input_right_pads_ << "}\n";
Chao Liu's avatar
Chao Liu committed
100
101
102

    return os;
}
Chao Liu's avatar
Chao Liu committed
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

std::string get_conv_param_parser_helper_msg()
{
    std::string msg;

    msg += "Following arguments (depending on number of spatial dims):\n"
           " Number of spatial dimensions (1=Conv1d, 2=Conv2d, 3=Conv3d)\n"
           " G, N, K, C, \n"
           " <filter spatial dimensions>, (ie Y, X for 2D)\n"
           " <input image spatial dimensions>, (ie Hi, Wi for 2D)\n"
           " <strides>, (ie Sy, Sx for 2D)\n"
           " <dilations>, (ie Dy, Dx for 2D)\n"
           " <left padding>, (ie LeftPy, LeftPx for 2D)\n"
           " <right padding>, (ie RightPy, RightPx for 2D)\n";

    return msg;
}

ck::utils::conv::ConvParam parse_conv_param(int num_dim_spatial, int arg_idx, char* const argv[])
{
    const ck::index_t G = std::stoi(argv[arg_idx++]);
    const ck::index_t N = std::stoi(argv[arg_idx++]);
    const ck::index_t K = std::stoi(argv[arg_idx++]);
    const ck::index_t C = std::stoi(argv[arg_idx++]);

    std::vector<ck::index_t> filter_spatial_lengths(num_dim_spatial);
    std::vector<ck::index_t> input_spatial_lengths(num_dim_spatial);
    std::vector<ck::index_t> conv_filter_strides(num_dim_spatial);
    std::vector<ck::index_t> conv_filter_dilations(num_dim_spatial);
    std::vector<ck::index_t> input_left_pads(num_dim_spatial);
    std::vector<ck::index_t> input_right_pads(num_dim_spatial);

    for(int i = 0; i < num_dim_spatial; ++i)
    {
        filter_spatial_lengths[i] = std::stoi(argv[arg_idx++]);
    }

    for(int i = 0; i < num_dim_spatial; ++i)
    {
        input_spatial_lengths[i] = std::stoi(argv[arg_idx++]);
    }

    for(int i = 0; i < num_dim_spatial; ++i)
    {
        conv_filter_strides[i] = std::stoi(argv[arg_idx++]);
    }

    for(int i = 0; i < num_dim_spatial; ++i)
    {
        conv_filter_dilations[i] = std::stoi(argv[arg_idx++]);
    }

    for(int i = 0; i < num_dim_spatial; ++i)
    {
        input_left_pads[i] = std::stoi(argv[arg_idx++]);
    }

    for(int i = 0; i < num_dim_spatial; ++i)
    {
        input_right_pads[i] = std::stoi(argv[arg_idx++]);
    }

    return ck::utils::conv::ConvParam{num_dim_spatial,
                                      G,
                                      N,
                                      K,
                                      C,
                                      filter_spatial_lengths,
                                      input_spatial_lengths,
                                      conv_filter_strides,
                                      conv_filter_dilations,
                                      input_left_pads,
                                      input_right_pads};
}