Thanks to visit codestin.com
Credit goes to github.com

Skip to content

BUG: Fix incorrect initialization in bspline kernel#9486

Merged
asi1024 merged 2 commits into
cupy:mainfrom
seberg:issue-7240
Nov 22, 2025
Merged

BUG: Fix incorrect initialization in bspline kernel#9486
asi1024 merged 2 commits into
cupy:mainfrom
seberg:issue-7240

Conversation

@seberg

@seberg seberg commented Nov 17, 2025

Copy link
Copy Markdown
Member

This fixes the use of uninitialized memory in the bspline kernel d_boor kernel.
Testing is unfortunately not really possible directly, this leads to occasionally test failures.

I did test it locally, by replacing all empty calls with either filling with NaN or the minimum integer, though.

Closes gh-7240


I am not really worried about it being wrong (the original code always uses uninitialized data here), but maybe @andfoy you can have a brief look? In some paths it seems it only matters that this value isn't NaN or similar (i.e. probably it leads to value - value which is mathematically be zero but isn't for NaN/inf).
But I think the design-matrix tests wanted one here?

@seberg seberg requested a review from a team as a code owner November 17, 2025 08:42
@asi1024 asi1024 self-assigned this Nov 18, 2025
@asi1024 asi1024 added cat:bug Bugs to-be-backported Pull-requests to be backported to stable branch prio:high labels Nov 18, 2025
@asi1024

asi1024 commented Nov 18, 2025

Copy link
Copy Markdown
Member

@seberg I think it is not necessary to initialize h[1]. In the first iteration of the outer loop: L115-L132 (when j = 1), h[1] is assigned at L130 without being read up to that point.

  • the inner loop - for (int p = 0; p < j; p++) { hh[p] = h[p]; } does not be executed, so h[1] is not referenced.
  • the inner loop - for (n = 1; n <= j; n++) { ... } assigns h[1] at h[n] = w * (xp - xa); when n = 1.

@seberg

This comment was marked as outdated.

This fixes the use of uninitialized memory in the bspline kernel
`d_boor` kernel.
Testing is unfortunately not really possible directly, this leads
to occasionally test failures.

I did test it locally, by replacing all ``empty`` calls with either
filling with NaN or the minimum integer, though.

Closes cupygh-7240
@seberg

seberg commented Nov 18, 2025

Copy link
Copy Markdown
Member Author

@asi1024 OK, I think I found the actual issue, I guess... This one looks like a clear typo and makes a lot more sense.

I won't claim to have understood why this issue leads to the above observations or the algorithm, but it's clear that x[n] must be filled in...

@seberg seberg changed the title BUG: Fix use of uninitialized memory in bspline kernel BUG: Fix incorrect initialization in bspline kernel Nov 18, 2025
@seberg

seberg commented Nov 18, 2025

Copy link
Copy Markdown
Member Author

We should wait a bit for @ev-br, we have been chatting a bit and he is looking at the SciPy code. SciPy has the same code although it (recently) started to zero the input.

But... let's see maybe @ev-br finds something more here. It still looks like a typo to me, but it sounds like there may be a bit more complexity here.

@seberg

seberg commented Nov 18, 2025

Copy link
Copy Markdown
Member Author

OK, I think we agreed to (and Evgeni found a bit more to back it up), that deBoors formula has a funny "use zero when it would be divide by zero" which is the reason for the path, so that the fix is right.
(It is still surprising that this error seems very subtle since the test suite doesn't notice a thing here for example!)

Evgeni figures the reason why this is that it is practically impossible to hit this path to begin with: The test is very strange.

@asi1024

asi1024 commented Nov 18, 2025

Copy link
Copy Markdown
Member

/test mini

@ev-br

ev-br commented Nov 19, 2025

Copy link
Copy Markdown
Contributor

To summarize, I indeed believe this is the right fix. A typo (mu<->n) led to using uninitialized memory in some cases.
The typo originates from scipy, where it traces back to the original commit which introduced the de_boor_d function, in 2007.
The spirit of the fix is indeed to enforce the "result is zero if denominator is zero" caveat for the recursive definition of b-splines.
Why tests do not catch it otherwise: it is rather difficult to hit this code path. The flaky test which caught it in CuPy has several features which helped catching it (mostly by chance): for a quadratic spline (k=2), it has a triple knot, and there are only two boundary knots next to it.

@asi1024

asi1024 commented Nov 22, 2025

Copy link
Copy Markdown
Member

@seberg Many thanks for looking into the flaky failure! LGTM!

@asi1024 asi1024 merged commit f05ce6a into cupy:main Nov 22, 2025
48 checks passed
chainer-ci pushed a commit to chainer-ci/cupy that referenced this pull request Nov 22, 2025
BUG: Fix incorrect initialization in bspline kernel
@seberg seberg deleted the issue-7240 branch November 22, 2025 08:30
@kmaehashi kmaehashi removed the to-be-backported Pull-requests to be backported to stable branch label Nov 22, 2025
ev-br pushed a commit to scipy/scipy that referenced this pull request Dec 5, 2025
@kmaehashi kmaehashi added this to the v14.0.0rc1 milestone Dec 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TestBSpline::test_bspline_derivative_jumps sometimes fail

4 participants