Skip to content
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
848b6f6
Add tuning parameters with updated doc comments
AlexBrownAMD Jun 4, 2024
6ff49e1
SK Port: (Host) Debug settings and Grid Selector (#1)
bethune-bryant Jun 5, 2024
c85586d
Merge branch 'ROCm:develop' into StreamK
bethune-bryant Jun 6, 2024
f25ba0b
Stream-K kernel arguments, metadata, and launch grid code
AlexBrownAMD Jun 6, 2024
1e19915
Increase default max workspace for tensile tuning client
AlexBrownAMD Jun 6, 2024
223aedc
Increase default workspace for bench client (#2)
bethune-bryant Jun 6, 2024
e1e38a7
Merge branch 'ROCm:develop' into StreamK
bethune-bryant Jun 7, 2024
d0d4bc3
Merge remote-tracking branch 'origin' into StreamK
AlexBrownAMD Jun 12, 2024
e9a56b0
Merge remote-tracking branch 'origin/StreamK' into StreamK
AlexBrownAMD Jun 21, 2024
7809986
Update gitignore
AlexBrownAMD Jun 21, 2024
cbf4ef3
Option to disable GSU in kernels.
AlexBrownAMD Jun 21, 2024
b92f313
UpdatedSolutionStructs, reject cases and golbal accumulation code
AlexBrownAMD Jun 24, 2024
ca5221d
Stream-k code gen work in progress
AlexBrownAMD Jun 26, 2024
8f5a915
Some bug fixes and more work on persistent loop
AlexBrownAMD Jun 26, 2024
0d5cec7
Store branches and close persistent loop
AlexBrownAMD Jun 28, 2024
2296748
Add code for workspace SRD, working on partials write, some updates/f…
AlexBrownAMD Jul 2, 2024
ac84fa9
Support for predicate arithmetic intensity added on top of streamK br…
adityalj Jul 15, 2024
259f6b4
Write partials and some bug fixes
AlexBrownAMD Jul 16, 2024
a100b1f
Grid prediction (#4)
adityalj Jul 22, 2024
5ce3017
Fixup/partials, flag init, bug fixes
AlexBrownAMD Jul 22, 2024
6a50f3d
Enable sk grid and fix tile calculation
AlexBrownAMD Jul 22, 2024
4df66e5
Merge branch 'StreamK' into StreamKGen
AlexBrownAMD Jul 22, 2024
fc0f23d
Merge pull request #6 from AlexBrownAMD/StreamKGen
AlexBrownAMD Jul 23, 2024
16fa505
Some build fixes
AlexBrownAMD Jul 23, 2024
9e8fa21
Fix race condition on flag reset
AlexBrownAMD Jul 23, 2024
5642e5c
Flag point to input synchronizer
adityalj Jul 23, 2024
2f882d6
point flag to synchronizer
adityalj Jul 24, 2024
0c5159d
remove space allocated for flags
adityalj Jul 24, 2024
445e1f1
Some bug fixes, general case sgemm tests passing
AlexBrownAMD Jul 31, 2024
8367400
Merge pull request #7 from adityalj/flag_init
AlexBrownAMD Aug 12, 2024
f734836
SOme bug fixes
AlexBrownAMD Aug 16, 2024
dca3d24
Merge remote-tracking branch 'upstream/develop' into StreamKMerge
AlexBrownAMD Aug 19, 2024
593e98f
Merge fixes for stream-k
AlexBrownAMD Aug 21, 2024
3a96ecf
Some stream-k test files
AlexBrownAMD Aug 21, 2024
2c7b462
Merge remote-tracking branch 'upstream/develop' into StreamKMerge2
AlexBrownAMD Aug 21, 2024
7b84b91
Bug fixes from merge
AlexBrownAMD Aug 22, 2024
cfdaf49
Update targets for new tests
AlexBrownAMD Aug 23, 2024
44f2d35
Remove duplicate code and addreject for unsupported config
AlexBrownAMD Aug 23, 2024
e7d7d57
If stream-k enabled, force GSU=0
AlexBrownAMD Aug 23, 2024
bfbfde1
Bug fixes for SKXCCM and SK=2
AlexBrownAMD Aug 28, 2024
e6de95f
Fix race condition when resetting synchronizer flags
AlexBrownAMD Sep 6, 2024
fc61d87
Disable LRA backup, not needed for stream-k, and not compatible with …
AlexBrownAMD Sep 6, 2024
e304cf7
Small optimization from PR review
AlexBrownAMD Sep 6, 2024
256da9b
Add new test case based on race condition
AlexBrownAMD Sep 6, 2024
3bbeff9
Merge remote-tracking branch 'upstream/develop' into StreamKMerge2
AlexBrownAMD Sep 6, 2024
21abe72
Fix merge issue
AlexBrownAMD Sep 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ tags
.vscode

# build-in-source directory and documentation artifacts
build/
build*/
_build/
_images/
_static/
_templates/
_toc.yml
Tensile.egg-info

# matrices
*.csr
Expand Down
2 changes: 1 addition & 1 deletion clients/benchmarks/client_groupedgemm_fixed_mk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,7 @@ int test_hipblaslt(hipDataType in_datatype,
}

// Set User Preference attributes
uint64_t max_workspace_size = 32 * 1024 * 1024;
uint64_t max_workspace_size = 128 * 1024 * 1024;
void* d_workspace;
CHECK_HIP_ERROR(hipMalloc(&d_workspace, max_workspace_size));

Expand Down
2 changes: 1 addition & 1 deletion clients/benchmarks/client_sequence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ class LayerConfigIOGeneralSettings
uint32_t rotating = 0; // Size in MB
uint32_t cold_iters = 1000;
uint32_t iters = 10;
int64_t max_workspace_size = 32 * 1024 * 1024;
int64_t max_workspace_size = 128 * 1024 * 1024;
bool graph_mode = false;
};

Expand Down
48 changes: 29 additions & 19 deletions library/src/amd_detail/rocblaslt/src/tensile_host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1886,7 +1886,7 @@ rocblaslt_status makeArgument(rocblaslt_handle handle,
if(useUserArgs)
{
data->kernels = solution->solveGroupedGemmGPU(
data->problem.gemms, data->inputs, nullptr, workspace, stream);
data->problem.gemms, data->inputs, *hardware, nullptr, workspace, stream);
}
else
{
Expand Down Expand Up @@ -2016,7 +2016,7 @@ rocblaslt_status getDeviceUserArgumentsValuesFromContractionProblem(rocblaslt_ha
{
std::shared_ptr<TensileDataGroupedGemm> data
= std::static_pointer_cast<TensileDataGroupedGemm>(gemmData);
auto solution = library->getSolutionByIndex(data->algoIndex);
auto solution = library->getSolutionByIndex(*hardware, data->algoIndex);
auto& problem = data->problem.gemms[0];
if(problem.activationComputeType() == Tensile::DataType::Float)
{
Expand Down Expand Up @@ -2077,7 +2077,7 @@ rocblaslt_status runKernelFromNewDeviceUserArguments(rocblaslt_handle hand
for(auto& it : data->kernels)
{
uint8_t* arg = it.args.rawdata();
auto solution = library->getSolutionByIndex(data->algoIndex);
auto solution = library->getSolutionByIndex(*hardware, data->algoIndex);
if(solution->internalArgsSupport.useUniversalArgs)
{
if(deviceUserArgs != nullptr)
Expand Down Expand Up @@ -2144,11 +2144,11 @@ rocblaslt_status runKernelFromDeviceUserArguments(rocblaslt_handle h
// don't overwrite data->algoIndex = *solutionIndex; here
if(gemmType == rocblaslt::RocGemmType::ROCBLASLT_GROUPED_GEMM)
{
auto solution = library->getSolutionByIndex(*solutionIndex);
auto solution = library->getSolutionByIndex(*hardware, *solutionIndex);
std::shared_ptr<TensileDataGroupedGemm> data
= std::static_pointer_cast<TensileDataGroupedGemm>(gemmData);
auto kernel = solution->solveGroupedGemmGPU(
data->problem.gemms, data->inputs, deviceUserArgs, workspace, stream);
data->problem.gemms, data->inputs,*hardware, deviceUserArgs, workspace, stream);
status = hip2RocStatus(adapter->launchKernels(kernel, stream, nullptr, nullptr));
}
else
Expand Down Expand Up @@ -2187,7 +2187,8 @@ void _convertToHeuristicResultArray(
rocblaslt_matmul_heuristic_result heuristicResultsArray[],
int* returnAlgoCount,
size_t maxWorkSpaceBytes,
const Tensile::ContractionProblemGemm& problem)
const Tensile::ContractionProblemGemm& problem,
const Tensile::Hardware& hardware)
{
*returnAlgoCount = std::min((int)solutions.size(), requestedAlgoCount);
for(size_t i = 0; i < *returnAlgoCount; i++)
Expand All @@ -2199,7 +2200,7 @@ void _convertToHeuristicResultArray(
heuristicResultsArray[i].algo.max_workspace_bytes = maxWorkSpaceBytes;
heuristicResultsArray[i].algo.fallback = false;
heuristicResultsArray[i].state = rocblaslt_status_success;
heuristicResultsArray[i].workspaceSize = solution->requiredWorkspaceSize(problem);
heuristicResultsArray[i].workspaceSize = solution->requiredWorkspaceSize(problem, hardware);
}
for(size_t i = *returnAlgoCount; i < requestedAlgoCount; i++)
{
Expand Down Expand Up @@ -2296,7 +2297,8 @@ rocblaslt_status getBestSolutions(RocblasltContractionProblem const& prob,
heuristicResultsArray,
returnAlgoCount,
maxWorkSpaceBytes,
data->problem);
data->problem,
*hardware);

return rocblaslt_status_success;
}
Expand Down Expand Up @@ -2367,7 +2369,7 @@ rocblaslt_status getAllSolutions(MyProblem&
heuristicResults[i].algo.fallback = false;
heuristicResults[i].state = rocblaslt_status_success;
if constexpr(std::is_same<MyProblem, Tensile::ContractionProblemGemm>::value)
heuristicResults[i].workspaceSize = solution->requiredWorkspaceSize(prob);
heuristicResults[i].workspaceSize = solution->requiredWorkspaceSize(prob, *hardware);
else
heuristicResults[i].workspaceSize = 0;
i++;
Expand Down Expand Up @@ -2452,7 +2454,7 @@ rocblaslt_status
for(auto index : solutionIndex)
{
isOutOfBound = isOutOfBound && (index > lastSolutionIndex);
auto solution = library->getSolutionByIndex(index);
auto solution = library->getSolutionByIndex(*hardware, index);
if(!solution)
continue;
rocblaslt_matmul_heuristic_result result;
Expand Down Expand Up @@ -2546,7 +2548,7 @@ rocblaslt_status isSolutionSupported(rocblaslt_handle handle,
}
else
{
*workspaceSizeInBytes = solution->requiredWorkspaceSize(tensile_prob);
*workspaceSizeInBytes = solution->requiredWorkspaceSize(tensile_prob, *hardware);
}
}
else if constexpr(std::is_same<MyProblem, Tensile::ContractionProblemGroupedGemm>::value)
Expand Down Expand Up @@ -2581,7 +2583,7 @@ rocblaslt_status isSolutionSupported(rocblaslt_handle handle,

bool isSupported = true;
bool isNormalGemm = true;
auto problemWs = solution->requiredWorkspaceSizeGroupedGemm(tensile_prob.gemms);
auto problemWs = solution->requiredWorkspaceSizeGroupedGemm(tensile_prob.gemms, *hardware);
for(int i = 0; i < tensile_prob.gemms.size(); i++)
{
tensile_prob.gemms[i].setWorkspaceSize(algo->max_workspace_bytes);
Expand Down Expand Up @@ -2730,7 +2732,8 @@ rocblaslt_status getBestSolutions(rocblaslt_handle handle,
heuristicResults.data(),
&returnAlgoCount,
workspaceBytes,
data->problem);
data->problem,
*hardware);
}
else if(gemmType == rocblaslt::RocGemmType::ROCBLASLT_GROUPED_GEMM)
{
Expand All @@ -2755,7 +2758,8 @@ rocblaslt_status getBestSolutions(rocblaslt_handle handle,
heuristicResults.data(),
&returnAlgoCount,
workspaceBytes,
data->problem.gemms[0]);
data->problem.gemms[0],
*hardware);
}

return rocblaslt_status_success;
Expand Down Expand Up @@ -2811,6 +2815,10 @@ std::string getSolutionNameFromData(rocblaslt_handle handle,
int wgm = 0;
int solutionIndex = -1;

std::shared_ptr<Tensile::Hardware> hardware;

hardware = Tensile::hip::GetDevice(*deviceProp);

if(gemmType == rocblaslt::RocGemmType::ROCBLASLT_GEMM)
{
std::shared_ptr<TensileDataGemm> data = std::static_pointer_cast<TensileDataGemm>(gemmData);
Expand All @@ -2828,7 +2836,7 @@ std::string getSolutionNameFromData(rocblaslt_handle handle,
}
if(solutionIndex == -1)
return "";
auto solution = library->getSolutionByIndex(solutionIndex);
auto solution = library->getSolutionByIndex( *hardware, solutionIndex);
std::string modifiedString = "";
if(gsu != solution->sizeMapping.globalSplitU && gsu != 0)
{
Expand All @@ -2853,9 +2861,10 @@ std::string getKernelNameFromAlgoIndex(rocblaslt_handle handle, const rocblaslt_
std::shared_ptr<hipDeviceProp_t> deviceProp;

auto adapter = get_library_and_adapter(&library, &deviceProp, handle->device);

std::shared_ptr<Tensile::Hardware> hardware;
hardware = Tensile::hip::GetDevice(*deviceProp);
int* solutionIndex = (int*)algo.data;
auto solution = library->getSolutionByIndex(*solutionIndex);
auto solution = library->getSolutionByIndex(*hardware, *solutionIndex);
return solution->kernelName;
}

Expand All @@ -2865,9 +2874,10 @@ std::string getSolutionNameFromAlgoIndex(rocblaslt_handle handle, const rocblasl
std::shared_ptr<hipDeviceProp_t> deviceProp;

auto adapter = get_library_and_adapter(&library, &deviceProp, handle->device);

std::shared_ptr<Tensile::Hardware> hardware;
hardware = Tensile::hip::GetDevice(*deviceProp);
int* solutionIndex = (int*)algo.data;
auto solution = library->getSolutionByIndex(*solutionIndex);
auto solution = library->getSolutionByIndex(*hardware , *solutionIndex);
return solution->solutionName;
}

Expand Down
36 changes: 28 additions & 8 deletions tensilelite/Tensile/AsmStoreState.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class StoreState:
# the generation of the store code.
##############################################################################
class StoreConstConfig:
def __init__(self, kernelWriter, kernel, ss, gwvw, edge, beta, atomic):
def __init__(self, kernelWriter, kernel, ss, gwvw, edge, beta, atomic, isWorkspace=False):

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.

Don't we need to change halfDataRegPerVI (line 105).
It refers DestDataType.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

self.gwvw = gwvw
self.lsu = kernel["LocalSplitU"]

Expand Down Expand Up @@ -76,14 +76,18 @@ def __init__(self, kernelWriter, kernel, ss, gwvw, edge, beta, atomic):
self.numElementsPerBatchLimitedBySgprs = 1 # dummy value
#assert self.numElementsPerBatchLimitedBySgprs > 0, "numElementsPerBatchLimitedBySgprs=0 for %s"%self.kernelName

bpeC = kernelWriter.states.bpeCexternal
if isWorkspace:
bpeC = kernelWriter.states.bpeCinternal

if atomic:
# flat atomics have another VGPR to allow different data for return#
regsPerElement = 2 if kernel["BufferStore"] else (3 + 1) # + 1 for alignment
# The atomic loop processes multiple elements in single instruction
# so will use VGPR from consec elements? TODO
self.numVgprsPerDataPerVI = (1.0 * regsPerElement * kernelWriter.states.bpeCexternal) / kernelWriter.states.bpr
self.numVgprsPerDataPerVI = (1.0 * regsPerElement * bpeC) / kernelWriter.states.bpr
elif beta:
self.numVgprsPerDataPerVI = (1.0 * kernelWriter.states.bpeCexternal) / kernelWriter.states.bpr
self.numVgprsPerDataPerVI = (1.0 * bpeC) / kernelWriter.states.bpr
else:
self.numVgprsPerDataPerVI = 0.0

Expand All @@ -104,7 +108,7 @@ def __init__(self, kernelWriter, kernel, ss, gwvw, edge, beta, atomic):
self.lsuStartVgprOffset = 0

# StoreState constructor:
def __init__(self, kernelWriter, kernel, gwvw, edge, beta, atomic, elements):
def __init__(self, kernelWriter, kernel, gwvw, edge, beta, atomic, elements, isWorkspace=False):
self.kernelWriter = kernelWriter
self.kernel = kernel
self.lsu = kernel["LocalSplitU"]
Expand Down Expand Up @@ -158,7 +162,7 @@ def __init__(self, kernelWriter, kernel, gwvw, edge, beta, atomic, elements):
if not atomic and len(kernel["PackedC1IndicesX"]) == 1:
self.optSrdIncForRow = 1

if kernel["StoreRemapVectorWidth"]:
if kernel["StoreRemapVectorWidth"] and not isWorkspace:
self.optSrdIncForRow = 1

if kernel["ProblemType"]["UseInitialStridesCD"]:
Expand All @@ -173,7 +177,7 @@ def __init__(self, kernelWriter, kernel, gwvw, edge, beta, atomic, elements):
assert (not (self.optSingleColVgpr and self.optSharedColVgpr))


self.cfg = self.StoreConstConfig(kernelWriter, kernel, self, gwvw, edge, beta, atomic)
self.cfg = self.StoreConstConfig(kernelWriter, kernel, self, gwvw, edge, beta, atomic, isWorkspace)

# Use to detect new rows:
self.lastCoordOffset1 = 0
Expand Down Expand Up @@ -262,9 +266,22 @@ def __init__(self, kernelWriter, kernel, gwvw, edge, beta, atomic, elements):
# For detecting when we are running first batch
self.firstBatch = True

# TODO code migrated from globalWrite, comments outdated with respect to features like activation
# how many vgprs are needed for zero elements
# 2 for addressC in vgpr for addition - already checked out
# 2 for coord0,1 of thread - already checked out
# 2 for tmp - already checked out

# 5 = how many vgprs are needed per element (flat)
# - 2 for addr
# - 3 for GLOBAL_OFFSET_C calculation (can overlap below, therefore max)
# - if beta gwvw*rpe for new value
# - if atomic 2*rpe for old and cmp values

# Calculate numVgprsPerElement
# print("numVgprsPerAddr=%u, numVgprsPerDataPerVI=%u, numVgprPerValuC=%u"%(self.cfg.numVgprsPerAddr, self.cfg.numVgprsPerDataPerVI, self.cfg.numVgprPerValuC))
self.numVgprsPerElement = self.cfg.numVgprPerValuC*gwvw + self.cfg.numVgprsPerAddr + int(ceil(self.cfg.numVgprsPerDataPerVI * gwvw))
# TODO STREAM-K Update numVgprsPerElement for workspace
if kernel["GroupLoadStore"] and kernel["ProblemType"]["UseBeta"]:
self.numVgprsPerElement += self.cfg.numVgprsPerAddr
if kernel["ProblemType"]["UseE"] and (kernel["GlobalSplitU"] == 1):
Expand Down Expand Up @@ -377,7 +394,7 @@ def getStoreElementsInfoForBatch(self, kernel, batchElements):

return self.elementCoord0, self.elementCoord1

def setupStoreElementsForBatch(self, kernel, gwvw, batchElements, batchElementSgprs, isOptNLL, factorDim):
def setupStoreElementsForBatch(self, kernel, gwvw, batchElements, batchElementSgprs, isOptNLL, factorDim, isWorkspace=False):

self.elementAddr = []
self.elementDataE = []
Expand All @@ -394,6 +411,9 @@ def setupStoreElementsForBatch(self, kernel, gwvw, batchElements, batchElementSg
#generate elementCoord0/1
self.getStoreElementsInfoForBatch(kernel, batchElements)
kw = self.kernelWriter
dataType = kernel["ProblemType"]["DestDataType"]
if isWorkspace:
dataType = kernel["ProblemType"]["ComputeDataType"]

biasVgprMap = {}
scaleAVecVgprMap = {}
Expand Down Expand Up @@ -514,7 +534,7 @@ def setupStoreElementsForBatch(self, kernel, gwvw, batchElements, batchElementSg
if self.cfg.halfDataRegPerVI:
# TODO- check (H,H,H,H,S,S)
if kernel["ProblemType"]["HighPrecisionAccumulate"] and \
(kernel["ProblemType"]["DestDataType"].isBFloat16() or kernel["ProblemType"]["DestDataType"].isHalf()):
(dataType.isBFloat16() or dataType.isHalf()):
data = kw.vgprPool.checkOutAligned(int(2*self.cfg.numVgprsPerDataPerVI*self.cfg.gwvw), \
int(ceil(int(2*self.cfg.numVgprsPerDataPerVI*self.cfg.gwvw))), "writeBatch-data for ei=%u and ei=%u"%(elementIdx,elementIdx+1), preventOverflow=not isOptNLL)
else:
Expand Down
Loading