Skip to content

Fix Jacobian output dtypes for mixed precision differentiation - #129941

Merged
copybara-service[bot] merged 2 commits into
tensorflow:masterfrom
shoutoutuoadi325:fix-jacobian-source-dtypes
Nov 9, 2026
Merged

copybara-service[bot] merged 2 commits into
tensorflow:masterfrom
shoutoutuoadi325:fix-jacobian-source-dtypes

Conversation

@shoutoutuoadi325

Copy link
Copy Markdown
Contributor

Fixes #129940.

When a differentiable computation changes dtype, disabling pfor makes GradientTape.jacobian and batch_jacobian allocate TensorArrays with the target dtype, although the gradients have the source dtype. For example, a float32 source cast to float64 raises a TensorArray dtype error. Allocate each loop output with its corresponding source dtype, restoring the documented fallback for computations that cannot be vectorized.

Use the source dtype for disconnected batch Jacobian zeros as well. This retains the existing zero-returning behavior in the default unconnected-gradient mode, while correcting the dtype to match connected Jacobians and unconnected_gradients='zero'.

Regression coverage includes nested sources with different dtypes, both float32/float64 conversion directions, eager and graph execution, tf.function, both computation backends, and disconnected gradients in both unconnected-gradient modes.

Validation on macOS arm64, Python 3.12.14, with tf-nightly 2.23.0.dev20261102:

  • Ran the repository's JacobianTest and BatchJacobianTest classes with the modified backprop.py loaded over the Nightly native runtime: 50 tests, 41 passed and 9 skipped under their existing decorators. No full Bazel build was run.
  • The final regression cases fail against the unmodified Nightly module and pass with the fix. The unmodified module is identical to current master's backprop.py.
  • An additional 28-case matrix checked real/complex and float16/bfloat16 conversions, Tensor/Variable sources, and eager/tf.function execution. Both Jacobian implementations matched pfor results and the ordinary gradient dtype.
  • git diff --check passed.

@google-ml-butler google-ml-butler Bot added size:M CL Change Size: Medium awaiting review Pull request awaiting review labels Nov 4, 2026

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

Copy link
Copy Markdown
Contributor

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 fixes dtype handling in tape.jacobian and tape.batch_jacobian when dealing with mixed-dtype sources and targets. Specifically, it ensures that the loop and output dtypes match the source dtypes rather than the target dtypes. It also adds comprehensive parameterized tests to verify mixed-dtype behavior for both jacobian and batch jacobian computations under various configurations. I have no feedback to provide as the changes are correct and well-tested.

@keerthanakadiri keerthanakadiri self-assigned this Nov 4, 2026
@keerthanakadiri keerthanakadiri added python Pull requests that update Python code prtype:bugfix PR to fix a bug labels Nov 4, 2026
@github-project-automation github-project-automation Bot moved this to Assigned Reviewer in PR Queue Nov 4, 2026
@keerthanakadiri
keerthanakadiri requested a review from a team November 4, 2026 03:53

@dmiltr3 dmiltr3 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for fixing mixed-precision dtype handling in GradientTape.jacobian and GradientTape.batch_jacobian. Please make two small updates before we merge this change:

  1. Normalize each source dtype with dtypes.as_dtype(...) in tensorflow/python/eager/backprop.py (lines 1195, 1341, and 1348). GradientTape supports variable wrappers whose .dtype attribute is a Python string, such as keras.Variable and VariableWithStringDtype. Inside pfor_ops.for_loop, TensorArray(dtype.base_dtype, iters) accesses .base_dtype directly, which raises an AttributeError on string dtypes.
      output = pfor_ops.for_loop(
          loop_fn,
          [dtypes.as_dtype(source.dtype) for source in flat_sources],
          target_size,
          parallel_iterations=parallel_iterations)

And in batch_jacobian:

      output = pfor_ops.for_loop(
          loop_fn, dtypes.as_dtype(source.dtype), target_row_size,
          parallel_iterations=parallel_iterations)

Please also pass dtypes.as_dtype(source.dtype) to array_ops.zeros on line 1348 for consistency.

  1. Add a regression test in tensorflow/python/eager/backprop_test.py for string-dtype variable wrappers. Reuse VariableWithStringDtype (from testUnconnectedGradientsVariableWithStringDtype) to test jacobian and batch_jacobian with experimental_use_pfor=False and mixed dtypes.

@github-project-automation github-project-automation Bot moved this from Assigned Reviewer to Reviewer Requested Changes in PR Queue Nov 5, 2026
@nithyak0204
nithyak0204 requested a review from dmiltr3 November 6, 2026 04:25
@google-ml-butler google-ml-butler Bot added kokoro:force-run Tests on submitted change ready to pull PR ready for merge process labels Nov 6, 2026
@github-project-automation github-project-automation Bot moved this from Reviewer Requested Changes to Approved by Reviewer in PR Queue Nov 6, 2026
@nithyak0204 nithyak0204 removed the awaiting review Pull request awaiting review label Nov 6, 2026
@copybara-service
copybara-service Bot merged commit 08bd379 into tensorflow:master Nov 9, 2026
19 checks passed
@github-project-automation github-project-automation Bot moved this from Approved by Reviewer to Merged in PR Queue Nov 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kokoro:force-run Tests on submitted change prtype:bugfix PR to fix a bug python Pull requests that update Python code ready to pull PR ready for merge process size:M CL Change Size: Medium

Projects

Status: Merged

Development

Successfully merging this pull request may close these issues.

GradientTape Jacobians fail on dtype-changing computations without pfor

4 participants