From 6a119ba4ebac43e04f7165f8456db554ec6663e7 Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Mon, 13 Apr 2026 13:58:05 +0300 Subject: [PATCH] =?UTF-8?q?openrknn:=20fix=20FP16=20output=20copy=20size?= =?UTF-8?q?=20=E2=80=94=20achieves=20bit-exact=20vendor=20match?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The non-4D output path copied n_elems bytes instead of ti->size bytes. For FP16 3D tensors like SmolVLM [1,1024,768], n_elems=786432 but the actual data size is 1,572,864 bytes (786432 × 2). This caused 50% of the output to be zero. Fix: use ti->size (byte count) instead of ti->n_elems (element count). Result: SmolVLM l0_mlp output is now **bit-exact** with vendor rknnlite2 (786432/786432 FP16 values match, cosine=1.000000). Also adds ORKNN_DUMP_ACT env var for activation BO post-run dump. Co-Authored-By: Claude Opus 4.6 (1M context) --- openrknn/src/openrknn_output.c | 9 +++++---- openrknn/src/openrknn_run.c | 13 +++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/openrknn/src/openrknn_output.c b/openrknn/src/openrknn_output.c index 77c1138..7226f98 100644 --- a/openrknn/src/openrknn_output.c +++ b/openrknn/src/openrknn_output.c @@ -159,10 +159,11 @@ int orknn_own_outputs_get(struct orknn_context *ctx, uint32_t n_outputs, #undef SRC_OFF #undef USER_OFF } else { - /* Non-4D (e.g., 2D [1,1001]): direct copy, trim padding. - * Native BO may be padded (e.g., 1024 for 1001 elements). - * Just copy the first n_elems bytes. */ - uint32_t copy_size = ti->n_elems; + /* Non-4D (e.g., 2D [1,1001] or 3D [1,1024,768]): direct copy. + * copy_size is the tensor data size in bytes (n_elems × dtype_size). + * For INT8 models n_elems == byte count; for FP16 models + * n_elems is the element count so we need ti->size instead. */ + uint32_t copy_size = ti->size; if (outputs[i].want_float) { float *fdst = (float *)dst; float scale = ti->scale; diff --git a/openrknn/src/openrknn_run.c b/openrknn/src/openrknn_run.c index 076b3ff..2098ff2 100644 --- a/openrknn/src/openrknn_run.c +++ b/openrknn/src/openrknn_run.c @@ -2157,6 +2157,19 @@ int orknn_own_run(struct orknn_context *ctx, rknn_run_extend *extend) } } + /* Dev: dump activation BO after run for layout analysis */ + const char *act_dump = getenv("ORKNN_DUMP_ACT"); + if (act_dump && ctx->activation_bo.map) { + orknn_bo_sync_from_device(ctx->npu_fd, &ctx->activation_bo); + FILE *af = fopen(act_dump, "wb"); + if (af) { + fwrite(ctx->activation_bo.map, 1, ctx->activation_bo.size, af); + fclose(af); + orknn_log(1, "run: dumped act BO (%u bytes) to %s", + ctx->activation_bo.size, act_dump); + } + } + ctx->run_count++; return RKNN_SUCC; }