chengchingwen / DoubleArrayTries.jl

MIT License
4 stars 0 forks source link

Error building binary image, LLVM ERROR #3

Open MNLubov opened 1 year ago

MNLubov commented 1 year ago

@chengchingwen Hi Peter,

I am encountering an issue with the DoubleArrayTries.jl package when building my Julia project. Specifically, I am getting an LLVM error related to the X86ISD::PDEP instruction in the succinct.jl file.

Here are the specific error messages I am seeing:

LLVM ERROR: Cannot select: 0x858313e8: i64 = X86ISD::PDEP 0x55ee3040, 0x6dc59ef0, /root/.julia/packages/DoubleArrayTries/C3L0R/src/succinct.jl:24 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/succinct.jl:56 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/succinct.jl:22 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:59 ] ] ]
  0x55ee3040: i64 = X86ISD::CMOV 0x2efc8880, Constant:i64<0>, TargetConstant:i8<3>, 0x85942258:1, int.jl:496 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/succinct.jl:56 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/succinct.jl:22 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:59 ] ] ]
    0x2efc8880: i64 = shl nuw Constant:i64<1>, 0x85942668, int.jl:496 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/succinct.jl:56 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/succinct.jl:22 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:59 ] ] ]
      0x8593de80: i64 = Constant<1>
      0x85942668: i8 = truncate 0x85941b70, int.jl:496 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/succinct.jl:56 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/succinct.jl:22 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:59 ] ] ]
        0x85941b70: i64 = sub 0x8582d010, 0x79a262b8, int.jl:86 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:59 ]
          0x8582d010: i64,ch = CopyFromReg 0x4bfdf28, Register:i64 %16, int.jl:86 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:59 ]
            0x662076c0: i64 = Register %16
          0x79a262b8: i64,ch = CopyFromReg 0x4bfdf28, Register:i64 %10, int.jl:86 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:59 ]
            0x8593e3c8: i64 = Register %10
    0x6dc592c0: i64 = Constant<0>
    0x422037b8: i8 = TargetConstant<3>
    0x85942258: i64,i32 = X86ISD::SUB 0x85941b70, Constant:i64<64>, int.jl:496 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/succinct.jl:56 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/succinct.jl:22 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:59 ] ] ]
      0x85941b70: i64 = sub 0x8582d010, 0x79a262b8, int.jl:86 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:59 ]
        0x8582d010: i64,ch = CopyFromReg 0x4bfdf28, Register:i64 %16, int.jl:86 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:59 ]
          0x662076c0: i64 = Register %16
        0x79a262b8: i64,ch = CopyFromReg 0x4bfdf28, Register:i64 %10, int.jl:86 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:59 ]
          0x8593e3c8: i64 = Register %10
      0x3d5194d0: i64 = Constant<64>
  0x6dc59ef0: i64,ch = load<(load (s64) from %ir.82, !tbaa !26043, addrspace 13)> 0x69611ef0:1, 0x99e5f30, undef:i64, array.jl:924 @[ abstractarray.jl:1244 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:58 ] ]
    0x99e5f30: i64 = add 0x422032d8, 0x38383c88, array.jl:924 @[ abstractarray.jl:1244 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:58 ] ]
      0x422032d8: i64,ch = load<(dereferenceable load (s64) from %ir.80, !tbaa !26035, addrspace 11)> 0x69611ef0:1, 0x69611ef0, undef:i64, array.jl:924 @[ abstractarray.jl:1244 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:58 ] ]
        0x69611ef0: i64,ch = AtomicLoad<(dereferenceable load unordered (s64) from %ir.78, addrspace 11)> 0x31305d70:1, 0x31305d70, Base.jl:38 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:58 ]
          0x31305d70: i64,ch = AtomicLoad<(dereferenceable load unordered (s64) from %ir.76, addrspace 11)> 0x4bfdf28, 0x2786b408, Base.jl:38 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:58 ]
            0x2786b408: i64 = add nuw 0x22ab4450, Constant:i64<8>, Base.jl:38 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:58 ]
              0x22ab4450: i64,ch = CopyFromReg 0x4bfdf28, Register:i64 %15, Base.jl:38 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:58 ]
                0x56898f90: i64 = Register %15
              0x7ca823c8: i64 = Constant<8>
        0x65da2e50: i64 = undef
      0x38383c88: i64 = shl 0x8582a190, Constant:i8<3>, array.jl:924 @[ abstractarray.jl:1244 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:58 ] ]
        0x8582a190: i64 = or 0x65da2be0, 0x70155b90, int.jl:87 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:57 ]
          0x65da2be0: i64 = AssertZext 0x4848c7f0, ValueType:ch:i3, int.jl:87 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:57 ]
            0x4848c7f0: i64,ch = CopyFromReg 0x4bfdf28, Register:i64 %9, int.jl:87 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:57 ]
              0x85aeff50: i64 = Register %9
          0x70155b90: i64 = shl 0x85834130, Constant:i8<3>, int.jl:88 @[ int.jl:991 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:57 ] ]
            0x85834130: i64,ch = CopyFromReg 0x4bfdf28, Register:i64 %5, int.jl:88 @[ int.jl:991 @[ /root/.julia/packages/DoubleArrayTries/C3L0R/src/bvector.jl:57 ] ]
              0xb9a8338: i64 = Register %5
            0x71990e08: i8 = Constant<3>
        0x71990e08: i8 = Constant<3>
    0x65da2e50: i64 = undef
In function: julia_select_134049
signal (6): Aborted
in expression starting at none:0
gsignal at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
abort at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
_ZN4llvm18report_fatal_errorERKNS_5TwineEb at /usr/local/julia/bin/../lib/julia/libLLVM-13jl.so (unknown line)
_ZN4llvm18report_fatal_errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb at /usr/local/julia/bin/../lib/julia/libLLVM-13jl.so (unknown line)
_ZN4llvm16SelectionDAGISel15CannotYetSelectEPNS_6SDNodeE at /usr/local/julia/bin/../lib/julia/libLLVM-13jl.so (unknown line)
_ZN4llvm16SelectionDAGISel16SelectCodeCommonEPNS_6SDNodeEPKhj at /usr/local/julia/bin/../lib/julia/libLLVM-13jl.so (unknown line)
_ZN12_GLOBAL__N_115X86DAGToDAGISel6SelectEPN4llvm6SDNodeE at /usr/local/julia/bin/../lib/julia/libLLVM-13jl.so (unknown line)
_ZN4llvm16SelectionDAGISel22DoInstructionSelectionEv at /usr/local/julia/bin/../lib/julia/libLLVM-13jl.so (unknown line)
_ZN4llvm16SelectionDAGISel17CodeGenAndEmitDAGEv at /usr/local/julia/bin/../lib/julia/libLLVM-13jl.so (unknown line)
_ZN4llvm16SelectionDAGISel20SelectAllBasicBlocksERKNS_8FunctionE at /usr/local/julia/bin/../lib/julia/libLLVM-13jl.so (unknown line)
_ZN4llvm16SelectionDAGISel20runOnMachineFunctionERNS_15MachineFunctionE.part.899 at /usr/local/julia/bin/../lib/julia/libLLVM-13jl.so (unknown line)
_ZN12_GLOBAL__N_115X86DAGToDAGISel20runOnMachineFunctionERN4llvm15MachineFunctionE at /usr/local/julia/bin/../lib/julia/libLLVM-13jl.so (unknown line)
_ZN4llvm19MachineFunctionPass13runOnFunctionERNS_8FunctionE at /usr/local/julia/bin/../lib/julia/libLLVM-13jl.so (unknown line)
_ZN4llvm13FPPassManager13runOnFunctionERNS_8FunctionE at /usr/local/julia/bin/../lib/julia/libLLVM-13jl.so (unknown line)
_ZN4llvm13FPPassManager11runOnModuleERNS_6ModuleE at /usr/local/julia/bin/../lib/julia/libLLVM-13jl.so (unknown line)
_ZN4llvm6legacy15PassManagerImpl3runERNS_6ModuleE at /usr/local/julia/bin/../lib/julia/libLLVM-13jl.so (unknown line)
operator() at /cache/build/default-amdci4-2/julialang/julia-release-1-dot-8/src/aotcompile.cpp:580 [inlined]
jl_dump_native_impl at /cache/build/default-amdci4-2/julialang/julia-release-1-dot-8/src/aotcompile.cpp:592
jl_write_compiler_output at /cache/build/default-amdci4-2/julialang/julia-release-1-dot-8/src/precompile.c:94
ijl_atexit_hook at /cache/build/default-amdci4-2/julialang/julia-release-1-dot-8/src/init.c:207
jl_repl_entrypoint at /cache/build/default-amdci4-2/julialang/julia-release-1-dot-8/src/jlapi.c:720
main at /cache/build/default-amdci4-2/julialang/julia-release-1-dot-8/cli/loader_exe.c:59
__libc_start_main at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x401098)
Allocations: 407042431 (Pool: 406866746; Big: 175685); GC: 137

Do you have any suggestions for how I can resolve this issue or any further troubleshooting steps I can try? I am happy to provide additional information or debug the issue further if needed.

Thank you for your help.

Sincerely, Maxim

chengchingwen commented 1 year ago

Hi Maxim,

I'm not sure why the error happened. It seems that LLVM does not know how to handle the pdep instruction while the cpu seems to support it. Does DoubleArrayTries.jl runs without error without PackageCompiler.jl? If it's a PackageCompiler-specific error, we should also open an issue there. I'll also see if there are any workaround I can do here.

MNLubov commented 1 year ago

Hi Peter,

Thank you for your response to my previous message. To provide further context, I have been experiencing issues while trying to build a binary image on AWS. I can confirm that on the local machine, the binary image is built without any issues. DoubleArrayTries.jl runs without error without PackageCompiler.jl.

chengchingwen commented 1 year ago

If I understand correctly, the error only happened on AWS with PackageCompiler.jl, but on local everything is fine? If so, could you check if the julia/LLVM version on AWS and your local machine are the same? Also, I would like to know if adding try block around those lines or forcing has_bmi2 return false avoiding the error. If these can be done, we can set some extra check or even a preference to turn on/off the pdep implementation.

MNLubov commented 1 year ago

After conducting experiments, I discovered that the error is quite unusual. I successfully built a binary image on AWS for a project that only has DoubleArrayTries, Transformers.jl, TextEncodeBase.jl as dependencies and nothing else. However, when attempting to build a binary image for the original project, it fails.

MNLubov commented 1 year ago

@chengchingwen

After conducting some experiments, I found that disabling the use of LLVM for pdep leads to a successful build of the binary image. Additionally, I discovered that a try-catch condition for calling pdep via LLVM results in the same error that I described in the issue. julia/LLVM version on AWS is 11.

chengchingwen commented 1 year ago

Can you share a minimal environment setting that could reproduce the error?

I found that disabling the use of LLVM for pdep leads to a successful build of the binary image

Did you do this by commenting out pdep implementation with llvmcall or you force the has_bmi2 return false? If it only works with commenting out pdep with LLVM, then it means we probably couldn't do anything on our side and we should report this error to PackageCompiler.jl

MNLubov commented 1 year ago

Thellvm error was connected to parameter cpu_target of the create_sysimage function:

PackageCompiler.create_sysimage(
    project_name,
    cpu_target="generic;sandybridge,-xsaveopt,clone_all;haswell,-rdrnd,base(1)",
    sysimage_path = joinpath(sysimage_dir, "image.so"),
    precompile_execution_file = "test/runtests.jl",
)

Removing cpu_target kwarg led to successful binary image build. As for cpu_target value, it's standard value for the x86 architecture, see here https://github.com/JuliaLang/PackageCompiler.jl/blob/df3543443b8b5740150e28a5638f7c635c2c61eb/src/PackageCompiler.jl#L33

Can you share a minimal environment setting that could reproduce the error?

project is build in Docker on AWS t3 instance using CentOS 7.9.2009 x86_64

Did you do this by commenting out pdep implementation with llvmcall or you force the has_bmi2 return false?

It worked either by setting has_bmi2 to false or by completely commenting out llvm implementation of pdep. Adding try-catch around llvm implementation of pdep led to the error.

So, summarizing all of the above, I suppose, it's PackageCompiler issue.

rssdev10 commented 1 year ago

Hello, looks like we have some idea what is going on.

The concern is about LLVM and a minimal processor family provided by the argument cpu_target="generic;sandybridge,-xsaveopt,clone_all;haswell,-rdrnd,base(1)". If we have a case of running LLVM with sandybridge target, definitely bmi2 is not supported. Right now we have a build agent VM with Skylake family and Intel(R) Xeon(R) Platinum 8259CL CPU. If we do not specify cpu_target, the PackageCompiler works without issues.

In the https://docs.julialang.org/en/v1/devdocs/sysimg/#Specifying-multiple-system-image-targets the only recommendation about cpu_target is present. Unfortunately even https://github.com/JuliaLang/julia/blob/0f5f62cf5a31b4a973ab0fae70988e35e2ea8da7/src/processor_x86.cpp#L196 doesn't answer how to specify haswell or broadwell as the minimal and the only required CPU family.

@KristofferC we need your help.

We cannot avoid use of cpu_target - we are using Docker images created inside an AWS VM with further deployment into an AWS cluster. Due to the use of virtual machines, we cannot guarantee a certain generation of physical CPUs. Sometimes, when we are building a Docker image, the build agent VM has a newer processor family than a Kubernetes cluster. After that, the error "unsupported processor type" appeared on deploy stage. When we have cpu_target hard restricted to the processor family, that is never happening.

rssdev10 commented 1 year ago

https://github.com/chengchingwen/DoubleArrayTries.jl/blob/main/src/succinct.jl#L21

@static if has_bmi2()
    select_in_word(x, k) = pdep_select_in_word(x, k)
    pdep(x::UInt32, y::UInt32) = ccall("llvm.x86.bmi.pdep.32", llvmcall, UInt32, (UInt32, UInt32), x, y)
    pdep(x::UInt64, y::UInt64) = ccall("llvm.x86.bmi.pdep.64", llvmcall, UInt64, (UInt64, UInt64), x, y)
else
    select_in_word(x, k) = tabled_select_in_word(x, k)
    pdep(x::T, y::T) where {T <: Union{UInt32, UInt64}} = _pdep(x, y)
end
chengchingwen commented 1 year ago

@MNLubov @rssdev10

Could you try using this branch and call DoubleArrayTries.set_native_pdep_support(false) to disable the pdep implementation with llvmcall and see if this work for you?

MNLubov commented 1 year ago

@chengchingwen Disabling llvm implementation of the pdep with DoubleArrayTries.set_native_pdep_support(false) works. Thank you!