-
Notifications
You must be signed in to change notification settings - Fork 22
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
Tensor product 1d nodes & basis functions #384
Tensor product 1d nodes & basis functions #384
Conversation
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.
Left a few comments that will hopefully simplify things, but otherwise looks good!
def __init__(self, mesh_el_group, order, index=None, *, basis, basis_1d, | ||
unit_nodes, unit_nodes_1d): |
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.
It feels a bit weird to pass in both (basis, unit_nodes)
and (basis_1d, unit_nodes_1d)
here since we can construct the first one from the second. Maybe move the construction of the nd ones here?
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.
Fixed this for 1D nodes in my latest push. modepy
doesn't seem to have a function like mp.tensor_product_nodes
for basis functions, so still working on that.
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 don't know if one is needed. You should be able to just construct a TensorProductBasis
like here (for a more general case, you'd just have a tensor product of mesh_el_group.dim
1D functions)
https://github.com/inducer/modepy/blob/0fa7355ebe979a4706a7da2ae15b7517d229b8b3/modepy/modes.py#L1219-L1232
Would that work?
@@ -549,6 +559,10 @@ def quadrature_rule(self): | |||
np.ones(len(basis_fcts))) | |||
return mp.Quadrature(nodes, weights, exact_to=self.order) | |||
|
|||
@property | |||
def unit_nodes_1d(self): | |||
return np.array([self._nodes_1d]) |
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.
Why is the np.array
needed?
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 a comment to clarify this. In short, modepy
expects a nested array as an argument when evaluating the basis functions.
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.
Maybe do this via reshape
instead (to clarify that it's already an array).
.pylintrc-local.yml
Outdated
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.
This wants to stay.
""" | ||
:arg basis: a :class:`modepy.TensorProductBasis`. | ||
:arg unit_nodes: unit nodes for the tensor product, obtained by | ||
using :func:`modepy.tensor_product_nodes`, for example. | ||
:arg basis_1d: a representation of the 1D basis from which the tensor |
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.
Let's make the 1D bases accessible from non-underscored attributes in modepy.
@@ -549,6 +559,10 @@ def quadrature_rule(self): | |||
np.ones(len(basis_fcts))) | |||
return mp.Quadrature(nodes, weights, exact_to=self.order) | |||
|
|||
@property | |||
def unit_nodes_1d(self): | |||
return np.array([self._nodes_1d]) |
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.
Maybe do this via reshape
instead (to clarify that it's already an array).
unit_nodes = mp.tensor_product_nodes( | ||
[self.unit_nodes_1d[0]] * self.mesh_el_group.dim) | ||
|
||
if unit_nodes.shape[0] != self.mesh_el_group.dim: |
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.
Maybe call self.unit_nodes
on construction so that this error arises at that point (and not arbitrarily later)?
Converted to draft since there's a bit more work I'd like to do other than making 1D nodes accessible.
LMK if you have any questions |
# FIXME?? there are cases where `basis` is a _SimplexONB object, not a | ||
# TensorProductBasis object. in those cases, it seems self._bases_1d is | ||
# unused. leaving as-is for now. | ||
if isinstance(basis, mp.TensorProductBasis): | ||
self._bases_1d = basis.bases[0] |
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.
Instead: If it's a 1D affair (check on both basis and nodes before making that decision), and the basis is not TP, wrap the basis in a TensorProductBasis
for consistency.
def __init__(self, mesh_el_group, order, index=None, *, basis, | ||
unit_nodes): |
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.
Try type-annotating?
This is ready for a final look I think. Only thing I'm unsure about is the type annotations I added to |
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.
LGTM with those two fixes.
4442850
to
4dc68ba
Compare
I think the Firedrake bits are failing because https://pypi.org/project/pocl-binary-distribution/ (aka https://github.com/isuruf/ocl-wheels/) does not have an LLVM new enough to understand EPYC CPUs. |
I tried to do a rebuild, but the container pull is failing with some sort of AWS signature message that I don't know how to fix. Maybe https://quay.io is broken ATM? |
Other tests are passing on AMD Epyc, though. Is there a large difference between other tests and Firedrake? Grudge tests passed on Epyc: |
They are! It depends on how pocl is installed. By and large, we install pocl from conda, and that works fine. For Firedrake, we install pocl via pip (yes, that's possible... Isuru worked some magic). That's the bit that's broken. |
Doesn't it install it from the Ubuntu repos? meshmode/.ci/install-for-firedrake.sh Line 10 in 9e942e6
|
Good catch! Thanks for spotting that. That makes for an obvious thing to try: Use pocl from pypi. :) |
Would you look at that. ;) Firedrake did run on EPYC and succeeded. |
…he tensor product Add functionality to store and retrieve 1D basis functions of the tensor product Return 1d nodes as a nested array to match shape expected by modepy Construct tensor product nodes from 1D nodes in TensorProductElementGroupBase Remove files created by running pylint Fix a small typo Minor change Get 1D and ND basis by passing a callable to TPGroupBase, probably not final Change formatting on docstring Mesh TP element groups: claim to be non-affine by default Change docstring Take advantage of changes in modepy to grab 1D components of TP Add FIXME regarding basis not being a TensorProductBasisObject Minor changes Minor documentation change Remove trailing whitespace Update handling of non-TensorProductBasis objects in TensorProductElementGroup Refactor Minor change Add type annotations Stop supplying orth weight to TP basis ValueError -> NotImplementedError Minor fixes Fully type TensorProductElementGroupBase constructor
7ec0efc
to
f07a64c
Compare
Without access to the 1D nodes and 1D basis functions used in the tensor product, we are not able to exploit the tensor product structure to reduce the cost required for operator evaluation, e.g. applying a differentiation operator to function data.
This PR:
TensorProductElementGroupBase
to store and retrieve 1D basis functions and 1D nodes used in the tensor productDepends on:
TensorProductBasis
: droporth_weight
argument modepy#72