JuliaLinearAlgebra / Arpack.jl

Julia Wrappers for the arpack-ng Fortran library
https://arpack.julialinearalgebra.org/stable
MIT License
69 stars 29 forks source link

Installation error when Julia is built from source #5

Closed yurivish closed 5 years ago

yurivish commented 6 years ago

I tried installing Arpack on 0.7 beta and saw this error trying to run eigs:

julia> A = Diagonal(1:4);
WARNING: Base.Diagonal is deprecated: it has been moved to the standard library package `LinearAlgebra`.
Add `using LinearAlgebra` to your imports.
 in module Main

julia> λ, ϕ = eigs(A, nev = 2);
ERROR: error compiling saupd: could not load library ""
dlopen(.dylib, 1): image not found
Stacktrace:
 [1] aupd_wrapper(::Any, ::getfield(Arpack, Symbol("#matvecA!#24")){LinearAlgebra.Diagonal{Float64,Array{Float64,1}}}, ::getfield(Arpack, Symbol("##18#25")), ::getfield(Arpack, Symbol("##19#26")), ::Int64, ::Bool, ::Bool, ::String, ::Int64, ::Int64, ::String, ::Float64, ::Int64, ::Int64, ::Array{Float64,1}) at /Users/yurivish/.julia/packages/Arpack/Rkbg/src/libarpack.jl:42
 [2] #_eigs#17(::Int64, ::Int64, ::Symbol, ::Float64, ::Int64, ::Nothing, ::Array{Float64,1}, ::Bool, ::Any, ::Any, ::Any) at /Users/yurivish/.julia/packages/Arpack/Rkbg/src/Arpack.jl:176
 [3] (::getfield(Arpack, Symbol("#kw##eigs")))(::NamedTuple{(:nev,),Tuple{Int64}}, ::typeof(eigs), ::LinearAlgebra.Diagonal{Int64,UnitRange{Int64}}) at ./none:0
 [4] top-level scope at none:0

To see if this was solved on master, I tried installing it. But this happens when I try to develop Arpack#master:

Error: Error building `Arpack`:
│ [ Info: Downloading https://github.com/JuliaLinearAlgebra/ArpackBuilder/releases/download/v3.5.0-0.2.20/ArpackBuilder.x86_64-apple-darwin14.tar.gz to /Users/yurivish/.julia/dev/Arpack/deps/usr/downloads/ArpackBuilder.x86_64-apple-darwin14.tar.gz...
│ ┌ Warning: `wait(t::Task)` is deprecated, use `fetch(t)` instead.
│ │   caller = macro expansion at OutputCollector.jl:63 [inlined]
│ └ @ Core OutputCollector.jl:63
│ ┌ Warning: `wait(t::Task)` is deprecated, use `fetch(t)` instead.
│ │   caller = wait(::OutputCollector) at OutputCollector.jl:158
│ └ @ BinaryProvider OutputCollector.jl:158
│ ┌ Warning: `wait(t::Task)` is deprecated, use `fetch(t)` instead.
│ │   caller = wait(::OutputCollector) at OutputCollector.jl:159
│ └ @ BinaryProvider OutputCollector.jl:159
│ ┌ Warning: `wait(t::Task)` is deprecated, use `fetch(t)` instead.
│ │   caller = wait(::OutputCollector) at OutputCollector.jl:163
│ └ @ BinaryProvider OutputCollector.jl:163
│ ERROR: LoadError: LibraryProduct(nothing, ["libarpack"], :libarpack, "Prefix(/Users/yurivish/.julia/dev/Arpack/deps/usr)") is not satisfied, cannot generate deps.jl!
│ Stacktrace:
│  [1] error at ./error.jl:33 [inlined]
│  [2] #write_deps_file#134(::Bool, ::Function, ::String, ::Array{LibraryProduct,1}) at /Users/yurivish/.julia/packages/BinaryProvider/2Hlv/src/Products.jl:389
│  [3] write_deps_file(::String, ::Array{LibraryProduct,1}) at /Users/yurivish/.julia/packages/BinaryProvider/2Hlv/src/Products.jl:376
│  [4] top-level scope at none:0
│  [5] include at ./boot.jl:317 [inlined]
│  [6] include_relative(::Module, ::String) at ./loading.jl:1075
│  [7] include(::Module, ::String) at ./sysimg.jl:29
│  [8] include(::String) at ./client.jl:393
│  [9] top-level scope at none:0
│ in expression starting at /Users/yurivish/.julia/dev/Arpack/deps/build.jl:40
julia> versioninfo()
Julia Version 0.7.0-beta.0
Commit f41b1ecaec (2018-06-24 01:32 UTC)
Platform Info:
  OS: macOS (x86_64-apple-darwin16.7.0)
  CPU: Intel(R) Core(TM) i7-3615QM CPU @ 2.30GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.0 (ORCJIT, ivybridge)
Environment:
  JULIA_EDITOR = subl
andreasnoack commented 6 years ago

Might be dup of #3. Did you build from source? What do you get from otool -L usr/lib/libopenblas64_.dylib?

bicycle1885 commented 6 years ago

I encountered the same problem on macOS, 0.7.0-beta.0.

~/v/julia ((v0.7.0-beta)|…) $ otool -L usr/lib/libopenblas64_.dylib
usr/lib/libopenblas64_.dylib:
        @rpath/libopenblas64_.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/local/opt/gcc/lib/gcc/6/libgfortran.3.dylib (compatibility version 4.0.0, current version 4.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.60.2)
        /usr/local/opt/gcc/lib/gcc/6/libquadmath.0.dylib (compatibility version 1.0.0, current version 1.0.0)
        /usr/local/lib/gcc/6/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)

Do we need to wait for the official binaries of Julia 0.7.0-beta?

andreasnoack commented 6 years ago

Do we need to wait for the official binaries of Julia 0.7.0-beta?

Either that or build your OpenBLAS with GCC 7.

bicycle1885 commented 6 years ago

Thank you. I will try.

yurivish commented 6 years ago

@andreasnoack this was with a build from source. Thanks to the pointer to Viral's issue – I didn't see it since it was closed.

$ otool -L usr/lib/libopenblas64_.dylib
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/objdump: 'usr/lib/libopenblas64_.dylib': No such file or directory
andreasnoack commented 6 years ago

@yurivish You'll need to adjust the path to match the usr directory within your root Julia directory.

blakejohnson commented 6 years ago
$ otool -L usr/lib/libopenblas64_.dylib 
usr/lib/libopenblas64_.dylib:
    @rpath/libopenblas64_.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/local/opt/gcc/lib/gcc/7/libgfortran.4.dylib (compatibility version 5.0.0, current version 5.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.60.2)
    /usr/local/opt/gcc/lib/gcc/7/libquadmath.0.dylib (compatibility version 1.0.0, current version 1.0.0)
    /usr/local/lib/gcc/7/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
bicycle1885 commented 6 years ago

FYI, Julia 0.7-beta binary for macOS is now available (https://julialang.org/downloads/), which solves the problem.

andreasnoack commented 6 years ago

@blakejohnson Things are more wrong than first anticipated. So the system libgfortran is apparently not in the RPATH. I'm able to get it working with DYLD_LIBRARY_PATH=/usr/local/opt/gcc@7/lib/gcc/7 julia-dev which is, of course, not a real solution but it identifies the issue here. Will have to hear @staticfloat what a proper solution would look like.

RalphAS commented 6 years ago

Another possible workaround is to copy (or maybe hard link) libgfortran.so.4 from another Julia package (e.g. SpecialFunctions) into Arpack/XXXX/deps/usr/lib and then run pkg> build Arpack. This appears to be working for me, with Julia built from source on Linux.

maleadt commented 6 years ago

Just for completeness (coming from #9), this obviously also occurs on Linux when not building with GCC 7. Doesn't seem easy to work around, with eg. Arch Linux' gcc7 package not providing libgfortran.4, and Debian Stable using GCC 6 / libgfortran.3 with no means to (safely) install GCC 7.

simonbyrne commented 6 years ago

Until we fix this, could we throw a more informative error?

juliohm commented 6 years ago

The new tag of Arpack.jl now fails to compile on Julia binaries as well:

julia> using Arpack
[ Info: Precompiling module Arpack
ERROR: LoadError: No deps.jl file could be found. Please try running Pkg.build("Arpack").
Currently, the build command might fail when Julia has been built from source
and the recommendation is to use the official binaries from julialang.org.
For more info see https://github.com/JuliaLinearAlgebra/Arpack.jl/issues/5.

Julia version:

julia> versioninfo()
Julia Version 0.7.0-beta.182
Commit feaee9ebbc (2018-07-06 12:39 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.0 (ORCJIT, skylake)
Environment:
  JULIA_NUM_THREADS = 2
staticfloat commented 6 years ago

Did you actually run Pkg.build("Arpack")?

juliohm commented 6 years ago

I did, there is no error message, and the build.log is empty.

andreasnoack commented 6 years ago

It the test for the deps.jl file that is wrong. See https://github.com/JuliaLinearAlgebra/Arpack.jl/pull/22

sbromberger commented 6 years ago

This may be stating the obvious, but the problem still exists with 1.4 on a Julia built from source (which is the only way I can do it right now). Is there a workaround for those of us in this unfortunate position?

staticfloat commented 6 years ago

You can try downloading the official Julia binaries, extracting the libgfortran.so.4 file, and putting it into your from-source Julia installation's lib directory. That should allow your arpack to find libgfortran.so.4 and get loaded; however all bets are off as to whether that will cause Julia to freak out or not due to there being multiple versions of certain symbols available within the process space. You'll just have to try it and find out until we have a better solution available.

sbromberger commented 6 years ago

Thank you for the followup.

You can try downloading the official Julia binaries, extracting the libgfortran.so.4 file, and putting it into your from-source Julia installation's lib directory.

Unfortunately I won't be able to do that due to environmental restrictions here.

I know people are working on this, but to set expectations, is there an approximate timeframe? The lack of a working eigs is causing failures in LightGraphs; if a fix is expected to take longer than a few more days, then it might make sense just to pull all uses of eigs out of the package in order to make progress in reviewing current PRs.

staticfloat commented 6 years ago

if a fix is expected to take longer than a few more days

It will definitely be more than a few days; it's very complex to create infrastructure to support every reasonable toolchain (rather than a single reasonable toolchain, which is what we do right now); think single-digit months rather than single-digit days.

If it is the official Julia distribution itself that is the problem, you don't have to get libgfortran.so.4 from that source. You could get it from your distribution's GCC channel, you could grab it from any other piece of software on your computer, or even download the GCC 7 source and compile it yourself to get libgfortran and copy that somewhere it can be used.

If none of those solutions will work in your environment, then I'm afraid you're just going to have to wait.

sbromberger commented 6 years ago

Thanks. That's disappointing but I'm not in a position to help other than state my use case.

it's very complex to create infrastructure to support every reasonable toolchain

I'm curious about this. I wouldn't think that downloading and building the Julia source code would be so far outside the norm that it's not part of the testing strategy. Are people doing something else? Because the upshot is that over 600 packages are using Arpack, and none of them will work on source-built installations.

(This is not really so much a complaint as a question of whether our environment is really that strange.)

chriselrod commented 6 years ago

Would it be feasible to support building Arpack from source as a generic fallback instead of downloading the binary?

staticfloat commented 6 years ago

I wouldn't think that downloading and building the Julia source code would be so far outside the norm that it's not part of the testing strategy.

Building Julia from source works just fine with these binaries, as long as you use a compiler version that is compatible with the binaries (e.g. GCC 7.x) or alternatively, are able to install the compiler support libraries (libgfortran, libgcc_s, etc...). Combine that with supporting the official Julia binaries, and we've covered a very large portion of the ecosystem. I don't have the hard numbers to tell you exactly how much of the ecosystem that covers, but anecdotally, I would guesstimate that the great majority of users use the precompiled binaries, and of those that don't, a good chunk are able to coerce their build system to be GCC 7-compatible.

This transition pain is considered worthwhile because the alternatives (using distro-provided package managers, building from source on user's machines, etc...) run into new issues constantly. It is a very large, ongoing, maintenance burden for us to constantly fix build scripts, debug user's broken toolchains, etc... It is much simpler for everyone if the binaries are built once, and simply distributed to users in the format they were going to compile down to anyway.

This of course raises the compiler compatibility issues, but I will also point out those compiler compatibility issues already existed in the "bad old days"; if you were using the official Julia binaries (as most users are) and you have to compile Arpack, you can run into similar problems. Not the exact same ones (where libraries are missing) but more subtle ones, where symbol duplication means that when Arpack tries to call a function whose functionality has changed between two compiler ABI versions, it just functions incorrectly/crashes.

Would it be feasible to support building Arpack from source as a generic fallback instead of downloading the binary?

Ah, that gives me another idea; Seth, for your particular use case, I'm sure you can manually compile Arpack and just insert it directly into Arpack.jl's deps/usr folder. Do something like this (yes, there's an obscenely long line in these instructions, oh well). Also I suggest doing a pkg> dev Arpack first, so that we can iterate on Arpack itself.

# First, clone arpack-ng and checkout a known good gitsha
git clone https://github.com/opencollab/arpack-ng.git arpack-ng
cd arpack-ng
git checkout b095052372aa95d4281a645ee1e367c28255c947

# We'll build inside the `build` directory
mkdir build; cd build/

# We're going to install to ~/.julia/dev/Arpack/deps/usr.  Change this if you have a different target installation location
prefix=$(echo ~/.julia/dev/Arpack/deps/usr)

# We need to link against OpenBLAS; get that from Julia: (Note; this only works for Julia 0.7)
openblas_dir=$(julia -e 'using Libdl; println(abspath(dirname(Libdl.dlpath(Libdl.dlopen(Base.libblas_name)))))') 

# Use cmake to configure, with a huge number of symbol renames for the fortran code.
cmake .. -DCMAKE_INSTALL_PREFIX=$prefix -DBUILD_SHARED_LIBS=ON -DBLAS_LIBRARIES="-L$openblas_dir -lopenblas64_" -DLAPACK_LIBRARIES="-L$prefix/lib -lopenblas64_" -DCMAKE_Fortran_FLAGS="-O2 -fPIC -ffixed-line-length-none -cpp -fdefault-integer-8 -Dsaxpy=saxpy_64 -Ddaxpy=daxpy_64  -Dscopy=scopy_64 -Ddcopy=dcopy_64  -Dsgemv=sgemv_64 -Ddgemv=dgemv_64  -Dsgeqr2=sgeqr2_64 -Ddgeqr2=dgeqr2_64  -Dslacpy=slacpy_64 -Ddlacpy=dlacpy_64  -Dslahqr=slahqr_64 -Ddlahqr=dlahqr_64  -Dslanhs=slanhs_64 -Ddlanhs=dlanhs_64  -Dslarnv=slarnv_64 -Ddlarnv=dlarnv_64  -Dslartg=slartg_64 -Ddlartg=dlartg_64  -Dslascl=slascl_64 -Ddlascl=dlascl_64  -Dslaset=slaset_64 -Ddlaset=dlaset_64  -Dsscal=sscal_64 -Ddscal=dscal_64  -Dstrevc=strevc_64 -Ddtrevc=dtrevc_64  -Dstrmm=strmm_64 -Ddtrmm=dtrmm_64  -Dstrsen=strsen_64 -Ddtrsen=dtrsen_64  -Dsgbmv=sgbmv_64 -Ddgbmv=dgbmv_64  -Dsgbtrf=sgbtrf_64 -Ddgbtrf=dgbtrf_64  -Dsgbtrs=sgbtrs_64 -Ddgbtrs=dgbtrs_64  -Dsgttrf=sgttrf_64 -Ddgttrf=dgttrf_64  -Dsgttrs=sgttrs_64 -Ddgttrs=dgttrs_64  -Dspttrf=spttrf_64 -Ddpttrf=dpttrf_64  -Dspttrs=spttrs_64 -Ddpttrs=dpttrs_64  -Dsdot=sdot_64 -Dddot=ddot_64  -Dsger=sger_64 -Ddger=dger_64  -Dslabad=slabad_64 -Ddlabad=dlabad_64  -Dslaev2=slaev2_64 -Ddlaev2=dlaev2_64  -Dslamch=slamch_64 -Ddlamch=dlamch_64  -Dslanst=slanst_64 -Ddlanst=dlanst_64  -Dslanv2=slanv2_64 -Ddlanv2=dlanv2_64  -Dslapy2=slapy2_64 -Ddlapy2=dlapy2_64  -Dslarf=slarf_64 -Ddlarf=dlarf_64  -Dslarfg=slarfg_64 -Ddlarfg=dlarfg_64  -Dslasr=slasr_64 -Ddlasr=dlasr_64  -Dsnrm2=snrm2_64 -Ddnrm2=dnrm2_64  -Dsorm2r=sorm2r_64 -Ddorm2r=dorm2r_64  -Dsrot=srot_64 -Ddrot=drot_64  -Dssteqr=ssteqr_64 -Ddsteqr=dsteqr_64  -Dsswap=sswap_64 -Ddswap=dswap_64  -Dcaxpy=caxpy_64 -Dzaxpy=zaxpy_64  -Dccopy=ccopy_64 -Dzcopy=zcopy_64  -Dcgemv=cgemv_64 -Dzgemv=zgemv_64  -Dcgeqr2=cgeqr2_64 -Dzgeqr2=zgeqr2_64  -Dclacpy=clacpy_64 -Dzlacpy=zlacpy_64  -Dclahqr=clahqr_64 -Dzlahqr=zlahqr_64  -Dclanhs=clanhs_64 -Dzlanhs=zlanhs_64  -Dclarnv=clarnv_64 -Dzlarnv=zlarnv_64  -Dclartg=clartg_64 -Dzlartg=zlartg_64  -Dclascl=clascl_64 -Dzlascl=zlascl_64  -Dclaset=claset_64 -Dzlaset=zlaset_64  -Dcscal=cscal_64 -Dzscal=zscal_64  -Dctrevc=ctrevc_64 -Dztrevc=ztrevc_64  -Dctrmm=ctrmm_64 -Dztrmm=ztrmm_64  -Dctrsen=ctrsen_64 -Dztrsen=ztrsen_64  -Dcgbmv=cgbmv_64 -Dzgbmv=zgbmv_64  -Dcgbtrf=cgbtrf_64 -Dzgbtrf=zgbtrf_64  -Dcgbtrs=cgbtrs_64 -Dzgbtrs=zgbtrs_64  -Dcgttrf=cgttrf_64 -Dzgttrf=zgttrf_64  -Dcgttrs=cgttrs_64 -Dzgttrs=zgttrs_64  -Dcpttrf=cpttrf_64 -Dzpttrf=zpttrf_64  -Dcpttrs=cpttrs_64 -Dzpttrs=zpttrs_64  -Dcdotc=cdotc_64 -Dzdotc=zdotc_64  -Dcgeru=cgeru_64 -Dzgeru=zgeru_64  -Dcunm2r=cunm2r_64 -Dzunm2r=zunm2r_64  -DSCOPY=SCOPY_64 -DDCOPY=DCOPY_64  -DSLABAD=SLABAD_64 -DDLABAD=DLABAD_64  -DSLAMCH=SLAMCH_64 -DDLAMCH=DLAMCH_64  -DSLANHS=SLANHS_64 -DDLANHS=DLANHS_64  -DSLANV2=SLANV2_64 -DDLANV2=DLANV2_64  -DSLARFG=SLARFG_64 -DDLARFG=DLARFG_64  -DSROT=SROT_64 -DDROT=DROT_64  -DSGEMV=SGEMV_64 -DDGEMV=DGEMV_64 -Dscnrm2=scnrm2_64 -Ddznrm2=dznrm2_64 -Dcsscal=csscal_64 -Dzdscal=zdscal_64"

# Do the make install
make install

Once you've verified that the necessary files have been dumped into your Arpack's deps/usr directory, you can write your own deps/deps.jl file:

## This file autogenerated by BinaryProvider.write_deps_file().
## Do not edit.
##
## Include this file within your main top-level source, and call
## `check_deps()` from within your module's `__init__()` method
const Arpack = joinpath(dirname(@__FILE__), "usr/lib64/libarpack.so")
function check_deps()
    global Arpack
    if !isfile(Arpack)
        error("$(Arpack) does not exist, Please re-run Pkg.build(\"Arpack\"), and restart Julia.")
    end

    if Libdl.dlopen_e(Arpack) == C_NULL
        error("$(Arpack) cannot be opened, Please re-run Pkg.build(\"Arpack\"), and restart Julia.")
    end
end

Note that on my machine, the make install process put libarpack.so into deps/usr/lib64, not deps/usr/lib. You may have to change that path to match your machine's output.

sbromberger commented 6 years ago

@staticfloat - thank you very much for the detailed reply. This looks like a good option.

Right now, after having talked with @jpfairbanks, we're going to try to reduce our dependency on eigs (writing our own substitute) since it looks like we're using it in limited, specific ways. Should that not be viable, I'll be back to try your suggestion.

jpfairbanks commented 6 years ago

I think that Elliot's method for compiling Arpack from source is the best way forward for getting the full Arpack functionality.

We can probably get away with just computing eigenvectors with the power method because we just need 1 from the LR part of the spectrum.

garrison commented 6 years ago

I followed @staticfloat's instructions, but I still get the same error when I run Pkg.build(). Not sure if I am doing something obvious wrong. (On Ubuntu 16.04.)

~/.julia/packages/Arpack/iUWc/deps$ ls -lrt
total 16
drwxr-xr-x 7 garrison garrison 4096 Jun  1 06:56 usr
-rw-rw-r-- 1 garrison garrison 2460 Jul 13 17:37 build.jl
-rw-rw-r-- 1 garrison garrison  604 Jul 13 18:22 deps.jl
-rw-rw-r-- 1 garrison garrison 1505 Jul 13 18:23 build.log
~/.julia/packages/Arpack/iUWc/deps$ ls usr/lib/libarpack.so* -l
lrwxrwxrwx 1 garrison garrison     14 Jun  1 06:56 usr/lib/libarpack.so -> libarpack.so.2
lrwxrwxrwx 1 garrison garrison     18 Jun  1 06:56 usr/lib/libarpack.so.2 -> libarpack.so.2.0.0
-rwxr-xr-x 1 garrison garrison 375376 Jun  1 06:56 usr/lib/libarpack.so.2.0.0
~/.julia/packages/Arpack/iUWc/deps$ cat build.log 
┌ Warning: `wait(t::Task)` is deprecated, use `fetch(t)` instead.
│   caller = macro expansion at OutputCollector.jl:62 [inlined]
└ @ Core ~/.julia/packages/BinaryProvider/mWAR/src/OutputCollector.jl:62
┌ Warning: `wait(t::Task)` is deprecated, use `fetch(t)` instead.
│   caller = wait(::OutputCollector) at OutputCollector.jl:160
└ @ BinaryProvider ~/.julia/packages/BinaryProvider/mWAR/src/OutputCollector.jl:160
┌ Warning: `wait(t::Task)` is deprecated, use `fetch(t)` instead.
│   caller = wait(::OutputCollector) at OutputCollector.jl:161
└ @ BinaryProvider ~/.julia/packages/BinaryProvider/mWAR/src/OutputCollector.jl:161
ERROR: LoadError: LibraryProduct(nothing, ["libarpack"], :libarpack, "Prefix(/home/garrison/.julia/packages/Arpack/iUWc/deps/usr)") is not satisfied, cannot generate deps.jl!
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] #write_deps_file#134(::Bool, ::Function, ::String, ::Array{LibraryProduct,1}) at /home/garrison/.julia/packages/BinaryProvider/mWAR/src/Products.jl:392
 [3] write_deps_file(::String, ::Array{LibraryProduct,1}) at /home/garrison/.julia/packages/BinaryProvider/mWAR/src/Products.jl:379
 [4] top-level scope at none:0
 [5] include at ./boot.jl:317 [inlined]
 [6] include_relative(::Module, ::String) at ./loading.jl:1034
 [7] include(::Module, ::String) at ./sysimg.jl:29
 [8] include(::String) at ./client.jl:393
 [9] top-level scope at none:0
in expression starting at /home/garrison/.julia/packages/Arpack/iUWc/deps/build.jl:40

My deps.jl is the same as above, but with lib64 replaced by lib.

staticfloat commented 6 years ago

You shouldn't need to build; you should be able to just using Arpack. You've manually run the build process at that point.

What happens if you just manually start up a julia shell, include() the deps.jl file, and then try to using Libdl; Libdl.dlopen(Arpack)?

garrison commented 6 years ago

OK, so instead of Pkg.build I had to Pkg.add("Arpack") again; before that I got

ERROR: ArgumentError: Package Arpack not found in current path:
 - Run `Pkg.add("Arpack")` to install the Arpack package.

Forward progress though. This is what I am now getting:

julia> using Arpack
[ Info: Precompiling module Arpack
ERROR: LoadError: LoadError: invalid redefinition of constant Arpack
Stacktrace:
 [1] top-level scope at none:0
 [2] include at ./boot.jl:317 [inlined]
 [3] include_relative(::Module, ::String) at ./loading.jl:1034
 [4] include at ./sysimg.jl:29 [inlined]
 [5] include(::String) at /home/garrison/.julia/packages/Arpack/iUWc/src/Arpack.jl:8
 [6] top-level scope at /home/garrison/.julia/packages/Arpack/iUWc/src/Arpack.jl:13
 [7] include at ./boot.jl:317 [inlined]
 [8] include_relative(::Module, ::String) at ./loading.jl:1034
 [9] include(::Module, ::String) at ./sysimg.jl:29
 [10] top-level scope at none:0
 [11] eval at ./boot.jl:319 [inlined]
 [12] eval(::Expr) at ./client.jl:394
 [13] top-level scope at ./none:3 [inlined]
 [14] top-level scope at ./<missing>:0
in expression starting at /home/garrison/.julia/packages/Arpack/iUWc/deps/deps.jl:6
in expression starting at /home/garrison/.julia/packages/Arpack/iUWc/src/Arpack.jl:12
ERROR: Failed to precompile Arpack to /home/garrison/.julia/compiled/v0.7/Arpack/X5VZ.ji.
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] macro expansion at ./logging.jl:298 [inlined]
 [3] compilecache(::Base.PkgId) at ./loading.jl:1173
 [4] _require(::Base.PkgId) at ./loading.jl:942
 [5] require(::Base.PkgId) at ./loading.jl:838
 [6] require(::Module, ::Symbol) at ./loading.jl:833
garrison commented 6 years ago

What happens if you just manually start up a julia shell, include() the deps.jl file, and then try to using Libdl; Libdl.dlopen(Arpack)?

julia> include("deps.jl")
check_deps (generic function with 1 method)

julia> using Libdl; Libdl.dlopen(Arpack)
ERROR: could not load library "/home/garrison/.julia/packages/Arpack/iUWc/deps/usr/lib/libarpack.so"
libgfortran.so.4: cannot open shared object file: No such file or directory
Stacktrace:
 [1] dlopen(::String, ::UInt32) at /home/garrison/julia-master/usr/share/julia/stdlib/v0.7/Libdl/src/Libdl.jl:99 (repeats 2 times)
 [2] top-level scope at none:0
staticfloat commented 6 years ago

I recommend dev'ing Arpack so that you can edit it, right now it's pulling Arpack out of /home/garrison/.julia/packages/Arpack/iUWc, and that folder is considered "under the control" of Pkg3.

staticfloat commented 6 years ago

I would not be surprised if Pkg just overwrote the libraries you tried to install. dev your Arpack (via the pkg repl mode; pkg> dev Arpack), then reinstall the libraries to that dev'ed version of Arpack, then put in the new deps.jl file, then try to include() it and dlopen it agian.

garrison commented 6 years ago

and dlopen it again

Success:

julia> include("deps.jl")
check_deps (generic function with 1 method)

julia> using Libdl; Libdl.dlopen(Arpack)
Ptr{Nothing} @0x0000000000f51300

I'm now investigating why using Arpack still gives the invalid redefinition of constant Arpack error. From the traceback, it still seems to be looking in ~/.julia/packages/Arpack/iUWc/src/Arpack.jl.

garrison commented 6 years ago

Changing Arpack to libarpack everywhere in deps.jl seems to move me forward a bit as well, at least getting rid of the invalid redefinition of constant Arpack. But now I think Pkg is somehow still confused about whether to look in dev or in packages.

staticfloat commented 6 years ago

What pkg3 environment are you working inside of? What does pkg> status say?

garrison commented 6 years ago

Everything works now. On the way to getting it working, I ran dev Arpack after noticing pkg> status was not using the development version. I got ERROR: Path "/home/garrison/.julia/dev/Arpack" exists but it does not contain "src/Arpack.jl". Somehow I ended up with ~/.julia/dev/Arpack having nothing other than usr inside it. I moved it aside, ran dev Arpack again, but then had to move usr and deps.jl back, overwriting the ones that presumably were copied there from ~/.julia/packages/Arpack/.../deps.

blakejohnson commented 6 years ago

To follow up on an older comment, @andreasnoack's solution of DYLD_LIBRARY_PATH=/usr/local/opt/gcc@7/lib/gcc/7 julia-dev also allows me to subsequently run Pkg.build("Arpack") without error. So, I guess I am not following along with some of the suggestions above. I am building julia from source on MacOS 10.12 (Sierra). The gfortran version used to build OpenBLAS is gcc 7.2.0. And if I can get things to work with a setting of DYLD_LIBRARY_PATH, then isn't there just a broken rpath somewhere?

staticfloat commented 6 years ago

That only works if you have an installation of gcc 7. The instructions above are for users that, (for whatever reason) are unable to install gcc 7. On Sat, Jul 14, 2018 at 10:40 Blake Johnson notifications@github.com wrote:

To follow up on an older comment, @andreasnoack https://github.com/andreasnoack's solution of DYLD_LIBRARY_PATH=/usr/local/opt/gcc@7/lib/gcc/7 julia-dev also allows me to subsequently run Pkg.build("Arpack") without error. So, I guess I am not following along with some of the suggestions above. I am building julia from source on MacOS 10.12 (Sierra). The gfortran version used to build OpenBLAS is gcc 7.2.0. And if I can get things to work with a setting of DYLD_LIBRARY_PATH, then isn't there just a broken rpath somewhere?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JuliaLinearAlgebra/Arpack.jl/issues/5#issuecomment-405038558, or mute the thread https://github.com/notifications/unsubscribe-auth/AAH_aJlW-kgMnwNbrKc1u_JkXljlYZ-qks5uGi0BgaJpZM4U1Wfr .

--

-E

blakejohnson commented 6 years ago

That only works if you have an installation of gcc 7. The instructions above are for users that, (for whatever reason) are unable to install gcc 7.

Understood. But, I'd like to understand how to fix this RPATH issue as well.

staticfloat commented 6 years ago

Ah, I see what you’re asking. The reason you have to define the environment variable is because that path is not a default dynamic library search path. Solutions are:

That only works if you have an installation of gcc 7. The instructions above are for users that, (for whatever reason) are unable to install gcc

1.

Understood. But, I'd like to understand how to fix this RPATH issue as well.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JuliaLinearAlgebra/Arpack.jl/issues/5#issuecomment-405039532, or mute the thread https://github.com/notifications/unsubscribe-auth/AAH_aNRbkCU4ImtbGYa7XxxK6suQG4ATks5uGjCxgaJpZM4U1Wfr .

--

-E

chriselrod commented 6 years ago

Trying to follow these build instructions with MKL: https://github.com/JuliaLinearAlgebra/Arpack.jl/issues/5#issuecomment-404934563

I replaced lopenblas64_ with lmkl_rt, and removed all the symbol-renames so it looked like this:

cmake .. -DCMAKE_INSTALL_PREFIX=$prefix -DBUILD_SHARED_LIBS=ON -DBLAS_LIBRARIES="-L$blas_dir -lmkl_rt" -DLAPACK_LIBRARIES="-L$prefix/lib -lmkl_rt" -DCMAKE_Fortran_FLAGS="-O2 -fPIC -mprefer-vector-width=512 -march=native -ftree-vectorize -ffixed-line-length-none -cpp -fdefault-integer-8"

In deps.jl I replaced the library name Arpack with libarpack. cmake and make install worked without a hitch, and then I could run using Arpack without getting an error. However, when I try to test Arpack, I got a segfault. First few lines:

signal (11): Segmentation fault
in expression starting at /home/chriselrod/.julia/dev/Arpack/test/runtests.jl:6
mkl_blas_avx512_xzdotc at /opt/intel/compilers_and_libraries_2018.3.222/linux/mkl/lib/intel64/libmkl_avx512.so (unknown line)
mkl_blas_zdotc at /opt/intel/compilers_and_libraries_2018.3.222/linux/mkl/lib/intel64/libmkl_intel_thread.so (unknown line)
zdotc at /opt/intel/compilers_and_libraries_2018.3.222/linux/mkl/lib/intel64/libmkl_intel_ilp64.so (unknown line)
zneupd_ at /home/chriselrod/.julia/dev/Arpack/deps/usr/lib64/libarpack.so (unknown line)
neupd at /home/chriselrod/.julia/dev/Arpack/src/libarpack.jl:275
unknown function (ip: 0x7efefe30f9e5)

Removing the -fdefault-integer-8 instead causes all three tests to fail:

elty = Float64: Error During Test at /home/chriselrod/.julia/dev/Arpack/test/runtests.jl:16
  Got exception outside of a @test
  ARPACKException: unspecified ARPACK error: 4294967292
  Stacktrace:
   [1] aupd_wrapper(::Type, ::getfield(Arpack, Symbol("#matvecA!#24")){SparseMatrixCSC{Float64,Int64}}, ::getfield(Arpack, Symbol("##18#25")), ::getfield(Arpack, Symbol("##19#26")), ::Int64, ::Bool, ::Bool, ::String, ::Int64, ::Int64, ::String, ::Float64, ::Int64, ::Int64, ::Array{Float64,1}) at /home/chriselrod/.julia/dev/Arpack/src/libarpack.jl:49
   [2] #_eigs#17(::Int64, ::Int64, ::Symbol, ::Float64, ::Int64, ::Nothing, ::Array{Float64,1}, ::Bool, ::typeof(Arpack._eigs), ::SparseMatrixCSC{Float64,Int64}, ::UniformScaling{Bool}) at /home/chriselrod/.julia/dev/Arpack/src/Arpack.jl:120
   [3] #_eigs at ./none:0 [inlined]
   [4] #eigs#10 at /home/chriselrod/.julia/dev/Arpack/src/Arpack.jl:63 [inlined]
   [5] #eigs at ./none:0 [inlined]
   [6] #eigs#9 at /home/chriselrod/.julia/dev/Arpack/src/Arpack.jl:62 [inlined]
   [7] (::getfield(Arpack, Symbol("#kw##eigs")))(::NamedTuple{(:nev,),Tuple{Int64}}, ::typeof(eigs), ::SparseMatrixCSC{Float64,Int64}) at ./none:0
   [8] macro expansion at /home/chriselrod/.julia/dev/Arpack/test/runtests.jl:33 [inlined]
   [9] macro expansion at /home/chriselrod/Documents/languages/jdev/usr/share/julia/stdlib/v1.0/Test/src/Test.jl:1156 [inlined]
   [10] macro expansion at /home/chriselrod/.julia/dev/Arpack/test/runtests.jl:16 [inlined]
   [11] macro expansion at /home/chriselrod/Documents/languages/jdev/usr/share/julia/stdlib/v1.0/Test/src/Test.jl:1083 [inlined]
   [12] top-level scope at /home/chriselrod/.julia/dev/Arpack/test/runtests.jl:7
   [13] include at ./boot.jl:317 [inlined]
   [14] include_relative(::Module, ::String) at ./loading.jl:1038
   [15] include(::Module, ::String) at ./sysimg.jl:29
   [16] include(::String) at ./client.jl:388
   [17] top-level scope at none:0
   [18] eval(::Module, ::Any) at ./boot.jl:319
   [19] macro expansion at ./logging.jl:317 [inlined]
   [20] exec_options(::Base.JLOptions) at ./client.jl:219
   [21] _start() at ./client.jl:421
elty = Complex{Float64}: Error During Test at /home/chriselrod/.julia/dev/Arpack/test/runtests.jl:16

I see a lot of references to Int64 there, so perhaps that's related when I change the default.

Any suggestions?

eli-schwartz commented 6 years ago

I'm curious about this. I wouldn't think that downloading and building the Julia source code would be so far outside the norm that it's not part of the testing strategy.

That's a weird testing strategy, there's a much, much, much more obvious way to detect this problem.

This precompiled archive contains the binary asset libarpack.so.2.0.0 This binary asset, as revealed by ldd, objdump, readelf, etc. is linked to the shared library libgfortran.so.4

This is an obvious problem, since basic software distribution logic states that if you depend on libraries you don't ship yourself and have no especial reason to think should be available, then your software breaks.

This is okay if it's guaranteed to be everywhere, like libc.so.6, and less okay if you're shipping for some binary dependency like, say, julia, except it's not part of the explicitly documented julia ABI.

This causes erroneous bug reports for Linux distributions foolish enough to try supporting the julia programming language... (I'm having flashbacks to "oh, julia has an option to be compiled against the system llvm39 except if you don't include these backports included in the julia source tree which we forgot to mention, it segfaults randomly". If the julia ecosystem keeps causing friction for users who don't use the precompiled binaries, maybe we should stop trying to support it in our distro...)

klpn commented 6 years ago

If using Julia 1.0.0 installed with the Arch package manager, it is possible to get Arpack.jl working by installing Arpack the same way (i.e. pacman -S arpack), then copy /usr/lib/libarpack.so.2.0.0 into the Arpack/xxxx/deps/usr/lib directory, and run Pkg.build("Arpack"). Perhaps, the build should check if libarpack.so.2.0.0 is present in /usr/lib, and use that version by default (because it is likely to be compiled against the same version of libgfortran.so as the version of Julia installed in the system), and only try to download the precompiled version of libarpack if this test fails?

Red-Portal commented 6 years ago

@klpn This worked on Arch Linux with julia 1.0.0 indeed. Thanks for the tip

non-Jedi commented 6 years ago

copying libarpack.so.2.0.0 was also what I had to do on my source-built Julia (with gcc 8). This whole strategy of ignoring binary dependencies already provided by the system seems misguided at best... Some of us don't have harddrives where it's reasonable to have multiple copies of libraries.

andreasnoack commented 6 years ago

Some of us don't have harddrives where it's reasonable to have multiple copies of libraries.

On my machine libarpack is 386kB.

eli-schwartz commented 6 years ago

On my machine libarpack is 386kB.

Sort of irrelevant, since the whole point here is that Arpack.jl is completely and utterly broken (not "takes too many kilobytes of HDD space", broken) on systems which aren't the prebuilt julia binaries.

And so, that logic is the logic which would lead to providing everything from libc on up. Which, the prebuilt julia binaries do. (Right?) Which are the binaries they're not using. (Right?)

Red-Portal commented 6 years ago

@eli-schwartz No. In my case, it's actually a prebuilt Julia binary but still fails.

klpn commented 6 years ago

In my case, it's actually a prebuilt Julia binary but still fails.

From your earlier post, I got the impression that you had Julia installed via pacman. These binaries are built from source by the package maintainers (see PKGBUILD), so they are not identical with the "official" prebuilt binaries.

eli-schwartz commented 6 years ago

This is still completely down to the different gcc version I guess.

Fun fact: basically everything else is the same anyway, seemingly julia 1.0 segfaults whenever attempting to build using basically any system libs.

non-Jedi commented 6 years ago

@andreasnoack you're right. This particular package isn't a great example for that argument. This was just the first of many places I will/have run into this, and I got a bit ranty.

I still believe in the argument in the general case, though.