[Relax][PyTorch] Cast non-bool inputs to bool in logical_and converter#19679
[Relax][PyTorch] Cast non-bool inputs to bool in logical_and converter#19679javierdejesusda wants to merge 1 commit into
Conversation
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.
There was a problem hiding this comment.
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.
cchung100m
left a comment
There was a problem hiding this comment.
LGTM, thanks to @javierdejesusda
Motivation
torch.logical_andaccepts input tensors of any dtype (treating any nonzeroelement as
True) and always returns abooltensor.The PyTorch frontend did not produce that
boolresult. The ExportedProgramfrontend lowered
logical_and.defaultwithself._binary_op(relax.op.logical_and, operator.and_), which kept the operanddtype and emitted
relax.op.logical_andon non-bool inputs (for examplefloat32).relax.op.logical_andrequires boolean inputs and otherwise failsLegalizeOpsin the TOPIlogical_and. The FX frontend did not registerlogical_andat all, so the op was unsupported there.Changes
_logical_andconverter inBaseFXGraphImporterthat castsnon-bool operands to
boolbefore applyingrelax.op.logical_and. Booloperands are passed through unchanged (no redundant cast).
logical_and.default(ExportedProgram) registration at the newconverter, and add a
logical_and(FX) registration that was previouslymissing, matching the existing
logical_notconverter.test_logical_andto both the FX and ExportedProgram testsuites asserting the corrected IR (
astypeto bool on each operand, thenlogical_and, producing abooloutput).Notes
The cast to
boollowers to an elementwise nonzero test, so it matchesPyTorch's "nonzero is True" semantics for float, integer, and NaN inputs.