| 122 | } |
| 123 | |
| 124 | void Tensor::reshape(const std::vector<int>& shape) { |
| 125 | LITE_ASSERT(m_layout.ndim > 0, "The tensor to be reshape is empty."); |
| 126 | uint32_t length = shape.size(); |
| 127 | LITE_ASSERT(length < Layout::MAXDIM, "The ndim of reshape input is too large."); |
| 128 | Layout new_layout = m_layout; |
| 129 | new_layout.ndim = length; |
| 130 | size_t total_length = get_tensor_total_size_in_byte() / m_layout.get_elem_size(); |
| 131 | uint32_t unfixed_number = 0; |
| 132 | uint32_t unfixed_index = 0; |
| 133 | for (uint32_t i = 0; i < length; i++) { |
| 134 | if (shape[i] == -1) { |
| 135 | unfixed_number += 1; |
| 136 | unfixed_index = i; |
| 137 | } else { |
| 138 | LITE_ASSERT(shape[i] > 0, "The reshape inputs invalid."); |
| 139 | new_layout.shapes[i] = shape[i]; |
| 140 | } |
| 141 | } |
| 142 | LITE_ASSERT(unfixed_number <= 1, "The reshape inputs invalid."); |
| 143 | if (unfixed_number) { |
| 144 | size_t left = total_length; |
| 145 | for (uint32_t i = 0; i < length; i++) { |
| 146 | if (i == unfixed_index) { |
| 147 | continue; |
| 148 | } else { |
| 149 | LITE_ASSERT( |
| 150 | left > 0 && (left % new_layout.shapes[i] == 0), |
| 151 | "The reshape inputs invalid."); |
| 152 | left = left / new_layout.shapes[i]; |
| 153 | } |
| 154 | } |
| 155 | LITE_ASSERT(left > 0, "The reshape inputs invalid."); |
| 156 | new_layout.shapes[unfixed_index] = left; |
| 157 | } |
| 158 | size_t new_total = 1; |
| 159 | for (uint32_t i = 0; i < length; i++) { |
| 160 | new_total *= new_layout.shapes[i]; |
| 161 | } |
| 162 | LITE_ASSERT(new_total == total_length, "The reshape inputs invalid."); |
| 163 | m_layout = new_layout; |
| 164 | m_tensor_impl->reshape(m_layout); |
| 165 | } |
| 166 | |
| 167 | size_t Tensor::get_tensor_total_size_in_byte() const { |
| 168 | LITE_ERROR_HANDLER_BEGIN |