Repository navigation
Stream-k initial support - #1035
Conversation
Modularize GSU code so it is more contained, reduces branch points in KernelWriter code. Fix a temp register allocation bug. Fix alignment of some registers rather than rely on a specific order.
#3) * Support for predicate arithmetic intensity added on top of streamK branch in Alex's repo
* Analytical grid size prediction model for Stream-K
Porting code gen changes for stream-k
Flag init
nakajee
left a comment
There was a problem hiding this comment.
First round review. I will spend more time later...
| ############################################################################## | ||
| class StoreConstConfig: | ||
| def __init__(self, kernelWriter, kernel, ss, gwvw, edge, beta, atomic): | ||
| def __init__(self, kernelWriter, kernel, ss, gwvw, edge, beta, atomic, isWorkspace=False): |
There was a problem hiding this comment.
Don't we need to change halfDataRegPerVI (line 105).
It refers DestDataType.
There was a problem hiding this comment.
I think line 105 is OK. It is just checking if the write target is a half type (and excluding 8-bit types). The isWorkspace parameter makes bpeC use internal compute size instead of external write size so numVgprsPerDataPerVI is correct for the partials write case.
| @@ -0,0 +1,58 @@ | |||
|
|
|||
| GlobalParameters: | |||
There was a problem hiding this comment.
I think we need skip here.
This should be only for gfx9xx
There was a problem hiding this comment.
Good catch, just posted a fix for this this test as well as the other stream-k tests that were added
| * `(n + d - 1)` would overflow. | ||
| */ | ||
| template <typename N, typename D> | ||
| __device__ __host__ inline constexpr N safe_ceil_div(N n, D d) |
There was a problem hiding this comment.
Might be able to use ceilDivide: https://github.com/ROCm/hipBLASLt/blob/fecd96c2ecb4064aa3c11610207b565605061ecd/tensilelite/Tensile/TensileInstructions/Utils.py#L195C5-L195C15, safe_ceil_div is probably better version of the implementation.
|
I tried HHS TN + StreamK: [0,1,2,3] but I see some issues. (2) error This is the folkparameters I tried. |
|
Please make sure all CI tests pass on your local node
|
| module.add(VReadfirstlaneB32(dst=sgpr(tmpSgpr+2), src=vgpr("Serial"), comment="Wave 0 updates flags")) | ||
| module.add(SCmpEQU32(src0=sgpr(tmpSgpr+2), src1=0, comment="Check for wave 0")) | ||
| module.add(SCBranchSCC0(labelName=skipFlagReset.getLabelName(), comment="Skip flag reset")) | ||
| module.add(SMovB32(dst=sgpr(tmpSgpr+2), src=0, comment="flag data")) |
There was a problem hiding this comment.
Small optimization.
tmpSgpr+2 is already 0 here based on the above condition.
We can remove SMovB32.
There was a problem hiding this comment.
Good catch, just posted an update
| skipFlagReset = Label(label=writer.labels.getNameInc("SK_SkipFlagReset"), comment="") | ||
| module.add(VReadfirstlaneB32(dst=sgpr(tmpSgpr+2), src=vgpr("Serial"), comment="Wave 0 updates flags")) | ||
| module.add(SCmpEQU32(src0=sgpr(tmpSgpr+2), src1=0, comment="Check for wave 0")) | ||
| module.add(SCBranchSCC0(labelName=skipFlagReset.getLabelName(), comment="Skip flag reset")) |
There was a problem hiding this comment.
Quick question.
Why we need this code only for tensilelite?
I did not see it in Tensile.
There was a problem hiding this comment.
In Tensile the synchronization flags are stored in the workspace, which is supplied by the user and could contain any values, so there is a pre-kernel that initializes the flags to 0.
In TensileLite the flags are stored in the Synchronizer buffer which is kept in the handle and initialized to 0. In this case we also have to reset the flags to 0 after it they have been read so that they're ready for the next kernel to run. The first version on this PR had all 4 wavefronts in a workgroup doing the s_store to the flag, which was creating a race condition between the WG doing the partial tile setting it to 1 and the WG doing the fixup resetting it to 0. The kernel would sometimes end with some flags set to 1 instead of 0 causing kernels that run afterwards to fail.
This update changes it so only wavefront 0 updates the flag value (and wavefronts in a WG are still synchronized with a barrier to ensure all partial data is fully written before setting the flag)
There was a problem hiding this comment.
I just added one more test file based on the test that most easily reproduced the race condition
|
Thanks for your update. |
| std::shared_ptr<hipDeviceProp_t> deviceProp; | ||
|
|
||
| auto adapter = get_library_and_adapter(&library, &deviceProp, handle->device); | ||
| <<<<<<< HEAD |
There was a problem hiding this comment.
Thanks, got it fixed
| std::shared_ptr<hipDeviceProp_t> deviceProp; | ||
|
|
||
| auto adapter = get_library_and_adapter(&library, &deviceProp, handle->device); | ||
| <<<<<<< HEAD |
|
Finished running tensilelite tox tests, working on hipblaslt-test =================================================================================== 75 passed, 31 skipped, 44 warnings in 7744.02s (2:09:04) ==================================================================================== |
nakajee
left a comment
There was a problem hiding this comment.
Thanks for your update.
Looks good.
|
All hipblaslt-test test cases passing as well: [----------] Global test environment tear-down |
This PR introduces initial stream-k support into hipBLASLt. SGEMM, HGEMM, and BGEMM have been validated with a large number of parameter combinations and problem sizes, and this PR includes some new CI tests for these problem types. The stream-k algorithm helps deliver improved and stable performance with smaller library size. For full details, see the presentations or paper.
Most of the code changes for stream-k are isolated in a component class to help with code readability. Since stream-k is not compatible with GSU, all the GSU related code has also been moved from the KernelWriter classes into it's own component class, and an additional setting has been added to allow generating kernels with GSU disabled (GSU=0 disables it, GSU=1 is still the default, a new CI test for both settings is included). A component for persistent looping has also been added since stream-k operates on a loop. Descriptions of how to use the stream-k options and run-time environment variables are included in the comments in Common.py.
Full stream-k support in hipBLASLt is still a work in progress, and this PR is meant to introduce the initial core functionality. There are a number of known issues that I will work in in future PRs and there are tickets to track, including: