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

Fix the FormSum memory leak #3897

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions firedrake/assemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import itertools
from itertools import product
import numbers
import numpy as np

import cachetools
import finat
Expand Down Expand Up @@ -469,8 +470,14 @@ def base_form_assembly_visitor(self, expr, tensor, *args):
return sum(weight * arg for weight, arg in zip(expr.weights(), args))
elif all(isinstance(op, firedrake.Cofunction) for op in args):
V, = set(a.function_space() for a in args)
res = sum([w*op.dat for (op, w) in zip(args, expr.weights())])
return firedrake.Cofunction(V, res)
result = firedrake.Cofunction(V)
for op, w in zip(args, expr.weights()):
for dat_result, dat_op in zip(result.dat.split, op.dat.split):
np.add(
dat_result.data_ro_with_halos,
w * dat_op.data_ro_with_halos,
out=dat_result.data_wo_with_halos)
Comment on lines +477 to +479
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not sure if make this operation with_halos is the right think to do.

Copy link
Contributor

Choose a reason for hiding this comment

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

Does result.assign(sum(w*arg for arg in args)) work? This code looks very very similar to what we do in assign.py.

Copy link
Contributor Author

@Ig-dolci Ig-dolci Dec 2, 2024

Choose a reason for hiding this comment

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

No. result is a Cofunction, and Cofunction assigning an exp that is isinstance(expr, BaseForm) will reach this code again, which leads to a maximum recursion. See this Cofunction assignment code.

return result
elif all(isinstance(op, ufl.Matrix) for op in args):
res = tensor.petscmat if tensor else PETSc.Mat()
is_set = False
Expand Down