@@ -22,15 +22,18 @@ void ReshapeLayer::run(const std::vector<Tensor>& input,
2222 }
2323 }
2424
25+ std::vector<int64_t > original_requested_shape = target_shape;
2526 auto final_shape =
2627 calculate_output_shape (data_tensor.get_shape (), target_shape);
2728
2829 switch (data_tensor.get_type ()) {
2930 case Type::kFloat :
30- reshape_impl<float >(data_tensor, output[0 ], final_shape);
31+ reshape_impl<float >(data_tensor, output[0 ], original_requested_shape,
32+ final_shape);
3133 break ;
3234 case Type::kInt :
33- reshape_impl<int >(data_tensor, output[0 ], final_shape);
35+ reshape_impl<int >(data_tensor, output[0 ], original_requested_shape,
36+ final_shape);
3437 break ;
3538 default :
3639 throw std::runtime_error (" Unsupported tensor data type for Reshape" );
@@ -39,19 +42,24 @@ void ReshapeLayer::run(const std::vector<Tensor>& input,
3942
4043std::vector<int64_t > ReshapeLayer::calculate_output_shape (
4144 const Shape& input_shape, const std::vector<int64_t >& requested_shape) {
45+ std::vector<int64_t > target_shape = requested_shape;
46+ if (requested_shape[0 ] == 1 && input_shape[0 ] > 1 ) {
47+ target_shape[0 ] = static_cast <int64_t >(input_shape[0 ]);
48+ }
49+
4250 size_t total_elements = 1 ;
4351 for (size_t i = 0 ; i < input_shape.dims (); ++i) {
4452 total_elements *= input_shape[i];
4553 }
4654
4755 std::vector<int64_t > output_shape;
48- output_shape.reserve (requested_shape .size ());
56+ output_shape.reserve (target_shape .size ());
4957
5058 int negative_dim = -1 ;
5159 size_t inferred_size = total_elements;
5260
53- for (size_t i = 0 ; i < requested_shape .size (); ++i) {
54- int64_t dim = requested_shape [i];
61+ for (size_t i = 0 ; i < target_shape .size (); ++i) {
62+ int64_t dim = target_shape [i];
5563
5664 if (dim == -1 ) {
5765 if (negative_dim != -1 ) {
@@ -69,10 +77,6 @@ std::vector<int64_t> ReshapeLayer::calculate_output_shape(
6977 inferred_size /= static_cast <size_t >(dim_value);
7078 }
7179 } else {
72- if (dim < 0 && dim != -1 ) {
73- throw std::runtime_error (
74- " Reshape: Negative dimension value not supported" );
75- }
7680 output_shape.push_back (dim);
7781 if (dim != 0 ) {
7882 inferred_size /= static_cast <size_t >(dim);
@@ -81,6 +85,10 @@ std::vector<int64_t> ReshapeLayer::calculate_output_shape(
8185 }
8286
8387 if (negative_dim != -1 ) {
88+ if (inferred_size == 0 ||
89+ inferred_size > std::numeric_limits<size_t >::max () / 1000 ) {
90+ throw std::runtime_error (" Reshape: Invalid inferred dimension size" );
91+ }
8492 output_shape[negative_dim] = static_cast <int64_t >(inferred_size);
8593 }
8694
@@ -89,35 +97,79 @@ std::vector<int64_t> ReshapeLayer::calculate_output_shape(
8997 new_total *= static_cast <size_t >(dim);
9098 }
9199
92- if (new_total != total_elements) {
93- throw std::runtime_error (" Reshape: Total elements mismatch" );
94- }
95-
96100 return output_shape;
97101}
98102
99103template <typename T>
100104void ReshapeLayer::reshape_impl (
101105 const Tensor& input, Tensor& output,
102- const std::vector<int64_t >& target_shape) const {
106+ const std::vector<int64_t >& original_requested_shape,
107+ const std::vector<int64_t >& final_shape) const {
108+ const auto * input_data = input.as <T>();
109+ const Shape& input_shape = input.get_shape ();
110+
111+ if (input_shape[0 ] > 1 && original_requested_shape[0 ] == 1 ) {
112+ apply_per_batch_reshape<T>(input, output, original_requested_shape);
113+ } else {
114+ std::vector<size_t > shape_size_t ;
115+ for (int64_t dim : final_shape) {
116+ shape_size_t .push_back (static_cast <size_t >(dim));
117+ }
118+ output = make_tensor (*input_data, Shape (shape_size_t ));
119+ }
120+ }
121+
122+ template <typename T>
123+ void ReshapeLayer::apply_per_batch_reshape (
124+ const Tensor& input, Tensor& output,
125+ const std::vector<int64_t >& original_requested_shape) const {
103126 const auto * input_data = input.as <T>();
104- if (!input_data) {
105- throw std::runtime_error (" Reshape: Invalid input data" );
127+ const Shape& input_shape = input.get_shape ();
128+ size_t batch_size = input_shape[0 ];
129+ size_t elements_per_batch = input_shape.count () / batch_size;
130+ std::vector<int64_t > per_batch_target = original_requested_shape;
131+ per_batch_target[0 ] = 1 ;
132+
133+ Shape single_batch_input_shape = input_shape;
134+ single_batch_input_shape[0 ] = 1 ;
135+
136+ std::vector<int64_t > single_batch_output_shape =
137+ calculate_output_shape (single_batch_input_shape, per_batch_target);
138+
139+ std::vector<size_t > final_output_shape_size_t ;
140+ final_output_shape_size_t .push_back (batch_size);
141+ for (size_t i = 1 ; i < single_batch_output_shape.size (); ++i) {
142+ final_output_shape_size_t .push_back (
143+ static_cast <size_t >(single_batch_output_shape[i]));
144+ }
145+
146+ Shape final_output_shape (final_output_shape_size_t );
147+
148+ size_t output_elements_per_batch = final_output_shape.count () / batch_size;
149+
150+ if (elements_per_batch != output_elements_per_batch) {
151+ throw std::runtime_error (" Reshape: Per-batch elements mismatch" );
106152 }
107153
108- std::vector<size_t > shape_size_t ;
109- shape_size_t .reserve (target_shape.size ());
110- for (int64_t dim : target_shape) {
111- shape_size_t .push_back (static_cast <size_t >(dim));
154+ std::vector<T> output_data (final_output_shape.count ());
155+
156+ for (size_t b = 0 ; b < batch_size; ++b) {
157+ size_t input_offset = b * elements_per_batch;
158+ size_t output_offset = b * output_elements_per_batch;
159+
160+ for (size_t i = 0 ; i < elements_per_batch; ++i) {
161+ output_data[output_offset + i] = (*input_data)[input_offset + i];
162+ }
112163 }
113164
114- Shape new_shape (shape_size_t );
115- output = make_tensor (*input_data, new_shape);
165+ output = make_tensor (output_data, final_output_shape);
116166}
117167
118168template void ReshapeLayer::reshape_impl<float >(
119- const Tensor&, Tensor&, const std::vector<int64_t >&) const ;
169+ const Tensor&, Tensor&, const std::vector<int64_t >&,
170+ const std::vector<int64_t >&) const ;
120171template void ReshapeLayer::reshape_impl<int >(
121- const Tensor&, Tensor&, const std::vector<int64_t >&) const ;
172+ const Tensor&, Tensor&, const std::vector<int64_t >&,
173+ const std::vector<int64_t >&) const ;
122174
123175} // namespace it_lab_ai
0 commit comments