Unverified Commit 17f65139 authored by PanZezhong1725's avatar PanZezhong1725 Committed by GitHub
Browse files

Merge pull request #604 from InfiniTensor/issue/602

Issue/602 - 给变量起个名字
parents b7d9252b c8df7bd1
...@@ -18,6 +18,7 @@ from .utils import ( ...@@ -18,6 +18,7 @@ from .utils import (
@dataclass @dataclass
class TestResult: class TestResult:
"""Test result data structure""" """Test result data structure"""
success: bool success: bool
return_code: int # 0: success, -1: failure, -2: skipped, -3: partial return_code: int # 0: success, -1: failure, -2: skipped, -3: partial
torch_time: float = 0.0 torch_time: float = 0.0
...@@ -57,26 +58,29 @@ class TestCase: ...@@ -57,26 +58,29 @@ class TestCase:
self.inputs = [] self.inputs = []
# Process inputs - support both single TensorSpecs and tuples of TensorSpecs # Process inputs - support both single TensorSpecs and tuples of TensorSpecs
for inp in inputs: for i, inp in enumerate(inputs):
if isinstance(inp, (list, tuple)): if isinstance(inp, (list, tuple)):
# Handle tuple/list of multiple TensorSpecs (e.g., for torch.cat) # Handle tuple/list of multiple TensorSpecs (e.g., for torch.cat)
processed_tuple = [] processed_tuple = []
for item in inp: for j, item in enumerate(inp):
if isinstance(item, (list, tuple)): if isinstance(item, (list, tuple)):
# Nested tuple - recursively process # Nested tuple - recursively process
nested_processed = [] nested_processed = []
for nested_item in item: for k, nested_item in enumerate(item):
if isinstance(nested_item, TensorSpec): if isinstance(nested_item, TensorSpec):
nested_item.fill_name(f"in_{i}_{j}_{k}")
nested_processed.append(nested_item) nested_processed.append(nested_item)
else: else:
nested_processed.append(nested_item) nested_processed.append(nested_item)
processed_tuple.append(tuple(nested_processed)) processed_tuple.append(tuple(nested_processed))
elif isinstance(item, TensorSpec): elif isinstance(item, TensorSpec):
item.fill_name(f"in_{i}_{j}")
processed_tuple.append(item) processed_tuple.append(item)
else: else:
processed_tuple.append(item) processed_tuple.append(item)
self.inputs.append(tuple(processed_tuple)) self.inputs.append(tuple(processed_tuple))
elif isinstance(inp, TensorSpec): elif isinstance(inp, TensorSpec):
inp.fill_name(f"in_{i}")
self.inputs.append(inp) self.inputs.append(inp)
else: else:
self.inputs.append(inp) self.inputs.append(inp)
...@@ -89,6 +93,10 @@ class TestCase: ...@@ -89,6 +93,10 @@ class TestCase:
self.tolerance = tolerance or {"atol": 1e-5, "rtol": 1e-3} self.tolerance = tolerance or {"atol": 1e-5, "rtol": 1e-3}
self.output_count = output_count self.output_count = output_count
if self.output_count > 1 and self.output_specs is not None:
for idx, spec in enumerate(self.output_specs):
spec.fill_name(f"out_{idx}")
# Validate output configuration # Validate output configuration
if self.output_count == 1: if self.output_count == 1:
if self.output_specs is not None: if self.output_specs is not None:
...@@ -124,45 +132,15 @@ class TestCase: ...@@ -124,45 +132,15 @@ class TestCase:
# Handle tuple inputs (e.g., for torch.cat) # Handle tuple inputs (e.g., for torch.cat)
tuple_strs = [] tuple_strs = []
for item in inp: for item in inp:
if hasattr(item, "is_scalar") and item.is_scalar: if isinstance(item, (list, tuple)):
dtype_str = f", dtype={item.dtype}" if item.dtype else "" # Handle nested tuples
tuple_strs.append(f"scalar({item.value}{dtype_str})") nested_strs = []
elif hasattr(item, "shape"): for nested_item in item:
dtype_str = f", {item.dtype}" if item.dtype else "" nested_strs.append(str(nested_item))
init_str = ( tuple_strs.append(f"tuple({', '.join(nested_strs)})")
f", init={item.init_mode}"
if item.init_mode != TensorInitializer.RANDOM
else ""
)
if hasattr(item, "strides") and item.strides:
strides_str = f", strides={item.strides}"
tuple_strs.append(
f"tensor{item.shape}{strides_str}{dtype_str}{init_str}"
)
else:
tuple_strs.append(
f"tensor{item.shape}{dtype_str}{init_str}"
)
else: else:
tuple_strs.append(str(item)) tuple_strs.append(str(item))
input_strs.append(f"tuple({'; '.join(tuple_strs)})") input_strs.append(f"tuple({'; '.join(tuple_strs)})")
elif hasattr(inp, "is_scalar") and inp.is_scalar:
dtype_str = f", dtype={inp.dtype}" if inp.dtype else ""
input_strs.append(f"scalar({inp.value}{dtype_str})")
elif hasattr(inp, "shape"):
dtype_str = f", {inp.dtype}" if inp.dtype else ""
init_str = (
f", init={inp.init_mode}"
if inp.init_mode != TensorInitializer.RANDOM
else ""
)
if hasattr(inp, "strides") and inp.strides:
strides_str = f", strides={inp.strides}"
input_strs.append(
f"tensor{inp.shape}{strides_str}{dtype_str}{init_str}"
)
else:
input_strs.append(f"tensor{inp.shape}{dtype_str}{init_str}")
else: else:
input_strs.append(str(inp)) input_strs.append(str(inp))
...@@ -175,48 +153,16 @@ class TestCase: ...@@ -175,48 +153,16 @@ class TestCase:
kwargs_strs = [] kwargs_strs = []
for key, value in self.kwargs.items(): for key, value in self.kwargs.items():
if key == "out" and isinstance(value, int): if key == "out" and isinstance(value, int):
kwargs_strs.append(f"{key}={value}") kwargs_strs.append(f"{key}={self.inputs[value].name}")
else: else:
kwargs_strs.append(f"{key}={value}") kwargs_strs.append(f"{key}={value}")
# Handle output specifications # Handle output specifications using TensorSpec's __str__
if self.output_count == 1 and self.output_spec: if self.output_count == 1 and self.output_spec:
dtype_str = ( kwargs_strs.append(f"out={self.output_spec}")
f", {self.output_spec.dtype}" if self.output_spec.dtype else ""
)
init_str = (
f", init={self.output_spec.init_mode}"
if self.output_spec.init_mode != TensorInitializer.RANDOM
else ""
)
if hasattr(self.output_spec, "strides") and self.output_spec.strides:
strides_str = f", strides={self.output_spec.strides}"
kwargs_strs.append(
f"out=tensor{self.output_spec.shape}{strides_str}{dtype_str}{init_str}"
)
else:
kwargs_strs.append(
f"out=tensor{self.output_spec.shape}{dtype_str}{init_str}"
)
elif self.output_count > 1 and self.output_specs: elif self.output_count > 1 and self.output_specs:
output_strs = []
for i, spec in enumerate(self.output_specs): for i, spec in enumerate(self.output_specs):
dtype_str = f", {spec.dtype}" if spec.dtype else "" kwargs_strs.append(f"out_{i}={spec}")
init_str = (
f", init={spec.init_mode}"
if spec.init_mode != TensorInitializer.RANDOM
else ""
)
if hasattr(spec, "strides") and spec.strides:
strides_str = f", strides={spec.strides}"
output_strs.append(
f"out_{i}=tensor{spec.shape}{strides_str}{dtype_str}{init_str}"
)
else:
output_strs.append(
f"out_{i}=tensor{spec.shape}{dtype_str}{init_str}"
)
kwargs_strs.extend(output_strs)
base_str += f", kwargs={{{'; '.join(kwargs_strs)}}}" base_str += f", kwargs={{{'; '.join(kwargs_strs)}}}"
...@@ -300,11 +246,15 @@ class TestRunner: ...@@ -300,11 +246,15 @@ class TestRunner:
elif test_result.return_code == -2: # Skipped elif test_result.return_code == -2: # Skipped
skip_msg = f"{test_case} - {InfiniDeviceNames[device]} - Both operators not implemented" skip_msg = f"{test_case} - {InfiniDeviceNames[device]} - Both operators not implemented"
self.skipped_tests.append(skip_msg) self.skipped_tests.append(skip_msg)
print(f"\033[93m⚠\033[0m Both operators not implemented - test skipped") print(
f"\033[93m⚠\033[0m Both operators not implemented - test skipped"
)
elif test_result.return_code == -3: # Partial elif test_result.return_code == -3: # Partial
partial_msg = f"{test_case} - {InfiniDeviceNames[device]} - One operator not implemented" partial_msg = f"{test_case} - {InfiniDeviceNames[device]} - One operator not implemented"
self.partial_tests.append(partial_msg) self.partial_tests.append(partial_msg)
print(f"\033[93m⚠\033[0m One operator not implemented - running single operator without comparison") print(
f"\033[93m⚠\033[0m One operator not implemented - running single operator without comparison"
)
if self.config.verbose and test_result.return_code != 0: if self.config.verbose and test_result.return_code != 0:
return False return False
...@@ -322,7 +272,7 @@ class TestRunner: ...@@ -322,7 +272,7 @@ class TestRunner:
return_code=-1, return_code=-1,
error_message=str(e), error_message=str(e),
test_case=test_case, test_case=test_case,
device=device device=device,
) )
self.test_results.append(failed_result) self.test_results.append(failed_result)
# In verbose mode, print full traceback and stop execution # In verbose mode, print full traceback and stop execution
...@@ -333,7 +283,11 @@ class TestRunner: ...@@ -333,7 +283,11 @@ class TestRunner:
if self.config.debug: if self.config.debug:
raise raise
return len(self.failed_tests) == 0 and len(self.skipped_tests) == 0 and len(self.partial_tests) == 0 return (
len(self.failed_tests) == 0
and len(self.skipped_tests) == 0
and len(self.partial_tests) == 0
)
def print_summary(self): def print_summary(self):
""" """
...@@ -520,7 +474,7 @@ class BaseOperatorTest(ABC): ...@@ -520,7 +474,7 @@ class BaseOperatorTest(ABC):
success=False, success=False,
return_code=-1, # Default to failure return_code=-1, # Default to failure
test_case=test_case, test_case=test_case,
device=device device=device,
) )
# Prepare inputs and kwargs with actual tensors # Prepare inputs and kwargs with actual tensors
......
...@@ -284,6 +284,7 @@ class TensorSpec: ...@@ -284,6 +284,7 @@ class TensorSpec:
self.is_scalar = is_scalar self.is_scalar = is_scalar
self.init_mode = init_mode self.init_mode = init_mode
self.kwargs = kwargs self.kwargs = kwargs
self.name = kwargs.get("name") if kwargs.get("name") else None
@classmethod @classmethod
def from_tensor( def from_tensor(
...@@ -339,10 +340,17 @@ class TensorSpec: ...@@ -339,10 +340,17 @@ class TensorSpec:
"""Check if this spec represents a tensor input (not scalar)""" """Check if this spec represents a tensor input (not scalar)"""
return not self.is_scalar return not self.is_scalar
def fill_name(self, name):
if self.name is None:
self.name = name
def __str__(self): def __str__(self):
name_str = f"{self.name}: " if self.name else ""
if self.is_scalar: if self.is_scalar:
return f"scalar({self.value})" return f"{name_str}scalar({self.value})"
else: else:
strides_str = f", strides={self.strides}" if self.strides else "" strides_str = f", strides={self.strides}" if self.strides else ""
dtype_str = f", dtype={self.dtype}" if self.dtype else "" dtype_str = (
return f"tensor{self.shape}{strides_str}{dtype_str}" f", {str(self.dtype).replace("infinicore.", "")}" if self.dtype else ""
)
return f"{name_str}tensor{self.shape}{strides_str}{dtype_str}"
...@@ -65,9 +65,9 @@ def parse_test_cases(): ...@@ -65,9 +65,9 @@ def parse_test_cases():
tolerance = _TOLERANCE_MAP.get(dtype, {"atol": 0, "rtol": 1e-3}) tolerance = _TOLERANCE_MAP.get(dtype, {"atol": 0, "rtol": 1e-3})
# Create typed tensor specs # Create typed tensor specs
a_spec = TensorSpec.from_tensor(shape, a_strides, dtype) a_spec = TensorSpec.from_tensor(shape, a_strides, dtype, name="a")
b_spec = TensorSpec.from_tensor(shape, b_strides, dtype) b_spec = TensorSpec.from_tensor(shape, b_strides, dtype, name="b")
c_spec = TensorSpec.from_tensor(shape, c_strides, dtype) c_spec = TensorSpec.from_tensor(shape, c_strides, dtype, name="c")
# Test Case 1: Out-of-place (return value) # Test Case 1: Out-of-place (return value)
test_cases.append( test_cases.append(
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment