Skip to content

Fix TensorList issues related to dtype and lambda (when applying disallow_dtypes) - #54

Closed
rsdcastro wants to merge 6 commits into
meta-pytorch:mainfrom
rsdcastro:tensorlist
Closed

rsdcastro wants to merge 6 commits into
meta-pytorch:mainfrom
rsdcastro:tensorlist

Conversation

@rsdcastro

@rsdcastro rsdcastro commented Jan 30, 2026 •

Copy link
Copy Markdown
Contributor

This PR addresses 2 issues:

  1. If TensorList is used, we see an issue related to dtype (error below)
  2. In a spec with TensorList, if TensorConfig is provided, FACTO fails with the error below (see repro script below).

This PR also updates the unit tests to verify TensorConfig cases as well.

BEFORE

Traceback (most recent call last):
  File "/home/rdcastro/github/FACTO/examples/tensorlist_example.py", line 75, in <module>
    main()
    ~~~~^^
  File "/home/rdcastro/github/FACTO/examples/tensorlist_example.py", line 59, in main
    for posargs, inkwargs, outargs in generator1.gen():
                                      ~~~~~~~~~~~~~~^^
  File "/home/rdcastro/github/FACTO/facto/inputgen/argtuple/gen.py", line 129, in gen
    for meta_tuple in engine.gen(valid=valid):
                      ~~~~~~~~~~^^^^^^^^^^^^^
  File "/home/rdcastro/github/FACTO/facto/inputgen/argtuple/engine.py", line 127, in gen
    return self.gen_valid_meta_tuples()
           ~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/rdcastro/github/FACTO/facto/inputgen/argtuple/engine.py", line 94, in gen_valid_meta_tuples
    valid_tuples += self.gen_meta_tuples(True, ix)
                    ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
  File "/home/rdcastro/github/FACTO/facto/inputgen/argtuple/engine.py", line 86, in gen_meta_tuples
    for meta_arg in engine.gen(focus):
                    ~~~~~~~~~~^^^^^^^
  File "/home/rdcastro/github/FACTO/facto/inputgen/argument/engine.py", line 301, in gen
    yield MetaArg(
          ~~~~~~~^
        self.argtype, dtype=dtype, structure=struct, value=space
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/rdcastro/github/FACTO/facto/inputgen/argument/engine.py", line 137, in __init__
    if len(self.structure) != len(self.dtype):
                              ~~~^^^^^^^^^^^^
TypeError: object of type 'torch.dtype' has no len()

AFTER applying first fix (dtype)

$ PYTHONPATH=.:$PYTHONPATH python3 examples/tensorlist_example.py 
============================================================
Traceback (most recent call last):
  File "/home/rdcastro/github/FACTO/examples/tensorlist_example.py", line 96, in <module>
    main()
    ~~~~^^
  File "/home/rdcastro/github/FACTO/examples/tensorlist_example.py", line 80, in main
    for posargs, inkwargs, outargs in generator1.gen():
                                      ~~~~~~~~~~~~~~^^
  File "/home/rdcastro/github/FACTO/facto/inputgen/argtuple/gen.py", line 129, in gen
    for meta_tuple in engine.gen(valid=valid):
                      ~~~~~~~~~~^^^^^^^^^^^^^
  File "/home/rdcastro/github/FACTO/facto/inputgen/argtuple/engine.py", line 127, in gen
    return self.gen_valid_meta_tuples()
           ~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/rdcastro/github/FACTO/facto/inputgen/argtuple/engine.py", line 94, in gen_valid_meta_tuples
    valid_tuples += self.gen_meta_tuples(True, ix)
                    ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
  File "/home/rdcastro/github/FACTO/facto/inputgen/argtuple/engine.py", line 86, in gen_meta_tuples
    for meta_arg in engine.gen(focus):
                    ~~~~~~~~~~^^^^^^^
  File "/home/rdcastro/github/FACTO/facto/inputgen/argument/engine.py", line 299, in gen
    for dtype in self.gen_dtypes(focus):
                 ~~~~~~~~~~~~~~~^^^^^^^
  File "/home/rdcastro/github/FACTO/facto/inputgen/argument/engine.py", line 224, in gen_dtypes
    return engine.gen(focus, self.deps)
           ~~~~~~~~~~^^^^^^^^^^^^^^^^^^
  File "/home/rdcastro/github/FACTO/facto/inputgen/attribute/engine.py", line 46, in gen
    for variable in self.solve(self.constraints, focus, self.valid, *args):
                    ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/rdcastro/github/FACTO/facto/inputgen/attribute/solve.py", line 93, in solve
    res = constraint.fn(*args)
TypeError: ArgumentTupleGenerator._apply_constraints_to_arg.<locals>.<lambda>() missing 2 required positional arguments: 'length' and 'ix'

AFTER applying second fix (lambda)

$ PYTHONPATH=.:$PYTHONPATH python3 examples/tensorlist_example.py 
============================================================

Sample #1:
  tensors: TensorList with 3 tensors
    [0]: shape=[4, 8], dtype=torch.float64
    [1]: shape=[4, 8], dtype=torch.float64
    [2]: shape=[4, 8], dtype=torch.float64
  dim: 1

Sample #2:
  tensors: TensorList with 3 tensors
    [0]: shape=[4, 8], dtype=torch.float32
    [1]: shape=[4, 8], dtype=torch.float32
    [2]: shape=[4, 8], dtype=torch.float32
  dim: 0

Sample #3:
  tensors: TensorList with 3 tensors
    [0]: shape=[4, 8], dtype=torch.float64
    [1]: shape=[4, 8], dtype=torch.float64
    [2]: shape=[4, 8], dtype=torch.float64
  dim: 1

Sample #4:
  tensors: TensorList with 3 tensors
    [0]: shape=[4, 8], dtype=torch.float32
    [1]: shape=[4, 8], dtype=torch.float32
    [2]: shape=[4, 8], dtype=torch.float32
  dim: 1

Sample #5:
  tensors: TensorList with 3 tensors
    [0]: shape=[4, 8], dtype=torch.float64
    [1]: shape=[4, 8], dtype=torch.float64
    [2]: shape=[4, 8], dtype=torch.float64
  dim: 0
  ... (showing first 5 of many samples)

============================================================
Done!
============================================================

Unit tests pass locally

$ python -m unittest discover -s test/inputgen -p "*.py"
....................../home/rdcastro/github/FACTO/test/inputgen/test_config.py:143: UserWarning: TypedStorage is deprecated. It will be removed in the future and UntypedStorage will be the only storage class. This should only matter to you if you are using storages directly.  To access UntypedStorage directly, use tensor.untyped_storage() instead of tensor.storage()
  len(tensor.storage()) - tensor.storage_offset(), tensor.numel()
...............................................
----------------------------------------------------------------------
Ran 69 tests in 0.217s

OK

Example repro script

import facto.utils.dtypes as dt
from facto.inputgen.argument.type import ArgType
from facto.inputgen.argtuple.gen import ArgumentTupleGenerator
from facto.inputgen.utils.config import TensorConfig
from facto.inputgen.specs.model import (
    ConstraintProducer as cp,
    InPosArg,
    OutArg,
    Spec,
)


def create_tensorlist_spec():
    spec = Spec(
        op="example.tensorlist_op",
        inspec=[
            InPosArg(
                ArgType.TensorList,
                name="tensors",
                constraints=[
                    cp.Length.Eq(lambda deps: 3),
                    cp.Dtype.In(lambda deps: dt._floating),
                    cp.Rank.Eq(lambda deps, length, ix: 2),
                    cp.Size.Eq(lambda deps, r, d: 4 if d == 0 else None),
                    cp.Size.Eq(lambda deps, r, d: 8 if d == 1 else None),
                ],
            ),
            InPosArg(
                ArgType.Int,
                name="dim",
                constraints=[
                    cp.Value.Ge(lambda deps: 0),
                    cp.Value.Le(lambda deps: 1),
                ],
            ),
        ],
        outspec=[
            OutArg(ArgType.Tensor, name="output"),
        ],
    )
    return spec


def print_tensorlist(tensors, name="tensors"):
    """Helper to print TensorList info."""
    print(f"  {name}: TensorList with {len(tensors)} tensors")
    for i, t in enumerate(tensors):
        print(f"    [{i}]: shape={list(t.shape)}, dtype={t.dtype}")


def main():
    print("=" * 60)

    spec1 = create_tensorlist_spec()
    config = TensorConfig()
    generator1 = ArgumentTupleGenerator(spec1, config)

    count = 0
    for posargs, inkwargs, outargs in generator1.gen():
        count += 1
        if count > 5:  # Limit output
            print(f"  ... (showing first 5 of many samples)")
            break
        print(f"\nSample #{count}:")
        print_tensorlist(posargs[0], "tensors")
        print(f"  dim: {posargs[1]}")

    print("\n" + "=" * 60)

    print("Done!")
    print("=" * 60)


if __name__ == "__main__":
    main()

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Jan 30, 2026
@rsdcastro rsdcastro changed the title Fix lambda for TensorList types when applying disallow_dtypes Fix TensorList issues related to dtype and lambda (when applying disallow_dtypes) Jan 30, 2026
@meta-codesync

meta-codesync Bot commented Feb 6, 2026

Copy link
Copy Markdown

@manuelcandales has imported this pull request. If you are a Meta employee, you can view this in D92559416.

@SS-JIA SS-JIA left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Review automatically exported from Phabricator review in Meta.

@meta-codesync

meta-codesync Bot commented Feb 11, 2026

Copy link
Copy Markdown

@rsdcastro merged this pull request in 2cdc686.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot. Merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants