Skip to content
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

Replacement fix #470

Merged
merged 6 commits into from
Nov 30, 2023
Merged

Replacement fix #470

merged 6 commits into from
Nov 30, 2023

Conversation

jrmaddison
Copy link
Collaborator

@jrmaddison jrmaddison commented Nov 28, 2023

Prior to this PR Replacement objects shared identity with originating variables in a number of ways:

  1. Shared their tlm_adjoint variable ID (obtained via var_id) with originating variables. Intended and required.
  2. Shared their UFL 'count' with originating variables. Intended, simplifies the code.
  3. Compared as equal with originating variables in some cases. Not intended, seems fragile.
  4. Shared their UFL count with other Replacement objects in some cases. Not intended, seems likely to lead to bugs.

The last of these is a consequence of Firedrake Constant and Function objects having their counts set independently, and would be resolved more easily by not replacing Constants at all -- since in most cases only scalar Constants work with the Firedrake backend.

This PR fixes this by ensuring that Replacement objects have their own UFL counts, meaning that 2., 3., and 4. no longer hold.

However

The order of var_replacement calls is dependent upon the behaviour of the Python garbage collector. While reference dropping occurs at specific points (controlled by the EquationManager), precisely which references are dropped and in what order depends upon details of garbage collection. This means that if we wait until the var_replacement call to instantiate a Replacement then their UFL counts might be ordered differently on different processes. which also seems fragile. This PR resolves this with an awkward partial initialization of Replacement objects, with the count set on originating variable instantiation, and the VariableInterface bound later on the var_replacement call. This PR resolves this by generating counts on originating variable instantiation.

@jrmaddison
Copy link
Collaborator Author

jrmaddison commented Nov 28, 2023

Some side-notes:

  • Cofunction instances compare as not equal with themselves (via __ne__). This is worked around in this PR. Now fixed upstream.
  • Given Cofunction and Cofunction subclass instances with the same count __eq__ is not even reflexive (one of the few behaviors not permitted in Python, https://peps.python.org/pep-0207) -- another case against letting replacements and originating variables share counts.

@jrmaddison jrmaddison force-pushed the jrmaddison/replacement_fix branch 3 times, most recently from 98cf191 to 1fc6263 Compare November 29, 2023 20:59
@jrmaddison jrmaddison force-pushed the jrmaddison/replacement_fix branch from 1fc6263 to 44c0db5 Compare November 30, 2023 08:08
@jrmaddison
Copy link
Collaborator Author

Pending an update to the Firedrake docker container

@jrmaddison jrmaddison merged commit e8fb4f2 into main Nov 30, 2023
4 checks passed
@jrmaddison jrmaddison deleted the jrmaddison/replacement_fix branch November 30, 2023 14:32
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.

1 participant