mirror of
https://github.com/tile-ai/tilelang.git
synced 2026-10-22 06:50:25 +08:00
* [Enhancement] Update examples and tests for improved type handling and functionality
- Enhanced various example scripts to support new data types and improve compatibility with PyTorch.
- Updated tests across multiple modules to ensure correct functionality with the latest changes in type handling.
- Refactored code in examples to streamline operations and improve clarity, particularly in tensor operations and memory management.
- Added comprehensive tests for new features and fixed existing issues related to type conversions and buffer handling.
* [Refactor] Update accumulation data type to float32 across examples
- Changed accumulation data type from "float" to T.float32 in multiple example scripts to ensure consistency and improve numerical stability.
- This update affects various modules including flash attention, GEMM analysis, convolution, and deepseek MLA examples, enhancing type handling across the board.
* [Refactor] Standardize data type usage across benchmark scripts
- Updated data type definitions in benchmark scripts to use T.float16 and T.float32 consistently, enhancing clarity and type handling.
- Adjusted dtype assignments in matmul functions and configuration setups to align with the new standard.
- Improved overall code consistency and maintainability by ensuring uniform data type usage across various modules.
* [Refactor] Standardize data type usage in templates and scripts
- Updated data type definitions in various templates and scripts to use string representations (e.g., "float16", "int32") instead of T.float16 and T.int32 for improved consistency and clarity.
- Enhanced overall code maintainability by ensuring uniform data type usage across multiple modules, including convolution, elementwise operations, and matrix multiplication templates.
- This change aims to streamline type handling and improve compatibility with existing workflows.
* [Refactor] Standardize data type usage in examples and benchmarks
- Updated data type definitions in various example and benchmark scripts to use T.float16 and T.int32 consistently, enhancing clarity and maintainability.
- Adjusted dtype assignments in kernel functions and configuration setups to align with the new standard.
- Improved overall code consistency by ensuring uniform data type usage across multiple modules, including attention mechanisms, matrix multiplication, and GEMM examples.
* [Refactor] Import dtypes from language.v2 module
- Added import statement for dtypes from the language.v2 module to enhance type handling and maintain consistency across the codebase.
- This change aims to streamline data type management and improve overall code clarity.
* fix
* [Refactor] Standardize data type usage across scripts
- Updated data type definitions in various scripts to use string representations (e.g., "float16", "int8") instead of T.float16 and T.int8 for improved consistency and clarity.
- Adjusted dtype assignments in functions and configuration setups to align with the new standard, enhancing overall code maintainability.
- This change affects multiple modules, including benchmark and attention mechanisms, ensuring uniform data type usage throughout the codebase.
* [Refactor] Update data type handling for consistency and clarity
- Changed string representations of data types in the Hint class to use T.float32 and T.int32 for improved consistency.
- Added new data types "int4" and "int16" to the dtypes module, enhancing type support across the codebase.
- Updated function signatures and assertions in the lop3 and mxfp modules to utilize the new data types, ensuring uniformity in type handling.
- This refactor aims to streamline data type management and improve overall code clarity and maintainability.
* [Enhancement] Improve data type handling and error messaging
- Introduced a mapping for canonical data types to their display strings, enhancing clarity in type representation.
- Updated the dtype creation logic to utilize the new mapping, ensuring more intuitive handling of string inputs.
- Refined error messages in the lop3 module to provide clearer feedback on invalid source formats, improving debugging and user experience.
* [Fix] Correct boolean flag in GEMM SP test case
- Updated the boolean flag in the test_gemm_sp_sm90 function to ensure proper functionality in the test case.
- This change enhances the accuracy of the test and aligns it with expected behavior for the GEMM SP implementation.
* [Refactor] Standardize data type usage across scripts
- Updated data type definitions in various scripts to use T.float16 and T.bfloat16 consistently, enhancing clarity and maintainability.
- Adjusted dtype assignments in function signatures and argument parsing to align with the new standard, ensuring uniform data type usage throughout the codebase.
- This change affects multiple modules, including benchmarks and examples, improving overall code consistency and readability.
* [Refactor] Standardize data type usage in various modules
- Updated data type assignments in multiple scripts to utilize T.float32, T.int8, and T.int32 consistently, enhancing clarity and maintainability.
- Adjusted function signatures and parameter types across benchmarks, examples, and tests to align with the new standard, ensuring uniform data type usage throughout the codebase.
- This change improves overall code consistency and readability, impacting modules related to matrix multiplication, GEMM, and tensor operations.
* [Refactor] Update argument parsing for data types in benchmarks
- Changed argument parsing for data types in benchmark_matmul_intrinsic.py and benchmark_matmul_sp.py to use string representations ("float16", "int8", "float") instead of T.float16 and T.float.
- This update enhances consistency in data type handling across benchmark scripts, improving clarity and maintainability.
* [Refactor] Update data type handling in benchmark and example scripts
- Changed data type arguments in benchmark and example scripts to use string representations ("float16") instead of T.float16 for improved consistency.
- Updated function signatures and argument parsing to align with the new standard, enhancing clarity and maintainability across the codebase.
- This change affects multiple modules related to attention mechanisms and tensor operations, ensuring uniform data type usage throughout the examples.
* [Refactor] Fix data type conversion in multiple scripts
- Corrected the usage of the data type conversion method from dtype..as_torch() to dtype.as_torch() across various benchmark and example scripts.
- This change enhances consistency in data type handling and improves code readability, impacting modules related to attention mechanisms and tensor operations.
* [Refactor] Update float8 data type usage across multiple scripts
- Changed instances of T.float8_e4m3 to T.float8_e4m3fn in various benchmark, example, and test scripts to ensure consistency in data type handling.
- This update enhances clarity and maintainability across the codebase, particularly in modules related to matrix multiplication and tensor operations.
* [Refactor] Enhance float8 data type handling in CUDA code generation
- Updated the handling of float8 data types in the CUDA code generation to include additional float8 variants, improving type conversion logic.
- Adjusted conditions to ensure proper type checks for float8 conversions, enhancing clarity and maintainability in the codebase.
- Modified layout inference to streamline float8 type checks, ensuring consistency across the implementation.
- This change impacts modules related to matrix operations and CUDA code generation, improving overall type handling and conversion accuracy.
* [Refactor] Streamline float8 data type handling in CUDA and related modules
- Enhanced float8 data type handling in CUDA code generation by refining type conversion logic and ensuring consistent type checks.
- Updated layout inference for float8 types to improve clarity and maintainability across the implementation.
- This change impacts modules related to matrix operations and CUDA code generation, improving overall type handling and conversion accuracy.
* [Refactor] Remove unnecessary cache disabling in float8 example script
- Eliminated the call to tilelang.disable_cache() in example_group_per_split_token_cast_to_fp8.py to streamline the code.
- This change enhances clarity and maintainability of the example script without affecting its functionality.
* [Refactor] Update data type usage in debug print tests
- Changed the argument for dtype in the test_debug_print_buffer function from a string representation to the corresponding T.bool type.
- This update enhances consistency in data type handling within the test suite, improving clarity and maintainability.
* lint fix
* Update function parameter types from `str` to `T.dtype` for improved type safety in attention sink and related examples
* Refactor `gemv_alloc_reducer` function signature for improved readability by formatting parameters across multiple lines.
230 lines
7.0 KiB
Python
230 lines
7.0 KiB
Python
import torch
|
|
import torch.backends
|
|
from tilelang import tvm as tvm
|
|
import tilelang.testing
|
|
from tvm import DataType
|
|
import tilelang.language as T
|
|
from tilelang.intrinsics import get_swizzle_layout
|
|
from tilelang.intrinsics.mma_macro_generator import (
|
|
TensorCoreIntrinEmitter,
|
|
)
|
|
from tilelang.transform import simplify_prim_func
|
|
from tilelang.utils.tensor import map_torch_type
|
|
|
|
tilelang.testing.set_random_seed(0)
|
|
|
|
|
|
def make_swizzle_layout(shared_buf):
|
|
dtype = shared_buf.dtype
|
|
shape = shared_buf.shape
|
|
|
|
can_swizzle = shape[-1] * DataType(dtype).bits == 512
|
|
if not can_swizzle:
|
|
return T.Layout(shape, lambda *args: args)
|
|
|
|
def transform_func(i, j):
|
|
new_warp_i, new_warp_j = get_swizzle_layout(i, j, shape[-1], dtype)
|
|
return [new_warp_i, new_warp_j]
|
|
|
|
return T.Layout(shape, transform_func)
|
|
|
|
|
|
@simplify_prim_func
|
|
def tl_matmul(
|
|
M,
|
|
N,
|
|
K,
|
|
in_dtype,
|
|
out_dtype,
|
|
accum_dtype,
|
|
):
|
|
assert in_dtype in [
|
|
T.float16,
|
|
T.bfloat16,
|
|
T.float8_e4m3fn,
|
|
T.float8_e5m2,
|
|
T.int8,
|
|
], "Currently only float16 and int8 are supported"
|
|
assert out_dtype in [
|
|
T.float16,
|
|
T.float32,
|
|
T.int32,
|
|
], "Currently only float16, float32 and int32 are supported"
|
|
|
|
micro_size_x = micro_size_y = micro_size_k = 16
|
|
|
|
is_float8 = in_dtype in [
|
|
T.float8_e4m3fn,
|
|
T.float8_e5m2,
|
|
T.float8_e4m3fn,
|
|
T.float8_e5m2fnuz,
|
|
]
|
|
if out_dtype == T.int32 or is_float8:
|
|
micro_size_k = 32
|
|
|
|
# This is a debug config
|
|
block_row_warps = 2
|
|
block_col_warps = 2
|
|
warp_row_tiles = 32
|
|
warp_col_tiles = 32
|
|
chunk = 32 if in_dtype == T.float16 else 64
|
|
shared_scope = "shared.dyn"
|
|
|
|
# Pipeline Stage
|
|
stage = 2
|
|
|
|
block_M = block_row_warps * warp_row_tiles
|
|
block_N = block_col_warps * warp_col_tiles
|
|
block_K = chunk
|
|
|
|
A_shape = (M, K)
|
|
B_shape = (N, K)
|
|
A_shared_shape = (block_M, block_K)
|
|
B_shared_shape = (block_N, block_K)
|
|
C_shared_shape = (
|
|
block_M // micro_size_x,
|
|
block_N // micro_size_y,
|
|
micro_size_x,
|
|
micro_size_y,
|
|
)
|
|
|
|
warp_size = 32
|
|
threads = warp_size * (block_row_warps * block_col_warps)
|
|
local_size_a = (micro_size_x * micro_size_k) // warp_size
|
|
local_size_b = (micro_size_y * micro_size_k) // warp_size
|
|
local_size_c = (micro_size_x * micro_size_y) // warp_size
|
|
warp_rows = warp_row_tiles // micro_size_x
|
|
warp_cols = warp_col_tiles // micro_size_y
|
|
|
|
# MMA Wrapper to Auto Generate Code for MMA
|
|
mma_emitter = TensorCoreIntrinEmitter(
|
|
a_dtype=in_dtype,
|
|
b_dtype=in_dtype,
|
|
accum_dtype=accum_dtype,
|
|
a_transposed=False,
|
|
b_transposed=True,
|
|
block_row_warps=block_row_warps,
|
|
block_col_warps=block_col_warps,
|
|
warp_row_tiles=warp_row_tiles,
|
|
warp_col_tiles=warp_col_tiles,
|
|
chunk=chunk,
|
|
)
|
|
|
|
@T.prim_func
|
|
def main(
|
|
A: T.Tensor(A_shape, in_dtype),
|
|
B: T.Tensor(B_shape, in_dtype),
|
|
C: T.Tensor((M, N), out_dtype),
|
|
):
|
|
with T.Kernel(T.ceildiv(N, block_N), T.ceildiv(M, block_M), threads=threads) as (bx, by):
|
|
A_shared = T.alloc_shared(A_shared_shape, in_dtype, scope=shared_scope)
|
|
B_shared = T.alloc_shared(B_shared_shape, in_dtype, scope=shared_scope)
|
|
C_shared = T.alloc_shared(C_shared_shape, out_dtype, scope=shared_scope)
|
|
A_local = T.alloc_local((warp_rows * local_size_a), in_dtype)
|
|
B_local = T.alloc_local((warp_cols * local_size_b), in_dtype)
|
|
C_local = T.alloc_local((warp_rows * warp_cols * local_size_c), accum_dtype)
|
|
|
|
T.annotate_layout(
|
|
{
|
|
A_shared: make_swizzle_layout(A_shared),
|
|
B_shared: make_swizzle_layout(B_shared),
|
|
}
|
|
)
|
|
|
|
# Improve L2 Cache
|
|
T.use_swizzle(panel_size=10)
|
|
|
|
T.clear(C_local)
|
|
|
|
for ko in T.Pipelined((K // block_K), num_stages=stage):
|
|
# Load A into shared memory
|
|
for i, k in T.Parallel(block_M, block_K):
|
|
A_shared[i, k] = A[by * block_M + i, ko * block_K + k]
|
|
|
|
# Load B into shared memory
|
|
for j, k in T.Parallel(block_N, block_K):
|
|
B_shared[j, k] = B[bx * block_N + j, ko * block_K + k]
|
|
|
|
for ki in T.serial(0, (block_K // micro_size_k)):
|
|
# Load A into fragment
|
|
mma_emitter.ldmatrix_a(
|
|
A_local,
|
|
A_shared,
|
|
ki,
|
|
)
|
|
|
|
# Load B into fragment
|
|
mma_emitter.ldmatrix_b(
|
|
B_local,
|
|
B_shared,
|
|
ki,
|
|
)
|
|
|
|
# Perform Matrix Multiplication
|
|
mma_emitter.mma(A_local, B_local, C_local)
|
|
|
|
# Perform STMatrix
|
|
mma_emitter.stmatrix(
|
|
C_local,
|
|
C_shared,
|
|
)
|
|
|
|
# Store shared into global
|
|
for i, j in T.Parallel(block_M, block_N):
|
|
C[by * block_M + i, bx * block_N + j] = C_shared[
|
|
i // micro_size_x,
|
|
j // micro_size_y,
|
|
i % micro_size_x,
|
|
j % micro_size_y,
|
|
]
|
|
|
|
return main
|
|
|
|
|
|
def assert_tl_matmul_correctness(M, N, K, in_dtype, out_dtype, accum_dtype):
|
|
matmul = tl_matmul(M, N, K, in_dtype, out_dtype, accum_dtype)
|
|
kernel = tilelang.compile(matmul, out_idx=[2])
|
|
profiler = kernel.get_profiler()
|
|
|
|
src_code = kernel.get_kernel_source()
|
|
# src_code is the generated cuda source
|
|
assert src_code is not None
|
|
|
|
in_dtype = map_torch_type(in_dtype)
|
|
out_dtype = map_torch_type(out_dtype)
|
|
accum_dtype = map_torch_type(accum_dtype)
|
|
|
|
if in_dtype in {torch.int8, torch.int32}:
|
|
A = torch.randint(-128, 128, (M, K), dtype=torch.int8).to(in_dtype).cuda()
|
|
B = torch.randint(-128, 128, (N, K), dtype=torch.int8).to(in_dtype).cuda()
|
|
elif in_dtype in {torch.float8_e4m3fn, torch.float8_e5m2}:
|
|
A = torch.randn(M, K).to(in_dtype).cuda()
|
|
B = torch.randn(N, K).to(in_dtype).cuda()
|
|
else:
|
|
A = torch.randn(M, K).to(in_dtype).cuda() - 0.5
|
|
B = torch.randn(N, K).to(in_dtype).cuda() - 0.5
|
|
|
|
C = torch.zeros(M, N, device="cuda", dtype=accum_dtype)
|
|
|
|
C = kernel(A, B)
|
|
|
|
latency = profiler.do_bench()
|
|
|
|
# Ensure that the latency is not None
|
|
assert latency is not None
|
|
|
|
# Get Reference Result
|
|
ref_c = torch.matmul(A.to(torch.float32), B.T.to(torch.float32)).to(out_dtype)
|
|
tilelang.testing.torch_assert_close(C, ref_c, rtol=1e-2, atol=1e-2)
|
|
|
|
|
|
@tilelang.testing.requires_cuda
|
|
@tilelang.testing.requires_cuda_compute_version(8, 0)
|
|
def test_assert_tl_matmul_bfloat16():
|
|
assert_tl_matmul_correctness(256, 256, 256, T.bfloat16, T.float32, T.float32)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# tilelang.testing.main()
|
|
test_assert_tl_matmul_bfloat16()
|