Download src/core/conversation_cache_test.cpp from WineryLabs/Winery-Strata: direct link, hf CLI and curl.
- Browser
- Download file 12.7 kB
-
https://huggingface.co/WineryLabs/Winery-Strata/resolve/main/src/core/conversation_cache_test.cpp
- Command line
-
hf download hf://WineryLabs/Winery-Strata/src/core/conversation_cache_test.cpp
-
curl -L -o conversation_cache_test.cpp https://huggingface.co/WineryLabs/Winery-Strata/resolve/main/src/core/conversation_cache_test.cpp
12.7 kB
| using namespace strata::core; | |
| namespace { | |
| int checks = 0; | |
| void check(bool value, const char* description) { | |
| ++checks; | |
| if (!value) { std::fprintf(stderr, "FAIL: %s\n", description); std::exit(1); } | |
| } | |
| SavedConversation image(std::initializer_list<int32_t> ids, bool cvec = true) { | |
| SavedConversation s; | |
| s.live.ids = ids; | |
| s.live.gdn.resize(64, 7); | |
| s.cvec = cvec; | |
| return s; | |
| } | |
| } | |
| int main() { | |
| { | |
| ConversationBuffer bytes; | |
| const size_t first = ConversationBuffer::segment_bytes + 17; | |
| const size_t peak = bytes.allocation_peak(first); | |
| bytes.resize(first, 7); | |
| check(bytes.bytes() <= peak, "segmented payload and directory fit admitted bytes"); | |
| uint8_t* original = nullptr; | |
| bytes.visit(0, 1, [&](uint8_t* p, size_t, size_t) { original = p; return true; }); | |
| const size_t grown_peak = bytes.allocation_peak(first + 99); | |
| bytes.resize(first + 99, 9); | |
| bytes.visit(0, 1, [&](uint8_t* p, size_t, size_t) { | |
| check(p == original, "appending preserves existing payload addresses"); return true; | |
| }); | |
| check(bytes.bytes() <= grown_peak, "growth including transient directory fits admission"); | |
| std::vector<uint8_t> tail(116); | |
| check(bytes.read(tail.data(), ConversationBuffer::segment_bytes, tail.size()), "read spans segment boundaries"); | |
| check(std::all_of(tail.begin(), tail.begin()+17, [](auto v){return v==7;}) && | |
| std::all_of(tail.begin()+17, tail.end(), [](auto v){return v==9;}), "growth preserves prefix and initializes only suffix"); | |
| auto copy = bytes; | |
| bytes.resize(ConversationBuffer::segment_bytes + 10); | |
| bytes.resize(first, 7); bytes.resize(first + 99, 9); | |
| check(bytes == copy, "equality ignores differing segmentation after rewind and regrowth"); | |
| check(!bytes.read(tail.data(), bytes.size()-1, 2), "range check rejects a truncated payload"); | |
| check(bytes.allocation_peak(SIZE_MAX) == SIZE_MAX, "allocation estimate rejects overflow"); | |
| } | |
| { | |
| ConversationBuffer bytes; | |
| for (size_t n=1;n<=4096;++n) { | |
| const size_t peak = bytes.allocation_peak(n*17); | |
| bytes.resize(n*17,7); | |
| check(bytes.bytes() <= peak,"small append stays within the predicted allocation peak"); | |
| } | |
| size_t segments = 0; | |
| bytes.visit(0,bytes.size(),[&](const uint8_t*,size_t,size_t){++segments;return true;}); | |
| check(segments <= 4,"thousands of small turns do not create thousands of restore transfers"); | |
| } | |
| { | |
| ConversationKv layer; | |
| layer.k.resize(400); | |
| std::vector<ConversationKv> layers; | |
| layers.push_back(std::move(layer)); | |
| const size_t retained = layers.capacity()*sizeof(ConversationKv) + layers[0].bytes(); | |
| const size_t parked = image({1,2,3}).bytes(); | |
| ConversationCache cache(retained + parked, 4); | |
| check(cache.put(image({1,2,3})), "park before retaining active storage"); | |
| cache.retain(std::move(layers), 16); | |
| check(cache.bytes() == retained + parked && cache.size() == 1, "active retained storage consumes bytes but no parked slot"); | |
| cache.limit_reuse(9); cache.limit_reuse(12); | |
| auto reuse = cache.take_reuse(); | |
| check(reuse.unchanged_tokens == 9, "a later continuation cannot undo a rewind's dirty boundary"); | |
| check(cache.bytes() == parked, "taking retained buffers releases their budget accounting"); | |
| cache.retain(std::move(reuse.kv), 16); | |
| check(!cache.can_fit(parked),"retained storage is counted when checking a capture without eviction"); | |
| check(cache.retained_bytes() == retained && cache.size() == 1 && cache.evictions() == 0, | |
| "optional reuse admission does not evict or release anything"); | |
| check(!cache.can_fit(SIZE_MAX) && !cache.can_fit(1,SIZE_MAX),"non-mutating reservation rejects overflow"); | |
| check(cache.make_room(parked), "reservation can discard optional active buffers"); | |
| check(cache.retained_bytes() == 0 && cache.size() == 1 && cache.evictions() == 0, | |
| "pressure drops retained storage before evicting parked conversations"); | |
| } | |
| const std::vector<int64_t> a = {1, 2, 3, 4}, b = {9, 8, 7, 6}; | |
| { | |
| ConversationCache cache(1024, 2); | |
| check(cache.put(image({1, 2, 3})), "park A"); | |
| check(cache.put(image({9, 8, 7})), "park B"); | |
| auto match = cache.best(a, {}, true); | |
| check(match.tokens == 3 && match.live, "A/B/A: recover A"); | |
| auto restored = cache.take(match.index); | |
| check(restored.live.ids == std::vector<int32_t>({1, 2, 3}), "taking selected A preserves identity"); | |
| check(cache.size() == 1 && cache.best(b, {}, true).tokens == 3, "B remains parked"); | |
| check(cache.bytes() == image({9,8,7}).bytes(), "byte accounting after take"); | |
| check(cache.put(std::move(restored)), "park returned A as newest"); | |
| check(cache.put(image({5, 6})), "evict oldest by slot limit"); | |
| check(cache.best(b, {}, true).tokens == 0 && cache.best(a, {}, true).tokens == 3, "B evicted before A"); | |
| check(cache.evictions() == 1, "eviction counter"); | |
| } | |
| { | |
| auto s = image({1, 2, 3}); | |
| ConversationCheckpoint cp; | |
| cp.ids = {1, 2}; | |
| s.checkpoints.push_back(cp); | |
| ConversationCache cache(4096, 4); | |
| cache.put(std::move(s)); | |
| auto match = cache.best(std::vector<int64_t>{1, 2, 9, 4}, {}, true); | |
| check(match.tokens == 2 && !match.live, "edited suffix falls back to parked checkpoint"); | |
| check(cache.best(a, {}, true).tokens == 3, "live prefix beats shorter checkpoint"); | |
| check(cache.best(a, {}, false).tokens == 0, "steering mode is isolated"); | |
| check(cache.best(std::vector<int64_t>{1, 2}, {}, true).tokens == 0, "equal-length checkpoint cannot consume last token"); | |
| check(cache.best(std::vector<int64_t>{1}, {}, true).tokens == 0, "short prompt cannot match"); | |
| check(cache.best(std::vector<int64_t>{}, {}, true).tokens == 0, "empty prompt cannot match"); | |
| cache.put(image({1, 2, 3})); | |
| check(cache.best(a, {}, true).index == 1, "ties prefer most recently parked"); | |
| } | |
| { | |
| auto s = image({1, 2, 3}); | |
| s.live.imgs = {{1, 123}}; | |
| ConversationCache cache(1024, 3); | |
| cache.put(std::move(s)); | |
| check(cache.best(a, {{1,123}}, true).tokens == 3, "same image can resume"); | |
| check(cache.best(a, {{1,124}}, true).tokens == 0, "different image pixels invalidate same pad tokens"); | |
| check(cache.best(a, {}, true).tokens == 0, "missing image invalidates prefix"); | |
| check(cache.best(a, {{1,123},{2,45}}, true).tokens == 0, "additional image in cached prefix invalidates"); | |
| check(cache.best(a, {{1,123},{3,45}}, true).tokens == 3, "image after cached prefix does not invalidate"); | |
| } | |
| { | |
| const size_t one = image({1,2,3}).bytes(); | |
| ConversationCache cache(one*2, 8); | |
| cache.put(image({1,2,3})); cache.put(image({9,8,7})); | |
| check(cache.bytes() == one*2, "budget holds two exact-sized images"); | |
| auto held = cache.take(cache.best(a, {}, true).index); | |
| check(cache.make_room(one, held.bytes()), "count in-flight image when reserving outgoing snapshot"); | |
| check(cache.size() == 0, "in-flight reservation evicts otherwise fitting B"); | |
| check(cache.put(image({5,6,7}), held.bytes()), "insert with in-flight accounting"); | |
| check(cache.bytes()+held.bytes() <= one*2, "exchange obeys byte budget"); | |
| check(!cache.make_room(one+1, one), "oversized exchange rejected"); | |
| check(cache.size() == 1, "oversized snapshot does not evict useful entries"); | |
| auto huge = image({1}); huge.live.gdn.resize(one*3); | |
| check(!cache.put(std::move(huge)), "oversized image rejected"); | |
| check(cache.size() == 1, "oversized put leaves cache unchanged"); | |
| check(!cache.make_room(0, one*2+1), "held larger than budget cannot underflow"); | |
| } | |
| { | |
| // #342: MAIN -> SUB (9 turns) -> MAIN with 4 slots. Every SUB turn parks the previous turn's live state | |
| // (its reply as generated, which the next request re-rendered) with a chain that holds that turn's | |
| // boundary checkpoint; the copy a turn back adds only that stale tail and is dropped, so MAIN survives. | |
| auto cp = [](std::vector<int32_t> ids) { ConversationCheckpoint c; c.ids = std::move(ids); return c; }; | |
| auto with = [](std::vector<int32_t> prefix, std::initializer_list<int32_t> more) { | |
| prefix.insert(prefix.end(), more); return prefix; | |
| }; | |
| const std::vector<int32_t> root = {1, 2, 3, 4}; | |
| SavedConversation main = image({}); | |
| main.live.ids = with(with(root, {10, 11, 12}), {13, 14}); | |
| main.checkpoints = {cp(root), cp(with(root, {10, 11, 12}))}; | |
| const size_t big = 1 << 20; | |
| ConversationCache cache(big, 4); | |
| check(cache.put(std::move(main)), "park MAIN"); | |
| std::vector<int32_t> history = with(root, {20}); // SUB's conversation so far, re-rendered | |
| std::vector<ConversationCheckpoint> chain = {cp(root)}; | |
| for (int turn = 1; turn <= 9; ++turn) { | |
| chain.push_back(cp(history)); // the turn boundary the next request resumes from | |
| SavedConversation sub = image({}); | |
| sub.live.ids = with(history, {900, (int32_t) turn}); // + the reply with its thinking (stale tail) | |
| sub.checkpoints = chain; | |
| check(cache.put(std::move(sub)), "park SUB turn"); | |
| check(cache.size() <= 2, "one parked copy of SUB at a time"); | |
| history = with(history, {30, (int32_t) turn}); // the reply as the next request renders it | |
| } | |
| check(cache.evictions() == 0 && cache.superseded() == 8, "8 superseded copies dropped, nothing evicted"); | |
| const auto m = cache.best(with(with(root, {10, 11, 12}), {13, 14, 15}), {}, true); | |
| check(m.tokens == 9 && m.live, "MAIN still restores in full"); | |
| const auto s = cache.best(with(history, {40}), {}, true); | |
| check(s.tokens == (int64_t) history.size() - 2, "SUB resumes from its last turn boundary"); | |
| } | |
| { | |
| // what is NOT superseded: another conversation sharing only the root, an entry without checkpoints, the | |
| // other steering mode, a branch whose deepest checkpoint the new chain does not hold | |
| auto cp = [](std::vector<int32_t> ids) { ConversationCheckpoint c; c.ids = std::move(ids); return c; }; | |
| ConversationCache cache(1 << 20, 8); | |
| SavedConversation other = image({1, 2, 3, 4, 50, 51, 52}); | |
| other.checkpoints = {cp({1, 2, 3, 4}), cp({1, 2, 3, 4, 50, 51})}; | |
| cache.put(std::move(other)); | |
| cache.put(image({1, 2, 3, 4, 7, 7})); // no checkpoints | |
| SavedConversation steered = image({1, 2, 3, 4, 60, 61}, false); | |
| steered.checkpoints = {cp({1, 2, 3, 4, 60})}; | |
| cache.put(std::move(steered)); | |
| SavedConversation branch = image({1, 2, 3, 4, 60, 70, 71}); | |
| branch.checkpoints = {cp({1, 2, 3, 4}), cp({1, 2, 3, 4, 60, 70})}; | |
| cache.put(std::move(branch)); | |
| SavedConversation incoming = image({1, 2, 3, 4, 60, 80, 81}); | |
| incoming.checkpoints = {cp({1, 2, 3, 4}), cp({1, 2, 3, 4, 60})}; | |
| check(cache.put(std::move(incoming)), "park a conversation sharing roots with all of them"); | |
| check(cache.size() == 5 && cache.superseded() == 0, "none of them is superseded"); | |
| SavedConversation same_state = image({1, 2, 3, 4, 60, 70}); // live equal to the branch's deepest point | |
| same_state.checkpoints = {cp({1, 2, 3, 4})}; | |
| check(cache.put(std::move(same_state)) && cache.superseded() == 1 && cache.size() == 5, | |
| "the live state equal to an entry's deepest checkpoint supersedes it"); | |
| SavedConversation huge = image({1, 2, 3, 4, 60, 80}); | |
| huge.checkpoints = {cp({1, 2, 3, 4}), cp({1, 2, 3, 4, 60})}; | |
| huge.live.gdn.resize(2 << 20); | |
| check(!cache.put(std::move(huge)) && cache.size() == 5 && cache.superseded() == 1, | |
| "an oversized put drops nothing"); | |
| } | |
| { | |
| ConversationCache disabled(0,4), no_slots(1024,0); | |
| check(!disabled.enabled() && !no_slots.enabled(), "both disable switches"); | |
| check(!disabled.put(image({1,2,3})) && !no_slots.put(image({1,2,3})), "disabled cache stores nothing"); | |
| check(disabled.best(a,{},true).tokens == 0, "disabled cache has no matches"); | |
| } | |
| std::printf("conversation_cache_test: %d checks passed\n", checks); | |
| } | |