Skip to content

Object id PR 1a fixes: demand creation by id, buffered index requests, synchronous LB location update - #4028

Merged
lvkale merged 1 commit into
objid-redesignfrom
objid-pr1a-fixes
Oct 10, 2026
Merged

lvkale merged 1 commit into
objid-redesignfrom
objid-pr1a-fixes

Conversation

@lvkale

@lvkale lvkale commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Fixes for every item in Aditya's review of #4017 (2026-10-04), which was merged into objid-redesign before the review was acted on. Needs Aditya's approval. Until it merges, #4015 and #4021 wait.

Item by item

Aditya's item Status in this PR Where Test
Must-fix 1: demand creation lost when the message reaches the home by id Fixed CkArray::handleUnknownByID, new CkLocMgr::recoverIndex objid_insert -n (packed kind): without the fix the elements are never created
Must-fix 2: requestLocation(idx, peToTell) replies with the null entry Fixed CkLocMgr::requestLocation(idx, peToTell) objid_insert phase 4b (createhere, packed kind, debug build): without the fix, Assertion e.pe != -1
Must-fix 3: CMK_GLOBAL_LOCATION_UPDATE update no longer synchronous Fixed, by the second of the two options suggested (counted epoch kept, broadcast kept) UpdateLocation, new CkLocMgr::updateLocationFromLB lb_test, GreedyLB and RotateLB, under a -DCMK_GLOBAL_LOCATION_UPDATE=1 debug build: passes. Not reproduced without the fix on one process (see below)
Smaller: decompress uses a signed 32-bit shift Fixed ckarrayindex.h build
Smaller: pupLayout has no version marker Fixed: a marker precedes the layout; a checkpoint without one aborts with a message pupLayout by inspection
Smaller: restart abort message says "process count" for the PE-per-process case Fixed: two messages CkLocMgr::pup by inspection
Smaller: uniqueBits < 16 checked at every startup Fixed: checked when the first hashed-kind array takes a tranche initLayout, getTranche by inspection
Smaller: pendingLocReqs entries stay set when the home drops a request Not changed, as the review itself suggested: PR 1b removes requestLocationOnce — —
"objid_insert phase 4 misses this because every PE sends" Addressed: -n makes only non-home PEs send objid_insert Makefile runs both kinds with and without -n

What each fix does

1. handleUnknownByID parked a message that asked for creation in bufferedIDMsgs and requested a location that nothing would ever report, since the element did not exist. Now, for a message with createhome or createhere, it recovers the index and takes the index-keyed path (handleUnknown), which approves creation through the home for createhome and creates at the original sender for createhere. recoverIndex(id, idx, scanAtHome) tries the compressor, then a local record, then, for a hashed-kind element at its home, a linear scan of the home's idx -> id bindings, which reclaimRemote keeps; that scan is reached only by the re-creation of a deleted element and never by delivery. A non-home PE that cannot name the index hands the message to the home. Buffer-kind messages are unchanged.

2. For a packed-index array the id of any in-bounds index is always known, so the home answered as soon as asked, with pe -1 and id 0. It now answers only when it knows the location, and otherwise holds the request in bufferedLocationRequests, which updateLocation answers once the element registers.

3. UpdateLocation is back and id-keyed (updateLocationFromLB), so every PE but the source records the destination before the move is acted on, which is the invariant the CentralLB comment and multiHop's assert rely on. The epoch is counted from the receiver's cache as before; that count never exceeds the element's true epoch (both advance by one per migration and a bystander's starts no higher), so the destination's insert still applies over it. The broadcast from the emigrating PE stays and carries the true epoch, closing the stale-reply window the review described. Cost: one group broadcast per migration, in this build mode only. Carrying the epoch in MigrateInfo would remove the broadcast; left for later. Design doc 4.4 records this.

Evidence

Unfixed runtime, debug build, 4 PEs, the new objid_insert: -b -n reports "(300,0) was never created" (item 1); -b, -n and the default run abort on Assertion e.pe != -1 in updateLocation (item 2). Fixed: all four pass, on one process and under lcrun -n 2. Also passing on the fixed debug build: objid_home, objid_bound (manual, RotateLB, GreedyLB), objid_sections, unbounded_migration, unbounded_restart (checkpoint, restart on 4 and on 2 PEs), demand_creation, anytime_bcastred (3 runs). lb_test with GreedyLB and RotateLB passes under the flagged debug build. It also passed without fix 3 on this laptop: in one process the emigrate broadcast lands before the resume, so the window is not reproduced here. Item 3 is fixed by construction, not by a reproduced failure.

Found on the way, not fixed here (predates the redesign)

Re-creating a destroyed element by createhere fails: the creating PE's insertElement follows its own stale location entry for the dead element (the isRemote redirect meant for bound siblings) and forwards the constructor elsewhere; and a re-created element restarts at epoch 0, so stale caches reject its location (debug builds assert in CkLocCache::insert on the creating PE). Phase 6 of the test therefore re-creates by createhome only, and says why. Worth an issue.

🤖 Generated with Claude Code

…, synchronous LB location update

Addresses Aditya's review of #4017 (2026-10-04), which was merged into
objid-redesign before the review was acted on. The three must-fix items and
the smaller ones; design doc sections 3.4 and 4.4 record what was done.

1. Demand creation is lost when a message reaches the home by id.
   CkArray::handleUnknownByID parked every message in bufferedIDMsgs and asked
   for a location that nothing would ever report, because the element did not
   exist. For a message that asks for creation it now recovers the index and
   takes the index-keyed path (handleUnknown), which approves creation through
   the home for createhome and creates at the original sender for createhere.
   New CkLocMgr::recoverIndex(id, idx, scanAtHome): the compressor, a local
   record, or, for a hashed-kind element at its home, a linear scan of the
   home's idx -> id bindings (kept by reclaimRemote; the case is the
   re-creation of a deleted element, and no delivery path uses the scan). A
   non-home PE that cannot name the index hands the message to the home.

2. requestLocation(idx, peToTell) answered with the null entry.
   For a packed-index array the id of any in-bounds index is always known, so
   the home replied as soon as it was asked, with pe -1 and id 0, which
   asserts in updateLocation (debug builds) and in production sends buffered
   messages for id 0 to PE -1. The home now answers only when it knows the
   location and otherwise holds the request in bufferedLocationRequests,
   which updateLocation answers once the element registers.

3. CMK_GLOBAL_LOCATION_UPDATE: the update was no longer synchronous.
   UpdateLocation had been emptied in favour of a broadcast from the
   emigrating PE, so a PE could resume after a balancing step and address an
   element at its old location (an extra hop; GPU zerocopy aborts on it, and
   multiHop asserts in this mode). The synchronous update is back, keyed by
   id (CkLocMgr::updateLocationFromLB), with the epoch counted from the
   receiver's cache as before; that count never exceeds the element's true
   epoch, so the destination's insert still applies over it. The broadcast
   stays, carrying the true epoch, which closes the stale-reply window of the
   counted epoch; cost one group broadcast per migration, in this mode only.
   Carrying the epoch in MigrateInfo would remove it (later).

Smaller: decompress masks with a 64-bit shift (a dimension may need 31 bits
now); pupLayout writes a marker so a checkpoint without a layout record fails
clearly instead of misreading the readonly messages; the hashed-kind restart
abort distinguishes a changed process count from a changed PE-per-process
layout; the uniqueBits < 16 check moves from initLayout to the first hashed
array's getTranche, so a run with only packed arrays never trips it.

Tests (tests/charm++/objid_insert): -n makes only non-home PEs send the
createhome demand creations, so the creation must come from a message that
reaches the home by id (fails without fix 1 on the packed kind: the elements
are never created, watchdog abort). Phase 4b adds createhere demand creation
with a single sender per element (fails without fix 2 on the packed kind in a
debug build: the null-entry assert). Phase 6 re-creates the elements
destroyed in phase 5 by createhome, from senders holding stale ids and
locations, which is the only path to the home-side index scan of the hashed
kind. Re-creation by createhere is documented as not tested: the creating
PE's insertElement follows its own stale location entry (the isRemote
redirect for bound siblings) and a re-created element restarts at epoch 0,
both of which predate the redesign. The Makefile runs both kinds with and
without -n. lb_test under a -DCMK_GLOBAL_LOCATION_UPDATE=1 debug build with
GreedyLB and RotateLB passes with the fix; it also passed without it on this
laptop (single process, 4 PEs), where the emigrate broadcast lands before
the resume. The window is real on a network, since nothing orders the two;
fix 3 closes it by construction (every PE is updated before the move is
acted on) rather than by a reproduced failure.

Not changed: pendingLocReqs entries can stay set when the home drops a
request for an id it does not know; PR 1b removes requestLocationOnce.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@lvkale
lvkale merged commit 6ddfc64 into objid-redesign Oct 10, 2026
5 checks passed
@lvkale
lvkale deleted the objid-pr1a-fixes branch October 10, 2026 20:08
lvkale added a commit that referenced this pull request Oct 10, 2026
The explicit location requests went away in "a forwarded delivery repairs
the sender's cache"; the helper and its pending set had no callers left.
This closes the last item of Aditya's review of #4017 (an entry in
pendingLocReqs stayed set when the home dropped a request), which #4028
left to this PR.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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