diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 00000000..dbad6f46 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,80 @@ +name: Create and publish a Docker image + +on: + push: + branches: + - "master" + release: + types: [published] + workflow_dispatch: + inputs: + tag: + required: true + type: string + latest: + default: false + type: boolean + + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Log in to the Container registry + uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Tag for workflow_dispatch + id: dispatch_tag + run: | + if [ x"$TAG" != x"" ];then + echo "::set-output name=tag::${FULL_TAG}" + fi + if [ x"$LATEST" = x"true" ]; then + echo "::set-output name=latest::${LATEST_TAG}" + fi + env: + FULL_TAG: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.event.inputs.tag }} + LATEST_TAG: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + TAG: ${{ github.event.inputs.tag }} + LATEST: ${{ github.event.inputs.latest }} + + - name: Build and push Docker image + uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + cache-from: type=gha + cache-to: type=gha,mode=max + tags: | + ${{ steps.meta.outputs.tags }} + ${{ steps.dispatch_tag.outputs.tag }} + ${{ steps.dispatch_tag.outputs.latest }} + labels: ${{ steps.meta.outputs.labels }} + diff --git a/Dockerfile b/Dockerfile index f5786999..b13d85e8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,41 +1,68 @@ -FROM debian:stable-slim as builder -RUN apt-get update && apt-get install -y \ - build-essential cmake xxd git zlib1g-dev libbz2-dev \ - && rm -rf /var/lib/apt/lists/* - -WORKDIR /opt/source -ADD . . +FROM --platform=$BUILDPLATFORM debian:stable-slim as builder +ARG TARGETARCH -WORKDIR /opt/source/build_sse2 -RUN cmake -DHAVE_MPI=0 -DHAVE_TESTS=0 -DHAVE_SSE2=1 -DCMAKE_BUILD_TYPE=Release .. -RUN make -j $(nproc --all) +RUN dpkg --add-architecture $TARGETARCH \ + && apt-get update \ + && apt-get install -y \ + build-essential cmake xxd git \ + zlib1g-dev libbz2-dev libatomic1 \ + crossbuild-essential-$TARGETARCH zlib1g-dev:$TARGETARCH libbz2-dev:$TARGETARCH \ + && rm -rf /var/lib/apt/lists/* -WORKDIR /opt/source/build_sse41 -RUN cmake -DHAVE_MPI=0 -DHAVE_TESTS=0 -DHAVE_SSE4_1=1 -DCMAKE_BUILD_TYPE=Release .. -RUN make -j $(nproc --all) +WORKDIR /opt/build +ADD . . -WORKDIR /opt/source/build_avx2 -RUN cmake -DHAVE_MPI=0 -DHAVE_TESTS=0 -DHAVE_AVX2=1 -DCMAKE_BUILD_TYPE=Release .. -RUN make -j $(nproc --all) +RUN if [ "$TARGETARCH" = "arm64" ]; then \ + mkdir -p build_$TARGETARCH/src; \ + cd /opt/build/build_$TARGETARCH; \ + CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ cmake -DHAVE_ARM8=1 -DHAVE_MPI=0 -DHAVE_TESTS=0 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=. ..; \ + make -j $(nproc --all); \ + mv src/plass /opt/build/plass_arch; \ + mv src/penguin /opt/build/penguin_arch; \ + touch /opt/build/plass_sse2 /opt/build/plass_sse41 /opt/build/plass_avx2; \ + touch /opt/build/penguin_sse2 /opt/build/penguin_sse41 /opt/build/penguin_avx2; \ + else \ + mkdir -p build_sse2/src && mkdir -p build_sse41/src && mkdir -p build_avx2/src; \ + cd /opt/build/build_sse2; \ + cmake -DHAVE_SSE2=1 -DHAVE_MPI=0 -DHAVE_TESTS=0 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=. ..; \ + make -j $(nproc --all); \ + mv src/plass /opt/build/plass_sse2; \ + mv src/penguin /opt/build/penguin_sse2; \ + cd /opt/build/build_sse41; \ + cmake -DHAVE_SSE4_1=1 -DHAVE_MPI=0 -DHAVE_TESTS=0 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=. ..; \ + make -j $(nproc --all); \ + mv src/plass /opt/build/plass_sse41; \ + mv src/penguin /opt/build/penguin_sse41; \ + cd /opt/build/build_avx2; \ + cmake -DHAVE_AVX2=1 -DHAVE_MPI=0 -DHAVE_TESTS=0 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=. ..; \ + make -j $(nproc --all); \ + mv src/plass /opt/build/plass_avx2; \ + mv src/penguin /opt/build/penguin_avx2; \ + touch /opt/build/plass_arch; \ + touch /opt/build/penguin_arch; \ + fi FROM debian:stable-slim -MAINTAINER Milot Mirdita +ARG TARGETARCH + RUN apt-get update && apt-get install -y \ gawk bash grep libstdc++6 libgomp1 libatomic1 zlib1g libbz2-1.0 wget tar \ - && rm -rf /var/lib/apt/lists/* + && rm -rf /var/lib/apt/lists/* -COPY --from=builder /opt/source/build_sse2/src/plass /usr/local/bin/plass_sse2 -COPY --from=builder /opt/source/build_sse41/src/plass /usr/local/bin/plass_sse41 -COPY --from=builder /opt/source/build_avx2/src/plass /usr/local/bin/plass_avx2 -RUN echo '#!/bin/sh\n\ -FLAGS="$(grep -m 1 "^flags" /proc/cpuinfo)"\n\ -case "${FLAGS}" in\n\ - *avx2*) exec /usr/local/bin/plass_avx2 "$@" ;;\n\ - *sse4_1*) exec /usr/local/bin/plass_sse41 "$@" ;;\n\ - *) exec /usr/local/bin/plass_sse2 "$@" ;;\n\ -esac' >> /usr/local/bin/plass -RUN chmod +x /usr/local/bin/plass +COPY --from=builder /opt/build/plass_arch /opt/build/plass_sse2 /opt/build/plass_sse41 /opt/build/plass_avx2 /usr/local/bin/ +COPY --from=builder /opt/build/penguin_arch /opt/build/penguin_sse2 /opt/build/penguin_sse41 /opt/build/penguin_avx2 /usr/local/bin/ -VOLUME ["/app"] -WORKDIR /app -ENTRYPOINT ["plass"] +RUN if [ "$TARGETARCH" != "arm64" ]; then \ + echo '#!/bin/sh\n\ + FLAGS="$(grep -m 1 "^flags" /proc/cpuinfo)"\n\ + case "${FLAGS}" in\n\ + *avx2*) exec /usr/local/bin/plass_avx2 "$@" ;;\n\ + *sse4_1*) exec /usr/local/bin/plass_sse41 "$@" ;;\n\ + *) exec /usr/local/bin/plass_sse2 "$@" ;;\n\ + esac' >> /usr/local/bin/plass; \ + chmod +x /usr/local/bin/plass; \ + sed 's/plass/penguin/g' /usr/local/bin/plass > /usr/local/bin/penguin; \ + chmod +x /usr/local/bin/penguin; \ + else \ + ln -s /usr/local/bin/plass_arch /usr/local/bin/plass; \ + fi