Skip to content

Optimization: don't construct many tiny numpy arrays inside numba routines #1648

Description

@Sevans711

Allocating lots of tiny numpy arrays is expensive compared to most other operations being performed in numba routines. Discovered during #1566, which also shows one example where this optimization caused >10x speedup: #1566 (comment). (Some part of the speedup quoted there might be from fastmath=True, which should generally be avoided in uxarray, but the majority of it is due to avoiding construction of many tiny numpy arrays.)

Here are a few examples where this occurs in uxarray right now:

  • _compute_gradients_on_faces (in gradient.py) constructs np.zeros(3) and result of np.cross for many pairs of faces. Each of those is a tiny numpy array being constructed.
  • _sort_points_by_angle (in zonal.py) constructs np.array for every point.
  • _small_angle_of_2_vectors (in grid/utils.py) calls np.linalg.norm, which will create a numpy array if inputs weren't a numpy array already. It doesn't have a loop internally, but it is used inside loops in other functions (see thread of issue linked above), where the inputs are just vectors with 3 components, like [ux, uy, uz], with no extra dimensions (it isn't being used in a vectorized manner).

There may be more examples throughout the code. A complete fix to this issue should attempt to find and address all of them.

Suggested fix:

  • Avoid constructing tiny numpy arrays inside numba functions. For example, work with ux, uy, uz components directly, using value = (ux**2 + uy**2 + uz**2)**0.5, instead of using value = np.linalg.norm(u).
  • Perhaps add a few helper functions, e.g. value = _numba_norm3(ux, uy, uz) instead of value = (ux**2 + uy**2 + uz**2)**0.5. That could make the changes easier to implement (closer to existing syntax) and maintain (one source of truth for the norm function, easier to avoid easy-to-miss typos like (ux**2 + uy**2 + ux**2)**0.5).

Tagging @cmdupuis3 in case you want to claim this one after it gets triaged! (I'd also be happy to do it, but would certainly end up asking for you to review any related PRs.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    scalabilityRelated to scalability & performance efforts

    Type

    No type

    Projects

    Status
    📚 Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions