| 33 | namespace nvcv::priv { |
| 34 | |
| 35 | static void ValidateTensorBufferStrided(const NVCVTensorData &tdata) |
| 36 | { |
| 37 | NVCV_ASSERT(tdata.bufferType == NVCV_TENSOR_BUFFER_STRIDED_CUDA); |
| 38 | |
| 39 | const NVCVTensorBufferStrided &buffer = tdata.buffer.strided; |
| 40 | |
| 41 | if (buffer.basePtr == nullptr) |
| 42 | { |
| 43 | throw Exception(NVCV_ERROR_INVALID_ARGUMENT) << "Memory buffer must not be NULL"; |
| 44 | } |
| 45 | |
| 46 | int rank = tdata.rank; |
| 47 | |
| 48 | if (rank <= 0) |
| 49 | { |
| 50 | throw Exception(NVCV_ERROR_INVALID_ARGUMENT, "Number of dimensions must be >= 1, not %d", rank); |
| 51 | } |
| 52 | |
| 53 | for (int i = 0; i < rank; ++i) |
| 54 | { |
| 55 | if (tdata.shape[i] < 1) |
| 56 | { |
| 57 | throw Exception(NVCV_ERROR_INVALID_ARGUMENT) << "Shape #" << i << " must be >= 1, not " << tdata.shape[i]; |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | DataType dtype{tdata.dtype}; |
| 62 | |
| 63 | int firstPacked = IsChannelLast(tdata.layout) ? std::max(0, rank - 2) : rank - 1; |
| 64 | |
| 65 | int prevStrideConsidered = buffer.strides[rank - 1]; |
| 66 | int prevSizeConsidered = tdata.shape[rank - 1]; |
| 67 | |
| 68 | // Test packed dimensions |
| 69 | int dim; |
| 70 | for (dim = rank - 1; dim >= firstPacked; --dim) |
| 71 | { |
| 72 | if (tdata.shape[dim] <= 1) |
| 73 | { |
| 74 | continue; |
| 75 | } |
| 76 | |
| 77 | int correctPitch = dim == rank - 1 ? dtype.strideBytes() : prevStrideConsidered * prevSizeConsidered; |
| 78 | if (buffer.strides[dim] != correctPitch) |
| 79 | { |
| 80 | throw Exception(NVCV_ERROR_INVALID_ARGUMENT) |
| 81 | << "Pitch of dimension " << dim << " must be == " << correctPitch << " (packed)" |
| 82 | << ", but it is " << buffer.strides[dim]; |
| 83 | } |
| 84 | prevStrideConsidered = buffer.strides[dim]; |
| 85 | prevSizeConsidered = tdata.shape[dim]; |
| 86 | } |
| 87 | |
| 88 | // Test non-packed dimensions |
| 89 | for (; dim >= 0; --dim) |
| 90 | { |
| 91 | if (tdata.shape[dim] <= 1) |
| 92 | { |
no test coverage detected