Unsafe_wrap perform memory allocations

,

Hi!
Im trying to wrap c pointer array into julia as follows:

function WrapArray(arr :: Ptr{Cdouble}, length :: Cint) :: Cdouble
    @timev wrapped = unsafe_wrap(Vector{Cdouble}, arr, length)   
  0.000003 seconds (2 allocations: 64 bytes)
elapsed time (ns):  2700.0
gc time (ns):       0
bytes allocated:    64

just to be able to get values from array.

But its perform allocations and slow down every function call twice.

This way is better to write c++ binding for array (CxxWrap) and do cast.
Which is much much faster. The price is unsupported array operations.

Is there a way to cast pointer into julia array without memory allocation?

I found the following old discussion
unsfe_wrap allocations which propose to make a custom array inside julia. (which i not fully understand yet)

Or reinterpret could work?

You can use UnsafeArray from UnsafeArrays.jl:

UnsafeArray(ptr, Int(length))
2 Likes

Thank for a hint
im trying the following but its not working:

comp = UnsafeArrays.UnsafeArray{Cdouble, 1}(arr, length)

You probably need to Intify the size (length in your case) like I did in my example (also, it is easier to help if you include error messages).

My length is Cint.
I try out cast directly as you did and errors still same.

But im using c++ to call julia and have pure messaging (dot get correct way to catch exceptions, JL_TRY is strange - it could be used only once)

fatal: error thrown and no exception handler available.
MethodError(f=UnsafeArrays.UnsafeArray{Float64, 1}, args=(0x000001ef854c8cb0, 3), world=0x00000000000068ac)
jl_method_error_bare at C:/workdir/src\gf.c:2254
jl_method_error at C:/workdir/src\gf.c:2272
jl_lookup_generic_ at C:/workdir/src\gf.c:3106
ijl_apply_generic at C:/workdir/src\gf.c:3121

Here’s a minimal demo of how to construct an UnsafeArray from a Ptr:

julia> using UnsafeArrays

julia> let N = 10, T = Float64
           _ptr = Libc.malloc(sizeof(T) * N)
           ptr = convert(Ptr{T}, _ptr)
           
           A = UnsafeArray(ptr, (N,))
           A .= 1
           @show sum(A)

           Libc.free(ptr)
       end
sum(A) = 10.0

the important thing to know here is that you have to call UnsafeArray(::Ptr{T}, ::NTuple{N, Int}) to construct an UnsafeArray{T, N}. For some reason they don’t have a method for UnsafeArray{T, N}(::Ptr, dims...). That’s why I did the convert step in the above code.

I’d recommend that at least while debugging your code and learning to make it work, you run your code within julia. It’ll make it easier to get error messages that make sense and get people to help you.

See also Please read: make it easier to help you

Thanks for example. I get to know about let syntax.

Try to figure out error handling in c++.

Run it in REPL - and everything is ok.

In my case its worked only if length specifyed in the code

wrapped = UnsafeArray{Cdouble, 1}(arr, (3,))

And its woked perfectly, but i don have length at compile time.