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

Object versioning for DataCarrier object #579

Merged
merged 29 commits into from
Jul 21, 2022
Merged

Conversation

nbouziani
Copy link
Contributor

@nbouziani nbouziani commented May 5, 2020

Small changes in DataCarrier to know if the value of DataCarrier.dat._data has been modified (e.g. object versioning). The purpose of these changes is to keep track of the value of firedrake.Constant objects.

pyop2/base.py Outdated
@@ -3112,6 +3120,7 @@ def pack(self):
@validate_type(('sparsity', Sparsity, SparsityTypeError),
('name', str, NameTypeError))
def __init__(self, sparsity, dtype=None, name=None):
DataCarrier.__init__(self)
self._sparsity = sparsity
self.lcomm = sparsity.lcomm
self.rcomm = sparsity.rcomm
Copy link
Member

Choose a reason for hiding this comment

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

This is a good start, but not all the places in which the data in a Dat or matrix can be modified. In petsc_base.py the .vec, and vec_wo context managers also induce modification of the data. (see VecAccessMixin). For matrices you should probably update the version in assemble (but also other functions that sound like they modify data, like zero_rows/set_values...).

Additionally, the halo exchange functions (global_to_local_end/local_to_global_end) might change data state as well (the user is allowed to call these).

Finally, the big one, a par_loop also updates argument state of all arguments other than READ arguments. Probably adapt ParLoop.update_arg_data_state.

Copy link
Contributor Author

@nbouziani nbouziani Apr 29, 2021

Choose a reason for hiding this comment

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

Thank you very much for you advice! I do apologize for my late reply, I have completely forgotten about this pending task! Yes, I initially pushed changes to handle op2.Global without considering op2.Dat/op2.Mat because object versioning was at that time needed for firedrake.Constant only.

I have just pushed some changes following your comment.

Regarding assemble: did you mean firedrake.assemble ? My first guess to catch the various assembly calls performed on base.Mat was to update the data version in petsc_base.Mat.assemble but I am not sure that all assembly calls go through this route. In particular, unlike firedrake.Matrix, firedrake.ImplicitMatrix does not seem to rely on base.Mat. Instead it uses the PETSc matrix object (PETSc.Mat()), and I am not sure how these two play with each other.

What do you think ?

Copy link
Contributor Author

@nbouziani nbouziani Apr 29, 2021

Choose a reason for hiding this comment

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

Naive question for ParLoop: Why would we need to adapt update_arg_data_state (which is called in ParLoop.compute) whereas local_to_global_end, which is called after, will take into account the access mode to update the data version ?

@wence-
Copy link
Member

wence- commented May 13, 2020

Aside, I don't know what you mean by "finality: firedrake.Constant".

@nbouziani nbouziani changed the title Object versioning for DataCarrier object (finality: firedrake.Constant) Object versioning for DataCarrier object (purpose: firedrake.Constant) Apr 28, 2021
@nbouziani nbouziani changed the title Object versioning for DataCarrier object (purpose: firedrake.Constant) Object versioning for DataCarrier object Apr 29, 2021
@nbouziani
Copy link
Contributor Author

Following previous discussions, object versioning is now implemented using the PETSc state counter.

Testing failure is due to the fact that tests don't rely on the PETSc branch that makes the state counter public. All tests are passing for me locally.

@nbouziani
Copy link
Contributor Author

Tests now rely on the appropriate petsc branch. Related PR: firedrakeproject/petsc#8

pyop2/types/dat.py Outdated Show resolved Hide resolved
pyop2/types/dat.py Outdated Show resolved Hide resolved
pyop2/types/dat.py Outdated Show resolved Hide resolved
@@ -44,6 +44,9 @@ def cdim(self):
the product of the dim tuple."""
return self._cdim

def increment_dat_version(self):
Copy link
Member

Choose a reason for hiding this comment

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

declare this abstract.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The problem is that this requires all the subclasses to implement it and at the moment Global, Dat and MixedDat get the implementation of increment_dat_version via another route, i.e. VecAccessMixin. That’s because we don’t want to duplicate the object versioning setup in Global and AbstractDat objects so I put it in the appropriate common ancestor (VecAccessMixin).

pyop2/types/mat.py Show resolved Hide resolved
@wence-
Copy link
Member

wence- commented Nov 25, 2021

I think the vec_context contextmanager on dats needs changing (it always calls self._vec.stateIncrease() but it should now not bother, because we correctly manipulate the state of things, I think).

@nbouziani
Copy link
Contributor Author

I think the vec_context contextmanager on dats needs changing (it always calls self._vec.stateIncrease() but it should now not bother, because we correctly manipulate the state of things, I think).

Yes I think that’s right, because calling stateIncrease() was the result of modifying Vec off PETSc’s radar in places like data or zeros, which we now catch. I have removed that which caused the following test to fail:

d1 = op2.Dat(...)
with d1.vec_wo as _:
	…
# Check that d1.dat_version has increased

but I think the problem here is that the test is wrong since we don’t want to update the object version if we just use a context manager but rather if we actually changes the value of d1 inside the context manager. So I removed the test as well.

@wence-
Copy link
Member

wence- commented Nov 26, 2021

I think the vec_context contextmanager on dats needs changing (it always calls self._vec.stateIncrease() but it should now not bother, because we correctly manipulate the state of things, I think).

Yes I think that’s right, because calling stateIncrease() was the result of modifying Vec off PETSc’s radar in places like data or zeros, which we now catch. I have removed that which caused the following test to fail:

d1 = op2.Dat(...)
with d1.vec_wo as _:
	…
# Check that d1.dat_version has increased

but I think the problem here is that the test is wrong since we don’t want to update the object version if we just use a context manager but rather if we actually changes the value of d1 inside the context manager. So I removed the test as well.

let us check that the interaction with petsc works well and modify vec.array in the context manager. the state should then increase.

@dham dham merged commit 784b217 into master Jul 21, 2022
@dham dham deleted the DataCarrier-object-versionning branch July 21, 2022 12:28
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.

3 participants