-
Notifications
You must be signed in to change notification settings - Fork 52
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
Add palace::GridFunction
to unify mfem::ParGridFunction
and mfem::ParComplexGridFunction
#204
Conversation
19f9618
to
36b3cfb
Compare
b32b634
to
21765bd
Compare
GridFunction &GridFunction::operator=(std::complex<double> s) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MFEM_ASSERT(s.imag() == 0.0 || !HasImag(), "Cannot assign complex scalar to a non-complex grid function!");
Assigning an actually complex into a real grid function is almost certainly an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added in 5f0543e
class GridFunction | ||
{ | ||
private: | ||
mfem::ParGridFunction gfr, gfi; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The alternative here is something like
template <bool Complex = false>
class GridFunction
{
private:
std::array<mfem::ParGridFunction, Complex ? 2 : 1> gfs;
public:
GridFunction(mfem::ParFiniteElementSpace &fespace);
GridFunction(FiniteElementSpace &fespace);
// Get access to the real and imaginary grid function parts.
const mfem::ParGridFunction &Real() const { return gfs[0]; }
mfem::ParGridFunction &Real() { return gf[0]; }
template <bool Enable = Complex, typename =std::enable_if_t<Complex>>
const mfem::ParGridFunction &Imag() const
{
return gfs[1];
}
template <bool Enable = Complex, typename =std::enable_if_t<Complex>>
mfem::ParGridFunction &Imag()
{
return gfs[1];
}
// Check if the grid function is suited for storing complex-valued fields.
bool HasImag() const { return Complex; }
// Get access to the underlying finite element space (match MFEM interface).
mfem::FiniteElementSpace *FESpace() { return gfr.FESpace(); }
const mfem::FiniteElementSpace *FESpace() const { return gfr.FESpace(); }
mfem::ParFiniteElementSpace *ParFESpace() { return gfr.ParFESpace(); }
const mfem::ParFiniteElementSpace *ParFESpace() const { return gfr.ParFESpace(); }
// Set all entries equal to s.
template <bool Enable = Complex, typename =std::enable_if_t<Enable>>
GridFunction &operator=(std::complex<double> s);
GridFunction &operator=(double s);
// Scale all entries by s.
GridFunction &operator*=(double s);
// Transform for space update (for example on mesh change).
void Update();
// Get the associated MPI communicator.
MPI_Comm GetComm() const { return ParFESpace()->GetComm(); }
};
where the enable_if
bits remove the imaginary methods (and operators) in the case of non-complex. This would mirror the existing the split between the two grid function types, with all the corresponding dispatch.
I think the runtime flag here is a better approach though, as the template is only going to eliminate if branches at a very high level, so the template isn't really worth it imo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered the template version but came to the same conclusion you have, that the runtime flag is just fine in this case from a performance and from an interface point of view.
5f0543e
to
8862604
Compare
36b3cfb
to
4932816
Compare
d07dc2e
to
702eb30
Compare
4932816
to
c2c5ae9
Compare
702eb30
to
ffaeafd
Compare
We have observed some issues with
mfem::Memory
aliasing when running on GPUs, which look like error messages of the form:One place this aliasing is used is
mfem::ComplexGridFunction
andmfem::ParComplexGridFunction
. This PR replaces the aliases with two separateParGridFunction
objects for the real and imaginary parts, and resolves the errors in our testing. I'm not certain this is an error with MFEM'sMemoryManager
or just our use of it without adequate synchronization. But for now, keeping this objects stored separately seems to resolve the problems.NOTE: This is on top of #193 and resolves the observed instances in testing for GPU support. #194 to follow this PR.