37 int axis = params.
axis;
39 const int concat_dimensions =
output_shape.DimensionsCount();
40 assert(axis < concat_dimensions);
42 [[maybe_unused]] int64_t concat_size = 0;
43 for (
int i = 0; i < inputs_count; i++)
45 assert(input_shapes[i]->DimensionsCount() == concat_dimensions);
46 for (
int j = 0; j < concat_dimensions; j++)
53 concat_size += input_shapes[i]->
Dims(axis);
56 int64_t outer_size = 1;
57 for (
int i = 0; i < axis; ++i)
63 int64_t base_inner_size = 1;
64 for (
int i = axis + 1; i < concat_dimensions; ++i)
69 Scalar *output_ptr = output_data;
70 for (
int k = 0; k < outer_size; k++)
72 for (
int i = 0; i < inputs_count; ++i)
74 const int copy_size = input_shapes[i]->
Dims(axis) * base_inner_size;
75 memcpy(output_ptr, input_data[i] + k * copy_size, copy_size *
sizeof(Scalar));
76 output_ptr += copy_size;
84 const Shape *
const *input_shapes,
88 int axis = params.
axis;
95 const int concat_dimensions =
output_shape.DimensionsCount();
96 assert(axis <= concat_dimensions);
98 [[maybe_unused]] int64_t concat_size = 0;
99 for (
int i = 0; i < inputs_count; i++)
101 assert(input_shapes[i]->DimensionsCount() == concat_dimensions);
102 for (
int j = 0; j < concat_dimensions; j++)
109 concat_size += input_shapes[i]->
Dims(axis);
112 int64_t outer_size = 1;
113 for (
int i = 0; i < axis; ++i)
119 int64_t base_inner_size = 1;
120 for (
int i = axis + 1; i < concat_dimensions; ++i)
125 const float inverse_output_scale = 1.f / output_scale;
126 uint8_t *output_ptr = output_data;
127 for (
int k = 0; k < outer_size; k++)
129 for (
int i = 0; i < inputs_count; ++i)
131 const int copy_size = input_shapes[i]->
Dims(axis) * base_inner_size;
132 const uint8_t *input_ptr = input_data[i] + k * copy_size;
133 if (input_zeropoint[i] == output_zeropoint && input_scale[i] == output_scale)
135 memcpy(output_ptr, input_ptr, copy_size);
139 const float scale = input_scale[i] * inverse_output_scale;
140 const float bias = -input_zeropoint[i] * scale;
141 for (
int j = 0; j < copy_size; ++j)
143 const int32_t value =
144 static_cast<int32_t
>(std::round(input_ptr[j] * scale + bias)) + output_zeropoint;
145 output_ptr[j] =
static_cast<uint8_t
>(std::max(std::min(255, value), 0));
148 output_ptr += copy_size;
void Concatenation(const ConcatenationParams ¶ms, const Shape *const *input_shapes, const Scalar *const *input_data, const Shape &output_shape, Scalar *output_data)