I am trying to modify AMD.jl to support Julia 0.7.0. This is a wrapper package to call C functions using ccall. The function pointers are defined as follows.
global const _libamd = Libdl.dlopen("libamd")
global const _amd_valid = Libdl.dlsym(_libamd, "amd_valid")
global const _amd_l_valid = Libdl.dlsym(_libamd, "amd_l_valid")
A main function amd_valid is defined with @eval to support different types.
for (validfn, typ) in ((_amd_valid, Cint), (_amd_l_valid, Clong))
@eval begin
function amd_valid(A :: SparseMatrixCSC{F,$typ}) where F
nrow = $typ(size(A,1))
ncol = $typ(size(A,2))
colptr = A.colptr .- $typ(1) # 0-based indexing
rowval = A.rowval .- $typ(1)
valid = ccall($validfn, $typ,
($typ, $typ, Ptr{$typ}, Ptr{$typ}), nrow, ncol, colptr, rowval)
return valid == AMD_OK || valid == AMD_OK_BUT_JUMBLED
end
end
end
Running a test, I got an error ERROR: LoadError: ccall: null function pointer. This function perfectly worked in Julia 0.6.0. When I replaced $validfn with Libdl.dlsym(Libdl.dlopen("libamd"), "amd_valid"), the function works without the error. It looks straightforward but a bit redundant.
What is the best way to modify this function? And if possible, please let me know why Julia 0.7 does not accept $validfn.
Thanks for looking into this. I wrote AMD.jl and I’m stuck at the same place. I thought the issue might be related to https://github.com/JuliaLang/julia/issues/26557#issuecomment-374963443 but writing a BinDeps script to download and build the libamd from SuiteSparse led to the same error message.
Yes, pointers will not survive the serialization + deserialization roundtrip from precompilation. Either re-initialize them in __init__ or turn off precompilation.