Skip to content

Images not portable between znver3 and "AMD EPYC 7B13" (missing xsaves feature) #50102

Closed
@nrontsis

Description

@nrontsis

Description

Pre-compiled code in Julia cannot be used in machines of "similar" architecture. This includes both pre-compiled environments (via Pkg.instantiate() and system images/apps, both of which are demonstrated in minimal examples.

Related discourse threads [1], [2].

Relevance

This is important for production setups where docker images are built in a CI/CD pipeline (where often times there is limited control on the exact hardware), and then deployed in VMs of specified hardware to serve production.

Minimal, reproducible example

In this examples we demonstrate issues with building a docker image with precompiled Julia code from Intel Cascade Lake to an AMD EPYC 7B13. The precompiled code is generated both via Pkg.instantiate() and via PackageCompiler.jl, while taking care to specify the correct target cpu_type.

To reproduce, save the following as Dockerfile in a c2-standard-4 VM (Intel Cascade Lake) in google cloud (say, with google's container-optimised OS):

FROM julia:1.9.0
RUN julia -e 'download("https://github.com/JuliaLang/PackageCompiler.jl/archive/refs/tags/v2.1.7.tar.gz", "v2.1.7.tar.gz")'
RUN tar -xf v2.1.7.tar.gz && rm v2.1.7.tar.gz
RUN julia --project=/PackageCompiler.jl-2.1.7/examples/MyApp -e "using Pkg; Pkg.instantiate()"
CMD JULIA_DEBUG=loading julia --project=/PackageCompiler.jl-2.1.7/examples/MyApp -e "using MyApp"

and then build it and pack it by running:

docker build . --tag julia_precompile
docker save julia_precompile > julia_precompile.tar

Then, transfering the resulting docker image into a t2d-standard-4 (AMD EPYC 7B13) VM in google cloud run:

docker load < julia_precompile.tar
docker run julia_precompile

This shows cache invalidations happening, for example:

┌ Debug: Rejecting cache file /root/.julia/compiled/v1.9/MyApp/6XOLX_U0SK4.ji for MyApp [f943f3d7-887a-4ed5-b0c0-a1d6899aa8f5] since pkgimage can't be loaded on this target
└ @ Base loading.jl:2706

The same issue (incompatibility of targets), appears also when building a system image, even when explicitly specifying the target's CPU (i.e. znver3 for t2d-standard-4). In this case we get ERROR: Unable to find compatible target in system image. To reproduce this simply follow the previous steps, but use the following Dockerfile instead:

FROM julia:1.9.0
RUN julia -e 'download("https://github.com/JuliaLang/PackageCompiler.jl/archive/refs/tags/v2.1.7.tar.gz", "v2.1.7.tar.gz")'
RUN tar -xf v2.1.7.tar.gz && rm v2.1.7.tar.gz
RUN apt-get update && apt-get -f install && apt-get -y install gcc g++  # Required by PackageCompiler
RUN julia -e 'using Pkg; Pkg.develop(path="/PackageCompiler.jl-2.1.7")'
RUN julia --project=/PackageCompiler.jl-2.1.7/examples/MyApp -e 'using PackageCompiler; create_sysimage(["MyApp"]; sysimage_path="/sysimage.so", cpu_target="znver3")'
CMD JULIA_DEBUG=loading julia -J/sysimage.so --project=/PackageCompiler.jl-2.1.7/examples/MyApp -e "using MyApp"

Known, sub-optimal workarounds:

Passing cpu_target="generic" in PackageCompiler. create_sysimage avoids the errors/precompilations. However this can result in particularly suboptimal performance.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions