Skip to content

feat(qli): add radix-select TopK demo with validated cases and known-issue notes - #78

Open
zzzyh222 wants to merge 13 commits into
PTO-ISA:mainfrom
zzzyh222:feat/qli-radix-topk
Open

feat(qli): add radix-select TopK demo with validated cases and known-issue notes#78
zzzyh222 wants to merge 13 commits into
PTO-ISA:mainfrom
zzzyh222:feat/qli-radix-topk

Conversation

@zzzyh222

Copy link
Copy Markdown

Summary

Add the QLI (Quant Lightning Indexer) radix-select TopK demo to one-level-arch.

QLI is the preprocessing operator of SparseFlashAttention (SFA): it selects the
topK most important K/V token indices. This PR adds:

  • kernels/qli/qli_pto_opt.hppmulti-round MSD radix-select TopK
    (qli_topk_radix): float score → IEEE-754 monotonic uint32 sortable key →
    THISTOGRAM Byte3→Byte0 narrowing (with Idx prefix) → tile pop-argmax
    extraction (in-tile zeroing, no scalar stores / no reload).
  • kernels/qli/qli_pto.hpp — baseline Step1-6 + TROWARGMAX TopK.
  • test/kernel/qli/ — demo driver qli_check_opt.cpp, golden generator
    gen_qli_golden.py (set-match criterion), data embed + address fix tools,
    Makefile / compile.all / README with full validation flow.

Validated cases (gfrun, set-match)

Sq Skv topK chunks cosine TopK set
64 128 128 1 1.000000 64/64
4 2048 512 1 1.000000 4/4
4 8192 512 4 1.000000 4/4
4 2080 512 1+tail 1.000000 4/4

Skv=2056 (non-kTk multiple) is not used for topK=512 because Step1-6 only
computes 2048 columns; Skv=2080 covers the tail-chunk path.

Known issues

Implementation-time emulator/toolchain issues (locally fixed or worked around,
all validated) are collected in qli_radix_issues_found.md (R1–R4).

Notes

  • TopK output contract: unordered set (tie → smallest index).
  • Performance (gfsim, Sq=4 Skv=8192 topK=512): 657K cycles vs ~1.82M baseline,
    BRob stall 31.0% → 14.9%, scalar block ratio 92.8% → 43.4%.

@zzzyh222
zzzyh222 force-pushed the feat/qli-radix-topk branch from cbe944f to 8f97c69 Compare August 24, 2026 14:29
@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

using tileK = TileRight<dtype, (qD==192? 256:qD), kTk, qD, kTk>;

P1 Badge Load transposed K through a column-major view

When fa_2d_unroll receives the documented row-major K[Skv,qD], changing tileK to [qD,kTk] without changing gmK makes TLOAD interpret the original buffer as a row-major qD × kTk window rather than as a transposed K block. In the checked cases (qD=128, kTk=32), even the first load selects the wrong elements, and gIterK(j,0) advances by qD*qD elements instead of kTk*qD, so every attention score is computed from incorrect K data. Use the same ColMajor<qD,Skv> transposed view used by the GMMA and QLI kernels, or retain the prior load shape.


if (outPos < topK) { \
tk iseq; TCMP<CmpMode::EQ>(iseq, key, kthk); \
RU cntEq = 0; \
RadixCountOf<CK, CKV>(iseq, &cntEq); \
int take = static_cast<int>(cntEq); \
if (outPos + take > topK) take = topK - outPos; \
QLI_RADIX_POP_EQN(tk, iseq, (RU)c * MaxTileCol, n1, \

P1 Badge Defer boundary candidates until all chunks are scanned

For multi-chunk inputs, this emits key == kth_value candidates as soon as their chunk is visited, before greater-than-threshold candidates in later chunks have been emitted. If the chunk containing the boundary value precedes any chunk containing a larger value, an equality candidate occupies one of the first topK slots prematurely; subsequent greater candidates are then written past the row's topK region, corrupting the next output row or scratch space. Extraction needs one pass over every chunk for all key > kth_value entries, followed by a second pass that fills the remaining slots from equality candidates.


# 1. 参数定义
# ============================================================
SQ = 64
G = 64
D = 128

P1 Badge Parameterize golden dimensions instead of only renaming output

The documented large-case workflow passes only an --outdir such as Sq4_Skv8192, but these module constants remain Sq=64, Skv=128, and topK=128; the directory name does not affect generated shapes. Consequently the advertised Sq=4, Skv=2048/8192/2080, topk=512 builds embed undersized K/scale_k data and compare against a reference computed for a different tensor, causing out-of-bounds input reads and invalid experiment results. Expose these dimensions as arguments and use them throughout generation and verification.


it_chunk cIter(chunk_ptr);
auto gin = cIter(0, 0);
tile_chunk S_chunk;
TLOAD(S_chunk, gin);

P2 Badge Restrict the final baseline TopK load to valid columns

When Skv > 2048 is not a multiple of 2048 (for example the documented Skv=2080 tail shape), the final chunk may contain only 32 valid scores, but this still loads and reduces a full 2048-column tile; the computed validCol is never applied. The reduction therefore reads into following rows or unrelated memory, may return an index beyond Skv, and then writes through that invalid index at line 430. Use a tail tile with physical padding and ValidCols=validCol, as the radix implementation does.


bad = [(i, v) for i, v in enumerate(vals) if v != golden]
if not bad:
print("PASS: all %d floats == %g (0x%s) <- matches golden K=%g"

P1 Badge Reject truncated matmul dumps before reporting success

When the dump is empty or contains fewer than M*N floats, bad is empty if every available value equals the golden (including the zero-element case), so this branch reports PASS. Although the CLI accepts M and N, they are used only to format mismatch locations and never to validate the dump length, allowing a failed or truncated --dump-memory operation to be recorded as a successful numerical check. Require exactly m*n values before comparing them.


if args.dbg_elf is None:
os.makedirs(CMP_ROOT, exist_ok=True)
with open(os.path.join(CMP_ROOT, args.res_log), "w") as f:
f.write("\nResult_Check Summary:\n")
f.write(f"\npass : {len(statics['pass'])}\n")

P1 Badge Return a failing status when numerical checks fail

After collecting failed runs or comparisons in statics['fail'], the program only writes the summary and falls off the end, so Python exits with status 0 even when every ELF timed out or produced incorrect output. This makes shell/CI callers treat the new numerical validator as successful; the new multi-thread copy has the same behavior. Exit nonzero whenever the failure list is nonempty, including in single-ELF debug mode.


if args.action in ("generate", "check"):
generate_data(
args.data_dir, args.rows, args.cols, args.epsilon, args.seed
)
if args.action == "check":
if args.elf is None:
raise ValueError("--elf is required for the check action")
run_gfrun(args.gfrun, args.elf, args.data_dir, args.timeout)

P2 Badge Keep the requested RMSNorm epsilon in sync with the ELF

For check, --epsilon changes only the generated golden data; the launched ELF always calls rms_norm with its compiled default 1e-6. Any caller exercising the exposed option with another epsilon therefore compares two different operators and receives a spurious numerical failure. Either compile/pass the requested epsilon into the kernel or reject non-default values during check.


make TESTCASE=rms_norm \
COMPILER_DIR="$COMPILER_DIR" \
M=16 N=256 \
tM=8 tN=128

P1 Badge Build the RMSNorm ELF with result checking enabled

The supplied build path omits res_check=on, so the resulting ELF takes the in-memory fallback branch and never reads input.bin/weight.bin or writes output.bin. Running the newly provided check_golden.sh after compile.all therefore cannot validate the generated data and fails because the expected output file is absent. Add res_check=on to the validation build or have the check script rebuild the matching ELF with that option.


DEFINES += -DTM=$(TM) -DTN=$(TN) -DTK=$(TK)

P2 Badge Wire the advertised FIXP global dimensions into the benchmark

Only TM/TN/TK are passed to the source, while M/N/K affect only the ELF filename. Thus an override such as M=64 N=64 K=64 TM=32 TN=32 TK=32, which the generated report says is supported, still allocates and executes a single 32×32×32 operation but labels it as a 64×64×64 benchmark. This silently misclassifies performance and coverage results; either implement the global-tile loops using M/N/K or remove those independent parameters from the target name and documentation.


tk tNan01; TCMP(tNan01, bits, tNan);

P2 Badge Detect every IEEE-754 NaN before building radix keys

This comparison recognizes only the single positive canonical bit pattern 0x7fc00000; negative NaNs, signaling NaNs, and quiet NaNs carrying another payload bypass the intended NaN-to-zero mapping. Positive payload NaNs then map above finite positive scores and can be selected into TopK, contrary to the function's stated NaN→0 behavior. Detect NaNs from the exponent and nonzero mantissa fields rather than comparing the entire word to one encoding.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

…line, golden dim args

- qli_pto_opt.hpp: extraction now emits all key>kth_value across chunks in a
  first pass, then fills remaining slots from key==kth_value equal candidates
  (prevents out-of-range writes when early chunks hold many equal-boundary
  values while later chunks hold larger keys).
- qli_pto_opt.hpp: NaN detection widened to 'exponent all-ones AND mantissa
  nonzero' so negative/signaling/payload NaNs map to the lowest sortable key
  instead of only the single canonical 0x7FC00000 pattern.
- qli_pto.hpp: Skv>2048 tail chunk loads use physical padding tile with
  ValidCols=tail length, avoiding out-of-bounds reads and >Skv indices.
- gen_qli_golden.py: dimensions (--sq/--skv/--topk/--g/--d) are CLI args; the
  output directory no longer drives tensor shapes.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b3dc77e526

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +41 to +42
python3 gen_qli_golden.py --mode gen \
--outdir ../../../../../compare/qli_fp8_B1_Sq4_Skv8192_g64_Tm16_Tk32

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Generate the 8192-token inputs with matching dimensions

This command only changes the output directory name; gen_qli_golden.py explicitly does not infer dimensions from that name and defaults SKV to 2080. Following the documented 8192-token flow therefore creates undersized K/scale data and 2080-column references, while the later build instantiates Skv=8192, causing the kernel to read beyond the embedded inputs and making verification fail or report invalid experiment results. Pass --skv 8192 (and ideally all dimensions) here.

Useful? React with 👍 / 👎.

.section .data
.global _binary_srcq_data_start
_binary_srcq_data_start:
.incbin "/home/z00947698/superScalar/SuperNPUBench/benchmark/one-level-arch/compare/qli_fp8_B1_Sq64_Skv128_g64_Tm16_Tk32/srcq.bin"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Replace the developer-specific incbin paths

On any checkout that does not have this exact /home/z00947698/... directory, assembling qli_check_data.s fails before the advertised demo can build. The documented sed command only replaces the configuration-directory suffix, so it leaves this machine-specific prefix intact; moreover, the preceding generation command writes relative to the current checkout. Use a repository-relative/configurable path or generate this assembly file from the selected data directory.

Useful? React with 👍 / 👎.

// indices 紧随 scores 之后,避免大 Sq*Skv 时与 scores 区域重叠
#define OUT_INDICES (0x4000802000ULL + (uint64_t)Sq * Skv * 4)

#define B 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor the configured batch count in the driver

When this test is built with B other than 1, the Makefile passes -DBatch=$(B) and names the ELF accordingly, but this unconditional definition keeps both execution loops at one iteration. A nominal B=2 run therefore computes and emits results only for the first batch even if matching two-batch input data is embedded; derive B from Batch as is done for the other configurable dimensions.

Useful? React with 👍 / 👎.

Comment on lines +328 to +330
if constexpr (Skv <= MaxTileCol) {
using tile_s = Tile<Location::Vec, float, 1, Skv, BLayout::RowMajor>;
using tile_idx = Tile<Location::Vec, uint32_t, 1, 32, BLayout::RowMajor, 1, 1>;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Pad small baseline score tiles to the minimum width

For any supported Skv below 128 that is still a multiple of 8, this branch creates a physical FP32 tile smaller than the documented 512-byte TLOAD/TSTORE minimum. The radix implementation already handles the same case with SinglePhy = max(Skv, 128) and a smaller valid width, but the baseline will instead produce an invalid tile for configurations such as Skv=64; apply the same physical padding here or reject those sizes.

Useful? React with 👍 / 👎.

Comment on lines +553 to +556
uint32_t* key_scratch = reinterpret_cast<uint32_t*>(
reinterpret_cast<uint8_t*>(indices_gm) + (uint64_t)Sq * topK * 4 + 8192);
uint32_t* temp_hist = key_scratch + (uint64_t)Sq * Skv;
uint32_t* prefix_buf = temp_hist + 256;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Accept an explicit workspace instead of writing past indices

When an integrator allocates only the documented [Sq, topK] indices output, this function unconditionally derives an undocumented scratch area beyond that allocation and writes Sq*Skv keys plus histogram and prefix storage there. The extra 8192-byte offset does not make the memory valid, so ordinary header use corrupts whatever allocation follows indices_gm; add an explicit workspace pointer/size or otherwise make the required storage part of the public buffer contract.

Useful? React with 👍 / 👎.

Comment on lines +89 to +91
# OUT_SCORES=0x4000802000, OUT_INDICES=OUT_SCORES+Sq*Skv*4(驱动内已动态化)
$SSM/bin/gfrun -f $ELF \
--dump-memory 0x4000802000:$((Sq*Skv*4 + Sq*topk*4 + 65536)):$OUTDIR/sim_out_radix.bin

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Define the dump-size variables before using them

The documented shell flow never assigns Sq, Skv, topk, or OUTDIR before this command. In a normal shell, the unset arithmetic variables evaluate to zero, so the advertised 8192-token case dumps only 65536 bytes even though its score matrix alone occupies 131072 bytes; the subsequent reshape then receives truncated data. Define the variables in the snippet or use the literal dimensions selected in the preceding build command.

Useful? React with 👍 / 👎.

…ore B)

- QLI_RADIX_POP_N: replace TROWMAX+TSTORE+TEXPANDS+TCMP+TMUL+TROWMAX
  index-derivation chain with TROWARGMAX(best) + TADDS(+chunkBase)
- QLI_RADIX_POP_EQN: same TROWARGMAX on rev+1 (smallest global index)
- drop unnecessary descending sort (TopK set contract)
- verified: 4 key cases (Sq64/128, Sq4/2048/8192/2080) cosine=1.0 set=100%;
  adversarial early-eq+later-gt case PASS; multi-pattern NaN PASS
- blocks Sq4/Skv2048: 71,918 -> 61,678 (-14.2%)
… extract)

- A1: TROWARGMAX single-op pop; 4 key cases cosine=1.0 set=100%; blocks -14%
- A2: bucket-reuse analysis shows no gain (skipped; docs record why)
- B: TSCAN instruction implemented+verified (SSM + tileop-api; prefix-sum
  correct); TSCATTER blocked by LinxV5 'Match Instruction Error' -> B not
  adoptable; SSM no regression confirmed

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: aed07713ca

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

{ gidx gi(prefix_buf); TLOAD(idxTile, gi); }

th hist;
THISTOGRAMX(hist, key, idxTile, r);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Include the required THISTOGRAM decoder fix

On the repository's documented SuperScalarModel environment, this multi-round call cannot distinguish Byte2/Byte1/Byte0: the newly added qli_radix_issues_found.md states that the model decodes every ByteId as Byte3 and that the validating runs used a local, still-unsubmitted Block.cpp fix. Consequently rounds r=2..0 repeatedly histogram the highest byte, producing an incorrect threshold and TopK set for ordinary inputs whose candidates share that byte. Land the paired model fix or avoid relying on the broken byte selector before advertising this demo as runnable.

Useful? React with 👍 / 👎.

using t1 = Tile<Location::Vec, RU, 1, 32, BLayout::RowMajor, 1, 1>;
using gi1 = global_tensor<RU, RowMajor<1, 1>>;
t1 s;
TROWSUM(s, m01);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Ship the UINT32 reduction and argmax support

On the stock documented SuperScalarModel, extraction aborts when this UINT32 mask reaches TROWSUM; the added design document explicitly says the successful runs used a local B8 validator change that permits UINT32/UINT16 for TROWSUM, TROWMAX, and TROWARGMAX, but that change is not part of this repository or the setup instructions. Even with the ByteId decoder corrected, every nonempty TopK invocation reaches this count operation and cannot run in the advertised environment, so either include the paired model update or implement the count/pop path with supported dtypes.

Useful? React with 👍 / 👎.

Comment on lines +356 to +357
volatile uint32_t* row_u32 = reinterpret_cast<volatile uint32_t*>(scores_gm + (uint64_t)i * Skv);
row_u32[idx_val] = 0xF149F2CAu;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use a sentinel below every selectable score

When topK > 1 and a row contains scores below -1e30f, replacing the first selected value with this bit pattern makes that position larger than the remaining candidates, so TROWARGMAX repeatedly emits the same index instead of distinct TopK entries. The QLI API does not bound score magnitude, and FP32 inputs/scales can legitimately produce values below this approximation; track selected positions with a mask or use a representation that is guaranteed to rank below every supported score.

Useful? React with 👍 / 👎.

Comment on lines +389 to +395
tk tSign; TANDS(tSign, key0, FP32_SIGN_MASK);
tk tNeg; TNOT(tNeg, key0);
tk tPos; TORS(tPos, key0, FP32_SIGN_MASK);
tk tSign01; TSHRS(tSign01, tSign, static_cast<RU>(31));
tk tDiff; TSUB(tDiff, tNeg, tPos);
TMUL(tDiff, tDiff, tSign01);
tk key; TADD(key, tPos, tDiff);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Canonicalize signed zero before constructing radix keys

When +0.0f and -0.0f straddle the TopK boundary, this sign-based mapping assigns them different keys (0x80000000 versus 0x7fffffff) even though they are equal FP32 scores. The documented contract says equal scores are resolved by smallest index, so a later-index +0.0f is incorrectly selected ahead of an earlier -0.0f; canonicalize both zero encodings before the sortable-key transform so the equality extraction applies the promised index tie-break.

Useful? React with 👍 / 👎.

…iver batch; document sim deps/scratch contract

Address Codex PR#78 review comments:
- qli_pto.hpp: pad Skv<128 baseline tile to SinglePhy / 128 (v5 512B min);
  replace -1e30f sentinel with -FLT_MAX (0xFF7FFFFF) so scores below -1e30
  cannot be re-selected.
- qli_pto_opt.hpp: canonicalize -0.0f to +0.0f in radix sortable-key so
  equal zero scores honor smallest-index tie-break.
- qli_check_opt.cpp: derive batch from -DBatch instead of hardcoding B=1.
- test/kernel/qli/README.md: pass explicit --sq/--skv/--topk to golden gen;
  define dump-size vars; document SuperScalarModel local-fix requirements
  (ByteId decode, UINT32 reduce/argmax gates, TROWARGMAX mapping) and the
  scratch-memory contract for qli_topk_radix.

Verified: 4 key cases (64/128, 4/2048, 4/8192, 4/2080) cosine=1.0 set=100%;
sentinel adversarial case topK [0,1] distinct.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 631a36cfb6

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

*out = static_cast<int32_t>(idx_val);

volatile uint32_t* row_u32 = reinterpret_cast<volatile uint32_t*>(scores_gm + (uint64_t)i * Skv);
row_u32[idx_val] = 0xFF7FFFFFu;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Mask selected entries instead of writing a finite sentinel

When the requested TopK reaches an input scored -inf, replacing a selected entry with 0xFF7FFFFF (-FLT_MAX) makes that entry larger than the remaining -inf candidates, so the next TROWARGMAX selects the same index again; the chunked branch repeats the same write at line 467. Fresh evidence after the earlier sentinel report is that the follow-up changed the sentinel to -FLT_MAX, which fixes finite FP32 values but still does not rank below negative infinity; use an explicit selected-position mask or otherwise exclude prior indices.

Useful? React with 👍 / 👎.


# scale_q: [Sq*g] FP32 — per-token-head Q 量化 scale
np.random.seed(SEED)
scaleQ = (np.random.randn(sq_ * g_) * 0.01).astype(np.float32)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Generate nonnegative quantization scales

The documented input contract declares scale_q and scale_k nonnegative, but this zero-mean Gaussian makes roughly half of scale_q negative, and line 90 does the same for scale_k. Consequently all advertised validation cases exercise sign-flipping values that cannot represent quantization scales, changing both score signs and TopK ordering relative to production-shaped inputs; generate positive scales, for example from absolute values or a positive distribution.

Useful? React with 👍 / 👎.

.global _binary_srcsq_data_end
_binary_srcsq_data_end:
.global _binary_srcsq_data_size
.equ _binary_srcsq_data_size, .-_binary_srcq_data_start

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Measure each embedded scale blob from its own start

Any consumer of _binary_srcsq_data_size receives the distance from the beginning of srcq, including all intervening Q/K/W data, rather than the size of srcsq; _binary_srcsk_data_size repeats the same error at line 44. Although the current driver only reads the start symbols, these exported size symbols will cause bounds checks, copies, or future generated-address code to overrun the corresponding blobs; subtract _binary_srcsq_data_start and _binary_srcsk_data_start, respectively.

Useful? React with 👍 / 👎.

nm_path = sys.argv[3]

# Get symbol addresses from ELF
result = subprocess.run([nm_path, elf_path], capture_output=True, text=True)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Abort when input-symbol address discovery fails

If llvm-nm exits unsuccessfully, is pointed at the wrong ELF, or omits even one expected symbol, this unchecked invocation leaves some or all hard-coded SRC*_ADDR values unchanged and the script still prints Addresses updated. Because the documented workflow relies on these absolute addresses, the rebuilt demo can silently read stale locations and report invalid scores; check the subprocess return code and require all five symbols before rewriting the source.

Useful? React with 👍 / 👎.

Concise summary of QLI's current implementation (radix-select TopK),
precision results, performance analysis, known issues, and future
optimization directions. Replaces verbose qli_fix_record.md history
as the canonical current-status reference.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fd26de9dc9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +87 to +88
sed -i "s|/home/z00947698/SuperNPUBench|$REPO_ROOT|g; \
s|qi_fp8_B1_Sq[0-9]*_Skv[0-9]*_g64_Tm16_Tk[0-9]*|qli_fp8_B1_Sq${SQ}_Skv${SKV}_g64_Tm16_Tk${TK}|g" \

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Match the committed incbin path in the replacement

Fresh evidence after the earlier developer-path report is that the new replacement command still matches neither part of the committed path: the prefix in qli_check_data.s contains /home/z00947698/superScalar/SuperNPUBench, while this pattern omits /superScalar, and the directory starts with qli_fp8 while the second pattern starts with qi_fp8. Following Step 2 therefore leaves all five developer-specific paths unchanged, so assembly fails on other checkouts and also cannot switch to the selected 8192-token dataset.

Useful? React with 👍 / 👎.

Comment on lines +22 to +23
#ifndef B
#define B 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use the macro that the Makefile actually defines

Fresh evidence after the earlier batch-count report is that the attempted guard checks B, but the qli_check_opt Makefile still passes -DBatch=$(B). Thus a documented build with B=2 leaves B undefined here, defines it as 1, and both execution loops process only the first batch; initialize B from Batch or have the Makefile define B.

Useful? React with 👍 / 👎.

Comment on lines +138 to +143
data = open('sim_out_radix.bin', 'rb').read()
scores = np.frombuffer(data[:SQ*SKV*4], dtype=np.float32).reshape(SQ, SKV)
indices = np.frombuffer(data[SQ*SKV*4:SQ*SKV*4+SQ*TOPK*4],
dtype=np.int32).reshape(SQ, TOPK)
ref = np.fromfile('reference_scores.bin', dtype=np.float32).reshape(SQ, SKV)
ref_idx = np.fromfile('reference_indices.bin', dtype=np.int32).reshape(SQ, TOPK)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Read verification artifacts from OUTDIR

When the documented steps are followed, gfrun writes sim_out_radix.bin to ${OUTDIR} and the generator also writes both reference files there, but this verification snippet opens all three as bare filenames without first changing into that directory. From the test/kernel/qli working directory established by the build steps, validation therefore raises FileNotFoundError; pass OUTDIR into the Python block or open ${OUTDIR}/... explicitly.

Useful? React with 👍 / 👎.

Comment on lines +229 to +231
ifeq ($(QLI_DTYPE), INT8)
DEFINES += -DQLI_INT8
DT_TAG = _int8

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject INT8 until the embedded inputs and golden match it

When QLI_DTYPE=INT8 is selected for the main qli_check_opt testcase, this branch makes the driver interpret srcq.bin and srck.bin as signed integers, but the only supplied generator always serializes FP8 E4M3 bit patterns and computes its reference from their FP8 values. The build therefore succeeds under an _int8 name while executing and validating unrelated numeric inputs, which can produce misleading experiment results; either add an INT8 generation/reference path or reject this configuration.

Useful? React with 👍 / 👎.

New file qli_pto_opt_simple.hpp: simplified MSD radix-select TopK with
~235 lines (vs ~376 in qli_pto_opt.hpp). Key simplifications:
- FOR_EACH_CHUNK macro eliminates 4× repeated tail branching
- MAKEKEY: sign-flip only (no NaN/-0 detection, ~7 tile ops)
- Single POP_N macro (no separate POP_EQN with rev trick)
- Merged GT+EQ extraction in single chunk loop
- Code is clean enough to see the actual cost (4×NumChunks THISTOGRAM
  + topK×POP)

qli_pto_opt.hpp retained as full-featured version (THISTOGRAMX asm,
NaN/-0 defense, rev min-index extraction).

Verified: Sq=64/128/128, Sq=4/2048/512, Sq=4/8192/512, Sq=4/128/8,
Sq=4/2080/512 all cosine=1.0 set=100% nan=0

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bc821b19d3

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".


#define OUT_SCORES 0x4000802000ULL
// indices 紧随 scores 之后,避免大 Sq*Skv 时与 scores 区域重叠
#define OUT_INDICES (0x4000802000ULL + (uint64_t)Sq * Skv * 4)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Place indices after every batch's score matrix

When the driver runs with B > 1—for example after correcting the already-reported Batch macro mismatch or when compiling with -DB=2—the score loop writes B * Sq * Skv floats, but OUT_INDICES begins after only one batch. The first TopK call therefore overwrites batch 1's score matrix before its call at lines 98–101 reads it, producing invalid indices for subsequent batches; offset the indices region by B * Sq * Skv * 4 bytes.

Useful? React with 👍 / 👎.

Comment on lines +316 to +318
tk sign; TANDS(sign, bits, 0x80000000u); \
tk neg; TNOT(neg, bits); \
tk pos; TORS(pos, bits, 0x80000000u); \

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Canonicalize signed zero in the demo's sortable keys

When +0.0f and -0.0f straddle the TopK boundary, this mapping assigns them different keys (0x80000000 and 0x7fffffff), so a later +0.0f can displace an earlier equal -0.0f. Fresh evidence after the earlier signed-zero report is that the full variant was corrected, but the actual demo driver now includes this simplified header, where the uncanonicalized mapping remains; normalize both zero encodings before applying the sign transform.

Useful? React with 👍 / 👎.

Replace all macros (FOR_EACH_CHUNK, MAKEKEY, HCHUNK, POP_N, EXTRACT)
with template functions (RadixMakeKey, RadixChunkHist, RadixPopN,
RadixExtract, HistMergeChunk, ExtractChunk). Main function uses
direct if-constexpr for tail handling instead of FOR_EACH_CHUNK macro.

- No macros, no lambdas, no ic wrappers
- Clean template functions taking raw pointers + compile-time shape params
- 207 lines for TopK section (vs ~235 with macros)
- All 5 key cases verified: cosine=1.0 set=100% nan=0

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c6c3b3aa66

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +315 to +316
template <int CK, int CKV>
inline void RadixPopN(TKey<CK, CKV>& mv, RU chunkBase, int32_t* out, int n) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep radix-pop tiles out of function parameters

When the recommended qli_check_opt target is built, it includes this simplified header, and every topK > 0 extraction eventually passes a candidate tile by reference to this function. The added qli_radix_issues_found.md documents that this exact RadixPopN function form is mis-lowered by the LinxV5 backend into an S64 load and an incompatible UINT32/INT64 comparison, causing validation to abort; qli_pto_opt.hpp therefore moved the operation into macros with function-local tiles, but the demo's simplified header retains the broken form. Apply the same local-tile workaround here or make the driver include the corrected implementation.

Useful? React with 👍 / 👎.

DEFINES += -DQLI_DTYPE_FP8
DT_TAG = _fp8
endif
TARGET = $(ELF_HEAD)/$(TESTCASE)$(DT_TAG)_B$(B)_Sq$(Sq)_Skv$(Skv)_g$(g)_Tm$(Tm)_Tk$(Tk).elf

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include topK in the generated ELF name

When two experiments use the same batch and tensor/tile dimensions but different topk values, both builds resolve to this identical target path even though -DTtopk changes the binary's output shape and behavior. The later build silently overwrites the earlier ELF, so downstream address-fixing, dumping, or verification can run a binary whose TopK configuration cannot be determined from its advertised filename; add topk to the target name as is already done for the other configuration dimensions.

Useful? React with 👍 / 👎.

Comment on lines +41 to +42
clean:
@find $(OBJ_ROOT) -type f -name "*.o" -exec rm -rf {} \;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restrict cleanup to QLI build objects

Every normal QLI build depends on the phony clean target from Makefile.common, and this replacement recipe deletes every .o beneath the shared one-level-architecture output tree rather than only QLI objects. Building this testcase therefore destroys cached objects for unrelated kernel tests and can also remove objects being produced by a concurrent build, leading to unnecessary full rebuilds or nondeterministic link failures; scope the deletion to this testcase's object directory.

Useful? React with 👍 / 👎.

…hpp)

New qli_pto_opt_dynamic.hpp: runtime Sq/Skv/topK (no template shape
params) + multi-PE interface (get_thread_idx + stride loop).

- Single PE (NPE=1, FP8 direct TMATMUL): verified on all key cases
  (Sq=4/64, Skv=128/2048/2080/8192, cosine=1.0 set=100% nan=0)
- Multi PE (NPE>1): standard cooperative path per matmul_multithread
  pattern - FP32 conversion (TCVT, FP32 NORM required by v0.58
  cooperative TMATMUL), D=128 split into two [64,32] FP32=8KB halves
  (Shared tile 8KB limit), TMOV_L2S_PUBLISH + TMATMUL/TMATMUL_ACC.
  Per-PE hist/prefix scratch (256+32 uint32) to avoid histogram
  races. Numeric verification NOT passing under gfrun (only token 3
  partially correct); documented as known limitation pending upstream
  cooperative TMATMUL support. Sq must be multiple of numPEs.
- scores row stride is paddedSkv = ceil(Skv/2048)*2048 (full-chunk
  reads; tail padding zeroed in key_scratch as key=0 never selected)
- Driver qli_check_opt_dynamic.cpp + Makefile entry (NPE param)

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 364ef93788

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

```bash
# 与 Makefile 维度一致
export SQ=4 SKV=8192 TOPK=512 G=64 TM=16 TK=32
OUTDIR=../../../../../compare/qli_fp8_B1_Sq${SQ}_Skv${SKV}_g${G}_Tm${TM}_Tk${TK}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep generated inputs under the path embedded in Step 2

Fresh evidence after the earlier path-replacement reports is that, when these instructions are followed from the repository root, $OUTDIR is expanded only after the cd test/kernel/qli/src, so five .. components resolve it to benchmark/compare/...; the assembly path that Step 2 attempts to produce remains under benchmark/one-level-arch/compare/.... Thus even after correcting the already-reported sed typos, Step 1 generates the blobs in a different directory and Step 3 cannot find them; use four .. components here or make the replacement target the generated absolute directory.

Useful? React with 👍 / 👎.

Comment on lines +293 to +294
uint32_t* hist_scratch = key_scratch + (uint64_t)Sq * paddedSkv
+ (uint64_t)tid * 288;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reserve histogram scratch for every PE

When numPEs > 1, each PE selects a distinct 288-word region using tid, so the required trailing workspace is numPEs * 1152 bytes. The public contract above this function promises only one 1152-byte hist/prefix region; a caller allocating exactly that documented size will have every PE after PE 0 write beyond the buffer during TopK. Include the PE multiplier in the workspace contract and allocation requirement.

Useful? React with 👍 / 👎.

Comment on lines +60 to +61
q + i * Sq * 64 * 128, k,
w + i * Sq * 64, scale_q + i * Sq * 64, scale_k,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Advance K and scale_k for each dynamic batch

When the dynamic target is run with B > 1 after the already-reported Batch/B macro mismatch is corrected (or when compiled with -DB directly), Q, W, and scale_q advance to the current batch but K and scale_k always remain at batch 0. This differs from the static driver, which advances all five inputs, and produces incorrect scores for later batches containing distinct K/scales; offset these pointers by i * Skv * 128 and i * Skv, respectively.

Useful? React with 👍 / 👎.

| concat | 4 | ✓ | gather/scatter |
| control | 1 | △ | pure tile-op; run gfsim with `-s core.singleTierMode=true`; `.data` via `gen_data.py` |
| sort | 1 | △ | topk |
| qli | 4 | ✓ | radix-select TopK (qli_check_opt); set-match verified; see [`qli/README.md`](qli/README.md) |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Register QLI with the aggregate compiler

A repo-wide search finds no QLI invocation in benchmark/one-level-arch/compile_all.sh, whose compile_operator calls explicitly enumerate every suite rather than discovering compile.all files. Consequently the newly listed QLI suite and its four compile configurations are skipped by the repository's full-compilation command, so aggregate runs can report completion without compiling any of this new kernel code; add the QLI suite to that enumeration.

Useful? React with 👍 / 👎.

- gen_cases.py: hist dst array now M*256 (was M*N) to match THISTOGRAM
  output shape [src.ValidRow, 256] UINT32
- vector_bench.hpp: added bench_hist_u32 with dst tile Tile<Vec,uint32_t,M,256>
- Regenerated thistogram_i16/i32_16x16.cpp to use bench_hist_u32
- gen_cases.py hist kind now emits uint32_t ch[M*256] dst buffer
- qli_check_data.s: updated QLI test data addresses
- qli_check_opt.cpp: updated QLI test driver addresses
- include/: symlinks to tileop-api headers for __cpu_sim__ build
1. Function signature: template_asm.hpp:224
2. Idx shape constraints: AccumulateBlockInfo.cpp:201-207
3. Assembly template: template_asm.hpp:226-233
4. Related histogram APIs: template_asm.hpp:6711-6971
5. Non-qli reference code: thistogram_i32_16x16.cpp:10
Migrate qli kernels to the PTO v0.58.4 tile interface (ops-20260828
toolchain: llvm adcb8794 + TileOP-API f94bc12 + gfrun d8903938):

- Step1-6 matmul: TileLeft/TileRight/Vec-acc + TLOAD/TSTORE ->
  CubeTileM16/CubeTileN8/CubeAccumulatorM16 + TLOAD_CUBE/TSTORE_CUBE,
  with a GM round-trip bridge (TSTORE_CUBE -> TLOAD) back to Vec tiles
  for the ReLU/W/TCOLSUM chain (same pattern as fa_2d_unroll_gmma)
- K operand: stored as transposed [D, Skv] row-major (CUBE_N8 contract);
  dynamic variant uses per-kTk-block contiguous layout with per-block
  iterators (avoids MaxSkv template-stride mismatch)
- W*scale_q: pre-broadcast to [kTm, kTk] GM by the driver, applied with
  plain TMUL (v0.58.4 row-expansion validator requires a physical
  one-column broadcast source, incompatible with the 128B tile floor)
- TopK: TCMP tile-tile replaced by TCMPS scalar compares + TSUB diff
  (TCMP tile-tile asm emits cmode mnemonics the current LLVM matcher
  rejects; THISTOGRAM B.DATR similarly fixed in the local TileOP header)
- Multi-PE dynamic: Q/K per-PE local CUBE tiles (Shared-B rendezvous
  semantics not realized under gfrun independent-main model; documented
  as known limitation)

Verified on ops-20260828 env (single PE, all cosine=1.0 set=100%):
  simple: Sq4/Skv128/8, Sq4/Skv2048/512, Sq4/Skv8192/512,
          Sq4/Skv2080/512(tail), Sq64/Skv128/128
  dynamic NPE=1: Sq4/Skv128/8 (scores + TopK)
  dynamic NPE=4: Step1-6 scores all-correct on 4 tokens; concurrent
  TopK index extraction races (only last-finishing PE's TopK intact)

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3ee5a75c4d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

for (int d = 0; d < 128; d++)
for (int c = 0; c < 32; c++)
ktt[j * 128 * 32 + d * 32 + c] = k[(j * 32 + c) * 128 + d];
static float tmp16[16 * 32];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Allocate a CUBE bridge slot for every PE

When the advertised dynamic target is built with NPE > 1, qli_pto_dynamic writes each PE's CUBE result to temp_gm + tid * 16 * 32, but this driver allocates only one 16×32 slot. PE 1 and above therefore write beyond tmp16, corrupting adjacent storage and invalidating the multi-PE experiment; size this buffer by numPEs or provide separate per-PE storage.

Useful? React with 👍 / 👎.

void bench_hist_u32(uint32_t *c, D *a, D *idx, int byteId, auto op) {
iter_t<D, M, N> gA(a), gIdx(idx);
auto gA0 = gA(0, 0), gI0 = gIdx(0, 0);
using dst_tile_t = Tile<Location::Vec, uint32_t, M, 256, BLayout::RowMajor>;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep the histogram destination within the 8KB tile limit

For both generated M=16 THISTOGRAM cases, this type creates a uint32_t[16,256] tile, which is 16KB even though the target's active tile limit is 8KB. The cases listed in microbenchmark/vector/compile.all will therefore be rejected or misencoded instead of testing THISTOGRAM; split the rows across multiple destination tiles or reduce the benchmark's M to at most 8.

Useful? React with 👍 / 👎.

static float* s_default_temp = nullptr;
if (temp_gm == nullptr) {
if (s_default_temp == nullptr) {
s_default_temp = scores_ptr + (uint64_t)Sq * Skv + 2048;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Account for the default temporary-buffer gap

When a caller omits temp_gm and allocates only the documented score output followed by kTm*kTk floats of scratch, this offset silently skips another 2048 floats (8192 bytes), so the subsequent CUBE store writes beyond that allocation. Either place the default temporary directly after the scores or explicitly require the additional 8192-byte gap in the public buffer contract.

Useful? React with 👍 / 👎.

TKey<CK, CKV> bits; TLOAD(bits, gs);
TKey<CK, CKV> sign; TANDS(sign, bits, 0x80000000u);
TKey<CK, CKV> neg; TNOT(neg, bits);
TKey<CK, CKV> pos; TORS(pos, bits, 0x80000000u);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Map NaNs below all selectable scores

When the recommended simple implementation receives the documented canonical NaN 0x7FC00000, this positive-value branch maps it to 0xFFC00000, which ranks above even positive infinity and is therefore selected into TopK. This contradicts the committed status report's promise that NaNs map to zero and are excluded; detect NaN exponent/mantissa patterns before applying the sortable-key transform, as the full implementation does.

Useful? React with 👍 / 👎.

fill_seq(a, 4096); fill_seq(b, 4096); fill_seq(d, 4096); zero(c, 4096);
BENCHSTART;
bench_hist<int32_t,M,N>(c,a,b,0,[](auto& dst,auto& s,auto& idx,auto b){ THISTOGRAM(dst,s,idx,b); });
uint32_t ch[4096]; zero(ch, 4096);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Initialize the histogram output before timing begins

In both committed THISTOGRAM microbenchmarks, the timed region now includes zeroing 4096 uint32_t elements before executing the single instruction under test. That scalar initialization can dominate the reported latency and makes these results incomparable with the other vector microbenchmarks, whose setup occurs before BENCHSTART; move the declaration and zero call outside the measured region and update the generator likewise.

Useful? React with 👍 / 👎.

Comment thread include/common
@@ -0,0 +1 @@
/home/z00947698/superScalar/linx-toolchain-build/output/linx_blockisa_llvm_musl/lib/clang/15.0.4/include/tileop-api/common No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Resolve TileOP headers from the configured toolchain

When COMPILER_DIR selects any toolchain other than this developer's /home/z00947698/.../linx-toolchain-build install, -I$(ROOT)/include still resolves common through this absolute symlink whenever that path exists, silently mixing headers from one TileOP-API version with a different compiler; on other machines the committed link is simply dangling. This repository explicitly supports arbitrary toolchain install paths, so derive these headers from COMPILER_DIR or remove the machine-specific links.

Useful? React with 👍 / 👎.

float* temp_gm = nullptr) // [kTm, kTk] CUBE->Vec 桥接临时区
{
constexpr int Qb = Sq;
constexpr int Kb = Skv / kTk;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Enforce the score kernel's Skv block constraint

When Skv is not divisible by kTk—for example the documented Skv=2056, kTk=32 case—this floor division processes only the first 2048 columns, while qli_topk_radix still consumes all 2056 score positions. The unwritten tail can therefore contribute arbitrary indices and corrupt experiment results; add the documented Skv % kTk == 0 static assertion here or implement a tail block.

Useful? React with 👍 / 👎.

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