| 156 | } |
| 157 | |
| 158 | Status CheckTensorStridesValidity(const std::shared_ptr<Buffer>& data, |
| 159 | const std::vector<int64_t>& shape, |
| 160 | const std::vector<int64_t>& strides, |
| 161 | const std::shared_ptr<DataType>& type) { |
| 162 | if (strides.size() != shape.size()) { |
| 163 | return Status::Invalid("strides must have the same length as shape"); |
| 164 | } |
| 165 | if (data->size() == 0 && std::find(shape.begin(), shape.end(), 0) != shape.end()) { |
| 166 | return Status::OK(); |
| 167 | } |
| 168 | |
| 169 | // Check the largest offset can be computed without overflow |
| 170 | const size_t ndim = shape.size(); |
| 171 | int64_t largest_offset = 0; |
| 172 | for (size_t i = 0; i < ndim; ++i) { |
| 173 | if (shape[i] == 0) continue; |
| 174 | if (strides[i] < 0) { |
| 175 | // TODO(mrkn): Support negative strides for sharing views |
| 176 | return Status::Invalid("negative strides not supported"); |
| 177 | } |
| 178 | |
| 179 | int64_t dim_offset; |
| 180 | if (!internal::MultiplyWithOverflow(shape[i] - 1, strides[i], &dim_offset)) { |
| 181 | if (!internal::AddWithOverflow(largest_offset, dim_offset, &largest_offset)) { |
| 182 | continue; |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | return Status::Invalid( |
| 187 | "offsets computed from shape and strides would not fit in 64-bit integer"); |
| 188 | } |
| 189 | |
| 190 | const int byte_width = type->byte_width(); |
| 191 | if (largest_offset > data->size() - byte_width) { |
| 192 | return Status::Invalid("strides must not involve buffer over run"); |
| 193 | } |
| 194 | return Status::OK(); |
| 195 | } |
| 196 | |
| 197 | } // namespace |
| 198 |
no test coverage detected