Skip to content

Autograd support for affine transformations #2490

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: develop
Choose a base branch
from

Conversation

yaugenst-flex
Copy link
Collaborator

@yaugenst-flex yaugenst-flex commented May 20, 2025

Supersedes #2475

@rahul-flex I rebased all the changes into this PR. Could you have a look and check if anything is missing?

Greptile Summary

Major enhancement to Tidy3D's autograd capabilities, adding support for differentiating through affine transformations (rotation, scaling, translation) of geometric structures.

  • Implemented surface mesh integration approach in tidy3d/components/geometry/base.py, replacing xarray-based derivative computation for improved robustness
  • Added comprehensive autograd support for box transformations in tidy3d/components/transformation.py, enabling chainable operations through ArrayBox type handling
  • Unified permittivity computation across geometry types in tidy3d/web/api/autograd/autograd.py by removing Box-specific special cases
  • Added extensive test suite validating AD vs FD derivatives within 30-35% tolerance across various geometric parameters and transformations
  • Enhanced transform matrix construction to avoid in-place operations for proper chain rule application

@rahul-flex
Copy link
Contributor

rahul-flex commented May 20, 2025

Supersedes #2475

@rahul-flex I rebased all the changes into this PR. Could you have a look and check if anything is missing?

Thanks! Went through it. Looks good. Added an else condition. Ran the numerical tests. They pass!
All the pyetsts pass as well. However, I am seeing an increase in pytest execution time (usually takes ~20 mins locally.. currently took ~ 1hr). It seems this is taking long to run. I did not get a chance to get to the bottom of it. Felt I should mention it here.
Screenshot 2025-05-20 at 4 47 37 PM

@yaugenst-flex
Copy link
Collaborator Author

@greptileai

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

8 files reviewed, 3 comments
Edit PR Review Bot Settings | Greptile

return (fun(x0 + δ) - fun(x0 - δ)) / (2 * δ)


def _assert_close(fd_val, ad_val, tag, axis=None, extra="", tol=0.35):
Copy link

Choose a reason for hiding this comment

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

style: The tolerance value 0.35 (35%) seems quite high for numerical comparison. Consider tightening or documenting justification.

return anp.sum(data.get_intensity("m").values)


def finite_diff_theta(center, size, eps, theta, axis, delta=1e-3):
Copy link

Choose a reason for hiding this comment

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

style: Default delta (1e-3) differs from global delta (0.016). Consider using the global delta by default.

@@ -66,7 +67,6 @@ def rotate_tensor(self, tensor: TensorReal) -> TensorReal:

if self.isidentity:
return tensor

return np.matmul(self.matrix, np.matmul(tensor, self.matrix.T))
Copy link

Choose a reason for hiding this comment

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

logic: rotate_tensor still uses np.matmul instead of anp.matmul - needs to be consistent with autograd usage.

Suggested change
return np.matmul(self.matrix, np.matmul(tensor, self.matrix.T))
return anp.matmul(self.matrix, anp.matmul(tensor, self.matrix.T))

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

8 files reviewed, 4 comments
Edit PR Review Bot Settings | Greptile

},
]

PARAM_LABELS = ["center_x", "center_x", "center_y", "center_z", "size_x", "size_y", "size_z"]
Copy link

Choose a reason for hiding this comment

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

syntax: Duplicate 'center_x' in PARAM_LABELS array

Suggested change
PARAM_LABELS = ["center_x", "center_x", "center_y", "center_z", "size_x", "size_y", "size_z"]
PARAM_LABELS = ["center_x", "center_y", "center_z", "size_x", "size_y", "size_z"]

def test_autograd_vs_fd_scenarios(scenario, param_label):
center0 = (0.0, 0.0, 0.0)
size0 = (2.0, 2.0, 2.0)
delta = 0.03
Copy link

Choose a reason for hiding this comment

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

style: Delta value 0.03 differs from default 1e-3 in fd_vs_ad_param. Consider documenting why or unifying these values.

Comment on lines +2261 to +2262


Copy link

Choose a reason for hiding this comment

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

style: make_sim_rotation could be reused by storing sim as a fixture instead of recreating for each test

Comment on lines +2286 to +2290
val, grad_c, grad_s = get_grad(center0, size0, angle=None, axis=None)
npx, npy, npz = grad_c
sSx, sSy, sSz = grad_s

assert not np.allclose(grad_c, 0.0), "center gradient is all zero."
Copy link

Choose a reason for hiding this comment

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

style: use more descriptive variable names than npx,npy,npz for gradient components

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