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

Tensor product 1d nodes & basis functions #384

Merged

Conversation

a-alveyblanc
Copy link
Contributor

@a-alveyblanc a-alveyblanc commented Aug 4, 2023

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:

  • Adds functionality to TensorProductElementGroupBase to store and retrieve 1D basis functions and 1D nodes used in the tensor product
  • Updates subclasses accordingly

Depends on:

Copy link
Collaborator

@alexfikl alexfikl left a 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!

Comment on lines 521 to 522
def __init__(self, mesh_el_group, order, index=None, *, basis, basis_1d,
unit_nodes, unit_nodes_1d):
Copy link
Collaborator

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?

Copy link
Contributor Author

@a-alveyblanc a-alveyblanc Aug 7, 2023

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.

Copy link
Collaborator

@alexfikl alexfikl Aug 8, 2023

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?

meshmode/discretization/poly_element.py Outdated Show resolved Hide resolved
@@ -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])
Copy link
Collaborator

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?

Copy link
Contributor Author

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.

Copy link
Owner

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).

Copy link
Owner

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
Copy link
Owner

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])
Copy link
Owner

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:
Copy link
Owner

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)?

@a-alveyblanc a-alveyblanc marked this pull request as draft September 6, 2023 16:30
@a-alveyblanc
Copy link
Contributor Author

a-alveyblanc commented Sep 6, 2023

Converted to draft since there's a bit more work I'd like to do other than making 1D nodes accessible.

  • modepy will have some updated functionality for returning 1D operators in the case of tensor products
  • meshmode will need some updating to reflect this

LMK if you have any questions

Comment on lines 549 to 553
# 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]
Copy link
Owner

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.

Comment on lines 521 to 522
def __init__(self, mesh_el_group, order, index=None, *, basis,
unit_nodes):
Copy link
Owner

Choose a reason for hiding this comment

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

Try type-annotating?

@a-alveyblanc a-alveyblanc marked this pull request as ready for review November 14, 2023 14:20
@a-alveyblanc
Copy link
Contributor Author

a-alveyblanc commented Nov 14, 2023

This is ready for a final look I think. Only thing I'm unsure about is the type annotations I added to TensorProductElementGroupBase

Copy link
Owner

@inducer inducer left a 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.

meshmode/discretization/poly_element.py Outdated Show resolved Hide resolved
meshmode/discretization/poly_element.py Outdated Show resolved Hide resolved
@inducer inducer force-pushed the tensor-product-1d-nodes-and-1d-basis branch from 4442850 to 4dc68ba Compare November 14, 2023 16:23
@inducer
Copy link
Owner

inducer commented Nov 14, 2023

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.

@inducer
Copy link
Owner

inducer commented Nov 14, 2023

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?

@a-alveyblanc
Copy link
Contributor Author

a-alveyblanc commented Nov 14, 2023

Other tests are passing on AMD Epyc, though. Is there a large difference between other tests and Firedrake? Grudge tests passed on Epyc: test/test_dt_utils.py::test_wave_dt_estimate[<PytatoPyOpenCLArrayContext for <pyopencl.Device 'cpu-AMD EPYC 7763 64-Core Processor' on 'Portable Computing Language'>>-2-1] (grabbed some random warning output from the Grudge tests)

@inducer
Copy link
Owner

inducer commented Nov 14, 2023

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.

@alexfikl
Copy link
Collaborator

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?

sudo apt install -y pocl-opencl-icd ocl-icd-opencl-dev

@inducer
Copy link
Owner

inducer commented Nov 15, 2023

Good catch! Thanks for spotting that. That makes for an obvious thing to try: Use pocl from pypi. :)

@inducer
Copy link
Owner

inducer commented Nov 15, 2023

Would you look at that. ;) Firedrake did run on EPYC and succeeded.

a-alveyblanc and others added 2 commits November 15, 2023 11:27
…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
@inducer inducer force-pushed the tensor-product-1d-nodes-and-1d-basis branch from 7ec0efc to f07a64c Compare November 15, 2023 17:27
@inducer inducer enabled auto-merge (rebase) November 15, 2023 17:28
@inducer inducer merged commit 052d11e into inducer:main Nov 15, 2023
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants