# Copyright 1999-2026 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

EAPI=8

PYTHON_COMPAT=( python3_{12..14} )

inherit python-single-r1

# Upstream has no releases or tags; this is the tip of main on 2026-08-27.
MY_COMMIT="d1d5232d0b82871bf5265e990fa2d26cdad22327"

DESCRIPTION="Convert GGUF fine-tunes to FastFlowLM's Q4NX format for the Ryzen AI NPU"
HOMEPAGE="https://github.com/ROCm/FLM_Q4NX_Converter"
SRC_URI="
	https://github.com/ROCm/FLM_Q4NX_Converter/archive/${MY_COMMIT}.tar.gz
		-> ${P}.tar.gz
"
S="${WORKDIR}/FLM_Q4NX_Converter-${MY_COMMIT}"

LICENSE="Apache-2.0"
SLOT="0"
KEYWORDS="~amd64"
REQUIRED_USE="${PYTHON_REQUIRED_USE}"

# Taken from the imports. Upstream's setup_venv.sh installs more (transformers,
# amd-quark, accelerate, matplotlib), none of which the code uses.
# verified 2026-10-11
RDEPEND="
	${PYTHON_DEPS}
	sci-ml/pytorch[${PYTHON_SINGLE_USEDEP}]
	$(python_gen_cond_dep '
		dev-python/einops[${PYTHON_USEDEP}]
		dev-python/gguf[${PYTHON_USEDEP}]
		dev-python/mpmath[${PYTHON_USEDEP}]
		dev-python/numpy[${PYTHON_USEDEP}]
		sci-ml/safetensors[${PYTHON_USEDEP}]
	')
"
# python_optimize runs the interpreter at build time.
BDEPEND="${PYTHON_DEPS}"

PATCHES=(
	# Find the layout configs from any working directory.
	"${FILESDIR}/${P}-configs-path.patch"
	# Dense Qwen3.5 output lacks tensors FastFlowLM requires (issue #22).
	# https://github.com/ROCm/FLM_Q4NX_Converter/pull/23, open 2026-10-11
	"${FILESDIR}/${P}-qwen35-prefill-copies.patch"
	# Qwen3.8-27B, which FastFlowLM ships from 1.0.7 on and upstream cannot
	# convert: first the dense path reads its layout from the GGUF, then the
	# model is added. Not upstream. verified 2026-10-11
	"${FILESDIR}/${P}-qwen35-value-heads.patch.xz"
	"${FILESDIR}/${P}-qwen38-27b.patch.xz"
	# gguf-py stores "Qwen3.8-27B-MyTune" as basename "Qwen3.8" and size label
	# "27B"; matched by basename alone, such a file is taken for plain Qwen3,
	# and a renamed fine-tune for nothing. Try basename-size first and
	# architecture-size last. Not upstream. verified 2026-10-11
	"${FILESDIR}/${P}-detect-size-label.patch"
)

src_prepare() {
	# eapply does not decompress: expand the .xz patches and repoint PATCHES.
	local i p
	for i in "${!PATCHES[@]}"; do
		p=${PATCHES[i]}
		[[ ${p} == *.xz ]] || continue
		PATCHES[i]="${T}/$(basename "${p}" .xz)"
		xz -dc "${p}" > "${PATCHES[i]}" || die
	done
	default
}

src_install() {
	# No pyproject.toml upstream, and convert.py is a top-level script that
	# q4nx imports back, so the tree is kept together outside site-packages.
	local dest="/usr/share/${PN}"
	insinto "${dest}"
	doins -r convert.py q4nx configs
	python_optimize "${ED}${dest}"

	newbin - flm-q4nx-convert <<-EOF
	#!/bin/sh
	exec "${PYTHON}" "${EPREFIX}${dest}/convert.py" "\$@"
	EOF

	# Header comparison against the base model's official weights.
	python_doscript "${FILESDIR}/flm-q4nx-check"

	dodoc README.md
}

pkg_postinst() {
	elog "flm-q4nx-convert repacks the weights of a GGUF file. It cannot build NPU"
	elog "kernels, so the source must be a fine-tune of a model FastFlowLM ships."
	elog "Compare the result with the base model's official file using"
	elog "flm-q4nx-check, then register it with flm-custom-sync from"
	elog "sci-ml/fastflowlm."
}