mirror of
https://github.com/SikongJueluo/Mini-Nav.git
synced 2026-07-12 20:15:31 +08:00
feat(retrieval): add CAM retrieval benchmark with topk scoring and read noise support
- Add cocotb benchmark infrastructure under hw/sim/benchmarks/retrieval/ with Makefile - Implement test_retrieval_benchmark.py supporting configurable topk-k, read/write noise - Add cluster-based synthetic dataset generator with configurable bit-flip rates - Add reference model functions: match_topk, match_topk_from_scores, score_rows_with_read_noise - Add .justfile shortcuts: cam-test-retrieval-no-noise, cam-test-retrieval-read-noise - Add TOPK_K to Verilator EXTRA_ARGS via cocotb-common.mk - Add unit tests for topk sorting logic and stateful read-noise scoring
This commit is contained in:
@@ -152,3 +152,70 @@ def test_read_noise_model_is_reproducible_after_reset_seed():
|
||||
assert first.top1_index == second.top1_index
|
||||
assert first.top1_score == second.top1_score
|
||||
assert first.scores.tolist() == second.scores.tolist()
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# 测试 5:Top-K 排序 — 分数降序、平局行号升序
|
||||
# ==============================================================================
|
||||
|
||||
|
||||
def test_match_topk_from_scores_uses_score_desc_then_row_asc():
|
||||
"""Top-K 排序规则:分数越大越优先;分数相同时行号越小越优先。"""
|
||||
from model.ref_model import match_topk_from_scores
|
||||
import numpy as np
|
||||
|
||||
scores = np.array([7, 9, 9, 2, 7], dtype=np.int32)
|
||||
assert match_topk_from_scores(scores, 4) == [1, 2, 0, 4]
|
||||
|
||||
|
||||
def test_match_topk_scores_rows_by_xnor_popcount():
|
||||
"""match_topk 通过 xnor_popcount 计算分数,返回排序后的行索引和分数数组。"""
|
||||
from model.ref_model import match_topk
|
||||
|
||||
rows = [0b0000, 0b1111, 0b0011, 0b0101]
|
||||
query = 0b0000
|
||||
indices, scores = match_topk(query, rows, width=4, k=3)
|
||||
assert scores.tolist() == [4, 0, 2, 2]
|
||||
assert indices == [0, 2, 3]
|
||||
|
||||
|
||||
def test_match_topk_clamps_k_to_row_count():
|
||||
"""当 k 超过实际行数时,返回所有行(按排序)。"""
|
||||
from model.ref_model import match_topk
|
||||
|
||||
indices, scores = match_topk(0, [0, 1], width=1, k=5)
|
||||
assert scores.tolist() == [1, 0]
|
||||
assert indices == [0, 1]
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# 测试 6:读取噪声 stateful 评分助手的跨查询状态推进
|
||||
# ==============================================================================
|
||||
|
||||
|
||||
def test_score_rows_with_read_noise_stateful_across_queries():
|
||||
"""score_rows_with_read_noise 在多次调用间正确推进 lane PRNG 状态。
|
||||
|
||||
两次调用使用相同的 rows/query 和零噪声率:
|
||||
- 分数应一致(无噪声翻转)
|
||||
- 但 lane states 应该变化(PRNG 已推进)
|
||||
"""
|
||||
from model.ref_model import score_rows_with_read_noise
|
||||
|
||||
rows = [0, 0, 0, 0]
|
||||
query = 0
|
||||
lane_states = [1, 2]
|
||||
|
||||
scores_1, next_states_1 = score_rows_with_read_noise(
|
||||
query, rows, lane_states=lane_states, width=128, lanes=2,
|
||||
noise_bits=2, rate_num=0, rate_den=100,
|
||||
)
|
||||
scores_2, next_states_2 = score_rows_with_read_noise(
|
||||
query, rows, lane_states=next_states_1, width=128, lanes=2,
|
||||
noise_bits=2, rate_num=0, rate_den=100,
|
||||
)
|
||||
|
||||
assert scores_1.tolist() == [128, 128, 128, 128]
|
||||
assert scores_2.tolist() == [128, 128, 128, 128]
|
||||
assert next_states_1 != lane_states
|
||||
assert next_states_2 != next_states_1
|
||||
|
||||
Reference in New Issue
Block a user