| 81 | } |
| 82 | |
| 83 | Result<std::vector<int64_t>> ComputeStrides(const std::shared_ptr<DataType>& value_type, |
| 84 | std::span<const int64_t> shape, |
| 85 | std::span<const int64_t> permutation) { |
| 86 | const auto ndim = shape.size(); |
| 87 | const int byte_width = value_type->byte_width(); |
| 88 | |
| 89 | // Use identity permutation if none provided |
| 90 | std::vector<int64_t> perm; |
| 91 | if (permutation.empty()) { |
| 92 | perm.resize(ndim); |
| 93 | std::iota(perm.begin(), perm.end(), 0); |
| 94 | } else { |
| 95 | perm.assign(permutation.begin(), permutation.end()); |
| 96 | } |
| 97 | |
| 98 | int64_t remaining = 0; |
| 99 | if (!shape.empty() && shape[0] > 0) { |
| 100 | remaining = byte_width; |
| 101 | for (auto i : perm) { |
| 102 | if (i > 0) { |
| 103 | if (MultiplyWithOverflow(remaining, shape[i], &remaining)) { |
| 104 | return Status::Invalid( |
| 105 | "Strides computed from shape would not fit in 64-bit integer"); |
| 106 | } |
| 107 | } |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | std::vector<int64_t> strides; |
| 112 | if (remaining == 0) { |
| 113 | strides.assign(ndim, byte_width); |
| 114 | return strides; |
| 115 | } |
| 116 | |
| 117 | strides.push_back(remaining); |
| 118 | for (auto i : perm) { |
| 119 | if (i > 0) { |
| 120 | remaining /= shape[i]; |
| 121 | strides.push_back(remaining); |
| 122 | } |
| 123 | } |
| 124 | Permute(perm, &strides); |
| 125 | |
| 126 | return strides; |
| 127 | } |
| 128 | |
| 129 | Result<std::shared_ptr<Buffer>> SliceTensorBuffer(const Array& data_array, |
| 130 | const DataType& value_type, |
no test coverage detected