CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
344 lines
13 KiB
C++
344 lines
13 KiB
C++
/*******************************************************************************
|
|
*
|
|
* MIT License
|
|
*
|
|
* Copyright (C) 2019-2023 Advanced Micro Devices, Inc. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*
|
|
*******************************************************************************/
|
|
#include <Tensile/UserDrivenTuningParser.hpp>
|
|
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <utility>
|
|
|
|
namespace Tensile
|
|
{
|
|
int dataTypeSize(DataType dt)
|
|
{
|
|
switch(dt)
|
|
{
|
|
case DataType::Int8:
|
|
return 1;
|
|
|
|
case DataType::Half:
|
|
case DataType::BFloat16:
|
|
return 2;
|
|
|
|
case DataType::Float:
|
|
case DataType::Int32:
|
|
return 4;
|
|
|
|
case DataType::Double:
|
|
case DataType::ComplexFloat:
|
|
return 8;
|
|
|
|
case DataType::ComplexDouble:
|
|
return 18;
|
|
|
|
default:
|
|
case DataType::None:
|
|
return 0;
|
|
};
|
|
}
|
|
|
|
DataType convertToDataType(const std::string& DataTypeStr)
|
|
{
|
|
return DataTypeStr == "f16_r" || DataTypeStr == "h" ? DataType::Half
|
|
: DataTypeStr == "f32_r" || DataTypeStr == "s" ? DataType::Float
|
|
: DataTypeStr == "f64_r" || DataTypeStr == "d" ? DataType::Double
|
|
: DataTypeStr == "bf16_r" ? DataType::BFloat16
|
|
: DataTypeStr == "f16_c" ? DataType::None
|
|
: DataTypeStr == "f32_c" || DataTypeStr == "c" ? DataType::ComplexFloat
|
|
: DataTypeStr == "f64_c" || DataTypeStr == "z" ? DataType::ComplexDouble
|
|
: DataTypeStr == "bf16_c" ? DataType::None
|
|
: DataTypeStr == "i8_r" ? DataType::Int8
|
|
: DataTypeStr == "i32_r" ? DataType::Int32
|
|
: DataTypeStr == "i8_c" ? DataType::None
|
|
: DataTypeStr == "i32_c" ? DataType::None
|
|
: DataTypeStr == "u8_r" ? DataType::None
|
|
: DataTypeStr == "u32_r" ? DataType::None
|
|
: DataTypeStr == "u8_c" ? DataType::None
|
|
: DataTypeStr == "u32_c" ? DataType::None
|
|
: DataType::None;
|
|
}
|
|
|
|
template <>
|
|
std::pair<ProblemOverride<ContractionProblem>, int>
|
|
problemFromEntries(const std::vector<std::string>& entries)
|
|
{
|
|
const size_t entries_n = entries.size();
|
|
if((entries_n != 15) && (entries_n != 18))
|
|
{
|
|
return std::make_pair(ProblemOverride<ContractionProblem>{}, -1);
|
|
}
|
|
|
|
// Common
|
|
bool transA = (entries[0] != "N");
|
|
bool transB = (entries[1] != "N");
|
|
|
|
size_t m, n, b, k;
|
|
size_t ldA, ldB, ldC;
|
|
size_t strideA, strideB, strideC;
|
|
double alpha, beta;
|
|
|
|
DataType inputType = DataType::None;
|
|
DataType outputType = DataType::None;
|
|
DataType computeType = DataType::None;
|
|
|
|
int solution_idx = -1;
|
|
|
|
try
|
|
{
|
|
m = std::stol(entries[2]);
|
|
n = std::stol(entries[3]);
|
|
b = std::stol(entries[4]);
|
|
k = std::stol(entries[5]);
|
|
|
|
beta = std::stod(entries[7]);
|
|
|
|
ldA = std::stol(entries[8]);
|
|
ldB = std::stol(entries[9]);
|
|
ldC = std::stol(entries[10]);
|
|
|
|
strideA = 1;
|
|
strideB = 1;
|
|
strideC = 1;
|
|
|
|
if(b > 1)
|
|
{
|
|
strideA = ldA * (transA ? m : k);
|
|
strideB = ldB * (transB ? k : n);
|
|
strideC = ldC * n;
|
|
}
|
|
|
|
if(entries_n == 15)
|
|
{
|
|
// Expected layout: transA,transB,M,N,batch_count,K,alpha,beta,lda,ldb,ldc,input_type,output_type,compute_type,solution_index
|
|
inputType = convertToDataType(entries[11]);
|
|
outputType = convertToDataType(entries[12]);
|
|
computeType = convertToDataType(entries[13]);
|
|
|
|
solution_idx = std::stoi(entries[14]);
|
|
}
|
|
else if(entries_n == 18)
|
|
{
|
|
// Expected layout: transA,transB,M,N,batch_count,K,alpha,beta,lda,ldb,ldc,stride_a,stride_b,stride_c,input_type,output_type,compute_type,solution_index
|
|
strideA = std::stol(entries[11]);
|
|
strideB = std::stol(entries[12]);
|
|
strideC = std::stol(entries[13]);
|
|
|
|
inputType = convertToDataType(entries[14]);
|
|
outputType = convertToDataType(entries[15]);
|
|
computeType = convertToDataType(entries[16]);
|
|
|
|
solution_idx = std::stoi(entries[17]);
|
|
}
|
|
}
|
|
catch(std::invalid_argument const& ex)
|
|
{
|
|
return std::make_pair(ProblemOverride<ContractionProblem>{}, -1);
|
|
}
|
|
catch(std::out_of_range const& ex)
|
|
{
|
|
return std::make_pair(ProblemOverride<ContractionProblem>{}, -1);
|
|
}
|
|
|
|
if(inputType == DataType::None || outputType == DataType::None
|
|
|| computeType == DataType::None)
|
|
{
|
|
return std::make_pair(ProblemOverride<ContractionProblem>{}, -1);
|
|
}
|
|
|
|
bool HPA = (dataTypeSize(computeType) > dataTypeSize(inputType));
|
|
|
|
ProblemOverride<ContractionProblem> po(transA,
|
|
transB,
|
|
inputType,
|
|
outputType,
|
|
HPA,
|
|
m,
|
|
n,
|
|
k,
|
|
b,
|
|
beta,
|
|
ldA,
|
|
strideA,
|
|
ldB,
|
|
strideB,
|
|
ldC,
|
|
strideC);
|
|
|
|
return std::make_pair(po, solution_idx);
|
|
}
|
|
|
|
template <typename MyProblem>
|
|
ProblemOverride<MyProblem>::ProblemOverride()
|
|
: m_transA(false)
|
|
, m_transB(false)
|
|
, m_inputType(DataType::None)
|
|
, m_outputType(DataType::None)
|
|
, m_HPA(false)
|
|
, m_m(0)
|
|
, m_n(0)
|
|
, m_k(0)
|
|
, m_batchSize(0)
|
|
, m_beta(0)
|
|
, m_ldA(0)
|
|
, m_strideA(0)
|
|
, m_ldB(0)
|
|
, m_strideB(0)
|
|
, m_ldC(0)
|
|
, m_strideC(0)
|
|
{
|
|
}
|
|
|
|
template <typename MyProblem>
|
|
ProblemOverride<MyProblem>::ProblemOverride(bool transA,
|
|
bool transB,
|
|
DataType inputType,
|
|
DataType outputType,
|
|
bool HPA,
|
|
size_t m,
|
|
size_t n,
|
|
size_t k,
|
|
size_t batchSize,
|
|
double beta,
|
|
size_t ldA,
|
|
size_t strideA,
|
|
size_t ldB,
|
|
size_t strideB,
|
|
size_t ldC,
|
|
size_t strideC)
|
|
: m_transA(transA)
|
|
, m_transB(transB)
|
|
, m_inputType(inputType)
|
|
, m_outputType(outputType)
|
|
, m_HPA(HPA)
|
|
, m_m(m)
|
|
, m_n(n)
|
|
, m_k(k)
|
|
, m_batchSize(batchSize)
|
|
, m_beta(beta)
|
|
, m_ldA(ldA)
|
|
, m_strideA(strideA)
|
|
, m_ldB(ldB)
|
|
, m_strideB(strideB)
|
|
, m_ldC(ldC)
|
|
, m_strideC(strideC)
|
|
{
|
|
}
|
|
|
|
template <>
|
|
ProblemOverride<ContractionProblem>::ProblemOverride(const ContractionProblem& problem)
|
|
{
|
|
m_transA = problem.transA();
|
|
m_transB = problem.transB();
|
|
m_inputType = problem.a().dataType();
|
|
m_outputType = problem.c().dataType();
|
|
m_HPA = problem.highPrecisionAccumulate();
|
|
m_m = problem.freeSizeA(0);
|
|
m_n = problem.freeSizeB(0);
|
|
m_k = problem.boundSize(0);
|
|
m_batchSize = problem.batchSize(0);
|
|
m_beta = problem.beta();
|
|
m_ldA = problem.a().strides()[1];
|
|
m_strideA = problem.a().strides()[2];
|
|
m_ldB = problem.b().strides()[1];
|
|
m_strideB = problem.b().strides()[2];
|
|
m_ldC = problem.c().strides()[1];
|
|
m_strideC = problem.c().strides()[2];
|
|
}
|
|
|
|
template <>
|
|
ContractionProblem ProblemOverride<ContractionProblem>::problem() const
|
|
{
|
|
auto problem = ContractionProblem::GEMM_Strides(m_transA,
|
|
m_transB,
|
|
m_inputType,
|
|
m_inputType,
|
|
m_outputType,
|
|
m_outputType,
|
|
m_m,
|
|
m_n,
|
|
m_k,
|
|
m_batchSize,
|
|
m_ldA,
|
|
m_strideA,
|
|
m_ldB,
|
|
m_strideB,
|
|
m_ldC,
|
|
m_strideC,
|
|
m_ldC,
|
|
m_strideC,
|
|
m_beta);
|
|
problem.setHighPrecisionAccumulate(m_HPA);
|
|
|
|
return problem;
|
|
}
|
|
|
|
template <>
|
|
std::vector<std::pair<ProblemOverride<ContractionProblem>, int>>
|
|
getContractionProblemsFromFile(const std::string& path)
|
|
{
|
|
std::vector<std::pair<ProblemOverride<ContractionProblem>, int>> out;
|
|
|
|
std::ifstream file(path);
|
|
std::string line, entry;
|
|
|
|
const auto delim = ',';
|
|
const auto first_heading = "transA";
|
|
const int max_entries = 18;
|
|
|
|
while(std::getline(file, line))
|
|
{
|
|
// Ignore lines without delimiter
|
|
if(line.find(delim) == std::string::npos)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Check for section start
|
|
if(line.find(first_heading) != std::string::npos)
|
|
{
|
|
// TODO: Get param index from headings?
|
|
continue;
|
|
}
|
|
|
|
std::vector<std::string> entries{};
|
|
entries.reserve(max_entries);
|
|
|
|
std::stringstream line_ss(line);
|
|
while(getline(line_ss, entry, delim))
|
|
{
|
|
entries.push_back(entry);
|
|
}
|
|
|
|
auto problemSolution = problemFromEntries<ContractionProblem>(entries);
|
|
if(problemSolution.second > 0)
|
|
{
|
|
out.push_back(problemSolution);
|
|
}
|
|
}
|
|
|
|
return out;
|
|
}
|
|
};
|