56 const std::vector<T> m_pad_row;
59 std::vector<int> m_kernel_y;
60 std::vector<int> m_kernel_x;
62 class column_handler {
67 const T *
const m_input_base;
68 const size_t m_input_stride;
71 const unsigned int m_start_pos;
72 const unsigned int m_start_offset;
75 const unsigned int m_length;
76 const unsigned int m_rounded_stringlen;
81 const column_handler &m_parent;
84 unsigned int m_start_output_y=0;
85 unsigned int m_start_output_x=0;
87 unsigned int m_length_remaining=0;
88 unsigned int m_current_pos=0;
90 unsigned int m_active_height=0;
93 row_handler(
const column_handler &parent,
unsigned int start_row,
unsigned int active_height) :
94 m_convolver(parent.m_parent),
96 m_start_output_y(start_row / m_convolver.m_params.output_width),
97 m_start_output_x(start_row % m_convolver.m_params.output_width),
98 m_length_remaining(m_parent.m_length),
99 m_current_pos(m_parent.m_start_pos),
100 m_active_height(active_height) { }
102 bool finished()
const {
103 return (m_length_remaining == 0);
106 std::tuple<unsigned int, unsigned int> next_block(
const T **
const row_ptr) {
108 return std::make_tuple(0, 0);
113 unsigned int offset = (m_current_pos == m_parent.m_start_pos) ? m_parent.m_start_offset : 0;
114 unsigned int in_width = std::min(m_length_remaining, static_cast<unsigned int>(m_convolver.m_params.input_channels) -
offset);
115 unsigned int out_width = std::min(m_length_remaining, m_parent.m_rounded_stringlen - offset);
117 unsigned int output_y = m_start_output_y;
118 unsigned int output_x = m_start_output_x;
120 for (
unsigned int row=0; row<m_active_height; row++) {
121 int input_y = (output_y * m_convolver.m_params.output_stride_h) + m_convolver.m_kernel_y[m_current_pos];
122 int input_x = (output_x * m_convolver.m_params.output_stride_w) + m_convolver.m_kernel_x[m_current_pos];
126 if (input_y < 0 || input_y >= m_convolver.m_params.input_height || input_x < 0 || input_x >= m_convolver.m_params.input_width) {
127 row_ptr[row] = m_convolver.m_pad_row.data();
129 row_ptr[row] = m_parent.m_input_base + ((input_y * m_convolver.m_params.input_width) + input_x) * m_parent.m_input_stride;
133 if (output_x == m_convolver.m_params.output_width) {
140 m_length_remaining-=out_width;
142 return std::make_tuple(in_width, offset);
147 column_handler(
const convolver<T> &parent,
const T *input_base,
size_t input_stride,
148 unsigned int k_start,
unsigned int k_end,
unsigned int rounded_stringlen)
149 : m_parent(parent), m_input_base(input_base), m_input_stride(input_stride),
150 m_start_pos(k_start / rounded_stringlen),
151 m_start_offset(k_start % rounded_stringlen),
152 m_length(k_end - k_start),
153 m_rounded_stringlen(rounded_stringlen) { }
155 row_handler process_rows(
unsigned int start_row,
unsigned int active_height)
const {
156 return row_handler(*
this, start_row, active_height);
162 m_params (params), m_pad_row(params.input_channels, static_cast<T>(params.padding_value)),
163 m_kernel_y(params.kernel_width * params.kernel_height, 0),
164 m_kernel_x(params.kernel_width * params.kernel_height, 0) {
177 unsigned int k_start,
unsigned int k_end,
unsigned int rounded_stringlen)
const {
178 return column_handler(*
this, input_base, input_stride, k_start, k_end, rounded_stringlen);
__global uchar * offset(const Image *img, int x, int y)
Get the pointer position of a Image.
convolver(ConvolutionParameters params)
column_handler process_columns(const T *input_base, size_t input_stride, unsigned int k_start, unsigned int k_end, unsigned int rounded_stringlen) const