Skip to content

Make Root module fully differentiable#55

Merged
SCiarella merged 19 commits into
mainfrom
root_diff
Nov 10, 2025
Merged

Make Root module fully differentiable#55
SCiarella merged 19 commits into
mainfrom
root_diff

Conversation

@SCiarella
Copy link
Copy Markdown
Collaborator

@SCiarella SCiarella commented Nov 3, 2025

This PR addresses the differentiability requirement of issue #47.

All the parameters except RDRRTB were already differentiable since we have defined them as torch.tensor.
To make RDRRTB differentiable, I had to redefine pcse.utils.Afgen to use tensors instead of list. For this reason I have added src/physical_models/crop/afgen.py which is now differentiable.

I have also restructured test_root_dynamics such that all the combinations of parameter-output are checked, and code duplication is reduced.


As a quality of life improvement, I have installed pre-commit that automatically runs ruff checks before each git commit.

@SCiarella
Copy link
Copy Markdown
Collaborator Author

For the efficiency requirement of issue #47, I believe that the current state already implements vectorized operation, so I think that #47 can be closed once this PR is finalized.

Copy link
Copy Markdown
Collaborator

@SarahAlidoost SarahAlidoost left a comment

Choose a reason for hiding this comment

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

@SCiarella thanks. The changes looks good. The PR needs a few modifications specially for the vecorization which its tests currently missing. Please see my comments, if something unclear, let me know.

Comment thread src/diffwofost/physical_models/afgen.py Outdated
Comment thread src/diffwofost/__init__.py Outdated
Comment thread tests/physical_models/crop/test_root_dynamics.py Outdated
Comment thread tests/physical_models/crop/test_root_dynamics.py Outdated
Comment thread tests/physical_models/crop/test_root_dynamics.py Outdated
Comment thread tests/physical_models/crop/test_root_dynamics.py
Comment thread tests/physical_models/crop/test_root_dynamics.py Outdated
Comment thread src/diffwofost/physical_models/crop/root_dynamics.py Outdated
Comment thread tests/physical_models/crop/test_root_dynamics.py Outdated
Comment thread pyproject.toml
Copy link
Copy Markdown
Collaborator Author

@SCiarella SCiarella left a comment

Choose a reason for hiding this comment

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

👋 @SarahAlidoost Thanks for the careful review!

I have implemented all the suggestions, except for a few points that remain open:

  • [1] I have cleaned the test_root_dynamics as you suggested, but I have kept the single-testclass structure because I think it is easier to extend and maintain and it is not hard to interpret, but let me know what you think
  • [2] I do not fully understand the vectorization requirement. To me it is already vectorized (parameter can be passed as tensors). Can you give me a practical example?
  • [3] should we ask someone to confirm that the gradient TWRT->RDRRTB is numerically 0?

Comment thread src/diffwofost/physical_models/afgen.py Outdated
Comment thread tests/physical_models/crop/test_root_dynamics.py Outdated
Comment thread tests/physical_models/crop/test_root_dynamics.py Outdated
Comment thread tests/physical_models/crop/test_root_dynamics.py Outdated
Comment thread tests/physical_models/crop/test_root_dynamics.py Outdated
Comment thread tests/physical_models/crop/test_root_dynamics.py Outdated
Comment thread tests/physical_models/crop/test_root_dynamics.py
Comment thread src/diffwofost/physical_models/crop/root_dynamics.py Outdated
Comment thread src/diffwofost/physical_models/crop/root_dynamics.py Outdated
Comment thread src/diffwofost/physical_models/crop/root_dynamics.py Outdated
Comment thread src/diffwofost/physical_models/crop/root_dynamics.py Outdated
Comment thread tests/physical_models/test_utils.py Outdated
Comment thread tests/physical_models/crop/test_root_dynamics.py Outdated
SCiarella and others added 4 commits November 5, 2025 10:43
Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com>
Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com>
Fix duplicated mask
@SCiarella
Copy link
Copy Markdown
Collaborator Author

👋 @SarahAlidoost

With the last commit I have implemented the vectorization for the root dynamics.
I have used _get_params_shape and _broadcast_to which I have now moved from the leaf module to utils.py.

Finally, I have copied all the vectorization tests that we use for the leaf dynamics and implemented them in test_root_dynamics.py.
Let me know what you think! 💪

Copy link
Copy Markdown
Collaborator

@SarahAlidoost SarahAlidoost left a comment

Choose a reason for hiding this comment

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

@SCiarella thanks for addressing the comments 👍 We need a few more tests to make sure everything works with vectorization:

  1. Tests for gradients when parameters are vectors, see my code suggestions in class TestDiffRootDynamicsGradients.
  2. Tests for parameter "RDRRTB", see the list in test_root_dynamics_with_one_parameter_vector.
  3. Tests for other parameters in test_root_dynamics_with_multiple_parameter_vectors, and test_root_dynamics_with_multiple_parameter_arrays. Currently, only two parameters ("RDI", "RRI") are there.

Please have a look and let me know if something is unclear. Thanks.

Comment thread tests/physical_models/crop/test_root_dynamics.py Outdated
Comment thread tests/physical_models/crop/test_root_dynamics.py Outdated
Comment thread tests/physical_models/crop/test_root_dynamics.py Outdated
Comment thread tests/physical_models/crop/test_root_dynamics.py Outdated
Extend tests
@SCiarella
Copy link
Copy Markdown
Collaborator Author

Thanks @SarahAlidoost!

Now I have fully vectorized also RDRRTB by extending the Afgen class to work with tensors of tables. I have extended the unit tests in test_utils to also cover the tensor case and I have expanded the test_root_dynamics to cover the case when all the parameters (including RDRRTB) are tensors, as you pointed out in the code review.

Notice that I have also added a branch to calculate_numerical_grad in order to return the correct gradient for RDRRTB.

Copy link
Copy Markdown
Collaborator

@SarahAlidoost SarahAlidoost left a comment

Choose a reason for hiding this comment

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

@SCiarella thanks for addressing the comments, nice work 💪 I have one suggestion on refactoring of numerical function making it more generic, see my suggestion on the code. If you agree with it, please go ahead with committing it and merge this PR 🚀

Comment thread src/diffwofost/physical_models/utils.py Outdated
Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com>
@sonarqubecloud
Copy link
Copy Markdown

@SCiarella SCiarella merged commit 347a536 into main Nov 10, 2025
11 checks passed
@SCiarella SCiarella deleted the root_diff branch November 10, 2025 10:10
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