Skip to content

Commit 5421751

Browse files
kmbandyclaude
andcommitted
feat(dsws): CPU model for Phase-B snapshot/quiesce + N-1 cross-check
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0132aDSBLwusCJ4KzHQTnvdu
1 parent 66eec7f commit 5421751

2 files changed

Lines changed: 56 additions & 0 deletions

File tree

ggml/src/ggml-cuda/aiter-integration/rdna4_fp8_gemm/spike/dvgpr_occ/dsws_ctrl_model.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,24 @@ static inline bool reserve_grow(std::atomic<uint32_t>& resv, uint32_t delta, uin
5252
}
5353
return true;
5454
}
55+
56+
struct WgSnap { uint32_t nC, nA, nB; };
57+
58+
static inline WgSnap snapshot_counts(uint32_t nC, uint32_t nA, uint32_t nB) {
59+
return WgSnap{nC, nA, nB};
60+
}
61+
62+
// Sentinels = work-threshold + snapshot role-count terminal bails (Phase A arithmetic,
63+
// with compile-time constants replaced by the per-epoch snapshot).
64+
static inline bool quiesce_ready(uint32_t rowblk_next, uint32_t bfrag_next,
65+
uint32_t arow_next, const WgSnap& s,
66+
uint32_t G, uint32_t FN) {
67+
return rowblk_next >= (G + s.nC)
68+
&& bfrag_next >= (FN + s.nB)
69+
&& arow_next >= (G + s.nA);
70+
}
71+
72+
// Role-agnostic safety net: fixed N waves, wid0 claimer never bails -> exactly N-1 bails.
73+
static inline bool quiesce_ready_nm1(uint32_t quiesce_cnt, uint32_t N) {
74+
return quiesce_cnt >= (N - 1);
75+
}

ggml/src/ggml-cuda/aiter-integration/rdna4_fp8_gemm/spike/dvgpr_occ/test_dsws_ctrl_model.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,41 @@ int main() {
4646
assert(r.load() == 90); // exactly the 3 winners' reservations remain
4747
}
4848

49+
// ---- snapshot/quiesce (Phase B Decision 1) ----
50+
{
51+
// snapshot freezes the counts used to size the quiesce sentinels
52+
WgSnap s = snapshot_counts(4, 2, 2); // G=6, FN=4
53+
// not ready: rowblk short of G + nC terminal bails
54+
assert(!quiesce_ready(6 + 3, 4 + 2, 6 + 2, s, 6, 4)); // rowblk 9 < 6+4
55+
// ready: every counter reached threshold + snapshot bails
56+
assert( quiesce_ready(6 + 4, 4 + 2, 6 + 2, s, 6, 4));
57+
// a moved partition (3c3a2b) needs different sentinels; old snapshot is wrong high
58+
WgSnap s2 = snapshot_counts(3, 3, 2); // sentinels: rowblk>=9, bfrag>=6, arow>=9
59+
assert( quiesce_ready(6 + 3, 4 + 2, 6 + 3, s2, 6, 4)); // 9,6,9 all meet -> ready
60+
assert(!quiesce_ready(6 + 3, 4 + 2, 6 + 2, s2, 6, 4)); // arow 8 < 9 -> NOT ready
61+
// N-1 cross-check agrees at the ready point (N=8 -> 7 bails)
62+
assert( quiesce_ready_nm1(7, 8));
63+
assert(!quiesce_ready_nm1(6, 8));
64+
}
65+
66+
{
67+
// Under any interleaving of N-1 bails, quiesce_ready_nm1 must not fire before the last bail.
68+
for (uint32_t trial = 0; trial < 64; ++trial) {
69+
std::atomic<uint32_t> cnt{0};
70+
std::atomic<bool> early{false};
71+
std::vector<std::thread> ts;
72+
const uint32_t N = 8;
73+
for (uint32_t w = 0; w < N - 1; ++w)
74+
ts.emplace_back([&]{
75+
if (quiesce_ready_nm1(cnt.load(), N)) early.store(true); // read BEFORE our bump
76+
cnt.fetch_add(1, std::memory_order_acq_rel);
77+
});
78+
for (auto& t : ts) t.join();
79+
assert(!early.load()); // never ready with a bail still outstanding
80+
assert(quiesce_ready_nm1(cnt.load(), N)); // ready once all N-1 landed
81+
}
82+
}
83+
4984
printf("dsws_ctrl_model: ALL PASS\n");
5085
return 0;
5186
}

0 commit comments

Comments
 (0)