Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 52 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,65 @@ COPY funannotate2 ./funannotate2
# Install from the lockfile; no-op if the lockfile already matches.
RUN pixi install --locked

# Rebuild pytantan from source with AVX2 disabled (SSE4-only baseline).
# The PyPI/bioconda wheel ships with AVX2 SIMD which SIGILLs on CPUs that lack
# it — notably Rosetta 2 on Apple Silicon — and AVX2 gives no meaningful win
# for this pipeline. `pip` uses build isolation, so scikit-build-core/cython/
# scoring-matrices are pulled in transparently; we only need the C/C++ toolchain.
# Rebuild pytantan from source with all SIMD backends disabled.
#
# Background: pytantan's wheels ship with AVX2 enabled, and prior to v0.1.4
# the generic path was also polluted with AVX2 flags via `add_compile_options`
# in the project-level CMakeLists.txt. Either way, on x86_64 CPUs without AVX2
# (notably Rosetta 2 on Apple Silicon) any code path that executes an AVX2
# instruction raises SIGILL. The runtime-dispatch added in v0.1.4 does not
# help us here because we want a build that is portable to *any* x86_64.
#
# pytantan's CMakeLists.txt uses FindAVX2/FindSSE4/FindNEON which auto-detect
# on the build host (GitHub Actions runners have AVX2), so we have to force
# the HAVE_* flags OFF. Pre-defining them in FindAVX2.cmake's `if((DEFINED ...))`
# guard short-circuits detection entirely.
#
# We pass these via pip's `--config-settings=cmake.define.*` rather than
# CMAKE_ARGS/SKBUILD_CMAKE_ARGS env vars, since that route goes directly into
# scikit-build-core's parser and is not subject to env-var filtering.
ARG PYTANTAN_VERSION
RUN apt-get update && \
apt-get install -y --no-install-recommends \
git build-essential cmake zlib1g-dev ca-certificates && \
git build-essential cmake zlib1g-dev binutils ca-certificates && \
rm -rf /var/lib/apt/lists/*
RUN CMAKE_ARGS="-DHAVE_AVX2=OFF -DAVX2_C_FLAGS= -DHAVE_SSE4=OFF -DSSE4_C_FLAGS= -DHAVE_NEON=OFF -DNEON_C_FLAGS=" \
/app/.pixi/envs/default/bin/pip install --no-deps --force-reinstall \
RUN /app/.pixi/envs/default/bin/pip install \
--no-deps --no-cache-dir --force-reinstall -v \
--config-settings=cmake.define.HAVE_AVX2=OFF \
--config-settings=cmake.define.HAVE_SSE4=OFF \
--config-settings=cmake.define.HAVE_NEON=OFF \
--config-settings=cmake.define.AVX2_C_FLAGS= \
--config-settings=cmake.define.SSE4_C_FLAGS= \
--config-settings=cmake.define.NEON_C_FLAGS= \
"pytantan @ git+https://github.com/althonos/pytantan.git@v${PYTANTAN_VERSION}" && \
rm -rf /root/.cache/pip

# Verify the rebuild was effective: only `generic` should be present in the
# platform/ directory and neither lib.*.so nor generic.*.so should contain
# any AVX/AVX2 instructions (no `ymm`/`zmm` register references, no `vex`-
# encoded vector ops). Fail the build loudly otherwise so we never ship an
# image that SIGILLs at import time.
RUN set -eux; \
PY=/app/.pixi/envs/default/bin/python; \
PT_DIR=$("$PY" -c 'import pytantan, os; print(os.path.dirname(pytantan.__file__))'); \
echo "pytantan installed at: $PT_DIR"; \
ls -la "$PT_DIR/platform/"; \
SIMD_MODS=$(ls "$PT_DIR/platform/" | grep -E '^(avx2|sse4|neon)\.' || true); \
if [ -n "$SIMD_MODS" ]; then \
echo "ERROR: SIMD platform modules were built despite HAVE_*=OFF: $SIMD_MODS"; \
exit 1; \
fi; \
BAD=""; \
for so in $(find "$PT_DIR" -maxdepth 2 -name '*.so'); do \
if objdump -d -M intel --no-show-raw-insn "$so" 2>/dev/null \
| grep -Eq '\b(ymm[0-9]+|zmm[0-9]+|vpbroadcast|vextracti128|vinserti128)\b'; then \
echo "ERROR: $so contains AVX/AVX2 instructions"; \
BAD="${BAD} ${so}"; \
fi; \
done; \
if [ -n "$BAD" ]; then exit 1; fi; \
"$PY" -c "import pytantan; from pytantan import Alphabet, RepeatFinder, default_scoring_matrix; print('pytantan smoke test OK', pytantan.__version__)"

# Pre-generate an activation script so the final image doesn't need pixi.
RUN mkdir -p /app/bin && \
{ echo '#!/bin/bash'; \
Expand Down
Loading