Skip to content

[BugFix] Keep multi-discrete masks boolean when casting specs - #4591

Open
mottopanikeiku wants to merge 1 commit into
pytorch:mainfrom
mottopanikeiku:fix/masked-spec-dtype
Open

mottopanikeiku wants to merge 1 commit into
pytorch:mainfrom
mottopanikeiku:fix/masked-spec-dtype

Conversation

@mottopanikeiku

@mottopanikeiku mottopanikeiku commented Oct 17, 2026 •

Copy link
Copy Markdown

Description

MultiCategorical.to and MultiOneHot.to cast their masks to the requested sample dtype. The new specs then reject those masks because they are no longer boolean. I now move each mask only to dest_device. The requested sample dtype and the existing device-conversion behavior are unchanged. I also documented that masks stay boolean during dtype conversion.

A small reproducer:

import torch
from torchrl.data import MultiCategorical, MultiOneHot

mask = torch.tensor([False, True, False, True, False])
for cls in (MultiCategorical, MultiOneHot):
    try:
        spec = cls([3, 2], mask=mask).to(torch.int32)
        print(cls.__name__, spec.rand().tolist(), spec.mask.dtype)
    except ValueError as err:
        print(cls.__name__, type(err).__name__, str(err))
main This PR
MultiCategorical.to(torch.int32) ValueError Only boolean masks are accepted. [1, 0] torch.bool
MultiOneHot.to(torch.int32) ValueError Only boolean masks are accepted. [0, 1, 0, 1, 0] torch.bool

Tests:

  • Both cases of TestTo.test_multi_masked_dtype fail on main. The test checks exact allowed actions, sample dtype, mask dtype, and that the original spec is unchanged.
  • With the fix, test/test_specs.py: 1822 passed, 9 skipped.
  • pre-commit passes on the changed files.
  • I tested the Python sources without building the optional C++ extension; these spec operations do not use it.

Motivation and Context

Changing the tensor dtype of a valid masked action spec should not invalidate its boolean action mask.

close #4589

  • I have raised an issue to propose this change (required for new features and bug fixes)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • I have read the CONTRIBUTION guide (required)
  • My change requires a change to the documentation.
  • I have updated the tests accordingly (required for a bug fix or a new feature).
  • I have updated the documentation accordingly.

I used AI assistance (Claude and GPT-6 Astra) to find, fix and test this bug.

MultiCategorical.to(dtype) and MultiOneHot.to(dtype) cast the mask to the
new dtype too, so the new spec rejected it with "Only boolean masks are
accepted". I move the mask to the target device only.

Assisted-by: Claude
Assisted-by: GPT-6 Astra
Signed-off-by: mottopanikeiku <176798723+mottopanikeiku@users.noreply.github.com>
@pytorch-bot

pytorch-bot Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/rl/4591

Note: Links to docs will display an error until the docs builds have been completed.

⚠️ 16 Awaiting Approval

As of commit 11dfb8b with merge base e7a05a7 (image):

AWAITING APPROVAL - The following workflows need approval before CI can run:

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 17, 2026

This branch has not been deployed

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

Labels

BugFix CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Casting masked MultiCategorical and MultiOneHot specs rejects their masks

1 participant