Skip to content

Say so when evaluate() answers for points this rank does not own (#606) - #655

Open
lmoresi wants to merge 1 commit into
developmentfrom
bugfix/evaluate-warns-on-unowned-points
Open

Say so when evaluate() answers for points this rank does not own (#606)#655
lmoresi wants to merge 1 commit into
developmentfrom
bugfix/evaluate-warns-on-unowned-points

Conversation

@lmoresi

@lmoresi lmoresi commented Aug 27, 2026

Copy link
Copy Markdown
Member

Closes the silent half of #606.

The defect

uw.function.evaluate is rank-local — it answers from the calling rank's portion of the mesh. In parallel, a point owned by another rank cannot be located here, so the locator extrapolates and returns a plausible number that is wrong. Nothing in the signature, docstring or return value said so.

Reproduced exactly, including the rank disagreement. P2 field holding x^2 + 2y^2 (exact in P2, so any discrepancy is location, not approximation); query set is every rank's own DOF coordinates allgathered, so every point is a mesh node:

np query max abs error
1 all coords 8.9e-16
2 own coords 6.7e-16
2 all coords 1.48 (rank 0) / 0.54 (rank 1)
4 all coords up to 2.59, two thirds of points wrong

on a field whose entire range is [0, 3]. global_evaluate is exact throughout.

The fix is to stop being silent, not to change the answer

global_evaluate already answers correctly; this points callers there. Two measurements made that clean:

The extrapolation mask is an exact detector. 69 flagged / 69 wrong at np=2, 120 / 120 at np=4 — no wrong-but-unflagged, no flagged-but-fine, worst unflagged error 8.9e-16. Checked before building on it, because a warning with false negatives would be worse than none.

Asking for it is free. 0.0073 s/call with, 0.0075 s/call without, on 1969 points — inside the noise. The locator has to decide whether it located a point in order to fall back, so the mask already exists. It is now requested unconditionally.

Scope

Serial is deliberately not warned about. There an extrapolated point is one genuinely outside the domain — a legitimate request, and warning would be noise.

The regression asserts both directions, because a warning that fired on correct rank-local use would be noise in every properly written parallel script:

  • own coordinates → exact and silent
  • cross-rank query → warns

It fails without the guard (verified by disabling it in the installed copy and re-running at np=2) and passes with it, at np=1 and np=2.

The docstring now carries the contract as a .. warning:: with the measured numbers. That absence was half of what #606 was actually reporting.

Not fixed here: the underlying inability to answer for a non-owned point. That is what global_evaluate is for, and #551 covers the locator work.

Tests: level_1 and tier_a 1074 passed, 0 failed; six evaluate-focused suites 57 passed; new parallel regression green at np=1 and np=2.

Underworld development team with AI support from Claude Code

`uw.function.evaluate` is rank-local: it answers from the calling rank's
portion of the mesh. In parallel a point owned by another rank cannot be
located here, so the locator extrapolates and returns a plausible number that
is wrong -- and two ranks asked the identical question return different
answers. Nothing in the signature, docstring or return value said so.

Measured on a P2 field holding x^2 + 2y^2, which P2 represents exactly, so any
discrepancy is location and not approximation. Query set = every rank's own
DOF coordinates allgathered, i.e. every point is a mesh node:

    np=1  all coords                     max error 8.9e-16
    np=2  own coords                     max error 6.7e-16
    np=2  all coords, rank 0 / rank 1     1.48 / 0.54
    np=4  all coords, worst rank          2.59

on a field whose whole range is [0, 3], with two thirds of the points wrong at
np=4. `global_evaluate` is exact throughout.

The fix is to stop being silent, not to change the answer. The extrapolation
mask turns out to be an EXACT detector of the affected points -- 69 flagged and
69 wrong at np=2, 120 and 120 at np=4, with no wrong-but-unflagged and no
flagged-but-fine, and a worst unflagged error of 8.9e-16 -- so a warning built
on it has neither false negatives nor false positives here.

It is now requested unconditionally, because asking costs nothing: 0.0073 s per
call against 0.0075 s without, on 1969 points, i.e. inside the noise. The
locator must decide whether it located a point in order to fall back, so the
mask is already known.

Serial is deliberately NOT warned about: there an extrapolated point is one
genuinely outside the domain, which is a legitimate request.

The regression asserts both directions, since a warning that fired on correct
rank-local use would be noise on every properly written parallel script: own
coordinates must stay exact AND silent; a cross-rank query must warn. It fails
without the guard (verified by disabling it in the installed copy) and passes
with it, at np=1 and np=2.

Not fixed here: the underlying inability to answer for a non-owned point.
`global_evaluate` already does that correctly, and this points callers at it.

Underworld development team with AI support from Claude Code
Copilot AI lite review requested due to automatic review settings August 27, 2026 03:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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.

2 participants