In my package (NCDatasets) I am calling a C function which expect an array as input.
I use two functions so that ranges, bit arrays, transposed arrays,… get converted
to plain arrays. However this does not work for offset arrays:
using OffsetArrays
function C_function_expecting_array(A::Array)
println("Yes, got an array. Thank you!")
end
function C_function_expecting_array(A::AbstractArray)
println("hold on, converting to array")
C_function_expecting_array(Array(A))
end
Example session:
julia> C_function_expecting_array([1,2,3])
Yes, got an array. Thank you!
julia> C_function_expecting_array(1:3)
hold on, converting to array
Yes, got an array. Thank you!
julia> C_function_expecting_array(BitArray([true,false]))
hold on, converting to array
Yes, got an array. Thank you!
julia> C_function_expecting_array(CUDA.cu([1,2,3])) # also works with CUDA arrays
hold on, converting to array
Yes, got an array. Thank you!
julia> C_function_expecting_array(OffsetArray([1,2,3],-1))
hold on, converting to array
ERROR: DimensionMismatch("axes must agree, got (Base.OneTo(3),) and (OffsetArrays.IdOffsetRange(values=0:2, indices=0:2),)")
Stacktrace:
[1] (::Base.var"#checkaxs#125")(axd::Tuple{Base.OneTo{Int64}}, axs::Tuple{OffsetArrays.IdOffsetRange{Int64, Base.OneTo{Int64}}})
@ Base ./abstractarray.jl:1101
[2] copyto_axcheck!(dest::Vector{Int64}, src::OffsetVector{Int64, Vector{Int64}})
@ Base ./abstractarray.jl:1103
[3] Array
@ ./array.jl:563 [inlined]
[4] Array
@ ./boot.jl:481 [inlined]
[5] C_function_expecting_array(A::OffsetVector{Int64, Vector{Int64}})
@ Main ./REPL[71]:3
[6] top-level scope
@ REPL[76]:1
[7] top-level scope
@ ~/.julia/packages/CUDA/fAEDi/src/initialization.jl:52
I believe I could call the first function directly with the offset array as we have:
a = [1,2,3]
pointer(a) == pointer(OffsetArray(a,-1))
# true
But I do not what to change the function signature to C_function_expecting_array(A::Union{Array,OffsetArray})
as it would introduce an explicit dependency to offset arrays.