Skip to content

[FIX] Fix 5 ReduceSymbolicExpr / symbolic engine regressions#306

Closed
mark14wu wants to merge 4 commits intomainfrom
fix-ReduceSymbolicExpr-regressions
Closed

[FIX] Fix 5 ReduceSymbolicExpr / symbolic engine regressions#306
mark14wu wants to merge 4 commits intomainfrom
fix-ReduceSymbolicExpr-regressions

Conversation

@mark14wu
Copy link
Copy Markdown
Collaborator

@mark14wu mark14wu commented Mar 3, 2026

Summary

  • Bugs 1 & 2: UnarySymbolicExpr didn't propagate dtype, causing NoneType errors in tl.sum(tl.exp(...)) and expand_dims after tl.exp
  • Bug 3: constexpr floats lacked .to() in interpreter mode — added monkey-patch on tl.constexpr and wrap scalar constexprs in tl.constexpr
  • Bug 4: bool args hit numpy int1 bitwidth mismatch — convert bool to int before _implicit_cvt
  • Bug 5: _resolve_element_dtype returned scalar dtype instead of block_type for block pointer loads, and CastSymbolicExpr didn't preserve block_type
  • Unwrap tl.constexpr in SymbolicExpr.from_value to prevent downstream type errors from constexpr wrapping
  • Remove all 5 xfail markers from regression tests

Test plan

  • All 5 regression tests pass (test_reduce_symbolic_nonetype, test_expand_dims_scalar_attr, test_float_no_attr_to, test_numpy_int1_bitwidth, test_reduce_symbolic_core_dtype)
  • Full test suite passes (210 passed, 4 skipped)

@mark14wu mark14wu force-pushed the fix-ReduceSymbolicExpr-regressions branch from 16a2f6e to d358c4f Compare March 3, 2026 01:20
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 3, 2026

Sanitizer Performance Benchmark

Benchmark main (min) PR (min) Change
simple_load_store 0.005s 0.005s +0.3%
gemm 0.023s 0.023s +0.6%
gemm_oob 0.024s 0.024s +0.4%
indirect_load 0.076s 0.076s +0.8%
nested_loop 0.024s 0.025s +0.7%
block_pointer_loop_advance 0.007s 0.007s +1.0%
liger_jsd 0.149s 0.149s +0.3%
flaggems_layernorm 2.893s 2.888s -0.2%
Total 3.201s 3.197s -0.1%

Iterations: 1 warmup + 40 measured

mark14wu added 2 commits March 3, 2026 01:34
Remove xfail markers from 5 regression tests that reproduce bugs
introduced during the symbolic engine refactor (77be4428982c15).
These tests are expected to FAIL at this commit.
- Propagate dtype in UnarySymbolicExpr (fixes NoneType dtype in reduce/expand_dims)
- Preserve block_type in CastSymbolicExpr and _resolve_element_dtype (fixes reduce on block_ptr data)
- Monkey-patch tl.constexpr.to() for interpreter mode (fixes constexpr .to(dtype))
- Wrap scalar constexprs in tl.constexpr, convert bool args to int (fixes float .to and int1 bitwidth)
- Unwrap tl.constexpr in SymbolicExpr.from_value to prevent downstream type errors
@mark14wu mark14wu force-pushed the fix-ReduceSymbolicExpr-regressions branch from d358c4f to 4c14d42 Compare March 3, 2026 01:34

_MISSING = object()

# Monkey-patch tl.constexpr to add .to() for interpreter mode.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be in an existing function or a new function

self.add_child("src", src)
self.add_child("dst_type", dst_type)
self.dtype = self.dst_type.to_py()
dst = self.dst_type.to_py()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need a to_py here?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.dst_type is a SymbolicExpr node wrapping the actual dtype value. to_py() unwraps it to get the raw Python object (e.g. tl.float32).

# Walk the ptr chain to find the MakeBlockPtrSymbolicExpr for block shape
block_shape = None
cur: SymbolicExpr | None = ptr
while cur is not None:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cannot you just store the block_shape attribute in the symbol?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

call_args[name] = arg
ret = arg
call_args[name] = (
tl.constexpr(arg) if isinstance(arg, (int, float, bool)) else arg
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which test case would trigger this bug?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why the fix just handles int float and bool

mark14wu added 2 commits March 4, 2026 01:25
…r-regressions

# Conflicts:
#	tests/end_to_end/test_sanitizer.py
Instead of walking the ptr chain to find MakeBlockPtrSymbolicExpr,
propagate block_shape_values at construction time so it can be
looked up directly via getattr.
@mark14wu
Copy link
Copy Markdown
Collaborator Author

mark14wu commented Mar 4, 2026

Closing in favor of 4 independent PRs that split each fix into its own iteration:

Each PR carries only the minimal code fix + its specific regression test(s).

@mark14wu mark14wu closed this Mar 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants