| 77 | |
| 78 | template <typename c_index_type, typename c_value_type> |
| 79 | void ConvertColumnMajorTensor(const Tensor& tensor, c_index_type* out_indices, |
| 80 | c_value_type* out_values, const int64_t size) { |
| 81 | const auto ndim = tensor.ndim(); |
| 82 | std::vector<c_index_type> indices(ndim * size); |
| 83 | std::vector<c_value_type> values(size); |
| 84 | ConvertRowMajorTensor(tensor, indices.data(), values.data(), size); |
| 85 | |
| 86 | // transpose indices |
| 87 | for (int64_t i = 0; i < size; ++i) { |
| 88 | for (int j = 0; j < ndim / 2; ++j) { |
| 89 | std::swap(indices[i * ndim + j], indices[i * ndim + ndim - j - 1]); |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | // sort indices |
| 94 | std::vector<int64_t> order(size); |
| 95 | std::iota(order.begin(), order.end(), 0); |
| 96 | std::sort(order.begin(), order.end(), [&](const int64_t xi, const int64_t yi) { |
| 97 | const int64_t x_offset = xi * ndim; |
| 98 | const int64_t y_offset = yi * ndim; |
| 99 | for (int j = 0; j < ndim; ++j) { |
| 100 | const auto x = indices[x_offset + j]; |
| 101 | const auto y = indices[y_offset + j]; |
| 102 | if (x < y) return true; |
| 103 | if (x > y) return false; |
| 104 | } |
| 105 | return false; |
| 106 | }); |
| 107 | |
| 108 | // transfer result |
| 109 | const auto* indices_data = indices.data(); |
| 110 | for (int64_t i = 0; i < size; ++i) { |
| 111 | out_values[i] = values[i]; |
| 112 | |
| 113 | std::copy_n(indices_data, ndim, out_indices); |
| 114 | indices_data += ndim; |
| 115 | out_indices += ndim; |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | template <typename c_index_type, typename c_value_type> |
| 120 | void ConvertStridedTensor(const Tensor& tensor, c_index_type* indices, |
nothing calls this directly
no test coverage detected