-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
[Refactor] Enforce attaching storage scope to PointerType #8366
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
.
@@ -491,6 +491,22 @@ def var(dtype, span): | |||
super().__init__(var, def_symbol=True) | |||
|
|||
|
|||
@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. |
@@ -177,7 +178,8 @@ Stmt MakeCrossThreadReduction(const ComputeOpNode* self, const Stage& stage, | |||
std::vector<Var> res_handles(size); | |||
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.
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
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 |
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@[email protected]> Co-authored-by: masa <[email protected]>
* 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@[email protected]> Co-authored-by: masa <[email protected]>
Right now, storage scope information is scattered across different places. This PR proposes to make
storage_scope
in PointerType, introduced in #8017, be the single source of truth. This enables eachAllocate
,Store
,Load
nodes to directly access its storage scope through its associated buffer variable, rather than viaattr::stroage_scope
+ a map betweenVar
and 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 creatingAttrStmt
withtir::attr::realize_scope
scope.schedule_postproc_to_primfunc.cc
, always create a newBuffer
using storage scope information inProduceRealizeNode
. This ensures thatPointerType
associated with the new buffer has always storage scope information attached.AllocateNode
directly, and removeattr::storage_scope
andattr::realize_scope
when they are no longer needed.Building on this PR, I'll send the following changes later:
attr::storage_scope
Buffer
classtvm/include/tvm/tir/buffer.h
Lines 70 to 71 in 2cca934