Skip to content

dialects: (tensor) add init to tensor.from_elements#5373

Draft
positr0nium wants to merge 16 commits intoxdslproject:mainfrom
positr0nium:tensor_operations_clean
Draft

dialects: (tensor) add init to tensor.from_elements#5373
positr0nium wants to merge 16 commits intoxdslproject:mainfrom
positr0nium:tensor_operations_clean

Conversation

@positr0nium
Copy link
Contributor

Implemented the constructor of tensor.FromElementsOp and set the NoMemoryEffect trait as detailed here.

@codecov
Copy link

codecov bot commented Oct 16, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.31%. Comparing base (a139775) to head (436dcfb).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #5373   +/-   ##
=======================================
  Coverage   86.30%   86.31%           
=======================================
  Files         404      404           
  Lines       57555    57560    +5     
  Branches     6684     6685    +1     
=======================================
+ Hits        49675    49682    +7     
+ Misses       6322     6321    -1     
+ Partials     1558     1557    -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@superlopuh superlopuh changed the title Tensor operations clean dialects: *tensor) add init to tensor.from_elements Oct 16, 2025
@superlopuh superlopuh changed the title dialects: *tensor) add init to tensor.from_elements dialects: (tensor) add init to tensor.from_elements Oct 16, 2025
traits = traits_def(NoMemoryEffect())

def __init__(self, *elements: SSAValue, result_type: Attribute | None = None):
if len(elements) == 0:
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if len(elements) == 0:
if not elements:

Copy link
Member

Choose a reason for hiding this comment

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

But also I'm not sure that it's possible to call this function with an empty list? Can you please either add a test that triggers the ValueError or remove this check?

Copy link
Member

Choose a reason for hiding this comment

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

Ah no I'm wrong, you've already added the test!

Copy link
Member

Choose a reason for hiding this comment

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

I would still recommend using truthiness for checking whether a Sequence is empty or not, as it's generally an O(1) operation, as opposed to len, which is potentially an O(n) operation.

Copy link
Member

Choose a reason for hiding this comment

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

I just remembered the trick to guarantee that the number of elements is not 0:

def foo(head: int, *tail: int):
    els = (head, *tail)

Then calling this without the first element is a type error, and we don't need to check it dynamically.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is addressed here: d244700

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure but I think the testing pipeline doesn't like the hack. It passes locally for me though.

positr0nium and others added 2 commits October 22, 2025 16:30
Co-authored-by: Sasha Lopoukhine <superlopuh@gmail.com>
Co-authored-by: Sasha Lopoukhine <superlopuh@gmail.com>
@superlopuh
Copy link
Member

Hi @positr0nium, do you have time to iterate in this in the next few weeks?

@positr0nium
Copy link
Contributor Author

Hi @superlopuh a bit of time is now available :) Let's finish this soon!

@positr0nium
Copy link
Contributor Author

My local pre-commit applies formatting changes that the remote pre-commit doesn't seem to appreciate. Any ideas on how to fix this?

@superlopuh
Copy link
Member

I would recommend running make pyright, then trying again.

@superlopuh
Copy link
Member

If that doesn't work let's debug together on Zulip.

Comment on lines +710 to +714
if result_type is None:
elem_type = element_0.type
result_type = TensorType(elem_type, (len(elements) + 1,))

super().__init__(operands=[(element_0,) + elements], result_types=[result_type])
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if result_type is None:
elem_type = element_0.type
result_type = TensorType(elem_type, (len(elements) + 1,))
super().__init__(operands=[(element_0,) + elements], result_types=[result_type])
elements = (element_o,) + elements
if result_type is None:
result_type = TensorType(element_0.type, (len(elements),))
super().__init__(operands=(elements,), result_types=[result_type])

Copy link
Member

Choose a reason for hiding this comment

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

I messed up in the UI resolving this, can you please revert these changes locally?

Copy link
Member

Choose a reason for hiding this comment

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

let's revert this change

Comment on lines +165 to +184
def test_from_elements_type_consistency():
"""Test that FromElementsOp enforces type consistency among elements."""
a_i64 = create_ssa_value(i64)
b_f64 = create_ssa_value(f64)

from xdsl.utils.exceptions import VerifyException

# This should raise an assertion error due to type mismatch
res = FromElementsOp(a_i64, b_f64)
with pytest.raises(VerifyException):
res.verify()


def test_from_elements_empty_list():
"""Test FromElementsOp with an empty list."""
# Empty lists should raise a TypeError since we can't infer element type

with pytest.raises(TypeError):
FromElementsOp()

Copy link
Member

Choose a reason for hiding this comment

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

let's remove these tests, we should test for this in the dialect lit tests

Comment on lines +132 to +162
def test_from_elements_single_element():
"""Test FromElementsOp with a single element in a list."""
a = create_ssa_value(f64)

res = FromElementsOp(a)

# Check that the result is a 1-D tensor with 1 element
assert isinstance(res.result.type, TensorType)
assert res.result.type.get_shape() == (1,)
assert res.result.type.element_type == f64
assert len(res.elements) == 1
assert res.elements[0] is a


def test_from_elements_different_numeric_types():
"""Test FromElementsOp with different numeric element types."""
# Test with f64
a_f64 = create_ssa_value(f64)
b_f64 = create_ssa_value(f64)

res_f64 = FromElementsOp(a_f64, b_f64)
assert res_f64.result.type.element_type == f64
assert res_f64.result.type.get_shape() == (2,)

# Test with i64
a_i64 = create_ssa_value(i64)
b_i64 = create_ssa_value(i64)

res_i64 = FromElementsOp(a_i64, b_i64)
assert res_i64.result.type.element_type == i64
assert res_i64.result.type.get_shape() == (2,)
Copy link
Member

Choose a reason for hiding this comment

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

these seem like duplicate tests from above?

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