| 284 | } |
| 285 | |
| 286 | void ReshapeTensorData(NVCVTensorData &tensor_data, int new_rank, const int64_t *new_shape, NVCVTensorLayout new_layout) |
| 287 | { |
| 288 | int64_t old_volume = 1; |
| 289 | for (int d = 0; d < tensor_data.rank; d++) old_volume *= tensor_data.shape[d]; |
| 290 | |
| 291 | // TODO: Add 0D tensor support, once it's supported accross the board |
| 292 | if (new_rank < 1 || new_rank > NVCV_TENSOR_MAX_RANK) |
| 293 | throw Exception(NVCV_ERROR_INVALID_ARGUMENT) |
| 294 | << "Number of dimensions must be between 1 and " << NVCV_TENSOR_MAX_RANK << ", not " << new_rank; |
| 295 | |
| 296 | int64_t new_volume = 1; |
| 297 | for (int d = 0; d < new_rank; d++) new_volume *= new_shape[d]; |
| 298 | |
| 299 | if (new_volume != old_volume) |
| 300 | { |
| 301 | throw Exception(NVCV_ERROR_INVALID_ARGUMENT) |
| 302 | << "The volume (" << new_volume << ") of the provided shape " << ShapeStr(new_rank, new_shape) |
| 303 | << " does not match the size of the array (" << old_volume << ")"; |
| 304 | } |
| 305 | |
| 306 | // layout ------------ |
| 307 | if (new_layout.rank > 0) |
| 308 | { |
| 309 | if (new_layout.rank != new_rank) |
| 310 | throw Exception(NVCV_ERROR_INVALID_ARGUMENT) |
| 311 | << "The number of dimensions of the provided layout and shape do not match. Got a " |
| 312 | "shape with " |
| 313 | << new_rank << " dimensions and a layout with " << new_layout.rank << " dimensions"; |
| 314 | } |
| 315 | tensor_data.layout = new_layout; |
| 316 | |
| 317 | // Check strides ------------ |
| 318 | |
| 319 | // right now is the only option supported |
| 320 | assert(tensor_data.bufferType == NVCV_TENSOR_BUFFER_STRIDED_CUDA); |
| 321 | |
| 322 | // Collapses non-strided dimensions into groups |
| 323 | // Example 1: |
| 324 | // A tensor with shape (480, 640, 3) and strides (2560, 4, 1) |
| 325 | // will be collapsed into (307200, 3) with strides (4, 1). |
| 326 | // Example 2: |
| 327 | // A tensor with shape (480, 640, 3) and strides (2560, 3, 1) |
| 328 | // will be collapsed into (921600,) with strides (1,). |
| 329 | int64_t simplified_shape[NVCV_TENSOR_MAX_RANK]; |
| 330 | int64_t simplified_strides[NVCV_TENSOR_MAX_RANK]; |
| 331 | int simplified_rank = Simplify(tensor_data.rank, tensor_data.shape, tensor_data.buffer.strided.strides, |
| 332 | simplified_shape, simplified_strides); |
| 333 | |
| 334 | // Calculate output strides (if reshape is possible) or throw an error |
| 335 | bool ret = ReshapeSimplified(simplified_rank, simplified_shape, simplified_strides, new_rank, new_shape, |
| 336 | tensor_data.buffer.strided.strides); |
| 337 | if (!ret) |
| 338 | { |
| 339 | throw Exception(NVCV_ERROR_INVALID_ARGUMENT) |
| 340 | << "Cannot reshape" |
| 341 | << ". Original shape: " << ShapeStr(tensor_data.rank, tensor_data.shape) |
| 342 | << ", Strides: " << ShapeStr(tensor_data.rank, tensor_data.buffer.strided.strides) |
| 343 | << ", Target shape: " << ShapeStr(new_rank, new_shape); |
no test coverage detected