This is an archive of the discontinued LLVM Phabricator instance.

[mlir][sparse] first general insertion implementation with pure codegen
ClosedPublic

Authored by aartbik on Nov 4 2022, 12:27 PM.

Details

Summary

This revision generalizes lowering the sparse_tensor.insert op into actual code that directly operates on the memrefs of a sparse storage scheme. The current insertion strategy does *not* rely on a cursor anymore, with introduces some testing overhead for each insertion (but still proportional to the rank, as before). Over time, we can optimize the code generation, but this version enables us to finish the effort to migrate from library to actual codegen.

Things to do:
(1) carefully deal with (un)ordered and (not)unique
(2) omit overhead when not needed
(3) optimize and specialize
(4) try to avoid the pointer "cleanup" (at HasInserts), and make sure the storage scheme is consistent at every insertion point (so that it can "escape" without concerns).

Diff Detail

Event Timeline

aartbik created this revision.Nov 4 2022, 12:27 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 4 2022, 12:27 PM
aartbik requested review of this revision.Nov 4 2022, 12:27 PM
aartbik edited the summary of this revision. (Show Details)
aartbik edited the summary of this revision. (Show Details)Nov 4 2022, 1:07 PM
aartbik edited the summary of this revision. (Show Details)
Peiming added inline comments.Nov 7 2022, 2:41 PM
mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorCodegen.cpp
375

So, the current implementation only works for sorted dimension, right?

Otherwise you will need a loop the check presence here, right?

aartbik added inline comments.Nov 7 2022, 2:59 PM
mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorCodegen.cpp
375

Yes. It assumes that insert "behaves well" so that (1) we sort the indices before the insertion chains happens for sorted storage OR (2) the data structure allows for the appending behavior (so, unsorted COO works as well). See L471 for a comment on this.

I agree the exact specs are a bit vague (but no more than our current lib impl), but as long as we control the insertion chain that is generated, we can make sure it keeps working as we refine it more and more. Of course, over time we need to make sure that any incoming MLIR that uses insert directly also works ;-)

Peiming added inline comments.Nov 7 2022, 2:59 PM
mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorCodegen.cpp
489

Why don't you need an append = true here?

aartbik added inline comments.Nov 7 2022, 3:06 PM
mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorCodegen.cpp
489

Ah, append is set by genCompressed. It is passed by reference.

I thought I had documented that really well (and had probably done so at one point ;-)
but can't find this anymore.

I will add comments to make that much more clear!

Peiming added inline comments.Nov 7 2022, 3:06 PM
mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorCodegen.cpp
449

Oh, it is set here...

But is it needed? This seems to prepare the next dim, which is one iteration ahead of the insertion code (L486), will this again be set properly there?

aartbik updated this revision to Diff 473809.Nov 7 2022, 3:08 PM

doc append change better

Peiming added inline comments.Nov 7 2022, 3:09 PM
mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorCodegen.cpp
489

Yeah, I saw it, but is it really need, what you really care is whether the last dim is dense or not, right? Can it be simplified into

append = isDenseDim(lastdim)?

aartbik marked an inline comment as done.Nov 7 2022, 3:10 PM
aartbik added inline comments.
mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorCodegen.cpp
449

Yeah, it is needed. When we hit a "linearized" dense pre-allocation, we insert (append==false). In all other cases we simply append. This way, we avoid the push_back x linear we used to do in the support lib for preparing the proper dense dimensions.

aartbik marked an inline comment as done.Nov 7 2022, 3:26 PM
aartbik added inline comments.
mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorCodegen.cpp
489

No, think

CSR -> level 1 has n+1 preallocated pointers, and we directly insert into those

DSCR -> level 1 has nothing preallocated, and we must append

Peiming added inline comments.Nov 7 2022, 4:22 PM
mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorCodegen.cpp
489

But the only read on append I found (except assertion) is at L522, which is only related to the the dimLevelType of the last dim.

aartbik added inline comments.Nov 7 2022, 5:01 PM
mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorCodegen.cpp
489

Yeah, that is the only "prod" use. We also have an assert to guard against strange cases (e.g. singleton without compressed outer). Those should of course be rejected with proper type verification, but I am guarding against it to make sure we never hit that case.

aartbik updated this revision to Diff 474041.Nov 8 2022, 10:08 AM

added dense test for insert vs append (with assert on append)
rebased with main

aartbik updated this revision to Diff 474050.Nov 8 2022, 11:05 AM

removed append

Peiming accepted this revision.Nov 8 2022, 1:06 PM
This revision is now accepted and ready to land.Nov 8 2022, 1:06 PM