BlockLayout2D: copy caller-supplied origins
An int64 C-contiguous origins array was kept by reference (and frozen in the caller's hands), so mutating it later changed layout.origins and block_cell without changing owner/halos. Copy before marking read-only; regression checks origins, owner and block_cell invariance. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
fa7fd9097a
commit
aecee19c19
@@ -144,7 +144,7 @@ class BlockLayout2D:
|
||||
jy, jx = np.divmod(np.arange(nby * nbx), nbx)
|
||||
origins = np.stack([jy * by, jx * bx], axis=1)
|
||||
selected = _selected_blocks(origins, ny, nx, by, bx)
|
||||
origins = np.asarray(origins, dtype=np.int64).reshape(-1, 2)
|
||||
origins = np.array(origins, dtype=np.int64).reshape(-1, 2) # own copy, never caller storage
|
||||
if (len(origins) + 1) * NQ * cells > np.iinfo(np.int64).max // 2:
|
||||
raise ValueError("blocked storage exceeds 64-bit indexing")
|
||||
|
||||
|
||||
@@ -411,6 +411,17 @@ class SparseBlockLayoutTests(unittest.TestCase):
|
||||
np.testing.assert_array_equal(stored[layout.owner.ravel()[owned].astype(np.intp)], flags[owned])
|
||||
self.assertEqual(np.count_nonzero(stored), owned.sum())
|
||||
|
||||
def test_caller_origins_are_copied(self):
|
||||
origins = np.array([[0, 0], [0, 4]], dtype=np.int64)
|
||||
layout = BlockLayout2D.build(6, 8, 3, 4, origins=origins)
|
||||
owner, address = layout.owner.copy(), layout.block_cell(0, 0, 0)
|
||||
self.assertTrue(origins.flags.writeable) # caller array is not frozen
|
||||
origins[0] = [3, 0]
|
||||
np.testing.assert_array_equal(layout.origins, [[0, 0], [0, 4]])
|
||||
np.testing.assert_array_equal(layout.owner, owner)
|
||||
self.assertEqual(layout.block_cell(0, 0, 0), address)
|
||||
self.assertEqual(address, layout.owner[0, 0])
|
||||
|
||||
def test_invalid_origins_rejected(self):
|
||||
for origins in ([(0, 4), (0, 0)], # not row-major
|
||||
[(3, 0), (0, 4)], # not row-major across rows
|
||||
|
||||
Reference in New Issue
Block a user