get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2194420/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2194420,
    "url": "http://patchwork.ozlabs.org/api/patches/2194420/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/glibc/patch/20260208220454.51741-4-zihong.plct@isrc.iscas.ac.cn/",
    "project": {
        "id": 41,
        "url": "http://patchwork.ozlabs.org/api/projects/41/?format=api",
        "name": "GNU C Library",
        "link_name": "glibc",
        "list_id": "libc-alpha.sourceware.org",
        "list_email": "libc-alpha@sourceware.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260208220454.51741-4-zihong.plct@isrc.iscas.ac.cn>",
    "list_archive_url": null,
    "date": "2026-02-08T22:04:38",
    "name": "[RFC,3/5] riscv: libmvec: add benchtests",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "052f4dea0ddf2af786658e56b901c0a18d055306",
    "submitter": {
        "id": 91553,
        "url": "http://patchwork.ozlabs.org/api/people/91553/?format=api",
        "name": "Yao Zihong",
        "email": "zihong.plct@isrc.iscas.ac.cn"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/glibc/patch/20260208220454.51741-4-zihong.plct@isrc.iscas.ac.cn/mbox/",
    "series": [
        {
            "id": 491443,
            "url": "http://patchwork.ozlabs.org/api/series/491443/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/glibc/list/?series=491443",
            "date": "2026-02-08T22:04:40",
            "name": "riscv: Add libmvec routines",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/491443/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2194420/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2194420/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "libc-alpha@sourceware.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@legolas.ozlabs.org",
            "libc-alpha@sourceware.org"
        ],
        "Authentication-Results": [
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org;\n receiver=patchwork.ozlabs.org)",
            "sourceware.org; dmarc=none (p=none dis=none)\n header.from=isrc.iscas.ac.cn",
            "sourceware.org;\n spf=pass smtp.mailfrom=isrc.iscas.ac.cn",
            "server2.sourceware.org;\n arc=none smtp.remote-ip=159.226.251.21"
        ],
        "Received": [
            "from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4f8MNh4gSJz1xtr\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 09 Feb 2026 09:06:28 +1100 (AEDT)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id BA0F64B9DB70\n\tfor <incoming@patchwork.ozlabs.org>; Sun,  8 Feb 2026 22:06:26 +0000 (GMT)",
            "from cstnet.cn (smtp21.cstnet.cn [159.226.251.21])\n by sourceware.org (Postfix) with ESMTPS id A85ED452C4FA\n for <libc-alpha@sourceware.org>; Sun,  8 Feb 2026 22:05:07 +0000 (GMT)",
            "from Mobilestation.localdomain (unknown [183.6.59.140])\n by APP-01 (Coremail) with SMTP id qwCowAAHsGuICIlpA257Bw--.50153S5;\n Mon, 09 Feb 2026 06:05:03 +0800 (CST)"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org BA0F64B9DB70",
            "OpenDKIM Filter v2.11.0 sourceware.org A85ED452C4FA"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org A85ED452C4FA",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org A85ED452C4FA",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1770588308; cv=none;\n b=AxwAKHteEAA1nUlD4YBxsyPPjrkQ5P38ol3UsUzaHUoL+SJLhAmdV5C8NEnF+BfEf8bz10CFBeRXsI+Ki/YsmBlfkEU52Ey4tExneRXNN3DZ2k9XE7KEtkPmyAhrYAa0jlknBo4HnRkStfsRRWCmZdpdOb/MxbjN3k4Kz1jx8xI=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1770588308; c=relaxed/simple;\n bh=XOWQHuXBr8PDAi4ecLZ+2F5d9ZBpP3BhWv+jBCxMf3I=;\n h=From:To:Subject:Date:Message-ID:MIME-Version;\n b=EFvzZWhZEqcHUD91xwuOE7uizGJjGO0TaaXVK30ZWzmz2CF1KCi3GLahXBnfKDGWu4kOjaZCXZcxrZyiMmaj8Zycdp1DqQl1JfWObKb1uvyk6heiMow1Tzc98wfb/snzuP9nKVWxVX1gPpNTDT+U2/eWFiOXmdGZYWe2BksNXVc=",
        "ARC-Authentication-Results": "i=1; server2.sourceware.org",
        "From": "Yao Zihong <zihong.plct@isrc.iscas.ac.cn>",
        "To": "libc-alpha@sourceware.org",
        "Cc": "zhangyin2018@iscas.ac.cn, zihongyao@outlook.com,\n Zihong Yao <zihong.plct@isrc.iscas.ac.cn>",
        "Subject": "[RFC PATCH 3/5] riscv: libmvec: add benchtests",
        "Date": "Mon,  9 Feb 2026 06:04:38 +0800",
        "Message-ID": "<20260208220454.51741-4-zihong.plct@isrc.iscas.ac.cn>",
        "X-Mailer": "git-send-email 2.47.3",
        "In-Reply-To": "<20260208220454.51741-1-zihong.plct@isrc.iscas.ac.cn>",
        "References": "<20260208220454.51741-1-zihong.plct@isrc.iscas.ac.cn>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-CM-TRANSID": "qwCowAAHsGuICIlpA257Bw--.50153S5",
        "X-Coremail-Antispam": "1UD129KBjvAXoW3KFWUtw47Kry8Ar4kWF1Utrb_yoW8Gr45Xo\n Z3KFWrJF47Jr1fCryrAa18trWfXry5GrW5X34DXa1DXws3Xr1rtF1Ik3W5X34fWwsrGa45\n Zas2qa9xXFWDXrnxn29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3\n AaLaJ3UjIYCTnIWjp_UUUYm7AC8VAFwI0_Xr0_Wr1l1xkIjI8I6I8E6xAIw20EY4v20xva\n j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r1rM28IrcIa0x\n kI8VCY1x0267AKxVW8JVW5JwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l84AC\n jcxK6xIIjxv20xvE14v26r1j6r1xM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4j6F4UM2\n 8EF7xvwVC2z280aVAFwI0_Jr0_Gr1l84ACjcxK6I8E87Iv6xkF7I0E14v26r4j6r4UJwAS\n 0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2\n IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0\n Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwCF04k20xvY0x0EwIxGrwCFx2\n IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v2\n 6r106r1rMI8E67AF67kF1VAFwI0_JF0_Jw1lIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67\n AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1lIxAIcVCF04k26cxKx2IY\n s7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr\n 0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x0JUTGQDUUUUU=",
        "X-Originating-IP": "[183.6.59.140]",
        "X-CM-SenderInfo": "p2lk00vjoszunw6l223fol2u1dvotugofq/",
        "X-BeenThere": "libc-alpha@sourceware.org",
        "X-Mailman-Version": "2.1.30",
        "Precedence": "list",
        "List-Id": "Libc-alpha mailing list <libc-alpha.sourceware.org>",
        "List-Unsubscribe": "<https://sourceware.org/mailman/options/libc-alpha>,\n <mailto:libc-alpha-request@sourceware.org?subject=unsubscribe>",
        "List-Archive": "<https://sourceware.org/pipermail/libc-alpha/>",
        "List-Post": "<mailto:libc-alpha@sourceware.org>",
        "List-Help": "<mailto:libc-alpha-request@sourceware.org?subject=help>",
        "List-Subscribe": "<https://sourceware.org/mailman/listinfo/libc-alpha>,\n <mailto:libc-alpha-request@sourceware.org?subject=subscribe>",
        "Errors-To": "libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org"
    },
    "content": "From: Zihong Yao <zihong.plct@isrc.iscas.ac.cn>\n\nAdd RISC-V libmvec benchtests for the benchtests subdir.\n\nWire the bench targets into the build, add RVV-specific CFLAGS,\nand provide an RVV capability check plus a generator script that\nemits per-function bench sources.\n\nSigned-off-by: Zihong Yao <zihong.plct@isrc.iscas.ac.cn>\n---\n sysdeps/riscv/rvd/Makeconfig                  |  12 +\n sysdeps/riscv/rvd/Makefile                    |  54 ++++\n sysdeps/riscv/rvd/bench-libmvec-arch.h        |  49 +++\n .../riscv/rvd/scripts/bench_libmvec_rvv.py    | 293 ++++++++++++++++++\n 4 files changed, 408 insertions(+)\n create mode 100644 sysdeps/riscv/rvd/bench-libmvec-arch.h\n create mode 100644 sysdeps/riscv/rvd/scripts/bench_libmvec_rvv.py",
    "diff": "diff --git a/sysdeps/riscv/rvd/Makeconfig b/sysdeps/riscv/rvd/Makeconfig\nindex 84649c6500..3c1fac4316 100644\n--- a/sysdeps/riscv/rvd/Makeconfig\n+++ b/sysdeps/riscv/rvd/Makeconfig\n@@ -65,3 +65,15 @@ $(common-objpfx)libmvec.mk: $(common-objpfx)config.make\n \t done; \\\n \t echo \"endif\";)> $@T\n \tmv -f $@T $@\n+\n+# Define libmvec function for benchtests directory.\n+libmvec-double-bench-funcs = \\\n+  log        \\\n+\n+libmvec-float-bench-funcs = \\\n+\n+bench-libmvec-double = \\\n+  $(addprefix double-, $(libmvec-double-bench-funcs)) \\\n+\n+bench-libmvec-float = \\\n+  $(addprefix float-, $(libmvec-float-bench-funcs))  \\\ndiff --git a/sysdeps/riscv/rvd/Makefile b/sysdeps/riscv/rvd/Makefile\nindex 7f409e3f02..3abcb8b913 100644\n--- a/sysdeps/riscv/rvd/Makefile\n+++ b/sysdeps/riscv/rvd/Makefile\n@@ -24,6 +24,48 @@ endif\n \n endif\n \n+ifeq ($(build-mathvec),yes)\n+\n+bench-libmvec := $(bench-libmvec-double) $(bench-libmvec-float)\n+\n+ifeq (${STATIC-BENCHTESTS},yes)\n+libmvec-benchtests = $(common-objpfx)mathvec/libmvec.a $(common-objpfx)math/libm.a\n+else\n+libmvec-benchtests = $(libmvec) $(libm)\n+endif\n+\n+$(addprefix $(objpfx)bench-,$(bench-libmvec)): $(libmvec-benchtests)\n+$(foreach b,$(bench-libmvec),$(eval LDLIBS-bench-$(b) += $(libmvec)))\n+\n+bench-libmvec-deps = $(..)benchtests/bench-libmvec-skeleton.c \\\n+\t\t     $(..)sysdeps/riscv/rvd/bench-libmvec-arch.h \\\n+\t\t     $(..)sysdeps/riscv/rvd/scripts/bench_libmvec_rvv.py \\\n+\t\t     bench-timing.h Makefile\n+\n+$(objpfx)bench-float-%.c: $(bench-libmvec-deps)\n+\t$(PYTHON) $(..)sysdeps/riscv/rvd/scripts/bench_libmvec_rvv.py $(basename $(@F)) > $@-tmp\n+\tmv -f $@-tmp $@\n+\n+$(objpfx)bench-double-%.c: $(bench-libmvec-deps)\n+\t$(PYTHON) $(..)sysdeps/riscv/rvd/scripts/bench_libmvec_rvv.py $(basename $(@F)) > $@-tmp\n+\tmv -f $@-tmp $@\n+\n+define riscv64-bench-vector-cflags-template\n+CFLAGS-bench-$(1).c += -march=rv64gcv -Wno-missing-prototypes -Wno-undef\n+endef\n+\n+define riscv32-bench-vector-cflags-template\n+CFLAGS-bench-$(1).c += -march=rv32gcv -Wno-missing-prototypes -Wno-undef\n+endef\n+\n+ifeq ($(config-machine),riscv64)\n+$(foreach b,$(bench-libmvec), $(eval $(call riscv64-bench-vector-cflags-template,$(b))))\n+endif\n+\n+ifeq ($(config-machine),riscv32)\n+$(foreach b,$(bench-libmvec), $(eval $(call riscv32-bench-vector-cflags-template,$(b))))\n+endif\n+\n ifneq ($(multi-arch),no)\n ifeq ($(subdir)$(build-mathvec),mathyes)\n \n@@ -36,4 +78,16 @@ endif\n \n endif\n \n+ifeq ($(subdir),benchtests)\n+\n+ifeq ($(build-mathvec),yes)\n+\n+bench-libmvec := $(bench-libmvec-float) $(bench-libmvec-double)\n+\n+endif\n+\n+endif\n+\n+endif\n+\n endif\ndiff --git a/sysdeps/riscv/rvd/bench-libmvec-arch.h b/sysdeps/riscv/rvd/bench-libmvec-arch.h\nnew file mode 100644\nindex 0000000000..41181206dc\n--- /dev/null\n+++ b/sysdeps/riscv/rvd/bench-libmvec-arch.h\n@@ -0,0 +1,49 @@\n+/* Runtime architecture check for libmvec benchtests.  RISC-V version.\n+   Copyright (C) 2026 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library; if not, see\n+   <https://www.gnu.org/licenses/>.  */\n+\n+#include <stdbool.h>\n+#include <stdio.h>\n+#include <stdlib.h>\n+#include <sys/hwprobe.h>\n+\n+#define INIT_ARCH()                                                           \\\n+  do                                                                          \\\n+  {                                                                           \\\n+    if (!supported ())                                                        \\\n+      return 77;                                                              \\\n+  }                                                                           \\\n+  while (0)\n+\n+static bool\n+supported (void)\n+{\n+  struct riscv_hwprobe pair = { .key = RISCV_HWPROBE_KEY_IMA_EXT_0 };\n+  if (__riscv_hwprobe (&pair, 1, 0, NULL, 0) != 0)\n+  {\n+    printf (\"__riscv_hwprobe failed.\\n\");\n+    return false;\n+  }\n+\n+  if ((pair.value & RISCV_HWPROBE_IMA_V) == 0)\n+  {\n+    printf (\"RVV not supported.\\n\");\n+    return false;\n+  }\n+\n+  return true;\n+}\ndiff --git a/sysdeps/riscv/rvd/scripts/bench_libmvec_rvv.py b/sysdeps/riscv/rvd/scripts/bench_libmvec_rvv.py\nnew file mode 100644\nindex 0000000000..45b2f70a52\n--- /dev/null\n+++ b/sysdeps/riscv/rvd/scripts/bench_libmvec_rvv.py\n@@ -0,0 +1,293 @@\n+#!/usr/bin/python3\n+# Copyright (C) 2026 Free Software Foundation, Inc.\n+# This file is part of the GNU C Library.\n+#\n+# The GNU C Library is free software; you can redistribute it and/or\n+# modify it under the terms of the GNU Lesser General Public\n+# License as published by the Free Software Foundation; either\n+# version 2.1 of the License, or (at your option) any later version.\n+#\n+# The GNU C Library is distributed in the hope that it will be useful,\n+# but WITHOUT ANY WARRANTY; without even the implied warranty of\n+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+# Lesser General Public License for more details.\n+#\n+# You should have received a copy of the GNU Lesser General Public\n+# License along with the GNU C Library; if not, see\n+# <https://www.gnu.org/licenses/>.\n+\n+\"\"\"Generate RVV libmvec bench source that exercises all exported variants.\"\"\"\n+\n+import re\n+import sys\n+from pathlib import Path\n+from typing import Dict, Iterable, Iterator, List, Tuple, Union\n+\n+TEMPLATE = r\"\"\"\n+#include <math.h>\n+#include <riscv_vector.h>\n+\n+#pragma GCC diagnostic ignored \"-Wmissing-prototypes\"\n+\n+struct args_1\n+{{\n+  {stype} arg0[{nelems}];\n+}};\n+\n+struct variant\n+{{\n+  const char *name;\n+  size_t stride;\n+  double (*call) (const struct args_1 *, size_t idx);\n+  const struct args_1 *in;\n+}};\n+\n+static const struct args_1 in0 = {{\n+{in_data}\n+}};\n+\n+{protos}\n+\n+{callers}\n+\n+static const struct variant variants[] = {{\n+{variant_table}\n+}};\n+\n+#define NUM_VARIANTS (sizeof (variants) / sizeof (variants[0]))\n+#define NUM_SAMPLES(i) ({nelems} / variants[i].stride)\n+#define VARIANT(i) (variants[i].name)\n+#define STRIDE (variants[v].stride)\n+\n+static double volatile ret;\n+\n+#define BENCH_FUNC(i, j) ({{ ret = variants[i].call (variants[i].in, (j) * variants[i].stride); }})\n+#define FUNCNAME \"{func}\"\n+\n+#include <bench-libmvec-skeleton.c>\n+\"\"\"\n+\n+\n+def _parse_variants_macro(lines: List[str], macro: str) -> List[Tuple[int, int]]:\n+    variants: List[Tuple[int, int]] = []\n+    in_macro = False\n+    for line in lines:\n+        if line.startswith(f\"#define {macro}\"):\n+            in_macro = True\n+        if not in_macro:\n+            continue\n+        for lmul, simdlen in re.findall(r\"X\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)\", line):\n+            variants.append((int(lmul), int(simdlen)))\n+        if in_macro and not line.rstrip().endswith(\"\\\\\"):\n+            in_macro = False\n+            if variants:\n+                break\n+    if not variants:\n+        raise SystemExit(f\"failed to parse {macro} from v_math_variants.h\")\n+    return variants\n+\n+\n+def _load_variants_from_header() -> Dict[str, List[Tuple[int, int]]]:\n+    header = Path(__file__).resolve().parent.parent / \"v_math_variants.h\"\n+    try:\n+        lines = header.read_text(encoding=\"utf-8\").splitlines()\n+    except OSError as exc:\n+        raise SystemExit(f\"cannot read {header}: {exc}\") from exc\n+\n+    return {\n+        \"double\": _parse_variants_macro(lines, \"RVV_LIBMVEC_VARIANTS_F64\"),\n+        \"float\": _parse_variants_macro(lines, \"RVV_LIBMVEC_VARIANTS_F32\"),\n+    }\n+\n+\n+VARIANTS = _load_variants_from_header()\n+\n+PRECISION_TABLE = {\n+    \"double\": {\n+        \"stype\": \"double\",\n+        \"elem_width\": 64,\n+        \"variants\": VARIANTS[\"double\"],\n+    },\n+    \"float\": {\n+        \"stype\": \"float\",\n+        \"elem_width\": 32,\n+        \"variants\": VARIANTS[\"float\"],\n+    },\n+}\n+\n+Variant = Dict[str, Union[str, int]]\n+\n+\n+def _make_vector_variants(\n+    func: str, elem_width: int, variants: Iterable[Tuple[int, int]]\n+) -> Iterator[Variant]:\n+    \"\"\"Yield vector variant metadata for the given function.\"\"\"\n+    vtype_prefix = f\"vfloat{elem_width}\"\n+    setvl_prefix = f\"e{elem_width}\"\n+    for lmul, simdlen in variants:\n+        m_suffix = f\"m{lmul}\"\n+        vtype = f\"{vtype_prefix}{m_suffix}_t\"\n+        setvl_suffix = f\"{setvl_prefix}{m_suffix}\"\n+        asm_sym = f\"_ZGVr{lmul}N{simdlen}v_{func}\"\n+        yield {\n+            \"name\": asm_sym,\n+            \"vtype\": vtype,\n+            \"setvl_suffix\": setvl_suffix,\n+            \"simdlen\": simdlen,\n+            \"asm_sym\": asm_sym,\n+            \"kind\": \"vector\",\n+        }\n+\n+\n+def _parse_bench_name(name: str) -> Tuple[str, str]:\n+    \"\"\"Parse a bench target name into (precision, function).\"\"\"\n+    # Accept names like \"double-log\" (bench list) or \"bench-double-log\"\n+    # (target name in benchtests).\n+    if name.startswith(\"bench-\"):\n+        name = name[len(\"bench-\"):]\n+\n+    parts = name.split(\"-\")\n+    if len(parts) < 2:\n+        raise SystemExit(f\"unexpected name format: {name}\")\n+\n+    prec = parts[0]\n+    func = \"_\".join(parts[1:])\n+    return prec, func\n+\n+\n+def _load_input_data(func: str) -> Tuple[str, int]:\n+    \"\"\"Load inputs for FUNC, returning the initializer and element count.\"\"\"\n+    input_filename = f\"{func}-inputs\"\n+    with open(\n+        f\"../benchtests/libmvec/{input_filename}\",\n+        encoding=\"utf-8\",\n+    ) as f:\n+        input_file = f.readlines()\n+\n+    arity_line = [l for l in input_file if l.startswith(\"## args: \")]\n+    if not arity_line:\n+        raise SystemExit(\"missing arity line in input file\")\n+\n+    in_vals = (l.strip() for l in input_file if l and not l.startswith(\"#\"))\n+    in_vals = (l.split(\", \") for l in in_vals)\n+    in_vals = list(zip(*in_vals))\n+    in_data = \",\\n\".join(\n+        \"{\" + (\", \".join(val for val in col) + \"}\") for col in in_vals\n+    )\n+    return in_data, len(in_vals[0])\n+\n+\n+def _vector_variant_snippets(\n+    idx: int,\n+    variant: Variant,\n+) -> Tuple[str, str, str]:\n+    \"\"\"Build prototype, caller, and table entry for a vector variant.\"\"\"\n+    vtype = variant[\"vtype\"]\n+    setvl_suffix = variant[\"setvl_suffix\"]\n+    simdlen = variant[\"simdlen\"]\n+    asm_sym = variant[\"asm_sym\"]\n+    name_sym = variant[\"name\"]\n+\n+    if \"float64\" in vtype:\n+        elem_width = \"64\"\n+        elem_type = \"f64\"\n+    elif \"float32\" in vtype:\n+        elem_width = \"32\"\n+        elem_type = \"f32\"\n+    else:\n+        raise SystemExit(f\"unsupported vtype: {vtype}\")\n+\n+    m_suffix = vtype.replace(f\"vfloat{elem_width}\", \"\").replace(\"_t\", \"\")\n+\n+    proto = (\n+        f\"extern {vtype} {name_sym}({vtype}) __asm__(\\\"{asm_sym}\\\");\"\n+    )\n+    caller = (\n+        f\"static double\\n\"\n+        f\"call_{idx} (const struct args_1 *in, size_t idx)\\n\"\n+        f\"{{\\n\"\n+        f\"  size_t vl = __riscv_vsetvl_{setvl_suffix} ({simdlen});\\n\"\n+        f\"  {vtype} x = \"\n+        f\"__riscv_vle{elem_width}_v_{elem_type}{m_suffix} \"\n+        f\"(&in->arg0[idx], vl);\\n\"\n+        f\"  {vtype} r = {name_sym} (x);\\n\"\n+        f\"  return __riscv_vfmv_f_s_{elem_type}{m_suffix}_{elem_type} \"\n+        f\"(r);\\n\"\n+        f\"}}\\n\"\n+    )\n+    entry = f'  {{\"{asm_sym}\", {simdlen}, call_{idx}, &in0}}'\n+    return proto, caller, entry\n+\n+\n+def _build_variants(\n+    func: str,\n+    elem_width: int,\n+    variants: Iterable[Tuple[int, int]],\n+) -> Tuple[List[str], List[str], List[str]]:\n+    \"\"\"Build prototypes, callers, and table entries for all variants.\"\"\"\n+    protos: List[str] = []\n+    callers: List[str] = []\n+    variant_entries: List[str] = []\n+\n+    variants_list = list(_make_vector_variants(func, elem_width, variants))\n+    variants_list.append(\n+        {\n+            \"name\": \"scalar\",\n+            \"asm_sym\": func,\n+            \"simdlen\": 1,\n+            \"kind\": \"scalar\",\n+        }\n+    )\n+\n+    for idx, variant in enumerate(variants_list):\n+        if variant[\"kind\"] == \"scalar\":\n+            callers.append(\n+                f\"static double\\n\"\n+                f\"call_{idx} (const struct args_1 *in, size_t idx)\\n\"\n+                f\"{{\\n\"\n+                f\"  return {func} (in->arg0[idx]);\\n\"\n+                f\"}}\\n\"\n+            )\n+            variant_entries.append(\n+                f'  {{\"{variant[\"asm_sym\"]}\", 1, call_{idx}, &in0}}'\n+            )\n+            continue\n+\n+        proto, caller, entry = _vector_variant_snippets(idx, variant)\n+        protos.append(proto)\n+        callers.append(caller)\n+        variant_entries.append(entry)\n+\n+    return protos, callers, variant_entries\n+\n+def main(name: str):\n+    prec, func = _parse_bench_name(name)\n+\n+    config = PRECISION_TABLE.get(prec)\n+    if not config:\n+        raise SystemExit(f\"unsupported precision: {prec}\")\n+\n+    stype = config[\"stype\"]\n+    elem_width = config[\"elem_width\"]\n+    in_data, nelems = _load_input_data(func)\n+    protos, callers, variant_entries = _build_variants(\n+        func,\n+        elem_width,\n+        config[\"variants\"],\n+    )\n+\n+    print(\n+        TEMPLATE.format(\n+            stype=stype,\n+            nelems=nelems,\n+            in_data=in_data,\n+            protos=\"\\n\".join(protos),\n+            callers=\"\\n\".join(callers),\n+            variant_table=\",\\n\".join(variant_entries),\n+            func=func,\n+        )\n+    )\n+\n+\n+if __name__ == \"__main__\":\n+    main(sys.argv[1])\n",
    "prefixes": [
        "RFC",
        "3/5"
    ]
}