Is there a means to retrieve the strides of a julia array from the C API?
https://docs.julialang.org/en/stable/stdlib/arrays/#Base.strides
The only property accessors available in julia.h
apparently are
JL_DLLEXPORT void *jl_array_ptr(jl_array_t *a);
JL_DLLEXPORT void *jl_array_eltype(jl_value_t *a);
JL_DLLEXPORT int jl_array_rank(jl_value_t *a);
JL_DLLEXPORT size_t jl_array_size(jl_value_t *a, int d);
If I can avoid recomputing the strides on the C++ side, that would be fantastic.
jl_array_t
are Array
and are always column major dense array.
I know, in xtensor-julia
, we do compute the column-major strides.
See e.g. https://github.com/QuantStack/xtensor-julia/blob/master/deps/xtensor-julia/include/xtensor-julia/jltensor.hpp#L134
but I guess that you already compute strides and store them in the memory representation of Julia arrays for efficiency.
It would be more efficient to me to be able to access them, just like we do in xtensor-python
, but wrapping the strides from the buffer protocol.
See e.g. https://github.com/QuantStack/xtensor-python/blob/master/include/xtensor-python/pyarray.hpp#L494
Is there a means to access the strides computed by Julia from the C API?
No, the strides aren’t pre-computed and cached. Only the dimension sizes themselves are stored. Here’s the array header definition: https://github.com/JuliaLang/julia/blob/4a814806811d13b350a3f6c04cb839ad4c9236f1/src/julia.h#L143-L162
And here’s the implementation of converting an n-dimensional index to an offset: https://github.com/JuliaLang/julia/blob/1093977c989a3f7bef4e791d58055c30ee2fee10/src/builtins.c#L906-L927
Well, the dimensions are essentially the strides, in units of sizeof
the elements. Typically, in C, you would access a Julia column-major array A[i1,i2,i3]
via
Adata[i1-1 + n1*(i2-1 + n2*(i3-1))]
where Adata
is a pointer (of the appropriate type) to the underlying data and n1
and n2
are the sizes of the first two dimensions, and I’ve subtracted 1 to convert between 1-based and 0-based indexing. By parenthesizing it like this, no additional stride calculations are needed.
1 Like
It’s not really related to the strides, but note that ArrayRef
in CxxWrap.jl makes working with native Julia arrays from C++ slightly easier:
https://github.com/JuliaInterop/CxxWrap.jl#reference-native-julia-arrays
The current API is limited to what I needed, so it doesn’t implement multi-dimensional indexing and you will still need to use @stevengj 's formula.
Thanks guys, this clarifies things quite a bit.