Skip to content

Conversation

@ValerianRey
Copy link
Contributor

@ValerianRey ValerianRey commented Nov 17, 2025

TODO:

  • Add a special type of error for that, like UnsupportedOnSparseError. We could catch that + NotImplementedError, but not catch ValueError for instance.
  • Prioritize using aten (low level) operations over torch (high level) operations to avoid going through all the dispatch mechanics several times.
  • Add pointwise and 0-to-0 functions that take one Tensor and some other arguments that can be directly forwarded to the call on the physical to the default implementation of pointwise functions.
  • Be careful about composition, need to make sure that every operation returns the right type of physical (and need tests).
  • Investigate overflow of the hnf_decomposition algorithm, with a matrix of shape [5, 7], rank 3 and values in range [-50, 51[, there was overflow (See test prior to ba9bf21)

Comment on lines 166 to 170
def div_Tensor(t1: Tensor | int | float, t2: Tensor | int | float) -> Tensor:
t1_, t2_ = prepare_for_elementwise_op(t1, t2)
t2_ = StructuredSparseTensor(1.0 / t2_.physical, t2_.strides)
all_dims = list(range(t1_.ndim))
return einsum((t1_, all_dims), (t2_, all_dims), output=all_dims)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is problematic, we do not divide by a sparse tensor, or at least by a non-dense tensor. The line

t2_ = StructuredSparseTensor(1.0 / t2_.physical, t2_.strides)

Is essentially the pointwise function $x\to 1/x$ applied to t2. Note that it can be applied if and only if it is dense. Still, if t2 is dense (and even if it is a sst), we are good, so I am not sure how to solve this.

Comment on lines 130 to 132
def prepare_for_elementwise_op(
t1: Tensor | int | float, t2: Tensor | int | float
) -> tuple[StructuredSparseTensor, StructuredSparseTensor]:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is something fishy about the responsibility of this function. It seems to be a mix between tricking einsum into handling non sst Tensors and handling non-tensor inputs. The thing is we don't want to use einsum for these when we have non-tensor inputs (it is too much machinery).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I believe that the einsum implementation of most of those based on int or float are actually wrong. For instance mul is ..., ... -> ..., but the number of dimensions might not match if it is a scalar, in which case you would want to multiply the physical by the scalar.

Comment on lines 5 to 24
def solve_int(A: Tensor, B: Tensor, tol=1e-9) -> Tensor | None:
"""
Solve A X = B where A, B and X have integer dtype.
Return X if such a matrix exists and otherwise None.
"""

A_ = A.to(torch.float64)
B_ = B.to(torch.float64)

try:
X = torch.linalg.solve(A_, B_)
except RuntimeError:
return None

X_rounded = X.round()
if not torch.all(torch.isclose(X, X_rounded, atol=tol)):
return None

# TODO: Verify that the round operation cannot fail
return X_rounded.to(torch.int64)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the short term this seems good enough, but in the long term I think we'd want to either use another library to solve integer linear equations (SymPy, maybe others) or to implement our own solver in torch.

The reason is that computations with floating point numbers may be wrong with large stride values, and it's probably faster to solve something with the extra knowledge that it's integer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll probably end up coding that in C.

* Note that in python, x % 0 raises ZeroDivisionError. The
  implementation of mod_c matches this behavior when t2 is the zero
vector.
@PierreQuinton PierreQuinton changed the title Add StructuredSparseTensor Add SparseLatticedTensor Nov 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat New feature or request package: sparse

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants