Skip to content

RFC: clarifying buffer declaration and access - #63

Merged
areusch merged 9 commits into
apache:mainfrom
vinx13:clarify-buffer-access
May 11, 2022
Merged

RFC: clarifying buffer declaration and access#63
areusch merged 9 commits into
apache:mainfrom
vinx13:clarify-buffer-access

Conversation

@vinx13

@vinx13vinx13 commented Mar 18, 2022

Copy link
Copy Markdown
Member

In apache/tvm#9727 and RFC#39, we deprecated Load and Store to use BufferLoad and BufferStore instead in order to support generalized multi-dimensional physical buffer access. This is a follow-up that documents necessary clarifications, implications about the new buffer convention, as well as the post-hoc pass checklist.

Rendered version: https://github.com/vinx13/tvm-rfcs/blob/clarify-buffer-access/rfcs/0063-clarifying-buffer-declaration-and-access.md

cc @tqchen@Lunderberg@junrushao1994@csullivan@mbs-octoml@jroesch@areusch @wrongtest @Hzfengsy

Co-authored-by: Eric Lunderberg <Lunderberg@users.noreply.github.com>
@vinx13
vinx13force-pushed the clarify-buffer-access branch from 507c133 to 116cdc4CompareMarch 20, 2022 07:06
convention of `PrimFunc` and are translated to assertions of buffer shapes, strides, etc. in
runtime.

During the lowering process, although buffer accesses inside `PrimFunc` are flattened to match

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I have a proof-of-concept implementation of this removal at apache/tvm#10940. It is able to pass all tests in test_target_codegen_llvm.py, and I don't see any roadblocks for updating the other tests as well.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Nice. We can then consider moving to explicit DeclBuffer (mentioned in this RFC) to define the alias.

@areuschareusch left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

thanks @vinx13@Lunderberg for this clarifying RFC! did a fine-grained pass and attempted to clarify some of the wording per my understanding.

Comment threadrfcs/0063-clarifying-buffer-declaration-and-access.md Outdated
Comment threadrfcs/0063-clarifying-buffer-declaration-and-access.md Outdated
Comment threadrfcs/0063-clarifying-buffer-declaration-and-access.md Outdated
Comment threadrfcs/0063-clarifying-buffer-declaration-and-access.md Outdated
Comment threadrfcs/0063-clarifying-buffer-declaration-and-access.md Outdated
Comment threadrfcs/0063-clarifying-buffer-declaration-and-access.md Outdated
Comment threadrfcs/0063-clarifying-buffer-declaration-and-access.md Outdated
Comment threadrfcs/0063-clarifying-buffer-declaration-and-access.md Outdated
Comment threadrfcs/0063-clarifying-buffer-declaration-and-access.md
Comment threadrfcs/0063-clarifying-buffer-declaration-and-access.md Outdated
Co-authored-by: Andrew Reusch <areusch@gmail.com>

@vinx13vinx13 left a comment

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

@areusch Thanks for the great feedback, will update the RFC accordingly

- Buffer map of `PrimFunc`. This specifies how opaque parameters of type `T.handle` should be
interpreted as a buffer inside the `PrimFunc`. `T.handle` represents an opaque pointer (`void *`).
- `T.alloc_buffer` is used `S-TIR` to create and allocate a buffer.
- `T.buffer_decl` can be used to create a buffer alias by specifying the underlying data variable to

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Yes. In TVM script, it is T.buffer_decl and we have plan to rename it to T.decl_buffer

that has a vectorized type, or by using `Ramp` as an index into a buffer that has a scalar type.
For N-D buffer indices, it is possible that `Ramp` being used in multiple dimensions
(e.g. `A[Ramp(...), ..., Ramp(...)]` ). In this case the number of lanes of the data type of such
value is the product of each `Ramp`. We may want to limit `Ramp` to only the last dimension as

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

@Lunderberg has already sent follow up PR to limit Ramp to the last dimension. I'll update this sentence

for TIR transformations. Passes that rewrite buffers should clearly indicate how aliased buffers
are handled. For example, when changing the underlying layout of stored elements in a buffer, all
buffer aliases must also be updated. While buffer aliasing is typically free at runtime, this
imposes a cost for buffer aliasing both to compile times and development complexity.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

we don't have any alias analysis right now

- Buffer map of `PrimFunc`. This specifies how opaque parameters of type `T.handle` should be
interpreted as a buffer inside the `PrimFunc`. `T.handle` represents an opaque pointer (`void *`).
- `T.alloc_buffer` is used `S-TIR` to create and allocate a buffer.
- `T.buffer_decl` can be used to create a buffer alias by specifying the underlying data variable to

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ok, if you're using T. notation here, you mean TVMScript, right? in which case, can you update all occurrences to match what you would grep for if using TVMScript? right now it's a dead-end.


`T.buffer_decl` creates a buffer alias if the underlying data variable (`.data` field) overlaps with
another buffer. Buffer created via `alloc_buffer` always do not alias. Buffer aliases do not need
`Allocate` to create the data variable. Each data variable can be allocated via `Allocate` once.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ok, can you update this in the doc? you could simply state "Buffer aliases do not need Allocate to create the data variable--they may simply reuse the data variable from the Buffer being aliased."

We would like to discuss some examples of when it is safe to transform a buffer w.r.t. aliasing rules:

(1) reshape, (2) layout transform (e.g. swap indices), (3) compact.
- (1) reshape

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

i think proper numbered list syntax is like

1. reshape
2. layout transform ...
3. compact


(1) reshape, (2) layout transform (e.g. swap indices), (3) compact.

(1) is fine under aliasing as long as the low level memory is shared. (2) and (3) would need more

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

yeah that makes sense, can you update the RFC?

@areusch

Copy link
Copy Markdown
Contributor

@vinx13 let me know when this is ready for another look!

@vinx13

Copy link
Copy Markdown
MemberAuthor

@areusch it is ready for another look

@areuschareusch left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

thanks @vinx13, just a few things to ping on but otherwise no need to block on me.

- Buffer map of `PrimFunc`. This specifies how opaque parameters of type `T.handle` should be
interpreted as a buffer inside the `PrimFunc`. `T.handle` represents an opaque pointer (`void *`).
- `T.alloc_buffer` is used `S-TIR` to create and allocate a buffer.
- `T.buffer_decl` can be used to create a buffer alias by specifying the underlying data variable to

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

could you add a note so someone knows what to grep for post-future rename?


**Explicit `DeclBuffer` IR construct**

`T.buffer_decl` is not an explicit statement in TIR - There is no such node in TIR.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ping on this one?

for TIR transformations. Passes that rewrite buffers should clearly indicate how aliased buffers
are handled. For example, when changing the underlying layout of stored elements in a buffer, all
buffer aliases must also be updated. While buffer aliasing is typically free at runtime, this
imposes a cost for buffer aliasing both to compile times and development complexity.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ok, perhaps we could state that in RFC i guess? it seems pretty useful to have that if we make this change.

@vinx13

Copy link
Copy Markdown
MemberAuthor

@areusch added some minor updates based on the comments, see the last two commits

@vinx13vinx13 mentioned this pull request May 10, 2022

@areuschareusch left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

thanks for the updates and sorry for the long delay!

@areusch
areusch merged commit de4fe97 into apache:mainMay 11, 2022
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@vinx13@areusch@Lunderberg