-
Notifications
You must be signed in to change notification settings - Fork 3.8k
[Refactor] Enforce attaching storage scope to PointerType #8366
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
0c9a912 to
79c6e8e
Compare
|
Thanks @masahi . seems there are still testcases that we need to fix |
29ae80c to
c443506
Compare
|
@tqchen I've hit an issue in
So I tried to replace this line by something like Creating a new variable also doesn't work because the old What should we do about this? |
|
In this particular case, we might need to create a new buffer var and remap the use of the old buffer vars to new one |
553402d to
73c6496
Compare
9f37d55 to
ba670d3
Compare
426b573 to
cb697d8
Compare
Yes this is one of my follow-up items. Apparently |
| namespace tvm { | ||
| namespace tir { | ||
|
|
||
| class UpdatePointerStorageScope : public StmtExprMutator { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is used by passes that require modifying storage scopes after buffer creation. Currently used by lower_thread_allreduce.cc and lower_warp_memory.cc.
|
|
||
|
|
||
| @register | ||
| class BufferVarDef(SpecialStmt): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @spectrometerHBH for tvmscript changes. This is for distinguishing a normal variable from a buffer variable. The latter one requires storage scope. See the change in test_tvmscript_roundtrip.py. The tvm script printer was also updated.
|
All tests passed, ready for review. |
| for (size_t idx = 0; idx < size; ++idx) { | ||
| DataType dtype = reduces[idx]->dtype; | ||
| res_handles[idx] = Var("reduce_temp" + std::to_string(idx), PointerType(PrimType(dtype))); | ||
| res_handles[idx] = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shall we remove storage_scope attr here
| body = AttrStmt(res_handles[idx - 1], tir::attr::storage_scope, StringImm("local"), body); |
| AttrStmt(normal_res_handles[idx - 1], tir::attr::storage_scope, StringImm("local"), body); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removal of AttrStmt creation with attr::storage_scope will come after this PR, where all attr::storage_scope usages will be removed at once. A lot of places in the code base still assume the existence of AttrStmt with attr::storage_scope, so I don't want to remove some AttrStmt while leaving others in this PR.
| namespace tvm { | ||
| namespace tir { | ||
|
|
||
| class UpdatePointerStorageScopeAllReduce final : public UpdatePointerStorageScope { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we merge this pass with UpdatePointerStorageScope by adding check for attr::volatile_scope in VisitStmt_(const AttrStmtNode*)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This attr::volatile_scope is created inside this AllocateNode visitor. A visitor for AttrStmtNode don't get to see this.
kparzysz-quic
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
csullivan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@masahi Thanks for the great and healthy refactor!
| @@ -0,0 +1,91 @@ | |||
| /* | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to also update lower_device_storage_access_info.cc to use the PointerType storage scope in this PR as well.
With a custom storage scope used in a cache_read stage, e.g.
s.cache_read(data, "global.texture", [OL])
I see that lower_device_storage_access_info.cc#L72 is unhappy with the scope tag.
Check failed: (e.info.defined()) is false: Cannot find memory info of global.texture
and this ICHECK failure does not occur on main.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm interesting. attr::storage_scope and the PointerType should have the same storage scope, by the invariant at
Lines 64 to 73 in 3e5e0ef
| if (attr_key == attr::storage_scope) { | |
| const VarNode* buf = node.as<VarNode>(); | |
| ICHECK(buf); | |
| const auto* ptr_type = buf->type_annotation.as<PointerTypeNode>(); | |
| ICHECK(ptr_type) << "The provided variable is not of pointer type"; | |
| auto attr_scope = value.as<StringImmNode>()->value; | |
| ICHECK_EQ(attr_scope, ptr_type->storage_scope) | |
| << "Storage scopes attached to AttrStmt and buffer var are different. " << attr_scope | |
| << ", " << ptr_type->storage_scope; | |
| } |
A possible explanation is that the value of scope.tag.length() at https://github.com/apache/tvm/blob/main/src/tir/transforms/lower_device_storage_access_info.cc#L70 is different between main and this branch. In this case, GetMemoryInfo assumes that a packed function tvm.info.mem.global.texture is defined, but I don't find it anywhere.
Do you have a repro script?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @masahi. I tracked this issue down to the buffer storage scope being set to global and removing the scope tag. Previously this was fine as the AttrStmtNode realize_scope annotation was used during texture lowering.
This demonstrate the value in removing the buffer storage scope in favor of consolidating around the PointerType's storage_scope. I look forward to that PR! Thanks again for this change.
|
will let @vinx13 manage this PR |
csullivan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
Thanks @masahi @kparzysz-quic @csullivan @tqchen this is merged |
* Add storage scope to ProducerRealize, always create a buffer with scope * update schedule_ops.cc * update schedule_postproc_to_primfunc.cc * restore more realize_scope This reverts commit b66c3ba. * make the default scope be "" instead of None in ir builder * restore realize_scope visit in storage_flatten.cc * update storage_access.cc * make sure buffer var is of PointerType in ir builder This reverts commit e650b6c. * enforce default storage scope of global * added remap pass but does not work yet * fixed all reduce issue This reverts commit 8e20003. * simplify * trying mitigation for aot test * merge remaining changes from initial branch * remove use of attr::storage_scope from codegen * restore a visit to AttrStmt with attr::storage_scope in storage_rewrite * disable check * lint fix * revert default scope to "" * format * fix volatile access to shared mem in lower all reduce * fixed gpu coorporative load/store test * pass storage scope to PointerType in tvm script parser This reverts commit 99cfb9d18781dcfdea169d920450f9063ab18b6b. * fixed tvmscript roundtrip test * fixed tir flatten buffer test * fixed test_tir_transform_hoist_if.py * use storage scope global by default in aot_executor_codegen.cc * add missing default storage scope in create_primfunc.cc * restore StorageInfo struct in llvm backend * UpdateStorageScope -> WithStorageScope * fixed lower warp memory test * GetStorageScope -> GetPtrStorageScope * Enable storage scope invariant check in AttrStmt constructor * remove GetPtrStorageScope and WithStorageScope from public header * move RemapStorageScope to its own file * add more method to RemapStorageScope * update lower_thread_allreduce to use RemapStorageScope * RemapStorageScope -> UpdatePointerStorageScope * remove realize_scope from hybrid script * removed realize_scope in schedule_ops * remove realize_scope from schedule_postproc_to_primfunc * remove remaining realize_scope usage from schedule_ops.cc * remove realize_scope usage from storage_flatten.cc * fixed test_tir_transform_lower_warp_memory.py following realize_scope removal * Add storage scope to ProducerRealize, always create a buffer with scope * update schedule_ops.cc * update schedule_postproc_to_primfunc.cc * restore more realize_scope This reverts commit b66c3ba. * make the default scope be "" instead of None in ir builder * restore realize_scope visit in storage_flatten.cc * update storage_access.cc * make sure buffer var is of PointerType in ir builder This reverts commit e650b6c. * enforce default storage scope of global * added remap pass but does not work yet * fixed all reduce issue This reverts commit 8e20003. * simplify * trying mitigation for aot test * merge remaining changes from initial branch * remove use of attr::storage_scope from codegen * restore a visit to AttrStmt with attr::storage_scope in storage_rewrite * disable check * lint fix * revert default scope to "" * format * fix volatile access to shared mem in lower all reduce * fixed gpu coorporative load/store test * pass storage scope to PointerType in tvm script parser This reverts commit 99cfb9d18781dcfdea169d920450f9063ab18b6b. * fixed tvmscript roundtrip test * fixed tir flatten buffer test * fixed test_tir_transform_hoist_if.py * use storage scope global by default in aot_executor_codegen.cc * add missing default storage scope in create_primfunc.cc * restore StorageInfo struct in llvm backend * UpdateStorageScope -> WithStorageScope * fixed lower warp memory test * GetStorageScope -> GetPtrStorageScope * Enable storage scope invariant check in AttrStmt constructor * remove GetPtrStorageScope and WithStorageScope from public header * move RemapStorageScope to its own file * add more method to RemapStorageScope * update lower_thread_allreduce to use RemapStorageScope * RemapStorageScope -> UpdatePointerStorageScope * remove realize_scope from hybrid script * removed realize_scope in schedule_ops * remove realize_scope from schedule_postproc_to_primfunc * remove remaining realize_scope usage from schedule_ops.cc * remove realize_scope usage from storage_flatten.cc * fixed test_tir_transform_lower_warp_memory.py following realize_scope removal * Address comments * Remove blank line diff Co-authored-by: Masahiro Masuda <masahi@129@gmail.com> Co-authored-by: masa <masa@pop-os.localdomain>
* Add storage scope to ProducerRealize, always create a buffer with scope * update schedule_ops.cc * update schedule_postproc_to_primfunc.cc * restore more realize_scope This reverts commit b66c3ba. * make the default scope be "" instead of None in ir builder * restore realize_scope visit in storage_flatten.cc * update storage_access.cc * make sure buffer var is of PointerType in ir builder This reverts commit e650b6c. * enforce default storage scope of global * added remap pass but does not work yet * fixed all reduce issue This reverts commit 8e20003. * simplify * trying mitigation for aot test * merge remaining changes from initial branch * remove use of attr::storage_scope from codegen * restore a visit to AttrStmt with attr::storage_scope in storage_rewrite * disable check * lint fix * revert default scope to "" * format * fix volatile access to shared mem in lower all reduce * fixed gpu coorporative load/store test * pass storage scope to PointerType in tvm script parser This reverts commit 99cfb9d18781dcfdea169d920450f9063ab18b6b. * fixed tvmscript roundtrip test * fixed tir flatten buffer test * fixed test_tir_transform_hoist_if.py * use storage scope global by default in aot_executor_codegen.cc * add missing default storage scope in create_primfunc.cc * restore StorageInfo struct in llvm backend * UpdateStorageScope -> WithStorageScope * fixed lower warp memory test * GetStorageScope -> GetPtrStorageScope * Enable storage scope invariant check in AttrStmt constructor * remove GetPtrStorageScope and WithStorageScope from public header * move RemapStorageScope to its own file * add more method to RemapStorageScope * update lower_thread_allreduce to use RemapStorageScope * RemapStorageScope -> UpdatePointerStorageScope * remove realize_scope from hybrid script * removed realize_scope in schedule_ops * remove realize_scope from schedule_postproc_to_primfunc * remove remaining realize_scope usage from schedule_ops.cc * remove realize_scope usage from storage_flatten.cc * fixed test_tir_transform_lower_warp_memory.py following realize_scope removal * Add storage scope to ProducerRealize, always create a buffer with scope * update schedule_ops.cc * update schedule_postproc_to_primfunc.cc * restore more realize_scope This reverts commit b66c3ba. * make the default scope be "" instead of None in ir builder * restore realize_scope visit in storage_flatten.cc * update storage_access.cc * make sure buffer var is of PointerType in ir builder This reverts commit e650b6c. * enforce default storage scope of global * added remap pass but does not work yet * fixed all reduce issue This reverts commit 8e20003. * simplify * trying mitigation for aot test * merge remaining changes from initial branch * remove use of attr::storage_scope from codegen * restore a visit to AttrStmt with attr::storage_scope in storage_rewrite * disable check * lint fix * revert default scope to "" * format * fix volatile access to shared mem in lower all reduce * fixed gpu coorporative load/store test * pass storage scope to PointerType in tvm script parser This reverts commit 99cfb9d18781dcfdea169d920450f9063ab18b6b. * fixed tvmscript roundtrip test * fixed tir flatten buffer test * fixed test_tir_transform_hoist_if.py * use storage scope global by default in aot_executor_codegen.cc * add missing default storage scope in create_primfunc.cc * restore StorageInfo struct in llvm backend * UpdateStorageScope -> WithStorageScope * fixed lower warp memory test * GetStorageScope -> GetPtrStorageScope * Enable storage scope invariant check in AttrStmt constructor * remove GetPtrStorageScope and WithStorageScope from public header * move RemapStorageScope to its own file * add more method to RemapStorageScope * update lower_thread_allreduce to use RemapStorageScope * RemapStorageScope -> UpdatePointerStorageScope * remove realize_scope from hybrid script * removed realize_scope in schedule_ops * remove realize_scope from schedule_postproc_to_primfunc * remove remaining realize_scope usage from schedule_ops.cc * remove realize_scope usage from storage_flatten.cc * fixed test_tir_transform_lower_warp_memory.py following realize_scope removal * Address comments * Remove blank line diff Co-authored-by: Masahiro Masuda <masahi@129@gmail.com> Co-authored-by: masa <masa@pop-os.localdomain>
Right now, storage scope information is scattered across different places. This PR proposes to make
storage_scopein PointerType, introduced in #8017, be the single source of truth. This enables eachAllocate,Store,Loadnodes to directly access its storage scope through its associated buffer variable, rather than viaattr::stroage_scope+ a map betweenVarand storage scope as currently done today (for example,tvm/src/tir/transforms/thread_storage_sync.cc
Line 341 in 8131364
The main changes are:
schedule_ops.cc, attach storage scope information toProduceRealizeNode, rather than creatingAttrStmtwithtir::attr::realize_scopescope.schedule_postproc_to_primfunc.cc, always create a newBufferusing storage scope information inProduceRealizeNode. This ensures thatPointerTypeassociated with the new buffer has always storage scope information attached.AllocateNodedirectly, and removeattr::storage_scopeandattr::realize_scopewhen they are no longer needed.Building on this PR, I'll send the following changes later:
attr::storage_scopeBufferclasstvm/include/tvm/tir/buffer.h
Lines 70 to 71 in 2cca934