Skip to content

Commit

Permalink
Merge pull request #217 from mfem/enzyme_hpp
Browse files Browse the repository at this point in the history
added enzyme.i and necessary changes to build
  • Loading branch information
sshiraiwa authored Mar 26, 2024
2 parents 324cd66 + 89effee commit 42722e5
Show file tree
Hide file tree
Showing 16 changed files with 132 additions and 88 deletions.
34 changes: 15 additions & 19 deletions examples/ex26.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,30 @@ def run(order_refinements=2,

class DiffusionMultigrid(mfem.PyGeometricMultigrid):
def __init__(self, fespaces, ess_bdr):
mfem.PyGeometricMultigrid.__init__(self, fespaces)
mfem.PyGeometricMultigrid.__init__(self, fespaces, ess_bdr)

self.smoothers = []
self.ConstructCoarseOperatorAndSolver(fespaces.GetFESpaceAtLevel(0),
ess_bdr)
self.ConstructCoarseOperatorAndSolver(
fespaces.GetFESpaceAtLevel(0),)

for level in range(1, fespaces.GetNumLevels()):
self.ConstructOperatorAndSmoother(fespaces.GetFESpaceAtLevel(level),
ess_bdr)
level)

def ConstructBilinearForm(self, fespace, ess_bdr):
def ConstructBilinearForm(self, fespace):
form = mfem.BilinearForm(fespace)
form.SetAssemblyLevel(mfem.AssemblyLevel_PARTIAL)
form.AddDomainIntegrator(mfem.DiffusionIntegrator(one))
form.Assemble()
self.AppendBilinearForm(form)

ess = mfem.intArray()
self.AppendEssentialTDofs(ess)
fespace.GetEssentialTrueDofs(ess_bdr, ess)
def ConstructCoarseOperatorAndSolver(self, coarse_fespace):

def ConstructCoarseOperatorAndSolver(self, coarse_fespace, ess_bdr):

self.ConstructBilinearForm(coarse_fespace, ess_bdr)
self.ConstructBilinearForm(coarse_fespace)

opr = mfem.OperatorPtr()
opr.SetType(mfem.Operator.ANY_TYPE)
self.bfs[-1].FormSystemMatrix(self.essentialTrueDofs[-1], opr)
self.bfs[0].FormSystemMatrix(self.essentialTrueDofs[0], opr)
opr.SetOperatorOwner(False)

pcg = mfem.CGSolver()
Expand All @@ -58,20 +54,20 @@ def ConstructCoarseOperatorAndSolver(self, coarse_fespace, ess_bdr):
self.smoothers.append((pcg, opr))
self.AddLevel(opr.Ptr(), pcg, False, False)

def ConstructOperatorAndSmoother(self, fespace, ess_bdr):
self.ConstructBilinearForm(fespace, ess_bdr)
def ConstructOperatorAndSmoother(self, fespace, level):
self.ConstructBilinearForm(fespace)

opr = mfem.OperatorPtr()
opr.SetType(mfem.Operator.ANY_TYPE)
self.bfs[-1].FormSystemMatrix(self.essentialTrueDofs[-1], opr)

self.bfs[level].FormSystemMatrix(
self.essentialTrueDofs[level], opr)
opr.SetOperatorOwner(False)

diag = mfem.Vector(fespace.GetTrueVSize())
self.bfs[-1].AssembleDiagonal(diag)

self.bfs[level].AssembleDiagonal(diag)
smoother = mfem.OperatorChebyshevSmoother(opr.Ptr(), diag,
self.essentialTrueDofs[-1], 2)

self.essentialTrueDofs[level], 2)
self.smoothers.append((smoother, opr))
self.AddLevel(opr.Ptr(), smoother, False, False)

Expand Down
34 changes: 15 additions & 19 deletions examples/ex26p.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,36 +23,31 @@ def run(order_refinements=2,

class DiffusionMultigrid(mfem.PyGeometricMultigrid):
def __init__(self, fespaces, ess_bdr):
mfem.PyGeometricMultigrid.__init__(self, fespaces)
mfem.PyGeometricMultigrid.__init__(self, fespaces, ess_bdr)

self.smoothers = []
self.ConstructCoarseOperatorAndSolver(fespaces.GetFESpaceAtLevel(0),
ess_bdr)
self.ConstructCoarseOperatorAndSolver(
fespaces.GetFESpaceAtLevel(0),)

for level in range(1, fespaces.GetNumLevels()):
self.ConstructOperatorAndSmoother(fespaces.GetFESpaceAtLevel(level),
ess_bdr)
level)

def ConstructBilinearForm(self, fespace, ess_bdr, partial_assembly):
def ConstructBilinearForm(self, fespace, partial_assembly):
form = mfem.ParBilinearForm(fespace)
if partial_assembly:
form.SetAssemblyLevel(mfem.AssemblyLevel_PARTIAL)
form.AddDomainIntegrator(mfem.DiffusionIntegrator(one))
form.Assemble()
self.AppendBilinearForm(form)

ess = mfem.intArray()
self.AppendEssentialTDofs(ess)
fespace.GetEssentialTrueDofs(ess_bdr, ess)
def ConstructCoarseOperatorAndSolver(self, coarse_fespace,):

def ConstructCoarseOperatorAndSolver(self, coarse_fespace,
ess_bdr):

self.ConstructBilinearForm(coarse_fespace, ess_bdr, False)
self.ConstructBilinearForm(coarse_fespace, False)

hypreCoarseMat = mfem.HypreParMatrix()
self.bfs[-1].FormSystemMatrix(self.essentialTrueDofs[-1],
hypreCoarseMat)
self.bfs[0].FormSystemMatrix(self.essentialTrueDofs[0],
hypreCoarseMat)

amg = mfem.HypreBoomerAMG(hypreCoarseMat)
amg.SetPrintLevel(-1)
Expand All @@ -69,20 +64,21 @@ def ConstructCoarseOperatorAndSolver(self, coarse_fespace,
self.AddLevel(hypreCoarseMat, pcg, False, False)
self.amg = amg

def ConstructOperatorAndSmoother(self, fespace, ess_bdr):
self.ConstructBilinearForm(fespace, ess_bdr, True)
def ConstructOperatorAndSmoother(self, fespace, level):
self.ConstructBilinearForm(fespace, True)

opr = mfem.OperatorPtr()
opr.SetType(mfem.Operator.ANY_TYPE)

self.bfs[-1].FormSystemMatrix(self.essentialTrueDofs[-1], opr)
self.bfs[level].FormSystemMatrix(
self.essentialTrueDofs[level], opr)
opr.SetOperatorOwner(False)

diag = mfem.Vector(fespace.GetTrueVSize())
self.bfs[-1].AssembleDiagonal(diag)
self.bfs[level].AssembleDiagonal(diag)

smoother = mfem.OperatorChebyshevSmoother(opr.Ptr(), diag,
self.essentialTrueDofs[-1],
self.essentialTrueDofs[level],
2,
fespace.GetParMesh().GetComm())

Expand Down
3 changes: 3 additions & 0 deletions mfem/_par/array.i
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,6 @@ INSTANTIATE_ARRAY_NUMPYARRAY(uint, unsigned int, NPY_UINT) // 32bit
%template(intArray2D) mfem::Array2D<int>;
%template(doubleArray2D) mfem::Array2D<double>;

/* Array< Array<int> *> */
IGNORE_ARRAY_METHODS(mfem::Array<int> *)
INSTANTIATE_ARRAY2(Array<int> *, Array<int>, intArray, 1)
4 changes: 4 additions & 0 deletions mfem/_par/bilinearform.i
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ namespace mfem {

} //end of namespace

%import "../common/array_instantiation_macro.i"
IGNORE_ARRAY_METHODS(mfem::BilinearForm *)
INSTANTIATE_ARRAY0(BilinearForm *, BilinearForm, 1)

%include "fem/bilinearform.hpp"

// instatitate template methods
Expand Down
3 changes: 1 addition & 2 deletions mfem/_par/device.i
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ import_array();
%include "../common/typemap_macros.i"
%include "../common/exception.i"



%import "enzyme.i"
%import "mem_manager.i"

// enforce that device class is created only once
Expand Down
13 changes: 13 additions & 0 deletions mfem/_par/enzyme.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
%module(package="mfem._par") enzyme
%{
#include "mfem.hpp"
%}

%include "../common/existing_mfem_headers.i"
#ifdef FILE_EXISTS_GENERAL_ENZYME

%import "exception.i"

%include "general/enzyme.hpp"

#endif
37 changes: 22 additions & 15 deletions mfem/_par/multigrid.i
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,24 @@ LIST_TO_MFEMOBJ_ARRAY_IN(const mfem::Array<mfem::Operator*>&,
LIST_TO_MFEMOBJ_ARRAY_IN(const mfem::Array<mfem::Solver*>&,
mfem::Solver*)
LIST_TO_MFEMOBJ_BOOLARRAY_IN(const mfem::Array<bool>& )
//%feature("director") mfem::PyGeometricMultigrid;

%pythonprepend mfem::PyGeometricMultigrid::AppendBilinearForm %{
if not hasattr(self, "_forms"): self._forms = []
self._forms.append(form)
form.thisown = 0
%}
%pythonprepend mfem::PyGeometricMultigrid::AppendEssentialTDofs %{
if not hasattr(self, "_esss"): self._esss = []
self._esss.append(ess)
ess.thisown = 0
if not hasattr(self, "forms"):
self.forms=[]
self.forms.append(form)
form.thisown=0
%}

%feature("shadow") mfem::PyGeometricMultigrid::_pybfs %{
@property
def bfs(self):
return self._forms
%}
return self._GetBilinearFormArray()
%}

%feature("shadow") mfem::PyGeometricMultigrid::_pyess %{
@property
def essentialTrueDofs(self):
return self._esss
return self._GetEssentialTrueDofs()
%}

%include "fem/multigrid.hpp"
Expand All @@ -60,15 +57,25 @@ LIST_TO_MFEMOBJ_BOOLARRAY_IN(const mfem::Array<bool>& )
class PyGeometricMultigrid : public GeometricMultigrid
{
public:
PyGeometricMultigrid(const FiniteElementSpaceHierarchy& fespaces_)
PyGeometricMultigrid(const FiniteElementSpaceHierarchy& fespaces_)
: GeometricMultigrid(fespaces_){}

PyGeometricMultigrid(const FiniteElementSpaceHierarchy& fespaces_,
const Array<int> &ess_bdr_)
: GeometricMultigrid(fespaces_, ess_bdr_){}

void AppendBilinearForm(BilinearForm *form){
bfs.Append(form);
}
void AppendEssentialTDofs(Array<int> *ess){
essentialTrueDofs.Append(ess);

Array<BilinearForm*> *_GetBilinearFormArray(){
return &bfs;
}

Array<Array<int> *> *_GetEssentialTrueDofs(){
return &essentialTrueDofs;
}

void _pybfs(void){}
void _pyess(void){}
};
Expand Down
7 changes: 4 additions & 3 deletions mfem/_par/navier_solver.i
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ OSTREAM_TYPEMAP(std::ostream&)
%typemap(argout) double &time {
%append_output(PyFloat_FromDouble(*$1));
}
\

%ignore *::AddVelDirichletBC(VecFuncT *f, Array &);
%ignore *::AddPresDirichletBC(ScalarFuncT *f, Array &);
%ignore *::AddAccelTerm(VecFuncT *f, Array &);
%ignore mfem::navier::NavierSolver::AddVelDirichletBC(VecFuncT *, Array<int> &);
%ignore mfem::navier::NavierSolver::AddPresDirichletBC(ScalarFuncT *f, Array<int> &);
%ignore mfem::navier::NavierSolver::AddAccelTerm(VecFuncT *f, Array<int> &);

%include "miniapps/navier/navier_solver.hpp"

4 changes: 3 additions & 1 deletion mfem/_par/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def get_extensions():
"tmop", "tmop_amr", "tmop_tools", "qspace", "qfunction",
"quadinterpolator", "quadinterpolator_face",
"submesh", "transfermap", "staticcond","sidredatacollection",
"psubmesh", "ptransfermap","navier_solver"]
"psubmesh", "ptransfermap", "enzyme"]

if add_pumi == '1':
from setup_local import puminc, pumilib
Expand All @@ -140,6 +140,8 @@ def get_extensions():
if add_cuda == '1':
from setup_local import cudainc
include_dirs.append(cudainc)
else:
modules.append("navier_solver")

if add_libceed == '1':
from setup_local import libceedinc
Expand Down
4 changes: 4 additions & 0 deletions mfem/_ser/array.i
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,7 @@ INSTANTIATE_ARRAY_NUMPYARRAY(uint, unsigned int, NPY_UINT) // 32bit
%template(intArray2D) mfem::Array2D<int>;
%template(doubleArray2D) mfem::Array2D<double>;

/* Array< Array<int> *> */
IGNORE_ARRAY_METHODS(mfem::Array<int> *)
INSTANTIATE_ARRAY2(Array<int> *, Array<int>, intArray, 1)

1 change: 1 addition & 0 deletions mfem/_ser/device.i
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import_array();
%include "../common/typemap_macros.i"
%include "../common/exception.i"

%import "enzyme.i"
%import "mem_manager.i"

%include "../common/deprecation.i"
Expand Down
13 changes: 13 additions & 0 deletions mfem/_ser/enzyme.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
%module(package="mfem._ser") enzyme
%{
#include "mfem.hpp"
%}

%include "../common/existing_mfem_headers.i"
#ifdef FILE_EXISTS_GENERAL_ENZYME

%import "exception.i"

%include "general/enzyme.hpp"

#endif
43 changes: 21 additions & 22 deletions mfem/_ser/multigrid.i
Original file line number Diff line number Diff line change
Expand Up @@ -31,33 +31,26 @@ LIST_TO_MFEMOBJ_ARRAY_IN(const mfem::Array<mfem::Operator*>&,
LIST_TO_MFEMOBJ_ARRAY_IN(const mfem::Array<mfem::Solver*>&,
mfem::Solver*)
LIST_TO_MFEMOBJ_BOOLARRAY_IN(const mfem::Array<bool>& )
/*
ObjectArrayInput(mfem::Solver *);
ObjectArrayInput(mfem::Operator *);
BoolArrayInput(bool);
*/
//%feature("director") mfem::PyGeometricMultigrid;

%pythonprepend mfem::PyGeometricMultigrid::AppendBilinearForm %{
if not hasattr(self, "_forms"): self._forms = []
self._forms.append(form)
form.thisown = 0
%}
%pythonprepend mfem::PyGeometricMultigrid::AppendEssentialTDofs %{
if not hasattr(self, "_esss"): self._esss = []
self._esss.append(ess)
ess.thisown = 0
if not hasattr(self, "forms"):
self.forms=[]
self.forms.append(form)
form.thisown=0
%}

%feature("shadow") mfem::PyGeometricMultigrid::_pybfs %{
@property
def bfs(self):
return self._forms
%}
return self._GetBilinearFormArray()
%}

%feature("shadow") mfem::PyGeometricMultigrid::_pyess %{
@property
def essentialTrueDofs(self):
return self._esss
return self._GetEssentialTrueDofs()
%}

%include "fem/multigrid.hpp"

%inline %{
Expand All @@ -67,18 +60,24 @@ class PyGeometricMultigrid : public GeometricMultigrid
public:
PyGeometricMultigrid(const FiniteElementSpaceHierarchy& fespaces_)
: GeometricMultigrid(fespaces_){}
PyGeometricMultigrid(const FiniteElementSpaceHierarchy& fespaces_,
const Array<int> &ess_bdr_)
: GeometricMultigrid(fespaces_, ess_bdr_){}

void AppendBilinearForm(BilinearForm *form){
bfs.Append(form);
}
void AppendEssentialTDofs(Array<int> *ess){
essentialTrueDofs.Append(ess);

Array<BilinearForm*> *_GetBilinearFormArray(){
return &bfs;
}

Array<Array<int> *> *_GetEssentialTrueDofs(){
return &essentialTrueDofs;
}

void _pybfs(void){}
void _pyess(void){}
};
} /* end of namespace */
%}



3 changes: 2 additions & 1 deletion mfem/_ser/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ def get_extensions():
"transfer", "std_vectors",
"tmop", "tmop_amr", "tmop_tools", "qspace", "qfunction",
"quadinterpolator", "quadinterpolator_face",
"submesh", "transfermap", "staticcond", "sidredatacollection"]
"submesh", "transfermap", "staticcond",
"sidredatacollection", "enzyme"]

if add_cuda == '1':
from setup_local import cudainc
Expand Down
Loading

0 comments on commit 42722e5

Please sign in to comment.