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

Assemble: use tensor kwarg in FormSum maxpy #4056

Merged
merged 27 commits into from
Mar 19, 2025
Merged
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
a5b09af
Assemble: use tensor kwarg in FormSum maxpy
pbrubeck Feb 19, 2025
082c625
BaseFormAssembler needs zeroing
pbrubeck Feb 19, 2025
eef29d6
BaseFormAssembler: check tensor
pbrubeck Feb 19, 2025
9a6f97c
Cleanup
pbrubeck Feb 19, 2025
821e583
Cofunction -> Function
pbrubeck Feb 19, 2025
11aa95d
ExternalOperator: update tensor
pbrubeck Feb 19, 2025
49950ee
MatrixBase: assign and zero
pbrubeck Feb 19, 2025
db0d9ce
fixup
pbrubeck Feb 19, 2025
31098be
No-op for ImplicitMatrix.zero()
pbrubeck Feb 20, 2025
c72988e
Only zero tensor when assembling FormSum
pbrubeck Feb 20, 2025
ecb6e6e
ImplicitMatrix: Do not implement zero()
pbrubeck Feb 20, 2025
5400181
Fix tests
pbrubeck Feb 20, 2025
db497a1
Update tests/firedrake/regression/test_vfs_component_bcs.py
pbrubeck Feb 20, 2025
c39f9e8
Update firedrake/assemble.py
pbrubeck Feb 20, 2025
2485e54
Apply suggestions from code review
pbrubeck Feb 20, 2025
9e7b915
lint
pbrubeck Feb 20, 2025
c6884bb
Apply suggestions from code review
pbrubeck Feb 20, 2025
5916217
more tests
pbrubeck Feb 21, 2025
7ea3dfc
Merge branch 'master' into pbrubeck/fix/base-form-tensor
pbrubeck Feb 25, 2025
179fe50
address review comments
pbrubeck Feb 26, 2025
b9201d0
Merge branch 'master' into pbrubeck/fix/base-form-tensor
pbrubeck Feb 26, 2025
bcd4e77
AssembledMatrix: set options_prefix
pbrubeck Feb 26, 2025
b81b9da
drop unrelated files
pbrubeck Feb 27, 2025
474ab65
Merge branch 'master' into pbrubeck/fix/base-form-tensor
pbrubeck Feb 27, 2025
c045bf4
Update firedrake/matrix.py
pbrubeck Mar 17, 2025
60002f4
MatrixBase: implement __sub__
pbrubeck Mar 17, 2025
c2c2243
Merge branch 'master' into pbrubeck/fix/base-form-tensor
pbrubeck Mar 17, 2025
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
Prev Previous commit
Next Next commit
address review comments
pbrubeck committed Feb 26, 2025
commit 179fe500b1c19d6956ce28c4b8b2b588f9365532
47 changes: 24 additions & 23 deletions firedrake/assemble.py
Original file line number Diff line number Diff line change
@@ -449,7 +449,6 @@ def base_form_assembly_visitor(self, expr, tensor, *args):
petsc_mat.hermitianTranspose(out=res)
(row, col) = mat.arguments()
return matrix.AssembledMatrix((col, row), self._bcs, res,
appctx=self._appctx,
options_prefix=self._options_prefix)
elif isinstance(expr, ufl.Action):
if len(args) != 2:
@@ -461,18 +460,15 @@ def base_form_assembly_visitor(self, expr, tensor, *args):
(row, col) = lhs.arguments()
# The matrix-vector product lives in the dual of the test space.
res = tensor if tensor else firedrake.Function(row.function_space().dual())
with rhs.dat.vec_ro as v_vec:
with res.dat.vec as res_vec:
petsc_mat.mult(v_vec, res_vec)
with rhs.dat.vec_ro as v_vec, res.dat.vec as res_vec:
petsc_mat.mult(v_vec, res_vec)
return res
elif isinstance(rhs, matrix.MatrixBase):
petsc_mat = lhs.petscmat
(row, col) = lhs.arguments()
res = tensor.petscmat if tensor else PETSc.Mat()
petsc_mat.matMult(rhs.petscmat, result=res)
return tensor if tensor else matrix.AssembledMatrix(expr, self._bcs, res,
appctx=self._appctx,
options_prefix=self._options_prefix)
result = tensor.petscmat if tensor else PETSc.Mat()
lhs.petscmat.matMult(rhs.petscmat, result=result)
if tensor is None:
tensor = self.assembled_matrix(expr, result)
return tensor
else:
raise TypeError("Incompatible RHS for Action.")
elif isinstance(lhs, (firedrake.Cofunction, firedrake.Function)):
@@ -501,17 +497,18 @@ def base_form_assembly_visitor(self, expr, tensor, *args):
result.dat.maxpy(expr.weights(), [a.dat for a in args])
return result
elif all(isinstance(op, ufl.Matrix) for op in args):
res = tensor.petscmat if tensor else PETSc.Mat()
result = tensor.petscmat if tensor else PETSc.Mat()
for (op, w) in zip(args, expr.weights()):
if res:
res.axpy(w, op.petscmat)
if result:
# If result is not void, then accumulate on it
result.axpy(w, op.petscmat)
else:
# Make a copy to avoid in-place scaling
res = op.petscmat.copy()
res.scale(w)
return tensor if tensor else matrix.AssembledMatrix(expr, self._bcs, res,
appctx=self._appctx,
options_prefix=self._options_prefix)
# If result is void, then allocate it with first term
op.petscmat.copy(result=result)
result.scale(w)
if tensor is None:
tensor = self.assembled_matrix(expr, result)
return tensor
else:
raise TypeError("Mismatching FormSum shapes")
elif isinstance(expr, ufl.ExternalOperator):
@@ -585,9 +582,9 @@ def base_form_assembly_visitor(self, expr, tensor, *args):
else:
# Copy the interpolation matrix into the output tensor
petsc_mat.copy(result=res)
return matrix.AssembledMatrix(expr.arguments(), self._bcs, res,
appctx=self._appctx,
options_prefix=self._options_prefix)
if tensor is None:
tensor = self.assembled_matrix(expr, res)
return tensor
else:
# The case rank == 0 is handled via the DAG restructuring
raise ValueError("Incompatible number of arguments.")
@@ -600,6 +597,10 @@ def base_form_assembly_visitor(self, expr, tensor, *args):
else:
raise TypeError(f"Unrecognised BaseForm instance: {expr}")

def assembled_matrix(self, expr, petscmat):
return matrix.AssembledMatrix(expr.arguments(), self._bcs, petscmat,
options_prefix=self._options_prefix)

@staticmethod
def base_form_postorder_traversal(expr, visitor, visited={}):
if expr in visited:
16 changes: 10 additions & 6 deletions firedrake/matrix.py
Original file line number Diff line number Diff line change
@@ -42,6 +42,8 @@ def __init__(self, a, bcs, mat_type):
self._analyze_form_arguments()
self._arguments = arguments

if bcs is None:
bcs = ()
self.bcs = bcs
self.comm = test.function_space().comm
self._comm = internal_comm(self.comm, self)
@@ -97,6 +99,12 @@ def __str__(self):
return "assembled %s(a=%s, bcs=%s)" % (type(self).__name__,
self.a, self.bcs)

def __add__(self, other):
if isinstance(other, MatrixBase):
return self.petscmat + other.petscmat
else:
return NotImplemented

def assign(self, val):
"""Set matrix entries."""
if isinstance(val, MatrixBase):
@@ -212,15 +220,11 @@ def __init__(self, a, bcs, petscmat, *args, **kwargs):
super(AssembledMatrix, self).__init__(a, bcs, "assembled")

self.petscmat = petscmat
options_prefix = kwargs.pop("options_prefix")
self.petscmat.setOptionsPrefix(options_prefix)

# this allows call to self.M.handle without a new class
self.M = SimpleNamespace(handle=self.mat())

def mat(self):
return self.petscmat

def __add__(self, other):
if isinstance(other, MatrixBase):
return self.petscmat + other.petscmat
else:
return NotImplemented