| 181 | } |
| 182 | |
| 183 | bool DetectSparseCOOIndexCanonicality(const std::shared_ptr<Tensor>& coords) { |
| 184 | DCHECK_EQ(coords->ndim(), 2); |
| 185 | |
| 186 | const auto& shape = coords->shape(); |
| 187 | const int64_t non_zero_length = shape[0]; |
| 188 | if (non_zero_length <= 1) return true; |
| 189 | |
| 190 | const int64_t ndim = shape[1]; |
| 191 | std::vector<int64_t> last_index, index; |
| 192 | GetCOOIndexTensorRow(coords, 0, &last_index); |
| 193 | for (int64_t i = 1; i < non_zero_length; ++i) { |
| 194 | GetCOOIndexTensorRow(coords, i, &index); |
| 195 | int64_t j = 0; |
| 196 | while (j < ndim) { |
| 197 | if (last_index[j] > index[j]) { |
| 198 | // last_index > index, so we can detect non-canonical here |
| 199 | return false; |
| 200 | } |
| 201 | if (last_index[j] < index[j]) { |
| 202 | // last_index < index, so we can skip the remaining dimensions |
| 203 | break; |
| 204 | } |
| 205 | ++j; |
| 206 | } |
| 207 | if (j == ndim) { |
| 208 | // last_index == index, so we can detect non-canonical here |
| 209 | return false; |
| 210 | } |
| 211 | swap(last_index, index); |
| 212 | } |
| 213 | |
| 214 | return true; |
| 215 | } |
| 216 | |
| 217 | } // namespace |
| 218 |
no test coverage detected