import unittest
from catlass_cppgen.op.gemm import Gemm
from catlass_cppgen.common.op_tensor import OpTensor
from catlass_cppgen.common.data_type import DataType
from catlass_cppgen.catlass.layout.layout import ColumnMajor, RowMajor
from catlass_cppgen.catlass.gemm_coord import GemmShape
from catlass_cppgen.catlass.arch.arch import Arch
from catlass_cppgen.catlass.gemm.dispatch_policy import (
MmadPingpong,
MmadPingpongTlaV2,
)
from catlass_cppgen.kernel.gemm import (
BasicMatmulKernel,
BatchedMatmulKernel,
StridedBatchedMatmulKernel,
BasicMatmulTlaVisitorKernel,
MultiCoreSplitkMatmulKernel,
StreamkMatmulKernel,
TailMultiCoreSplitkMatmulKernel,
)
from assertion_helper import TestAssertions
def find_kernel_by_type(kernels, kernel_type):
"""根据类型查找 kernel"""
for kernel in kernels:
if isinstance(kernel, kernel_type):
return kernel
return None
class TestGemm(unittest.TestCase):
def setUp(self):
self.check = TestAssertions(self)
def test_basic_matmul_kernel(self):
a = OpTensor.from_shape_stride(
shape=(128, 256), stride=(256, 1), dtype=DataType.FLOAT
)
b = OpTensor.from_shape_stride(
shape=(256, 384), stride=(384, 1), dtype=DataType.FLOAT
)
gemm_plan = Gemm(
atlas_arch=Arch.Ascend950, element=DataType.FLOAT, layout=RowMajor, A=a, B=b
)
kernels = gemm_plan.get_kernels()
basic_kernel = find_kernel_by_type(kernels, BasicMatmulKernel)
if basic_kernel is None:
raise ValueError(
f"No kernel named 'BasicMatmulKernel' found, available kernel list: {[type(k).__name__ for k in kernels]}"
)
self.assertEqual(type(basic_kernel), BasicMatmulKernel)
self.assertFalse(basic_kernel.relu_enable)
basic_kernel.tune(
GemmShape(128, 256, 64),
GemmShape(128, 256, 64),
dispatch_policy=MmadPingpong(arch_tag=Arch.Ascend950),
)
params = basic_kernel.gen_params_device(def_mode=False)
self.check.test_params(
params,
(
"problemShape",
"deviceA",
"layoutA",
"deviceB",
"layoutB",
"deviceC",
"layoutC",
"deviceBias",
),
)
kernel_str = basic_kernel.gen_kernel_template()
self.check.test_tileshape(kernel_str, GemmShape(128, 256, 64))
self.check.test_tileshape(kernel_str, GemmShape(128, 256, 64), pos="L0")
self.check.test_element_dtype(kernel_str, DataType.FLOAT)
self.check.test_layout(kernel_str, "RowMajor")
self.check.test_layout(kernel_str, "RowMajor", "TagB")
self.check.test_layout(kernel_str, "RowMajor", "TagC")
self.check.test_kernel(kernel_str, "BasicMatmulTla")
self.check.test_dispatch_policy(kernel_str, "MmadPingpong")
self.check.test_arch_tag(kernel_str, Arch.Ascend950)
def test_batched_matmul(self):
a = OpTensor.from_shape_stride(
shape=(8, 128, 256), stride=(32768, 256, 1), dtype=DataType.FLOAT
)
b = OpTensor.from_shape_stride(
shape=(8, 256, 384), stride=(98304, 384, 1), dtype=DataType.FLOAT
)
gemm_plan = Gemm(
atlas_arch=Arch.Ascend950, element_C=DataType.FLOAT, core_num=8, A=a, B=b
)
kernels = gemm_plan.get_kernels()
batched_kernel = find_kernel_by_type(kernels, BatchedMatmulKernel)
if batched_kernel is None:
raise ValueError(
f"No kernel named 'BatchedMatmulKernel' found, available kernel list: {[type(k).__name__ for k in kernels]}"
)
self.assertEqual(type(batched_kernel), BatchedMatmulKernel)
self.assertFalse(batched_kernel.relu_enable)
batched_kernel.tune(
GemmShape(128, 256, 64),
GemmShape(128, 256, 64),
dispatch_policy=MmadPingpong(
arch_tag=Arch.Ascend950, enable_unit_flag=True
),
)
kernel_str = batched_kernel.gen_kernel_template()
self.check.test_tileshape(kernel_str, GemmShape(128, 256, 64))
self.check.test_tileshape(kernel_str, GemmShape(128, 256, 64), pos="L0")
self.check.test_element_dtype(kernel_str, DataType.FLOAT)
self.check.test_layout(kernel_str, "RowMajor")
self.check.test_layout(kernel_str, "RowMajor", "TagB")
self.check.test_layout(kernel_str, "RowMajor", "TagC")
self.check.test_kernel(kernel_str, "BatchedMatmulTla")
self.check.test_dispatch_policy(kernel_str, "MmadPingpong")
self.check.test_arch_tag(kernel_str, Arch.Ascend950)
def test_strided_batched_matmul(self):
a = OpTensor.from_shape_stride(
shape=(3, 128, 256),
stride=(256, 3 * 256, 1),
dtype=DataType.FLOAT16,
)
b = OpTensor.from_shape_stride(
shape=(3, 256, 384),
stride=(256 * 384, 384, 1),
dtype=DataType.FLOAT16,
)
gemm_plan = Gemm(
atlas_arch=Arch.AtlasA2,
element_C=DataType.FLOAT16,
core_num=8,
A=a,
B=b,
strided_batched=True,
transA=True,
transB=False,
)
kernel = find_kernel_by_type(
gemm_plan.get_kernels(),
StridedBatchedMatmulKernel,
)
self.assertIsNotNone(kernel)
kernel_str = kernel.gen_kernel_template()
layout_str = kernel.gen_layout_template()
self.check.test_kernel(kernel_str, "StridedBatchedMatmulTla")
self.check.test_dispatch_policy(kernel_str, "MmadPingpongTlaV2")
self.check.test_arch_tag(kernel_str, Arch.AtlasA2)
self.assertIn("constexpr bool transA = true;", layout_str)
self.assertIn("constexpr bool transB = false;", layout_str)
self.assertIn(
"strideBatchA = transA ? static_cast<int64_t>(k)",
layout_str,
)
self.assertIn(
"strideMA = transA ? static_cast<int64_t>(batchCount) * k",
layout_str,
)
self.assertNotIn("lda", kernel.gen_params_device())
self.assertNotIn("strideA", kernel.gen_params_device())
self.assertIn("_TN_", kernel.gen_kernel_name())
def test_strided_batched_matmul_with_tune(self):
a = OpTensor.from_shape_stride(
shape=(3, 128, 256),
stride=(256, 1, 384),
dtype=DataType.FLOAT,
)
b = OpTensor.from_shape_stride(
shape=(3, 256, 384),
stride=(384, 1152, 1),
dtype=DataType.FLOAT,
)
gemm_plan = Gemm(
atlas_arch=Arch.Ascend950,
element_C=DataType.FLOAT,
core_num=8,
A=a,
B=b,
strided_batched=True,
transA=True,
transB=False,
)
kernel = find_kernel_by_type(
gemm_plan.get_kernels(),
StridedBatchedMatmulKernel,
)
self.assertIsNotNone(kernel)
self.assertEqual(type(kernel), StridedBatchedMatmulKernel)
kernel.tune(
GemmShape(256, 256, 128),
GemmShape(256, 256, 32),
dispatch_policy=MmadPingpongTlaV2(
arch_tag=Arch.Ascend950, enable_unit_flag=True
),
)
kernel_str = kernel.gen_kernel_template()
layout_str = kernel.gen_layout_template()
self.check.test_tileshape(kernel_str, GemmShape(256, 256, 128))
self.check.test_tileshape(kernel_str, GemmShape(256, 256, 32), pos="L0")
self.check.test_element_dtype(kernel_str, DataType.FLOAT)
self.check.test_layout(kernel_str, "ColumnMajor")
self.check.test_layout(kernel_str, "RowMajor", "TagB")
self.check.test_layout(kernel_str, "RowMajor", "TagC")
self.check.test_kernel(kernel_str, "StridedBatchedMatmulTla")
self.check.test_dispatch_policy(kernel_str, "MmadPingpongTlaV2")
self.check.test_arch_tag(kernel_str, Arch.Ascend950)
self.assertIn("constexpr bool transA = true;", layout_str)
self.assertIn("constexpr bool transB = false;", layout_str)
params = kernel.gen_params_device(def_mode=False)
self.check.test_params(
params,
(
"batchCount",
"problemShape",
"deviceA",
"layoutA",
"deviceB",
"layoutB",
"deviceC",
"layoutC",
),
)
def test_basic_matmul_kernel_with_relu(self):
a = OpTensor.from_shape_stride(
shape=(128, 256), stride=(256, 1), dtype=DataType.FLOAT
)
b = OpTensor.from_shape_stride(
shape=(256, 384), stride=(384, 1), dtype=DataType.FLOAT
)
gemm_plan = Gemm(
atlas_arch=Arch.Ascend950, element=DataType.FLOAT, layout=RowMajor, A=a, B=b
)
kernels = gemm_plan.get_kernels()
basic_kernel = find_kernel_by_type(kernels, BasicMatmulKernel)
if basic_kernel is None:
raise ValueError(
f"No kernel named 'BasicMatmulKernel' found, available kernel list: {[type(k).__name__ for k in kernels]}"
)
self.assertEqual(type(basic_kernel), BasicMatmulKernel)
self.assertFalse(basic_kernel.relu_enable)
basic_kernel.tune(
GemmShape(128, 256, 64),
GemmShape(128, 256, 64),
dispatch_policy=MmadPingpong(arch_tag=Arch.Ascend950),
relu_enable=True,
)
self.assertTrue(basic_kernel.relu_enable)
kernel_str = basic_kernel.gen_kernel_template()
self.check.test_tileshape(kernel_str, GemmShape(128, 256, 64))
self.check.test_tileshape(kernel_str, GemmShape(128, 256, 64), pos="L0")
self.check.test_element_dtype(kernel_str, DataType.FLOAT)
self.check.test_layout(kernel_str, "RowMajor")
self.check.test_layout(kernel_str, "RowMajor", "TagB")
self.check.test_layout(kernel_str, "RowMajor", "TagC")
self.check.test_kernel(kernel_str, "BasicMatmulTla")
self.check.test_dispatch_policy(kernel_str, "MmadPingpong")
self.check.test_arch_tag(kernel_str, Arch.Ascend950)
def test_basic_matmul_kernel_with_is_hf32(self):
a = OpTensor.from_shape_stride(
shape=(128, 256), stride=(256, 1), dtype=DataType.FLOAT
)
b = OpTensor.from_shape_stride(
shape=(256, 384), stride=(384, 1), dtype=DataType.FLOAT
)
gemm_plan = Gemm(
atlas_arch=Arch.Ascend950, element=DataType.FLOAT, layout=RowMajor, A=a, B=b
)
kernels = gemm_plan.get_kernels()
basic_kernel = find_kernel_by_type(kernels, BasicMatmulKernel)
if basic_kernel is None:
raise ValueError(
f"No kernel named 'BasicMatmulKernel' found, available kernel list: {[type(k).__name__ for k in kernels]}"
)
self.assertEqual(type(basic_kernel), BasicMatmulKernel)
basic_kernel.tune(
GemmShape(128, 256, 64),
GemmShape(128, 256, 64),
dispatch_policy=MmadPingpong(arch_tag=Arch.Ascend950),
is_hf32=True,
)
self.assertTrue(basic_kernel.dispatch_policy[0].use_hf32_mode)
kernel_str = basic_kernel.gen_kernel_template()
self.check.test_tileshape(kernel_str, GemmShape(128, 256, 64))
self.check.test_tileshape(kernel_str, GemmShape(128, 256, 64), pos="L0")
self.check.test_element_dtype(kernel_str, DataType.FLOAT)
self.check.test_layout(kernel_str, "RowMajor")
self.check.test_layout(kernel_str, "RowMajor", "TagB")
self.check.test_layout(kernel_str, "RowMajor", "TagC")
self.check.test_kernel(kernel_str, "BasicMatmulTla")
self.check.test_dispatch_policy(kernel_str, "MmadPingpong")
self.check.test_arch_tag(kernel_str, Arch.Ascend950)
def test_matmul_with_bias(self):
a = OpTensor.from_shape_stride(
shape=(128, 256), stride=(256, 1), dtype=DataType.FLOAT
)
b = OpTensor.from_shape_stride(
shape=(256, 384), stride=(384, 1), dtype=DataType.FLOAT
)
bias = OpTensor.from_shape_stride(
shape=(384,), stride=(1,), dtype=DataType.FLOAT
)
gemm_plan = Gemm(
atlas_arch=Arch.Ascend950,
element=DataType.FLOAT,
layout=RowMajor,
A=a,
B=b,
Bias=bias,
)
kernels = gemm_plan.get_kernels()
basic_kernel = find_kernel_by_type(kernels, BasicMatmulKernel)
if basic_kernel is None:
raise ValueError(
f"No kernel named 'BasicMatmulKernel' found, available kernel list: {[type(k).__name__ for k in kernels]}"
)
self.assertEqual(type(basic_kernel), BasicMatmulKernel)
basic_kernel.tune(
GemmShape(128, 256, 64),
GemmShape(128, 256, 64),
dispatch_policy=MmadPingpong(arch_tag=Arch.Ascend950),
)
params = basic_kernel.gen_params_device(def_mode=False)
self.check.test_params(
params,
(
"problemShape",
"deviceA",
"layoutA",
"deviceB",
"layoutB",
"deviceC",
"layoutC",
"deviceBias",
),
)
kernel_str = basic_kernel.gen_kernel_template()
self.check.test_tileshape(kernel_str, GemmShape(128, 256, 64))
self.check.test_tileshape(kernel_str, GemmShape(128, 256, 64), pos="L0")
self.check.test_element_dtype(kernel_str, DataType.FLOAT)
self.check.test_layout(kernel_str, "RowMajor")
self.check.test_layout(kernel_str, "RowMajor", "TagB")
self.check.test_layout(kernel_str, "RowMajor", "TagC")
self.check.test_kernel(kernel_str, "BasicMatmulTla")
self.check.test_dispatch_policy(kernel_str, "MmadPingpong")
self.check.test_arch_tag(kernel_str, Arch.Ascend950)
def test_tile_shape_with_bias(self):
a = OpTensor.from_shape_stride(
shape=(128, 256), stride=(256, 1), dtype=DataType.FLOAT
)
b = OpTensor.from_shape_stride(
shape=(256, 384), stride=(384, 1), dtype=DataType.FLOAT
)
bias = OpTensor.from_shape_stride(
shape=(384,), stride=(1,), dtype=DataType.FLOAT
)
gemm_plan_without_bias = Gemm(
atlas_arch=Arch.Ascend950, element=DataType.FLOAT, layout=RowMajor, A=a, B=b
)
kernels_without_bias = gemm_plan_without_bias.get_kernels()
basic_kernel_without_bias = find_kernel_by_type(
kernels_without_bias, BasicMatmulKernel
)
if basic_kernel_without_bias is None:
raise ValueError(
f"No kernel named 'BasicMatmulKernel' found, available kernel list: {[type(k).__name__ for k in kernels_without_bias]}"
)
default_shape_no_bias = basic_kernel_without_bias.get_default_tile_shape()
self.assertEqual(
default_shape_no_bias, (GemmShape(256, 256, 128), GemmShape(256, 256, 32))
)
gemm_plan_with_bias = Gemm(
atlas_arch=Arch.Ascend950,
element=DataType.FLOAT,
layout=RowMajor,
A=a,
B=b,
Bias=bias,
)
kernels_with_bias = gemm_plan_with_bias.get_kernels()
basic_kernel_with_bias = find_kernel_by_type(
kernels_with_bias, BasicMatmulKernel
)
if basic_kernel_with_bias is None:
raise ValueError(
f"No kernel named 'BasicMatmulKernel' found, available kernel list: {[type(k).__name__ for k in kernels_with_bias]}"
)
default_shape_with_bias = basic_kernel_with_bias.get_default_tile_shape()
self.assertEqual(
default_shape_with_bias, (GemmShape(240, 256, 128), GemmShape(240, 256, 32))
)
def test_streamk_matmul(self):
a = OpTensor.from_shape_stride(
shape=(1280, 3000), stride=(3000, 1), dtype=DataType.FLOAT
)
b = OpTensor.from_shape_stride(
shape=(3000, 256), stride=(256, 1), dtype=DataType.FLOAT
)
gemm_plan = Gemm(
atlas_arch=Arch.Ascend950,
element=DataType.FLOAT,
layout=RowMajor,
core_num=8,
A=a,
B=b,
)
kernels = gemm_plan.get_kernels()
streamk_kernel = find_kernel_by_type(kernels, StreamkMatmulKernel)
if streamk_kernel is None:
raise ValueError(
f"No kernel named 'StreamkMatmulKernel' found, available kernel list: {[type(k).__name__ for k in kernels]}"
)
self.assertEqual(type(streamk_kernel), StreamkMatmulKernel)
self.assertEqual(streamk_kernel.slice_axis, "K")
self.assertFalse(streamk_kernel.relu_enable)
streamk_kernel.tune(
GemmShape(256, 256, 128),
GemmShape(256, 256, 32),
dispatch_policy=MmadPingpong(
arch_tag=Arch.Ascend950, enable_unit_flag=True
),
)
kernel_str = streamk_kernel.gen_kernel_template()
self.check.test_tileshape(kernel_str, GemmShape(256, 256, 128))
self.check.test_tileshape(kernel_str, GemmShape(256, 256, 32), pos="L0")
self.check.test_element_dtype(kernel_str, DataType.FLOAT)
self.check.test_layout(kernel_str, "RowMajor")
self.check.test_layout(kernel_str, "RowMajor", "TagB")
self.check.test_layout(kernel_str, "RowMajor", "TagC")
self.check.test_kernel(kernel_str, "StreamkMatmulTla")
self.check.test_dispatch_policy(kernel_str, "MmadPingpong")
self.check.test_arch_tag(kernel_str, Arch.Ascend950)
def test_multi_core_splitk_matmul_kernel(self):
a = OpTensor.from_shape_stride(
shape=(256, 3000), stride=(3000, 1), dtype=DataType.FLOAT
)
b = OpTensor.from_shape_stride(
shape=(3000, 256), stride=(256, 1), dtype=DataType.FLOAT
)
gemm_plan = Gemm(
atlas_arch=Arch.Ascend950,
element=DataType.FLOAT,
layout=RowMajor,
core_num=8,
A=a,
B=b,
)
kernels = gemm_plan.get_kernels()
splitk_kernel = find_kernel_by_type(kernels, MultiCoreSplitkMatmulKernel)
if splitk_kernel is None:
raise ValueError(
f"No kernel named 'MultiCoreSplitkMatmulKernel' found, available kernel list: {[type(k).__name__ for k in kernels]}"
)
self.assertEqual(type(splitk_kernel), MultiCoreSplitkMatmulKernel)
self.assertEqual(splitk_kernel.slice_axis, "K")
self.assertFalse(splitk_kernel.relu_enable)
splitk_kernel.tune(
GemmShape(256, 256, 128),
GemmShape(256, 256, 32),
dispatch_policy=MmadPingpong(
arch_tag=Arch.Ascend950, enable_unit_flag=True
),
)
kernel_str = splitk_kernel.gen_kernel_template()
self.check.test_tileshape(kernel_str, GemmShape(256, 256, 128))
self.check.test_tileshape(kernel_str, GemmShape(256, 256, 32), pos="L0")
self.check.test_element_dtype(kernel_str, DataType.FLOAT)
self.check.test_layout(kernel_str, "RowMajor")
self.check.test_layout(kernel_str, "RowMajor", "TagB")
self.check.test_layout(kernel_str, "RowMajor", "TagC")
self.check.test_kernel(kernel_str, "MultiCoreSplitkMatmulTla")
self.check.test_dispatch_policy(kernel_str, "MmadPingpong")
self.check.test_arch_tag(kernel_str, Arch.Ascend950)
def test_tail_multi_core_splitk_matmul_kernel(self):
a = OpTensor.from_shape_stride(
shape=(768, 3000), stride=(3000, 1), dtype=DataType.FLOAT
)
b = OpTensor.from_shape_stride(
shape=(3000, 768), stride=(768, 1), dtype=DataType.FLOAT
)
gemm_plan = Gemm(
atlas_arch=Arch.Ascend950,
element=DataType.FLOAT,
layout=RowMajor,
core_num=8,
A=a,
B=b,
)
kernels = gemm_plan.get_kernels()
tail_splitk_kernel = find_kernel_by_type(
kernels, TailMultiCoreSplitkMatmulKernel
)
if tail_splitk_kernel is None:
raise ValueError(
f"No kernel named 'TailMultiCoreSplitkMatmulKernel' found, available kernel list: {[type(k).__name__ for k in kernels]}"
)
self.assertEqual(type(tail_splitk_kernel), TailMultiCoreSplitkMatmulKernel)
self.assertEqual(tail_splitk_kernel.slice_axis, "K")
self.assertFalse(tail_splitk_kernel.relu_enable)
tail_splitk_kernel.tune(
GemmShape(256, 256, 128),
GemmShape(256, 256, 32),
dispatch_policy=MmadPingpong(
arch_tag=Arch.Ascend950, enable_unit_flag=True
),
)
kernel_str = tail_splitk_kernel.gen_kernel_template()
self.check.test_tileshape(kernel_str, GemmShape(256, 256, 128))
self.check.test_tileshape(kernel_str, GemmShape(256, 256, 32), pos="L0")
self.check.test_element_dtype(kernel_str, DataType.FLOAT)
self.check.test_layout(kernel_str, "RowMajor")
self.check.test_layout(kernel_str, "RowMajor", "TagB")
self.check.test_layout(kernel_str, "RowMajor", "TagC")
self.check.test_kernel(kernel_str, "TailMultiCoreSplitkMatmulTla")
self.check.test_dispatch_policy(kernel_str, "MmadPingpong")
self.check.test_arch_tag(kernel_str, Arch.Ascend950)
def test_basic_matmul_tla_visitor_kernel(self):
a = OpTensor.from_shape_stride(
shape=(128, 256), stride=(256, 1), dtype=DataType.FLOAT
)
b = OpTensor.from_shape_stride(
shape=(256, 384), stride=(384, 1), dtype=DataType.FLOAT
)
function_source = """
def epilogue(accum):
temp = accum
return temp
"""
example_inputs = {
"accum": OpTensor.from_shape_stride(
shape=(128, 384), stride=(384, 1), dtype=DataType.FLOAT
),
"temp": OpTensor.from_shape_stride(
shape=(128, 384), stride=(384, 1), dtype=DataType.FLOAT
),
}
evg_config = {
"fn_src": function_source,
"example_inputs": example_inputs,
}
gemm_plan = Gemm(
atlas_arch=Arch.Ascend950,
evg_config=evg_config,
element=DataType.FLOAT,
layout=RowMajor,
A=a,
B=b,
)
kernels = gemm_plan.get_kernels()
visitor_kernel = find_kernel_by_type(kernels, BasicMatmulTlaVisitorKernel)
if visitor_kernel is None:
raise ValueError(
f"No kernel named 'BasicMatmulTlaVisitorKernel' found, available kernel list: {[type(k).__name__ for k in kernels]}"
)
self.assertEqual(type(visitor_kernel), BasicMatmulTlaVisitorKernel)
self.assertEqual(visitor_kernel.slice_axis, None)
self.assertFalse(visitor_kernel.relu_enable)
visitor_kernel.tune(
GemmShape(128, 256, 64),
GemmShape(128, 256, 64),
dispatch_policy=MmadPingpong(arch_tag=Arch.Ascend950),
)
kernel_str = visitor_kernel.gen_kernel_template()
self.check.test_tileshape(kernel_str, GemmShape(128, 256, 64))
self.check.test_tileshape(kernel_str, GemmShape(128, 256, 64), pos="L0")
self.check.test_element_dtype(kernel_str, DataType.FLOAT)
self.check.test_layout(kernel_str, "RowMajor")
self.check.test_layout(kernel_str, "RowMajor", "TagB")
self.check.test_layout(kernel_str, "RowMajor", "TagC")
self.check.test_kernel(kernel_str, "BasicMatmulTlaVisitor")
self.check.test_dispatch_policy(kernel_str, "MmadPingpong")
self.check.test_arch_tag(kernel_str, Arch.Ascend950)
def test_basic_matmul_tla_visitor_kernel_with_constant(self):
a = OpTensor.from_shape_stride(
shape=(128, 256), stride=(256, 1), dtype=DataType.FLOAT
)
b = OpTensor.from_shape_stride(
shape=(256, 384), stride=(384, 1), dtype=DataType.FLOAT
)
function_source = """
def epilogue(accum):
scale = constant(0.1, "float")
result = accum * scale
return result
"""
example_inputs = {
"accum": OpTensor.from_shape_stride(
shape=(128, 384), stride=(384, 1), dtype=DataType.FLOAT
),
"result": OpTensor.from_shape_stride(
shape=(128, 384), stride=(384, 1), dtype=DataType.FLOAT
),
}
evg_config = {
"fn_src": function_source,
"example_inputs": example_inputs,
}
gemm_plan = Gemm(
atlas_arch=Arch.Ascend950,
evg_config=evg_config,
element=DataType.FLOAT,
layout=RowMajor,
A=a,
B=b,
)
kernels = gemm_plan.get_kernels()
visitor_kernel = find_kernel_by_type(kernels, BasicMatmulTlaVisitorKernel)
if visitor_kernel is None:
raise ValueError(
f"No kernel named 'BasicMatmulTlaVisitorKernel' found, available kernel list: {[type(k).__name__ for k in kernels]}"
)
self.assertEqual(type(visitor_kernel), BasicMatmulTlaVisitorKernel)
visitor_kernel.tune(
GemmShape(128, 256, 64),
GemmShape(128, 256, 64),
dispatch_policy=MmadPingpong(arch_tag=Arch.Ascend950),
)
kernel_str = visitor_kernel.gen_kernel_template()
self.check.test_tileshape(kernel_str, GemmShape(128, 256, 64))
self.check.test_tileshape(kernel_str, GemmShape(128, 256, 64), pos="L0")
self.check.test_element_dtype(kernel_str, DataType.FLOAT)
self.check.test_layout(kernel_str, "RowMajor")
self.check.test_layout(kernel_str, "RowMajor", "TagB")
self.check.test_layout(kernel_str, "RowMajor", "TagC")
self.check.test_kernel(kernel_str, "BasicMatmulTlaVisitor")
self.check.test_dispatch_policy(kernel_str, "MmadPingpong")
self.check.test_arch_tag(kernel_str, Arch.Ascend950)
def test_to_evg_method(self):
a = OpTensor.from_shape_stride(
shape=(128, 256), stride=(256, 1), dtype=DataType.FLOAT
)
b = OpTensor.from_shape_stride(
shape=(256, 384), stride=(384, 1), dtype=DataType.FLOAT
)
gemm_plan = Gemm(
atlas_arch=Arch.Ascend950, element=DataType.FLOAT, layout=RowMajor, A=a, B=b
)
kernels = gemm_plan.get_kernels()
basic_kernel = find_kernel_by_type(kernels, BasicMatmulKernel)
if basic_kernel is None:
raise ValueError(
f"No kernel named 'BasicMatmulKernel' found, available kernel list: {[type(k).__name__ for k in kernels]}"
)
self.assertEqual(type(basic_kernel), BasicMatmulKernel)
is_support_evg = bool(getattr(basic_kernel, "is_support_evg", False))
self.assertTrue(is_support_evg)
function_source = """
def epilogue(accum, bias):
result = accum + bias
return result
"""
example_inputs = {
"accum": OpTensor.from_shape_stride(
shape=(128, 384), stride=(384, 1), dtype=DataType.FLOAT
),
"bias": OpTensor.from_shape_stride(
shape=(1, 384), stride=(384, 1), dtype=DataType.FLOAT
),
"result": OpTensor.from_shape_stride(
shape=(128, 384), stride=(384, 1), dtype=DataType.FLOAT
),
}
evg_config = {
"fn_src": function_source,
"example_inputs": example_inputs,
}
basic_kernel.tune(
GemmShape(128, 256, 64),
GemmShape(128, 256, 64),
dispatch_policy=MmadPingpong(arch_tag=Arch.Ascend950),
)
evg_kernel = basic_kernel.to_evg(evg_config)
self.assertIsNotNone(evg_kernel)
self.assertIsInstance(evg_kernel, BasicMatmulTlaVisitorKernel)
self.assertIsNotNone(evg_kernel.evg)
kernel_str = evg_kernel.gen_kernel_template()
self.check.test_tileshape(kernel_str, GemmShape(128, 256, 64))
self.check.test_tileshape(kernel_str, GemmShape(128, 256, 64), pos="L0")
self.check.test_element_dtype(kernel_str, DataType.FLOAT)
self.check.test_layout(kernel_str, "RowMajor")
self.check.test_layout(kernel_str, "RowMajor", "TagB")
self.check.test_layout(kernel_str, "RowMajor", "TagC")
self.check.test_kernel(kernel_str, "BasicMatmulTlaVisitor")
self.check.test_dispatch_policy(kernel_str, "MmadPingpong")
self.check.test_arch_tag(kernel_str, Arch.Ascend950)
def test_to_evg_unsupported_kernel(self):
a = OpTensor.from_shape_stride(
shape=(256, 3000), stride=(3000, 1), dtype=DataType.FLOAT
)
b = OpTensor.from_shape_stride(
shape=(3000, 256), stride=(256, 1), dtype=DataType.FLOAT
)
gemm_plan = Gemm(
atlas_arch=Arch.Ascend950,
element=DataType.FLOAT,
layout=RowMajor,
core_num=8,
A=a,
B=b,
)
kernels = gemm_plan.get_kernels()
splitk_kernel = find_kernel_by_type(kernels, MultiCoreSplitkMatmulKernel)
if splitk_kernel is None:
raise ValueError(
f"No kernel named 'MultiCoreSplitkMatmulKernel' found, available kernel list: {[type(k).__name__ for k in kernels]}"
)
self.assertEqual(type(splitk_kernel), MultiCoreSplitkMatmulKernel)
is_support_evg = bool(getattr(splitk_kernel, "is_support_evg", False))
self.assertFalse(is_support_evg)
evg_config = {
"fn_src": "def epilogue(accum): return accum\n",
"example_inputs": {
"accum": OpTensor.from_shape_stride(
shape=(256, 256), stride=(256, 1), dtype=DataType.FLOAT
),
"result": OpTensor.from_shape_stride(
shape=(256, 256), stride=(256, 1), dtype=DataType.FLOAT
),
},
}
result = splitk_kernel.to_evg(evg_config)
self.assertIsNone(result)
if __name__ == "__main__":
unittest.main()