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
546 lines
19 KiB
Python
546 lines
19 KiB
Python
# Copyright Advanced Micro Devices, Inc., or its affiliates.
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
"""Tests for origami configuration selection."""
|
|
|
|
import pytest
|
|
import origami
|
|
import csv
|
|
from helpers import create_config_list
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_select_config_basic(hardware):
|
|
"""Test basic configuration selection."""
|
|
configs = create_config_list(hardware, "f16")
|
|
assert len(configs) > 0
|
|
|
|
problem = origami.problem_t()
|
|
problem.size = origami.dim3_t(2048, 2048, 2048)
|
|
problem.batch = 1
|
|
problem.a_transpose = origami.transpose_t.T
|
|
problem.b_transpose = origami.transpose_t.N
|
|
problem.a_dtype = origami.string_to_datatype("f16")
|
|
problem.b_dtype = origami.string_to_datatype("f16")
|
|
problem.d_dtype = origami.string_to_datatype("f16")
|
|
problem.c_dtype = problem.d_dtype
|
|
problem.mi_dtype = problem.a_dtype
|
|
problem.a_mx_block_size = 0
|
|
problem.b_mx_block_size = 0
|
|
|
|
result = origami.select_config(problem, hardware, configs, origami.model_t.gemm)
|
|
assert result.latency > 0
|
|
assert result.config is not None
|
|
assert result.config.mt.m > 0
|
|
assert result.config.mt.n > 0
|
|
assert result.config.mt.k > 0
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_rank_configs(hardware):
|
|
"""Test ranking multiple configurations."""
|
|
configs = create_config_list(hardware, "f16")
|
|
assert len(configs) > 0
|
|
|
|
problem = origami.problem_t()
|
|
problem.size = origami.dim3_t(8192, 8192, 8192)
|
|
problem.batch = 1
|
|
problem.a_transpose = origami.transpose_t.T
|
|
problem.b_transpose = origami.transpose_t.N
|
|
problem.a_dtype = origami.string_to_datatype("f16")
|
|
problem.b_dtype = origami.string_to_datatype("f16")
|
|
problem.d_dtype = origami.string_to_datatype("f16")
|
|
problem.c_dtype = problem.d_dtype
|
|
problem.mi_dtype = problem.a_dtype
|
|
|
|
ranked_configs = origami.rank_configs(problem, hardware, configs, origami.model_t.gemm)
|
|
assert len(ranked_configs) > 0
|
|
assert len(ranked_configs) <= len(configs)
|
|
|
|
# Check that results are sorted by latency (best first)
|
|
for i in range(len(ranked_configs) - 1):
|
|
assert ranked_configs[i].latency <= ranked_configs[i + 1].latency
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_select_config_mnk(hardware):
|
|
"""Test select_config_mnk function."""
|
|
configs = create_config_list(hardware, "f16")
|
|
assert len(configs) > 0
|
|
|
|
result = origami.select_config_mnk(2048, 2048, 2048, hardware, configs)
|
|
assert result.latency > 0
|
|
assert result.config is not None
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_select_topk_configs(hardware):
|
|
"""Test select_topk_configs function."""
|
|
configs = create_config_list(hardware, "f16")
|
|
assert len(configs) > 0
|
|
|
|
problem = origami.problem_t()
|
|
problem.size = origami.dim3_t(8192, 8192, 8192)
|
|
problem.batch = 1
|
|
problem.a_transpose = origami.transpose_t.T
|
|
problem.b_transpose = origami.transpose_t.N
|
|
problem.a_dtype = origami.string_to_datatype("f16")
|
|
problem.b_dtype = origami.string_to_datatype("f16")
|
|
problem.d_dtype = origami.string_to_datatype("f16")
|
|
problem.c_dtype = problem.d_dtype
|
|
problem.mi_dtype = problem.a_dtype
|
|
|
|
topk = 5
|
|
top_configs = origami.select_topk_configs(problem, hardware, configs, topk, origami.model_t.gemm)
|
|
assert len(top_configs) <= topk
|
|
assert len(top_configs) > 0
|
|
|
|
# Check that results are sorted by latency (best first)
|
|
for i in range(len(top_configs) - 1):
|
|
assert top_configs[i].latency <= top_configs[i + 1].latency
|
|
|
|
|
|
@pytest.mark.integration
|
|
@pytest.mark.slow
|
|
def test_select_config_with_csv(tmp_path, hardware):
|
|
"""Test configuration selection with CSV input file."""
|
|
# Create a test CSV file
|
|
csv_file = tmp_path / "test_sizes.csv"
|
|
with open(csv_file, "w") as f:
|
|
writer = csv.writer(f)
|
|
writer.writerow([2048, 2048, 1, 2048])
|
|
writer.writerow([4096, 4096, 1, 4096])
|
|
|
|
configs = create_config_list(hardware, "f16")
|
|
|
|
with open(csv_file, "r") as csvfile:
|
|
csv_reader = csv.reader(csvfile)
|
|
for row in csv_reader:
|
|
M = int(row[0])
|
|
N = int(row[1])
|
|
B = int(row[2])
|
|
K = int(row[3])
|
|
|
|
problem = origami.problem_t()
|
|
problem.size = origami.dim3_t(M, N, K)
|
|
problem.batch = B
|
|
problem.a_transpose = origami.transpose_t.T
|
|
problem.b_transpose = origami.transpose_t.N
|
|
problem.a_dtype = origami.string_to_datatype("f16")
|
|
problem.b_dtype = origami.string_to_datatype("f16")
|
|
problem.d_dtype = origami.string_to_datatype("f16")
|
|
problem.c_dtype = problem.d_dtype
|
|
problem.mi_dtype = problem.a_dtype
|
|
|
|
best_config = origami.select_config(problem, hardware, configs, origami.model_t.gemm)
|
|
assert best_config.latency > 0
|
|
assert best_config.config is not None
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_hardware_print(hardware):
|
|
"""Test hardware print functionality."""
|
|
# This should not raise an exception
|
|
hardware.print()
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_compute_perf_gflops(hardware):
|
|
"""Test compute_perf_gflops function."""
|
|
configs = create_config_list(hardware, "f16")
|
|
problem = origami.problem_t()
|
|
problem.size = origami.dim3_t(2048, 2048, 2048)
|
|
problem.batch = 1
|
|
problem.a_transpose = origami.transpose_t.T
|
|
problem.b_transpose = origami.transpose_t.N
|
|
problem.a_dtype = origami.string_to_datatype("f16")
|
|
problem.b_dtype = origami.string_to_datatype("f16")
|
|
problem.d_dtype = origami.string_to_datatype("f16")
|
|
problem.c_dtype = problem.d_dtype
|
|
problem.mi_dtype = problem.a_dtype
|
|
|
|
result = origami.select_config(problem, hardware, configs, origami.model_t.gemm)
|
|
gflops = origami.compute_perf_gflops(hardware, problem, result.latency)
|
|
assert gflops > 0
|
|
|
|
|
|
# StreamK Grid Selection Tests
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_select_grid_size(hardware):
|
|
"""Test grid size selection."""
|
|
problem = origami.problem_t()
|
|
problem.size = origami.dim3_t(8192, 8192, 8192)
|
|
problem.batch = 1
|
|
problem.a_transpose = origami.transpose_t.T
|
|
problem.b_transpose = origami.transpose_t.N
|
|
problem.a_dtype = origami.string_to_datatype("f16")
|
|
problem.b_dtype = origami.string_to_datatype("f16")
|
|
problem.d_dtype = origami.string_to_datatype("f16")
|
|
problem.c_dtype = problem.d_dtype
|
|
problem.mi_dtype = origami.string_to_datatype("f16")
|
|
problem.a_mx_block_size = 0
|
|
problem.b_mx_block_size = 0
|
|
|
|
config = origami.config_t()
|
|
config.mt = origami.dim3_t(32, 32, 256)
|
|
config.mi = origami.dim3_t(16, 16, 16)
|
|
config.occupancy = 1
|
|
config.workgroup_mapping = 6
|
|
|
|
grid_size = origami.select_grid_size(
|
|
problem, hardware, config, origami.grid_selection_t.analytical
|
|
)
|
|
assert grid_size > 0
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_select_reduction(hardware):
|
|
"""Test reduction strategy selection."""
|
|
problem = origami.problem_t()
|
|
problem.size = origami.dim3_t(8192, 8192, 8192)
|
|
problem.batch = 1
|
|
problem.a_transpose = origami.transpose_t.T
|
|
problem.b_transpose = origami.transpose_t.N
|
|
problem.a_dtype = origami.string_to_datatype("f16")
|
|
problem.b_dtype = origami.string_to_datatype("f16")
|
|
problem.d_dtype = origami.string_to_datatype("f16")
|
|
problem.c_dtype = problem.d_dtype
|
|
problem.mi_dtype = origami.string_to_datatype("f16")
|
|
|
|
config = origami.config_t()
|
|
config.mt = origami.dim3_t(32, 32, 256)
|
|
config.mi = origami.dim3_t(16, 16, 16)
|
|
config.occupancy = 1
|
|
config.workgroup_mapping = 6
|
|
|
|
reduction = origami.select_reduction(
|
|
problem, hardware, config, origami.grid_selection_t.analytical
|
|
)
|
|
assert reduction is not None
|
|
|
|
|
|
@pytest.mark.integration
|
|
@pytest.mark.parametrize(
|
|
"algorithm",
|
|
[
|
|
origami.grid_selection_t.number_of_cus,
|
|
origami.grid_selection_t.min_resources,
|
|
origami.grid_selection_t.energy_aware,
|
|
origami.grid_selection_t.reduction_cost_aware,
|
|
origami.grid_selection_t.data_parallel,
|
|
origami.grid_selection_t.analytical,
|
|
origami.grid_selection_t.k_split_aware,
|
|
],
|
|
)
|
|
def test_select_grid_size_algorithms(hardware, algorithm):
|
|
"""Test different grid selection algorithms."""
|
|
problem = origami.problem_t()
|
|
problem.size = origami.dim3_t(8192, 8192, 8192)
|
|
problem.batch = 1
|
|
problem.a_transpose = origami.transpose_t.T
|
|
problem.b_transpose = origami.transpose_t.N
|
|
problem.a_dtype = origami.string_to_datatype("f16")
|
|
problem.b_dtype = origami.string_to_datatype("f16")
|
|
problem.d_dtype = origami.string_to_datatype("f16")
|
|
problem.c_dtype = problem.d_dtype
|
|
problem.mi_dtype = origami.string_to_datatype("f16")
|
|
|
|
config = origami.config_t()
|
|
config.mt = origami.dim3_t(32, 32, 256)
|
|
config.mi = origami.dim3_t(16, 16, 16)
|
|
config.occupancy = 1
|
|
config.workgroup_mapping = 6
|
|
|
|
grid_size = origami.select_grid_size(problem, hardware, config, algorithm)
|
|
assert grid_size > 0
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_compute_number_of_output_tiles():
|
|
"""Test compute_number_of_output_tiles function."""
|
|
num_tiles = origami.compute_number_of_output_tiles(32, 32, 8192, 8192, 1)
|
|
assert num_tiles > 0
|
|
assert num_tiles == (8192 // 32) * (8192 // 32) * 1
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_select_workgroup_mapping(hardware):
|
|
"""Test workgroup mapping selection."""
|
|
problem = origami.problem_t()
|
|
problem.size = origami.dim3_t(8192, 8192, 8192)
|
|
problem.batch = 1
|
|
problem.a_transpose = origami.transpose_t.T
|
|
problem.b_transpose = origami.transpose_t.N
|
|
problem.a_dtype = origami.string_to_datatype("f16")
|
|
problem.b_dtype = origami.string_to_datatype("f16")
|
|
problem.d_dtype = origami.string_to_datatype("f16")
|
|
problem.c_dtype = problem.d_dtype
|
|
problem.mi_dtype = origami.string_to_datatype("f16")
|
|
|
|
config = origami.config_t()
|
|
config.mt = origami.dim3_t(32, 32, 256)
|
|
config.mi = origami.dim3_t(16, 16, 16)
|
|
config.occupancy = 1
|
|
config.workgroup_mapping = 6
|
|
|
|
sk_grid = 100
|
|
result = origami.select_workgroup_mapping(problem, hardware, config, sk_grid)
|
|
assert isinstance(result, origami.workgroup_mapping_t)
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_gfx950_bfloat16_recommended_matrix_instruction():
|
|
"""Test that gfx950 recommends 16x16x32 matrix instruction for bfloat16."""
|
|
# Create hardware object for gfx950
|
|
hardware = origami.hardware_t(
|
|
origami.architecture_t.gfx950,
|
|
304, # N_CU
|
|
65536, # lds_capacity
|
|
512 * 1024, # rf_capacity
|
|
12, # NUM_XCD
|
|
1.0, # mem1_perf_ratio
|
|
1.0, # mem2_perf_ratio
|
|
1.0, # mem3_perf_ratio
|
|
25165824, # L2_capacity
|
|
2.1, # compute_clock_ghz
|
|
4, # parallel_mi_cu
|
|
(1.0, 1.0, 1.0), # mem_bw_per_wg_coefficients
|
|
None, # pci_chip_id
|
|
)
|
|
|
|
# Get recommended matrix instruction for bfloat16
|
|
bfloat16_dtype = origami.data_type_t.BFloat16
|
|
recommended_mi = hardware.get_recommended_matrix_instruction(bfloat16_dtype)
|
|
|
|
# Verify it's 16x16x32
|
|
assert recommended_mi.m == 16, f"Expected m=16, got {recommended_mi.m}"
|
|
assert recommended_mi.n == 16, f"Expected n=16, got {recommended_mi.n}"
|
|
assert recommended_mi.k == 32, f"Expected k=32, got {recommended_mi.k}"
|
|
|
|
|
|
# Formocast Simulation Mode Tests
|
|
|
|
@pytest.mark.integration
|
|
def test_prediction_modes_enum_exists():
|
|
"""Test that prediction_modes_t enum is available."""
|
|
assert hasattr(origami, 'prediction_modes_t')
|
|
assert hasattr(origami.prediction_modes_t, 'estimation')
|
|
assert hasattr(origami.prediction_modes_t, 'simulation')
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_config_has_formocast_fields():
|
|
"""Test that config_t has Formocast-specific fields via variant backend."""
|
|
config = origami.config_t()
|
|
|
|
# Check prediction_mode field
|
|
assert hasattr(config, 'prediction_mode')
|
|
|
|
# Check tensile accessor method exists
|
|
assert hasattr(config, 'tensile')
|
|
assert callable(config.tensile)
|
|
assert hasattr(config, 'has_tensile_params')
|
|
assert hasattr(config, 'set_tensile_params')
|
|
|
|
# Get tensile params (initializes if not set)
|
|
tensile = config.tensile()
|
|
|
|
# Check vectorization fields on config (generic, not Tensile-specific)
|
|
assert hasattr(config, 'grvw_a')
|
|
assert hasattr(config, 'grvw_b')
|
|
assert hasattr(config, 'gwvw_d')
|
|
assert hasattr(config, 'vector_width_a')
|
|
assert hasattr(config, 'vector_width_b')
|
|
|
|
# Check Tensile-specific fields
|
|
assert hasattr(tensile, 'depth_u')
|
|
assert hasattr(tensile, 'global_split_u')
|
|
assert hasattr(tensile, 'global_accumulation')
|
|
assert hasattr(tensile, 'local_split_u')
|
|
assert hasattr(tensile, 'direct_to_vgpr_a')
|
|
assert hasattr(tensile, 'direct_to_vgpr_b')
|
|
assert hasattr(tensile, 'wave_num')
|
|
assert hasattr(tensile, 'wave_group_m')
|
|
assert hasattr(tensile, 'wave_group_n')
|
|
assert hasattr(tensile, 'prefetch_global_read')
|
|
|
|
# Verify has_tensile_params returns True after accessing
|
|
assert config.has_tensile_params()
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_simulation_mode_returns_valid_latency():
|
|
"""Test that simulation mode returns a valid positive latency."""
|
|
# Create hardware for gfx942
|
|
hardware = origami.hardware_t(
|
|
origami.architecture_t.gfx942,
|
|
304, # N_CU
|
|
65536, # lds_capacity
|
|
512 * 1024, # rf_capacity
|
|
8, # NUM_XCD
|
|
1.0, # mem1_perf_ratio
|
|
1.0, # mem2_perf_ratio
|
|
1.0, # mem3_perf_ratio
|
|
4000000, # L2_capacity
|
|
1.5, # compute_clock_ghz
|
|
1, # parallel_mi_cu
|
|
(0.0, 0.015, 0.0), # mem_bw_per_wg_coefficients
|
|
None,
|
|
)
|
|
|
|
# Create problem
|
|
problem = origami.problem_t()
|
|
problem.size = origami.dim3_t(2048, 2048, 2048)
|
|
problem.batch = 1
|
|
problem.a_transpose = origami.transpose_t.T
|
|
problem.b_transpose = origami.transpose_t.N
|
|
problem.a_dtype = origami.data_type_t.Half
|
|
problem.b_dtype = origami.data_type_t.Half
|
|
problem.c_dtype = origami.data_type_t.Half
|
|
problem.d_dtype = origami.data_type_t.Half
|
|
problem.mi_dtype = origami.data_type_t.Half
|
|
|
|
# Create config with simulation mode
|
|
config = origami.config_t()
|
|
config.mt = origami.dim3_t(128, 128, 32)
|
|
config.mi = origami.dim3_t(16, 16, 16)
|
|
config.occupancy = 2
|
|
config.workgroup_mapping = 8
|
|
config.prediction_mode = origami.prediction_modes_t.simulation
|
|
|
|
# Set Formocast-specific parameters (via tensile nested struct)
|
|
config.tensile().depth_u = 32
|
|
config.tensile().global_split_u = 1
|
|
config.grvw_a = 4
|
|
config.grvw_b = 4
|
|
config.gwvw_d = 4
|
|
config.tensile().wave_num = 4
|
|
config.tensile().wave_group_m = 2
|
|
config.tensile().wave_group_n = 2
|
|
config.tensile().prefetch_global_read = 2
|
|
|
|
# Call compute_total_latency with simulation mode
|
|
latency = origami.compute_total_latency(problem, hardware, config)
|
|
|
|
assert latency > 0, f"Expected positive latency, got {latency}"
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_simulation_mode_via_compute_total_latency():
|
|
"""Test that compute_total_latency uses Formocast when prediction_mode is simulation."""
|
|
# Create hardware for gfx942
|
|
hardware = origami.hardware_t(
|
|
origami.architecture_t.gfx942,
|
|
304, # N_CU
|
|
65536, # lds_capacity
|
|
512 * 1024, # rf_capacity
|
|
8, # NUM_XCD
|
|
1.0, # mem1_perf_ratio
|
|
1.0, # mem2_perf_ratio
|
|
1.0, # mem3_perf_ratio
|
|
4000000, # L2_capacity
|
|
1.5, # compute_clock_ghz
|
|
1, # parallel_mi_cu
|
|
(0.0, 0.015, 0.0), # mem_bw_per_wg_coefficients
|
|
None,
|
|
)
|
|
|
|
# Create problem
|
|
problem = origami.problem_t()
|
|
problem.size = origami.dim3_t(2048, 2048, 2048)
|
|
problem.batch = 1
|
|
problem.a_transpose = origami.transpose_t.T
|
|
problem.b_transpose = origami.transpose_t.N
|
|
problem.a_dtype = origami.data_type_t.Half
|
|
problem.b_dtype = origami.data_type_t.Half
|
|
problem.c_dtype = origami.data_type_t.Half
|
|
problem.d_dtype = origami.data_type_t.Half
|
|
problem.mi_dtype = origami.data_type_t.Half
|
|
|
|
# Create config with estimation mode
|
|
config_estimation = origami.config_t()
|
|
config_estimation.mt = origami.dim3_t(128, 128, 32)
|
|
config_estimation.mi = origami.dim3_t(16, 16, 16)
|
|
config_estimation.occupancy = 2
|
|
config_estimation.workgroup_mapping = 8
|
|
config_estimation.prediction_mode = origami.prediction_modes_t.estimation
|
|
|
|
# Create config with simulation mode
|
|
config_simulation = origami.config_t()
|
|
config_simulation.mt = origami.dim3_t(128, 128, 32)
|
|
config_simulation.mi = origami.dim3_t(16, 16, 16)
|
|
config_simulation.occupancy = 2
|
|
config_simulation.workgroup_mapping = 8
|
|
config_simulation.prediction_mode = origami.prediction_modes_t.simulation
|
|
config_simulation.tensile().depth_u = 32
|
|
config_simulation.tensile().global_split_u = 1
|
|
config_simulation.grvw_a = 4
|
|
config_simulation.grvw_b = 4
|
|
config_simulation.gwvw_d = 4
|
|
config_simulation.tensile().wave_num = 4
|
|
config_simulation.tensile().wave_group_m = 2
|
|
config_simulation.tensile().wave_group_n = 2
|
|
config_simulation.tensile().prefetch_global_read = 2
|
|
|
|
# Get latencies from both modes
|
|
latency_estimation = origami.compute_total_latency(
|
|
problem, hardware, config_estimation)
|
|
latency_simulation = origami.compute_total_latency(
|
|
problem, hardware, config_simulation)
|
|
|
|
# Both should return positive values
|
|
assert latency_estimation > 0, f"Estimation latency should be positive: {latency_estimation}"
|
|
assert latency_simulation > 0, f"Simulation latency should be positive: {latency_simulation}"
|
|
|
|
# The values should be different (different models)
|
|
# Note: They use different units (cycles vs microseconds), so they will definitely differ
|
|
assert latency_estimation != latency_simulation, \
|
|
"Estimation and simulation should produce different results"
|
|
|
|
|
|
@pytest.mark.integration
|
|
@pytest.mark.parametrize("m,n,k", [
|
|
(1024, 1024, 1024),
|
|
(2048, 2048, 2048),
|
|
(4096, 4096, 512),
|
|
(512, 4096, 4096),
|
|
])
|
|
def test_simulation_mode_various_problem_sizes(m, n, k):
|
|
"""Test simulation mode with various problem sizes."""
|
|
# Create hardware for gfx942
|
|
hardware = origami.hardware_t(
|
|
origami.architecture_t.gfx942,
|
|
304, 65536, 512 * 1024, 8, 1.0, 1.0, 1.0, 4000000, 1.5, 1, (0.0, 0.015, 0.0), None
|
|
)
|
|
|
|
problem = origami.problem_t()
|
|
problem.size = origami.dim3_t(m, n, k)
|
|
problem.batch = 1
|
|
problem.a_transpose = origami.transpose_t.T
|
|
problem.b_transpose = origami.transpose_t.N
|
|
problem.a_dtype = origami.data_type_t.Half
|
|
problem.b_dtype = origami.data_type_t.Half
|
|
problem.c_dtype = origami.data_type_t.Half
|
|
problem.d_dtype = origami.data_type_t.Half
|
|
problem.mi_dtype = origami.data_type_t.Half
|
|
|
|
config = origami.config_t()
|
|
config.mt = origami.dim3_t(128, 128, 32)
|
|
config.mi = origami.dim3_t(16, 16, 16)
|
|
config.occupancy = 2
|
|
config.workgroup_mapping = 8
|
|
config.prediction_mode = origami.prediction_modes_t.simulation
|
|
config.tensile().depth_u = 32
|
|
config.tensile().global_split_u = 1
|
|
config.grvw_a = 4
|
|
config.grvw_b = 4
|
|
config.gwvw_d = 4
|
|
config.tensile().wave_num = 4
|
|
config.tensile().wave_group_m = 2
|
|
config.tensile().wave_group_n = 2
|
|
|
|
latency = origami.compute_total_latency(problem, hardware, config)
|
|
assert latency > 0, f"Expected positive latency for {m}x{n}x{k}, got {latency}"
|