| 85 | // was created, and is used to sanity check the indices in `group'. |
| 86 | template <typename T> |
| 87 | void CheckGroup(OpKernelContext* ctx, const sparse::Group& group, |
| 88 | const VarDimArray& sparse_tensor_shape) { |
| 89 | const auto& indices = group.indices(); |
| 90 | const auto& values = group.values<T>(); |
| 91 | |
| 92 | // Sanity check: group is non-empty, and indices and values are same size. |
| 93 | const auto num_values = values.dimension(0); |
| 94 | OP_REQUIRES(ctx, indices.size() > 0, errors::Internal("Empty group.")); |
| 95 | OP_REQUIRES( |
| 96 | ctx, indices.dimension(0) == num_values, |
| 97 | errors::Internal("shape[0] of group indices ", indices.dimension(0), |
| 98 | " != values ", num_values, ".")); |
| 99 | |
| 100 | // Sanity check: valid indices. |
| 101 | const auto group_rank = indices.dimension(1); |
| 102 | const auto expected_rank = sparse_tensor_shape.size(); |
| 103 | OP_REQUIRES(ctx, expected_rank == group_rank, |
| 104 | errors::Internal("Rank expected ", expected_rank, ", got ", |
| 105 | group_rank, ".")); |
| 106 | for (int32 j = 0; j < expected_rank; ++j) { |
| 107 | const auto dim_size = sparse_tensor_shape[j]; |
| 108 | OP_REQUIRES( |
| 109 | ctx, dim_size > 0, |
| 110 | errors::Internal("Invalid dim_size[", j, "] = ", dim_size, ".")); |
| 111 | for (int64 i = 0; i < num_values; ++i) { |
| 112 | const auto index = indices(i, j); |
| 113 | OP_REQUIRES(ctx, dim_size > index, |
| 114 | errors::Internal("indices[", i, ", ", j, "] expected < ", |
| 115 | dim_size, ", got ", index, ".")); |
| 116 | } |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | // This lets us calculate the row-major index into flattened output. |
| 121 | const ShapeArray Strides(const VarDimArray& shape) { |