Skip to content

[Relax][PyTorch] Cast non-bool inputs to bool in logical_and converter#19679

Open
javierdejesusda wants to merge 1 commit into
apache:mainfrom
javierdejesusda:relax-torch-logical-and-bool
Open

[Relax][PyTorch] Cast non-bool inputs to bool in logical_and converter#19679
javierdejesusda wants to merge 1 commit into
apache:mainfrom
javierdejesusda:relax-torch-logical-and-bool

Conversation

@javierdejesusda
Copy link
Copy Markdown
Contributor

Motivation

torch.logical_and accepts input tensors of any dtype (treating any nonzero
element as True) and always returns a bool tensor.

The PyTorch frontend did not produce that bool result. The ExportedProgram
frontend lowered logical_and.default with
self._binary_op(relax.op.logical_and, operator.and_), which kept the operand
dtype and emitted relax.op.logical_and on non-bool inputs (for example
float32). relax.op.logical_and requires boolean inputs and otherwise fails
LegalizeOps in the TOPI logical_and. The FX frontend did not register
logical_and at all, so the op was unsupported there.

Changes

  • Add a shared _logical_and converter in BaseFXGraphImporter that casts
    non-bool operands to bool before applying relax.op.logical_and. Bool
    operands are passed through unchanged (no redundant cast).
  • Point the logical_and.default (ExportedProgram) registration at the new
    converter, and add a logical_and (FX) registration that was previously
    missing, matching the existing logical_not converter.
  • Add a standalone test_logical_and to both the FX and ExportedProgram test
    suites asserting the corrected IR (astype to bool on each operand, then
    logical_and, producing a bool output).

Notes

The cast to bool lowers to an elementwise nonzero test, so it matches
PyTorch's "nonzero is True" semantics for float, integer, and NaN inputs.

torch.logical_and returns a boolean tensor for any input dtype, but relax.op.logical_and requires boolean inputs. The exported-program frontend lowered logical_and directly to relax.op.logical_and, which fails LegalizeOps for non-bool inputs, and the FX frontend did not support logical_and at all. Add a shared converter that casts non-bool operands to bool first, matching torch and the existing logical_not converter, and register it for both frontends.
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request implements a custom translator for torch.logical_and in the TVM Relax PyTorch frontend. The new _logical_and method casts non-boolean inputs to boolean first, aligning with PyTorch's behavior. This translator is registered in both FX and Exported Program translators, and corresponding tests are added. A review comment suggests adding safety checks to ensure struct_info is an instance of relax.TensorStructInfo before accessing its dtype to prevent potential AttributeErrors.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread python/tvm/relax/frontend/torch/base_fx_graph_translator.py
Copy link
Copy Markdown
Contributor

@cchung100m cchung100m left a comment

Choose a reason for hiding this comment

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

LGTM, thanks to @javierdejesusda

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