This is an archive of the discontinued LLVM Phabricator instance.

[mlir][CRunnerUtils] Fix iterators accessing MemRefs with non-zero offset
ClosedPublic

Authored by ubfx on Aug 3 2023, 8:14 AM.

Details

Summary

MemRef descriptors contain - among others - a field called alignedPtr or data and a field called offset. The actual buffer of the MemRef starts at offset elements after alignedPtr. In the CRunnerUtils, there exist helper classes to iterate over MemRefs' elements but the offset is not handled consistently so that accessing a MemRef with an offset != 0 via an iterator will lead to incorrect results.

The problem is that "offset" can be understood in two ways, firstly as the offset of the beginning of the MemRef with respect to the alignedPtr, ie what the offset field means in the MemRef descriptor, and secondly as the offset of some element within the MemRef relative to the first element of the MemRef, which could more accurately be called something like linearIndex.

The offset field within StridedMemRefIterator and DynamicMemRefIterator are interpreted the first way, therefore the offsets passed to the constructors of these classes need to account for the already existing offset in the descriptor on top of any potential "shift" within the MemRef.
This patch takes care of that and adds some basic tests that catch problems with indexing MemRefs with an offset.

Diff Detail

Event Timeline

ubfx created this revision.Aug 3 2023, 8:14 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 3 2023, 8:14 AM
ubfx requested review of this revision.Aug 3 2023, 8:14 AM
ubfx updated this revision to Diff 546886.Aug 3 2023, 8:16 AM

add newline at end of file

ubfx added a subscriber: mscuttari.EditedAug 3 2023, 8:21 AM

Tagging @mscuttari and @mehdi_amini who have last worked on this

Thanks for the patch. I am away from home though, I will try giving a look next week!

Thanks! What we floated with @ftynse recently was whether this offset was really needed or if we could just remove it entirely, we haven't articulated a good use case why it exists: thoughts?

ubfx added a comment.Aug 9 2023, 12:12 PM

we haven't articulated a good use case why it exists: thoughts?

If I had to make a case for the offset, I would argue that it is the only way to allow the user to do custom arithmetic on the memref "pointer", before it actually is lowered to a pointer. If we want to support something like extract_strided_metadata -> do something -> reinterpret_cast, it seems like offset fits in with sizes and strides because it's also given in the denomination of the memref element size. I'm not sure whether such a use case should be encouraged but if we want to be able to move around the pointer via something like reinterpret_cast, then we need something like the offset to hide away the element size.

ubfx added a comment.Aug 30 2023, 6:26 AM

friendly ping 🙏

mehdi_amini accepted this revision.Aug 30 2023, 10:45 PM

The direction in https://github.com/llvm/llvm-project/issues/64334 is to remove the offset.
That said we can fix this in the meantime.

This revision is now accepted and ready to land.Aug 30 2023, 10:45 PM
ubfx added a comment.Sep 1 2023, 12:36 AM

Thank you, Mehdi. While I can't really weigh in on the very in-depth discussion about the consequences of restructuring the Memref descriptors, I have found a few bugs around the MemrefToLLVM / Memref interface to C / Python and submitted patches for them. I noticed that these bugs are in pretty core functionality (i.e. LLVM lowering of memref.copy, memref.transpose, etc.) but they had not been caught earlier because we don't seem to have tests that check (dynamically) whether the generated LLVMIR actually does what the Memref Ops demand.

We have unit tests for the ExecutionEngine that run generated LLVMIR but they are checking core functionality of the ExecutionEngine / Runtime and not the correctness of the lowering of higher level Ops (in this case memref). Do you think it would make sense to add such unittests, which lower to LLVMIR, run the IR using the ExecutionEngine and then check the behavior? I could provide a few of these and maybe they would be useful to ensure the transition to removing the offset field goes smoothly. I just wasn't sure whether such unittests are even desired because the unittests/Conversion folder is pretty empty.

btw: could you commit this revision for me?

bugs I'm talking about:
https://reviews.llvm.org/D156126
https://reviews.llvm.org/D158494
https://reviews.llvm.org/D159290