Skip to content

Refactor: host build graph, lazy completion watermark, 4 AICPU schedulers - #1619

Open
raphael-s-steiner wants to merge 1 commit into
hw-native-sys:mainfrom
huawei-csl:refactor/lazy-completion-mark
Open

Refactor: host build graph, lazy completion watermark, 4 AICPU schedulers#1619
raphael-s-steiner wants to merge 1 commit into
hw-native-sys:mainfrom
huawei-csl:refactor/lazy-completion-mark

Conversation

@raphael-s-steiner

@raphael-s-steiner raphael-s-steiner commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Refactor: host build graph — 4 AICPU schedulers, lazy completion watermark

Branch refactor/lazy-completion-markmain (single commit, e5979580), simpler repo.

One of two possible versions of host-build-graph completion-watermark refactor the other one being #1618.

This lazy one is somewhat less performant due to duplicated work, but has easier synchronization.

Revert: 3S+1P → back to 4 full schedulers

The prior model split the aicpu_thread_num_ AICPU threads into (N-1) core-owning scheduler threads (S) plus one dedicated, core-less resolution thread (P). Finished tasks were handed off through a per-S SPSC CompletedTaskQueue, and only P called on_task_complete — publishing completion_flags, draining wake lists, and advancing the watermark.

This branch reverts that split: all aicpu_thread_num_ threads are now full schedulers again (scheduler_cold_path.cppactive_sched_threads_ = aicpu_thread_num_, the aicpu_thread_num_ >= 2 gate is gone). Each thread's loop (scheduler_dispatch.cpp) now does completion (Phase 1), async/mailbox polling, dummy/dependency-only drain (Phase 3), and dispatch (Phase 4) itself. Removed entirely: run_resolution_thread, CompletedTaskQueue, p_thread_idx(), and the sp_queues_ array.

Completion watermark: lazy updates

  • completed_flags changed from a 1-byte-per-slot array (0/1) to int32 stamps: -1 = pending, else the completing task's own local_id. This is what makes flag-slot reuse (below) detectable.
  • The per-completion watermark advance is now a cheap, bounded, best-effort bump (weak_update_completed_watermark, capped at task_id + 1) done inline in on_mixed_task_complete — instead of always walking the full contiguous completed prefix on every single completion.
  • The expensive full-prefix walk (update_completed_watermark) still exists but now runs at most once per scheduler-loop iteration, after that iteration's completions and dispatch, plus at the loop's exit points (scheduler_cold_path.cpp's handle_orchestrator_exit) — so a low-id straggler completing after a higher one doesn't strand the watermark.
  • Semantics flipped from inclusive to exclusive: completed_watermark is now "lowest id not yet guaranteed complete" (was "highest id guaranteed complete"), so every gate changed from >= to > (wait_for_tensor_ready, on_scope_end, append_fanin_or_fail, etc. in pto_runtime2.cpp, pto_orchestrator.cpp).

Flag-slot reuse (fewer flags than tasks)

completion_flags is sized to task_window_size (the ring window), not to the total task count, so a slot is reused by local_id + task_window_size once a run submits more tasks than the array has room for:

  • Indexing goes through a new flag_index() bit-shuffle (swaps shuffle_lower_bits/shuffle_higher_bits of local_id & task_window_mask) so consecutive ids land on different cachelines — good for the linear watermark scan — while remaining a bijection over [0, task_window_size), so the reuse period is unchanged.
  • is_completion_flag_set stays correct across reuse via a completed_watermark fallback (cached per-thread in the new cached_completed_watermark array): once an id falls behind the watermark it reads as complete forever, even after its slot is later overwritten by a subsequent lap.
  • try_set_completion_flag (non-blocking) only writes once the slot's previous occupant (local_id - task_window_mask) is watermark-certified; otherwise it returns false without writing or spinning.
  • set_completion_flag (blocking/spinning) survives only for the host-side early-resolve publish in alloc_tensors (pto_orchestrator.cpp) — there's no AICPU scheduler loop on the host to retry from, so it has to spin instead.

Deadlock failsafe

A failed try_set_completion_flag is pushed onto a per-AICPU-thread min-heap, failed_heap_of_set_completion_flag (pto_scheduler.h), and retried once per loop iteration via retry_set_completion_flags, which drains it in ascending task-id order and stops at the first still-blocked entry (the heap min always has the loosest watermark requirement). Critically, the deferred store's wake-list drain is deferred right along with it — draining a producer's wake list before its flag is durably set would let a reclassified waiter re-register on an already-SENTINEL producer and spin forever, since that producer will never run on_mixed_task_complete again.

Correctness (no deadlock) rests on one invariant: no task may depend, directly or transitively, on a task whose id is >= its own id + task_window_size — a topologically-submitted graph satisfies this for free, since every fanin producer's id is already less than its consumer's. The heap/retry machinery is a pure failsafe on top of that — the code comment on failed_heap_of_set_completion_flag notes it "should always be empty."

Also included

  • New unit test test_hbg_shared_memory.cpp (+ CMake target) validating the shuffle_higher_bits invariant: init_per_ring now rejects a task_window_size too small to provide shuffle_lower_bits (4) trailing zero bits, which would otherwise make flag_index's shift amount negative (UB).
  • PTO2SharedMemoryRingHeader/PTO2SharedMemoryHeader grew (256→576 / 320→640 bytes) to hold the per-thread cached-watermark array and shuffle metadata; layout static_asserts updated accordingly.

Performance

Comparison against main and #1618 for both device wall-clock and kernel only (as measured by tracr)

A226CE25-BED4-4002-B56C-8E6CE81FA767 5F71AA5E-3B03-40EF-80BE-714FE8597F7E 6C3BA7A0-E4F9-40B5-B67D-EACF477455DE

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 160307fa-e8fd-4571-bc53-d6627916c479

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The scheduler replaces byte completion flags and a dedicated resolution thread with task-id stamps, per-thread watermark tracking, deferred publication retries, and inline task resolution across all AICPU scheduler threads.

Changes

Completion and scheduler execution

Layer / File(s) Summary
Shared-memory completion contract
src/a2a3/runtime/host_build_graph/runtime/pto_shared_memory.h, src/a2a3/runtime/host_build_graph/runtime/shared/pto_shared_memory.cpp, tests/ut/cpp/a2a3/test_hbg_shared_memory.cpp, tests/ut/cpp/CMakeLists.txt
Completion flags use atomic int32_t task-id stamps with -1 as the pending value. The shared-memory layout tracks per-thread cached watermarks and validates shuffle-bit requirements. Unit tests cover valid and invalid initialization.
Completion publication and retry flow
src/a2a3/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h, src/a2a3/runtime/host_build_graph/runtime/pto_async_wait.h, src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_cold_path.cpp
Scheduler completion paths pass thread indices, defer blocked flag stores in per-thread min-heaps, retry them in order, drain wake lists after publication, and advance completion watermarks.
Inline scheduler execution
src/a2a3/runtime/host_build_graph/aicpu/aicpu_executor.cpp, src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_context.h, src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_completion.cpp, src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_dispatch.cpp
All AICPU threads run dispatch and resolution work. Async tasks and dummy-ready tasks resolve inline. The dedicated resolution-thread queue and API were removed.
Watermark integration and runtime documentation
src/a2a3/runtime/host_build_graph/runtime/orchestrator_core/pto_orchestrator.cpp, src/a2a3/runtime/host_build_graph/runtime/orchestrator_core/pto_runtime2.cpp, src/a2a3/runtime/host_build_graph/runtime/pto_runtime2_types.h, src/a2a3/runtime/host_build_graph/docs/RUNTIME_LOGIC.md
Reclamation and consumer waits now require the completed watermark to exceed the relevant consumer ID. Hidden allocation completion publishes both the completion flag and watermark. Documentation describes the updated semantics.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SchedulerThread
  participant PTO2SchedulerState
  participant PTO2SharedMemoryRingHeader
  participant AsyncWaitList
  SchedulerThread->>PTO2SchedulerState: complete task with thread_idx
  PTO2SchedulerState->>PTO2SharedMemoryRingHeader: publish or queue completion flag
  PTO2SchedulerState->>PTO2SharedMemoryRingHeader: retry queued flags
  PTO2SchedulerState->>AsyncWaitList: drain wake list after publication
  PTO2SharedMemoryRingHeader-->>SchedulerThread: advance completed watermark
Loading

Possibly related PRs

Poem

A rabbit watched the task flags glow,
With watermarks in steady flow.
No thread was left to resolve alone;
Each scheduler claimed its own.
Stamps and retries kept paths bright—
Completion hopped through day and night.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 67.65% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main refactor: lazy completion-watermark updates and restoration of four full AICPU schedulers.
Description check ✅ Passed The description directly and comprehensively explains the scheduler refactor, watermark changes, flag reuse, retries, tests, and performance results.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/a2a3/runtime/host_build_graph/runtime/shared/pto_shared_memory.cpp (1)

83-102: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Guard the shuffle floor inside init_header_per_ring.

init_per_ring rejects task_window_sizes[r] whose __builtin_ctzll(...) is less than shuffle_lower_bits, but init_header() calls init_header_per_ring() directly and can set shuffle_higher_bits to a negative value. flag_index() then shifts by that negative amount, causing undefined behavior if a small task_window_size is passed there. Put this validation in init_header_per_ring so every caller is protected.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/a2a3/runtime/host_build_graph/runtime/shared/pto_shared_memory.cpp`
around lines 83 - 102, Move the task-window alignment validation from
PTO2SharedMemoryHandle::init_per_ring into
PTO2SharedMemoryHandle::init_header_per_ring, checking every task_window_sizes
entry before calculating or storing shuffle_higher_bits. Ensure direct callers
such as init_header() reject values with insufficient trailing zero bits,
preventing flag_index() from receiving a negative shift amount.
🧹 Nitpick comments (5)
src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_dispatch.cpp (2)

1141-1144: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Drop the always-true thread_idx guard, or state the intent.

AicpuExecutor::run rejects any thread_idx >= aicpu_thread_num_ before it calls resolve_and_dispatch (aicpu_executor.cpp lines 220-226). The condition at line 1141 is therefore always true, and every thread drains the dummy queue. If the guard is a leftover from the removed resolution-thread partition, remove it. If it encodes a future restriction, replace it with an assertion.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_dispatch.cpp`
around lines 1141 - 1144, Remove the redundant thread_idx < aicpu_thread_num_
guard around the dummy_ready_queue drain in resolve_and_dispatch, since
AicpuExecutor::run already validates the index; keep the dummy batch pop
behavior unchanged for every valid executor thread.

1293-1301: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Resolve the "Can be made less frequent" note before merge.

Line 1300 carries an open tuning note inside the hot loop. update_completed_watermark scans the completed prefix once per iteration on every thread, so the cost scales with task_window_size times the iteration count. Either record the measured cost that justifies the current frequency, or convert the note into a tracked item. The PR already contains measurements for this branch, so a short statement of the observed cost is enough.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_dispatch.cpp`
around lines 1293 - 1301, The hot-loop comment near
header->ring.update_completed_watermark must resolve the “Can be made less
frequent” note. Replace it with a brief statement documenting the measured cost
of the per-iteration completed-prefix scan, using the existing branch
measurements, or convert it into a tracked item with an issue reference;
preserve the watermark update behavior.
src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_completion.cpp (1)

186-225: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the duplicated Resolve phase emit. Both sites now time on_task_complete, redefine the same RESOLVE_EMIT_MIN_CYCLES constant, apply the same 1 µs filter, and call l2_swimlane_aicpu_record_sched_phase with L2SwimlaneSchedPhaseKind::Resolve. The shared root cause is the absence of one helper for this emit, so the constant and the filter can drift apart.

  • src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_completion.cpp#L186-L225: replace the inline timing, constant, and emit with a call to a single helper, for example emit_resolve_phase(thread_idx, t0, t1, consumers_resolved), and keep the on_task_complete call at this site.
  • src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_dispatch.cpp#L1160-L1188: call the same helper for the dummy path and delete the second RESOLVE_EMIT_MIN_CYCLES definition.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_completion.cpp`
around lines 186 - 225, The Resolve phase emission logic is duplicated across
both scheduler paths. In
src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_completion.cpp:186-225,
keep the on_task_complete call but replace the inline timing/filter/recording
logic with a shared emit_resolve_phase helper; in
src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_dispatch.cpp:1160-1188,
use the same helper for the dummy path and remove its duplicate
RESOLVE_EMIT_MIN_CYCLES definition, centralizing the 1 µs threshold and Resolve
recording behavior.
src/a2a3/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h (1)

34-34: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add explicit headers for the heap algorithms and comparator.

pto_scheduler.h uses std::push_heap, std::pop_heap, and std::greater<>, but only includes <atomic> and <vector> among the standard headers. Add <algorithm> for the heap operations and <functional> for std::greater<>.

♻️ Proposed include addition
+#include <algorithm>
+#include <functional>
 `#include` <vector>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/a2a3/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h` at line
34, Update the includes in pto_scheduler.h to add the standard headers algorithm
and functional, supporting the existing std::push_heap/std::pop_heap and
std::greater<> usages while retaining the current includes.
src/a2a3/runtime/host_build_graph/runtime/pto_async_wait.h (1)

283-285: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the unused Profiling template parameter.

The declaration, definition, call site, and body use <false> only and do not read Profiling, so make this a plain member function unless a future specialization adds profiling behavior. The matching out-of-class definition uses template <bool Profiling>.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/a2a3/runtime/host_build_graph/runtime/pto_async_wait.h` around lines 283
- 285, Remove the unused Profiling template parameter from poll_and_complete,
converting its declaration and matching out-of-class definition to a
non-template member function. Update every call site currently invoking
poll_and_complete<false> to call poll_and_complete directly, preserving the
existing behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/a2a3/runtime/host_build_graph/docs/RUNTIME_LOGIC.md`:
- Around line 664-667: Update the RUNTIME_LOGIC.md description of
retry_set_completion_flags to state that it runs at the Phase 1 → Phase 2
boundary, replacing the “top of the loop iteration” wording while preserving the
existing behavior details.
- Around line 686-694: Correct the RUNTIME_LOGIC.md description in §§8.2 and 8.4
to distinguish the two watermark advances: on_mixed_task_complete uses
weak_update_completed_watermark for a bounded advance through task_id + 1, while
resolve_and_dispatch performs the full contiguous-prefix advance once per
scheduler-loop iteration. Remove the claim that the completion callback advances
the full prefix or that capping at my_id is incorrect, and update §8.2 step 3 to
reference both mechanisms accurately.

In `@src/a2a3/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h`:
- Around line 471-473: Replace
PTO2SchedulerState::failed_heap_of_set_completion_flag with a fixed int32_t
storage array sized by a PTO2_MAX_... capacity and a count field, avoiding
non-trivial std::vector state. Update all accesses to use the count and bounded
array, and report an overflow when the failsafe cannot record another entry
instead of silently exceeding capacity.

In `@src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_dispatch.cpp`:
- Around line 994-998: Update the scheduler loop in the relevant dispatch
function so every exit path—completed_, orchestrator or scheduler errors, async
polling errors, and timeout—calls sched_->retry_set_completion_flags(thread_idx)
before header->ring.update_completed_watermark(thread_idx). Ensure deferred
completion entries are retried consistently before leaving the loop, without
changing the existing exit behavior.

---

Outside diff comments:
In `@src/a2a3/runtime/host_build_graph/runtime/shared/pto_shared_memory.cpp`:
- Around line 83-102: Move the task-window alignment validation from
PTO2SharedMemoryHandle::init_per_ring into
PTO2SharedMemoryHandle::init_header_per_ring, checking every task_window_sizes
entry before calculating or storing shuffle_higher_bits. Ensure direct callers
such as init_header() reject values with insufficient trailing zero bits,
preventing flag_index() from receiving a negative shift amount.

---

Nitpick comments:
In `@src/a2a3/runtime/host_build_graph/runtime/pto_async_wait.h`:
- Around line 283-285: Remove the unused Profiling template parameter from
poll_and_complete, converting its declaration and matching out-of-class
definition to a non-template member function. Update every call site currently
invoking poll_and_complete<false> to call poll_and_complete directly, preserving
the existing behavior.

In `@src/a2a3/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h`:
- Line 34: Update the includes in pto_scheduler.h to add the standard headers
algorithm and functional, supporting the existing std::push_heap/std::pop_heap
and std::greater<> usages while retaining the current includes.

In
`@src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_completion.cpp`:
- Around line 186-225: The Resolve phase emission logic is duplicated across
both scheduler paths. In
src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_completion.cpp:186-225,
keep the on_task_complete call but replace the inline timing/filter/recording
logic with a shared emit_resolve_phase helper; in
src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_dispatch.cpp:1160-1188,
use the same helper for the dummy path and remove its duplicate
RESOLVE_EMIT_MIN_CYCLES definition, centralizing the 1 µs threshold and Resolve
recording behavior.

In `@src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_dispatch.cpp`:
- Around line 1141-1144: Remove the redundant thread_idx < aicpu_thread_num_
guard around the dummy_ready_queue drain in resolve_and_dispatch, since
AicpuExecutor::run already validates the index; keep the dummy batch pop
behavior unchanged for every valid executor thread.
- Around line 1293-1301: The hot-loop comment near
header->ring.update_completed_watermark must resolve the “Can be made less
frequent” note. Replace it with a brief statement documenting the measured cost
of the per-iteration completed-prefix scan, using the existing branch
measurements, or convert it into a tracked item with an issue reference;
preserve the watermark update behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6a325e04-21b6-4075-8a13-25d7dd3f5c57

📥 Commits

Reviewing files that changed from the base of the PR and between 80aa287 and 5a13e02.

📒 Files selected for processing (15)
  • src/a2a3/runtime/host_build_graph/aicpu/aicpu_executor.cpp
  • src/a2a3/runtime/host_build_graph/docs/RUNTIME_LOGIC.md
  • src/a2a3/runtime/host_build_graph/runtime/orchestrator_core/pto_orchestrator.cpp
  • src/a2a3/runtime/host_build_graph/runtime/orchestrator_core/pto_runtime2.cpp
  • src/a2a3/runtime/host_build_graph/runtime/pto_async_wait.h
  • src/a2a3/runtime/host_build_graph/runtime/pto_runtime2_types.h
  • src/a2a3/runtime/host_build_graph/runtime/pto_shared_memory.h
  • src/a2a3/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h
  • src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_cold_path.cpp
  • src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_completion.cpp
  • src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_context.h
  • src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_dispatch.cpp
  • src/a2a3/runtime/host_build_graph/runtime/shared/pto_shared_memory.cpp
  • tests/ut/cpp/CMakeLists.txt
  • tests/ut/cpp/a2a3/test_hbg_shared_memory.cpp
💤 Files with no reviewable changes (1)
  • src/a2a3/runtime/host_build_graph/runtime/scheduler/scheduler_context.h

Comment thread src/a2a3/runtime/host_build_graph/docs/RUNTIME_LOGIC.md Outdated
Comment thread src/a2a3/runtime/host_build_graph/docs/RUNTIME_LOGIC.md
Comment thread src/a2a3/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h Outdated
@raphael-s-steiner
raphael-s-steiner force-pushed the refactor/lazy-completion-mark branch from 5a13e02 to d792027 Compare July 31, 2026 14:51
…lers

Co-authored-by: noabauma <noah.baumann@h-partners.com>

Co-authored-by: Sergio Martin <eienburuu@gmail.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.

1 participant