N-dimensional view into an N+1 dimension array

I have an Array{T,N+1} and I want to pass a slice/view of the first N dimensions to a function. If I knew, say, N=2 I would do

b = @view a[:,:,1]
f(b,args...)

But the number of colons depends on N. Is there a way to do this for general N?

2 Likes

Awesome!

Or also selectdim(array,dim_to_select,indx_on_that_dim), e.g. b = selectdim(a,3,1)

4 Likes

I really like the solution with selectdim(), but I add this one too

vv = @view v[ntuple(_->:,ndims(v)-1)...,1]
1 Like

Does this produce a “view” or copy to a new array?

A tupple of colons! Didn’t know you could do that!

a view Arrays · The Julia Language

As far as I understand (:) is a function, like isless() for example
It should be equivalent (alias?) of Colon().

But let’s wait for someone who knows to explain better how it works :slight_smile:

Just try it :slight_smile::

julia> x = [1 2; 3 4]
2×2 Matrix{Int64}:
 1  2
 3  4
julia> xd2_1 = selectdim(x,2,1)
2-element view(::Matrix{Int64}, :, 1) with eltype Int64:
 1
 3
julia> xd2_1[2] = 30
30
julia> x
2×2 Matrix{Int64}:
  1  2
 30  4
1 Like

That’s right:

So Colon is a struct type and the singleton instance Colon() is a function and : is a synonym for that.

1 Like

I don’t have Julia installed on my phone… yet!

This is the Base solution, so I’ll switch this to the answer. But b=@view a(..,i) from EllipsisNotation.jl is a really nice bit of syntactic sugar.

1 Like

Huh. The ellipsis version works fine on the GPU, but selectdim throws an allocation error:

ERROR: InvalidIRError: compiling MethodInstance for (::GPUArrays.var"#broadcast_kernel#28")(::CUDA.CuKernelContext, ::CuDeviceVector{SVector{3, Float32}, 1}, ::Base.Broadcast.Broadcasted{CUDA.CuArrayStyle{1}, Tuple{Base.OneTo{Int64}}, typeof(interp!), Tuple{Base.Broadcast.Extruded{CuDeviceVector{SVector{3, Float32}, 1}, Tuple{Bool}, Tuple{Int64}}, Base.Broadcast.Extruded{CuDeviceVector{SVector{3, Float32}, 1}, Tuple{Bool}, Tuple{Int64}}, CUDA.CuRefValue{CuDeviceArray{Float32, 4, 1}}}}, ::Int64) resulted in invalid LLVM IR
Reason: unsupported call through a literal pointer (call to ijl_alloc_array_1d)

@maleadt , Is there a reason why a view created by selectdim shouldn’t work within a kernel?

Not that I know; SubArrays of CuDeviceArrays should generally be supported. Please include the full backtrace, and make sure the code is type stable first.

I’ll work on a MWE.